refactor(render): de-Qt oakrender and wrap it in a pure C ABI

- copy engine/render to src/render/src (sunk param types excluded),
  de-Qt in five parallel groups: core machinery (tickets/worker pool/
  jobs), caches, color/texture, preview/IPC, GPU backends
- replace Qt GL/Vulkan wrappers with native context abstractions
  (CGL/EGL/WGL, raw vulkan.h), QProcess with POSIX WorkerProcess,
  QJsonObject with a minimal NDJSON-compatible workerjson (wire
  protocol unchanged), QDataStream disk state with a byte-compatible
  BinaryStream
- signals become single std::function callbacks or facade-triggered
  calls per the documented signal/slot strategy
- pure C ABI in include/render + src/render/c_api (renderer/cache/
  color/manager families, OAKRENDER_E_* codes), 37 gtest cases
- bridge src/node/transition/render/* stubs to the real oakrender
  headers, closing the node<->render cycle: liboaknode links
  liboakrender, zero dangling symbols
- docs: M7 implementation status + oakrender semantic-change notes
This commit is contained in:
2026-08-06 03:21:26 +08:00
parent d77348ad9f
commit edbd3913af
170 changed files with 818511 additions and 358 deletions
@@ -0,0 +1,94 @@
#pragma once
// Transitional: engine/audio/audiovisualwaveform.h de-Qt target form
// (oakaudio contract, M6). Data-only surface used by oakrender: the Sample
// reduction types plus the writers renderprocessor/audiowaveformcache call.
// QPainter-based draw_sample() stays in the app layer.
#include <map>
#include <vector>
#include "olive/core/render/samplebuffer.h"
#include "olive/core/util/rational.h"
namespace olive {
using core::Rational;
using core::SampleBuffer;
class AudioVisualWaveform {
public:
struct SamplePerChannel {
float min;
float max;
};
using Sample = std::vector<SamplePerChannel>;
// Same value as the engine original (audiovisualwaveform.cpp)
inline static const Rational k_minimum_sample_rate = Rational(1, 8);
int channel_count() const { return int(channels_.size()); }
void set_channel_count(int channels) { channels_.resize(size_t(channels)); }
void overwrite_samples(const SampleBuffer &samples, int sample_rate,
bool /*from_maximum*/ = false)
{
(void) samples;
(void) sample_rate;
}
Sample get_summary_from_time(const Rational &, const Rational &) const
{
return Sample();
}
static Sample sum_samples(const SampleBuffer &, size_t, size_t)
{
return Sample();
}
static Sample re_sum_samples(const SamplePerChannel *, int, int)
{
return Sample();
}
const Rational &length() const { return length_; }
// Simplified stub-model version of the engine writer: the real
// implementation walks mipmapped rates; here sums are merged 1:1 per
// channel at sample granularity (dest/offset in the same time base).
void overwrite_sums(const AudioVisualWaveform &sums, const Rational &dest,
const Rational &offset = 0, const Rational &length = 0)
{
size_t our_start = size_t(dest.to_double());
size_t their_start = size_t(offset.to_double());
size_t count = length.to_double() > 0
? size_t(length.to_double())
: SIZE_MAX;
for (size_t ch = 0; ch < channels_.size() &&
ch < sums.channels_.size();
ch++) {
Sample &our_arr = channels_[ch];
const Sample &their_arr = sums.channels_[ch];
if (our_start + count > our_arr.size()) {
our_arr.resize(our_start + (count == SIZE_MAX ? their_arr.size() - their_start : count));
}
for (size_t i = 0; i < count &&
their_start + i < their_arr.size() &&
our_start + i < our_arr.size();
i++) {
our_arr[our_start + i] = their_arr[their_start + i];
}
}
Rational end = dest + (length.to_double() > 0 ? length : Rational());
if (end > length_) {
length_ = end;
}
}
private:
std::vector<Sample> channels_;
Rational length_;
};
}
+299
View File
@@ -0,0 +1,299 @@
#pragma once
// Transitional: QDataStream replacement for the render disk-cache state and
// index files. Mirrors QDataStream's default (big-endian) wire format for the
// subset of types those files use, so existing cache files stay readable:
// quint32/qint32/qint64 -> big-endian bytes
// bool -> quint8
// QString -> quint32 byte length + UTF-16BE code units
// QUuid -> 16 raw bytes in RFC 4122 order
// Reads past EOF yield zeroed values (QDataStream::ReadPastEnd semantics).
#include <cstdint>
#include <cstdio>
#include <string>
namespace olive
{
namespace binarystream_detail
{
inline void append_utf16be(std::string &out, uint32_t cp)
{
if (cp >= 0x10000) {
cp -= 0x10000;
uint16_t hi = 0xD800 + (cp >> 10);
uint16_t lo = 0xDC00 + (cp & 0x3FF);
out += char(hi >> 8);
out += char(hi & 0xFF);
out += char(lo >> 8);
out += char(lo & 0xFF);
} else {
out += char(cp >> 8);
out += char(cp & 0xFF);
}
}
inline std::string utf8_to_utf16be(const std::string &s)
{
std::string out;
size_t i = 0;
while (i < s.size()) {
unsigned char c = s[i];
uint32_t cp;
size_t extra;
if (c < 0x80) {
cp = c;
extra = 0;
} else if ((c & 0xE0) == 0xC0) {
cp = c & 0x1F;
extra = 1;
} else if ((c & 0xF0) == 0xE0) {
cp = c & 0x0F;
extra = 2;
} else if ((c & 0xF8) == 0xF0) {
cp = c & 0x07;
extra = 3;
} else {
// Invalid byte, emit U+FFFD like Qt's UTF-8 handling
cp = 0xFFFD;
extra = 0;
}
for (size_t j = 0; j < extra; j++) {
if (i + 1 < s.size()) {
cp = (cp << 6) | (uint8_t(s[i + 1]) & 0x3F);
i++;
}
}
i++;
append_utf16be(out, cp);
}
return out;
}
inline void append_utf8(std::string &out, uint32_t cp)
{
if (cp < 0x80) {
out += char(cp);
} else if (cp < 0x800) {
out += char(0xC0 | (cp >> 6));
out += char(0x80 | (cp & 0x3F));
} else if (cp < 0x10000) {
out += char(0xE0 | (cp >> 12));
out += char(0x80 | ((cp >> 6) & 0x3F));
out += char(0x80 | (cp & 0x3F));
} else {
out += char(0xF0 | (cp >> 18));
out += char(0x80 | ((cp >> 12) & 0x3F));
out += char(0x80 | ((cp >> 6) & 0x3F));
out += char(0x80 | (cp & 0x3F));
}
}
inline std::string utf16be_to_utf8(const std::string &be)
{
std::string out;
size_t units = be.size() / 2;
for (size_t i = 0; i < units; i++) {
uint16_t u = (uint8_t(be[i * 2]) << 8) | uint8_t(be[i * 2 + 1]);
uint32_t cp = u;
if (u >= 0xD800 && u < 0xDC00 && i + 1 < units) {
uint16_t lo = (uint8_t(be[i * 2 + 2]) << 8) |
uint8_t(be[i * 2 + 3]);
if (lo >= 0xDC00 && lo < 0xE000) {
cp = 0x10000 + ((uint32_t(u) - 0xD800) << 10) + (lo - 0xDC00);
i++;
}
}
append_utf8(out, cp);
}
return out;
}
inline int hex_digit(char c)
{
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
return 0;
}
} // namespace binarystream_detail
class BinaryStreamWriter {
public:
explicit BinaryStreamWriter(std::FILE *f)
: f_(f)
{
}
BinaryStreamWriter &operator<<(uint32_t v)
{
write_be(v, 4);
return *this;
}
BinaryStreamWriter &operator<<(int32_t v)
{
write_be(uint32_t(v), 4);
return *this;
}
BinaryStreamWriter &operator<<(int64_t v)
{
write_be(uint64_t(v), 8);
return *this;
}
BinaryStreamWriter &operator<<(bool v)
{
write_be(v ? 1 : 0, 1);
return *this;
}
// QString: quint32 byte length + UTF-16BE data
BinaryStreamWriter &operator<<(const std::string &v)
{
std::string be = binarystream_detail::utf8_to_utf16be(v);
write_be(uint32_t(be.size()), 4);
if (!be.empty()) {
std::fwrite(be.data(), 1, be.size(), f_);
}
return *this;
}
// QUuid: 16 raw bytes in RFC 4122 order. Accepts the canonical text form
// "{8-4-4-4-12}" (braces optional), which is what cache uuids are stored as.
void write_uuid_text(const std::string &uuid_text)
{
uint8_t bytes[16] = { 0 };
int nibble = 0;
for (char c : uuid_text) {
if (c == '{' || c == '}' || c == '-') {
continue;
}
if (nibble >= 32) {
break;
}
int d = binarystream_detail::hex_digit(c);
if (nibble % 2 == 0) {
bytes[nibble / 2] = uint8_t(d << 4);
} else {
bytes[nibble / 2] |= uint8_t(d);
}
nibble++;
}
std::fwrite(bytes, 1, 16, f_);
}
private:
void write_be(uint64_t v, int bytes)
{
uint8_t b[8];
for (int i = 0; i < bytes; i++) {
b[i] = uint8_t(v >> ((bytes - 1 - i) * 8));
}
std::fwrite(b, 1, bytes, f_);
}
std::FILE *f_;
};
class BinaryStreamReader {
public:
explicit BinaryStreamReader(std::FILE *f)
: f_(f)
{
}
BinaryStreamReader &operator>>(uint32_t &v)
{
v = uint32_t(read_be(4));
return *this;
}
BinaryStreamReader &operator>>(int32_t &v)
{
v = int32_t(read_be(4));
return *this;
}
BinaryStreamReader &operator>>(int64_t &v)
{
v = int64_t(read_be(8));
return *this;
}
BinaryStreamReader &operator>>(bool &v)
{
v = read_be(1) != 0;
return *this;
}
BinaryStreamReader &operator>>(std::string &v)
{
uint32_t len = uint32_t(read_be(4));
v.clear();
if (len == 0xFFFFFFFF || len == 0) {
return *this;
}
std::string be(len, '\0');
size_t got = std::fread(&be[0], 1, len, f_);
be.resize(got);
v = binarystream_detail::utf16be_to_utf8(be);
return *this;
}
// QUuid: 16 raw bytes -> canonical "{8-4-4-4-12}" lowercase text
std::string read_uuid_text()
{
uint8_t bytes[16] = { 0 };
std::fread(bytes, 1, 16, f_);
static const char k_hex[] = "0123456789abcdef";
std::string out;
out.reserve(38);
out += '{';
for (int i = 0; i < 16; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) {
out += '-';
}
out += k_hex[bytes[i] >> 4];
out += k_hex[bytes[i] & 0xF];
}
out += '}';
return out;
}
bool at_end() const
{
int c = std::fgetc(f_);
if (c == EOF) {
return true;
}
std::ungetc(c, f_);
return false;
}
private:
uint64_t read_be(int bytes)
{
uint8_t b[8] = { 0 };
std::fread(b, 1, bytes, f_);
uint64_t v = 0;
for (int i = 0; i < bytes; i++) {
v = (v << 8) | b[i];
}
return v;
}
std::FILE *f_;
};
}
+140
View File
@@ -0,0 +1,140 @@
#pragma once
// Transitional: engine/codec/decoder.h de-Qt target form (oakcodec contract,
// M5). Covers the Decoder/DecoderCache-facing surface the render core uses:
// stream identification, open/close, video/audio retrieval and access-time
// bookkeeping. CodecStream gains operator< because de-Qt RenderCache is
// std::map-based (QHash used qHash before).
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "loopmode.h"
#include "rendermodes.h"
#include "cancelatom.h"
#include "codec/frame.h"
#include "project/footage/footagedescription.h"
#include "olive/core/render/audioparams.h"
#include "olive/core/render/samplebuffer.h"
#include "olive/core/util/rational.h"
#include "olive/core/util/timerange.h"
namespace olive {
using core::AudioParams;
using core::Rational;
using core::SampleBuffer;
using core::TimeRange;
class Block;
class Renderer;
class Texture;
using TexturePtr = std::shared_ptr<Texture>;
class Decoder;
using DecoderPtr = std::shared_ptr<Decoder>;
class Decoder {
public:
virtual ~Decoder() = default;
class CodecStream {
public:
CodecStream()
: stream_(-1)
, block_(nullptr)
{
}
CodecStream(const std::string &filename, int stream, Block *block)
: filename_(filename)
, stream_(stream)
, block_(block)
{
}
bool is_valid() const { return !filename_.empty() && stream_ >= 0; }
void reset() { *this = CodecStream(); }
bool operator==(const CodecStream &rhs) const
{
return filename_ == rhs.filename_ && stream_ == rhs.stream_;
}
bool operator<(const CodecStream &rhs) const
{
if (filename_ != rhs.filename_) {
return filename_ < rhs.filename_;
}
return stream_ < rhs.stream_;
}
const std::string &filename() const { return filename_; }
int stream() const { return stream_; }
Block *block() const { return block_; }
private:
std::string filename_;
int stream_;
Block *block_;
};
bool open(const CodecStream &) { return false; }
void close() {}
// Same value as the engine original (decoder.cpp): RATIONAL_MIN.
// inline because this stub is header-only.
inline static const Rational k_any_timecode = RATIONAL_MIN;
struct RetrieveVideoParams {
Renderer *renderer = nullptr;
Rational time;
int divider = 1;
PixelFormat maximum_format = PixelFormat::invalid;
CancelAtom *cancelled = nullptr;
VideoParams::ColorRange force_range = VideoParams::k_color_range_default;
VideoParams::Interlacing src_interlacing = VideoParams::k_interlace_none;
};
TexturePtr retrieve_video(const RetrieveVideoParams &) { return nullptr; }
FramePtr retrieve_video_frame(const RetrieveVideoParams &) { return nullptr; }
enum RetrieveAudioStatus {
k_invalid = -1,
k_ok,
k_waiting_for_conform,
k_unknown_error
};
RetrieveAudioStatus retrieve_audio(SampleBuffer &, const TimeRange &,
const AudioParams &,
const std::string &, LoopMode,
RenderMode::Mode)
{
return k_invalid;
}
int64_t get_last_accessed_time() { return 0; }
void increment_access_time(int64_t) {}
static DecoderPtr create_from_id(const std::string &) { return nullptr; }
// oaknode 侧契约(footage.cpp 探针路径)
static std::vector<DecoderPtr> receive_list_of_all_decoders() { return {}; }
FootageDescription probe(const std::string &, CancelAtom *)
{
return FootageDescription();
}
static std::string
transform_image_sequence_file_name(const std::string &filename,
int64_t frame_number)
{
(void) frame_number;
return filename;
}
};
}
+61
View File
@@ -0,0 +1,61 @@
#pragma once
// Transitional: engine/codec/frame.h de-Qt target form (oakcodec contract,
// M5). Covers the surface the render core uses. Based on
// src/node/transition/codec/frame.h, extended with the frame-allocation and
// linesize API renderprocessor/renderworkerpool call.
#include <cstddef>
#include <cstdint>
#include <memory>
#include "videoparams.h"
#include "olive/core/util/color.h"
#include "olive/core/util/rational.h"
namespace olive {
using core::Color;
using core::Rational;
class Frame;
using FramePtr = std::shared_ptr<Frame>;
class Frame {
public:
static FramePtr create() { return std::make_shared<Frame>(); }
static int generate_linesize_bytes(int width, PixelFormat format,
int channel_count)
{
(void) width; (void) format; (void) channel_count;
return 0;
}
bool is_allocated() const { return false; }
bool allocate() { return false; }
char *data() { return nullptr; }
const char *const_data() const { return nullptr; }
int64_t allocated_size() const { return 0; }
int width() const { return 0; }
int height() const { return 0; }
PixelFormat format() const { return PixelFormat::invalid; }
int channel_count() const { return 0; }
int linesize_bytes() const { return 0; }
int linesize_pixels() const { return 0; }
void set_pixel(int, int, const Color &) {}
const Rational &timestamp() const
{
static const Rational r;
return r;
}
void set_timestamp(const Rational &) {}
const VideoParams &video_params() const
{
static VideoParams p;
return p;
}
void set_video_params(const VideoParams &) {}
};
}
+140
View File
@@ -0,0 +1,140 @@
// Transitional copy of engine/common/avframeptr.h(本身已无 Qt,待下沉 oakcommon)。只增不删。
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
Modifications Copyright (C) 2025 mikesolar
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef OAK_AVFRAMEPTR_H
#define OAK_AVFRAMEPTR_H
#include <stdint.h>
#include <memory>
#include <ffmpeg_bridge/ffmpeg_bridge.h>
namespace olive
{
/**
* @brief C++ adapter around the ffmpeg_bridge frame handle
*
* Mirrors the AVFrame field access the codebase used to perform directly,
* but every operation goes through the pure C bridge API so the editor
* never touches FFmpeg itself. The underlying frame object always lives
* inside the bridge library.
*/
class AVFrame {
public:
AVFrame() :
handle_(fb_frame_alloc())
{
}
explicit AVFrame(FBFrame *handle) :
handle_(handle)
{
}
~AVFrame()
{
if (handle_) {
fb_frame_free(&handle_);
}
}
AVFrame(const AVFrame &) = delete;
AVFrame &operator=(const AVFrame &) = delete;
FBFrame *handle() const { return handle_; }
int width() const { return fb_frame_get_width(handle_); }
void set_width(int w) { fb_frame_set_width(handle_, w); }
int height() const { return fb_frame_get_height(handle_); }
void set_height(int h) { fb_frame_set_height(handle_, h); }
int format() const { return fb_frame_get_format(handle_); }
void set_format(int f) { fb_frame_set_format(handle_, f); }
int64_t pts() const { return fb_frame_get_pts(handle_); }
void set_pts(int64_t p) { fb_frame_set_pts(handle_, p); }
int64_t best_effort_timestamp() const
{
return fb_frame_get_best_effort_timestamp(handle_);
}
int nb_samples() const { return fb_frame_get_nb_samples(handle_); }
void set_nb_samples(int n) { fb_frame_set_nb_samples(handle_, n); }
int sample_rate() const { return fb_frame_get_sample_rate(handle_); }
void set_sample_rate(int r) { fb_frame_set_sample_rate(handle_, r); }
int color_range() const { return fb_frame_get_color_range(handle_); }
void set_color_range(int r) { fb_frame_set_color_range(handle_, r); }
int colorspace() const { return fb_frame_get_colorspace(handle_); }
void set_colorspace(int cs) { fb_frame_set_colorspace(handle_, cs); }
uint64_t channel_layout_mask() const
{
return fb_frame_get_channel_layout_mask(handle_);
}
void set_channel_layout_mask(uint64_t m)
{
fb_frame_set_channel_layout_mask(handle_, m);
}
bool is_hw() const { return fb_frame_is_hw(handle_) != 0; }
int hw_transfer_data(const AVFrame *src)
{
return fb_frame_hw_transfer_data(handle_, src->handle_);
}
int get_buffer(int align) { return fb_frame_get_buffer(handle_, align); }
int make_writable() { return fb_frame_make_writable(handle_); }
uint8_t *data(int plane) { return fb_frame_get_data(handle_, plane); }
const uint8_t *data(int plane) const
{
return fb_frame_get_data_const(handle_, plane);
}
void set_data(int plane, uint8_t *d)
{
fb_frame_set_data(handle_, plane, d);
}
int linesize(int plane) const
{
return fb_frame_get_linesize(handle_, plane);
}
void set_linesize(int plane, int l)
{
fb_frame_set_linesize(handle_, plane, l);
}
private:
FBFrame *handle_;
};
using AVFramePtr = std::shared_ptr<AVFrame>;
inline AVFramePtr create_av_frame_ptr(FBFrame *f)
{
return std::make_shared<AVFrame>(f);
}
inline AVFramePtr create_av_frame_ptr()
{
return std::make_shared<AVFrame>();
}
}
#endif // OAK_AVFRAMEPTR_H
@@ -0,0 +1,33 @@
#pragma once
// Transitional: engine/common/cancelableobject.h de-Qt target form. Header-only
// in the original; the only Qt dependency was the transitively included
// render/cancelatom.h, which oakrender provides for real. M-common folds this
// into oakcommon; until then this contract matches the original 1:1.
#include "cancelatom.h"
namespace olive {
class CancelableObject {
public:
CancelableObject() {}
virtual ~CancelableObject() = default;
void cancel()
{
cancel_.cancel();
CancelEvent();
}
CancelAtom *get_cancel_atom() { return &cancel_; }
bool is_cancelled() { return cancel_.is_cancelled(); }
protected:
virtual void CancelEvent() {}
private:
CancelAtom cancel_;
};
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
// Transitional: engine/common/jobtime.h de-Qt target form. Original kept a
// process-global mutex-protected counter; the atomic below preserves the same
// monotonic-unique semantics. oakcommon has no jobtime.h yet (M-common folds
// it in); renderjobtracker.h includes "common/jobtime.h".
#include <atomic>
#include <cstdint>
namespace olive {
class JobTime {
public:
JobTime() { acquire(); }
void acquire()
{
static std::atomic<uint64_t> index{ 0 };
value_ = index.fetch_add(1, std::memory_order_relaxed);
}
uint64_t value() const { return value_; }
bool operator==(const JobTime &rhs) const { return value_ == rhs.value_; }
bool operator!=(const JobTime &rhs) const { return value_ != rhs.value_; }
bool operator<(const JobTime &rhs) const { return value_ < rhs.value_; }
bool operator>(const JobTime &rhs) const { return value_ > rhs.value_; }
bool operator<=(const JobTime &rhs) const { return value_ <= rhs.value_; }
bool operator>=(const JobTime &rhs) const { return value_ >= rhs.value_; }
private:
uint64_t value_;
};
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
// Transitional stub for engine/config/config.h (still Qt-based, config 未拆分).
// Union of the src/node/transition stub and the render-facing surface:
// keeps the OAK_CONFIG* call shape; values are inert defaults until the
// config milestone wires the real store. operator[] returns a stored
// reference so writes (lutlibrary) compile; nothing is persisted. 只增不删。
#include <map>
#include <string>
#include "variant.h"
#ifndef QStringLiteral
#define QStringLiteral(x) x
#endif
namespace olive {
class ConfigValue : public olive::Variant {
public:
ConfigValue() = default;
ConfigValue(const std::string &s) : olive::Variant(s) {}
ConfigValue &operator=(const std::string &s)
{
olive::Variant::operator=(olive::Variant(s));
return *this;
}
bool toBool() const { return to_bool(); }
int toInt() const { return to_int(); }
uint64_t toULongLong() const { return to_u_long_long(); }
// rendermanager reads the graphics backend name through this
std::string toString() const { return to_string(); }
std::vector<std::string> toStringList() const { return to_string_list(); }
};
class Config {
public:
static Config &current() { static Config c; return c; }
ConfigValue &operator[](const std::string &key) { return values_[key]; }
private:
std::map<std::string, ConfigValue> values_;
};
}
#ifndef OAK_CONFIG
#define OAK_CONFIG(x) Config::current()[x]
#endif
#ifndef OAK_CONFIG_STR
#define OAK_CONFIG_STR(x) Config::current()[x]
#endif
+44
View File
@@ -0,0 +1,44 @@
#pragma once
// Transitional: engine/coreengine.h belongs to the facade layer and is not
// available to the de-Qt render/node libraries. Union of the surfaces
// oakrender (warn_cache_full, diskmanager.cpp) and oaknode (undo_stack,
// timecode display, clipboard) use; the real implementation lives on the
// facade side. Superset of the former src/node/transition stub.
#include <string>
#include "olive/core/util/timecodefunctions.h"
#include "undostack.h"
namespace olive
{
class EngineCore {
public:
static EngineCore *instance()
{
static EngineCore e;
return &e;
}
void warn_cache_full()
{
}
core::Timecode::Display get_timecode_display() const
{
return core::Timecode::k_timecode_seconds;
}
UndoStack *undo_stack()
{
return &undo_stack_;
}
static void copy_string_to_clipboard(const std::string &) {}
static std::string paste_string_from_clipboard() { return std::string(); }
private:
UndoStack undo_stack_;
};
}
@@ -0,0 +1,69 @@
#pragma once
// Transitional stub for engine/pluginSupport/oliveclip.h (real header still
// Qt-based, M9 处理). Only the surface render/plugin uses, with de-Qt'd
// boundary types (std::string / olive::VideoParams / TexturePtr). OFX
// HostSupport 交互签名一行不改。只增不删。
#include <mutex>
#include <string>
#include "ofxhImageEffect.h"
#include "ofxImageEffect.h"
#include "videoparams.h"
#include "render/texture.h"
namespace olive
{
namespace plugin
{
class OliveClipInstance : public OFX::Host::ImageEffect::ClipInstance {
public:
OFX::Host::ImageEffect::Image *getOutputImage(OfxTime time)
{
(void) time;
return nullptr;
}
const std::string &getUnmappedComponents() const override
{
static const std::string s;
return s;
}
OFX::Host::ImageEffect::Image *
getImage(OfxTime time, const OfxRectD *optional_bounds) override
{
(void) time;
(void) optional_bounds;
return nullptr;
}
void setRegionOfDefinition(OfxRectD region_of_definition, OfxTime time)
{
(void) region_of_definition;
(void) time;
}
void setParams(const VideoParams &params)
{
(void) params;
}
void setInputTexture(TexturePtr texture, OfxTime time,
bool readback = true)
{
(void) texture;
(void) time;
(void) readback;
}
void setOutputTexture(TexturePtr texture, OfxTime time)
{
(void) texture;
(void) time;
}
};
}
}
@@ -0,0 +1,69 @@
#pragma once
// Transitional stub for engine/pluginSupport/oliveplugininstance.h (real
// header still Qt-based, M9 处理). Only the surface render/plugin uses, with
// de-Qt'd boundary types. OFX HostSupport 交互签名一行不改。只增不删。
#include <memory>
#include <mutex>
#include "ofxhImageEffect.h"
#include "videoparams.h"
namespace olive
{
namespace plugin
{
class PluginNode;
class OlivePluginInstance : public OFX::Host::ImageEffect::Instance {
public:
void setVideoParam(VideoParams params)
{
(void) params;
}
// oaknode 侧契约(plugin.cpp)
void setNode(std::shared_ptr<PluginNode> node)
{
node_ = node;
}
std::shared_ptr<PluginNode> node() const
{
return node_;
}
void setOpenGLEnabled(bool enabled)
{
(void) enabled;
}
bool isCreated() const
{
return false;
}
int getNClips() const
{
return 0;
}
OFX::Host::ImageEffect::ClipInstance *getNthClip(int i)
{
(void) i;
return nullptr;
}
std::mutex &mutex()
{
return mutex_;
}
private:
std::mutex mutex_;
std::shared_ptr<PluginNode> node_;
};
}
}
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/backend/renderbackend_c.h" include to the real de-Qt
// oakrender header (src/render/src/backend/renderbackend_c.h).
#include "../../../src/backend/renderbackend_c.h"
@@ -0,0 +1,5 @@
#pragma once
// Bridge: oaknode still includes "render/colorprocessor.h". Route it to the
// real de-Qt oakrender header (src/render/src/colorprocessor.h) so both sides
// see the same class definition.
#include "../../src/colorprocessor.h"
@@ -0,0 +1,5 @@
#pragma once
// Bridge: oaknode still includes "render/job/colortransformjob.h". Route it
// to the real de-Qt oakrender header (src/render/src/job/colortransformjob.h)
// so both sides see the same class definition.
#include "../../../src/job/colortransformjob.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/job/pluginjob.h" include to the real de-Qt
// oakrender header (src/render/src/job/pluginjob.h).
#include "../../../src/job/pluginjob.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/job/shaderjob.h" include to the real de-Qt
// oakrender header (src/render/src/job/shaderjob.h).
#include "../../../src/job/shaderjob.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/opengl/openglcontext.h" include to the real de-Qt
// oakrender header (src/render/src/opengl/openglcontext.h).
#include "../../../src/opengl/openglcontext.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/opengl/openglcontextprovider.h" include to the real de-Qt
// oakrender header (src/render/src/opengl/openglcontextprovider.h).
#include "../../../src/opengl/openglcontextprovider.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/opengl/openglfunctions.h" include to the real de-Qt
// oakrender header (src/render/src/opengl/openglfunctions.h).
#include "../../../src/opengl/openglfunctions.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/opengl/openglrenderer.h" include to the real de-Qt
// oakrender header (src/render/src/opengl/openglrenderer.h).
#include "../../../src/opengl/openglrenderer.h"
+4
View File
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/renderer.h" include to the real de-Qt
// oakrender header (src/render/src/renderer.h).
#include "../../src/renderer.h"
@@ -0,0 +1,5 @@
#pragma once
// Bridge: oaknode still includes "render/shadercode.h". Route it to the
// real de-Qt oakrender header (src/render/src/shadercode.h) so both sides
// see the same class definition.
#include "../../src/shadercode.h"
+7
View File
@@ -0,0 +1,7 @@
#pragma once
// Bridge: oaknode still includes "render/texture.h". Route it to the real
// de-Qt oakrender header (src/render/src/texture.h) so both sides see the
// same class definition. samplebuffer.h is included first because oaknode's
// value.h relied on the old transition texture.h pulling it in transitively.
#include "render/samplebuffer.h"
#include "../../src/texture.h"
@@ -0,0 +1,4 @@
#pragma once
// Bridge: route the engine-style "render/vulkan/vulkanrenderer.h" include to the real de-Qt
// oakrender header (src/render/src/vulkan/vulkanrenderer.h).
#include "../../../src/vulkan/vulkanrenderer.h"