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;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,39 @@
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Minimum level emitted by log_message(); default k_debug_info.
|
||||
*/
|
||||
std::atomic<int> g_log_level{ k_debug_info };
|
||||
|
||||
/**
|
||||
* @brief Guards g_log_sink (std::function is not atomic).
|
||||
*/
|
||||
std::mutex g_sink_mutex;
|
||||
LogSink g_log_sink;
|
||||
|
||||
/**
|
||||
* @brief Default sink: stderr + flush, same as debug_handler().
|
||||
*/
|
||||
void stderr_sink(const std::string &line)
|
||||
{
|
||||
fputs(line.c_str(), stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int debug_level_name(int level, char *buf, int buf_size)
|
||||
{
|
||||
const char *name;
|
||||
@@ -58,16 +85,82 @@ int debug_level_name(int level, char *buf, int buf_size)
|
||||
return needed;
|
||||
}
|
||||
|
||||
void debug_handler(int level, const char *msg)
|
||||
std::string format_log_line(int level, const std::string &msg)
|
||||
{
|
||||
char level_name[16];
|
||||
|
||||
debug_level_name(level, level_name, sizeof(level_name));
|
||||
fprintf(stderr, "[%s] %s\n", level_name, msg ? msg : "");
|
||||
|
||||
// Always flush so debug messages appear immediately, even on
|
||||
// platforms that buffer stderr.
|
||||
fflush(stderr);
|
||||
std::string line;
|
||||
line.reserve(strlen(level_name) + msg.size() + 4);
|
||||
line += '[';
|
||||
line += level_name;
|
||||
line += "] ";
|
||||
line += msg;
|
||||
line += '\n';
|
||||
return line;
|
||||
}
|
||||
|
||||
void debug_handler(int level, const char *msg)
|
||||
{
|
||||
stderr_sink(format_log_line(level, msg ? msg : ""));
|
||||
}
|
||||
|
||||
void set_log_sink(LogSink sink)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_sink_mutex);
|
||||
g_log_sink = std::move(sink);
|
||||
}
|
||||
|
||||
void set_log_level(DebugLevel level)
|
||||
{
|
||||
if (level < k_debug_debug || level > k_debug_fatal)
|
||||
return;
|
||||
g_log_level.store(static_cast<int>(level), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
DebugLevel get_log_level()
|
||||
{
|
||||
return static_cast<DebugLevel>(g_log_level.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void log_message(int level, const std::string &msg)
|
||||
{
|
||||
if (level < g_log_level.load(std::memory_order_relaxed))
|
||||
return;
|
||||
|
||||
std::string line = format_log_line(level, msg);
|
||||
|
||||
LogSink sink;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_sink_mutex);
|
||||
sink = g_log_sink;
|
||||
}
|
||||
// Invoke outside the lock so a sink may log re-entrantly.
|
||||
if (sink)
|
||||
sink(line);
|
||||
else
|
||||
stderr_sink(line);
|
||||
}
|
||||
|
||||
void log_debug(const std::string &msg)
|
||||
{
|
||||
log_message(k_debug_debug, msg);
|
||||
}
|
||||
|
||||
void log_info(const std::string &msg)
|
||||
{
|
||||
log_message(k_debug_info, msg);
|
||||
}
|
||||
|
||||
void log_warning(const std::string &msg)
|
||||
{
|
||||
log_message(k_debug_warning, msg);
|
||||
}
|
||||
|
||||
void log_critical(const std::string &msg)
|
||||
{
|
||||
log_message(k_debug_error, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+61
-1
@@ -21,6 +21,9 @@
|
||||
#ifndef OAK_DEBUG_H
|
||||
#define OAK_DEBUG_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -28,7 +31,8 @@ namespace olive
|
||||
* @brief Severity levels for debug output.
|
||||
*
|
||||
* Replaces Qt's QtMsgType now that the debug handler no longer depends
|
||||
* on QDebug.
|
||||
* on QDebug. Values are ordered by ascending severity so that a simple
|
||||
* `level < threshold` comparison implements level filtering.
|
||||
*/
|
||||
enum DebugLevel {
|
||||
k_debug_debug,
|
||||
@@ -56,9 +60,65 @@ int debug_level_name(int level, char *buf, int buf_size);
|
||||
* De-Qt replacement for the old Qt message handler: qDebug() output is
|
||||
* replaced by fprintf(stderr). A NULL message is treated as an empty
|
||||
* string. Lines are always flushed so messages appear immediately.
|
||||
*
|
||||
* This is the unfiltered low-level writer; use log_message() (or the
|
||||
* log_debug()/log_info()/... helpers) for level-filtered logging.
|
||||
*/
|
||||
void debug_handler(int level, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Format a log line as "[LEVEL] message\n".
|
||||
*/
|
||||
std::string format_log_line(int level, const std::string &msg);
|
||||
|
||||
/**
|
||||
* @brief Destination for filtered log lines.
|
||||
*
|
||||
* Receives the fully formatted line ("[LEVEL] message\n"). The default
|
||||
* sink writes to stderr and flushes, matching debug_handler().
|
||||
*/
|
||||
using LogSink = std::function<void(const std::string &line)>;
|
||||
|
||||
/**
|
||||
* @brief Install a custom log sink (e.g. for tests or log files).
|
||||
*
|
||||
* Passing an empty LogSink restores the default stderr sink.
|
||||
* Thread-safe; the sink is invoked without the internal lock held.
|
||||
*/
|
||||
void set_log_sink(LogSink sink);
|
||||
|
||||
/**
|
||||
* @brief Set the minimum level emitted by log_message().
|
||||
*
|
||||
* Messages with a lower level are dropped. The default is
|
||||
* k_debug_info. Values outside the DebugLevel range are ignored.
|
||||
* Thread-safe (atomic store).
|
||||
*/
|
||||
void set_log_level(DebugLevel level);
|
||||
|
||||
/**
|
||||
* @brief The current minimum level emitted by log_message().
|
||||
*/
|
||||
DebugLevel get_log_level();
|
||||
|
||||
/**
|
||||
* @brief Emit a message if `level` passes the current level filter.
|
||||
*
|
||||
* The formatted line ("[LEVEL] message\n") is handed to the installed
|
||||
* sink. Messages below the level set with set_log_level() are dropped.
|
||||
*/
|
||||
void log_message(int level, const std::string &msg);
|
||||
|
||||
/**
|
||||
* @brief Level-filtered convenience wrappers, replacing qDebug(),
|
||||
* qInfo(), qWarning() and qCritical(). Callers compose the message
|
||||
* themselves (plain std::string concatenation).
|
||||
*/
|
||||
void log_debug(const std::string &msg);
|
||||
void log_info(const std::string &msg);
|
||||
void log_warning(const std::string &msg);
|
||||
void log_critical(const std::string &msg);
|
||||
|
||||
}
|
||||
|
||||
#endif // OAK_DEBUG_H
|
||||
|
||||
@@ -88,17 +88,3 @@ OIIOUtils::get_pixel_aspect_ratio_from_oiio(const OIIO::ImageSpec &spec)
|
||||
return olive::core::Rational::from_double(
|
||||
spec.get_float_attribute("PixelAspectRatio", 1));
|
||||
}
|
||||
|
||||
void OIIOUtils::frame_to_buffer(const void *data, int64_t linesize_bytes,
|
||||
OIIO::ImageBuf *buf)
|
||||
{
|
||||
buf->set_pixels(OIIO::ROI(), buf->spec().format, data, OIIO::AutoStride,
|
||||
static_cast<OIIO::stride_t>(linesize_bytes));
|
||||
}
|
||||
|
||||
void OIIOUtils::buffer_to_frame(OIIO::ImageBuf *buf, void *data,
|
||||
int64_t linesize_bytes)
|
||||
{
|
||||
buf->get_pixels(OIIO::ROI(), buf->spec().format, data, OIIO::AutoStride,
|
||||
static_cast<OIIO::stride_t>(linesize_bytes));
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
* Qt-free reimplementation of the former olive::OIIOUtils. The reverse
|
||||
* dependencies on codec/frame.h and render/videoparams.h (which pull in
|
||||
* Qt) were replaced with the Qt-free olive/core/render/pixelformat.h and
|
||||
* olive/core/util/rational.h. The Frame-based helpers were flattened to
|
||||
* raw data pointer + linesize, which is all they ever used from Frame.
|
||||
* olive/core/util/rational.h. The Frame-based helpers (frame_to_buffer /
|
||||
* buffer_to_frame) moved to oakcodec in M5
|
||||
* (src/codec/src/oiioframebridge.h) — they are only used by codec.
|
||||
*/
|
||||
class OIIOUtils {
|
||||
public:
|
||||
@@ -65,24 +66,6 @@ public:
|
||||
*/
|
||||
static olive::core::Rational
|
||||
get_pixel_aspect_ratio_from_oiio(const OIIO::ImageSpec &spec);
|
||||
|
||||
/**
|
||||
* @brief Copies raw pixel data into an OIIO image buffer
|
||||
*
|
||||
* Flattened form of the former Frame-based frame_to_buffer(); pass
|
||||
* Frame::const_data() and Frame::linesize_bytes() at the call site.
|
||||
*/
|
||||
static void frame_to_buffer(const void *data, int64_t linesize_bytes,
|
||||
OIIO::ImageBuf *buf);
|
||||
|
||||
/**
|
||||
* @brief Copies an OIIO image buffer's pixels into raw memory
|
||||
*
|
||||
* Flattened form of the former Frame-based buffer_to_frame(); pass
|
||||
* Frame::data() and Frame::linesize_bytes() at the call site.
|
||||
*/
|
||||
static void buffer_to_frame(OIIO::ImageBuf *buf, void *data,
|
||||
int64_t linesize_bytes);
|
||||
};
|
||||
|
||||
#endif // OAK_OIIOUTILS_H
|
||||
|
||||
@@ -26,6 +26,8 @@ add_executable(oakcommon-gtest
|
||||
dropworkflowbehavior_test.cpp
|
||||
ffmpegutils_test.cpp
|
||||
filefunctions_test.cpp
|
||||
handle_test.cpp
|
||||
log_test.cpp
|
||||
memorypool_test.cpp
|
||||
miscutils_test.cpp
|
||||
ocioutils_test.cpp
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string read_string(int (*fn)(OakCommonColorTransform *, char *, int),
|
||||
OakCommonColorTransform *t)
|
||||
std::string read_string(int (*fn)(OakColorTransform, char *, int),
|
||||
OakColorTransform t)
|
||||
{
|
||||
int needed = fn(t, nullptr, 0);
|
||||
EXPECT_GT(needed, 0);
|
||||
@@ -43,9 +43,8 @@ std::string read_string(int (*fn)(OakCommonColorTransform *, char *, int),
|
||||
|
||||
TEST(CommonColorTransformCApi, InitOutput)
|
||||
{
|
||||
OakCommonColorTransform *t =
|
||||
oakcommon_colortransform_init_output("sRGB");
|
||||
ASSERT_NE(t, nullptr);
|
||||
OakColorTransform t = oakcommon_colortransform_init_output("sRGB");
|
||||
ASSERT_NE(t.ctx, nullptr);
|
||||
|
||||
int is_display = -1;
|
||||
EXPECT_EQ(oakcommon_colortransform_is_display(t, &is_display),
|
||||
@@ -54,19 +53,19 @@ TEST(CommonColorTransformCApi, InitOutput)
|
||||
EXPECT_EQ(read_string(oakcommon_colortransform_get_output, t), "sRGB");
|
||||
EXPECT_EQ(read_string(oakcommon_colortransform_get_display, t), "sRGB");
|
||||
|
||||
oakcommon_colortransform_free(t);
|
||||
oakcommon_colortransform_free(&t);
|
||||
}
|
||||
|
||||
TEST(CommonColorTransformCApi, InitOutputNullString)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_colortransform_init_output(nullptr), nullptr);
|
||||
EXPECT_EQ(oakcommon_colortransform_init_output(nullptr).ctx,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
TEST(CommonColorTransformCApi, InitDisplay)
|
||||
{
|
||||
OakCommonColorTransform *t =
|
||||
oakcommon_colortransform_init_display("sRGB", "Studio", "None");
|
||||
ASSERT_NE(t, nullptr);
|
||||
OakColorTransform t = oakcommon_colortransform_init_display("sRGB", "Studio", "None");
|
||||
ASSERT_NE(t.ctx, nullptr);
|
||||
|
||||
int is_display = 0;
|
||||
EXPECT_EQ(oakcommon_colortransform_is_display(t, &is_display),
|
||||
@@ -76,16 +75,16 @@ TEST(CommonColorTransformCApi, InitDisplay)
|
||||
EXPECT_EQ(read_string(oakcommon_colortransform_get_view, t), "Studio");
|
||||
EXPECT_EQ(read_string(oakcommon_colortransform_get_look, t), "None");
|
||||
|
||||
oakcommon_colortransform_free(t);
|
||||
oakcommon_colortransform_free(&t);
|
||||
}
|
||||
|
||||
TEST(CommonColorTransformCApi, InitDisplayNullString)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display(nullptr, "v", "l"),
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display(nullptr, "v", "l").ctx,
|
||||
nullptr);
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display("d", nullptr, "l"),
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display("d", nullptr, "l").ctx,
|
||||
nullptr);
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display("d", "v", nullptr),
|
||||
EXPECT_EQ(oakcommon_colortransform_init_display("d", "v", nullptr).ctx,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
@@ -98,24 +97,23 @@ TEST(CommonColorTransformCApi, NullHandleErrors)
|
||||
{
|
||||
int i = 0;
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_colortransform_is_display(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_colortransform_is_display(OakColorTransform{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_colortransform_get_display(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_colortransform_get_display(OakColorTransform{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_colortransform_get_output(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_colortransform_get_output(OakColorTransform{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_colortransform_get_view(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_colortransform_get_view(OakColorTransform{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_colortransform_get_look(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_colortransform_get_look(OakColorTransform{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonColorTransformCApi, NullOutParam)
|
||||
{
|
||||
OakCommonColorTransform *t =
|
||||
oakcommon_colortransform_init_output("sRGB");
|
||||
ASSERT_NE(t, nullptr);
|
||||
OakColorTransform t = oakcommon_colortransform_init_output("sRGB");
|
||||
ASSERT_NE(t.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_colortransform_is_display(t, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_colortransform_free(t);
|
||||
oakcommon_colortransform_free(&t);
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
TEST(CommandLineParser, InitFree)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, FreeNull)
|
||||
@@ -41,14 +41,13 @@ TEST(CommandLineParser, FreeNull)
|
||||
|
||||
TEST(CommandLineParser, AddOptionInvalidArgs)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
const char *names[] = { "h", "-help" };
|
||||
OakCommonCommandLineOption *option = nullptr;
|
||||
OakCommandLineOption option = {};
|
||||
|
||||
EXPECT_EQ(oakcommon_commandlineparser_add_option(
|
||||
nullptr, names, 2, "desc", 0, nullptr, 0, &option),
|
||||
EXPECT_EQ(oakcommon_commandlineparser_add_option(OakCommandLineParser{}, names, 2, "desc", 0, nullptr, 0, &option),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, nullptr, 2, "desc", 0, nullptr, 0, &option),
|
||||
@@ -57,28 +56,28 @@ TEST(CommandLineParser, AddOptionInvalidArgs)
|
||||
parser, names, 0, "desc", 0, nullptr, 0, &option),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, ProcessOptionHitAndMiss)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
const char *names[] = { "h", "-help" };
|
||||
OakCommonCommandLineOption *hit = nullptr;
|
||||
OakCommonCommandLineOption *miss = nullptr;
|
||||
OakCommandLineOption hit = {};
|
||||
OakCommandLineOption miss = {};
|
||||
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, names, 2, "Show help", 0, nullptr, 0, &hit),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_NE(hit, nullptr);
|
||||
ASSERT_NE(hit.ctx, nullptr);
|
||||
|
||||
const char *other_names[] = { "v", "-version" };
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, other_names, 2, "Show version", 0, nullptr, 0, &miss),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_NE(miss, nullptr);
|
||||
ASSERT_NE(miss.ctx, nullptr);
|
||||
|
||||
const char *argv[] = { "oak", "-h" };
|
||||
ASSERT_EQ(oakcommon_commandlineparser_process(parser, argv, 2),
|
||||
@@ -92,18 +91,18 @@ TEST(CommandLineParser, ProcessOptionHitAndMiss)
|
||||
ASSERT_EQ(oakcommon_commandlineoption_is_set(miss, &is_set), OAKCOMMON_OK);
|
||||
EXPECT_FALSE(is_set);
|
||||
|
||||
oakcommon_commandlineoption_free(hit);
|
||||
oakcommon_commandlineoption_free(miss);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineoption_free(&hit);
|
||||
oakcommon_commandlineoption_free(&miss);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, ProcessMatchesSecondAliasCaseInsensitive)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
const char *names[] = { "h", "-help" };
|
||||
OakCommonCommandLineOption *option = nullptr;
|
||||
OakCommandLineOption option = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, names, 2, "Show help", 0, nullptr, 0, &option),
|
||||
OAKCOMMON_OK);
|
||||
@@ -118,17 +117,17 @@ TEST(CommandLineParser, ProcessMatchesSecondAliasCaseInsensitive)
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_TRUE(is_set);
|
||||
|
||||
oakcommon_commandlineoption_free(option);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineoption_free(&option);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, OptionTakesArg)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
const char *names[] = { "e", "-export" };
|
||||
OakCommonCommandLineOption *option = nullptr;
|
||||
OakCommandLineOption option = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, names, 2, "Export", 1, "filename", 0, &option),
|
||||
OAKCOMMON_OK);
|
||||
@@ -153,20 +152,20 @@ TEST(CommandLineParser, OptionTakesArg)
|
||||
required);
|
||||
EXPECT_STREQ(buf.data(), "/tmp/out.mp4");
|
||||
|
||||
oakcommon_commandlineoption_free(option);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineoption_free(&option);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, PositionalArgument)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
OakCommonCommandLinePositionalArgument *arg = nullptr;
|
||||
OakCommandLinePositionalArgument arg = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_positional_argument(
|
||||
parser, "project", "Project file", 0, &arg),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_NE(arg, nullptr);
|
||||
ASSERT_NE(arg.ctx, nullptr);
|
||||
|
||||
const char *argv[] = { "oak", "/tmp/project.ove" };
|
||||
ASSERT_EQ(oakcommon_commandlineparser_process(parser, argv, 2),
|
||||
@@ -182,20 +181,20 @@ TEST(CommandLineParser, PositionalArgument)
|
||||
required);
|
||||
EXPECT_STREQ(buf.data(), "/tmp/project.ove");
|
||||
|
||||
oakcommon_commandlinepositionalargument_free(arg);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlinepositionalargument_free(&arg);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, PositionalArgumentSetGetSetting)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
OakCommonCommandLinePositionalArgument *arg = nullptr;
|
||||
OakCommandLinePositionalArgument arg = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_positional_argument(
|
||||
parser, "project", "Project file", 0, &arg),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_NE(arg, nullptr);
|
||||
ASSERT_NE(arg.ctx, nullptr);
|
||||
|
||||
ASSERT_EQ(oakcommon_commandlinepositionalargument_set_setting(arg,
|
||||
"hello.ove"),
|
||||
@@ -209,28 +208,28 @@ TEST(CommandLineParser, PositionalArgumentSetGetSetting)
|
||||
EXPECT_STREQ(buf, "hello.ove");
|
||||
|
||||
// Error paths
|
||||
EXPECT_EQ(oakcommon_commandlinepositionalargument_set_setting(nullptr,
|
||||
EXPECT_EQ(oakcommon_commandlinepositionalargument_set_setting(OakCommandLinePositionalArgument{},
|
||||
"x"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_commandlinepositionalargument_set_setting(arg,
|
||||
nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_commandlinepositionalargument_get_setting(nullptr,
|
||||
EXPECT_EQ(oakcommon_commandlinepositionalargument_get_setting(OakCommandLinePositionalArgument{},
|
||||
buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_commandlinepositionalargument_free(arg);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlinepositionalargument_free(&arg);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, TwoStageStringGetterSmallBuffer)
|
||||
{
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
|
||||
const char *names[] = { "e" };
|
||||
OakCommonCommandLineOption *option = nullptr;
|
||||
OakCommandLineOption option = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, names, 1, "Export", 1, "filename", 0, &option),
|
||||
OAKCOMMON_OK);
|
||||
@@ -249,27 +248,27 @@ TEST(CommandLineParser, TwoStageStringGetterSmallBuffer)
|
||||
EXPECT_EQ(oakcommon_commandlineoption_get_setting(option, nullptr, 0), 7);
|
||||
|
||||
// Error paths
|
||||
EXPECT_EQ(oakcommon_commandlineoption_get_setting(nullptr, buf,
|
||||
EXPECT_EQ(oakcommon_commandlineoption_get_setting(OakCommandLineOption{}, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_commandlineoption_is_set(option, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
bool dummy = false;
|
||||
EXPECT_EQ(oakcommon_commandlineoption_is_set(nullptr, &dummy),
|
||||
EXPECT_EQ(oakcommon_commandlineoption_is_set(OakCommandLineOption{}, &dummy),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_commandlineoption_free(option);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineoption_free(&option);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, ProcessInvalidArgs)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_commandlineparser_process(nullptr, nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_commandlineparser_process(OakCommandLineParser{}, nullptr, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
OakCommonCommandLineParser *parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser, nullptr);
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
ASSERT_NE(parser.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_commandlineparser_process(parser, nullptr, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_commandlineparser_free(parser);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
}
|
||||
|
||||
@@ -24,25 +24,29 @@
|
||||
|
||||
#include "common/current.h"
|
||||
|
||||
TEST(OakCommonCurrent, InstanceIsSingleton)
|
||||
TEST(OakCurrent, InstanceIsSingleton)
|
||||
{
|
||||
OakCommonCurrent *a = oakcommon_current_instance();
|
||||
OakCommonCurrent *b = oakcommon_current_instance();
|
||||
OakCurrent a = oakcommon_current_instance();
|
||||
OakCurrent b = oakcommon_current_instance();
|
||||
|
||||
ASSERT_NE(a, nullptr);
|
||||
EXPECT_EQ(a, b);
|
||||
ASSERT_NE(a.ctx, nullptr);
|
||||
EXPECT_EQ(a.ctx, b.ctx);
|
||||
EXPECT_EQ(a.abi_version, OAKCOMMON_ABI_VERSION);
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, FreeNullIsNoOp)
|
||||
TEST(OakCurrent, FreeNullIsNoOp)
|
||||
{
|
||||
oakcommon_current_free(nullptr);
|
||||
oakcommon_current_free(oakcommon_current_instance());
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
oakcommon_current_free(&c);
|
||||
// Releasing the singleton handle never destroys the object.
|
||||
EXPECT_NE(c.ctx, nullptr);
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, VideoParamsSetGetRoundTrip)
|
||||
TEST(OakCurrent, VideoParamsSetGetRoundTrip)
|
||||
{
|
||||
OakCommonCurrent *c = oakcommon_current_instance();
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
int *params = static_cast<int *>(malloc(sizeof(int)));
|
||||
ASSERT_NE(params, nullptr);
|
||||
*params = 42;
|
||||
@@ -62,9 +66,9 @@ TEST(OakCommonCurrent, VideoParamsSetGetRoundTrip)
|
||||
EXPECT_EQ(out, nullptr);
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, AudioParamsSetGetRoundTrip)
|
||||
TEST(OakCurrent, AudioParamsSetGetRoundTrip)
|
||||
{
|
||||
OakCommonCurrent *c = oakcommon_current_instance();
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
int value = 7; // non-owning storage, no destroy callback
|
||||
|
||||
ASSERT_EQ(oakcommon_current_set_audio_params(c, &value, nullptr),
|
||||
@@ -78,9 +82,9 @@ TEST(OakCommonCurrent, AudioParamsSetGetRoundTrip)
|
||||
OAKCOMMON_OK);
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, PluginHostAndCacheRoundTrip)
|
||||
TEST(OakCurrent, PluginHostAndCacheRoundTrip)
|
||||
{
|
||||
OakCommonCurrent *c = oakcommon_current_instance();
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
int host = 1, cache = 2;
|
||||
|
||||
ASSERT_EQ(oakcommon_current_set_plugin_host(c, &host, nullptr),
|
||||
@@ -100,31 +104,29 @@ TEST(OakCommonCurrent, PluginHostAndCacheRoundTrip)
|
||||
OAKCOMMON_OK);
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, NullHandleAndOutArgs)
|
||||
TEST(OakCurrent, NullHandleAndOutArgs)
|
||||
{
|
||||
void *out = nullptr;
|
||||
int flag = 0;
|
||||
|
||||
EXPECT_EQ(oakcommon_current_set_video_params(nullptr, &flag, nullptr),
|
||||
EXPECT_EQ(oakcommon_current_set_video_params(OakCurrent{}, &flag, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_current_get_video_params(nullptr, &out),
|
||||
EXPECT_EQ(oakcommon_current_get_video_params(OakCurrent{}, &out),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_current_get_video_params(
|
||||
oakcommon_current_instance(), nullptr),
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
EXPECT_EQ(oakcommon_current_get_video_params(c, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_current_is_interactive(nullptr, &flag),
|
||||
EXPECT_EQ(oakcommon_current_is_interactive(OakCurrent{}, &flag),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_current_is_interactive(
|
||||
oakcommon_current_instance(), nullptr),
|
||||
EXPECT_EQ(oakcommon_current_is_interactive(c, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonCurrent, IsInteractive)
|
||||
TEST(OakCurrent, IsInteractive)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
ASSERT_EQ(oakcommon_current_is_interactive(
|
||||
oakcommon_current_instance(), &flag),
|
||||
OAKCOMMON_OK);
|
||||
OakCurrent c = oakcommon_current_instance();
|
||||
ASSERT_EQ(oakcommon_current_is_interactive(c, &flag), OAKCOMMON_OK);
|
||||
EXPECT_EQ(flag, 1);
|
||||
}
|
||||
|
||||
@@ -22,25 +22,25 @@
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
TEST(OakCommonDebug, LogValidMessage)
|
||||
TEST(OakDebug, LogValidMessage)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_debug_log(OAKCOMMON_DEBUG_WARNING, "hello"),
|
||||
OAKCOMMON_OK);
|
||||
}
|
||||
|
||||
TEST(OakCommonDebug, LogNullMessage)
|
||||
TEST(OakDebug, LogNullMessage)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_debug_log(OAKCOMMON_DEBUG_WARNING, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonDebug, LogOutOfRangeLevel)
|
||||
TEST(OakDebug, LogOutOfRangeLevel)
|
||||
{
|
||||
// Out-of-range levels are tolerated and print as UNKNOWN.
|
||||
EXPECT_EQ(oakcommon_debug_log(999, "odd level"), OAKCOMMON_OK);
|
||||
}
|
||||
|
||||
TEST(OakCommonDebug, LevelNameRoundTrip)
|
||||
TEST(OakDebug, LevelNameRoundTrip)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
@@ -51,14 +51,14 @@ TEST(OakCommonDebug, LevelNameRoundTrip)
|
||||
EXPECT_STREQ(buf, "WARNING");
|
||||
}
|
||||
|
||||
TEST(OakCommonDebug, LevelNameQuerySize)
|
||||
TEST(OakDebug, LevelNameQuerySize)
|
||||
{
|
||||
int needed = oakcommon_debug_level_name(OAKCOMMON_DEBUG_DEBUG,
|
||||
nullptr, 0);
|
||||
EXPECT_EQ(needed, 6); // "DEBUG" + NUL
|
||||
}
|
||||
|
||||
TEST(OakCommonDebug, LevelNameUnknownLevel)
|
||||
TEST(OakDebug, LevelNameUnknownLevel)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "common/dropworkflowbehavior.h"
|
||||
|
||||
TEST(OakCommonDropWorkflowBehavior, IsValidAcceptsAllEnumerators)
|
||||
TEST(OakDropWorkflowBehavior, IsValidAcceptsAllEnumerators)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_drop_workflow_behavior_is_valid(OAKCOMMON_DWS_ASK),
|
||||
1);
|
||||
@@ -36,13 +36,13 @@ TEST(OakCommonDropWorkflowBehavior, IsValidAcceptsAllEnumerators)
|
||||
1);
|
||||
}
|
||||
|
||||
TEST(OakCommonDropWorkflowBehavior, IsValidRejectsOutOfRange)
|
||||
TEST(OakDropWorkflowBehavior, IsValidRejectsOutOfRange)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_drop_workflow_behavior_is_valid(-1), 0);
|
||||
EXPECT_EQ(oakcommon_drop_workflow_behavior_is_valid(4), 0);
|
||||
}
|
||||
|
||||
TEST(OakCommonDropWorkflowBehavior, NameRoundTrip)
|
||||
TEST(OakDropWorkflowBehavior, NameRoundTrip)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
@@ -53,7 +53,7 @@ TEST(OakCommonDropWorkflowBehavior, NameRoundTrip)
|
||||
EXPECT_STREQ(buf, "AUTO");
|
||||
}
|
||||
|
||||
TEST(OakCommonDropWorkflowBehavior, NameQuerySizeAndTooSmallBuffer)
|
||||
TEST(OakDropWorkflowBehavior, NameQuerySizeAndTooSmallBuffer)
|
||||
{
|
||||
int needed = oakcommon_drop_workflow_behavior_name(OAKCOMMON_DWS_DISABLE,
|
||||
nullptr, 0);
|
||||
@@ -65,7 +65,7 @@ TEST(OakCommonDropWorkflowBehavior, NameQuerySizeAndTooSmallBuffer)
|
||||
needed);
|
||||
}
|
||||
|
||||
TEST(OakCommonDropWorkflowBehavior, NameInvalidValue)
|
||||
TEST(OakDropWorkflowBehavior, NameInvalidValue)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "../src/ffmpegutils.h"
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetCompatiblePixelFormatMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, GetCompatiblePixelFormatMapsCorrectly)
|
||||
{
|
||||
int out = -2;
|
||||
|
||||
@@ -51,14 +51,14 @@ TEST(OakCommonFFmpegUtils, GetCompatiblePixelFormatMapsCorrectly)
|
||||
EXPECT_EQ(out, olive::core::PixelFormat::invalid);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetCompatiblePixelFormatNullOut)
|
||||
TEST(OakFFmpegUtils, GetCompatiblePixelFormatNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_get_compatible_pixel_format(
|
||||
olive::core::PixelFormat::u8, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetFFmpegPixelFormatMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, GetFFmpegPixelFormatMapsCorrectly)
|
||||
{
|
||||
int out = -2;
|
||||
|
||||
@@ -92,7 +92,7 @@ TEST(OakCommonFFmpegUtils, GetFFmpegPixelFormatMapsCorrectly)
|
||||
EXPECT_EQ(out, fb_pix_fmt_none);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetFFmpegPixelFormatNullOut)
|
||||
TEST(OakFFmpegUtils, GetFFmpegPixelFormatNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_get_ffmpeg_pixel_format(
|
||||
olive::core::PixelFormat::u8,
|
||||
@@ -100,7 +100,7 @@ TEST(OakCommonFFmpegUtils, GetFFmpegPixelFormatNullOut)
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetNativeSampleFormatMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, GetNativeSampleFormatMapsCorrectly)
|
||||
{
|
||||
int out = -2;
|
||||
|
||||
@@ -125,14 +125,14 @@ TEST(OakCommonFFmpegUtils, GetNativeSampleFormatMapsCorrectly)
|
||||
EXPECT_EQ(out, olive::core::SampleFormat::invalid);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetNativeSampleFormatNullOut)
|
||||
TEST(OakFFmpegUtils, GetNativeSampleFormatNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_get_native_sample_format(
|
||||
fb_sample_fmt_u8, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetFFmpegSampleFormatMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, GetFFmpegSampleFormatMapsCorrectly)
|
||||
{
|
||||
int out = -2;
|
||||
|
||||
@@ -157,14 +157,14 @@ TEST(OakCommonFFmpegUtils, GetFFmpegSampleFormatMapsCorrectly)
|
||||
EXPECT_EQ(out, fb_sample_fmt_none);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetFFmpegSampleFormatNullOut)
|
||||
TEST(OakFFmpegUtils, GetFFmpegSampleFormatNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_get_ffmpeg_sample_format(
|
||||
olive::core::SampleFormat::u8, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, ConvertJpegSpaceToRegularSpaceMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, ConvertJpegSpaceToRegularSpaceMapsCorrectly)
|
||||
{
|
||||
int out = -2;
|
||||
|
||||
@@ -184,21 +184,21 @@ TEST(OakCommonFFmpegUtils, ConvertJpegSpaceToRegularSpaceMapsCorrectly)
|
||||
EXPECT_EQ(out, fb_pix_fmt_rgba);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, ConvertJpegSpaceToRegularSpaceNullOut)
|
||||
TEST(OakFFmpegUtils, ConvertJpegSpaceToRegularSpaceNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_convert_jpeg_space_to_regular_space(
|
||||
fb_pix_fmt_rgba, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetCompatibleBridgePixelFormatNullOut)
|
||||
TEST(OakFFmpegUtils, GetCompatibleBridgePixelFormatNullOut)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_ffmpegutils_get_compatible_bridge_pixel_format(
|
||||
fb_pix_fmt_rgba, -1, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakCommonFFmpegUtils, GetCompatibleBridgePixelFormatMapsCorrectly)
|
||||
TEST(OakFFmpegUtils, GetCompatibleBridgePixelFormatMapsCorrectly)
|
||||
{
|
||||
/* Calls fb_find_best_pix_fmt_of_list() in ffmpeg_bridge, which
|
||||
* requires a working FFmpeg runtime environment. */
|
||||
|
||||
@@ -35,7 +35,7 @@ protected:
|
||||
void SetUp() override
|
||||
{
|
||||
handle_ = oakcommon_filefunctions_init();
|
||||
ASSERT_NE(handle_, nullptr);
|
||||
ASSERT_NE(handle_.ctx, nullptr);
|
||||
|
||||
temp_dir_ = fs::temp_directory_path() /
|
||||
fs::path("oakcommon_filefunctions_test_" +
|
||||
@@ -46,8 +46,8 @@ protected:
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
oakcommon_filefunctions_free(handle_);
|
||||
handle_ = nullptr;
|
||||
oakcommon_filefunctions_free(&handle_);
|
||||
handle_.ctx = nullptr;
|
||||
|
||||
std::error_code ec;
|
||||
fs::remove_all(temp_dir_, ec);
|
||||
@@ -84,7 +84,7 @@ protected:
|
||||
return std::string(buf.data());
|
||||
}
|
||||
|
||||
OakCommonFileFunctions *handle_ = nullptr;
|
||||
OakFileFunctions handle_ = {};
|
||||
fs::path temp_dir_;
|
||||
};
|
||||
|
||||
@@ -98,43 +98,36 @@ TEST_F(FileFunctionsTest, NullHandleReturnsInvalid)
|
||||
{
|
||||
char buf[16];
|
||||
int out = 0;
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_configuration_location(
|
||||
nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_configuration_location(OakFileFunctions{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_application_path(nullptr, buf,
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_application_path(OakFileFunctions{}, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_temp_file_path(nullptr, buf,
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_temp_file_path(OakFileFunctions{}, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_auto_recovery_root(nullptr, buf,
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_auto_recovery_root(OakFileFunctions{}, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_unique_file_identifier(
|
||||
nullptr, "x", buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_unique_file_identifier(OakFileFunctions{}, "x", buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_ensure_filename_extension(
|
||||
nullptr, "x", "y", buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_filefunctions_ensure_filename_extension(OakFileFunctions{}, "x", "y", buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_read_file_as_string(nullptr, "x",
|
||||
EXPECT_EQ(oakcommon_filefunctions_read_file_as_string(OakFileFunctions{}, "x",
|
||||
buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_safe_temporary_filename(
|
||||
nullptr, "x", buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_safe_temporary_filename(OakFileFunctions{}, "x", buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_formatted_executable_for_platform(
|
||||
nullptr, "x", buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_filefunctions_get_formatted_executable_for_platform(OakFileFunctions{}, "x", buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_directory_is_valid(nullptr, "x", 1,
|
||||
EXPECT_EQ(oakcommon_filefunctions_directory_is_valid(OakFileFunctions{}, "x", 1,
|
||||
&out),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_can_copy_directory_without_overwriting(
|
||||
nullptr, "a", "b", &out),
|
||||
EXPECT_EQ(oakcommon_filefunctions_can_copy_directory_without_overwriting(OakFileFunctions{}, "a", "b", &out),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_copy_directory(nullptr, "a", "b", 0),
|
||||
EXPECT_EQ(oakcommon_filefunctions_copy_directory(OakFileFunctions{}, "a", "b", 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_filefunctions_rename_file_allow_overwrite(
|
||||
nullptr, "a", "b", &out),
|
||||
EXPECT_EQ(oakcommon_filefunctions_rename_file_allow_overwrite(OakFileFunctions{}, "a", "b", &out),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/***
|
||||
|
||||
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/>.
|
||||
|
||||
***/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common/colortransform.h"
|
||||
#include "common/commandlineparser.h"
|
||||
#include "common/current.h"
|
||||
#include "common/filefunctions.h"
|
||||
#include "common/ocioutils.h"
|
||||
#include "common/oiioutils.h"
|
||||
#include "common/subtitleparams.h"
|
||||
#include "common/videoparams.h"
|
||||
#include "common/xmlutils.h"
|
||||
|
||||
// Native C++ headers (exported through the oakcommon target's public
|
||||
// include dirs) for the init_from_native tests.
|
||||
#include "colortransform.h"
|
||||
#include "subtitleparams.h"
|
||||
#include "videoparams.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Every init-produced handle must carry the current ABI version
|
||||
* and non-NULL addref/release thunks.
|
||||
*/
|
||||
template <typename Handle> void expect_valid_handle(const Handle &h)
|
||||
{
|
||||
EXPECT_NE(h.ctx, nullptr);
|
||||
EXPECT_NE(h.addref, nullptr);
|
||||
EXPECT_NE(h.release, nullptr);
|
||||
EXPECT_EQ(h.abi_version, OAKCOMMON_ABI_VERSION);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(OakHandle, AbiVersionStampedEverywhere)
|
||||
{
|
||||
OakVideoParams vp = oakcommon_videoparams_init();
|
||||
expect_valid_handle(vp);
|
||||
oakcommon_videoparams_free(&vp);
|
||||
|
||||
OakSubtitleParams sp = oakcommon_subtitleparams_init();
|
||||
expect_valid_handle(sp);
|
||||
oakcommon_subtitleparams_free(&sp);
|
||||
|
||||
OakColorTransform ct = oakcommon_colortransform_init_output("sRGB");
|
||||
expect_valid_handle(ct);
|
||||
oakcommon_colortransform_free(&ct);
|
||||
|
||||
OakCommandLineParser parser = oakcommon_commandlineparser_init();
|
||||
expect_valid_handle(parser);
|
||||
|
||||
const char *names[] = { "h" };
|
||||
OakCommandLineOption option = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_option(
|
||||
parser, names, 1, "help", 0, nullptr, 0, &option),
|
||||
OAKCOMMON_OK);
|
||||
expect_valid_handle(option);
|
||||
oakcommon_commandlineoption_free(&option);
|
||||
|
||||
OakCommandLinePositionalArgument arg = {};
|
||||
ASSERT_EQ(oakcommon_commandlineparser_add_positional_argument(
|
||||
parser, "file", "desc", 0, &arg),
|
||||
OAKCOMMON_OK);
|
||||
expect_valid_handle(arg);
|
||||
oakcommon_commandlinepositionalargument_free(&arg);
|
||||
oakcommon_commandlineparser_free(&parser);
|
||||
|
||||
OakXmlReader reader =
|
||||
oakcommon_xml_reader_init("<root/>");
|
||||
expect_valid_handle(reader);
|
||||
oakcommon_xml_reader_free(&reader);
|
||||
|
||||
OakXmlWriter writer = oakcommon_xml_writer_init();
|
||||
expect_valid_handle(writer);
|
||||
oakcommon_xml_writer_free(&writer);
|
||||
|
||||
OakFileFunctions ff = oakcommon_filefunctions_init();
|
||||
expect_valid_handle(ff);
|
||||
oakcommon_filefunctions_free(&ff);
|
||||
|
||||
OakOCIOUtils ocio = oakcommon_ocioutils_init();
|
||||
expect_valid_handle(ocio);
|
||||
oakcommon_ocioutils_free(&ocio);
|
||||
|
||||
OakOIIOUtils oiio = oakcommon_oiioutils_init();
|
||||
expect_valid_handle(oiio);
|
||||
oakcommon_oiioutils_free(&oiio);
|
||||
|
||||
OakCurrent current = oakcommon_current_instance();
|
||||
expect_valid_handle(current);
|
||||
}
|
||||
|
||||
TEST(OakHandle, AddrefReleaseCountSemantics)
|
||||
{
|
||||
OakVideoParams h = oakcommon_videoparams_init();
|
||||
ASSERT_NE(h.ctx, nullptr);
|
||||
|
||||
ASSERT_EQ(oakcommon_videoparams_set_width(h, 1920), OAKCOMMON_OK);
|
||||
|
||||
// Copy the handle struct and take a second reference through the
|
||||
// function pointer, like a foreign (Rust/DLL) consumer would.
|
||||
OakVideoParams copy = h;
|
||||
h.addref(h.ctx);
|
||||
|
||||
// Dropping the first reference must not destroy the object: the copy
|
||||
// is still fully usable.
|
||||
h.release(h.ctx);
|
||||
int width = 0;
|
||||
ASSERT_EQ(oakcommon_videoparams_get_width(copy, &width), OAKCOMMON_OK);
|
||||
EXPECT_EQ(width, 1920);
|
||||
|
||||
// Dropping the last reference destroys the object; free() clears ctx.
|
||||
oakcommon_videoparams_free(©);
|
||||
EXPECT_EQ(copy.ctx, nullptr);
|
||||
}
|
||||
|
||||
TEST(OakHandle, FreeNullAndEmptyCtxAreNoOp)
|
||||
{
|
||||
// NULL handle pointer.
|
||||
oakcommon_videoparams_free(nullptr);
|
||||
oakcommon_subtitleparams_free(nullptr);
|
||||
oakcommon_colortransform_free(nullptr);
|
||||
oakcommon_commandlineparser_free(nullptr);
|
||||
oakcommon_commandlineoption_free(nullptr);
|
||||
oakcommon_commandlinepositionalargument_free(nullptr);
|
||||
oakcommon_xml_reader_free(nullptr);
|
||||
oakcommon_xml_writer_free(nullptr);
|
||||
oakcommon_filefunctions_free(nullptr);
|
||||
oakcommon_ocioutils_free(nullptr);
|
||||
oakcommon_oiioutils_free(nullptr);
|
||||
oakcommon_current_free(nullptr);
|
||||
|
||||
// Handle whose ctx is NULL (e.g. after a failed init or a free).
|
||||
OakVideoParams h = {};
|
||||
oakcommon_videoparams_free(&h);
|
||||
int width = 0;
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(h, &width),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
// release() itself must tolerate a NULL ctx (foreign consumers may
|
||||
// call it directly).
|
||||
h.release = nullptr; // no thunk available on a zero-initialized handle
|
||||
oakcommon_videoparams_free(&h);
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
TEST(OakHandle, VideoParamsFromNativeSurvivesSource)
|
||||
{
|
||||
OakVideoParams h = {};
|
||||
{
|
||||
olive::VideoParams native(
|
||||
1920, 1080, olive::core::Rational(1, 25),
|
||||
olive::core::PixelFormat::u8, 4, olive::core::Rational(1, 1),
|
||||
olive::VideoParams::k_interlace_none, 1);
|
||||
h = oakcommon_videoparams_init_from_native(&native);
|
||||
ASSERT_NE(h.ctx, nullptr);
|
||||
EXPECT_EQ(h.abi_version, OAKCOMMON_ABI_VERSION);
|
||||
} // native stack object destroyed here
|
||||
|
||||
int width = 0, height = 0, num = 0, den = 0;
|
||||
ASSERT_EQ(oakcommon_videoparams_get_width(h, &width), OAKCOMMON_OK);
|
||||
ASSERT_EQ(oakcommon_videoparams_get_height(h, &height), OAKCOMMON_OK);
|
||||
ASSERT_EQ(oakcommon_videoparams_get_time_base(h, &num, &den),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(width, 1920);
|
||||
EXPECT_EQ(height, 1080);
|
||||
EXPECT_EQ(num, 1);
|
||||
EXPECT_EQ(den, 25);
|
||||
oakcommon_videoparams_free(&h);
|
||||
|
||||
// NULL source yields an empty handle, not a crash.
|
||||
OakVideoParams empty =
|
||||
oakcommon_videoparams_init_from_native(nullptr);
|
||||
EXPECT_EQ(empty.ctx, nullptr);
|
||||
}
|
||||
|
||||
TEST(OakHandle, SubtitleParamsFromNativeSurvivesSource)
|
||||
{
|
||||
OakSubtitleParams h = {};
|
||||
{
|
||||
olive::SubtitleParams native;
|
||||
native.push_back(olive::Subtitle(
|
||||
olive::core::TimeRange(olive::core::Rational(0, 1),
|
||||
olive::core::Rational(2, 1)),
|
||||
"hello"));
|
||||
h = oakcommon_subtitleparams_init_from_native(&native);
|
||||
ASSERT_NE(h.ctx, nullptr);
|
||||
} // native stack object destroyed here
|
||||
|
||||
int count = 0;
|
||||
ASSERT_EQ(oakcommon_subtitleparams_count(h, &count), OAKCOMMON_OK);
|
||||
EXPECT_EQ(count, 1);
|
||||
|
||||
char buf[16];
|
||||
int needed = oakcommon_subtitleparams_get_subtitle_text(h, 0, buf,
|
||||
sizeof(buf));
|
||||
ASSERT_EQ(needed, 6);
|
||||
EXPECT_STREQ(buf, "hello");
|
||||
oakcommon_subtitleparams_free(&h);
|
||||
}
|
||||
|
||||
TEST(OakHandle, ColorTransformFromNativeSurvivesSource)
|
||||
{
|
||||
OakColorTransform h = {};
|
||||
{
|
||||
olive::ColorTransform native(std::string("Display"),
|
||||
std::string("Standard"),
|
||||
std::string("None"));
|
||||
h = oakcommon_colortransform_init_from_native(&native);
|
||||
ASSERT_NE(h.ctx, nullptr);
|
||||
} // native stack object destroyed here
|
||||
|
||||
int is_display = 0;
|
||||
ASSERT_EQ(oakcommon_colortransform_is_display(h, &is_display),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(is_display, 1);
|
||||
|
||||
char buf[16];
|
||||
int needed = oakcommon_colortransform_get_view(h, buf, sizeof(buf));
|
||||
ASSERT_EQ(needed, 9);
|
||||
EXPECT_STREQ(buf, "Standard");
|
||||
oakcommon_colortransform_free(&h);
|
||||
}
|
||||
|
||||
TEST(OakHandle, CurrentSingletonReleaseNeverDestroys)
|
||||
{
|
||||
OakCurrent h = oakcommon_current_instance();
|
||||
ASSERT_NE(h.ctx, nullptr);
|
||||
void *ctx = h.ctx;
|
||||
|
||||
// The singleton's addref/release are deliberate no-ops.
|
||||
h.addref(h.ctx);
|
||||
h.release(h.ctx);
|
||||
oakcommon_current_free(&h);
|
||||
|
||||
OakCurrent again = oakcommon_current_instance();
|
||||
EXPECT_EQ(again.ctx, ctx);
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/***
|
||||
|
||||
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/>.
|
||||
|
||||
***/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
// Native C++ header (exported through the oakcommon target's public
|
||||
// include dirs) for sink injection.
|
||||
#include "debug.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief RAII helper: captures all filtered log lines into a vector and
|
||||
* restores the default stderr sink and level on destruction.
|
||||
*/
|
||||
class LogCapture {
|
||||
public:
|
||||
LogCapture()
|
||||
{
|
||||
olive::set_log_sink([this](const std::string &line) {
|
||||
lines.push_back(line);
|
||||
});
|
||||
}
|
||||
|
||||
~LogCapture()
|
||||
{
|
||||
olive::set_log_sink(nullptr);
|
||||
olive::set_log_level(olive::k_debug_info);
|
||||
}
|
||||
|
||||
std::vector<std::string> lines;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(OakLog, LevelSetGetRoundTrip)
|
||||
{
|
||||
ASSERT_EQ(oakcommon_log_set_level(OAKCOMMON_DEBUG_WARNING),
|
||||
OAKCOMMON_OK);
|
||||
int level = -1;
|
||||
ASSERT_EQ(oakcommon_log_get_level(&level), OAKCOMMON_OK);
|
||||
EXPECT_EQ(level, OAKCOMMON_DEBUG_WARNING);
|
||||
|
||||
ASSERT_EQ(oakcommon_log_set_level(OAKCOMMON_DEBUG_DEBUG),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_EQ(oakcommon_log_get_level(&level), OAKCOMMON_OK);
|
||||
EXPECT_EQ(level, OAKCOMMON_DEBUG_DEBUG);
|
||||
|
||||
// Restore default for other tests.
|
||||
ASSERT_EQ(oakcommon_log_set_level(OAKCOMMON_DEBUG_INFO), OAKCOMMON_OK);
|
||||
}
|
||||
|
||||
TEST(OakLog, LevelSetGetInvalidArgs)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_log_set_level(-1), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_log_set_level(999), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_log_get_level(nullptr), OAKCOMMON_E_INVALID);
|
||||
|
||||
// The failed sets above must not have changed the level.
|
||||
int level = -1;
|
||||
ASSERT_EQ(oakcommon_log_get_level(&level), OAKCOMMON_OK);
|
||||
EXPECT_EQ(level, OAKCOMMON_DEBUG_INFO);
|
||||
}
|
||||
|
||||
TEST(OakLog, LevelFilterDropsLowerLevels)
|
||||
{
|
||||
LogCapture capture;
|
||||
|
||||
ASSERT_EQ(oakcommon_log_set_level(OAKCOMMON_DEBUG_WARNING),
|
||||
OAKCOMMON_OK);
|
||||
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_DEBUG, "dbg"), OAKCOMMON_OK);
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_INFO, "inf"), OAKCOMMON_OK);
|
||||
EXPECT_TRUE(capture.lines.empty());
|
||||
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_WARNING, "wrn"), OAKCOMMON_OK);
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_ERROR, "err"), OAKCOMMON_OK);
|
||||
ASSERT_EQ(capture.lines.size(), 2u);
|
||||
EXPECT_EQ(capture.lines[0], "[WARNING] wrn\n");
|
||||
EXPECT_EQ(capture.lines[1], "[ERROR] err\n");
|
||||
}
|
||||
|
||||
TEST(OakLog, DefaultLevelIsInfo)
|
||||
{
|
||||
// The default filter is INFO: DEBUG is dropped, INFO passes.
|
||||
LogCapture capture;
|
||||
|
||||
olive::log_debug("invisible");
|
||||
olive::log_info("visible");
|
||||
ASSERT_EQ(capture.lines.size(), 1u);
|
||||
EXPECT_EQ(capture.lines[0], "[INFO] visible\n");
|
||||
}
|
||||
|
||||
TEST(OakLog, ConvenienceWrappersUseTheirLevels)
|
||||
{
|
||||
LogCapture capture;
|
||||
olive::set_log_level(olive::k_debug_debug);
|
||||
|
||||
olive::log_debug("d");
|
||||
olive::log_info("i");
|
||||
olive::log_warning("w");
|
||||
olive::log_critical("c");
|
||||
ASSERT_EQ(capture.lines.size(), 4u);
|
||||
EXPECT_EQ(capture.lines[0], "[DEBUG] d\n");
|
||||
EXPECT_EQ(capture.lines[1], "[INFO] i\n");
|
||||
EXPECT_EQ(capture.lines[2], "[WARNING] w\n");
|
||||
EXPECT_EQ(capture.lines[3], "[ERROR] c\n");
|
||||
}
|
||||
|
||||
TEST(OakLog, PrintfFormatting)
|
||||
{
|
||||
LogCapture capture;
|
||||
olive::set_log_level(olive::k_debug_debug);
|
||||
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_INFO, "w=%d h=%d name=%s",
|
||||
1920, 1080, "clip"),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_EQ(capture.lines.size(), 1u);
|
||||
EXPECT_EQ(capture.lines[0], "[INFO] w=1920 h=1080 name=clip\n");
|
||||
}
|
||||
|
||||
TEST(OakLog, PrintfLongMessageNotTruncated)
|
||||
{
|
||||
LogCapture capture;
|
||||
|
||||
std::string long_msg(100 * 1024, 'x');
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_WARNING, "%s",
|
||||
long_msg.c_str()),
|
||||
OAKCOMMON_OK);
|
||||
ASSERT_EQ(capture.lines.size(), 1u);
|
||||
EXPECT_EQ(capture.lines[0],
|
||||
"[WARNING] " + long_msg + "\n");
|
||||
}
|
||||
|
||||
TEST(OakLog, PrintfNullFormat)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_log(OAKCOMMON_DEBUG_WARNING, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OakLog, OutOfRangeLevelPrintsUnknown)
|
||||
{
|
||||
LogCapture capture;
|
||||
olive::set_log_level(olive::k_debug_debug);
|
||||
|
||||
// Out-of-range levels are tolerated and print as UNKNOWN (same as
|
||||
// oakcommon_debug_log).
|
||||
EXPECT_EQ(oakcommon_log(999, "odd"), OAKCOMMON_OK);
|
||||
ASSERT_EQ(capture.lines.size(), 1u);
|
||||
EXPECT_EQ(capture.lines[0], "[UNKNOWN] odd\n");
|
||||
}
|
||||
@@ -34,9 +34,9 @@ namespace ocio = OCIO_NAMESPACE;
|
||||
|
||||
TEST(OCIOUtilsCApi, InitReturnsHandle)
|
||||
{
|
||||
OakCommonOCIOUtils *utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
oakcommon_ocioutils_free(utils);
|
||||
OakOCIOUtils utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
oakcommon_ocioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OCIOUtilsCApi, FreeNullIsNoOp)
|
||||
@@ -46,8 +46,8 @@ TEST(OCIOUtilsCApi, FreeNullIsNoOp)
|
||||
|
||||
TEST(OCIOUtilsCApi, BitDepthMappingMatchesOCIO)
|
||||
{
|
||||
OakCommonOCIOUtils *utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOCIOUtils utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
const struct {
|
||||
int pixel_format;
|
||||
@@ -68,13 +68,13 @@ TEST(OCIOUtilsCApi, BitDepthMappingMatchesOCIO)
|
||||
EXPECT_EQ(depth, static_cast<int>(c.expected));
|
||||
}
|
||||
|
||||
oakcommon_ocioutils_free(utils);
|
||||
oakcommon_ocioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OCIOUtilsCApi, InvalidFormatYieldsUnknownDepth)
|
||||
{
|
||||
OakCommonOCIOUtils *utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOCIOUtils utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int depth = -1;
|
||||
EXPECT_EQ(oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
@@ -82,33 +82,32 @@ TEST(OCIOUtilsCApi, InvalidFormatYieldsUnknownDepth)
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(depth, static_cast<int>(ocio::BIT_DEPTH_UNKNOWN));
|
||||
|
||||
oakcommon_ocioutils_free(utils);
|
||||
oakcommon_ocioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OCIOUtilsCApi, NullHandleReturnsInvalid)
|
||||
{
|
||||
int depth = 0;
|
||||
EXPECT_EQ(oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
NULL, OAKCOMMON_PIXEL_FORMAT_U8, &depth),
|
||||
EXPECT_EQ(oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(OakOCIOUtils{}, OAKCOMMON_PIXEL_FORMAT_U8, &depth),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(OCIOUtilsCApi, NullOutParamReturnsInvalid)
|
||||
{
|
||||
OakCommonOCIOUtils *utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOCIOUtils utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
EXPECT_EQ(oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
utils, OAKCOMMON_PIXEL_FORMAT_U8, NULL),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_ocioutils_free(utils);
|
||||
oakcommon_ocioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OCIOUtilsCApi, OutOfRangeFormatReturnsInvalid)
|
||||
{
|
||||
OakCommonOCIOUtils *utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOCIOUtils utils = oakcommon_ocioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int depth = 0;
|
||||
EXPECT_EQ(oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
@@ -118,5 +117,5 @@ TEST(OCIOUtilsCApi, OutOfRangeFormatReturnsInvalid)
|
||||
utils, -2, &depth),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_ocioutils_free(utils);
|
||||
oakcommon_ocioutils_free(&utils);
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
|
||||
TEST(OIIOUtilsCApi, InitReturnsHandle)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
oakcommon_oiioutils_free(utils);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, FreeNullIsNoOp)
|
||||
@@ -49,8 +49,8 @@ TEST(OIIOUtilsCApi, FreeNullIsNoOp)
|
||||
|
||||
TEST(OIIOUtilsCApi, BaseTypeFromPixelFormat)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
const struct {
|
||||
int pixel_format;
|
||||
@@ -72,17 +72,16 @@ TEST(OIIOUtilsCApi, BaseTypeFromPixelFormat)
|
||||
EXPECT_EQ(base_type, c.expected_base_type);
|
||||
}
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, BaseTypeFromPixelFormatRejectsBadArgs)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int base_type = 0;
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_oiio_base_type_from_format(
|
||||
NULL, OAKCOMMON_PIXEL_FORMAT_U8, &base_type),
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_oiio_base_type_from_format(OakOIIOUtils{}, OAKCOMMON_PIXEL_FORMAT_U8, &base_type),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_oiio_base_type_from_format(
|
||||
utils, OAKCOMMON_PIXEL_FORMAT_U8, NULL),
|
||||
@@ -94,13 +93,13 @@ TEST(OIIOUtilsCApi, BaseTypeFromPixelFormatRejectsBadArgs)
|
||||
utils, -2, &base_type),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, PixelFormatFromBaseType)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
const struct {
|
||||
int base_type;
|
||||
@@ -123,17 +122,16 @@ TEST(OIIOUtilsCApi, PixelFormatFromBaseType)
|
||||
EXPECT_EQ(pixel_format, c.expected_pixel_format);
|
||||
}
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, PixelFormatFromBaseTypeRejectsBadArgs)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int pixel_format = 0;
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_format_from_oiio_basetype(
|
||||
NULL, 2, &pixel_format),
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_format_from_oiio_basetype(OakOIIOUtils{}, 2, &pixel_format),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_format_from_oiio_basetype(
|
||||
utils, 2, NULL),
|
||||
@@ -145,13 +143,13 @@ TEST(OIIOUtilsCApi, PixelFormatFromBaseTypeRejectsBadArgs)
|
||||
utils, 100, &pixel_format),
|
||||
OAKCOMMON_E_INVALID); /* >= LASTBASE */
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, PixelAspectRatioConvertsToRational)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int num = 0;
|
||||
int den = 0;
|
||||
@@ -167,17 +165,17 @@ TEST(OIIOUtilsCApi, PixelAspectRatioConvertsToRational)
|
||||
ASSERT_NE(den, 0);
|
||||
EXPECT_NEAR(static_cast<double>(num) / den, 1.5, 1e-9);
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
TEST(OIIOUtilsCApi, PixelAspectRatioRejectsBadArgs)
|
||||
{
|
||||
OakCommonOIIOUtils *utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils, nullptr);
|
||||
OakOIIOUtils utils = oakcommon_oiioutils_init();
|
||||
ASSERT_NE(utils.ctx, nullptr);
|
||||
|
||||
int num = 0;
|
||||
int den = 0;
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_pixel_aspect_ratio(NULL, 1.0, &num,
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_pixel_aspect_ratio(OakOIIOUtils{}, 1.0, &num,
|
||||
&den),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_oiioutils_get_pixel_aspect_ratio(utils, 1.0, NULL,
|
||||
@@ -187,5 +185,5 @@ TEST(OIIOUtilsCApi, PixelAspectRatioRejectsBadArgs)
|
||||
NULL),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_oiioutils_free(utils);
|
||||
oakcommon_oiioutils_free(&utils);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace
|
||||
{
|
||||
|
||||
std::string read_indexed_string(
|
||||
int (*fn)(OakCommonSubtitleParams *, int, char *, int),
|
||||
OakCommonSubtitleParams *p, int index)
|
||||
int (*fn)(OakSubtitleParams, int, char *, int),
|
||||
OakSubtitleParams p, int index)
|
||||
{
|
||||
int needed = fn(p, index, nullptr, 0);
|
||||
EXPECT_GT(needed, 0);
|
||||
@@ -53,8 +53,8 @@ std::string read_static_string(int (*fn)(char *, int))
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, InitFree)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int index = -1;
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_stream_index(p, &index),
|
||||
@@ -66,7 +66,7 @@ TEST(CommonSubtitleParamsCApi, InitFree)
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(enabled, 1);
|
||||
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, FreeNull)
|
||||
@@ -76,48 +76,48 @@ TEST(CommonSubtitleParamsCApi, FreeNull)
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, SetStreamIndex)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_stream_index(p, 3), OAKCOMMON_OK);
|
||||
int index = 0;
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_stream_index(p, &index),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(index, 3);
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, SetStreamIndexNullHandle)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_stream_index(nullptr, 3),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_stream_index(OakSubtitleParams{}, 3),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_stream_index(nullptr, nullptr),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_stream_index(OakSubtitleParams{}, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, SetEnabled)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_enabled(p, 0), OAKCOMMON_OK);
|
||||
int enabled = 1;
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_enabled(p, &enabled),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(enabled, 0);
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, SetEnabledNullHandle)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_enabled(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_enabled(OakSubtitleParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_enabled(nullptr, nullptr),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_enabled(OakSubtitleParams{}, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, AddAndReadSubtitles)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int is_valid = 1;
|
||||
EXPECT_EQ(oakcommon_subtitleparams_is_valid(p, &is_valid), OAKCOMMON_OK);
|
||||
@@ -156,40 +156,40 @@ TEST(CommonSubtitleParamsCApi, AddAndReadSubtitles)
|
||||
EXPECT_EQ(oakcommon_subtitleparams_count(p, &count), OAKCOMMON_OK);
|
||||
EXPECT_EQ(count, 0);
|
||||
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, SubtitleErrorPaths)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int i = 0;
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_subtitleparams_add_subtitle(nullptr, 0, 1, 1, 1, "x"),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_add_subtitle(OakSubtitleParams{}, 0, 1, 1, 1, "x"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_add_subtitle(p, 0, 1, 1, 1, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle(p, 0, &i, &i, &i, &i),
|
||||
OAKCOMMON_E_NOT_FOUND);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle(nullptr, 0, &i, &i, &i,
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle(OakSubtitleParams{}, 0, &i, &i, &i,
|
||||
&i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle_text(p, 5, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_NOT_FOUND);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle_text(nullptr, 0, buf,
|
||||
EXPECT_EQ(oakcommon_subtitleparams_get_subtitle_text(OakSubtitleParams{}, 0, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_is_valid(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_is_valid(OakSubtitleParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_count(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_count(OakSubtitleParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_duration(nullptr, &i, &i),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_duration(OakSubtitleParams{}, &i, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_clear(nullptr), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_clear(OakSubtitleParams{}), OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, GenerateAssHeader)
|
||||
@@ -203,8 +203,8 @@ TEST(CommonSubtitleParamsCApi, GenerateAssHeader)
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, XmlRoundTrip)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_set_stream_index(p, 2), OAKCOMMON_OK);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_add_subtitle(p, 1, 25, 2, 25,
|
||||
"First <line>"),
|
||||
@@ -215,8 +215,8 @@ TEST(CommonSubtitleParamsCApi, XmlRoundTrip)
|
||||
std::vector<char> buf(needed);
|
||||
ASSERT_EQ(oakcommon_subtitleparams_save_xml(p, buf.data(), needed), needed);
|
||||
|
||||
OakCommonSubtitleParams *q = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(q, nullptr);
|
||||
OakSubtitleParams q = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(q.ctx, nullptr);
|
||||
ASSERT_EQ(oakcommon_subtitleparams_load_xml(q, buf.data()), OAKCOMMON_OK);
|
||||
|
||||
int index = 0;
|
||||
@@ -230,22 +230,22 @@ TEST(CommonSubtitleParamsCApi, XmlRoundTrip)
|
||||
oakcommon_subtitleparams_get_subtitle_text, q, 0),
|
||||
"First <line>");
|
||||
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(q);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
oakcommon_subtitleparams_free(&q);
|
||||
}
|
||||
|
||||
TEST(CommonSubtitleParamsCApi, XmlErrorPaths)
|
||||
{
|
||||
OakCommonSubtitleParams *p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakSubtitleParams p = oakcommon_subtitleparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_subtitleparams_load_xml(nullptr, "<a/>"),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_load_xml(OakSubtitleParams{}, "<a/>"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_load_xml(p, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_load_xml(p, "not xml"),
|
||||
OAKCOMMON_E_FAILED);
|
||||
EXPECT_EQ(oakcommon_subtitleparams_save_xml(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_subtitleparams_save_xml(OakSubtitleParams{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_subtitleparams_free(p);
|
||||
oakcommon_subtitleparams_free(&p);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
TEST(CommonVideoParamsCApi, InitDefaults)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakVideoParams p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int v = -1;
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(p, &v), OAKCOMMON_OK);
|
||||
@@ -38,7 +38,7 @@ TEST(CommonVideoParamsCApi, InitDefaults)
|
||||
EXPECT_EQ(oakcommon_videoparams_get_is_valid(p, &v), OAKCOMMON_OK);
|
||||
EXPECT_EQ(v, 0);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, FreeNull)
|
||||
@@ -48,10 +48,10 @@ TEST(CommonVideoParamsCApi, FreeNull)
|
||||
|
||||
TEST(CommonVideoParamsCApi, InitBasic)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init_basic(
|
||||
OakVideoParams p = oakcommon_videoparams_init_basic(
|
||||
1920, 1080, OAKCOMMON_PIXEL_FORMAT_U8,
|
||||
4, 1, 1, OAKCOMMON_VIDEO_INTERLACE_NONE, 2);
|
||||
ASSERT_NE(p, nullptr);
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int v;
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(p, &v), OAKCOMMON_OK);
|
||||
@@ -91,15 +91,15 @@ TEST(CommonVideoParamsCApi, InitBasic)
|
||||
EXPECT_EQ(oakcommon_videoparams_get_buffer_size(p, &v), OAKCOMMON_OK);
|
||||
EXPECT_EQ(v, 1920 * 1080 * 4);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, InitWithTimeBase)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init_with_time_base(
|
||||
OakVideoParams p = oakcommon_videoparams_init_with_time_base(
|
||||
1280, 720, 1001, 30000, OAKCOMMON_PIXEL_FORMAT_F32, 4, 1, 1,
|
||||
OAKCOMMON_VIDEO_INTERLACE_NONE, 1);
|
||||
ASSERT_NE(p, nullptr);
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int num, den;
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_base(p, &num, &den),
|
||||
@@ -117,13 +117,13 @@ TEST(CommonVideoParamsCApi, InitWithTimeBase)
|
||||
EXPECT_EQ(num, 1001);
|
||||
EXPECT_EQ(den, 30000);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, ScalarSetters)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakVideoParams p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int v;
|
||||
EXPECT_EQ(oakcommon_videoparams_set_width(p, 640), OAKCOMMON_OK);
|
||||
@@ -205,7 +205,7 @@ TEST(CommonVideoParamsCApi, ScalarSetters)
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_depth(p, &v), OAKCOMMON_OK);
|
||||
EXPECT_EQ(v, 1);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, NullHandleErrors)
|
||||
@@ -214,123 +214,123 @@ TEST(CommonVideoParamsCApi, NullHandleErrors)
|
||||
float f;
|
||||
int64_t i64;
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_width(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_width(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_height(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_height(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_height(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_height(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_depth(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_depth(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_depth(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_depth(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_is_3d(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_is_3d(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_base(nullptr, &i, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_base(OakVideoParams{}, &i, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_time_base(nullptr, 1, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_time_base(OakVideoParams{}, 1, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_frame_rate(nullptr, &i, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_frame_rate(OakVideoParams{}, &i, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_frame_rate(nullptr, 1, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_frame_rate(OakVideoParams{}, 1, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_frame_rate_as_time_base(nullptr, &i, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_frame_rate_as_time_base(OakVideoParams{}, &i, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_pixel_aspect_ratio(nullptr, &i, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_pixel_aspect_ratio(OakVideoParams{}, &i, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_pixel_aspect_ratio(nullptr, 1, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_pixel_aspect_ratio(OakVideoParams{}, 1, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_format(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_format(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_format(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_format(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_channel_count(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_channel_count(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_channel_count(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_channel_count(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_interlacing(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_interlacing(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_interlacing(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_interlacing(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_divider(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_divider(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_divider(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_divider(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_enabled(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_enabled(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_enabled(nullptr, 1),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_enabled(OakVideoParams{}, 1),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_x(nullptr, &f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_x(nullptr, 0.0f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_y(nullptr, &f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_y(nullptr, 0.0f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_stream_index(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_x(OakVideoParams{}, &f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_x(OakVideoParams{}, 0.0f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_y(OakVideoParams{}, &f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_y(OakVideoParams{}, 0.0f), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_stream_index(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_stream_index(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_stream_index(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_video_type(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_video_type(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_video_type(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_video_type(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_start_time(nullptr, &i64),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_start_time(OakVideoParams{}, &i64),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_start_time(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_start_time(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_duration(nullptr, &i64),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_duration(OakVideoParams{}, &i64),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_duration(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_duration(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_premultiplied_alpha(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_premultiplied_alpha(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_premultiplied_alpha(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_premultiplied_alpha(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_range(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_range(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_range(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_range(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_primaries(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_primaries(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_primaries(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_primaries(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_transfer(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_transfer(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_transfer(nullptr, 0),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_transfer(OakVideoParams{}, 0),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_colorspace(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_colorspace(OakVideoParams{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_colorspace(nullptr, "x"),
|
||||
EXPECT_EQ(oakcommon_videoparams_set_colorspace(OakVideoParams{}, "x"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_square_pixel_width(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_square_pixel_width(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_width(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_width(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_height(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_height(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_depth(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_effective_depth(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_is_valid(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_is_valid(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_bytes_per_channel(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_bytes_per_channel(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_bytes_per_pixel(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_bytes_per_pixel(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_buffer_size(nullptr, &i),
|
||||
EXPECT_EQ(oakcommon_videoparams_get_buffer_size(OakVideoParams{}, &i),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_in_timebase_units(nullptr, 0, 1,
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_in_timebase_units(OakVideoParams{}, 0, 1,
|
||||
&i64),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_load_xml(nullptr, "<a/>"),
|
||||
EXPECT_EQ(oakcommon_videoparams_load_xml(OakVideoParams{}, "<a/>"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_save_xml(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_videoparams_save_xml(OakVideoParams{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, NullOutParamErrors)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakVideoParams p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_width(p, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_base(p, nullptr, nullptr),
|
||||
@@ -340,13 +340,13 @@ TEST(CommonVideoParamsCApi, NullOutParamErrors)
|
||||
EXPECT_EQ(oakcommon_videoparams_load_xml(p, nullptr), OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_load_xml(p, "not xml"),
|
||||
OAKCOMMON_E_FAILED);
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, Colorspace)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p, nullptr);
|
||||
OakVideoParams p = oakcommon_videoparams_init();
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_colorspace(p, "rec709"),
|
||||
OAKCOMMON_OK);
|
||||
int needed = oakcommon_videoparams_get_colorspace(p, nullptr, 0);
|
||||
@@ -355,15 +355,15 @@ TEST(CommonVideoParamsCApi, Colorspace)
|
||||
EXPECT_EQ(oakcommon_videoparams_get_colorspace(p, buf.data(), needed),
|
||||
needed);
|
||||
EXPECT_STREQ(buf.data(), "rec709");
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(&p);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, TimeInTimebaseUnits)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init_with_time_base(
|
||||
OakVideoParams p = oakcommon_videoparams_init_with_time_base(
|
||||
1920, 1080, 1, 25, OAKCOMMON_PIXEL_FORMAT_U8, 4, 1, 1,
|
||||
OAKCOMMON_VIDEO_INTERLACE_NONE, 1);
|
||||
ASSERT_NE(p, nullptr);
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
|
||||
int64_t ts = -1;
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_in_timebase_units(p, 2, 1, &ts),
|
||||
@@ -371,26 +371,26 @@ TEST(CommonVideoParamsCApi, TimeInTimebaseUnits)
|
||||
EXPECT_EQ(ts, 50); // 2 seconds at 25 fps
|
||||
|
||||
// Without a time base the result is AV_NOPTS_VALUE
|
||||
OakCommonVideoParams *q = oakcommon_videoparams_init();
|
||||
ASSERT_NE(q, nullptr);
|
||||
OakVideoParams q = oakcommon_videoparams_init();
|
||||
ASSERT_NE(q.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_videoparams_get_time_in_timebase_units(q, 2, 1, &ts),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(ts, INT64_MIN);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(q);
|
||||
oakcommon_videoparams_free(&p);
|
||||
oakcommon_videoparams_free(&q);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, Equals)
|
||||
{
|
||||
OakCommonVideoParams *a = oakcommon_videoparams_init_basic(
|
||||
OakVideoParams a = oakcommon_videoparams_init_basic(
|
||||
1920, 1080, OAKCOMMON_PIXEL_FORMAT_U8, 4, 1, 1,
|
||||
OAKCOMMON_VIDEO_INTERLACE_NONE, 1);
|
||||
OakCommonVideoParams *b = oakcommon_videoparams_init_basic(
|
||||
OakVideoParams b = oakcommon_videoparams_init_basic(
|
||||
1920, 1080, OAKCOMMON_PIXEL_FORMAT_U8, 4, 1, 1,
|
||||
OAKCOMMON_VIDEO_INTERLACE_NONE, 1);
|
||||
ASSERT_NE(a, nullptr);
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_NE(a.ctx, nullptr);
|
||||
ASSERT_NE(b.ctx, nullptr);
|
||||
|
||||
int equal = 0;
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(a, b, &equal), OAKCOMMON_OK);
|
||||
@@ -400,23 +400,23 @@ TEST(CommonVideoParamsCApi, Equals)
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(a, b, &equal), OAKCOMMON_OK);
|
||||
EXPECT_EQ(equal, 0);
|
||||
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(nullptr, b, &equal),
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(OakVideoParams{}, b, &equal),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(a, nullptr, &equal),
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(a, OakVideoParams{}, &equal),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_videoparams_equals(a, b, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_videoparams_free(a);
|
||||
oakcommon_videoparams_free(b);
|
||||
oakcommon_videoparams_free(&a);
|
||||
oakcommon_videoparams_free(&b);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, XmlRoundTrip)
|
||||
{
|
||||
OakCommonVideoParams *p = oakcommon_videoparams_init_with_time_base(
|
||||
OakVideoParams p = oakcommon_videoparams_init_with_time_base(
|
||||
1920, 1080, 1, 25, OAKCOMMON_PIXEL_FORMAT_F16, 4, 4, 3,
|
||||
OAKCOMMON_VIDEO_INTERLACED_BOTTOM_FIRST, 2);
|
||||
ASSERT_NE(p, nullptr);
|
||||
ASSERT_NE(p.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_colorspace(p, "rec709"),
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(oakcommon_videoparams_set_color_primaries(p, 9), OAKCOMMON_OK);
|
||||
@@ -426,8 +426,8 @@ TEST(CommonVideoParamsCApi, XmlRoundTrip)
|
||||
std::vector<char> buf(needed);
|
||||
ASSERT_EQ(oakcommon_videoparams_save_xml(p, buf.data(), needed), needed);
|
||||
|
||||
OakCommonVideoParams *q = oakcommon_videoparams_init();
|
||||
ASSERT_NE(q, nullptr);
|
||||
OakVideoParams q = oakcommon_videoparams_init();
|
||||
ASSERT_NE(q.ctx, nullptr);
|
||||
ASSERT_EQ(oakcommon_videoparams_load_xml(q, buf.data()), OAKCOMMON_OK);
|
||||
|
||||
int equal = 0;
|
||||
@@ -450,8 +450,8 @@ TEST(CommonVideoParamsCApi, XmlRoundTrip)
|
||||
EXPECT_EQ(oakcommon_videoparams_get_color_primaries(q, &v), OAKCOMMON_OK);
|
||||
EXPECT_EQ(v, 9);
|
||||
|
||||
oakcommon_videoparams_free(p);
|
||||
oakcommon_videoparams_free(q);
|
||||
oakcommon_videoparams_free(&p);
|
||||
oakcommon_videoparams_free(&q);
|
||||
}
|
||||
|
||||
TEST(CommonVideoParamsCApi, StaticHelpers)
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string read_string(int (*fn)(OakCommonXmlReader *, char *, int),
|
||||
OakCommonXmlReader *reader)
|
||||
std::string read_string(int (*fn)(OakXmlReader, char *, int),
|
||||
OakXmlReader reader)
|
||||
{
|
||||
int needed = fn(reader, nullptr, 0);
|
||||
EXPECT_GT(needed, 0);
|
||||
@@ -43,7 +43,7 @@ std::string read_string(int (*fn)(OakCommonXmlReader *, char *, int),
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReaderInitNullData)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_xml_reader_init(nullptr), nullptr);
|
||||
EXPECT_EQ(oakcommon_xml_reader_init(nullptr).ctx, nullptr);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReaderFreeNull)
|
||||
@@ -53,9 +53,8 @@ TEST(CommonXmlUtilsCApi, ReaderFreeNull)
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReadNextStartElement)
|
||||
{
|
||||
OakCommonXmlReader *r =
|
||||
oakcommon_xml_reader_init("<root><child>value</child></root>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
OakXmlReader r = oakcommon_xml_reader_init("<root><child>value</child></root>");
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
@@ -68,26 +67,26 @@ TEST(CommonXmlUtilsCApi, ReadNextStartElement)
|
||||
EXPECT_EQ(found, 1);
|
||||
EXPECT_EQ(read_string(oakcommon_xml_reader_name, r), "child");
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReadNextStartElementNullHandle)
|
||||
{
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(nullptr, &found),
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(OakXmlReader{}, &found),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
OakXmlReader r = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReadNextStartElementReturnsFalseAtEnd)
|
||||
{
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
OakXmlReader r = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
|
||||
int found = -1;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
@@ -97,21 +96,21 @@ TEST(CommonXmlUtilsCApi, ReadNextStartElementReturnsFalseAtEnd)
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(found, 0);
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, NameNullHandle)
|
||||
{
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_xml_reader_name(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_xml_reader_name(OakXmlReader{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReadElementText)
|
||||
{
|
||||
OakCommonXmlReader *r =
|
||||
OakXmlReader r =
|
||||
oakcommon_xml_reader_init("<root><child>a & b</child></root>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
@@ -122,22 +121,22 @@ TEST(CommonXmlUtilsCApi, ReadElementText)
|
||||
EXPECT_EQ(read_string(oakcommon_xml_reader_read_element_text, r),
|
||||
"a & b");
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, ReadElementTextNullHandle)
|
||||
{
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_element_text(nullptr, buf,
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_element_text(OakXmlReader{}, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, SkipCurrentElement)
|
||||
{
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init(
|
||||
OakXmlReader r = oakcommon_xml_reader_init(
|
||||
"<root><unknown><nested/></unknown><known/></root>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
@@ -153,20 +152,20 @@ TEST(CommonXmlUtilsCApi, SkipCurrentElement)
|
||||
EXPECT_EQ(found, 1);
|
||||
EXPECT_EQ(read_string(oakcommon_xml_reader_name, r), "known");
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, SkipCurrentElementNullHandle)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_xml_reader_skip_current_element(nullptr),
|
||||
EXPECT_EQ(oakcommon_xml_reader_skip_current_element(OakXmlReader{}),
|
||||
OAKCOMMON_E_INVALID);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, Attributes)
|
||||
{
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init(
|
||||
OakXmlReader r = oakcommon_xml_reader_init(
|
||||
"<root><item id=\"7\" name=\"a"b\"/></root>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
@@ -191,16 +190,16 @@ TEST(CommonXmlUtilsCApi, Attributes)
|
||||
0);
|
||||
EXPECT_STREQ(buf, "a\"b");
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, AttributeErrorPaths)
|
||||
{
|
||||
EXPECT_EQ(oakcommon_xml_reader_attribute_count(nullptr, nullptr),
|
||||
EXPECT_EQ(oakcommon_xml_reader_attribute_count(OakXmlReader{}, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init("<root a=\"1\"/>");
|
||||
ASSERT_NE(r, nullptr);
|
||||
OakXmlReader r = oakcommon_xml_reader_init("<root a=\"1\"/>");
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
int found = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_read_next_start_element(r, &found),
|
||||
OAKCOMMON_OK);
|
||||
@@ -210,30 +209,29 @@ TEST(CommonXmlUtilsCApi, AttributeErrorPaths)
|
||||
OAKCOMMON_E_NOT_FOUND);
|
||||
EXPECT_EQ(oakcommon_xml_reader_attribute_value(r, -1, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_NOT_FOUND);
|
||||
EXPECT_EQ(oakcommon_xml_reader_attribute_name(nullptr, 0, buf,
|
||||
EXPECT_EQ(oakcommon_xml_reader_attribute_name(OakXmlReader{}, 0, buf,
|
||||
sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, HasError)
|
||||
{
|
||||
OakCommonXmlReader *bad =
|
||||
oakcommon_xml_reader_init("<root><unclosed></root>");
|
||||
ASSERT_NE(bad, nullptr);
|
||||
OakXmlReader bad = oakcommon_xml_reader_init("<root><unclosed></root>");
|
||||
ASSERT_NE(bad.ctx, nullptr);
|
||||
int has_error = 0;
|
||||
EXPECT_EQ(oakcommon_xml_reader_has_error(bad, &has_error), OAKCOMMON_OK);
|
||||
EXPECT_EQ(has_error, 1);
|
||||
oakcommon_xml_reader_free(bad);
|
||||
oakcommon_xml_reader_free(&bad);
|
||||
|
||||
OakCommonXmlReader *good = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(good, nullptr);
|
||||
OakXmlReader good = oakcommon_xml_reader_init("<root/>");
|
||||
ASSERT_NE(good.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_xml_reader_has_error(good, &has_error), OAKCOMMON_OK);
|
||||
EXPECT_EQ(has_error, 0);
|
||||
EXPECT_EQ(oakcommon_xml_reader_has_error(nullptr, &has_error),
|
||||
EXPECT_EQ(oakcommon_xml_reader_has_error(OakXmlReader{}, &has_error),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_xml_reader_free(good);
|
||||
oakcommon_xml_reader_free(&good);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, WriterFreeNull)
|
||||
@@ -244,17 +242,17 @@ TEST(CommonXmlUtilsCApi, WriterFreeNull)
|
||||
TEST(CommonXmlUtilsCApi, WriterNullHandleAndArgs)
|
||||
{
|
||||
char buf[16];
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_start_element(nullptr, "a"),
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_start_element(OakXmlWriter{}, "a"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_end_element(nullptr),
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_end_element(OakXmlWriter{}),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_end_document(nullptr),
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_end_document(OakXmlWriter{}),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_xml_writer_output(nullptr, buf, sizeof(buf)),
|
||||
EXPECT_EQ(oakcommon_xml_writer_output(OakXmlWriter{}, buf, sizeof(buf)),
|
||||
OAKCOMMON_E_INVALID);
|
||||
|
||||
OakCommonXmlWriter *w = oakcommon_xml_writer_init();
|
||||
ASSERT_NE(w, nullptr);
|
||||
OakXmlWriter w = oakcommon_xml_writer_init();
|
||||
ASSERT_NE(w.ctx, nullptr);
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_start_element(w, nullptr),
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_attribute(w, "a", nullptr),
|
||||
@@ -263,13 +261,13 @@ TEST(CommonXmlUtilsCApi, WriterNullHandleAndArgs)
|
||||
OAKCOMMON_E_INVALID);
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_text_element(w, nullptr, "x"),
|
||||
OAKCOMMON_E_INVALID);
|
||||
oakcommon_xml_writer_free(w);
|
||||
oakcommon_xml_writer_free(&w);
|
||||
}
|
||||
|
||||
TEST(CommonXmlUtilsCApi, WriterRoundTrip)
|
||||
{
|
||||
OakCommonXmlWriter *w = oakcommon_xml_writer_init();
|
||||
ASSERT_NE(w, nullptr);
|
||||
OakXmlWriter w = oakcommon_xml_writer_init();
|
||||
ASSERT_NE(w.ctx, nullptr);
|
||||
|
||||
EXPECT_EQ(oakcommon_xml_writer_write_start_element(w, "root"),
|
||||
OAKCOMMON_OK);
|
||||
@@ -287,11 +285,11 @@ TEST(CommonXmlUtilsCApi, WriterRoundTrip)
|
||||
ASSERT_GT(needed, 0);
|
||||
std::vector<char> buf(needed);
|
||||
EXPECT_EQ(oakcommon_xml_writer_output(w, buf.data(), needed), needed);
|
||||
oakcommon_xml_writer_free(w);
|
||||
oakcommon_xml_writer_free(&w);
|
||||
|
||||
// Read the produced document back.
|
||||
OakCommonXmlReader *r = oakcommon_xml_reader_init(buf.data());
|
||||
ASSERT_NE(r, nullptr);
|
||||
OakXmlReader r = oakcommon_xml_reader_init(buf.data());
|
||||
ASSERT_NE(r.ctx, nullptr);
|
||||
int has_error = 1;
|
||||
EXPECT_EQ(oakcommon_xml_reader_has_error(r, &has_error), OAKCOMMON_OK);
|
||||
EXPECT_EQ(has_error, 0);
|
||||
@@ -326,5 +324,5 @@ TEST(CommonXmlUtilsCApi, WriterRoundTrip)
|
||||
OAKCOMMON_OK);
|
||||
EXPECT_EQ(found, 0);
|
||||
|
||||
oakcommon_xml_reader_free(r);
|
||||
oakcommon_xml_reader_free(&r);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user