/***
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 .
***/
#ifndef OAKENGINE_ENCODING_H
#define OAKENGINE_ENCODING_H
#include
#include "export.h"
#include "timeline.h"
#include "videoparams.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file encoding.h
* @brief C ABI for the encoding parameter surface (EncodingParams /
* ExportFormat / ExportCodec)
*
* This family exposes everything the application's export dialog (and the
* audio-recording path) needs without touching the engine's C++ classes:
*
* - Container/codec metadata queries (format names/extensions, codec lists
* per format, codec names/flags, supported pixel and sample formats).
* - An opaque OakEngineEncodingParams handle wrapping the engine's
* EncodingParams: full getter/setter surface, preset path/listing and
* preset load/save.
* - oakengine_export_render_with_params(): runs the same synchronous export
* path as oakengine_export_render_ex() (oakengine/exporter.h) using a
* params handle assembled through this family.
*
* Enum int fields carry the engine's own enum values
* (olive::ExportFormat::Format, olive::ExportCodec::Codec,
* olive::VideoParams::Interlacing/ColorRange, olive::PixelFormat::Format,
* olive::core::SampleFormat::Format). Conventions match the other facade
* families: 0 (OAKENGINE_OK) / negative OAKENGINE_E_* codes, buf/size
* strings (return value is the would-be length excluding the NUL), NULL
* handles are no-ops returning the documented failure value.
*/
/** @brief Opaque encoding-parameters handle (olive::EncodingParams). */
typedef struct OakEngineEncodingParams OakEngineEncodingParams;
/** @brief Scaling method values (EncodingParams::VideoScalingMethod). */
#define OAKENGINE_ENCODING_SCALING_FIT 0
#define OAKENGINE_ENCODING_SCALING_STRETCH 1
#define OAKENGINE_ENCODING_SCALING_CROP 2
/**
* @brief Container formats (olive::ExportFormat::Format) referenced by name
* in UI code. Only append; the values are serialized in project/preset
* files. The complete list lives in engine/codec/exportformat.h.
*/
#define OAKENGINE_ENCODING_FORMAT_MATROSKA 1
#define OAKENGINE_ENCODING_FORMAT_MPEG4_VIDEO 2
#define OAKENGINE_ENCODING_FORMAT_QUICKTIME 4
#define OAKENGINE_ENCODING_FORMAT_PNG 5
#define OAKENGINE_ENCODING_FORMAT_WAV 7
#define OAKENGINE_ENCODING_FORMAT_SRT 13
/**
* @brief Codecs (olive::ExportCodec::Codec) referenced by name in UI code.
* Only append; the values are serialized. The complete list lives in
* engine/codec/exportcodec.h.
*/
#define OAKENGINE_ENCODING_CODEC_H264 1
#define OAKENGINE_ENCODING_CODEC_H264RGB 2
#define OAKENGINE_ENCODING_CODEC_H265 3
#define OAKENGINE_ENCODING_CODEC_CINEFORM 7
#define OAKENGINE_ENCODING_CODEC_AAC 12
#define OAKENGINE_ENCODING_CODEC_PCM 13
#define OAKENGINE_ENCODING_CODEC_SRT 17
#define OAKENGINE_ENCODING_CODEC_AV1 18
/** @brief olive::VideoParams::ColorRange values. */
#define OAKENGINE_ENCODING_COLOR_RANGE_LIMITED 0
#define OAKENGINE_ENCODING_COLOR_RANGE_FULL 1
/** @brief olive::VideoParams::Interlacing values. */
#define OAKENGINE_ENCODING_INTERLACE_NONE 0
#define OAKENGINE_ENCODING_INTERLACE_TOP_FIRST 1
#define OAKENGINE_ENCODING_INTERLACE_BOTTOM_FIRST 2
/* ---- Container format / codec metadata ---------------------------------- */
/** @brief Number of container formats (olive::ExportFormat::k_format_count). */
OAKENGINE_API int oakengine_encoding_format_count(void);
/** @brief Display name of a container format (buf/size); -1 invalid. */
OAKENGINE_API int oakengine_encoding_format_name(int format, char *buf,
int buf_size);
/** @brief File extension (no dot) of a container format (buf/size). */
OAKENGINE_API int oakengine_encoding_format_extension(int format, char *buf,
int buf_size);
/**
* @brief Number of video codecs a container format supports; -1 when the
* format is invalid.
*/
OAKENGINE_API int oakengine_encoding_format_video_codec_count(int format);
/**
* @brief The `index`-th video codec of `format` as an
* olive::ExportCodec::Codec value; -1 when out of range.
*/
OAKENGINE_API int oakengine_encoding_format_video_codec_at(int format,
int index);
/** @brief Audio-codec variant of the two functions above. */
OAKENGINE_API int oakengine_encoding_format_audio_codec_count(int format);
OAKENGINE_API int oakengine_encoding_format_audio_codec_at(int format,
int index);
/** @brief Subtitle-codec variant of the two functions above. */
OAKENGINE_API int oakengine_encoding_format_subtitle_codec_count(int format);
OAKENGINE_API int oakengine_encoding_format_subtitle_codec_at(int format,
int index);
/** @brief Display name of a codec (buf/size); -1 when invalid. */
OAKENGINE_API int oakengine_encoding_codec_name(int codec, char *buf,
int buf_size);
/** @brief 1 when `codec` encodes still images (PNG/TIFF/OpenEXR). */
OAKENGINE_API int oakengine_encoding_codec_is_still_image(int codec);
/** @brief 1 when `codec` is lossless (no bit-rate setting applies). */
OAKENGINE_API int oakengine_encoding_codec_is_lossless(int codec);
/**
* @brief Number of encoded pixel formats (e.g. "yuv420p") usable with
* `codec` inside `format`; -1 when invalid.
*/
OAKENGINE_API int oakengine_encoding_pix_fmt_count(int format, int codec);
/** @brief The `index`-th encoded pixel format name (buf/size). */
OAKENGINE_API int oakengine_encoding_pix_fmt_at(int format, int codec,
int index, char *buf,
int buf_size);
/**
* @brief Index of `pix_fmt` (e.g. "yuv420p") in `codec`'s supported pixel
* format list; 0 (the codec's preferred format) when absent or `pix_fmt` is
* NULL/empty.
*/
OAKENGINE_API int oakengine_encoding_pix_fmt_index(int codec,
const char *pix_fmt);
/**
* @brief Number of sample formats usable with `codec` inside `format`;
* -1 when invalid.
*/
OAKENGINE_API int oakengine_encoding_sample_format_count(int format,
int codec);
/**
* @brief The `index`-th sample format as an olive::core::SampleFormat::Format
* value; -1 when out of range.
*/
OAKENGINE_API int oakengine_encoding_sample_format_at(int format, int codec,
int index);
/* ---- Image-sequence filename helpers (olive::Encoder statics) ----------- */
/** @brief 1 when `filename` contains a "[#####]" digit placeholder. */
OAKENGINE_API int
oakengine_encoding_filename_contains_digit_placeholder(const char *filename);
/**
* @brief Digit count of the filename's "[#####]" placeholder; 0 when none.
*/
OAKENGINE_API int
oakengine_encoding_image_sequence_digit_count(const char *filename);
/** @brief `filename` with the digit placeholder removed (buf/size). */
OAKENGINE_API int
oakengine_encoding_filename_remove_digit_placeholder(const char *filename,
char *buf, int buf_size);
/**
* @brief Fit/stretch/crop transform matrix
* (EncodingParams::generate_matrix()).
*
* Writes the 16 floats of the column-major 4x4 matrix to `out16`
* (QMatrix4x4 layout). `method` is OAKENGINE_ENCODING_SCALING_*.
*
* @return OAKENGINE_OK, or OAKENGINE_E_INVALID for bad arguments.
*/
OAKENGINE_API int oakengine_encoding_generate_matrix(int method, int src_width,
int src_height,
int dest_width,
int dest_height,
float out16[16]);
/* ---- Encoding parameters handle ----------------------------------------- */
/**
* @brief Create an empty encoding-parameters handle (all tracks disabled,
* format unset). Destroy with oakengine_encoding_params_destroy().
*/
OAKENGINE_API OakEngineEncodingParams *oakengine_encoding_params_create(void);
/** @brief Destroy a handle created by oakengine_encoding_params_create(). */
OAKENGINE_API void
oakengine_encoding_params_destroy(OakEngineEncodingParams *params);
/**
* @brief 1 when at least one of video/audio/subtitles is enabled
* (EncodingParams::is_valid()).
*/
OAKENGINE_API int
oakengine_encoding_params_is_valid(const OakEngineEncodingParams *params);
/** @brief Output filename (buf/size convention). */
OAKENGINE_API int
oakengine_encoding_params_set_filename(OakEngineEncodingParams *params,
const char *filename);
OAKENGINE_API int
oakengine_encoding_params_filename(const OakEngineEncodingParams *params,
char *buf, int buf_size);
/**
* @brief Container format as olive::ExportFormat::Format; the getter returns
* -1 when unset. The setter rejects out-of-range values with
* OAKENGINE_E_INVALID.
*/
OAKENGINE_API int
oakengine_encoding_params_set_format(OakEngineEncodingParams *params,
int format);
OAKENGINE_API int
oakengine_encoding_params_format(const OakEngineEncodingParams *params);
/**
* @brief Enable video with the given parameters and codec
* (EncodingParams::enable_video()).
*/
OAKENGINE_API int
oakengine_encoding_params_enable_video(OakEngineEncodingParams *params,
const oak_video_params *video,
int codec);
/**
* @brief Enable audio (EncodingParams::enable_audio()). `sample_format` is
* an olive::core::SampleFormat::Format value.
*/
OAKENGINE_API int
oakengine_encoding_params_enable_audio(OakEngineEncodingParams *params,
int sample_rate,
uint64_t channel_layout,
int sample_format, int codec);
/** @brief Enable embedded subtitles. */
OAKENGINE_API int
oakengine_encoding_params_enable_subtitles(OakEngineEncodingParams *params,
int codec);
/** @brief Enable sidecar subtitles with the given sidecar container. */
OAKENGINE_API int oakengine_encoding_params_enable_sidecar_subtitles(
OakEngineEncodingParams *params, int format, int codec);
OAKENGINE_API void
oakengine_encoding_params_disable_video(OakEngineEncodingParams *params);
OAKENGINE_API void
oakengine_encoding_params_disable_audio(OakEngineEncodingParams *params);
OAKENGINE_API void
oakengine_encoding_params_disable_subtitles(OakEngineEncodingParams *params);
OAKENGINE_API int
oakengine_encoding_params_video_enabled(const OakEngineEncodingParams *params);
OAKENGINE_API int
oakengine_encoding_params_video_codec(const OakEngineEncodingParams *params);
/**
* @brief Read back the video parameters (any field may be NULL);
* OAKENGINE_E_STATE when video is disabled.
*/
OAKENGINE_API int oakengine_encoding_params_get_video_params(
const OakEngineEncodingParams *params, oak_video_params *out);
OAKENGINE_API int
oakengine_encoding_params_audio_enabled(const OakEngineEncodingParams *params);
OAKENGINE_API int
oakengine_encoding_params_audio_codec(const OakEngineEncodingParams *params);
/**
* @brief Read back the audio parameters (any field may be NULL);
* OAKENGINE_E_STATE when audio is disabled.
*/
OAKENGINE_API int oakengine_encoding_params_get_audio_params(
const OakEngineEncodingParams *params, int *sample_rate,
uint64_t *channel_layout, int *sample_format);
OAKENGINE_API int oakengine_encoding_params_subtitles_enabled(
const OakEngineEncodingParams *params);
OAKENGINE_API int oakengine_encoding_params_subtitles_are_sidecar(
const OakEngineEncodingParams *params);
OAKENGINE_API int oakengine_encoding_params_subtitles_sidecar_format(
const OakEngineEncodingParams *params);
OAKENGINE_API int oakengine_encoding_params_subtitles_codec(
const OakEngineEncodingParams *params);
/** @brief Video bit rates / buffer size (bit/s, bytes). */
OAKENGINE_API void
oakengine_encoding_params_set_video_bit_rate(OakEngineEncodingParams *params,
int64_t rate);
OAKENGINE_API int64_t
oakengine_encoding_params_video_bit_rate(const OakEngineEncodingParams *params);
OAKENGINE_API void
oakengine_encoding_params_set_video_min_bit_rate(
OakEngineEncodingParams *params, int64_t rate);
OAKENGINE_API int64_t oakengine_encoding_params_video_min_bit_rate(
const OakEngineEncodingParams *params);
OAKENGINE_API void
oakengine_encoding_params_set_video_max_bit_rate(
OakEngineEncodingParams *params, int64_t rate);
OAKENGINE_API int64_t oakengine_encoding_params_video_max_bit_rate(
const OakEngineEncodingParams *params);
OAKENGINE_API void
oakengine_encoding_params_set_video_buffer_size(
OakEngineEncodingParams *params, int64_t size);
OAKENGINE_API int64_t oakengine_encoding_params_video_buffer_size(
const OakEngineEncodingParams *params);
/** @brief Encoder thread count (0 = auto). */
OAKENGINE_API void
oakengine_encoding_params_set_video_threads(OakEngineEncodingParams *params,
int threads);
OAKENGINE_API int
oakengine_encoding_params_video_threads(const OakEngineEncodingParams *params);
/** @brief Audio bit rate (bit/s). */
OAKENGINE_API void
oakengine_encoding_params_set_audio_bit_rate(OakEngineEncodingParams *params,
int64_t rate);
OAKENGINE_API int64_t
oakengine_encoding_params_audio_bit_rate(const OakEngineEncodingParams *params);
/** @brief Encoded pixel format name (e.g. "yuv420p"; buf/size getter). */
OAKENGINE_API int
oakengine_encoding_params_set_video_pix_fmt(OakEngineEncodingParams *params,
const char *pix_fmt);
OAKENGINE_API int
oakengine_encoding_params_video_pix_fmt(
const OakEngineEncodingParams *params, char *buf, int buf_size);
/** @brief Image-sequence flag (0/1). */
OAKENGINE_API void
oakengine_encoding_params_set_video_is_image_sequence(
OakEngineEncodingParams *params, int is_image_sequence);
OAKENGINE_API int oakengine_encoding_params_video_is_image_sequence(
const OakEngineEncodingParams *params);
/**
* @brief Output color transform by OCIO color space name; an empty/NULL
* name selects the reference space (no transform).
*/
OAKENGINE_API int oakengine_encoding_params_set_color_transform(
OakEngineEncodingParams *params, const char *output_name);
OAKENGINE_API int oakengine_encoding_params_color_transform_output(
const OakEngineEncodingParams *params, char *buf, int buf_size);
/** @brief Export length as rational seconds. */
OAKENGINE_API void
oakengine_encoding_params_set_export_length(OakEngineEncodingParams *params,
int num, int den);
OAKENGINE_API int
oakengine_encoding_params_get_export_length(
const OakEngineEncodingParams *params, int *num, int *den);
/**
* @brief Custom export range as rational seconds [in, out). The getter
* returns OAKENGINE_E_NOT_FOUND when no custom range is set.
*/
OAKENGINE_API void
oakengine_encoding_params_set_custom_range(OakEngineEncodingParams *params,
int64_t in_num, int64_t in_den,
int64_t out_num, int64_t out_den);
OAKENGINE_API int
oakengine_encoding_params_has_custom_range(
const OakEngineEncodingParams *params);
OAKENGINE_API int
oakengine_encoding_params_get_custom_range(
const OakEngineEncodingParams *params, int64_t *in_num, int64_t *in_den,
int64_t *out_num, int64_t *out_den);
/** @brief Scaling method (OAKENGINE_ENCODING_SCALING_*). */
OAKENGINE_API int
oakengine_encoding_params_set_video_scaling_method(
OakEngineEncodingParams *params, int method);
OAKENGINE_API int oakengine_encoding_params_video_scaling_method(
const OakEngineEncodingParams *params);
/**
* @brief Encoder-specific video option (key/value strings, e.g. "crf" =
* "18"); mirrors EncodingParams::set_video_option(). The getter returns the
* would-be length (buf/size) or OAKENGINE_E_NOT_FOUND when the key is unset.
*/
OAKENGINE_API int
oakengine_encoding_params_set_video_option(OakEngineEncodingParams *params,
const char *key, const char *value);
OAKENGINE_API int
oakengine_encoding_params_video_option(const OakEngineEncodingParams *params,
const char *key, char *buf,
int buf_size);
/* ---- Presets ------------------------------------------------------------- */
/** @brief Directory where export presets live (buf/size). */
OAKENGINE_API int oakengine_encoding_preset_path(char *buf, int buf_size);
/** @brief Number of saved presets. */
OAKENGINE_API int oakengine_encoding_preset_count(void);
/** @brief Name of the `index`-th preset (buf/size); -1 when out of range. */
OAKENGINE_API int oakengine_encoding_preset_name(int index, char *buf,
int buf_size);
/**
* @brief Load parameters from a preset/XML file (overwrites the handle's
* contents on success).
*
* @return OAKENGINE_OK, OAKENGINE_E_INVALID for bad arguments, or
* OAKENGINE_E_FAILED when the file cannot be read or parsed.
*/
OAKENGINE_API int
oakengine_encoding_params_load_file(OakEngineEncodingParams *params,
const char *path);
/** @brief Save parameters to a preset/XML file (same return convention). */
OAKENGINE_API int
oakengine_encoding_params_save_file(const OakEngineEncodingParams *params,
const char *path);
/* ---- Export execution / per-sequence last-used --------------------------- */
/**
* @brief Run a synchronous offline export with a params handle assembled
* through this family.
*
* Same blocking/progress/cancel semantics as oakengine_export_render_ex()
* (oakengine/exporter.h): progress via
* oakengine_export_set_progress_callback(), cancellation via
* oakengine_export_cancel(), failure reason via
* oakengine_export_last_error(). The output filename and image-sequence
* template come from the handle itself.
*
* @return OAKENGINE_OK / OAKENGINE_E_INVALID / OAKENGINE_E_STATE /
* OAKENGINE_E_FAILED / OAKENGINE_E_CANCELLED.
*/
OAKENGINE_API int
oakengine_export_render_with_params(OakEngineSequence *seq,
const OakEngineEncodingParams *params);
/**
* @brief Copy of the sequence's last-used encoding parameters
* (ViewerOutput::get_last_used_encoding_params()), or NULL when none is
* valid. Caller destroys with oakengine_encoding_params_destroy().
*/
OAKENGINE_API OakEngineEncodingParams *
oakengine_encoding_params_get_last_used(OakEngineSequence *seq);
/**
* @brief Store `params` as the sequence's last-used encoding parameters
* (ViewerOutput::set_last_used_encoding_params()); NULL is a no-op.
*/
OAKENGINE_API void oakengine_encoding_params_set_last_used(
OakEngineSequence *seq, const OakEngineEncodingParams *params);
/**
* @brief Start audio recording to the file described by `params`
* (AudioManager::start_recording(); audio must be enabled on the handle).
*
* @return OAKENGINE_OK on success; OAKENGINE_E_INVALID for bad arguments;
* OAKENGINE_E_STATE when the audio manager is not running;
* OAKENGINE_E_FAILED otherwise (a human-readable reason is written to
* `errbuf`/`errbuf_size` when given).
*/
OAKENGINE_API int
oakengine_encoding_start_audio_recording(const OakEngineEncodingParams *params,
char *errbuf, int errbuf_size);
#ifdef __cplusplus
}
#endif
#endif /* OAKENGINE_ENCODING_H */