refactor(codec): de-Qt oakcodec and wrap it in a pure C ABI; switch common handles to refcounted value structs

- oakcodec: de-Qt all 20 sources (QThread decode loop -> std::thread,
  QObject/signals -> callbacks), pure C ABI in include/codec with
  refcounted neutral handles (OakFrame/OakDecoder/OakEncoder),
  framemanager moved in from render, frame_to_buffer/buffer_to_frame
  moved in from oakcommon oiioutils, codec->task via submit callback
  (M8 will register), all cross-module calls go through the other
  side's C API, -fvisibility=hidden + OAKCODEC_API
- oakcommon: handles become refcounted value structs
  {ctx, addref, release, abi_version} (FFmpeg-style), pass-by-value
  signatures, free() as release wrapper; init_from_native/get_native
  for copyable value objects; OakCommonXxx renamed to OakXxx
- oakcommon: add logging (log_debug/info/warning/critical with level
  filtering and sink injection) + printf-style oakcommon_log C wrapper
- oakrender: add CancelAtom C API family; complete
  oakrender_color_processor_convert_frame; fix get_processor() missing
  definition and OCIO env var lookup
- tests: oakcommon 174, oaknode 96, oakrender 42, oakcodec 18, all
  green in their standalone builds
This commit is contained in:
2026-08-06 18:50:07 +08:00
parent edbd3913af
commit 3d004c081b
127 changed files with 13760 additions and 1222 deletions
+200 -132
View File
@@ -23,10 +23,20 @@
#include <cstring>
#include "../src/videoparams.h"
#include "refcounted.h"
struct OakCommonVideoParams {
olive::VideoParams impl;
};
namespace
{
/**
* @brief Recover the boxed olive::VideoParams from a handle (NULL-safe).
*/
olive::VideoParams *vp(OakVideoParams params)
{
return oakcommon::handle_impl<olive::VideoParams>(params.ctx);
}
} // namespace
namespace
{
@@ -51,317 +61,345 @@ int get_rational(const olive::core::Rational &r, int *numerator,
} // namespace
OakCommonVideoParams *oakcommon_videoparams_init(void)
OakVideoParams oakcommon_videoparams_init(void)
{
try {
return new OakCommonVideoParams{olive::VideoParams()};
return oakcommon::make_handle<OakVideoParams>(
olive::VideoParams());
} catch (...) {
return nullptr;
OakVideoParams h = {};
return h;
}
}
OakCommonVideoParams *oakcommon_videoparams_init_basic(
OakVideoParams oakcommon_videoparams_init_basic(
int width, int height, int pixel_format, int nb_channels,
int pixel_aspect_num, int pixel_aspect_den, int interlacing, int divider)
{
try {
return new OakCommonVideoParams{olive::VideoParams(
width, height,
static_cast<olive::core::PixelFormat::Format>(pixel_format),
nb_channels,
olive::core::Rational(pixel_aspect_num, pixel_aspect_den),
static_cast<olive::VideoParams::Interlacing>(interlacing),
divider)};
return oakcommon::make_handle<OakVideoParams>(
olive::VideoParams(
width, height,
static_cast<olive::core::PixelFormat::Format>(pixel_format),
nb_channels,
olive::core::Rational(pixel_aspect_num, pixel_aspect_den),
static_cast<olive::VideoParams::Interlacing>(interlacing),
divider));
} catch (...) {
return nullptr;
OakVideoParams h = {};
return h;
}
}
OakCommonVideoParams *oakcommon_videoparams_init_with_time_base(
OakVideoParams oakcommon_videoparams_init_with_time_base(
int width, int height, int time_base_num, int time_base_den,
int pixel_format, int nb_channels, int pixel_aspect_num,
int pixel_aspect_den, int interlacing, int divider)
{
try {
return new OakCommonVideoParams{olive::VideoParams(
width, height,
olive::core::Rational(time_base_num, time_base_den),
static_cast<olive::core::PixelFormat::Format>(pixel_format),
nb_channels,
olive::core::Rational(pixel_aspect_num, pixel_aspect_den),
static_cast<olive::VideoParams::Interlacing>(interlacing),
divider)};
return oakcommon::make_handle<OakVideoParams>(
olive::VideoParams(
width, height,
olive::core::Rational(time_base_num, time_base_den),
static_cast<olive::core::PixelFormat::Format>(pixel_format),
nb_channels,
olive::core::Rational(pixel_aspect_num, pixel_aspect_den),
static_cast<olive::VideoParams::Interlacing>(interlacing),
divider));
} catch (...) {
return nullptr;
OakVideoParams h = {};
return h;
}
}
void oakcommon_videoparams_free(OakCommonVideoParams *params)
OakVideoParams oakcommon_videoparams_init_from_native(
const olive::VideoParams *src)
{
delete params;
if (!src) {
OakVideoParams h = {};
return h;
}
try {
return oakcommon::make_handle<OakVideoParams>(
olive::VideoParams(*src));
} catch (...) {
OakVideoParams h = {};
return h;
}
}
const olive::VideoParams *oakcommon_videoparams_get_native(
OakVideoParams params)
{
return vp(params);
}
void oakcommon_videoparams_free(OakVideoParams *params)
{
oakcommon::free_handle(params);
}
#define OAKCOMMON_VIDEOPARAMS_INT_GETTER(name, expr) \
int oakcommon_videoparams_get_##name(OakCommonVideoParams *params, \
int oakcommon_videoparams_get_##name(OakVideoParams params, \
int *out) \
{ \
if (!params || !out) \
if (!vp(params) || !out) \
return OAKCOMMON_E_INVALID; \
*out = (expr); \
return OAKCOMMON_OK; \
}
#define OAKCOMMON_VIDEOPARAMS_INT_SETTER(name, stmt) \
int oakcommon_videoparams_set_##name(OakCommonVideoParams *params, \
int oakcommon_videoparams_set_##name(OakVideoParams params, \
int value) \
{ \
if (!params) \
if (!vp(params)) \
return OAKCOMMON_E_INVALID; \
stmt; \
return OAKCOMMON_OK; \
}
OAKCOMMON_VIDEOPARAMS_INT_GETTER(width, params->impl.width())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(width, params->impl.set_width(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(height, params->impl.height())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(height, params->impl.set_height(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(depth, params->impl.depth())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(depth, params->impl.set_depth(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(is_3d, params->impl.is_3d() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_GETTER(format, static_cast<int>(params->impl.format()))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(width, vp(params)->width())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(width, vp(params)->set_width(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(height, vp(params)->height())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(height, vp(params)->set_height(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(depth, vp(params)->depth())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(depth, vp(params)->set_depth(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(is_3d, vp(params)->is_3d() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_GETTER(format, static_cast<int>(vp(params)->format()))
OAKCOMMON_VIDEOPARAMS_INT_SETTER(
format, params->impl.set_format(
format, vp(params)->set_format(
static_cast<olive::core::PixelFormat::Format>(value)))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(channel_count, params->impl.channel_count())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(channel_count, vp(params)->channel_count())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(channel_count,
params->impl.set_channel_count(value))
vp(params)->set_channel_count(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(interlacing,
static_cast<int>(params->impl.interlacing()))
static_cast<int>(vp(params)->interlacing()))
OAKCOMMON_VIDEOPARAMS_INT_SETTER(
interlacing,
params->impl.set_interlacing(
vp(params)->set_interlacing(
static_cast<olive::VideoParams::Interlacing>(value)))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(divider, params->impl.divider())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(divider, params->impl.set_divider(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(enabled, params->impl.enabled() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_SETTER(enabled, params->impl.set_enabled(value != 0))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(stream_index, params->impl.stream_index())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(divider, vp(params)->divider())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(divider, vp(params)->set_divider(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(enabled, vp(params)->enabled() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_SETTER(enabled, vp(params)->set_enabled(value != 0))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(stream_index, vp(params)->stream_index())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(stream_index,
params->impl.set_stream_index(value))
vp(params)->set_stream_index(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(video_type,
static_cast<int>(params->impl.video_type()))
static_cast<int>(vp(params)->video_type()))
OAKCOMMON_VIDEOPARAMS_INT_SETTER(
video_type,
params->impl.set_video_type(static_cast<olive::VideoParams::Type>(value)))
vp(params)->set_video_type(static_cast<olive::VideoParams::Type>(value)))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(premultiplied_alpha,
params->impl.premultiplied_alpha() ? 1 : 0)
vp(params)->premultiplied_alpha() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_SETTER(premultiplied_alpha,
params->impl.set_premultiplied_alpha(
vp(params)->set_premultiplied_alpha(
value != 0))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(color_range,
static_cast<int>(params->impl.color_range()))
static_cast<int>(vp(params)->color_range()))
OAKCOMMON_VIDEOPARAMS_INT_SETTER(
color_range, params->impl.set_color_range(
color_range, vp(params)->set_color_range(
static_cast<olive::VideoParams::ColorRange>(value)))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(color_primaries,
params->impl.color_primaries())
vp(params)->color_primaries())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(color_primaries,
params->impl.set_color_primaries(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(color_transfer, params->impl.color_transfer())
vp(params)->set_color_primaries(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(color_transfer, vp(params)->color_transfer())
OAKCOMMON_VIDEOPARAMS_INT_SETTER(color_transfer,
params->impl.set_color_transfer(value))
vp(params)->set_color_transfer(value))
OAKCOMMON_VIDEOPARAMS_INT_GETTER(square_pixel_width,
params->impl.square_pixel_width())
vp(params)->square_pixel_width())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(effective_width,
params->impl.effective_width())
vp(params)->effective_width())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(effective_height,
params->impl.effective_height())
vp(params)->effective_height())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(effective_depth,
params->impl.effective_depth())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(is_valid, params->impl.is_valid() ? 1 : 0)
vp(params)->effective_depth())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(is_valid, vp(params)->is_valid() ? 1 : 0)
OAKCOMMON_VIDEOPARAMS_INT_GETTER(bytes_per_channel,
params->impl.get_bytes_per_channel())
vp(params)->get_bytes_per_channel())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(bytes_per_pixel,
params->impl.get_bytes_per_pixel())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(buffer_size, params->impl.get_buffer_size())
vp(params)->get_bytes_per_pixel())
OAKCOMMON_VIDEOPARAMS_INT_GETTER(buffer_size, vp(params)->get_buffer_size())
int oakcommon_videoparams_get_x(OakCommonVideoParams *params, float *x)
int oakcommon_videoparams_get_x(OakVideoParams params, float *x)
{
if (!params || !x)
if (!vp(params) || !x)
return OAKCOMMON_E_INVALID;
*x = params->impl.x();
*x = vp(params)->x();
return OAKCOMMON_OK;
}
int oakcommon_videoparams_set_x(OakCommonVideoParams *params, float x)
int oakcommon_videoparams_set_x(OakVideoParams params, float x)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_x(x);
vp(params)->set_x(x);
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_y(OakCommonVideoParams *params, float *y)
int oakcommon_videoparams_get_y(OakVideoParams params, float *y)
{
if (!params || !y)
if (!vp(params) || !y)
return OAKCOMMON_E_INVALID;
*y = params->impl.y();
*y = vp(params)->y();
return OAKCOMMON_OK;
}
int oakcommon_videoparams_set_y(OakCommonVideoParams *params, float y)
int oakcommon_videoparams_set_y(OakVideoParams params, float y)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_y(y);
vp(params)->set_y(y);
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_start_time(OakCommonVideoParams *params,
int oakcommon_videoparams_get_start_time(OakVideoParams params,
int64_t *start_time)
{
if (!params || !start_time)
if (!vp(params) || !start_time)
return OAKCOMMON_E_INVALID;
*start_time = params->impl.start_time();
*start_time = vp(params)->start_time();
return OAKCOMMON_OK;
}
int oakcommon_videoparams_set_start_time(OakCommonVideoParams *params,
int oakcommon_videoparams_set_start_time(OakVideoParams params,
int64_t start_time)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_start_time(start_time);
vp(params)->set_start_time(start_time);
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_duration(OakCommonVideoParams *params,
int oakcommon_videoparams_get_duration(OakVideoParams params,
int64_t *duration)
{
if (!params || !duration)
if (!vp(params) || !duration)
return OAKCOMMON_E_INVALID;
*duration = params->impl.duration();
*duration = vp(params)->duration();
return OAKCOMMON_OK;
}
int oakcommon_videoparams_set_duration(OakCommonVideoParams *params,
int oakcommon_videoparams_set_duration(OakVideoParams params,
int64_t duration)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_duration(duration);
vp(params)->set_duration(duration);
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_time_base(OakCommonVideoParams *params,
int oakcommon_videoparams_get_time_base(OakVideoParams params,
int *numerator, int *denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
return get_rational(params->impl.time_base(), numerator, denominator);
return get_rational(vp(params)->time_base(), numerator, denominator);
}
int oakcommon_videoparams_set_time_base(OakCommonVideoParams *params,
int oakcommon_videoparams_set_time_base(OakVideoParams params,
int numerator, int denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_time_base(olive::core::Rational(numerator, denominator));
vp(params)->set_time_base(olive::core::Rational(numerator, denominator));
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_frame_rate(OakCommonVideoParams *params,
int oakcommon_videoparams_get_frame_rate(OakVideoParams params,
int *numerator, int *denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
return get_rational(params->impl.frame_rate(), numerator, denominator);
return get_rational(vp(params)->frame_rate(), numerator, denominator);
}
int oakcommon_videoparams_set_frame_rate(OakCommonVideoParams *params,
int oakcommon_videoparams_set_frame_rate(OakVideoParams params,
int numerator, int denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_frame_rate(olive::core::Rational(numerator, denominator));
vp(params)->set_frame_rate(olive::core::Rational(numerator, denominator));
return OAKCOMMON_OK;
}
int oakcommon_videoparams_frame_rate_as_time_base(OakCommonVideoParams *params,
int oakcommon_videoparams_frame_rate_as_time_base(OakVideoParams params,
int *numerator,
int *denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
return get_rational(params->impl.frame_rate_as_time_base(), numerator,
return get_rational(vp(params)->frame_rate_as_time_base(), numerator,
denominator);
}
int oakcommon_videoparams_get_pixel_aspect_ratio(OakCommonVideoParams *params,
int oakcommon_videoparams_get_pixel_aspect_ratio(OakVideoParams params,
int *numerator,
int *denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
return get_rational(params->impl.pixel_aspect_ratio(), numerator,
return get_rational(vp(params)->pixel_aspect_ratio(), numerator,
denominator);
}
int oakcommon_videoparams_set_pixel_aspect_ratio(OakCommonVideoParams *params,
int oakcommon_videoparams_set_pixel_aspect_ratio(OakVideoParams params,
int numerator, int denominator)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
params->impl.set_pixel_aspect_ratio(
vp(params)->set_pixel_aspect_ratio(
olive::core::Rational(numerator, denominator));
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_colorspace(OakCommonVideoParams *params,
int oakcommon_videoparams_get_colorspace(OakVideoParams params,
char *buf, int buf_size)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
try {
return copy_string(params->impl.colorspace(), buf, buf_size);
return copy_string(vp(params)->colorspace(), buf, buf_size);
} catch (...) {
return OAKCOMMON_E_FAILED;
}
}
int oakcommon_videoparams_set_colorspace(OakCommonVideoParams *params,
int oakcommon_videoparams_set_colorspace(OakVideoParams params,
const char *colorspace)
{
if (!params || !colorspace)
if (!vp(params) || !colorspace)
return OAKCOMMON_E_INVALID;
params->impl.set_colorspace(colorspace);
vp(params)->set_colorspace(colorspace);
return OAKCOMMON_OK;
}
int oakcommon_videoparams_get_time_in_timebase_units(
OakCommonVideoParams *params, int time_num, int time_den,
OakVideoParams params, int time_num, int time_den,
int64_t *timestamp)
{
if (!params || !timestamp)
if (!vp(params) || !timestamp)
return OAKCOMMON_E_INVALID;
*timestamp = params->impl.get_time_in_timebase_units(
*timestamp = vp(params)->get_time_in_timebase_units(
olive::core::Rational(time_num, time_den));
return OAKCOMMON_OK;
}
int oakcommon_videoparams_equals(OakCommonVideoParams *params,
OakCommonVideoParams *other, int *equal)
int oakcommon_videoparams_equals(OakVideoParams params,
OakVideoParams other, int *equal)
{
if (!params || !other || !equal)
if (!vp(params) || !vp(other) || !equal)
return OAKCOMMON_E_INVALID;
*equal = (params->impl == other->impl) ? 1 : 0;
*equal = (*vp(params) == *vp(other)) ? 1 : 0;
return OAKCOMMON_OK;
}
int oakcommon_videoparams_load_xml(OakCommonVideoParams *params,
int oakcommon_videoparams_load_xml(OakVideoParams params,
const char *xml)
{
if (!params || !xml)
if (!vp(params) || !xml)
return OAKCOMMON_E_INVALID;
try {
olive::XmlStreamReader reader(xml);
@@ -370,22 +408,22 @@ int oakcommon_videoparams_load_xml(OakCommonVideoParams *params,
// Position on the root element; load() consumes its children.
if (!olive::xml_read_next_start_element(&reader))
return OAKCOMMON_E_FAILED;
params->impl.load(&reader);
vp(params)->load(&reader);
return OAKCOMMON_OK;
} catch (...) {
return OAKCOMMON_E_FAILED;
}
}
int oakcommon_videoparams_save_xml(OakCommonVideoParams *params, char *buf,
int oakcommon_videoparams_save_xml(OakVideoParams params, char *buf,
int buf_size)
{
if (!params)
if (!vp(params))
return OAKCOMMON_E_INVALID;
try {
olive::XmlStreamWriter writer;
writer.write_start_element("videoparams");
params->impl.save(&writer);
vp(params)->save(&writer);
writer.write_end_element();
return copy_string(writer.output(), buf, buf_size);
} catch (...) {
@@ -476,3 +514,33 @@ int oakcommon_videoparams_frame_rate_to_string(int numerator, int denominator,
return OAKCOMMON_E_FAILED;
}
}
static olive::PixelFormat convert_to_olive_format(OakPixelFormat format)
{
switch (format) {
case OAKCOMMON_PIXEL_FORMAT_INVALID:
return olive::PixelFormat::invalid;
case OAKCOMMON_PIXEL_FORMAT_COUNT:
return olive::PixelFormat::count;
case OAKCOMMON_PIXEL_FORMAT_U8:
return olive::PixelFormat::u8;
case OAKCOMMON_PIXEL_FORMAT_U10:
return olive::PixelFormat::u10;
case OAKCOMMON_PIXEL_FORMAT_U16:
return olive::PixelFormat::u16;
case OAKCOMMON_PIXEL_FORMAT_F16:
return olive::PixelFormat::f16;
case OAKCOMMON_PIXEL_FORMAT_F32:
return olive::PixelFormat::f32;
}
return olive::PixelFormat::invalid;
}
int oakcommon_videoparams_static_get_bytes_per_channel(OakPixelFormat format)
{
return olive::VideoParams::get_bytes_per_channel(convert_to_olive_format(format));
}
int oakcommon_videoparams_static_get_bytes_per_pixel(OakPixelFormat format, int channels)
{
return olive::VideoParams::get_bytes_per_pixel(convert_to_olive_format(format), channels);
}