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:
@@ -23,10 +23,15 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "../src/colortransform.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonColorTransform {
|
||||
olive::ColorTransform impl;
|
||||
};
|
||||
/**
|
||||
* @brief Recover the boxed olive::ColorTransform from a handle (NULL-safe).
|
||||
*/
|
||||
static olive::ColorTransform *ct(OakColorTransform transform)
|
||||
{
|
||||
return oakcommon::handle_impl<olive::ColorTransform>(transform.ctx);
|
||||
}
|
||||
|
||||
static int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
{
|
||||
@@ -36,89 +41,116 @@ static int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
return needed;
|
||||
}
|
||||
|
||||
OakCommonColorTransform *oakcommon_colortransform_init_output(
|
||||
OakColorTransform oakcommon_colortransform_init_output(
|
||||
const char *output)
|
||||
{
|
||||
OakColorTransform h = {};
|
||||
if (!output)
|
||||
return nullptr;
|
||||
return h;
|
||||
try {
|
||||
return new OakCommonColorTransform{
|
||||
olive::ColorTransform(std::string(output))};
|
||||
return oakcommon::make_handle<OakColorTransform>(
|
||||
olive::ColorTransform(std::string(output)));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakColorTransform empty = {};
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
OakCommonColorTransform *oakcommon_colortransform_init_display(
|
||||
OakColorTransform oakcommon_colortransform_init_display(
|
||||
const char *display, const char *view, const char *look)
|
||||
{
|
||||
OakColorTransform h = {};
|
||||
if (!display || !view || !look)
|
||||
return nullptr;
|
||||
return h;
|
||||
try {
|
||||
return new OakCommonColorTransform{olive::ColorTransform(
|
||||
std::string(display), std::string(view), std::string(look))};
|
||||
return oakcommon::make_handle<OakColorTransform>(
|
||||
olive::ColorTransform(std::string(display), std::string(view),
|
||||
std::string(look)));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakColorTransform empty = {};
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_colortransform_free(OakCommonColorTransform *transform)
|
||||
OakColorTransform oakcommon_colortransform_init_from_native(
|
||||
const olive::ColorTransform *src)
|
||||
{
|
||||
delete transform;
|
||||
if (!src) {
|
||||
OakColorTransform h = {};
|
||||
return h;
|
||||
}
|
||||
try {
|
||||
return oakcommon::make_handle<OakColorTransform>(
|
||||
olive::ColorTransform(*src));
|
||||
} catch (...) {
|
||||
OakColorTransform h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_is_display(OakCommonColorTransform *transform,
|
||||
const olive::ColorTransform *oakcommon_colortransform_get_native(
|
||||
OakColorTransform transform)
|
||||
{
|
||||
return ct(transform);
|
||||
}
|
||||
|
||||
void oakcommon_colortransform_free(OakColorTransform *transform)
|
||||
{
|
||||
oakcommon::free_handle(transform);
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_is_display(OakColorTransform transform,
|
||||
int *is_display)
|
||||
{
|
||||
if (!transform || !is_display)
|
||||
if (!ct(transform) || !is_display)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
*is_display = transform->impl.is_display() ? 1 : 0;
|
||||
*is_display = ct(transform)->is_display() ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_get_display(OakCommonColorTransform *transform,
|
||||
int oakcommon_colortransform_get_display(OakColorTransform transform,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!transform)
|
||||
if (!ct(transform))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(transform->impl.display(), buf, buf_size);
|
||||
return copy_string(ct(transform)->display(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_get_output(OakCommonColorTransform *transform,
|
||||
int oakcommon_colortransform_get_output(OakColorTransform transform,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!transform)
|
||||
if (!ct(transform))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(transform->impl.output(), buf, buf_size);
|
||||
return copy_string(ct(transform)->output(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_get_view(OakCommonColorTransform *transform,
|
||||
int oakcommon_colortransform_get_view(OakColorTransform transform,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!transform)
|
||||
if (!ct(transform))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(transform->impl.view(), buf, buf_size);
|
||||
return copy_string(ct(transform)->view(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_colortransform_get_look(OakCommonColorTransform *transform,
|
||||
int oakcommon_colortransform_get_look(OakColorTransform transform,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!transform)
|
||||
if (!ct(transform))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(transform->impl.look(), buf, buf_size);
|
||||
return copy_string(ct(transform)->look(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
@@ -26,43 +26,79 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../src/commandlineparser.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonCommandLineParser {
|
||||
CommandLineParser impl;
|
||||
};
|
||||
namespace
|
||||
{
|
||||
|
||||
struct OakCommonCommandLineOption {
|
||||
/**
|
||||
* @brief State boxed behind an option handle's ctx pointer.
|
||||
*
|
||||
* The option pointer is borrowed: the option itself is owned by the
|
||||
* parser, so releasing the box never destroys it.
|
||||
*/
|
||||
struct OptionState {
|
||||
CommandLineParser::Option *option;
|
||||
};
|
||||
|
||||
struct OakCommonCommandLinePositionalArgument {
|
||||
/**
|
||||
* @brief State boxed behind a positional-argument handle's ctx pointer.
|
||||
*
|
||||
* The argument pointer is borrowed: the argument itself is owned by the
|
||||
* parser, so releasing the box never destroys it.
|
||||
*/
|
||||
struct PositionalArgumentState {
|
||||
CommandLineParser::PositionalArgument *argument;
|
||||
};
|
||||
|
||||
OakCommonCommandLineParser *oakcommon_commandlineparser_init(void)
|
||||
CommandLineParser *clp(OakCommandLineParser parser)
|
||||
{
|
||||
return oakcommon::handle_impl<CommandLineParser>(parser.ctx);
|
||||
}
|
||||
|
||||
CommandLineParser::Option *clo(OakCommandLineOption option)
|
||||
{
|
||||
OptionState *state =
|
||||
oakcommon::handle_impl<OptionState>(option.ctx);
|
||||
return state ? state->option : nullptr;
|
||||
}
|
||||
|
||||
CommandLineParser::PositionalArgument *clpa(
|
||||
OakCommandLinePositionalArgument argument)
|
||||
{
|
||||
PositionalArgumentState *state =
|
||||
oakcommon::handle_impl<PositionalArgumentState>(argument.ctx);
|
||||
return state ? state->argument : nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OakCommandLineParser oakcommon_commandlineparser_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonCommandLineParser();
|
||||
return oakcommon::make_handle_in_place<OakCommandLineParser,
|
||||
CommandLineParser>();
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
OakCommandLineParser h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_commandlineparser_free(OakCommonCommandLineParser *parser)
|
||||
void oakcommon_commandlineparser_free(OakCommandLineParser *parser)
|
||||
{
|
||||
delete parser;
|
||||
oakcommon::free_handle(parser);
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_set_app_info(OakCommonCommandLineParser *parser,
|
||||
int oakcommon_commandlineparser_set_app_info(OakCommandLineParser parser,
|
||||
const char *name,
|
||||
const char *version)
|
||||
{
|
||||
if (!parser || !name) {
|
||||
if (!clp(parser) || !name) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
parser->impl.set_app_info(name, version ? version : "");
|
||||
clp(parser)->set_app_info(name, version ? version : "");
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
@@ -70,11 +106,11 @@ int oakcommon_commandlineparser_set_app_info(OakCommonCommandLineParser *parser,
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_add_option(
|
||||
OakCommonCommandLineParser *parser, const char *const *names, int name_count,
|
||||
OakCommandLineParser parser, const char *const *names, int name_count,
|
||||
const char *description, int takes_arg, const char *arg_placeholder,
|
||||
int hidden, OakCommonCommandLineOption **out_option)
|
||||
int hidden, OakCommandLineOption *out_option)
|
||||
{
|
||||
if (!parser || !names || name_count <= 0) {
|
||||
if (!clp(parser) || !names || name_count <= 0) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -88,18 +124,16 @@ int oakcommon_commandlineparser_add_option(
|
||||
strings.emplace_back(names[i]);
|
||||
}
|
||||
|
||||
const CommandLineParser::Option *option = parser->impl.add_option(
|
||||
const CommandLineParser::Option *option = clp(parser)->add_option(
|
||||
strings, description ? description : "", takes_arg != 0,
|
||||
arg_placeholder ? arg_placeholder : "", hidden != 0);
|
||||
|
||||
if (out_option) {
|
||||
auto *handle =
|
||||
new (std::nothrow) OakCommonCommandLineOption();
|
||||
if (!handle) {
|
||||
*out_option = oakcommon::make_handle<OakCommandLineOption>(
|
||||
OptionState{const_cast<CommandLineParser::Option *>(option)});
|
||||
if (!out_option->ctx) {
|
||||
return OAKCOMMON_E_NOMEM;
|
||||
}
|
||||
handle->option = const_cast<CommandLineParser::Option *>(option);
|
||||
*out_option = handle;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
@@ -109,28 +143,28 @@ int oakcommon_commandlineparser_add_option(
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_add_positional_argument(
|
||||
OakCommonCommandLineParser *parser, const char *name,
|
||||
OakCommandLineParser parser, const char *name,
|
||||
const char *description, int required,
|
||||
OakCommonCommandLinePositionalArgument **out_argument)
|
||||
OakCommandLinePositionalArgument *out_argument)
|
||||
{
|
||||
if (!parser || !name) {
|
||||
if (!clp(parser) || !name) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
const CommandLineParser::PositionalArgument *argument =
|
||||
parser->impl.add_positional_argument(
|
||||
clp(parser)->add_positional_argument(
|
||||
name, description ? description : "", required != 0);
|
||||
|
||||
if (out_argument) {
|
||||
auto *handle =
|
||||
new (std::nothrow) OakCommonCommandLinePositionalArgument();
|
||||
if (!handle) {
|
||||
*out_argument =
|
||||
oakcommon::make_handle<OakCommandLinePositionalArgument>(
|
||||
PositionalArgumentState{
|
||||
const_cast<CommandLineParser::PositionalArgument *>(
|
||||
argument)});
|
||||
if (!out_argument->ctx) {
|
||||
return OAKCOMMON_E_NOMEM;
|
||||
}
|
||||
handle->argument =
|
||||
const_cast<CommandLineParser::PositionalArgument *>(argument);
|
||||
*out_argument = handle;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
@@ -139,10 +173,10 @@ int oakcommon_commandlineparser_add_positional_argument(
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_process(OakCommonCommandLineParser *parser,
|
||||
int oakcommon_commandlineparser_process(OakCommandLineParser parser,
|
||||
const char *const *argv, int argc)
|
||||
{
|
||||
if (!parser || !argv || argc < 0) {
|
||||
if (!clp(parser) || !argv || argc < 0) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -153,37 +187,37 @@ int oakcommon_commandlineparser_process(OakCommonCommandLineParser *parser,
|
||||
args.emplace_back(argv[i] ? argv[i] : "");
|
||||
}
|
||||
|
||||
parser->impl.process(args);
|
||||
clp(parser)->process(args);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_print_help(OakCommonCommandLineParser *parser,
|
||||
int oakcommon_commandlineparser_print_help(OakCommandLineParser parser,
|
||||
const char *filename)
|
||||
{
|
||||
if (!parser || !filename) {
|
||||
if (!clp(parser) || !filename) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
parser->impl.print_help(filename);
|
||||
clp(parser)->print_help(filename);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_is_set(OakCommonCommandLineOption *option,
|
||||
int oakcommon_commandlineoption_is_set(OakCommandLineOption option,
|
||||
bool *is_set)
|
||||
{
|
||||
if (!option || !option->option || !is_set) {
|
||||
if (!clo(option) || !is_set) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*is_set = option->option->is_set();
|
||||
*is_set = clo(option)->is_set();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
@@ -212,29 +246,29 @@ static int copy_setting(const std::string &value, char *buf, int buf_size)
|
||||
return required;
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_get_setting(OakCommonCommandLineOption *option,
|
||||
int oakcommon_commandlineoption_get_setting(OakCommandLineOption option,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!option || !option->option) {
|
||||
if (!clo(option)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return copy_setting(option->option->get_setting(), buf, buf_size);
|
||||
return copy_setting(clo(option)->get_setting(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_set_setting(OakCommonCommandLineOption *option,
|
||||
int oakcommon_commandlineoption_set_setting(OakCommandLineOption option,
|
||||
const char *value)
|
||||
{
|
||||
if (!option || !option->option || !value) {
|
||||
if (!clo(option) || !value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
option->option->set_setting(value);
|
||||
clo(option)->set_setting(value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
@@ -242,41 +276,41 @@ int oakcommon_commandlineoption_set_setting(OakCommonCommandLineOption *option,
|
||||
}
|
||||
|
||||
int oakcommon_commandlinepositionalargument_get_setting(
|
||||
OakCommonCommandLinePositionalArgument *argument, char *buf, int buf_size)
|
||||
OakCommandLinePositionalArgument argument, char *buf, int buf_size)
|
||||
{
|
||||
if (!argument || !argument->argument) {
|
||||
if (!clpa(argument)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return copy_setting(argument->argument->get_setting(), buf, buf_size);
|
||||
return copy_setting(clpa(argument)->get_setting(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlinepositionalargument_set_setting(
|
||||
OakCommonCommandLinePositionalArgument *argument, const char *value)
|
||||
OakCommandLinePositionalArgument argument, const char *value)
|
||||
{
|
||||
if (!argument || !argument->argument || !value) {
|
||||
if (!clpa(argument) || !value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
argument->argument->set_setting(value);
|
||||
clpa(argument)->set_setting(value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_commandlineoption_free(OakCommonCommandLineOption *option)
|
||||
void oakcommon_commandlineoption_free(OakCommandLineOption *option)
|
||||
{
|
||||
delete option;
|
||||
oakcommon::free_handle(option);
|
||||
}
|
||||
|
||||
void oakcommon_commandlinepositionalargument_free(
|
||||
OakCommonCommandLinePositionalArgument *argument)
|
||||
OakCommandLinePositionalArgument *argument)
|
||||
{
|
||||
delete argument;
|
||||
oakcommon::free_handle(argument);
|
||||
}
|
||||
|
||||
@@ -22,25 +22,47 @@
|
||||
|
||||
#include "../src/current.h"
|
||||
|
||||
struct OakCommonCurrent {
|
||||
Current *current;
|
||||
};
|
||||
|
||||
OakCommonCurrent *oakcommon_current_instance(void)
|
||||
namespace
|
||||
{
|
||||
static OakCommonCurrent handle = { &Current::get_instance() };
|
||||
return &handle;
|
||||
|
||||
/**
|
||||
* @brief No-op addref/release for the singleton: it is never destroyed.
|
||||
*/
|
||||
void singleton_noop(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
void oakcommon_current_free(OakCommonCurrent *self)
|
||||
/**
|
||||
* @brief Recover the Current singleton from a handle (NULL-safe).
|
||||
*/
|
||||
Current *current_of(OakCurrent self)
|
||||
{
|
||||
// No-op: the handle wraps a process-wide singleton.
|
||||
return static_cast<Current *>(self.ctx);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OakCurrent oakcommon_current_instance(void)
|
||||
{
|
||||
OakCurrent h = {};
|
||||
h.ctx = &Current::get_instance();
|
||||
h.addref = &singleton_noop;
|
||||
h.release = &singleton_noop;
|
||||
h.abi_version = OAKCOMMON_ABI_VERSION;
|
||||
return h;
|
||||
}
|
||||
|
||||
void oakcommon_current_free(OakCurrent *self)
|
||||
{
|
||||
// No-op: the handle wraps a process-wide singleton whose release()
|
||||
// intentionally never destroys anything.
|
||||
(void)self;
|
||||
}
|
||||
|
||||
static int current_set(Current *current,
|
||||
void (Current::*set_fn)(std::shared_ptr<void>),
|
||||
void *obj, OakCommonDestroyFn destroy)
|
||||
void *obj, OakDestroyFn destroy)
|
||||
{
|
||||
try {
|
||||
std::shared_ptr<void> value;
|
||||
@@ -70,78 +92,78 @@ static int current_get(Current *current,
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_current_set_video_params(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
int oakcommon_current_set_video_params(OakCurrent self, void *obj,
|
||||
OakDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
if (!current_of(self))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_current_video_params,
|
||||
return current_set(current_of(self), &Current::set_current_video_params,
|
||||
obj, destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_audio_params(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
int oakcommon_current_set_audio_params(OakCurrent self, void *obj,
|
||||
OakDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
if (!current_of(self))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_current_audio_params,
|
||||
return current_set(current_of(self), &Current::set_current_audio_params,
|
||||
obj, destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_plugin_host(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
int oakcommon_current_set_plugin_host(OakCurrent self, void *obj,
|
||||
OakDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
if (!current_of(self))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_plugin_host, obj,
|
||||
return current_set(current_of(self), &Current::set_plugin_host, obj,
|
||||
destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_plugin_cache(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
int oakcommon_current_set_plugin_cache(OakCurrent self, void *obj,
|
||||
OakDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
if (!current_of(self))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_plugin_cache, obj,
|
||||
return current_set(current_of(self), &Current::set_plugin_cache, obj,
|
||||
destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_video_params(OakCommonCurrent *self, void **out)
|
||||
int oakcommon_current_get_video_params(OakCurrent self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
if (!current_of(self) || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::current_video_params,
|
||||
return current_get(current_of(self), &Current::current_video_params,
|
||||
out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_audio_params(OakCommonCurrent *self, void **out)
|
||||
int oakcommon_current_get_audio_params(OakCurrent self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
if (!current_of(self) || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::current_audio_params,
|
||||
return current_get(current_of(self), &Current::current_audio_params,
|
||||
out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_plugin_host(OakCommonCurrent *self, void **out)
|
||||
int oakcommon_current_get_plugin_host(OakCurrent self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
if (!current_of(self) || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::plugin_host, out);
|
||||
return current_get(current_of(self), &Current::plugin_host, out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_plugin_cache(OakCommonCurrent *self, void **out)
|
||||
int oakcommon_current_get_plugin_cache(OakCurrent self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
if (!current_of(self) || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::plugin_cache, out);
|
||||
return current_get(current_of(self), &Current::plugin_cache, out);
|
||||
}
|
||||
|
||||
int oakcommon_current_is_interactive(OakCommonCurrent *self, int *out)
|
||||
int oakcommon_current_is_interactive(OakCurrent self, int *out)
|
||||
{
|
||||
if (!self || !out)
|
||||
if (!current_of(self) || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*out = self->current->interactive() ? 1 : 0;
|
||||
*out = current_of(self)->interactive() ? 1 : 0;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
|
||||
#include "../src/debug.h"
|
||||
|
||||
int oakcommon_debug_log(int level, const char *msg)
|
||||
@@ -43,3 +46,68 @@ int oakcommon_debug_level_name(int level, char *buf, int buf_size)
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_log(int level, const char *fmt, ...)
|
||||
{
|
||||
if (!fmt)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
va_list sizing;
|
||||
va_copy(sizing, args);
|
||||
int needed = vsnprintf(nullptr, 0, fmt, sizing);
|
||||
va_end(sizing);
|
||||
|
||||
if (needed < 0) {
|
||||
va_end(args);
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
std::string msg;
|
||||
try {
|
||||
// Dynamically sized: arbitrary message length, no truncation,
|
||||
// no fixed stack buffer.
|
||||
std::vector<char> buf(static_cast<size_t>(needed) + 1);
|
||||
vsnprintf(buf.data(), buf.size(), fmt, args);
|
||||
msg.assign(buf.data(), static_cast<size_t>(needed));
|
||||
} catch (...) {
|
||||
va_end(args);
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
try {
|
||||
olive::log_message(level, msg);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_log_set_level(int level)
|
||||
{
|
||||
if (level < OAKCOMMON_DEBUG_DEBUG || level > OAKCOMMON_DEBUG_FATAL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
olive::set_log_level(static_cast<olive::DebugLevel>(level));
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_log_get_level(int *out_level)
|
||||
{
|
||||
if (!out_level)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out_level = static_cast<int>(olive::get_log_level());
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
@@ -24,11 +24,21 @@
|
||||
#include <string>
|
||||
|
||||
#include "../src/filefunctions.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonFileFunctions {
|
||||
int unused; /**< Stateless family; handle kept for API uniformity. */
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Stateless family; the boxed object is empty and only exists so
|
||||
* the handle has something to reference-count.
|
||||
*/
|
||||
struct FileFunctionsState {
|
||||
int unused;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -54,25 +64,27 @@ bool is_valid_string_out(const char *buf, int buf_size)
|
||||
|
||||
} // namespace
|
||||
|
||||
OakCommonFileFunctions *oakcommon_filefunctions_init(void)
|
||||
OakFileFunctions oakcommon_filefunctions_init(void)
|
||||
{
|
||||
try {
|
||||
return new OakCommonFileFunctions{0};
|
||||
return oakcommon::make_handle<OakFileFunctions>(
|
||||
FileFunctionsState{0});
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakFileFunctions h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_filefunctions_free(OakCommonFileFunctions *self)
|
||||
void oakcommon_filefunctions_free(OakFileFunctions *self)
|
||||
{
|
||||
delete self;
|
||||
oakcommon::free_handle(self);
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_unique_file_identifier(
|
||||
OakCommonFileFunctions *self, const char *filename, char *buf,
|
||||
OakFileFunctions self, const char *filename, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr ||
|
||||
if (self.ctx == nullptr || filename == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -87,9 +99,9 @@ int oakcommon_filefunctions_get_unique_file_identifier(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_configuration_location(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
OakFileFunctions self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
if (self.ctx == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -103,9 +115,9 @@ int oakcommon_filefunctions_get_configuration_location(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_application_path(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
OakFileFunctions self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
if (self.ctx == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -118,9 +130,9 @@ int oakcommon_filefunctions_get_application_path(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_temp_file_path(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
OakFileFunctions self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
if (self.ctx == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -133,9 +145,9 @@ int oakcommon_filefunctions_get_temp_file_path(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_auto_recovery_root(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
OakFileFunctions self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
if (self.ctx == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -148,10 +160,10 @@ int oakcommon_filefunctions_get_auto_recovery_root(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_can_copy_directory_without_overwriting(
|
||||
OakCommonFileFunctions *self, const char *source, const char *dest,
|
||||
OakFileFunctions self, const char *source, const char *dest,
|
||||
int *out)
|
||||
{
|
||||
if (self == nullptr || source == nullptr || dest == nullptr ||
|
||||
if (self.ctx == nullptr || source == nullptr || dest == nullptr ||
|
||||
out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -167,11 +179,11 @@ int oakcommon_filefunctions_can_copy_directory_without_overwriting(
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_copy_directory(OakCommonFileFunctions *self,
|
||||
int oakcommon_filefunctions_copy_directory(OakFileFunctions self,
|
||||
const char *source,
|
||||
const char *dest, int overwrite)
|
||||
{
|
||||
if (self == nullptr || source == nullptr || dest == nullptr) {
|
||||
if (self.ctx == nullptr || source == nullptr || dest == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -184,10 +196,10 @@ int oakcommon_filefunctions_copy_directory(OakCommonFileFunctions *self,
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_directory_is_valid(
|
||||
OakCommonFileFunctions *self, const char *dir,
|
||||
OakFileFunctions self, const char *dir,
|
||||
int try_to_create_if_not_exists, int *out)
|
||||
{
|
||||
if (self == nullptr || dir == nullptr || out == nullptr) {
|
||||
if (self.ctx == nullptr || dir == nullptr || out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -203,10 +215,10 @@ int oakcommon_filefunctions_directory_is_valid(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_ensure_filename_extension(
|
||||
OakCommonFileFunctions *self, const char *filename,
|
||||
OakFileFunctions self, const char *filename,
|
||||
const char *extension, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr || extension == nullptr ||
|
||||
if (self.ctx == nullptr || filename == nullptr || extension == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -222,10 +234,10 @@ int oakcommon_filefunctions_ensure_filename_extension(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_read_file_as_string(
|
||||
OakCommonFileFunctions *self, const char *filename, char *buf,
|
||||
OakFileFunctions self, const char *filename, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr ||
|
||||
if (self.ctx == nullptr || filename == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -240,10 +252,10 @@ int oakcommon_filefunctions_read_file_as_string(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_safe_temporary_filename(
|
||||
OakCommonFileFunctions *self, const char *original, char *buf,
|
||||
OakFileFunctions self, const char *original, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || original == nullptr ||
|
||||
if (self.ctx == nullptr || original == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -258,10 +270,10 @@ int oakcommon_filefunctions_get_safe_temporary_filename(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_rename_file_allow_overwrite(
|
||||
OakCommonFileFunctions *self, const char *from, const char *to,
|
||||
OakFileFunctions self, const char *from, const char *to,
|
||||
int *out)
|
||||
{
|
||||
if (self == nullptr || from == nullptr || to == nullptr ||
|
||||
if (self.ctx == nullptr || from == nullptr || to == nullptr ||
|
||||
out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
@@ -276,10 +288,10 @@ int oakcommon_filefunctions_rename_file_allow_overwrite(
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_formatted_executable_for_platform(
|
||||
OakCommonFileFunctions *self, const char *unformatted, char *buf,
|
||||
OakFileFunctions self, const char *unformatted, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || unformatted == nullptr ||
|
||||
if (self.ctx == nullptr || unformatted == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
@@ -23,30 +23,42 @@
|
||||
#include <new>
|
||||
|
||||
#include "../src/ocioutils.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonOCIOUtils {
|
||||
int unused; /**< Stateless; only the address matters. */
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Stateless family; the boxed object is empty and only exists so
|
||||
* the handle has something to reference-count.
|
||||
*/
|
||||
struct OCIOUtilsState {
|
||||
int unused;
|
||||
};
|
||||
|
||||
OakCommonOCIOUtils *oakcommon_ocioutils_init(void)
|
||||
} // namespace
|
||||
|
||||
OakOCIOUtils oakcommon_ocioutils_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonOCIOUtils{};
|
||||
return oakcommon::make_handle<OakOCIOUtils>(
|
||||
OCIOUtilsState{0});
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
OakOCIOUtils h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_ocioutils_free(OakCommonOCIOUtils *self)
|
||||
void oakcommon_ocioutils_free(OakOCIOUtils *self)
|
||||
{
|
||||
delete self;
|
||||
oakcommon::free_handle(self);
|
||||
}
|
||||
|
||||
int oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
OakCommonOCIOUtils *self, int pixel_format, int *out_bit_depth)
|
||||
OakOCIOUtils self, int pixel_format, int *out_bit_depth)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_bit_depth == NULL)
|
||||
if (self.ctx == NULL || out_bit_depth == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (pixel_format < OAKCOMMON_PIXEL_FORMAT_INVALID ||
|
||||
pixel_format >= OAKCOMMON_PIXEL_FORMAT_COUNT)
|
||||
|
||||
@@ -23,30 +23,42 @@
|
||||
#include <new>
|
||||
|
||||
#include "../src/oiioutils.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonOIIOUtils {
|
||||
int unused; /**< Stateless; only the address matters. */
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Stateless family; the boxed object is empty and only exists so
|
||||
* the handle has something to reference-count.
|
||||
*/
|
||||
struct OIIOUtilsState {
|
||||
int unused;
|
||||
};
|
||||
|
||||
OakCommonOIIOUtils *oakcommon_oiioutils_init(void)
|
||||
} // namespace
|
||||
|
||||
OakOIIOUtils oakcommon_oiioutils_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonOIIOUtils{};
|
||||
return oakcommon::make_handle<OakOIIOUtils>(
|
||||
OIIOUtilsState{0});
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
OakOIIOUtils h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_oiioutils_free(OakCommonOIIOUtils *self)
|
||||
void oakcommon_oiioutils_free(OakOIIOUtils *self)
|
||||
{
|
||||
delete self;
|
||||
oakcommon::free_handle(self);
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_oiio_base_type_from_format(
|
||||
OakCommonOIIOUtils *self, int pixel_format, int *out_base_type)
|
||||
OakOIIOUtils self, int pixel_format, int *out_base_type)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_base_type == NULL)
|
||||
if (self.ctx == NULL || out_base_type == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (pixel_format < OAKCOMMON_PIXEL_FORMAT_INVALID ||
|
||||
pixel_format >= OAKCOMMON_PIXEL_FORMAT_COUNT)
|
||||
@@ -63,10 +75,10 @@ int oakcommon_oiioutils_get_oiio_base_type_from_format(
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_format_from_oiio_basetype(
|
||||
OakCommonOIIOUtils *self, int base_type, int *out_pixel_format)
|
||||
OakOIIOUtils self, int base_type, int *out_pixel_format)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_pixel_format == NULL)
|
||||
if (self.ctx == NULL || out_pixel_format == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (base_type < 0 || base_type >= OIIO::TypeDesc::LASTBASE)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
@@ -82,11 +94,11 @@ int oakcommon_oiioutils_get_format_from_oiio_basetype(
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_pixel_aspect_ratio(
|
||||
OakCommonOIIOUtils *self, double pixel_aspect_ratio, int *out_numerator,
|
||||
OakOIIOUtils self, double pixel_aspect_ratio, int *out_numerator,
|
||||
int *out_denominator)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_numerator == NULL || out_denominator == NULL)
|
||||
if (self.ctx == NULL || out_numerator == NULL || out_denominator == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
olive::core::Rational par =
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
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 OAKCOMMON_C_API_REFCOUNTED_H
|
||||
#define OAKCOMMON_C_API_REFCOUNTED_H
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "common/handle.h"
|
||||
|
||||
namespace oakcommon
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Heap box behind every handle's ctx pointer.
|
||||
*
|
||||
* Holds the wrapped object plus its atomic reference count. addref and
|
||||
* release are emitted per boxed type so that the function pointers stored
|
||||
* in a handle always run code from the DLL that created the object.
|
||||
*/
|
||||
template <typename T> struct RefCounted {
|
||||
T impl;
|
||||
std::atomic<uint32_t> refs;
|
||||
|
||||
template <typename... Args>
|
||||
explicit RefCounted(Args &&...args)
|
||||
: impl(std::forward<Args>(args)...)
|
||||
, refs(1)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Handle addref thunk: atomically increments the count.
|
||||
*/
|
||||
template <typename T> void ref_counted_addref(void *ctx)
|
||||
{
|
||||
auto *box = static_cast<RefCounted<T> *>(ctx);
|
||||
if (box)
|
||||
box->refs.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle release thunk: decrements the count, destroys at zero.
|
||||
*/
|
||||
template <typename T> void ref_counted_release(void *ctx)
|
||||
{
|
||||
auto *box = static_cast<RefCounted<T> *>(ctx);
|
||||
if (box && box->refs.fetch_sub(1, std::memory_order_acq_rel) == 1)
|
||||
delete box;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build a by-value handle owning a freshly boxed object (count 1).
|
||||
*
|
||||
* The object is constructed in place inside the box, so non-movable
|
||||
* types are supported. On allocation failure the returned handle has
|
||||
* ctx == NULL (all C API functions treat that as OAKCOMMON_E_INVALID
|
||||
* and free() as a no-op).
|
||||
*/
|
||||
template <typename Handle, typename T, typename... Args>
|
||||
Handle make_handle_in_place(Args &&...args)
|
||||
{
|
||||
Handle h = {};
|
||||
try {
|
||||
h.ctx = new RefCounted<T>(std::forward<Args>(args)...);
|
||||
} catch (...) {
|
||||
h.ctx = nullptr;
|
||||
}
|
||||
h.addref = &ref_counted_addref<T>;
|
||||
h.release = &ref_counted_release<T>;
|
||||
h.abi_version = OAKCOMMON_ABI_VERSION;
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build a by-value handle from an existing object (copied/moved
|
||||
* into the box, reference count 1).
|
||||
*/
|
||||
template <typename Handle, typename T>
|
||||
Handle make_handle(T &&value)
|
||||
{
|
||||
return make_handle_in_place<Handle, typename std::decay<T>::type>(
|
||||
std::forward<T>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Recover the boxed object from a handle ctx (NULL-safe).
|
||||
*/
|
||||
template <typename T> T *handle_impl(void *ctx)
|
||||
{
|
||||
auto *box = static_cast<RefCounted<T> *>(ctx);
|
||||
return box ? &box->impl : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shared free() body: release the ctx, no-op on NULL/empty handle.
|
||||
*
|
||||
* Clears ctx afterwards so a double free through the same (copied)
|
||||
* struct is caught by the caller's own bookkeeping, not by us.
|
||||
*/
|
||||
template <typename Handle> void free_handle(Handle *h)
|
||||
{
|
||||
if (!h || !h->ctx || !h->release)
|
||||
return;
|
||||
h->release(h->ctx);
|
||||
h->ctx = nullptr;
|
||||
}
|
||||
|
||||
} // namespace oakcommon
|
||||
|
||||
#endif // OAKCOMMON_C_API_REFCOUNTED_H
|
||||
@@ -23,14 +23,19 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "../src/subtitleparams.h"
|
||||
|
||||
struct OakCommonSubtitleParams {
|
||||
olive::SubtitleParams impl;
|
||||
};
|
||||
#include "refcounted.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Recover the boxed olive::SubtitleParams from a handle (NULL-safe).
|
||||
*/
|
||||
olive::SubtitleParams *sp(OakSubtitleParams params)
|
||||
{
|
||||
return oakcommon::handle_impl<olive::SubtitleParams>(params.ctx);
|
||||
}
|
||||
|
||||
int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
{
|
||||
int needed = (int)value.size() + 1;
|
||||
@@ -41,92 +46,110 @@ int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
|
||||
} // namespace
|
||||
|
||||
OakCommonSubtitleParams *oakcommon_subtitleparams_init(void)
|
||||
OakSubtitleParams oakcommon_subtitleparams_init(void)
|
||||
{
|
||||
try {
|
||||
return new OakCommonSubtitleParams{olive::SubtitleParams()};
|
||||
return oakcommon::make_handle<OakSubtitleParams>(
|
||||
olive::SubtitleParams());
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakSubtitleParams h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_subtitleparams_free(OakCommonSubtitleParams *params)
|
||||
OakSubtitleParams oakcommon_subtitleparams_init_from_native(
|
||||
const olive::SubtitleParams *src)
|
||||
{
|
||||
delete params;
|
||||
if (!src) {
|
||||
OakSubtitleParams h = {};
|
||||
return h;
|
||||
}
|
||||
try {
|
||||
return oakcommon::make_handle<OakSubtitleParams>(
|
||||
olive::SubtitleParams(*src));
|
||||
} catch (...) {
|
||||
OakSubtitleParams h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_subtitleparams_free(OakSubtitleParams *params)
|
||||
{
|
||||
oakcommon::free_handle(params);
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_get_stream_index(
|
||||
OakCommonSubtitleParams *params, int *index)
|
||||
OakSubtitleParams params, int *index)
|
||||
{
|
||||
if (!params || !index)
|
||||
if (!sp(params) || !index)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
*index = params->impl.stream_index();
|
||||
*index = sp(params)->stream_index();
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_set_stream_index(
|
||||
OakCommonSubtitleParams *params, int index)
|
||||
OakSubtitleParams params, int index)
|
||||
{
|
||||
if (!params)
|
||||
if (!sp(params))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
params->impl.set_stream_index(index);
|
||||
sp(params)->set_stream_index(index);
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_get_enabled(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_get_enabled(OakSubtitleParams params,
|
||||
int *enabled)
|
||||
{
|
||||
if (!params || !enabled)
|
||||
if (!sp(params) || !enabled)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
*enabled = params->impl.enabled() ? 1 : 0;
|
||||
*enabled = sp(params)->enabled() ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_set_enabled(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_set_enabled(OakSubtitleParams params,
|
||||
int enabled)
|
||||
{
|
||||
if (!params)
|
||||
if (!sp(params))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
params->impl.set_enabled(enabled != 0);
|
||||
sp(params)->set_enabled(enabled != 0);
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_is_valid(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_is_valid(OakSubtitleParams params,
|
||||
int *is_valid)
|
||||
{
|
||||
if (!params || !is_valid)
|
||||
if (!sp(params) || !is_valid)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
*is_valid = params->impl.is_valid() ? 1 : 0;
|
||||
*is_valid = sp(params)->is_valid() ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_count(OakCommonSubtitleParams *params, int *count)
|
||||
int oakcommon_subtitleparams_count(OakSubtitleParams params, int *count)
|
||||
{
|
||||
if (!params || !count)
|
||||
if (!sp(params) || !count)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
*count = (int)params->impl.size();
|
||||
*count = (int)sp(params)->size();
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_duration(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_duration(OakSubtitleParams params,
|
||||
int *numerator, int *denominator)
|
||||
{
|
||||
if (!params || !numerator || !denominator)
|
||||
if (!sp(params) || !numerator || !denominator)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
olive::core::Rational d = params->impl.duration();
|
||||
olive::core::Rational d = sp(params)->duration();
|
||||
*numerator = d.numerator();
|
||||
*denominator = d.denominator();
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_add_subtitle(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_add_subtitle(OakSubtitleParams params,
|
||||
int in_num, int in_den, int out_num,
|
||||
int out_den, const char *text)
|
||||
{
|
||||
if (!params || !text)
|
||||
if (!sp(params) || !text)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
params->impl.push_back(olive::Subtitle(
|
||||
sp(params)->push_back(olive::Subtitle(
|
||||
olive::core::TimeRange(olive::core::Rational(in_num, in_den),
|
||||
olive::core::Rational(out_num, out_den)),
|
||||
text));
|
||||
@@ -136,23 +159,23 @@ int oakcommon_subtitleparams_add_subtitle(OakCommonSubtitleParams *params,
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_clear(OakCommonSubtitleParams *params)
|
||||
int oakcommon_subtitleparams_clear(OakSubtitleParams params)
|
||||
{
|
||||
if (!params)
|
||||
if (!sp(params))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
params->impl.clear();
|
||||
sp(params)->clear();
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_get_subtitle(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_get_subtitle(OakSubtitleParams params,
|
||||
int index, int *in_num, int *in_den,
|
||||
int *out_num, int *out_den)
|
||||
{
|
||||
if (!params || !in_num || !in_den || !out_num || !out_den)
|
||||
if (!sp(params) || !in_num || !in_den || !out_num || !out_den)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (index < 0 || index >= (int)params->impl.size())
|
||||
if (index < 0 || index >= (int)sp(params)->size())
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
const olive::Subtitle &s = params->impl.at(index);
|
||||
const olive::Subtitle &s = sp(params)->at(index);
|
||||
olive::core::Rational in = s.time().in();
|
||||
olive::core::Rational out = s.time().out();
|
||||
*in_num = in.numerator();
|
||||
@@ -162,16 +185,16 @@ int oakcommon_subtitleparams_get_subtitle(OakCommonSubtitleParams *params,
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_get_subtitle_text(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_get_subtitle_text(OakSubtitleParams params,
|
||||
int index, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (!params)
|
||||
if (!sp(params))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (index < 0 || index >= (int)params->impl.size())
|
||||
if (index < 0 || index >= (int)sp(params)->size())
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
try {
|
||||
return copy_string(params->impl.at(index).text(), buf, buf_size);
|
||||
return copy_string(sp(params)->at(index).text(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
@@ -187,10 +210,10 @@ int oakcommon_subtitleparams_generate_ass_header(char *buf, int buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_load_xml(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_load_xml(OakSubtitleParams params,
|
||||
const char *xml)
|
||||
{
|
||||
if (!params || !xml)
|
||||
if (!sp(params) || !xml)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
olive::XmlStreamReader reader(xml);
|
||||
@@ -199,22 +222,22 @@ int oakcommon_subtitleparams_load_xml(OakCommonSubtitleParams *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);
|
||||
sp(params)->load(&reader);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_subtitleparams_save_xml(OakCommonSubtitleParams *params,
|
||||
int oakcommon_subtitleparams_save_xml(OakSubtitleParams params,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!params)
|
||||
if (!sp(params))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
olive::XmlStreamWriter writer;
|
||||
writer.write_start_element("subtitleparams");
|
||||
params->impl.save(&writer);
|
||||
sp(params)->save(&writer);
|
||||
writer.write_end_element();
|
||||
return copy_string(writer.output(), buf, buf_size);
|
||||
} catch (...) {
|
||||
|
||||
+200
-132
@@ -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);
|
||||
}
|
||||
|
||||
@@ -24,24 +24,40 @@
|
||||
#include <new>
|
||||
|
||||
#include "../src/xmlutils.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct OakCommonXmlReader {
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Reader state boxed behind the handle's ctx pointer.
|
||||
*/
|
||||
struct XmlReaderState {
|
||||
olive::XmlStreamReader reader;
|
||||
std::string cached_text;
|
||||
bool has_cached_text = false;
|
||||
|
||||
explicit OakCommonXmlReader(const char *data)
|
||||
explicit XmlReaderState(const char *data)
|
||||
: reader(data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct OakCommonXmlWriter {
|
||||
olive::XmlStreamWriter writer;
|
||||
};
|
||||
|
||||
namespace
|
||||
/**
|
||||
* @brief Recover the boxed reader state from a handle (NULL-safe).
|
||||
*/
|
||||
XmlReaderState *xr(OakXmlReader reader)
|
||||
{
|
||||
return oakcommon::handle_impl<XmlReaderState>(reader.ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Recover the boxed writer from a handle (NULL-safe).
|
||||
*/
|
||||
olive::XmlStreamWriter *xw(OakXmlWriter writer)
|
||||
{
|
||||
return oakcommon::handle_impl<olive::XmlStreamWriter>(writer.ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy @p value into the two-stage string buffer.
|
||||
@@ -62,99 +78,102 @@ int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
|
||||
extern "C" {
|
||||
|
||||
OakCommonXmlReader *oakcommon_xml_reader_init(const char *data)
|
||||
OakXmlReader oakcommon_xml_reader_init(const char *data)
|
||||
{
|
||||
OakXmlReader h = {};
|
||||
if (!data)
|
||||
return nullptr;
|
||||
return h;
|
||||
try {
|
||||
return new (std::nothrow) OakCommonXmlReader(data);
|
||||
return oakcommon::make_handle<OakXmlReader>(
|
||||
XmlReaderState(data));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakXmlReader empty = {};
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_xml_reader_free(OakCommonXmlReader *reader)
|
||||
void oakcommon_xml_reader_free(OakXmlReader *reader)
|
||||
{
|
||||
delete reader;
|
||||
oakcommon::free_handle(reader);
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_read_next_start_element(OakCommonXmlReader *reader,
|
||||
int oakcommon_xml_reader_read_next_start_element(OakXmlReader reader,
|
||||
int *found)
|
||||
{
|
||||
if (!reader || !found)
|
||||
if (!xr(reader) || !found)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
reader->has_cached_text = false;
|
||||
*found = olive::xml_read_next_start_element(&reader->reader) ? 1 : 0;
|
||||
xr(reader)->has_cached_text = false;
|
||||
*found = olive::xml_read_next_start_element(&xr(reader)->reader) ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_name(OakCommonXmlReader *reader, char *buf,
|
||||
int oakcommon_xml_reader_name(OakXmlReader reader, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
if (!xr(reader))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(reader->reader.name(), buf, buf_size);
|
||||
return copy_string(xr(reader)->reader.name(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_read_element_text(OakCommonXmlReader *reader,
|
||||
int oakcommon_xml_reader_read_element_text(OakXmlReader reader,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
if (!xr(reader))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
// read_element_text() consumes the stream, so cache the result to
|
||||
// keep the two-stage (size query then copy) buffer convention working.
|
||||
if (!reader->has_cached_text) {
|
||||
reader->cached_text = reader->reader.read_element_text();
|
||||
reader->has_cached_text = true;
|
||||
if (!xr(reader)->has_cached_text) {
|
||||
xr(reader)->cached_text = xr(reader)->reader.read_element_text();
|
||||
xr(reader)->has_cached_text = true;
|
||||
}
|
||||
return copy_string(reader->cached_text, buf, buf_size);
|
||||
return copy_string(xr(reader)->cached_text, buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_skip_current_element(OakCommonXmlReader *reader)
|
||||
int oakcommon_xml_reader_skip_current_element(OakXmlReader reader)
|
||||
{
|
||||
if (!reader)
|
||||
if (!xr(reader))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
reader->has_cached_text = false;
|
||||
reader->reader.skip_current_element();
|
||||
xr(reader)->has_cached_text = false;
|
||||
xr(reader)->reader.skip_current_element();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_count(OakCommonXmlReader *reader,
|
||||
int oakcommon_xml_reader_attribute_count(OakXmlReader reader,
|
||||
int *count)
|
||||
{
|
||||
if (!reader || !count)
|
||||
if (!xr(reader) || !count)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*count = static_cast<int>(reader->reader.attributes().size());
|
||||
*count = static_cast<int>(xr(reader)->reader.attributes().size());
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_name(OakCommonXmlReader *reader, int index,
|
||||
int oakcommon_xml_reader_attribute_name(OakXmlReader reader, int index,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
if (!xr(reader))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
const auto &attrs = reader->reader.attributes();
|
||||
const auto &attrs = xr(reader)->reader.attributes();
|
||||
if (index < 0 || index >= static_cast<int>(attrs.size()))
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
return copy_string(attrs[index].name, buf, buf_size);
|
||||
@@ -163,13 +182,13 @@ int oakcommon_xml_reader_attribute_name(OakCommonXmlReader *reader, int index,
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_value(OakCommonXmlReader *reader,
|
||||
int oakcommon_xml_reader_attribute_value(OakXmlReader reader,
|
||||
int index, char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
if (!xr(reader))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
const auto &attrs = reader->reader.attributes();
|
||||
const auto &attrs = xr(reader)->reader.attributes();
|
||||
if (index < 0 || index >= static_cast<int>(attrs.size()))
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
return copy_string(attrs[index].value, buf, buf_size);
|
||||
@@ -178,117 +197,119 @@ int oakcommon_xml_reader_attribute_value(OakCommonXmlReader *reader,
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_has_error(OakCommonXmlReader *reader,
|
||||
int oakcommon_xml_reader_has_error(OakXmlReader reader,
|
||||
int *has_error)
|
||||
{
|
||||
if (!reader || !has_error)
|
||||
if (!xr(reader) || !has_error)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*has_error = reader->reader.has_error() ? 1 : 0;
|
||||
*has_error = xr(reader)->reader.has_error() ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
OakCommonXmlWriter *oakcommon_xml_writer_init(void)
|
||||
OakXmlWriter oakcommon_xml_writer_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonXmlWriter();
|
||||
return oakcommon::make_handle<OakXmlWriter>(
|
||||
olive::XmlStreamWriter());
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
OakXmlWriter h = {};
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_xml_writer_free(OakCommonXmlWriter *writer)
|
||||
void oakcommon_xml_writer_free(OakXmlWriter *writer)
|
||||
{
|
||||
delete writer;
|
||||
oakcommon::free_handle(writer);
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_start_element(OakCommonXmlWriter *writer,
|
||||
int oakcommon_xml_writer_write_start_element(OakXmlWriter writer,
|
||||
const char *name)
|
||||
{
|
||||
if (!writer || !name)
|
||||
if (!xw(writer) || !name)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_start_element(name);
|
||||
xw(writer)->write_start_element(name);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_attribute(OakCommonXmlWriter *writer,
|
||||
int oakcommon_xml_writer_write_attribute(OakXmlWriter writer,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
if (!writer || !name || !value)
|
||||
if (!xw(writer) || !name || !value)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_attribute(name, value);
|
||||
xw(writer)->write_attribute(name, value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_characters(OakCommonXmlWriter *writer,
|
||||
int oakcommon_xml_writer_write_characters(OakXmlWriter writer,
|
||||
const char *text)
|
||||
{
|
||||
if (!writer || !text)
|
||||
if (!xw(writer) || !text)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_characters(text);
|
||||
xw(writer)->write_characters(text);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_text_element(OakCommonXmlWriter *writer,
|
||||
int oakcommon_xml_writer_write_text_element(OakXmlWriter writer,
|
||||
const char *name,
|
||||
const char *text)
|
||||
{
|
||||
if (!writer || !name || !text)
|
||||
if (!xw(writer) || !name || !text)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_text_element(name, text);
|
||||
xw(writer)->write_text_element(name, text);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_end_element(OakCommonXmlWriter *writer)
|
||||
int oakcommon_xml_writer_write_end_element(OakXmlWriter writer)
|
||||
{
|
||||
if (!writer)
|
||||
if (!xw(writer))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_end_element();
|
||||
xw(writer)->write_end_element();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_end_document(OakCommonXmlWriter *writer)
|
||||
int oakcommon_xml_writer_write_end_document(OakXmlWriter writer)
|
||||
{
|
||||
if (!writer)
|
||||
if (!xw(writer))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_end_document();
|
||||
xw(writer)->write_end_document();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_output(OakCommonXmlWriter *writer, char *buf,
|
||||
int oakcommon_xml_writer_output(OakXmlWriter writer, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (!writer)
|
||||
if (!xw(writer))
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(writer->writer.output(), buf, buf_size);
|
||||
return copy_string(xw(writer)->output(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user