The full pure-C facade used by the app: node/project/timeline/viewer/ undo/task/events/serializer/playback/preview/renderer/gizmo/color/ audio/footage/proxy/encoding/exporter/config/disk/ipc/plugin/worker families, plus undo-group semantics, display renderer handles, NodeFactory accessors, and per-family pure-C engine tests.
168 lines
6.6 KiB
C
168 lines
6.6 KiB
C
/***
|
|
|
|
Oak - 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 OAKENGINE_TRAVERSE_H
|
|
#define OAKENGINE_TRAVERSE_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "export.h"
|
|
#include "init.h"
|
|
#include "node.h"
|
|
#include "videoparams.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @file traverse.h
|
|
* @brief C ABI for synchronous node-graph value evaluation
|
|
* (olive::NodeTraverser)
|
|
*
|
|
* The engine evaluates a node's value at a given time by traversing its
|
|
* input graph (olive::NodeTraverser). The application uses this in three
|
|
* places: the node table view (per-input value databases), the node value
|
|
* tree (one output table + the element a downstream input's value hint
|
|
* selects) and the viewer display gizmos (a transform between two nodes
|
|
* and the gizmo node's input row at drag start). This family exposes
|
|
* those paths without leaking NodeValueTable/NodeValueRow C++ types.
|
|
*
|
|
* All evaluation is SYNCHRONOUS on the calling thread and CPU-only in
|
|
* this family (textures are resolved as engine-side dummy textures, which
|
|
* is exactly what the table/tree views need -- they only read metadata).
|
|
* Call from the GUI thread.
|
|
*
|
|
* OakEngineTraverseDb is an OWNED result object; free it with
|
|
* oakengine_traverse_db_free(). Strings it returns point into the object
|
|
* and are valid until freed. Times are Rational seconds as int64
|
|
* numerator/denominator pairs, like the rest of the facade.
|
|
*/
|
|
|
|
typedef struct OakEngineTraverseDb OakEngineTraverseDb;
|
|
|
|
/**
|
|
* @brief Evaluate every input of `node` over [in_num/in_den,
|
|
* out_num/out_den] seconds and return the per-input value database
|
|
* (NodeTraverser::generate_database()). NULL on invalid arguments.
|
|
*/
|
|
OAKENGINE_API OakEngineTraverseDb *oakengine_traverse_generate_database(
|
|
OakEngineNode *node, int64_t in_num, int64_t in_den, int64_t out_num,
|
|
int64_t out_den);
|
|
|
|
/**
|
|
* @brief Evaluate the single output table of `node`
|
|
* (NodeTraverser::generate_table()). Returned as a database with exactly
|
|
* one entry whose input id is an empty string.
|
|
*/
|
|
OAKENGINE_API OakEngineTraverseDb *oakengine_traverse_generate_table(
|
|
OakEngineNode *node, int64_t in_num, int64_t in_den, int64_t out_num,
|
|
int64_t out_den);
|
|
|
|
/** @brief Free a database returned by this family. NULL is a no-op. */
|
|
OAKENGINE_API void oakengine_traverse_db_free(OakEngineTraverseDb *db);
|
|
|
|
/** @brief Number of input entries (generate_database: one per input id
|
|
* that produced a table; generate_table: exactly 1). */
|
|
OAKENGINE_API int oakengine_traverse_db_input_count(
|
|
const OakEngineTraverseDb *db);
|
|
|
|
/** @brief Input id of entry `input_index` (valid until db is freed). */
|
|
OAKENGINE_API const char *oakengine_traverse_db_input_id(
|
|
const OakEngineTraverseDb *db, int input_index);
|
|
|
|
/** @brief Row count of the table at `input_index`
|
|
* (NodeValueTable::count()). */
|
|
OAKENGINE_API int oakengine_traverse_db_row_count(
|
|
const OakEngineTraverseDb *db, int input_index);
|
|
|
|
/**
|
|
* @brief Row accessors. `row` is 0-based in table order (the views
|
|
* reverse it themselves where needed). Strings are valid until db is
|
|
* freed.
|
|
*
|
|
* - type: oak_node_value_type of the value.
|
|
* - source: borrowed node that produced the value, or NULL.
|
|
* - tag: the value's tag (may be empty, never NULL).
|
|
* - value_string: NodeValue::value_to_string(value, false).
|
|
* - split_count / split_string: NodeValue::to_split_value() count and
|
|
* NodeValue::value_to_string(type, split[k], true) per element.
|
|
*/
|
|
OAKENGINE_API int oakengine_traverse_row_type(const OakEngineTraverseDb *db,
|
|
int input_index, int row);
|
|
OAKENGINE_API OakEngineNode *oakengine_traverse_row_source(
|
|
const OakEngineTraverseDb *db, int input_index, int row);
|
|
OAKENGINE_API const char *oakengine_traverse_row_tag(
|
|
const OakEngineTraverseDb *db, int input_index, int row);
|
|
OAKENGINE_API const char *oakengine_traverse_row_value_string(
|
|
const OakEngineTraverseDb *db, int input_index, int row);
|
|
OAKENGINE_API int oakengine_traverse_row_split_count(
|
|
const OakEngineTraverseDb *db, int input_index, int row);
|
|
OAKENGINE_API const char *oakengine_traverse_row_split_string(
|
|
const OakEngineTraverseDb *db, int input_index, int row, int split);
|
|
|
|
/**
|
|
* @brief The table element selected by `hint_node`'s value hint for input
|
|
* `input_id`@`element` against a table produced by
|
|
* oakengine_traverse_generate_table() (pass its db; must contain exactly
|
|
* one entry) -- NodeTraverser::generate_row_value_element_index().
|
|
* Returns -1 when no element matches.
|
|
*/
|
|
OAKENGINE_API int oakengine_traverse_table_element_index_for_hint(
|
|
OakEngineNode *hint_node, const char *input_id, int element,
|
|
const OakEngineTraverseDb *table_db);
|
|
|
|
/**
|
|
* @brief Fill a caller-allocated olive::NodeValueRow with `node`'s input
|
|
* values over the given range (NodeTraverser::generate_row()) -- the
|
|
* viewer display gizmo drag-start path. `cache_video_params` (may be NULL
|
|
* for engine defaults) and `sample_rate`/`channel_layout` seed the
|
|
* traverser's cache params (NodeTraverser::set_cache_video_params /
|
|
* set_cache_audio_params).
|
|
*
|
|
* Transition bridge (same pattern as
|
|
* replaced by internal ColorTransformJob API): `row_out` is opaque to C
|
|
* consumers; the application passes a pointer to its own
|
|
* olive::NodeValueRow (a QHash typedef, no engine symbols) which the
|
|
* engine fills in place.
|
|
*/
|
|
OAKENGINE_API int oakengine_traverse_generate_row(
|
|
OakEngineNode *node, int64_t in_num, int64_t in_den, int64_t out_num,
|
|
int64_t out_den, const oak_video_params *cache_video_params,
|
|
int sample_rate, uint64_t channel_layout, void *row_out);
|
|
|
|
/**
|
|
* @brief Accumulate the transform from `start` to `end` over the given
|
|
* range (NodeTraverser::transform()) and return it as the 6 affine
|
|
* coefficients of a QTransform (m11, m12, m21, m22, dx, dy), suitable for
|
|
* `QTransform(m11, m12, m21, m22, dx, dy)`. `cache_video_params` may be
|
|
* NULL for engine defaults.
|
|
*/
|
|
OAKENGINE_API int oakengine_traverse_transform(
|
|
OakEngineNode *start, OakEngineNode *end, int64_t in_num, int64_t in_den,
|
|
int64_t out_num, int64_t out_den, const oak_video_params *cache_video_params,
|
|
double out_m[6]);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* OAKENGINE_TRAVERSE_H */
|