refactor(render,timeline,task): switch remaining handles to refcounted value structs
- oakrender: renderer/texture/frame/cache/colorprocessor/ticket/copier
all become by-value {ctx, addref, release, abi_version} handles over a
generic box; retain() folds into addref; new
oakrender_cache_wrap_borrowed for native caches from oaknode
- oaktimeline: marker list/workarea borrowed handles become value
handles (non-owning boxes) with explicit free
- oaktask: OakTaskTask becomes a value handle; ownership still moves
to the manager on start (owns flag flips)
- consumers (timeline/task/codec sources) migrated; tests everywhere
updated; suites green: render 45, timeline 117, task 106, node 96,
common 193, codec 18, audio 36
This commit is contained in:
+48
-24
@@ -38,10 +38,13 @@ extern "C" {
|
||||
* @brief C ABI for the oakrender playback/frame-hash caches
|
||||
* (olive::PlaybackCache / olive::FrameHashCache), M7 §2.2.
|
||||
*
|
||||
* An OakRenderCache IS a reinterpreted olive::FrameHashCache (created
|
||||
* without a parent node), no wrapper allocation. Handles from
|
||||
* oakrender_cache_create() are owned by the caller and must be released
|
||||
* with oakrender_cache_free().
|
||||
* An OakRenderCache is a by-value reference-counted handle (shared_ptr
|
||||
* semantics, see oakcommon's common/handle.h) boxing an
|
||||
* olive::FrameHashCache (created without a parent node). Handles from
|
||||
* oakrender_cache_create() are owned by the caller (reference count 1)
|
||||
* and must be released with oakrender_cache_free(); handles from
|
||||
* oakrender_cache_wrap_borrowed() are borrowed (release only frees the
|
||||
* box).
|
||||
*
|
||||
* All timestamps are int64 frame numbers in the cache's timebase (see
|
||||
* oakrender_cache_set_timebase()); a cache without a valid timebase
|
||||
@@ -51,27 +54,48 @@ extern "C" {
|
||||
* invalidate/validate are triggered by and known to the caller; the
|
||||
* facade re-emits notifications after the triggering command.
|
||||
*/
|
||||
typedef struct OakRenderCache OakRenderCache;
|
||||
typedef struct OakRenderCache {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakRenderCache;
|
||||
|
||||
/**
|
||||
* @brief Create a detached frame hash cache (no parent node, no
|
||||
* timebase). Owned by the caller.
|
||||
*
|
||||
* @return Cache handle, or NULL on allocation failure.
|
||||
* @return Cache handle with reference count 1; ctx is NULL on
|
||||
* allocation failure.
|
||||
*/
|
||||
OakRenderCache *oakrender_cache_create(void);
|
||||
OakRenderCache oakrender_cache_create(void);
|
||||
|
||||
/** @brief Destroy a cache created by oakrender_cache_create(). NULL-safe. */
|
||||
/**
|
||||
* @brief Release one reference to a cache created by
|
||||
* oakrender_cache_create(). Convenience wrapper around
|
||||
* cache->release(cache->ctx). NULL / empty-handle no-op; clears
|
||||
* cache->ctx after releasing.
|
||||
*/
|
||||
void oakrender_cache_free(OakRenderCache *cache);
|
||||
|
||||
/**
|
||||
* @brief Borrowed handle wrapping a native frame cache pointer obtained
|
||||
* through oaknode (oaknode_node_get_video_frame_cache()).
|
||||
*
|
||||
* The cache itself stays owned by its node: release() on this handle
|
||||
* only frees the box. Empty handle (ctx == NULL) for a NULL native
|
||||
* pointer.
|
||||
*/
|
||||
OakRenderCache oakrender_cache_wrap_borrowed(void *native_cache);
|
||||
|
||||
/**
|
||||
* @brief Set the frame timebase used to interpret all timestamps of this
|
||||
* cache (FrameHashCache::set_timebase()).
|
||||
*
|
||||
* @return OAKRENDER_OK, or OAKRENDER_E_INVALID for NULL cache or
|
||||
* @return OAKRENDER_OK, or OAKRENDER_E_INVALID for an empty cache or
|
||||
* non-positive num/den.
|
||||
*/
|
||||
int oakrender_cache_set_timebase(OakRenderCache *cache, int num, int den);
|
||||
int oakrender_cache_set_timebase(OakRenderCache cache, int num, int den);
|
||||
|
||||
/**
|
||||
* @brief Set the cache UUID used in on-disk frame cache filenames
|
||||
@@ -79,27 +103,27 @@ int oakrender_cache_set_timebase(OakRenderCache *cache, int num, int den);
|
||||
*
|
||||
* @return OAKRENDER_OK or OAKRENDER_E_INVALID.
|
||||
*/
|
||||
int oakrender_cache_set_uuid(OakRenderCache *cache, const char *uuid);
|
||||
int oakrender_cache_set_uuid(OakRenderCache cache, const char *uuid);
|
||||
|
||||
/**
|
||||
* @brief Mark the timestamp range [in_ts, out_ts) invalidated
|
||||
* (PlaybackCache::invalidate()). NULL cache is a no-op.
|
||||
* (PlaybackCache::invalidate()). Empty cache is a no-op.
|
||||
*/
|
||||
void oakrender_cache_invalidate(OakRenderCache *cache, int64_t in_ts,
|
||||
void oakrender_cache_invalidate(OakRenderCache cache, int64_t in_ts,
|
||||
int64_t out_ts);
|
||||
|
||||
/**
|
||||
* @brief Mark the timestamp range [in_ts, out_ts) validated
|
||||
* (PlaybackCache::validate()). NULL cache is a no-op.
|
||||
* (PlaybackCache::validate()). Empty cache is a no-op.
|
||||
*/
|
||||
void oakrender_cache_validate(OakRenderCache *cache, int64_t in_ts,
|
||||
void oakrender_cache_validate(OakRenderCache cache, int64_t in_ts,
|
||||
int64_t out_ts);
|
||||
|
||||
/**
|
||||
* @brief 1 when the cache holds any validated range
|
||||
* (PlaybackCache::has_validated_ranges()), 0 otherwise / on NULL.
|
||||
* (PlaybackCache::has_validated_ranges()), 0 otherwise / empty.
|
||||
*/
|
||||
int oakrender_cache_has_validated_ranges(const OakRenderCache *cache);
|
||||
int oakrender_cache_has_validated_ranges(OakRenderCache cache);
|
||||
|
||||
/**
|
||||
* @brief Timeline cache indicator height in pixels
|
||||
@@ -117,7 +141,7 @@ int oakrender_cache_indicator_height(void);
|
||||
*
|
||||
* @return Range count (>= 0), or a negative OAKRENDER_E_* code.
|
||||
*/
|
||||
int oakrender_cache_get_invalidated_ranges(OakRenderCache *c,
|
||||
int oakrender_cache_get_invalidated_ranges(OakRenderCache c,
|
||||
int64_t in_num, int64_t in_den, int64_t out_num, int64_t out_den,
|
||||
int64_t *ranges, int max_ranges);
|
||||
|
||||
@@ -130,20 +154,20 @@ int oakrender_cache_get_invalidated_ranges(OakRenderCache *c,
|
||||
* @param out_frame Receives an owned frame handle (release with
|
||||
* oakrender_codec_frame_free()).
|
||||
*
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (NULL argument), or
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (empty/NULL argument), or
|
||||
* OAKRENDER_E_NOT_FOUND (no cached frame at `ts` / undecodable).
|
||||
*/
|
||||
int oakrender_frame_cache_load(OakRenderCache *cache, const char *path,
|
||||
int oakrender_frame_cache_load(OakRenderCache cache, const char *path,
|
||||
const char *uuid, int64_t ts,
|
||||
OakCodecFrame **out_frame);
|
||||
OakCodecFrame *out_frame);
|
||||
|
||||
/**
|
||||
* @brief Save a frame to the disk cache under the cache's timebase and
|
||||
* the frame's own timestamp (FrameHashCache::save_cache_frame()).
|
||||
* NULL arguments are a no-op.
|
||||
* Empty/NULL arguments are a no-op.
|
||||
*/
|
||||
void oakrender_frame_cache_save(OakRenderCache *cache, const char *path,
|
||||
const char *uuid, const OakCodecFrame *frame);
|
||||
void oakrender_frame_cache_save(OakRenderCache cache, const char *path,
|
||||
const char *uuid, OakCodecFrame frame);
|
||||
|
||||
/* ---- Debug --------------------------------------------------------------- */
|
||||
|
||||
|
||||
@@ -37,16 +37,6 @@ namespace olive { class CancelAtom; }
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Current ABI version stamped into every oakrender handle.
|
||||
*
|
||||
* Bump whenever a handle layout or the semantics of any exported function
|
||||
* change incompatibly. Consumers should compare a handle's abi_version
|
||||
* field against the value they were compiled with before dereferencing
|
||||
* ctx.
|
||||
*/
|
||||
#define OAKRENDER_ABI_VERSION 1
|
||||
|
||||
/**
|
||||
* @file cancelatom.h
|
||||
* @brief C ABI for the oakrender cancellation primitive
|
||||
|
||||
+29
-18
@@ -34,10 +34,11 @@ extern "C" {
|
||||
* the process-wide default OCIO config (olive::ColorManager
|
||||
* statics), M7 §2.3.
|
||||
*
|
||||
* An OakColorProcessor IS a wrapper allocation holding a
|
||||
* ColorProcessorPtr (ColorProcessor is shared_ptr-managed); release with
|
||||
* oakrender_color_processor_free(). NULL is accepted by every function
|
||||
* and yields a no-op / OAKRENDER_E_INVALID.
|
||||
* An OakColorProcessor is a by-value reference-counted handle (shared_ptr
|
||||
* semantics, see oakcommon's common/handle.h) boxing a ColorProcessorPtr
|
||||
* (ColorProcessor is shared_ptr-managed); release with
|
||||
* oakrender_color_processor_free(). Empty handles (ctx == NULL) are
|
||||
* accepted by every function and yield a no-op / OAKRENDER_E_INVALID.
|
||||
*
|
||||
* Processors are built against the process-wide default OCIO config
|
||||
* (olive::ColorManager::get_default_config()): the $OCIO config when the
|
||||
@@ -52,7 +53,12 @@ enum {
|
||||
OAKRENDER_COLOR_DIRECTION_INVERSE = 1
|
||||
};
|
||||
|
||||
typedef struct OakColorProcessor OakColorProcessor;
|
||||
typedef struct OakColorProcessor {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakColorProcessor;
|
||||
|
||||
/**
|
||||
* @brief Create a colorspace-to-colorspace processor on the default
|
||||
@@ -67,29 +73,34 @@ typedef struct OakColorProcessor OakColorProcessor;
|
||||
* still returned but oakrender_color_processor_is_valid() reports 0 and
|
||||
* conversions are pass-through.
|
||||
*
|
||||
* @return Processor handle, or NULL for NULL/empty strings, an unknown
|
||||
* direction, no default config, or allocation failure.
|
||||
* @return Processor handle with reference count 1; ctx is NULL for
|
||||
* NULL/empty strings, an unknown direction, no default config,
|
||||
* or allocation failure.
|
||||
*/
|
||||
OakColorProcessor *oakrender_color_processor_create(const char *src_space,
|
||||
const char *dst_transform,
|
||||
int direction);
|
||||
OakColorProcessor oakrender_color_processor_create(const char *src_space,
|
||||
const char *dst_transform,
|
||||
int direction);
|
||||
|
||||
/** @brief Release a processor handle. NULL-safe no-op. */
|
||||
/**
|
||||
* @brief Release one reference to a processor handle. Convenience
|
||||
* wrapper around processor->release(processor->ctx). NULL /
|
||||
* empty-handle no-op; clears processor->ctx after releasing.
|
||||
*/
|
||||
void oakrender_color_processor_free(OakColorProcessor *processor);
|
||||
|
||||
/**
|
||||
* @brief 1 when the processor holds a valid OCIO processor
|
||||
* (ColorProcessor::get_processor() != null), 0 otherwise / on NULL.
|
||||
* (ColorProcessor::get_processor() != null), 0 otherwise / empty.
|
||||
*/
|
||||
int oakrender_color_processor_is_valid(const OakColorProcessor *processor);
|
||||
int oakrender_color_processor_is_valid(OakColorProcessor processor);
|
||||
|
||||
/**
|
||||
* @brief Convert a single RGBA color (ColorProcessor::convert_color()).
|
||||
* On an invalid processor the input is copied through.
|
||||
*
|
||||
* @return OAKRENDER_OK, or OAKRENDER_E_INVALID for NULL arguments.
|
||||
* @return OAKRENDER_OK, or OAKRENDER_E_INVALID for empty/NULL arguments.
|
||||
*/
|
||||
int oakrender_color_processor_convert(OakColorProcessor *processor,
|
||||
int oakrender_color_processor_convert(OakColorProcessor processor,
|
||||
double ir, double ig, double ib,
|
||||
double ia, double *out_r, double *out_g,
|
||||
double *out_b, double *out_a);
|
||||
@@ -105,11 +116,11 @@ int oakrender_color_processor_convert(OakColorProcessor *processor,
|
||||
* non-fatal) is a pass-through and returns OAKRENDER_OK, mirroring the
|
||||
* C++ API.
|
||||
*
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID for NULL/uninitialized
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID for empty/uninitialized
|
||||
* arguments, or OAKRENDER_E_FAILED on an internal exception.
|
||||
*/
|
||||
int oakrender_color_processor_convert_frame(OakColorProcessor *processor,
|
||||
OakCodecFrame *frame);
|
||||
int oakrender_color_processor_convert_frame(OakColorProcessor processor,
|
||||
OakCodecFrame frame);
|
||||
|
||||
/* ---- ColorManager statics ------------------------------------------------- */
|
||||
|
||||
|
||||
+26
-9
@@ -30,35 +30,52 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Opaque handle to a project copier (olive::ProjectCopier):
|
||||
* deep-copies a project graph for background processing
|
||||
* (export/precache).
|
||||
* @brief Reference-counted handle to a project copier
|
||||
* (olive::ProjectCopier): deep-copies a project graph for
|
||||
* background processing (export/precache).
|
||||
*
|
||||
* By-value handle (shared_ptr semantics, see oakcommon's
|
||||
* common/handle.h): oakrender_project_copier_create() returns a handle
|
||||
* with reference count 1; release it with
|
||||
* oakrender_project_copier_free().
|
||||
*/
|
||||
typedef struct OakRenderProjectCopier OakRenderProjectCopier;
|
||||
typedef struct OakRenderProjectCopier {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakRenderProjectCopier;
|
||||
|
||||
/**
|
||||
* @brief Create a copier. The copy is built by
|
||||
* oakrender_project_copier_set_project().
|
||||
*
|
||||
* @return Copier handle with reference count 1; ctx is NULL on
|
||||
* allocation failure.
|
||||
*/
|
||||
OakRenderProjectCopier *oakrender_project_copier_create(void);
|
||||
OakRenderProjectCopier oakrender_project_copier_create(void);
|
||||
|
||||
/** @brief Free the copier AND its copied project. NULL-safe. */
|
||||
/**
|
||||
* @brief Release one reference to a copier; the final release frees the
|
||||
* copier AND its copied project. NULL / empty-handle no-op; clears
|
||||
* copier->ctx after releasing.
|
||||
*/
|
||||
void oakrender_project_copier_free(OakRenderProjectCopier *copier);
|
||||
|
||||
/** @brief (Re)build the copy from `project` (borrowed handle). */
|
||||
int oakrender_project_copier_set_project(OakRenderProjectCopier *copier,
|
||||
int oakrender_project_copier_set_project(OakRenderProjectCopier copier,
|
||||
OakNodeProject project);
|
||||
|
||||
/** @brief The copied counterpart of an original node (borrowed handle;
|
||||
* freeing it only releases the handle box), empty handle when the
|
||||
* node is not in the copied project. */
|
||||
OakNodeNode oakrender_project_copier_get_copy(
|
||||
OakRenderProjectCopier *copier, OakNodeNode original);
|
||||
OakRenderProjectCopier copier, OakNodeNode original);
|
||||
|
||||
/** @brief The copied project (borrowed handle; freeing it only releases
|
||||
* the handle box). */
|
||||
OakNodeProject oakrender_project_copier_get_copied_project(
|
||||
OakRenderProjectCopier *copier);
|
||||
OakRenderProjectCopier copier);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -29,6 +29,16 @@
|
||||
* failure. String getters return the required buffer size in bytes
|
||||
* (including the terminating NUL) as a non-negative value instead.
|
||||
*/
|
||||
/**
|
||||
* @brief Current ABI version stamped into every oakrender handle.
|
||||
*
|
||||
* Bump whenever a handle layout or the semantics of any exported function
|
||||
* change incompatibly. Consumers should compare a handle's abi_version
|
||||
* field against the value they were compiled with before dereferencing
|
||||
* ctx.
|
||||
*/
|
||||
#define OAKRENDER_ABI_VERSION 1
|
||||
|
||||
#define OAKRENDER_OK 0 /**< Success. */
|
||||
#define OAKRENDER_E_INVALID (-1) /**< NULL handle or invalid argument. */
|
||||
#define OAKRENDER_E_STATE (-2) /**< Call not valid in the current state. */
|
||||
|
||||
@@ -46,9 +46,9 @@ extern "C" {
|
||||
* The frame request callback is the asynchronous command return channel
|
||||
* (M7 §2.2 note): it fires on a render worker thread, possibly after
|
||||
* cancellation. The delivered OakCodecFrame is owned by the callback
|
||||
* recipient (release with oakrender_codec_frame_free()); a NULL frame
|
||||
* signals "no result" (cancelled or failed). Beyond this callback there
|
||||
* are no event subscription interfaces.
|
||||
* recipient (release with oakrender_codec_frame_free()); an empty frame
|
||||
* (ctx == NULL) signals "no result" (cancelled or failed). Beyond this
|
||||
* callback there are no event subscription interfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -69,11 +69,11 @@ void oakrender_manager_shutdown(void);
|
||||
/**
|
||||
* @brief Completion callback of an asynchronous frame request.
|
||||
*
|
||||
* @param frame Owned frame handle, or NULL when the request finished
|
||||
* without a result (cancelled/failed).
|
||||
* @param frame Owned frame handle, or an empty handle (ctx == NULL)
|
||||
* when the request finished without a result (cancelled/failed).
|
||||
* @param ts The request's timestamp, passed back verbatim.
|
||||
*/
|
||||
typedef void (*oakrender_frame_ready_fn)(OakCodecFrame *frame, int64_t ts,
|
||||
typedef void (*oakrender_frame_ready_fn)(OakCodecFrame frame, int64_t ts,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
@@ -114,11 +114,11 @@ int oakrender_set_cacher_multicam(OakNodeNode multicam_or_NULL);
|
||||
/**
|
||||
* @brief Set the display color processor on the manager's auto-cacher
|
||||
* (PreviewAutoCacher::set_display_color_processor()). Borrowed handle,
|
||||
* NULL to clear.
|
||||
* empty ctx to clear.
|
||||
*
|
||||
* @return OAKRENDER_OK or OAKRENDER_E_STATE.
|
||||
*/
|
||||
int oakrender_set_display_color_processor(OakColorProcessor *p_or_NULL);
|
||||
int oakrender_set_display_color_processor(OakColorProcessor p_or_NULL);
|
||||
|
||||
/* ---- Disk cache (olive::DiskManager) -------------------------------------- */
|
||||
|
||||
|
||||
+117
-66
@@ -38,20 +38,25 @@ extern "C" {
|
||||
* (docs/zh/plans/completed/r7-pure-abi-plan.md §A.2) with the
|
||||
* oakrender_ prefix (M7 §2.1).
|
||||
*
|
||||
* Ownership protocol: textures and frames are opaque handles pointing to
|
||||
* oakrender-heap control blocks (internally holding std::shared_ptr;
|
||||
* invisible to the ABI). Ownership transfers via explicit retain/free.
|
||||
* Every retain must be paired with exactly one free. NULL is accepted by
|
||||
* every function and yields a no-op / zero result / OAKRENDER_E_INVALID.
|
||||
* Ownership protocol: every public handle is a by-value
|
||||
* reference-counted struct (see oakcommon's common/handle.h; shared_ptr
|
||||
* semantics). init/create functions return a handle with reference
|
||||
* count 1, handle.addref(handle.ctx) takes another reference, and
|
||||
* handle.release(handle.ctx) (or the oakrender_*_free() convenience
|
||||
* wrappers, which also null the caller's ctx) drops one; the object is
|
||||
* destroyed in this library when the count reaches zero. Empty handles
|
||||
* (ctx == NULL) are accepted by every function and yield a no-op / zero
|
||||
* result / OAKRENDER_E_INVALID.
|
||||
*
|
||||
* Cross-thread handoff (§A.3): the producing side retains before
|
||||
* publishing a handle into a shared slot; the consuming side frees the
|
||||
* handle it replaced. The side holding the slot when it is torn down
|
||||
* frees the remaining handle.
|
||||
* Cross-thread handoff (§A.3): the producing side addrefs before
|
||||
* publishing a handle into a shared slot; the consuming side releases
|
||||
* the handle it replaced. The side holding the slot when it is torn
|
||||
* down releases the remaining handle.
|
||||
*
|
||||
* Handles:
|
||||
* - OakRenderRenderer IS a reinterpreted olive::Renderer (no wrapper).
|
||||
* - OakRenderTexture / OakCodecFrame are refcounted control blocks.
|
||||
* - OakRenderRenderer wraps a native olive::Renderer.
|
||||
* - OakRenderTexture / OakCodecFrame box shared_ptr-managed engine
|
||||
* objects.
|
||||
* - `gl_context` is an opaque borrowed olive::OpenGLContext* (or NULL
|
||||
* to let the backend create its own offscreen surface).
|
||||
*/
|
||||
@@ -81,17 +86,42 @@ typedef struct oakrender_video_params {
|
||||
int premultiplied_alpha; /**< 0/1. */
|
||||
} oakrender_video_params;
|
||||
|
||||
typedef struct OakRenderRenderer OakRenderRenderer;
|
||||
typedef struct OakRenderTexture OakRenderTexture;
|
||||
/**
|
||||
* @brief Reference-counted handle to a display renderer
|
||||
* (olive::Renderer). See the file-level ownership protocol.
|
||||
*/
|
||||
typedef struct OakRenderRenderer {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakRenderRenderer;
|
||||
|
||||
/**
|
||||
* @brief Opaque CPU frame handle (refcounted control block around an
|
||||
* olive::FramePtr). Declared here so the cache family (render/cache.h)
|
||||
* can use the same type; the frame functions live in this header.
|
||||
* @brief Reference-counted handle to a GPU texture (olive::Texture).
|
||||
* See the file-level ownership protocol.
|
||||
*/
|
||||
typedef struct OakRenderTexture {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakRenderTexture;
|
||||
|
||||
/**
|
||||
* @brief Reference-counted handle to a CPU frame (an olive::FramePtr
|
||||
* boxed in a control block). Declared here so the cache family
|
||||
* (render/cache.h) can use the same type; the frame functions live in
|
||||
* this header.
|
||||
* Named OakCodecFrame per the M7 §2.2 contract; the oakcodec wave (M5)
|
||||
* adopts the same handle.
|
||||
*/
|
||||
typedef struct OakCodecFrame OakCodecFrame;
|
||||
typedef struct OakCodecFrame {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakCodecFrame;
|
||||
|
||||
/**
|
||||
* @brief Flattened POD of olive::ColorTransformJob for the display blit
|
||||
@@ -99,8 +129,8 @@ typedef struct OakCodecFrame OakCodecFrame;
|
||||
* means identity.
|
||||
*/
|
||||
typedef struct oakrender_color_transform_job {
|
||||
const void *processor; /**< OakColorProcessor* (borrowed), may be NULL. */
|
||||
void *input_texture; /**< OakRenderTexture* (borrowed, not retained). */
|
||||
const void *processor; /**< OakColorProcessor ctx (borrowed), may be NULL. */
|
||||
void *input_texture; /**< OakRenderTexture ctx (borrowed, not retained). */
|
||||
int input_alpha_association; /**< 0=none, 1=associated. */
|
||||
int clear_destination; /**< 0/1. */
|
||||
int force_opaque; /**< 0/1. */
|
||||
@@ -115,116 +145,137 @@ typedef struct oakrender_color_transform_job {
|
||||
* "vulkan"; olive::DynamicRenderer). Loads the backend shared library;
|
||||
* falls back per DynamicRenderer rules.
|
||||
*
|
||||
* @return Renderer handle, or NULL on NULL/empty backend id, load
|
||||
* failure, or allocation failure.
|
||||
* @return Renderer handle with reference count 1; ctx is NULL on
|
||||
* NULL/empty backend id, load failure, or allocation failure.
|
||||
*/
|
||||
OakRenderRenderer *oakrender_display_renderer_create_dynamic(
|
||||
OakRenderRenderer oakrender_display_renderer_create_dynamic(
|
||||
const char *backend_id);
|
||||
|
||||
/**
|
||||
* @brief Create an OpenGL renderer (olive::OpenGLRenderer). The renderer
|
||||
* is not initialized; call oakrender_display_renderer_init() before use.
|
||||
*
|
||||
* @return Renderer handle, or NULL on allocation failure.
|
||||
* @return Renderer handle with reference count 1; ctx is NULL on
|
||||
* allocation failure.
|
||||
*/
|
||||
OakRenderRenderer *oakrender_display_renderer_create_opengl(void);
|
||||
OakRenderRenderer oakrender_display_renderer_create_opengl(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize a renderer. `gl_context` is a borrowed opaque
|
||||
* olive::OpenGLContext*, or NULL to use the backend's default
|
||||
* device/context path (Renderer::init()).
|
||||
*
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (NULL renderer), or
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (empty renderer), or
|
||||
* OAKRENDER_E_FAILED (backend init failed).
|
||||
*/
|
||||
int oakrender_display_renderer_init(OakRenderRenderer *renderer,
|
||||
int oakrender_display_renderer_init(OakRenderRenderer renderer,
|
||||
void *gl_context);
|
||||
|
||||
/**
|
||||
* @brief Destroy a renderer (Renderer::destroy() + delete). NULL-safe
|
||||
* no-op.
|
||||
* @brief Release one reference to a renderer (the final release runs
|
||||
* Renderer::destroy() + delete). Convenience wrapper around
|
||||
* renderer->release(renderer->ctx): NULL / empty-handle no-op; clears
|
||||
* renderer->ctx after releasing.
|
||||
*/
|
||||
void oakrender_display_renderer_destroy(OakRenderRenderer *renderer);
|
||||
|
||||
/* ---- Renderer queries ---------------------------------------------------- */
|
||||
|
||||
/** @brief 1 when the renderer is OpenGL-based, 0 otherwise / on NULL. */
|
||||
int oakrender_display_renderer_is_open_gl(const OakRenderRenderer *renderer);
|
||||
/** @brief 1 when the renderer is OpenGL-based, 0 otherwise / empty. */
|
||||
int oakrender_display_renderer_is_open_gl(OakRenderRenderer renderer);
|
||||
|
||||
/** @brief 1 when the renderer is Vulkan-based, 0 otherwise / on NULL. */
|
||||
int oakrender_display_renderer_is_vulkan(const OakRenderRenderer *renderer);
|
||||
/** @brief 1 when the renderer is Vulkan-based, 0 otherwise / empty. */
|
||||
int oakrender_display_renderer_is_vulkan(OakRenderRenderer renderer);
|
||||
|
||||
/* ---- Texture handle (opaque, refcounted) --------------------------------- */
|
||||
/* ---- Texture handle ------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* @brief Create a GPU texture on `renderer`.
|
||||
*
|
||||
* @param pixels Initial pixel data, or NULL for an uninitialized texture.
|
||||
* @param linesize Stride of `pixels` in bytes (0 when pixels is NULL).
|
||||
* @return New texture handle (refcount=1), or NULL on invalid arguments /
|
||||
* allocation failure.
|
||||
* @return New texture handle (reference count 1); ctx is NULL on invalid
|
||||
* arguments / allocation failure.
|
||||
*/
|
||||
OakRenderTexture *oakrender_display_texture_create(
|
||||
OakRenderRenderer *renderer, const oakrender_video_params *params,
|
||||
OakRenderTexture oakrender_display_texture_create(
|
||||
OakRenderRenderer renderer, const oakrender_video_params *params,
|
||||
const void *pixels, int linesize);
|
||||
|
||||
/** @brief Increment refcount, return the same handle. NULL-safe. */
|
||||
OakRenderTexture *oakrender_display_texture_retain(OakRenderTexture *texture);
|
||||
/**
|
||||
* @brief Take another reference to a texture and return the same handle.
|
||||
*
|
||||
* Convenience wrapper around handle.addref(handle.ctx). An empty handle
|
||||
* in yields an empty handle out. Every retain must be paired with
|
||||
* exactly one free/release.
|
||||
*/
|
||||
OakRenderTexture oakrender_display_texture_retain(OakRenderTexture texture);
|
||||
|
||||
/** @brief Decrement refcount; frees at zero. NULL-safe. */
|
||||
/**
|
||||
* @brief Release one reference to a texture. Convenience wrapper around
|
||||
* texture->release(texture->ctx): frees the texture when the count
|
||||
* reaches zero. NULL / empty-handle no-op; clears texture->ctx after
|
||||
* releasing.
|
||||
*/
|
||||
void oakrender_display_texture_free(OakRenderTexture *texture);
|
||||
|
||||
int oakrender_display_texture_upload(OakRenderTexture *texture,
|
||||
int oakrender_display_texture_upload(OakRenderTexture texture,
|
||||
const void *pixels, int linesize);
|
||||
|
||||
int oakrender_display_texture_download(OakRenderTexture *texture, void *pixels,
|
||||
int oakrender_display_texture_download(OakRenderTexture texture, void *pixels,
|
||||
int linesize);
|
||||
|
||||
/* ---- Texture queries ----------------------------------------------------- */
|
||||
|
||||
int oakrender_display_texture_get_params(const OakRenderTexture *texture,
|
||||
int oakrender_display_texture_get_params(OakRenderTexture texture,
|
||||
oakrender_video_params *out);
|
||||
|
||||
/** @brief Native texture id (0 on NULL or a dummy/id-less texture). */
|
||||
int oakrender_display_texture_id(const OakRenderTexture *texture);
|
||||
/** @brief Native texture id (0 on empty or a dummy/id-less texture). */
|
||||
int oakrender_display_texture_id(OakRenderTexture texture);
|
||||
|
||||
/* ---- Frame handle (opaque, refcounted) ----------------------------------- */
|
||||
/* ---- Frame handle -------------------------------------------------------- */
|
||||
|
||||
/** @brief Create an empty CPU frame. Returns handle (refcount=1). */
|
||||
OakCodecFrame *oakrender_codec_frame_create(void);
|
||||
/** @brief Create an empty CPU frame. Returns a handle with count 1. */
|
||||
OakCodecFrame oakrender_codec_frame_create(void);
|
||||
|
||||
/** @brief Increment refcount, return the same handle. NULL-safe. */
|
||||
OakCodecFrame *oakrender_codec_frame_retain(OakCodecFrame *frame);
|
||||
/**
|
||||
* @brief Take another reference to a frame and return the same handle.
|
||||
* Empty in yields empty out (see oakrender_display_texture_retain()).
|
||||
*/
|
||||
OakCodecFrame oakrender_codec_frame_retain(OakCodecFrame frame);
|
||||
|
||||
/** @brief Decrement refcount; frees at zero. NULL-safe. */
|
||||
/**
|
||||
* @brief Release one reference to a frame. Convenience wrapper around
|
||||
* frame->release(frame->ctx). NULL / empty-handle no-op; clears
|
||||
* frame->ctx after releasing.
|
||||
*/
|
||||
void oakrender_codec_frame_free(OakCodecFrame *frame);
|
||||
|
||||
int oakrender_codec_frame_set_video_params(
|
||||
OakCodecFrame *frame, const oakrender_video_params *params);
|
||||
OakCodecFrame frame, const oakrender_video_params *params);
|
||||
|
||||
int oakrender_codec_frame_get_params(const OakCodecFrame *frame,
|
||||
int oakrender_codec_frame_get_params(OakCodecFrame frame,
|
||||
oakrender_video_params *out);
|
||||
|
||||
/**
|
||||
* @brief Allocate the pixel buffer per the frame's video params
|
||||
* (Frame::allocate()).
|
||||
*
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (NULL frame), or
|
||||
* @return OAKRENDER_OK, OAKRENDER_E_INVALID (empty frame), or
|
||||
* OAKRENDER_E_FAILED (invalid params / allocation failed).
|
||||
*/
|
||||
int oakrender_codec_frame_allocate(OakCodecFrame *frame);
|
||||
int oakrender_codec_frame_allocate(OakCodecFrame frame);
|
||||
|
||||
/** @brief Borrowed pixel data pointer (valid until free). */
|
||||
void *oakrender_codec_frame_data(OakCodecFrame *frame);
|
||||
/** @brief Borrowed pixel data pointer (valid until the final release). */
|
||||
void *oakrender_codec_frame_data(OakCodecFrame frame);
|
||||
|
||||
/** @brief Borrowed const pixel data pointer. */
|
||||
const void *oakrender_codec_frame_const_data(const OakCodecFrame *frame);
|
||||
const void *oakrender_codec_frame_const_data(OakCodecFrame frame);
|
||||
|
||||
/** @brief Line stride in bytes. */
|
||||
int oakrender_codec_frame_linesize_bytes(const OakCodecFrame *frame);
|
||||
int oakrender_codec_frame_linesize_bytes(OakCodecFrame frame);
|
||||
|
||||
/** @brief 1 when the pixel buffer is allocated, 0 otherwise / on NULL. */
|
||||
int oakrender_codec_frame_is_allocated(const OakCodecFrame *frame);
|
||||
/** @brief 1 when the pixel buffer is allocated, 0 otherwise / empty. */
|
||||
int oakrender_codec_frame_is_allocated(OakCodecFrame frame);
|
||||
|
||||
/* ---- Color-managed blit -------------------------------------------------- */
|
||||
|
||||
@@ -232,18 +283,18 @@ int oakrender_codec_frame_is_allocated(const OakCodecFrame *frame);
|
||||
* @brief Blit a color-managed image through the OCIO pipeline
|
||||
* (Renderer::blit_color_managed()).
|
||||
*
|
||||
* @param dst_texture Destination texture handle, or NULL for the current
|
||||
* output target.
|
||||
* @param dst_texture Destination texture handle, or an empty handle for
|
||||
* the current output target.
|
||||
* @param params Destination video params, or NULL to use dst_texture's.
|
||||
*/
|
||||
int oakrender_display_renderer_blit_color_managed(
|
||||
OakRenderRenderer *renderer, const oakrender_color_transform_job *job,
|
||||
OakRenderTexture *dst_texture, const oakrender_video_params *params);
|
||||
OakRenderRenderer renderer, const oakrender_color_transform_job *job,
|
||||
OakRenderTexture dst_texture, const oakrender_video_params *params);
|
||||
|
||||
/* ---- Cross-backend texture download -------------------------------------- */
|
||||
|
||||
int oakrender_display_renderer_download_from_texture(
|
||||
OakRenderRenderer *renderer, int texture_id,
|
||||
OakRenderRenderer renderer, int texture_id,
|
||||
const oakrender_video_params *params, void *dst_pixels, int linesize);
|
||||
|
||||
/* ---- Backend management (M7 §2.1) ---------------------------------------- */
|
||||
|
||||
+37
-23
@@ -38,19 +38,29 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Opaque handle to a render ticket (olive::RenderTicketWatcher).
|
||||
* @brief Reference-counted handle to a render ticket
|
||||
* (olive::RenderTicketWatcher).
|
||||
*
|
||||
* Created by oakrender_ticket_render_frame() /
|
||||
* oakrender_ticket_render_audio(); free with oakrender_ticket_free().
|
||||
* By-value handle (shared_ptr semantics, see oakcommon's
|
||||
* common/handle.h). Created by oakrender_ticket_render_frame() /
|
||||
* oakrender_ticket_render_audio() with reference count 1; release with
|
||||
* oakrender_ticket_free().
|
||||
*/
|
||||
typedef struct OakRenderTicket OakRenderTicket;
|
||||
typedef struct OakRenderTicket {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKRENDER_ABI_VERSION. */
|
||||
} OakRenderTicket;
|
||||
|
||||
/**
|
||||
* @brief Finished callback (async command return channel, 01 §4
|
||||
* exception). Fires on the ticket's finishing thread, exactly
|
||||
* once (cancelled tickets fire with a NULL result).
|
||||
* once (cancelled tickets fire with a NULL result). The ticket
|
||||
* handle is a borrowed copy of the submitter's handle; the
|
||||
* submitter keeps ownership and releases it.
|
||||
*/
|
||||
typedef void (*oakrender_ticket_finished_fn)(OakRenderTicket *ticket,
|
||||
typedef void (*oakrender_ticket_finished_fn)(OakRenderTicket ticket,
|
||||
void *userdata);
|
||||
|
||||
/** @brief Ticket types (RenderManager::TicketType). */
|
||||
@@ -77,7 +87,7 @@ typedef struct oakrender_video_ticket_params {
|
||||
int has_force_matrix;
|
||||
int force_format; /**< PixelFormat as int, -1 = off. */
|
||||
int force_channel_count; /**< 0 = off. */
|
||||
OakColorProcessor *force_color_output; /**< May be NULL. */
|
||||
OakColorProcessor force_color_output; /**< Borrowed; empty ctx = none. */
|
||||
OakColorTransform force_color_transform; /**< By value; empty ctx = default. */
|
||||
OakNodeFrameCache *cache; /**< Borrowed frame cache, may be NULL. */
|
||||
} oakrender_video_ticket_params;
|
||||
@@ -85,11 +95,12 @@ typedef struct oakrender_video_ticket_params {
|
||||
/**
|
||||
* @brief Submit a video frame render ticket.
|
||||
*
|
||||
* @return Ticket handle (caller frees), or NULL on failure. The finished
|
||||
* callback fires exactly once; NULL `cb` is allowed (poll with
|
||||
* @return Ticket handle with reference count 1 (caller releases); ctx is
|
||||
* NULL on failure. The finished callback fires exactly once;
|
||||
* NULL `cb` is allowed (poll with
|
||||
* oakrender_ticket_wait()/oakrender_ticket_is_finished()).
|
||||
*/
|
||||
OakRenderTicket *oakrender_ticket_render_frame(
|
||||
OakRenderTicket oakrender_ticket_render_frame(
|
||||
const oakrender_video_ticket_params *params,
|
||||
oakrender_ticket_finished_fn cb, void *userdata);
|
||||
|
||||
@@ -99,48 +110,51 @@ OakRenderTicket *oakrender_ticket_render_frame(
|
||||
* @param output_node Connected sample output node.
|
||||
* @param params Audio params (borrowed oakcore handle).
|
||||
*/
|
||||
OakRenderTicket *oakrender_ticket_render_audio(
|
||||
OakRenderTicket oakrender_ticket_render_audio(
|
||||
OakNodeNode output_node, int64_t in_num, int64_t in_den,
|
||||
int64_t out_num, int64_t out_den, const OakAudioParams *params,
|
||||
int mode, oakrender_ticket_finished_fn cb, void *userdata);
|
||||
|
||||
int oakrender_ticket_is_finished(OakRenderTicket *ticket);
|
||||
int oakrender_ticket_is_finished(OakRenderTicket ticket);
|
||||
|
||||
/** @brief Block until the ticket finishes. */
|
||||
int oakrender_ticket_wait(OakRenderTicket *ticket);
|
||||
int oakrender_ticket_wait(OakRenderTicket ticket);
|
||||
|
||||
int oakrender_ticket_cancel(OakRenderTicket *ticket);
|
||||
int oakrender_ticket_cancel(OakRenderTicket ticket);
|
||||
|
||||
/** @brief OAKRENDER_TICKET_* or negative error. */
|
||||
int oakrender_ticket_get_type(OakRenderTicket *ticket);
|
||||
int oakrender_ticket_get_type(OakRenderTicket ticket);
|
||||
|
||||
/** @brief Ticket timestamp (video tickets). */
|
||||
int oakrender_ticket_get_time(OakRenderTicket *ticket, int64_t *out_num,
|
||||
int oakrender_ticket_get_time(OakRenderTicket ticket, int64_t *out_num,
|
||||
int64_t *out_den);
|
||||
|
||||
/** @brief Ticket time range (audio tickets). */
|
||||
int oakrender_ticket_get_range(OakRenderTicket *ticket, int64_t *in_num,
|
||||
int oakrender_ticket_get_range(OakRenderTicket ticket, int64_t *in_num,
|
||||
int64_t *in_den, int64_t *out_num,
|
||||
int64_t *out_den);
|
||||
|
||||
/**
|
||||
* @brief The resulting frame (video tickets). *out receives a retained
|
||||
* @brief The resulting frame (video tickets). *out receives an owned
|
||||
* OakCodecFrame (release with oakrender_codec_frame_free()).
|
||||
* OAKRENDER_E_STATE when unfinished, OAKRENDER_E_FAILED when the
|
||||
* ticket has no frame result.
|
||||
*/
|
||||
int oakrender_ticket_get_frame(OakRenderTicket *ticket,
|
||||
OakCodecFrame **out);
|
||||
int oakrender_ticket_get_frame(OakRenderTicket ticket, OakCodecFrame *out);
|
||||
|
||||
/**
|
||||
* @brief The resulting samples (audio tickets). *out receives a copy
|
||||
* (release with oakcore_samplebuffer_free()).
|
||||
*/
|
||||
int oakrender_ticket_get_samples(OakRenderTicket *ticket,
|
||||
int oakrender_ticket_get_samples(OakRenderTicket ticket,
|
||||
OakSampleBuffer **out);
|
||||
|
||||
/** @brief Free the ticket handle (safe on finished tickets; cancels and
|
||||
* waits on running ones). No-op on NULL. */
|
||||
/**
|
||||
* @brief Release one reference to a ticket (the final release is safe on
|
||||
* finished tickets; cancels and waits on running ones). Convenience
|
||||
* wrapper around ticket->release(ticket->ctx). NULL / empty-handle
|
||||
* no-op; clears ticket->ctx after releasing.
|
||||
*/
|
||||
void oakrender_ticket_free(OakRenderTicket *ticket);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user