feat(engine): clip move, clip effect_input, mandatory static FFmpeg
- oakengine_sequence_move_clip implemented for real (oaktimeline TrackMoveBlockCommand; fixes the graph-ownership/gap-anchor/ripple trim bugs the stub was hiding); same-track via the frozen C ABI, cross-track supported by the module command - oaknode clip blocks now declare a tex_in texture input and set effect_input to it, so timeline clips can host effect chains; facade test covers effect insert/remove on a real clip - oakffmpeg-link: FFMPEG_DIR is now mandatory with a clear panic (a Homebrew upgrade left the system ffmpeg .pc pointing at a deleted dav1d Cellar path, breaking links); reads a git-ignored workspace .env for IDEs that cannot inject env vars (RustRover); links the C++ stdlib for C++ codec libs (svt-av1) - oakengine re-exports oaknode so tests share one crate instance; it_node uses the direct instance's value type where it calls the module FFI (the --workspace dev-dependency feature split builds oaknode twice)
This commit is contained in:
@@ -81,7 +81,9 @@ pub extern "C" fn oakengine_audio_get_output_device() -> i64 {
|
||||
if m.is_null() {
|
||||
return Ok(PA_NO_DEVICE);
|
||||
}
|
||||
Ok(i64::from(unsafe { a::oakaudio_manager_get_output_device(m) }))
|
||||
Ok(i64::from(unsafe {
|
||||
a::oakaudio_manager_get_output_device(m)
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,7 +107,9 @@ pub extern "C" fn oakengine_audio_get_input_device() -> i64 {
|
||||
if m.is_null() {
|
||||
return Ok(PA_NO_DEVICE);
|
||||
}
|
||||
Ok(i64::from(unsafe { a::oakaudio_manager_get_input_device(m) }))
|
||||
Ok(i64::from(unsafe {
|
||||
a::oakaudio_manager_get_input_device(m)
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -460,14 +464,7 @@ pub unsafe extern "C" fn oakengine_audio_processor_open(
|
||||
let out_layout = a::oakcore_audioparams_channel_layout(to);
|
||||
let out_format = a::oakcore_audioparams_format(to);
|
||||
Error::from_module(a::oakaudio_processor_open(
|
||||
handle,
|
||||
in_rate,
|
||||
in_layout,
|
||||
in_format,
|
||||
out_rate,
|
||||
out_layout,
|
||||
out_format,
|
||||
tempo,
|
||||
handle, in_rate, in_layout, in_format, out_rate, out_layout, out_format, tempo,
|
||||
))
|
||||
})
|
||||
}
|
||||
@@ -486,7 +483,9 @@ pub unsafe extern "C" fn oakengine_audio_processor_close(p: *mut OakEngineAudioP
|
||||
|
||||
/// `oakengine_audio_processor_is_open` — 1 when open, 0 when NULL.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_audio_processor_is_open(p: *mut OakEngineAudioProcessor) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_audio_processor_is_open(
|
||||
p: *mut OakEngineAudioProcessor,
|
||||
) -> c_int {
|
||||
crate::handle::guard_int(|| unsafe {
|
||||
if p.is_null() {
|
||||
return Ok(0);
|
||||
|
||||
@@ -54,24 +54,24 @@ use crate::handle::CHandle;
|
||||
/// the oakaudio crate's struct (identical layout).
|
||||
pub type OffsetResult = oakaudio::ffi::sync::OffsetResult;
|
||||
|
||||
|
||||
/// `oakaudio_stretchoffsetresult` C ABI POD. Single-lib unification: aliases
|
||||
/// the oakaudio crate's struct (identical layout).
|
||||
pub type StretchOffsetResult = oakaudio::ffi::sync::StretchOffsetResult;
|
||||
|
||||
|
||||
/// `oakaudio_sourceclip` C ABI POD. Single-lib unification: aliases
|
||||
/// the oakaudio crate's struct (identical layout).
|
||||
pub type SourceClip = oakaudio::ffi::sync::SourceClip;
|
||||
|
||||
|
||||
|
||||
/// `oakaudio` recording-params POD — single-lib unification: aliases the
|
||||
/// oakaudio crate's type (itself the oakcodec `oakcodec_encoding_params`).
|
||||
pub type EncodingParams = oakaudio::bridge::codec::EncodingParams;
|
||||
|
||||
extern "C" {
|
||||
pub fn oakcore_audioparams_create(sample_rate: c_int, channel_layout: u64, format: c_int) -> *mut c_void;
|
||||
pub fn oakcore_audioparams_create(
|
||||
sample_rate: c_int,
|
||||
channel_layout: u64,
|
||||
format: c_int,
|
||||
) -> *mut c_void;
|
||||
pub fn oakcore_audioparams_free(params: *mut c_void);
|
||||
pub fn oakcore_audioparams_sample_rate(params: *const c_void) -> c_int;
|
||||
pub fn oakcore_audioparams_channel_layout(params: *const c_void) -> u64;
|
||||
@@ -111,16 +111,27 @@ pub fn oakaudio_manager_set_output_notify_interval(_self: CHandle, bytes: i64) -
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_manager_push_to_output(
|
||||
_self: CHandle,
|
||||
rate: c_int,
|
||||
layout: u64,
|
||||
format: c_int,
|
||||
samples: *const c_char,
|
||||
samples_size: i64,
|
||||
error_buf: *mut c_char,
|
||||
error_buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::manager::oakaudio_manager_push_to_output(_self, rate, layout, format, samples, samples_size, error_buf, error_buf_size) }
|
||||
_self: CHandle,
|
||||
rate: c_int,
|
||||
layout: u64,
|
||||
format: c_int,
|
||||
samples: *const c_char,
|
||||
samples_size: i64,
|
||||
error_buf: *mut c_char,
|
||||
error_buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::manager::oakaudio_manager_push_to_output(
|
||||
_self,
|
||||
rate,
|
||||
layout,
|
||||
format,
|
||||
samples,
|
||||
samples_size,
|
||||
error_buf,
|
||||
error_buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
@@ -183,7 +194,14 @@ pub fn oakaudio_manager_start_recording(
|
||||
error_buf: *mut c_char,
|
||||
error_buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::manager::oakaudio_manager_start_recording(_self, params, error_buf, error_buf_size) }
|
||||
unsafe {
|
||||
oakaudio::ffi::manager::oakaudio_manager_start_recording(
|
||||
_self,
|
||||
params,
|
||||
error_buf,
|
||||
error_buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
@@ -213,16 +231,20 @@ pub fn oakaudio_processor_free(_self: *mut CHandle) {
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_processor_open(
|
||||
_self: CHandle,
|
||||
in_rate: c_int,
|
||||
in_layout: u64,
|
||||
in_format: c_int,
|
||||
out_rate: c_int,
|
||||
out_layout: u64,
|
||||
out_format: c_int,
|
||||
speed: c_double,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::processor::oakaudio_processor_open(_self, in_rate, in_layout, in_format, out_rate, out_layout, out_format, speed) }
|
||||
_self: CHandle,
|
||||
in_rate: c_int,
|
||||
in_layout: u64,
|
||||
in_format: c_int,
|
||||
out_rate: c_int,
|
||||
out_layout: u64,
|
||||
out_format: c_int,
|
||||
speed: c_double,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::processor::oakaudio_processor_open(
|
||||
_self, in_rate, in_layout, in_format, out_rate, out_layout, out_format, speed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
@@ -240,63 +262,109 @@ pub fn oakaudio_processor_is_open(_self: CHandle) -> c_int {
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_sync_estimate_envelope_offset(
|
||||
reference: *const c_double,
|
||||
reference_len: c_int,
|
||||
candidate: *const c_double,
|
||||
candidate_len: c_int,
|
||||
reference_valid: *const u8,
|
||||
candidate_valid: *const u8,
|
||||
window_samples: u64,
|
||||
max_offset_windows: i64,
|
||||
out: *mut OffsetResult,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::sync::oakaudio_sync_estimate_envelope_offset(reference, reference_len, candidate, candidate_len, reference_valid, candidate_valid, window_samples, max_offset_windows, out) }
|
||||
reference: *const c_double,
|
||||
reference_len: c_int,
|
||||
candidate: *const c_double,
|
||||
candidate_len: c_int,
|
||||
reference_valid: *const u8,
|
||||
candidate_valid: *const u8,
|
||||
window_samples: u64,
|
||||
max_offset_windows: i64,
|
||||
out: *mut OffsetResult,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::sync::oakaudio_sync_estimate_envelope_offset(
|
||||
reference,
|
||||
reference_len,
|
||||
candidate,
|
||||
candidate_len,
|
||||
reference_valid,
|
||||
candidate_valid,
|
||||
window_samples,
|
||||
max_offset_windows,
|
||||
out,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_sync_estimate_stretch_and_offset(
|
||||
reference: *const c_double,
|
||||
reference_len: c_int,
|
||||
candidate: *const c_double,
|
||||
candidate_len: c_int,
|
||||
reference_valid: *const u8,
|
||||
candidate_valid: *const u8,
|
||||
window_samples: u64,
|
||||
max_offset_windows: i64,
|
||||
min_rate: c_double,
|
||||
max_rate: c_double,
|
||||
rate_step: c_double,
|
||||
out: *mut StretchOffsetResult,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::sync::oakaudio_sync_estimate_stretch_and_offset(reference, reference_len, candidate, candidate_len, reference_valid, candidate_valid, window_samples, max_offset_windows, min_rate, max_rate, rate_step, out) }
|
||||
reference: *const c_double,
|
||||
reference_len: c_int,
|
||||
candidate: *const c_double,
|
||||
candidate_len: c_int,
|
||||
reference_valid: *const u8,
|
||||
candidate_valid: *const u8,
|
||||
window_samples: u64,
|
||||
max_offset_windows: i64,
|
||||
min_rate: c_double,
|
||||
max_rate: c_double,
|
||||
rate_step: c_double,
|
||||
out: *mut StretchOffsetResult,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::sync::oakaudio_sync_estimate_stretch_and_offset(
|
||||
reference,
|
||||
reference_len,
|
||||
candidate,
|
||||
candidate_len,
|
||||
reference_valid,
|
||||
candidate_valid,
|
||||
window_samples,
|
||||
max_offset_windows,
|
||||
min_rate,
|
||||
max_rate,
|
||||
rate_step,
|
||||
out,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_sync_place_by_source_time(
|
||||
reference: *const SourceClip,
|
||||
candidate: *const SourceClip,
|
||||
reference_timeline_in_num: i64,
|
||||
reference_timeline_in_den: i64,
|
||||
out_num: *mut i64,
|
||||
out_den: *mut i64,
|
||||
out_valid: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::sync::oakaudio_sync_place_by_source_time(reference, candidate, reference_timeline_in_num, reference_timeline_in_den, out_num, out_den, out_valid) }
|
||||
reference: *const SourceClip,
|
||||
candidate: *const SourceClip,
|
||||
reference_timeline_in_num: i64,
|
||||
reference_timeline_in_den: i64,
|
||||
out_num: *mut i64,
|
||||
out_den: *mut i64,
|
||||
out_valid: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::sync::oakaudio_sync_place_by_source_time(
|
||||
reference,
|
||||
candidate,
|
||||
reference_timeline_in_num,
|
||||
reference_timeline_in_den,
|
||||
out_num,
|
||||
out_den,
|
||||
out_valid,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakaudio` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakaudio_sync_place_by_waveform_offset(
|
||||
reference_timeline_in_num: i64,
|
||||
reference_timeline_in_den: i64,
|
||||
candidate_offset_samples: i64,
|
||||
sample_rate: c_int,
|
||||
out_num: *mut i64,
|
||||
out_den: *mut i64,
|
||||
out_valid: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakaudio::ffi::sync::oakaudio_sync_place_by_waveform_offset(reference_timeline_in_num, reference_timeline_in_den, candidate_offset_samples, sample_rate, out_num, out_den, out_valid) }
|
||||
reference_timeline_in_num: i64,
|
||||
reference_timeline_in_den: i64,
|
||||
candidate_offset_samples: i64,
|
||||
sample_rate: c_int,
|
||||
out_num: *mut i64,
|
||||
out_den: *mut i64,
|
||||
out_valid: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakaudio::ffi::sync::oakaudio_sync_place_by_waveform_offset(
|
||||
reference_timeline_in_num,
|
||||
reference_timeline_in_den,
|
||||
candidate_offset_samples,
|
||||
sample_rate,
|
||||
out_num,
|
||||
out_den,
|
||||
out_valid,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ use crate::handle::CHandle;
|
||||
/// `encoder_init`/recording can consume the pointer directly).
|
||||
pub type EncodingParamsPOD = oakcodec::ffi::encoder::oakcodec_encoding_params;
|
||||
|
||||
|
||||
/// Zeroed encoding-params POD (all fields 0 / NUL). The codec crate's
|
||||
/// struct has no zeroed constructor; this facade helper provides it.
|
||||
pub fn zeroed_encoding_params() -> EncodingParamsPOD {
|
||||
@@ -67,7 +66,6 @@ pub fn zeroed_encoding_params() -> EncodingParamsPOD {
|
||||
unsafe { std::mem::zeroed() }
|
||||
}
|
||||
|
||||
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_format_count() -> c_int {
|
||||
@@ -83,10 +81,10 @@ pub fn oakcodec_encoding_format_name(format: c_int, buf: *mut c_char, buf_size:
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_format_extension(
|
||||
format: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
format: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcodec::ffi::format::oakcodec_encoding_format_extension(format, buf, buf_size) }
|
||||
}
|
||||
|
||||
@@ -153,13 +151,15 @@ pub fn oakcodec_encoding_pix_fmt_count(format: c_int, codec: c_int) -> c_int {
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_pix_fmt_at(
|
||||
format: c_int,
|
||||
codec: c_int,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcodec::ffi::format::oakcodec_encoding_pix_fmt_at(format, codec, index, buf, buf_size) }
|
||||
format: c_int,
|
||||
codec: c_int,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcodec::ffi::format::oakcodec_encoding_pix_fmt_at(format, codec, index, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
@@ -183,7 +183,9 @@ pub fn oakcodec_encoding_sample_format_at(format: c_int, codec: c_int, index: c_
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_filename_contains_digit_placeholder(filename: *const c_char) -> c_int {
|
||||
unsafe { oakcodec::ffi::format::oakcodec_encoding_filename_contains_digit_placeholder(filename) }
|
||||
unsafe {
|
||||
oakcodec::ffi::format::oakcodec_encoding_filename_contains_digit_placeholder(filename)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
@@ -195,24 +197,32 @@ pub fn oakcodec_encoding_image_sequence_digit_count(filename: *const c_char) ->
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_filename_remove_digit_placeholder(
|
||||
filename: *const c_char,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcodec::ffi::format::oakcodec_encoding_filename_remove_digit_placeholder(filename, buf, buf_size) }
|
||||
filename: *const c_char,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcodec::ffi::format::oakcodec_encoding_filename_remove_digit_placeholder(
|
||||
filename, buf, buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcodec_encoding_generate_matrix(
|
||||
method: c_int,
|
||||
src_width: c_int,
|
||||
src_height: c_int,
|
||||
dst_width: c_int,
|
||||
dst_height: c_int,
|
||||
out_matrix: *mut f64,
|
||||
) -> c_int {
|
||||
unsafe { oakcodec::ffi::encoder::oakcodec_encoding_generate_matrix(method, src_width, src_height, dst_width, dst_height, out_matrix) }
|
||||
method: c_int,
|
||||
src_width: c_int,
|
||||
src_height: c_int,
|
||||
dst_width: c_int,
|
||||
dst_height: c_int,
|
||||
out_matrix: *mut f64,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcodec::ffi::encoder::oakcodec_encoding_generate_matrix(
|
||||
method, src_width, src_height, dst_width, dst_height, out_matrix,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcodec` crate (single-lib unification; the
|
||||
@@ -230,4 +240,3 @@ pub fn oakcodec_encoder_init(params: *const EncodingParamsPOD) -> CHandle {
|
||||
pub fn oakcodec_encoder_free(encoder: *mut CHandle) {
|
||||
unsafe { oakcodec::ffi::encoder::oakcodec_encoder_free(encoder) }
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,9 @@ use std::ffi::{c_char, c_int, c_void};
|
||||
use crate::handle::CHandle;
|
||||
|
||||
/// `include/common/config.h` — error handler callback.
|
||||
pub type ConfigErrorHandler =
|
||||
Option<unsafe extern "C" fn(title: *const c_char, message: *const c_char, userdata: *mut c_void)>;
|
||||
pub type ConfigErrorHandler = Option<
|
||||
unsafe extern "C" fn(title: *const c_char, message: *const c_char, userdata: *mut c_void),
|
||||
>;
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
@@ -81,27 +82,27 @@ pub fn oakcommon_config_set(group: *const c_char, key: *const c_char, value: *co
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_config_get(
|
||||
group: *const c_char,
|
||||
key: *const c_char,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
group: *const c_char,
|
||||
key: *const c_char,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::config::oakcommon_config_get(group, key, buf, buf_size) }
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_config_get_int(group: *const c_char, key: *const c_char, fallback: c_int) -> c_int {
|
||||
pub fn oakcommon_config_get_int(
|
||||
group: *const c_char,
|
||||
key: *const c_char,
|
||||
fallback: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::config::oakcommon_config_get_int(group, key, fallback) }
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_config_get_int64(
|
||||
group: *const c_char,
|
||||
key: *const c_char,
|
||||
fallback: i64,
|
||||
) -> i64 {
|
||||
pub fn oakcommon_config_get_int64(group: *const c_char, key: *const c_char, fallback: i64) -> i64 {
|
||||
unsafe { oakcommon::ffi::config::oakcommon_config_get_int64(group, key, fallback) }
|
||||
}
|
||||
|
||||
@@ -113,7 +114,11 @@ pub fn oakcommon_config_get_double(group: *const c_char, key: *const c_char, fal
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_config_get_bool(group: *const c_char, key: *const c_char, fallback: c_int) -> c_int {
|
||||
pub fn oakcommon_config_get_bool(
|
||||
group: *const c_char,
|
||||
key: *const c_char,
|
||||
fallback: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::config::oakcommon_config_get_bool(group, key, fallback) }
|
||||
}
|
||||
|
||||
@@ -149,7 +154,10 @@ pub fn oakcommon_config_entry_type(group: *const c_char, key: *const c_char) ->
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_config_set_error_handler(handler: ConfigErrorHandler, userdata: *mut c_void) -> c_int {
|
||||
pub fn oakcommon_config_set_error_handler(
|
||||
handler: ConfigErrorHandler,
|
||||
userdata: *mut c_void,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::config::oakcommon_config_set_error_handler(handler, userdata) }
|
||||
}
|
||||
|
||||
@@ -173,8 +181,14 @@ pub fn oakcommon_videoparams_init_basic(
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_init_basic(
|
||||
width, height, pixel_format, nb_channels, pixel_aspect_num, pixel_aspect_den,
|
||||
interlacing, divider,
|
||||
width,
|
||||
height,
|
||||
pixel_format,
|
||||
nb_channels,
|
||||
pixel_aspect_num,
|
||||
pixel_aspect_den,
|
||||
interlacing,
|
||||
divider,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -195,8 +209,16 @@ pub fn oakcommon_videoparams_init_with_time_base(
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_init_with_time_base(
|
||||
width, height, time_base_num, time_base_den, pixel_format, nb_channels,
|
||||
pixel_aspect_num, pixel_aspect_den, interlacing, divider,
|
||||
width,
|
||||
height,
|
||||
time_base_num,
|
||||
time_base_den,
|
||||
pixel_format,
|
||||
nb_channels,
|
||||
pixel_aspect_num,
|
||||
pixel_aspect_den,
|
||||
interlacing,
|
||||
divider,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -234,61 +256,97 @@ pub fn oakcommon_videoparams_set_height(params: CHandle, height: c_int) -> c_int
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_time_base(
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_time_base(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_time_base(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_time_base(
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_time_base(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_time_base(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_frame_rate(
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_frame_rate(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_frame_rate(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_frame_rate(
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_frame_rate(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_frame_rate(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_pixel_aspect_ratio(
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_pixel_aspect_ratio(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: *mut c_int,
|
||||
denominator: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_pixel_aspect_ratio(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_pixel_aspect_ratio(
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_pixel_aspect_ratio(params, numerator, denominator) }
|
||||
params: CHandle,
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_pixel_aspect_ratio(
|
||||
params,
|
||||
numerator,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -306,13 +364,17 @@ pub fn oakcommon_videoparams_set_format(params: CHandle, format: c_int) -> c_int
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_interlacing(params: CHandle, interlacing: *mut c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_interlacing(params, interlacing) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_interlacing(params, interlacing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_interlacing(params: CHandle, interlacing: c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_interlacing(params, interlacing) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_interlacing(params, interlacing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -342,28 +404,45 @@ pub fn oakcommon_videoparams_set_video_type(params: CHandle, type_: c_int) -> c_
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_premultiplied_alpha(
|
||||
params: CHandle,
|
||||
premultiplied: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_premultiplied_alpha(params, premultiplied) }
|
||||
params: CHandle,
|
||||
premultiplied: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_premultiplied_alpha(
|
||||
params,
|
||||
premultiplied,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_premultiplied_alpha(params: CHandle, premultiplied: c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_premultiplied_alpha(params, premultiplied) }
|
||||
pub fn oakcommon_videoparams_set_premultiplied_alpha(
|
||||
params: CHandle,
|
||||
premultiplied: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_premultiplied_alpha(
|
||||
params,
|
||||
premultiplied,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_color_range(params: CHandle, color_range: *mut c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_color_range(params, color_range) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_color_range(params, color_range)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_set_color_range(params: CHandle, color_range: c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_set_color_range(params, color_range) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_set_color_range(params, color_range)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -381,7 +460,9 @@ pub fn oakcommon_videoparams_get_effective_width(params: CHandle, width: *mut c_
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_effective_height(params: CHandle, height: *mut c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_effective_height(params, height) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_effective_height(params, height)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -405,61 +486,93 @@ pub fn oakcommon_videoparams_format_is_float(pixel_format: c_int) -> c_int {
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_format_name(
|
||||
pixel_format: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_format_name(pixel_format, buf, buf_size) }
|
||||
pixel_format: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_format_name(
|
||||
pixel_format,
|
||||
buf,
|
||||
buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_frame_rate_to_string(
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_frame_rate_to_string(numerator, denominator, buf, buf_size) }
|
||||
numerator: c_int,
|
||||
denominator: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_frame_rate_to_string(
|
||||
numerator,
|
||||
denominator,
|
||||
buf,
|
||||
buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_name_for_divider(
|
||||
divider: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_name_for_divider(divider, buf, buf_size) }
|
||||
divider: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_name_for_divider(
|
||||
divider, buf, buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_scaled_dimension(dimension: c_int, divider: c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_scaled_dimension(dimension, divider) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_scaled_dimension(dimension, divider)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_generate_auto_divider(width: i64, height: i64) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_generate_auto_divider(width, height) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_generate_auto_divider(width, height)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_divider_for_target_resolution(
|
||||
src_width: c_int,
|
||||
src_height: c_int,
|
||||
target_width: c_int,
|
||||
target_height: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_divider_for_target_resolution(src_width, src_height, target_width, target_height) }
|
||||
src_width: c_int,
|
||||
src_height: c_int,
|
||||
target_width: c_int,
|
||||
target_height: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_divider_for_target_resolution(
|
||||
src_width,
|
||||
src_height,
|
||||
target_width,
|
||||
target_height,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_get_bytes_per_channel_for_format(pixel_format: c_int) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_bytes_per_channel_for_format(pixel_format) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_bytes_per_channel_for_format(
|
||||
pixel_format,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -468,16 +581,26 @@ pub fn oakcommon_videoparams_get_bytes_per_pixel_for_format(
|
||||
pixel_format: c_int,
|
||||
channels: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_bytes_per_pixel_for_format(pixel_format, channels) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_bytes_per_pixel_for_format(
|
||||
pixel_format,
|
||||
channels,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_videoparams_static_get_bytes_per_pixel(
|
||||
pixel_format: c_int,
|
||||
channels: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_static_get_bytes_per_pixel(pixel_format, channels) }
|
||||
pixel_format: c_int,
|
||||
channels: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_static_get_bytes_per_pixel(
|
||||
pixel_format,
|
||||
channels,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -494,7 +617,11 @@ pub fn oakcommon_videoparams_get_time_in_timebase_units(
|
||||
time_den: c_int,
|
||||
timestamp: *mut i64,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::videoparams::oakcommon_videoparams_get_time_in_timebase_units(params, time_num, time_den, timestamp) }
|
||||
unsafe {
|
||||
oakcommon::ffi::videoparams::oakcommon_videoparams_get_time_in_timebase_units(
|
||||
params, time_num, time_den, timestamp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -506,11 +633,13 @@ pub fn oakcommon_colortransform_init_output(output: *const c_char) -> CHandle {
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_colortransform_init_display(
|
||||
display: *const c_char,
|
||||
view: *const c_char,
|
||||
look: *const c_char,
|
||||
) -> CHandle {
|
||||
unsafe { oakcommon::ffi::colortransform::oakcommon_colortransform_init_display(display, view, look) }
|
||||
display: *const c_char,
|
||||
view: *const c_char,
|
||||
look: *const c_char,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakcommon::ffi::colortransform::oakcommon_colortransform_init_display(display, view, look)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -528,41 +657,53 @@ pub fn oakcommon_colortransform_is_display(transform: CHandle) -> c_int {
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_colortransform_get_display(
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::colortransform::oakcommon_colortransform_get_display(transform, buf, buf_size) }
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::colortransform::oakcommon_colortransform_get_display(
|
||||
transform, buf, buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_colortransform_get_output(
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::colortransform::oakcommon_colortransform_get_output(transform, buf, buf_size) }
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::colortransform::oakcommon_colortransform_get_output(
|
||||
transform, buf, buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_colortransform_get_view(
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::colortransform::oakcommon_colortransform_get_view(transform, buf, buf_size) }
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::colortransform::oakcommon_colortransform_get_view(transform, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_colortransform_get_look(
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::colortransform::oakcommon_colortransform_get_look(transform, buf, buf_size) }
|
||||
transform: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::colortransform::oakcommon_colortransform_get_look(transform, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -592,11 +733,13 @@ pub fn oakcommon_xml_reader_name(reader: CHandle, buf: *mut c_char, buf_size: c_
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_xml_reader_read_element_text(
|
||||
reader: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::xmlutils::oakcommon_xml_reader_read_element_text(reader, buf, buf_size) }
|
||||
reader: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::xmlutils::oakcommon_xml_reader_read_element_text(reader, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -614,23 +757,27 @@ pub fn oakcommon_xml_reader_attribute_count(reader: CHandle, count: *mut c_int)
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_xml_reader_attribute_name(
|
||||
reader: CHandle,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::xmlutils::oakcommon_xml_reader_attribute_name(reader, index, buf, buf_size) }
|
||||
reader: CHandle,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::xmlutils::oakcommon_xml_reader_attribute_name(reader, index, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_xml_reader_attribute_value(
|
||||
reader: CHandle,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::xmlutils::oakcommon_xml_reader_attribute_value(reader, index, buf, buf_size) }
|
||||
reader: CHandle,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakcommon::ffi::xmlutils::oakcommon_xml_reader_attribute_value(reader, index, buf, buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
@@ -660,10 +807,10 @@ pub fn oakcommon_xml_writer_write_start_element(writer: CHandle, name: *const c_
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_xml_writer_write_attribute(
|
||||
writer: CHandle,
|
||||
name: *const c_char,
|
||||
value: *const c_char,
|
||||
) -> c_int {
|
||||
writer: CHandle,
|
||||
name: *const c_char,
|
||||
value: *const c_char,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::xmlutils::oakcommon_xml_writer_write_attribute(writer, name, value) }
|
||||
}
|
||||
|
||||
@@ -676,10 +823,10 @@ pub fn oakcommon_xml_writer_write_characters(writer: CHandle, text: *const c_cha
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_xml_writer_write_text_element(
|
||||
writer: CHandle,
|
||||
name: *const c_char,
|
||||
text: *const c_char,
|
||||
) -> c_int {
|
||||
writer: CHandle,
|
||||
name: *const c_char,
|
||||
text: *const c_char,
|
||||
) -> c_int {
|
||||
unsafe { oakcommon::ffi::xmlutils::oakcommon_xml_writer_write_text_element(writer, name, text) }
|
||||
}
|
||||
|
||||
@@ -728,12 +875,15 @@ pub fn oakcommon_decibel_to_logarithmic(db: f64, out_logarithmic: *mut f64) -> c
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_decibel_linear_to_logarithmic(linear: f64, out_logarithmic: *mut f64) -> c_int {
|
||||
unsafe { oakcommon::ffi::misc::oakcommon_decibel_linear_to_logarithmic(linear, out_logarithmic) }
|
||||
unsafe {
|
||||
oakcommon::ffi::misc::oakcommon_decibel_linear_to_logarithmic(linear, out_logarithmic)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakcommon` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakcommon_decibel_logarithmic_to_linear(logarithmic: f64, out_linear: *mut f64) -> c_int {
|
||||
unsafe { oakcommon::ffi::misc::oakcommon_decibel_logarithmic_to_linear(logarithmic, out_linear) }
|
||||
unsafe {
|
||||
oakcommon::ffi::misc::oakcommon_decibel_logarithmic_to_linear(logarithmic, out_linear)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
pub mod audio;
|
||||
pub mod codec;
|
||||
pub mod common;
|
||||
pub mod undo;
|
||||
pub mod node;
|
||||
pub mod plugin;
|
||||
pub mod render;
|
||||
pub mod node;
|
||||
pub mod timeline;
|
||||
pub mod task;
|
||||
pub mod timeline;
|
||||
pub mod undo;
|
||||
|
||||
+1180
-401
File diff suppressed because it is too large
Load Diff
@@ -72,7 +72,10 @@ pub fn oakplugin_host_plugin_id_at(index: c_int, buf: *mut c_char, buf_size: c_i
|
||||
|
||||
/// Direct call into the `oakplugin` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakplugin_host_plugin_label(plugin_id: *const c_char, buf: *mut c_char, buf_size: c_int) -> c_int {
|
||||
pub fn oakplugin_host_plugin_label(
|
||||
plugin_id: *const c_char,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakplugin::ffi::oakplugin_host_plugin_label(plugin_id, buf, buf_size) }
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ use crate::handle::CHandle;
|
||||
/// layout; all handle fields are the shared [`CHandle`]).
|
||||
pub type OakVideoTicketParams = oakrender::ffi::OakVideoTicketParams;
|
||||
|
||||
|
||||
/// `include/render/renderer.h` — frame video-params POD returned by
|
||||
/// `oakrender_codec_frame_get_params`. Single-lib unification: aliases
|
||||
/// the oakrender crate's POD.
|
||||
@@ -116,29 +115,36 @@ pub fn oakrender_set_display_color_processor(p_or_null: CHandle) -> c_int {
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakrender_ticket_render_frame(
|
||||
params: *const OakVideoTicketParams,
|
||||
cb: Option<unsafe extern "C" fn(CHandle, *mut c_void)>,
|
||||
userdata: *mut c_void,
|
||||
) -> CHandle {
|
||||
params: *const OakVideoTicketParams,
|
||||
cb: Option<unsafe extern "C" fn(CHandle, *mut c_void)>,
|
||||
userdata: *mut c_void,
|
||||
) -> CHandle {
|
||||
unsafe { oakrender::ffi::ticket::oakrender_ticket_render_frame(params, cb, userdata) }
|
||||
}
|
||||
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakrender_ticket_render_audio(
|
||||
output_node: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
out_num: i64,
|
||||
out_den: i64,
|
||||
params: *const c_void,
|
||||
mode: c_int,
|
||||
cb: Option<unsafe extern "C" fn(CHandle, *mut c_void)>,
|
||||
userdata: *mut c_void,
|
||||
) -> CHandle {
|
||||
output_node: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
out_num: i64,
|
||||
out_den: i64,
|
||||
params: *const c_void,
|
||||
mode: c_int,
|
||||
cb: Option<unsafe extern "C" fn(CHandle, *mut c_void)>,
|
||||
userdata: *mut c_void,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakrender::ffi::ticket::oakrender_ticket_render_audio(
|
||||
output_node, in_num, in_den, out_num, out_den, params as *const CHandle, mode, cb,
|
||||
output_node,
|
||||
in_num,
|
||||
in_den,
|
||||
out_num,
|
||||
out_den,
|
||||
params as *const CHandle,
|
||||
mode,
|
||||
cb,
|
||||
userdata,
|
||||
)
|
||||
}
|
||||
@@ -237,11 +243,13 @@ pub fn oakrender_codec_frame_get_params(frame: CHandle, out: *mut OakRenderVideo
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakrender_color_processor_create(
|
||||
src_space: *const c_char,
|
||||
dst_transform: *const c_char,
|
||||
direction: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oakrender::ffi::color::oakrender_color_processor_create(src_space, dst_transform, direction) }
|
||||
src_space: *const c_char,
|
||||
dst_transform: *const c_char,
|
||||
direction: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakrender::ffi::color::oakrender_color_processor_create(src_space, dst_transform, direction)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
@@ -259,28 +267,36 @@ pub fn oakrender_color_processor_is_valid(processor: CHandle) -> c_int {
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakrender_color_processor_create_transform(
|
||||
manager: CHandle,
|
||||
input: *const c_char,
|
||||
dest: CHandle,
|
||||
direction: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oakrender::ffi::color::oakrender_color_processor_create_transform(manager, input, dest, direction) }
|
||||
manager: CHandle,
|
||||
input: *const c_char,
|
||||
dest: CHandle,
|
||||
direction: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oakrender::ffi::color::oakrender_color_processor_create_transform(
|
||||
manager, input, dest, direction,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakrender_color_processor_convert(
|
||||
processor: CHandle,
|
||||
ir: c_double,
|
||||
ig: c_double,
|
||||
ib: c_double,
|
||||
ia: c_double,
|
||||
out_r: *mut c_double,
|
||||
out_g: *mut c_double,
|
||||
out_b: *mut c_double,
|
||||
out_a: *mut c_double,
|
||||
) -> c_int {
|
||||
unsafe { oakrender::ffi::color::oakrender_color_processor_convert(processor, ir, ig, ib, ia, out_r, out_g, out_b, out_a) }
|
||||
processor: CHandle,
|
||||
ir: c_double,
|
||||
ig: c_double,
|
||||
ib: c_double,
|
||||
ia: c_double,
|
||||
out_r: *mut c_double,
|
||||
out_g: *mut c_double,
|
||||
out_b: *mut c_double,
|
||||
out_a: *mut c_double,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oakrender::ffi::color::oakrender_color_processor_convert(
|
||||
processor, ir, ig, ib, ia, out_r, out_g, out_b, out_a,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oakrender` crate (single-lib unification; the
|
||||
@@ -312,4 +328,3 @@ pub fn oakrender_lut_supported_extensions_count() -> c_int {
|
||||
pub fn oakrender_lut_supported_extension_at(i: c_int, buf: *mut c_char, n: c_int) -> c_int {
|
||||
unsafe { oakrender::ffi::color::oakrender_lut_supported_extension_at(i, buf, n) }
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,11 @@ use crate::handle::CHandle;
|
||||
pub type OakTaskEventFn = unsafe extern "C" fn(event_id: c_int, value: f64, userdata: *mut c_void);
|
||||
|
||||
/// `oaktask_otio_import_confirm_fn` (`include/task/project.h`).
|
||||
pub type OakTaskOtioImportConfirmFn =
|
||||
unsafe extern "C" fn(sequence_names: *const *const c_char, count: c_int, userdata: *mut c_void) -> c_int;
|
||||
pub type OakTaskOtioImportConfirmFn = unsafe extern "C" fn(
|
||||
sequence_names: *const *const c_char,
|
||||
count: c_int,
|
||||
userdata: *mut c_void,
|
||||
) -> c_int;
|
||||
|
||||
/// `oaktask_image_sequence_confirm_fn` (`include/task/project.h`).
|
||||
pub type OakTaskImageSequenceConfirmFn =
|
||||
@@ -160,7 +163,11 @@ pub fn oaktask_task_error(t: CHandle, buf: *mut c_char, buf_size: c_int) -> c_in
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_task_subscribe(t: CHandle, cb: Option<OakTaskEventFn>, userdata: *mut c_void) -> i64 {
|
||||
pub fn oaktask_task_subscribe(
|
||||
t: CHandle,
|
||||
cb: Option<OakTaskEventFn>,
|
||||
userdata: *mut c_void,
|
||||
) -> i64 {
|
||||
unsafe { oaktask::ffi::task::oaktask_task_subscribe(t, cb, userdata) }
|
||||
}
|
||||
|
||||
@@ -184,14 +191,31 @@ pub fn oaktask_load_take_project(t: CHandle) -> CHandle {
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_create_project_save(project: CHandle, filename_or_null: *const c_char, use_compression: c_int) -> CHandle {
|
||||
unsafe { oaktask::ffi::project::oaktask_create_project_save(project, filename_or_null, use_compression) }
|
||||
pub fn oaktask_create_project_save(
|
||||
project: CHandle,
|
||||
filename_or_null: *const c_char,
|
||||
use_compression: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktask::ffi::project::oaktask_create_project_save(
|
||||
project,
|
||||
filename_or_null,
|
||||
use_compression,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_create_project_import(folder: CHandle, project: CHandle, urls: *const *const c_char, url_count: c_int) -> CHandle {
|
||||
unsafe { oaktask::ffi::project::oaktask_create_project_import(folder, project, urls, url_count) }
|
||||
pub fn oaktask_create_project_import(
|
||||
folder: CHandle,
|
||||
project: CHandle,
|
||||
urls: *const *const c_char,
|
||||
url_count: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktask::ffi::project::oaktask_create_project_import(folder, project, urls, url_count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
@@ -220,7 +244,12 @@ pub fn oaktask_import_invalid_count(t: CHandle) -> c_int {
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_import_invalid_at(t: CHandle, index: c_int, buf: *mut c_char, buf_size: c_int) -> c_int {
|
||||
pub fn oaktask_import_invalid_at(
|
||||
t: CHandle,
|
||||
index: c_int,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktask::ffi::project::oaktask_import_invalid_at(t, index, buf, buf_size) }
|
||||
}
|
||||
|
||||
@@ -244,7 +273,10 @@ pub fn oaktask_create_project_save_otio(project: CHandle, filename: *const c_cha
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_load_otio_set_confirm_cb(cb: Option<OakTaskOtioImportConfirmFn>, userdata: *mut c_void) {
|
||||
pub fn oaktask_load_otio_set_confirm_cb(
|
||||
cb: Option<OakTaskOtioImportConfirmFn>,
|
||||
userdata: *mut c_void,
|
||||
) {
|
||||
unsafe { oaktask::ffi::project::oaktask_load_otio_set_confirm_cb(cb, userdata) }
|
||||
}
|
||||
|
||||
@@ -260,16 +292,18 @@ pub fn oaktask_create_precache(footage: CHandle, index: c_int, sequence: CHandle
|
||||
/// (single-lib unification; the encoding-params POD is the shared
|
||||
/// oakcodec type).
|
||||
pub fn oaktask_create_export(
|
||||
viewer: CHandle,
|
||||
color_manager: CHandle,
|
||||
params: *const crate::bridge::codec::EncodingParamsPOD,
|
||||
) -> CHandle {
|
||||
viewer: CHandle,
|
||||
color_manager: CHandle,
|
||||
params: *const crate::bridge::codec::EncodingParamsPOD,
|
||||
) -> CHandle {
|
||||
unsafe { oaktask::ffi::project::oaktask_create_export(viewer, color_manager, params) }
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktask` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktask_import_set_image_sequence_confirm_cb(cb: Option<OakTaskImageSequenceConfirmFn>, userdata: *mut c_void) {
|
||||
pub fn oaktask_import_set_image_sequence_confirm_cb(
|
||||
cb: Option<OakTaskImageSequenceConfirmFn>,
|
||||
userdata: *mut c_void,
|
||||
) {
|
||||
unsafe { oaktask::ffi::project::oaktask_import_set_image_sequence_confirm_cb(cb, userdata) }
|
||||
}
|
||||
|
||||
|
||||
@@ -79,15 +79,19 @@ pub fn oaktimeline_marker_list_free(list: *mut CHandle) {
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_marker_add(
|
||||
list: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
name: *const c_char,
|
||||
color: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktimeline::ffi::marker::oaktimeline_marker_add(list, in_num, in_den, out_num, out_den, name, color) }
|
||||
list: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
name: *const c_char,
|
||||
color: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_add(
|
||||
list, in_num, in_den, out_num, out_den, name, color,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -99,31 +103,39 @@ pub fn oaktimeline_marker_count(list: CHandle, out_count: *mut c_int) -> c_int {
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_marker_at(
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
color: *mut c_int,
|
||||
name_buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktimeline::ffi::marker::oaktimeline_marker_at(list, index, in_num, in_den, out_num, out_den, color, name_buf, buf_size) }
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
color: *mut c_int,
|
||||
name_buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_at(
|
||||
list, index, in_num, in_den, out_num, out_den, color, name_buf, buf_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_marker_add_command(
|
||||
list: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
name: *const c_char,
|
||||
color: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::marker::oaktimeline_marker_add_command(list, in_num, in_den, out_num, out_den, name, color) }
|
||||
list: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
name: *const c_char,
|
||||
color: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_add_command(
|
||||
list, in_num, in_den, out_num, out_den, name, color,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -135,25 +147,31 @@ pub fn oaktimeline_marker_remove_at_command(list: CHandle, index: c_int) -> CHan
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_marker_set_time_command(
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::marker::oaktimeline_marker_set_time_command(list, index, in_num, in_den, out_num, out_den) }
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_set_time_command(
|
||||
list, index, in_num, in_den, out_num, out_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_marker_set_props_command(
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
color: c_int,
|
||||
name: *const c_char,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::marker::oaktimeline_marker_set_props_command(list, index, color, name) }
|
||||
list: CHandle,
|
||||
index: c_int,
|
||||
color: c_int,
|
||||
name: *const c_char,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_set_props_command(list, index, color, name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -195,42 +213,62 @@ pub fn oaktimeline_workarea_set_enabled(w: CHandle, enabled: c_int) -> c_int {
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_workarea_get(
|
||||
w: CHandle,
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
enabled: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktimeline::ffi::workarea::oaktimeline_workarea_get(w, in_num, in_den, out_num, out_den, enabled) }
|
||||
w: CHandle,
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
enabled: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oaktimeline::ffi::workarea::oaktimeline_workarea_get(
|
||||
w, in_num, in_den, out_num, out_den, enabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_workarea_set_range(
|
||||
w: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktimeline::ffi::workarea::oaktimeline_workarea_set_range(w, in_num, in_den, out_num, out_den) }
|
||||
w: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oaktimeline::ffi::workarea::oaktimeline_workarea_set_range(
|
||||
w, in_num, in_den, out_num, out_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_workarea_set_range_command(
|
||||
w: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
old_in_num: c_int,
|
||||
old_in_den: c_int,
|
||||
old_out_num: c_int,
|
||||
old_out_den: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::workarea::oaktimeline_workarea_set_range_command(w, in_num, in_den, out_num, out_den, old_in_num, old_in_den, old_out_num, old_out_den) }
|
||||
w: CHandle,
|
||||
in_num: c_int,
|
||||
in_den: c_int,
|
||||
out_num: c_int,
|
||||
out_den: c_int,
|
||||
old_in_num: c_int,
|
||||
old_in_den: c_int,
|
||||
old_out_num: c_int,
|
||||
old_out_den: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::workarea::oaktimeline_workarea_set_range_command(
|
||||
w,
|
||||
in_num,
|
||||
in_den,
|
||||
out_num,
|
||||
out_den,
|
||||
old_in_num,
|
||||
old_in_den,
|
||||
old_out_num,
|
||||
old_out_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -242,12 +280,14 @@ pub fn oaktimeline_workarea_set_enabled_command(w: CHandle, enabled: c_int) -> C
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_workarea_reset(
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe { oaktimeline::ffi::workarea::oaktimeline_workarea_reset(in_num, in_den, out_num, out_den) }
|
||||
in_num: *mut c_int,
|
||||
in_den: *mut c_int,
|
||||
out_num: *mut c_int,
|
||||
out_den: *mut c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
oaktimeline::ffi::workarea::oaktimeline_workarea_reset(in_num, in_den, out_num, out_den)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -277,13 +317,21 @@ pub fn oaktimeline_remove_track_command(track: CHandle) -> CHandle {
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_place_block_command(
|
||||
list: CHandle,
|
||||
track_index: c_int,
|
||||
block: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_place_block_command(list, track_index, block, in_num, in_den) }
|
||||
list: CHandle,
|
||||
track_index: c_int,
|
||||
block: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_place_block_command(
|
||||
list,
|
||||
track_index,
|
||||
block,
|
||||
in_num,
|
||||
in_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
@@ -294,83 +342,149 @@ pub fn oaktimeline_replace_block_with_gap_command(track: CHandle, block: CHandle
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_trim_command(
|
||||
track: CHandle,
|
||||
block: CHandle,
|
||||
new_length_num: i64,
|
||||
new_length_den: i64,
|
||||
mode: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_trim_command(track, block, new_length_num, new_length_den, mode) }
|
||||
pub fn oaktimeline_move_block_command(
|
||||
list: CHandle,
|
||||
track_index: c_int,
|
||||
block: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_move_block_command(
|
||||
list,
|
||||
track_index,
|
||||
block,
|
||||
in_num,
|
||||
in_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_split_command(blocks: *const CHandle, count: c_int, point_num: i64, point_den: i64) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_split_command(blocks, count, point_num, point_den) }
|
||||
pub fn oaktimeline_trim_command(
|
||||
track: CHandle,
|
||||
block: CHandle,
|
||||
new_length_num: i64,
|
||||
new_length_den: i64,
|
||||
mode: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_trim_command(
|
||||
track,
|
||||
block,
|
||||
new_length_num,
|
||||
new_length_den,
|
||||
mode,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_split_command(
|
||||
blocks: *const CHandle,
|
||||
count: c_int,
|
||||
point_num: i64,
|
||||
point_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_split_command(blocks, count, point_num, point_den)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_split_preserving_links_command(
|
||||
blocks: *const CHandle,
|
||||
count: c_int,
|
||||
point_nums: *const i64,
|
||||
point_dens: *const i64,
|
||||
time_count: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_split_preserving_links_command(blocks, count, point_nums, point_dens, time_count) }
|
||||
blocks: *const CHandle,
|
||||
count: c_int,
|
||||
point_nums: *const i64,
|
||||
point_dens: *const i64,
|
||||
time_count: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_split_preserving_links_command(
|
||||
blocks, count, point_nums, point_dens, time_count,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_ripple_delete_gaps_command(
|
||||
sequence: CHandle,
|
||||
in_nums: *const i64,
|
||||
in_dens: *const i64,
|
||||
out_nums: *const i64,
|
||||
out_dens: *const i64,
|
||||
tracks: *const CHandle,
|
||||
range_count: c_int,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_ripple_delete_gaps_command(sequence, in_nums, in_dens, out_nums, out_dens, tracks, range_count) }
|
||||
sequence: CHandle,
|
||||
in_nums: *const i64,
|
||||
in_dens: *const i64,
|
||||
out_nums: *const i64,
|
||||
out_dens: *const i64,
|
||||
tracks: *const CHandle,
|
||||
range_count: c_int,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_ripple_delete_gaps_command(
|
||||
sequence,
|
||||
in_nums,
|
||||
in_dens,
|
||||
out_nums,
|
||||
out_dens,
|
||||
tracks,
|
||||
range_count,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_slide_command(
|
||||
track: CHandle,
|
||||
blocks: *const CHandle,
|
||||
block_count: c_int,
|
||||
in_adjacent: CHandle,
|
||||
out_adjacent: CHandle,
|
||||
movement_num: i64,
|
||||
movement_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_slide_command(track, blocks, block_count, in_adjacent, out_adjacent, movement_num, movement_den) }
|
||||
track: CHandle,
|
||||
blocks: *const CHandle,
|
||||
block_count: c_int,
|
||||
in_adjacent: CHandle,
|
||||
out_adjacent: CHandle,
|
||||
movement_num: i64,
|
||||
movement_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_slide_command(
|
||||
track,
|
||||
blocks,
|
||||
block_count,
|
||||
in_adjacent,
|
||||
out_adjacent,
|
||||
movement_num,
|
||||
movement_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_ripple_remove_area_command(
|
||||
track: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
out_num: i64,
|
||||
out_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_ripple_remove_area_command(track, in_num, in_den, out_num, out_den) }
|
||||
track: CHandle,
|
||||
in_num: i64,
|
||||
in_den: i64,
|
||||
out_num: i64,
|
||||
out_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_ripple_remove_area_command(
|
||||
track, in_num, in_den, out_num, out_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Direct call into the `oaktimeline` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oaktimeline_insert_gaps_command(
|
||||
list: CHandle,
|
||||
point_num: i64,
|
||||
point_den: i64,
|
||||
length_num: i64,
|
||||
length_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe { oaktimeline::ffi::edit::oaktimeline_insert_gaps_command(list, point_num, point_den, length_num, length_den) }
|
||||
list: CHandle,
|
||||
point_num: i64,
|
||||
point_den: i64,
|
||||
length_num: i64,
|
||||
length_den: i64,
|
||||
) -> CHandle {
|
||||
unsafe {
|
||||
oaktimeline::ffi::edit::oaktimeline_insert_gaps_command(
|
||||
list, point_num, point_den, length_num, length_den,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ use std::ffi::{c_char, c_int};
|
||||
|
||||
use crate::handle::CHandle;
|
||||
|
||||
|
||||
/// `include/undo/undocommand.h` — callback table backing a
|
||||
/// caller-defined undo command. Single-lib unification: aliases the
|
||||
/// oakundo crate's vtable POD.
|
||||
@@ -57,9 +56,9 @@ pub type OakUndoCommandVtable = oakundo::undocommand::OakUndoCommandVtable;
|
||||
/// Direct call into the `oakundo` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakundo_command_init(
|
||||
vtable: *const OakUndoCommandVtable,
|
||||
userdata: *mut std::ffi::c_void,
|
||||
) -> CHandle {
|
||||
vtable: *const OakUndoCommandVtable,
|
||||
userdata: *mut std::ffi::c_void,
|
||||
) -> CHandle {
|
||||
unsafe { oakundo::ffi::command::oakundo_command_init(vtable, userdata) }
|
||||
}
|
||||
|
||||
@@ -83,11 +82,7 @@ pub fn oakundo_command_multi_child_count(multi: CHandle, out_count: *mut c_int)
|
||||
|
||||
/// Direct call into the `oakundo` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakundo_command_multi_child(
|
||||
multi: CHandle,
|
||||
index: c_int,
|
||||
out_child: *mut CHandle,
|
||||
) -> c_int {
|
||||
pub fn oakundo_command_multi_child(multi: CHandle, index: c_int, out_child: *mut CHandle) -> c_int {
|
||||
unsafe { oakundo::ffi::command::oakundo_command_multi_child(multi, index, out_child) }
|
||||
}
|
||||
|
||||
@@ -130,10 +125,10 @@ pub fn oakundo_undostack_push(stack: CHandle, command: CHandle, name: *const c_c
|
||||
/// Direct call into the `oakundo` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakundo_undostack_push_pre_executed(
|
||||
stack: CHandle,
|
||||
command: CHandle,
|
||||
name: *const c_char,
|
||||
) -> c_int {
|
||||
stack: CHandle,
|
||||
command: CHandle,
|
||||
name: *const c_char,
|
||||
) -> c_int {
|
||||
unsafe { oakundo::ffi::undostack::oakundo_undostack_push_pre_executed(stack, command, name) }
|
||||
}
|
||||
|
||||
@@ -188,21 +183,16 @@ pub fn oakundo_undostack_index(stack: CHandle, out_index: *mut i64) -> c_int {
|
||||
/// Direct call into the `oakundo` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakundo_undostack_command_text(
|
||||
stack: CHandle,
|
||||
row: i64,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
stack: CHandle,
|
||||
row: i64,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
unsafe { oakundo::ffi::undostack::oakundo_undostack_command_text(stack, row, buf, buf_size) }
|
||||
}
|
||||
|
||||
/// Direct call into the `oakundo` crate (single-lib unification; the
|
||||
/// `#[no_mangle]` export stays for the external C ABI).
|
||||
pub fn oakundo_undostack_command_is_done(
|
||||
stack: CHandle,
|
||||
row: i64,
|
||||
out_value: *mut c_int,
|
||||
) -> c_int {
|
||||
pub fn oakundo_undostack_command_is_done(stack: CHandle, row: i64, out_value: *mut c_int) -> c_int {
|
||||
unsafe { oakundo::ffi::undostack::oakundo_undostack_command_is_done(stack, row, out_value) }
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ use std::collections::HashMap;
|
||||
use std::ffi::{c_char, c_int, c_void};
|
||||
|
||||
use crate::bridge::codec as k;
|
||||
use crate::bridge::codec::{EncodingParamsPOD, zeroed_encoding_params};
|
||||
use crate::bridge::codec::{zeroed_encoding_params, EncodingParamsPOD};
|
||||
use crate::common::OakVideoParamsPod;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::handle::{guard, guard_int, string_result};
|
||||
@@ -97,7 +97,11 @@ fn field_str(field: &[u8]) -> String {
|
||||
/// Write a string into a fixed array field (truncated, NUL-terminated).
|
||||
fn write_field(field: &mut [u8], value: &str) {
|
||||
for (i, slot) in field.iter_mut().enumerate() {
|
||||
*slot = if i < value.len() { value.as_bytes()[i] } else { 0 };
|
||||
*slot = if i < value.len() {
|
||||
value.as_bytes()[i]
|
||||
} else {
|
||||
0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +181,10 @@ pub extern "C" fn oakengine_encoding_format_subtitle_codec_count(format: c_int)
|
||||
|
||||
/// `oakengine_encoding_format_subtitle_codec_at`.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn oakengine_encoding_format_subtitle_codec_at(format: c_int, index: c_int) -> c_int {
|
||||
pub extern "C" fn oakengine_encoding_format_subtitle_codec_at(
|
||||
format: c_int,
|
||||
index: c_int,
|
||||
) -> c_int {
|
||||
guard_int(|| Ok(unsafe { k::oakcodec_encoding_format_subtitle_codec_at(format, index) }))
|
||||
}
|
||||
|
||||
@@ -237,7 +244,10 @@ pub unsafe extern "C" fn oakengine_encoding_pix_fmt_at(
|
||||
|
||||
/// `oakengine_encoding_pix_fmt_index` (0 = preferred when absent).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_encoding_pix_fmt_index(codec: c_int, pix_fmt: *const c_char) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_encoding_pix_fmt_index(
|
||||
codec: c_int,
|
||||
pix_fmt: *const c_char,
|
||||
) -> c_int {
|
||||
guard_int(|| Ok(unsafe { k::oakcodec_encoding_pix_fmt_index(codec, pix_fmt) }))
|
||||
}
|
||||
|
||||
@@ -249,7 +259,11 @@ pub extern "C" fn oakengine_encoding_sample_format_count(format: c_int, codec: c
|
||||
|
||||
/// `oakengine_encoding_sample_format_at` (-1 out of range).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn oakengine_encoding_sample_format_at(format: c_int, codec: c_int, index: c_int) -> c_int {
|
||||
pub extern "C" fn oakengine_encoding_sample_format_at(
|
||||
format: c_int,
|
||||
codec: c_int,
|
||||
index: c_int,
|
||||
) -> c_int {
|
||||
guard_int(|| Ok(unsafe { k::oakcodec_encoding_sample_format_at(format, codec, index) }))
|
||||
}
|
||||
|
||||
@@ -350,11 +364,14 @@ pub unsafe extern "C" fn oakengine_encoding_params_is_valid(
|
||||
) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
let p = params_ref(params)?;
|
||||
Ok(if p.pod.video_enabled != 0 || p.pod.audio_enabled != 0 || p.pod.subtitles_enabled != 0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
})
|
||||
Ok(
|
||||
if p.pod.video_enabled != 0 || p.pod.audio_enabled != 0 || p.pod.subtitles_enabled != 0
|
||||
{
|
||||
1
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -383,7 +400,11 @@ pub unsafe extern "C" fn oakengine_encoding_params_filename(
|
||||
) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
let p = params_ref(params)?;
|
||||
Ok(crate::handle::write_string(&field_str(&p.pod.filename), buf, buf_size))
|
||||
Ok(crate::handle::write_string(
|
||||
&field_str(&p.pod.filename),
|
||||
buf,
|
||||
buf_size,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -697,11 +718,31 @@ macro_rules! params_i64_field {
|
||||
};
|
||||
}
|
||||
|
||||
params_i64_field!(oakengine_encoding_params_set_video_bit_rate, oakengine_encoding_params_video_bit_rate, video_bit_rate);
|
||||
params_i64_field!(oakengine_encoding_params_set_video_min_bit_rate, oakengine_encoding_params_video_min_bit_rate, video_min_bit_rate);
|
||||
params_i64_field!(oakengine_encoding_params_set_video_max_bit_rate, oakengine_encoding_params_video_max_bit_rate, video_max_bit_rate);
|
||||
params_i64_field!(oakengine_encoding_params_set_video_buffer_size, oakengine_encoding_params_video_buffer_size, video_buffer_size);
|
||||
params_i64_field!(oakengine_encoding_params_set_audio_bit_rate, oakengine_encoding_params_audio_bit_rate, audio_bit_rate);
|
||||
params_i64_field!(
|
||||
oakengine_encoding_params_set_video_bit_rate,
|
||||
oakengine_encoding_params_video_bit_rate,
|
||||
video_bit_rate
|
||||
);
|
||||
params_i64_field!(
|
||||
oakengine_encoding_params_set_video_min_bit_rate,
|
||||
oakengine_encoding_params_video_min_bit_rate,
|
||||
video_min_bit_rate
|
||||
);
|
||||
params_i64_field!(
|
||||
oakengine_encoding_params_set_video_max_bit_rate,
|
||||
oakengine_encoding_params_video_max_bit_rate,
|
||||
video_max_bit_rate
|
||||
);
|
||||
params_i64_field!(
|
||||
oakengine_encoding_params_set_video_buffer_size,
|
||||
oakengine_encoding_params_video_buffer_size,
|
||||
video_buffer_size
|
||||
);
|
||||
params_i64_field!(
|
||||
oakengine_encoding_params_set_audio_bit_rate,
|
||||
oakengine_encoding_params_audio_bit_rate,
|
||||
audio_bit_rate
|
||||
);
|
||||
|
||||
/// `oakengine_encoding_params_set_video_threads`.
|
||||
#[no_mangle]
|
||||
@@ -752,7 +793,11 @@ pub unsafe extern "C" fn oakengine_encoding_params_video_pix_fmt(
|
||||
) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
let p = params_ref(params)?;
|
||||
Ok(crate::handle::write_string(&field_str(&p.pod.video_pix_fmt), buf, buf_size))
|
||||
Ok(crate::handle::write_string(
|
||||
&field_str(&p.pod.video_pix_fmt),
|
||||
buf,
|
||||
buf_size,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -948,8 +993,10 @@ pub unsafe extern "C" fn oakengine_encoding_params_set_video_option(
|
||||
if key.is_null() || value.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
p.video_options
|
||||
.insert(crate::handle::read_cstr(key), crate::handle::read_cstr(value));
|
||||
p.video_options.insert(
|
||||
crate::handle::read_cstr(key),
|
||||
crate::handle::read_cstr(value),
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@@ -982,7 +1029,10 @@ pub unsafe extern "C" fn oakengine_encoding_params_video_option(
|
||||
/// `oakengine_encoding_preset_path` — **not backed** (no preset API in the
|
||||
/// oakcodec crate). Returns OAKENGINE_E_FAILED.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_encoding_preset_path(_buf: *mut c_char, _buf_size: c_int) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_encoding_preset_path(
|
||||
_buf: *mut c_char,
|
||||
_buf_size: c_int,
|
||||
) -> c_int {
|
||||
crate::error::OAKENGINE_E_FAILED
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ use crate::handle::{
|
||||
static ERROR_FN: OnceLock<Mutex<Option<(Option<ConfigErrorFn>, usize)>>> = OnceLock::new();
|
||||
|
||||
/// `engine/include/oakengine/config.h` error callback.
|
||||
pub type ConfigErrorFn = unsafe extern "C" fn(title: *const c_char, message: *const c_char, userdata: *mut c_void);
|
||||
pub type ConfigErrorFn =
|
||||
unsafe extern "C" fn(title: *const c_char, message: *const c_char, userdata: *mut c_void);
|
||||
|
||||
fn error_fn_slot() -> &'static Mutex<Option<(Option<ConfigErrorFn>, usize)>> {
|
||||
ERROR_FN.get_or_init(|| Mutex::new(None))
|
||||
@@ -113,7 +114,11 @@ pub extern "C" fn oakengine_config_get_int(key: *const c_char, default_value: i6
|
||||
if key.is_null() {
|
||||
return Ok(default_value);
|
||||
}
|
||||
Ok(c::oakcommon_config_get_int64(std::ptr::null(), key, default_value))
|
||||
Ok(c::oakcommon_config_get_int64(
|
||||
std::ptr::null(),
|
||||
key,
|
||||
default_value,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -151,12 +156,19 @@ pub extern "C" fn oakengine_config_set_error_handler(
|
||||
/// `oakengine_config_report_error` — report an error through the
|
||||
/// registered handler (logged and discarded when none is set).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_config_report_error(title: *const c_char, message: *const c_char) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_config_report_error(
|
||||
title: *const c_char,
|
||||
message: *const c_char,
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
let slot = error_fn_slot().lock().unwrap_or_else(|e| e.into_inner());
|
||||
if let Some((Some(fn_), userdata)) = *slot {
|
||||
let title = if title.is_null() { empty_cstr() } else { title };
|
||||
let message = if message.is_null() { empty_cstr() } else { message };
|
||||
let message = if message.is_null() {
|
||||
empty_cstr()
|
||||
} else {
|
||||
message
|
||||
};
|
||||
fn_(title, message, userdata as *mut c_void);
|
||||
}
|
||||
Ok(())
|
||||
@@ -194,14 +206,8 @@ const SUPPORTED_FRAME_RATES: &[(c_int, c_int)] = &[
|
||||
|
||||
/// Standard pixel aspect ratios as num/den
|
||||
/// (`VideoParams::k_standard_pixel_aspects`).
|
||||
const STANDARD_PIXEL_ASPECTS: &[(c_int, c_int)] = &[
|
||||
(1, 1),
|
||||
(8, 9),
|
||||
(32, 27),
|
||||
(16, 15),
|
||||
(64, 45),
|
||||
(4, 3),
|
||||
];
|
||||
const STANDARD_PIXEL_ASPECTS: &[(c_int, c_int)] =
|
||||
&[(1, 1), (8, 9), (32, 27), (16, 15), (64, 45), (4, 3)];
|
||||
|
||||
/// Supported preview dividers (`VideoParams::k_supported_dividers`).
|
||||
const SUPPORTED_DIVIDERS: &[c_int] = &[1, 2, 3, 4, 6, 8, 12, 16];
|
||||
@@ -455,7 +461,9 @@ pub unsafe extern "C" fn oakengine_video_params_make(
|
||||
/// from a POD (returns an opaque engine pointer; free with
|
||||
/// `oakengine_video_params_free`).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_video_params_create(pod: *const OakVideoParamsPod) -> *mut c_void {
|
||||
pub unsafe extern "C" fn oakengine_video_params_create(
|
||||
pod: *const OakVideoParamsPod,
|
||||
) -> *mut c_void {
|
||||
crate::handle::guard_ptr(|| unsafe {
|
||||
if pod.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -469,7 +477,11 @@ pub unsafe extern "C" fn oakengine_video_params_create(pod: *const OakVideoParam
|
||||
rc = c::oakcommon_videoparams_set_height(params, (*pod).height);
|
||||
}
|
||||
if rc == 0 {
|
||||
rc = c::oakcommon_videoparams_set_time_base(params, (*pod).time_base_num, (*pod).time_base_den);
|
||||
rc = c::oakcommon_videoparams_set_time_base(
|
||||
params,
|
||||
(*pod).time_base_num,
|
||||
(*pod).time_base_den,
|
||||
);
|
||||
}
|
||||
if rc == 0 {
|
||||
rc = c::oakcommon_videoparams_set_format(params, (*pod).format);
|
||||
@@ -494,7 +506,10 @@ pub unsafe extern "C" fn oakengine_video_params_create(pod: *const OakVideoParam
|
||||
rc = c::oakcommon_videoparams_set_video_type(params, (*pod).video_type);
|
||||
}
|
||||
if rc == 0 {
|
||||
rc = c::oakcommon_videoparams_set_premultiplied_alpha(params, (*pod).premultiplied_alpha);
|
||||
rc = c::oakcommon_videoparams_set_premultiplied_alpha(
|
||||
params,
|
||||
(*pod).premultiplied_alpha,
|
||||
);
|
||||
}
|
||||
if rc != 0 {
|
||||
let mut p = params;
|
||||
@@ -570,7 +585,9 @@ pub unsafe extern "C" fn oakengine_video_params_is_valid(p: *const OakVideoParam
|
||||
/// `format` with `channels` channels.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn oakengine_video_params_bytes_per_pixel(format: c_int, channels: c_int) -> c_int {
|
||||
guard_int(|| Ok(unsafe { c::oakcommon_videoparams_static_get_bytes_per_pixel(format, channels) }))
|
||||
guard_int(|| {
|
||||
Ok(unsafe { c::oakcommon_videoparams_static_get_bytes_per_pixel(format, channels) })
|
||||
})
|
||||
}
|
||||
|
||||
/// `oakengine_video_params_internal_channel_count` — RGBA.
|
||||
|
||||
+33
-38
@@ -403,8 +403,7 @@ impl FrameSlotPool {
|
||||
let ring_cap = slot_count + 1;
|
||||
let free_off = align_up(POOL_HEADER_SIZE, K_ALIGN);
|
||||
let ready_off = free_off + align_up(SpscRingBuffer::bytes_needed(ring_cap), K_ALIGN);
|
||||
let meta_off =
|
||||
ready_off + align_up(SpscRingBuffer::bytes_needed(ring_cap), K_ALIGN);
|
||||
let meta_off = ready_off + align_up(SpscRingBuffer::bytes_needed(ring_cap), K_ALIGN);
|
||||
let data_off = meta_off + align_up(FRAME_SLOT_META_SIZE * slot_count as usize, K_ALIGN);
|
||||
|
||||
let pool = unsafe {
|
||||
@@ -479,8 +478,12 @@ impl FrameSlotPool {
|
||||
FrameSlotPool {
|
||||
base: ptr::null_mut(),
|
||||
header: ptr::null_mut(),
|
||||
free_ring: SpscRingBuffer { base: ptr::null_mut() },
|
||||
ready_ring: SpscRingBuffer { base: ptr::null_mut() },
|
||||
free_ring: SpscRingBuffer {
|
||||
base: ptr::null_mut(),
|
||||
},
|
||||
ready_ring: SpscRingBuffer {
|
||||
base: ptr::null_mut(),
|
||||
},
|
||||
meta: ptr::null_mut(),
|
||||
data: ptr::null_mut(),
|
||||
}
|
||||
@@ -694,10 +697,7 @@ impl SharedMemoryRegion {
|
||||
|
||||
if mode == ShmMode::Create {
|
||||
if unsafe { libc::ftruncate(fd, size as libc::off_t) } != 0 {
|
||||
self.error = format!(
|
||||
"ftruncate failed: {}",
|
||||
std::io::Error::last_os_error()
|
||||
);
|
||||
self.error = format!("ftruncate failed: {}", std::io::Error::last_os_error());
|
||||
self.close();
|
||||
return false;
|
||||
}
|
||||
@@ -707,10 +707,7 @@ impl SharedMemoryRegion {
|
||||
// enough up front.
|
||||
let mut st: libc::stat = unsafe { std::mem::zeroed() };
|
||||
if unsafe { libc::fstat(fd, &mut st) } != 0 {
|
||||
self.error = format!(
|
||||
"fstat failed: {}",
|
||||
std::io::Error::last_os_error()
|
||||
);
|
||||
self.error = format!("fstat failed: {}", std::io::Error::last_os_error());
|
||||
self.close();
|
||||
return false;
|
||||
}
|
||||
@@ -876,9 +873,7 @@ pub unsafe extern "C" fn oakengine_ipc_shm_close(self_: *mut OakSharedMemoryRegi
|
||||
|
||||
/// `oakengine_ipc_shm_is_valid` — 1/0.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_is_valid(
|
||||
self_: *const OakSharedMemoryRegion,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_is_valid(self_: *const OakSharedMemoryRegion) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -889,9 +884,7 @@ pub unsafe extern "C" fn oakengine_ipc_shm_is_valid(
|
||||
|
||||
/// `oakengine_ipc_shm_data` — the mapped data pointer (NULL when invalid).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_data(
|
||||
self_: *mut OakSharedMemoryRegion,
|
||||
) -> *mut c_void {
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_data(self_: *mut OakSharedMemoryRegion) -> *mut c_void {
|
||||
guard_ptr(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -903,9 +896,7 @@ pub unsafe extern "C" fn oakengine_ipc_shm_data(
|
||||
|
||||
/// `oakengine_ipc_shm_size` — mapping size in bytes.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_size(
|
||||
self_: *const OakSharedMemoryRegion,
|
||||
) -> usize {
|
||||
pub unsafe extern "C" fn oakengine_ipc_shm_size(self_: *const OakSharedMemoryRegion) -> usize {
|
||||
if self_.is_null() {
|
||||
return 0;
|
||||
}
|
||||
@@ -991,9 +982,7 @@ pub unsafe extern "C" fn oakengine_ipc_framepool_create(
|
||||
|
||||
/// `oakengine_ipc_framepool_attach` — map an existing pool (peer side).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_attach(
|
||||
mem: *mut c_void,
|
||||
) -> *mut OakFrameSlotPool {
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_attach(mem: *mut c_void) -> *mut OakFrameSlotPool {
|
||||
guard_ptr(|| unsafe {
|
||||
if mem.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -1034,9 +1023,7 @@ pub unsafe extern "C" fn oakengine_ipc_framepool_free(self_: *mut OakFrameSlotPo
|
||||
|
||||
/// `oakengine_ipc_framepool_is_valid` — 1/0.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_is_valid(
|
||||
self_: *const OakFrameSlotPool,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_is_valid(self_: *const OakFrameSlotPool) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -1047,9 +1034,7 @@ pub unsafe extern "C" fn oakengine_ipc_framepool_is_valid(
|
||||
|
||||
/// `oakengine_ipc_framepool_slot_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_slot_count(
|
||||
self_: *const OakFrameSlotPool,
|
||||
) -> u32 {
|
||||
pub unsafe extern "C" fn oakengine_ipc_framepool_slot_count(self_: *const OakFrameSlotPool) -> u32 {
|
||||
if self_.is_null() {
|
||||
return 0;
|
||||
}
|
||||
@@ -1242,10 +1227,8 @@ mod tests {
|
||||
fn test_key(name: &str) -> String {
|
||||
static COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
let n = COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
SharedMemoryRegion::make_key(
|
||||
i64::from(std::process::id()),
|
||||
(n & 0x7FFF) as i32,
|
||||
) + &format!("-{name}")
|
||||
SharedMemoryRegion::make_key(i64::from(std::process::id()), (n & 0x7FFF) as i32)
|
||||
+ &format!("-{name}")
|
||||
}
|
||||
|
||||
/// Create one segment and map it a second time — the in-process
|
||||
@@ -1664,7 +1647,10 @@ mod tests {
|
||||
.into_owned();
|
||||
assert_eq!(s, "olive-rw-7-2");
|
||||
// NULL/0 buffer only queries the size.
|
||||
assert_eq!(unsafe { oakengine_ipc_shm_make_key(7, 2, std::ptr::null_mut(), 0) }, n);
|
||||
assert_eq!(
|
||||
unsafe { oakengine_ipc_shm_make_key(7, 2, std::ptr::null_mut(), 0) },
|
||||
n
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1694,7 +1680,10 @@ mod tests {
|
||||
assert_eq!(unsafe { oakengine_ipc_framepool_is_valid(attached) }, 1);
|
||||
|
||||
let mut slot = 0u32;
|
||||
assert_eq!(unsafe { oakengine_ipc_framepool_acquire(pool, &mut slot) }, 1);
|
||||
assert_eq!(
|
||||
unsafe { oakengine_ipc_framepool_acquire(pool, &mut slot) },
|
||||
1
|
||||
);
|
||||
// SAFETY: acquired slot; slot_bytes writable (count in bytes).
|
||||
unsafe {
|
||||
ptr::write_bytes(
|
||||
@@ -1709,7 +1698,10 @@ mod tests {
|
||||
assert_eq!(unsafe { oakengine_ipc_framepool_publish(pool, slot) }, 1);
|
||||
|
||||
let mut got = 99u32;
|
||||
assert_eq!(unsafe { oakengine_ipc_framepool_consume(attached, &mut got) }, 1);
|
||||
assert_eq!(
|
||||
unsafe { oakengine_ipc_framepool_consume(attached, &mut got) },
|
||||
1
|
||||
);
|
||||
assert_eq!(got, slot);
|
||||
// SAFETY: consumed slot.
|
||||
let meta = unsafe { &*oakengine_ipc_framepool_meta_const(attached, got) };
|
||||
@@ -1755,7 +1747,10 @@ mod tests {
|
||||
let region2 = unsafe { oakengine_ipc_shm_create() };
|
||||
let bad = std::ffi::CString::new("olive-rw-no-such-segment-for-test").unwrap();
|
||||
// SAFETY: valid C string + owned handle.
|
||||
assert_eq!(unsafe { oakengine_ipc_shm_open(region2, bad.as_ptr(), size, 1) }, 0);
|
||||
assert_eq!(
|
||||
unsafe { oakengine_ipc_shm_open(region2, bad.as_ptr(), size, 1) },
|
||||
0
|
||||
);
|
||||
let mut eb = [0 as c_char; 256];
|
||||
let n = unsafe { oakengine_ipc_shm_error(region2, eb.as_mut_ptr(), 256) };
|
||||
assert!(n > 0);
|
||||
|
||||
@@ -57,6 +57,14 @@
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
// Re-export the node crate so integration tests (and embedders) address
|
||||
// the SAME compiled instance the facade uses: under `cargo test
|
||||
// --workspace`, oaknode is built twice (oaknode's own dev-dependency
|
||||
// enables oakcodec/test-stubs), and a test that mixes `oaknode::` direct
|
||||
// imports with `oakengine::` re-exports gets two incompatible type
|
||||
// instances (E0308 "multiple different versions of crate oaknode").
|
||||
pub use oaknode;
|
||||
|
||||
pub mod audio;
|
||||
pub mod bridge;
|
||||
pub mod codec;
|
||||
@@ -85,8 +93,8 @@ mod test_link {
|
||||
#![allow(dead_code)]
|
||||
fn force_link() -> usize {
|
||||
let fns: [usize; 4] = [
|
||||
oakrender::ffi::renderer::oakrender_display_renderer_create_opengl
|
||||
as *const () as usize,
|
||||
oakrender::ffi::renderer::oakrender_display_renderer_create_opengl as *const ()
|
||||
as usize,
|
||||
oaknode::ffi::project::oaknode_project_init as *const () as usize,
|
||||
oaktimeline::ffi::marker::oaktimeline_marker_list_create as *const () as usize,
|
||||
oaktask::ffi::manager::oaktask_manager_init as *const () as usize,
|
||||
|
||||
+203
-203
@@ -24,8 +24,8 @@ use crate::bridge::node as n;
|
||||
use crate::common::OakVideoParamsPod;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::handle::{
|
||||
box_handle, free_box, guard, guard_int, guard_ptr, guard_void, read_cstr, string_result,
|
||||
unbox, write_string, CHandle, OakEngineClipboard, OakEngineFootage, OakEngineFrameCache,
|
||||
box_handle, free_box, guard, guard_int, guard_ptr, guard_void, read_cstr, string_result, unbox,
|
||||
write_string, CHandle, OakEngineClipboard, OakEngineFootage, OakEngineFrameCache,
|
||||
OakEngineKeyframe, OakEngineNode, OakEngineNodeDragger, OakEngineProject, OakEngineSequence,
|
||||
OakEngineThumbnailCache, OakEngineWaveformCache,
|
||||
};
|
||||
@@ -302,7 +302,8 @@ fn time_base_for(node: CHandle) -> (i64, i64) {
|
||||
if rc == 0 && !params.is_null() {
|
||||
let mut num: c_int = 0;
|
||||
let mut den: c_int = 0;
|
||||
let fr = unsafe { c::oakcommon_videoparams_get_frame_rate(params, &mut num, &mut den) };
|
||||
let fr =
|
||||
unsafe { c::oakcommon_videoparams_get_frame_rate(params, &mut num, &mut den) };
|
||||
let mut h = params;
|
||||
unsafe { c::oakcommon_videoparams_free(&mut h) };
|
||||
if fr == 0 && num > 0 && den > 0 {
|
||||
@@ -354,8 +355,8 @@ fn command_box(cmd: CHandle) -> Result<*mut OakEngineClipboard> {
|
||||
unsafe fn push_command(cmd: CHandle, name: &str) -> Result<()> {
|
||||
unsafe {
|
||||
let boxed = command_box(cmd)?;
|
||||
let name_c = std::ffi::CString::new(name)
|
||||
.map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
let name_c =
|
||||
std::ffi::CString::new(name).map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
push_or_run(boxed, name_c.as_ptr())
|
||||
}
|
||||
}
|
||||
@@ -574,7 +575,10 @@ pub unsafe extern "C" fn oakengine_project_set_modified(
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
let h = project_handle(self_)?;
|
||||
Error::from_module(n::oaknode_project_set_modified(h, if modified != 0 { 1 } else { 0 }))
|
||||
Error::from_module(n::oaknode_project_set_modified(
|
||||
h,
|
||||
if modified != 0 { 1 } else { 0 },
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -616,9 +620,7 @@ pub unsafe extern "C" fn oakengine_project_filename(
|
||||
|
||||
/// `oakengine_project_footage_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_project_footage_count(
|
||||
self_: *const OakEngineProject,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_project_footage_count(self_: *const OakEngineProject) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -666,8 +668,7 @@ pub unsafe extern "C" fn oakengine_project_footage_is_online(
|
||||
if footage.is_null() {
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let filename =
|
||||
module_string(|buf, size| n::oaknode_footage_filename(footage, buf, size))?;
|
||||
let filename = module_string(|buf, size| n::oaknode_footage_filename(footage, buf, size))?;
|
||||
let path = std::path::Path::new(&filename);
|
||||
if path.exists() {
|
||||
return Ok(1);
|
||||
@@ -739,9 +740,7 @@ pub unsafe extern "C" fn oakengine_project_redo(self_: *mut OakEngineProject) ->
|
||||
|
||||
/// `oakengine_project_sequence_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_project_sequence_count(
|
||||
self_: *const OakEngineProject,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_project_sequence_count(self_: *const OakEngineProject) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -792,7 +791,8 @@ pub unsafe extern "C" fn oakengine_folder_create(
|
||||
} else {
|
||||
read_cstr(name)
|
||||
};
|
||||
let label_c = std::ffi::CString::new(label.as_str()).map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
let label_c = std::ffi::CString::new(label.as_str())
|
||||
.map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
// The module's folder_create already registers the node in the
|
||||
// project's graph, so only the FolderAddChild command is needed
|
||||
// (the C++ additionally pushes a NodeAddCommand; that surface does
|
||||
@@ -850,9 +850,7 @@ pub unsafe extern "C" fn oakengine_folder_index_of_child(
|
||||
|
||||
/// `oakengine_folder_item_child_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_folder_item_child_count(
|
||||
folder: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_folder_item_child_count(folder: *const OakEngineNode) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if folder.is_null() {
|
||||
return Ok(0);
|
||||
@@ -916,9 +914,8 @@ pub unsafe extern "C" fn oakengine_folder_add_child(
|
||||
// another folder is rejected with the module STATE error.
|
||||
let parent = n::oaknode_folder_parent_of(c);
|
||||
if !parent.ctx.is_null() {
|
||||
let already_here =
|
||||
n::oaknode_node_identity(parent) != 0
|
||||
&& n::oaknode_node_identity(parent) == n::oaknode_node_identity(f);
|
||||
let already_here = n::oaknode_node_identity(parent) != 0
|
||||
&& n::oaknode_node_identity(parent) == n::oaknode_node_identity(f);
|
||||
// The borrowed parent handle's shell is released here.
|
||||
if let Some(release) = parent.release {
|
||||
unsafe { release(parent.ctx) };
|
||||
@@ -964,7 +961,8 @@ pub unsafe extern "C" fn oakengine_folder_move_child(
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
let mut nodes = [node];
|
||||
let rc = oakengine_folder_move_children(nodes.as_mut_ptr(), 1, new_folder, std::ptr::null());
|
||||
let rc =
|
||||
oakengine_folder_move_children(nodes.as_mut_ptr(), 1, new_folder, std::ptr::null());
|
||||
Error::from_module(rc)
|
||||
})
|
||||
}
|
||||
@@ -1222,9 +1220,7 @@ pub extern "C" fn oakengine_node_last_error(buf: *mut c_char, buf_size: c_int) -
|
||||
|
||||
/// `oakengine_project_node_count` — number of nodes in the graph.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_project_node_count(
|
||||
self_: *const OakEngineProject,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_project_node_count(self_: *const OakEngineProject) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -1276,10 +1272,7 @@ pub unsafe extern "C" fn oakengine_node_factory_create_from_id(
|
||||
}
|
||||
let node = n::oaknode_factory_create_from_id(type_id);
|
||||
if node.ctx.is_null() {
|
||||
set_node_error(&format!(
|
||||
"unknown node type id \"{}\"",
|
||||
read_cstr(type_id)
|
||||
));
|
||||
set_node_error(&format!("unknown node type id \"{}\"", read_cstr(type_id)));
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
Ok(box_handle::<OakEngineNode>(node))
|
||||
@@ -1740,15 +1733,16 @@ pub unsafe extern "C" fn oakengine_node_set_color_label_command(
|
||||
|
||||
/// `oakengine_node_get_color_label`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_get_color_label(
|
||||
self_: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_node_get_color_label(self_: *const OakEngineNode) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(-1);
|
||||
}
|
||||
let mut value: c_int = -1;
|
||||
Error::from_module(n::oaknode_node_get_override_color(unbox(self_)?, &mut value))?;
|
||||
Error::from_module(n::oaknode_node_get_override_color(
|
||||
unbox(self_)?,
|
||||
&mut value,
|
||||
))?;
|
||||
Ok(value)
|
||||
})
|
||||
}
|
||||
@@ -1766,7 +1760,10 @@ pub unsafe extern "C" fn oakengine_node_get_effective_color_label(
|
||||
return Ok(-1);
|
||||
}
|
||||
let mut value: c_int = -1;
|
||||
Error::from_module(n::oaknode_node_get_override_color(unbox(self_)?, &mut value))?;
|
||||
Error::from_module(n::oaknode_node_get_override_color(
|
||||
unbox(self_)?,
|
||||
&mut value,
|
||||
))?;
|
||||
Ok(value)
|
||||
})
|
||||
}
|
||||
@@ -1838,7 +1835,11 @@ pub unsafe extern "C" fn oakengine_node_input_get_type(
|
||||
return Ok(0);
|
||||
}
|
||||
let mut ty: c_int = 0;
|
||||
Error::from_module(n::oaknode_node_input_get_type(unbox(self_)?, input_id, &mut ty))?;
|
||||
Error::from_module(n::oaknode_node_input_get_type(
|
||||
unbox(self_)?,
|
||||
input_id,
|
||||
&mut ty,
|
||||
))?;
|
||||
Ok(ty)
|
||||
})
|
||||
}
|
||||
@@ -2014,13 +2015,7 @@ pub unsafe extern "C" fn oakengine_node_set_value_at_time_command(
|
||||
let h = unbox(node.cast::<OakEngineNode>())?;
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_set_input_at_time_undoable(
|
||||
h,
|
||||
input,
|
||||
time_num,
|
||||
time_den,
|
||||
value,
|
||||
track,
|
||||
&mut cmd,
|
||||
h, input, time_num, time_den, value, track, &mut cmd,
|
||||
);
|
||||
if rc != 0 {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -2603,13 +2598,7 @@ pub unsafe extern "C" fn oakengine_node_keyframe_add(
|
||||
// keyframing enablement of the capi are not reachable).
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_set_input_at_time_undoable(
|
||||
h,
|
||||
input_id,
|
||||
t_num,
|
||||
t_den,
|
||||
value,
|
||||
0,
|
||||
&mut cmd,
|
||||
h, input_id, t_num, t_den, value, 0, &mut cmd,
|
||||
);
|
||||
if rc != 0 {
|
||||
return Err(Error::Module(rc));
|
||||
@@ -2661,13 +2650,7 @@ pub unsafe extern "C" fn oakengine_node_insert_keyframe_command(
|
||||
let (t_num, t_den) = ts_to_time(time_ts, tb);
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_set_input_at_time_undoable(
|
||||
h,
|
||||
input_id,
|
||||
t_num,
|
||||
t_den,
|
||||
value,
|
||||
track,
|
||||
&mut cmd,
|
||||
h, input_id, t_num, t_den, value, track, &mut cmd,
|
||||
);
|
||||
if rc != 0 {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -2994,7 +2977,11 @@ pub unsafe extern "C" fn oakengine_node_input_is_keyframable(
|
||||
return Ok(0);
|
||||
}
|
||||
let mut ty: c_int = 0;
|
||||
Error::from_module(n::oaknode_node_input_get_type(unbox(self_)?, input_id, &mut ty))?;
|
||||
Error::from_module(n::oaknode_node_input_get_type(
|
||||
unbox(self_)?,
|
||||
input_id,
|
||||
&mut ty,
|
||||
))?;
|
||||
let keyframable = matches!(
|
||||
ty,
|
||||
value_type::INT
|
||||
@@ -3054,10 +3041,8 @@ pub unsafe extern "C" fn oakengine_node_get_label_and_name(
|
||||
) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
let h = unbox(self_)?;
|
||||
let label =
|
||||
module_string(|b, s| n::oaknode_node_get_label(h, b, s))?;
|
||||
let name =
|
||||
module_string(|b, s| n::oaknode_node_get_name(h, b, s))?;
|
||||
let label = module_string(|b, s| n::oaknode_node_get_label(h, b, s))?;
|
||||
let name = module_string(|b, s| n::oaknode_node_get_name(h, b, s))?;
|
||||
// The engine's default `get_label_and_name()`: label when set,
|
||||
// otherwise the name.
|
||||
Ok(write_string(
|
||||
@@ -3155,23 +3140,23 @@ pub unsafe extern "C" fn oakengine_node_is_item(self_: *const OakEngineNode) ->
|
||||
return Ok(0);
|
||||
}
|
||||
let h = unbox(self_)?;
|
||||
Ok(if is_node_type(h, TYPE_ID_FOLDER)
|
||||
|| is_node_type(h, TYPE_ID_FOOTAGE)
|
||||
|| is_node_type(h, TYPE_ID_SEQUENCE)
|
||||
|| is_node_type(h, TYPE_ID_GROUP)
|
||||
{
|
||||
1
|
||||
} else {
|
||||
0
|
||||
})
|
||||
Ok(
|
||||
if is_node_type(h, TYPE_ID_FOLDER)
|
||||
|| is_node_type(h, TYPE_ID_FOOTAGE)
|
||||
|| is_node_type(h, TYPE_ID_SEQUENCE)
|
||||
|| is_node_type(h, TYPE_ID_GROUP)
|
||||
{
|
||||
1
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// `oakengine_node_folder` — the folder owning this item node.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_folder(
|
||||
self_: *const OakEngineNode,
|
||||
) -> *mut OakEngineNode {
|
||||
pub unsafe extern "C" fn oakengine_node_folder(self_: *const OakEngineNode) -> *mut OakEngineNode {
|
||||
guard_ptr(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -3574,9 +3559,7 @@ pub unsafe extern "C" fn oakengine_node_is_multicam(self_: *const OakEngineNode)
|
||||
|
||||
/// `oakengine_node_context_node_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_context_node_count(
|
||||
context: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_node_context_node_count(context: *const OakEngineNode) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if context.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -3688,13 +3671,8 @@ pub unsafe extern "C" fn oakengine_node_get_context_position(
|
||||
set_node_error("invalid arguments");
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let rc = n::oaknode_node_get_context_position(
|
||||
unbox(node)?,
|
||||
unbox(context)?,
|
||||
x,
|
||||
y,
|
||||
expanded,
|
||||
);
|
||||
let rc =
|
||||
n::oaknode_node_get_context_position(unbox(node)?, unbox(context)?, x, y, expanded);
|
||||
Error::from_module(rc)
|
||||
})
|
||||
}
|
||||
@@ -3984,7 +3962,11 @@ pub unsafe extern "C" fn oakengine_node_effect_insert(
|
||||
/// # Safety
|
||||
/// `host` must be a live module node handle; `type_id` a NUL-terminated
|
||||
/// C string.
|
||||
unsafe fn node_effect_insert_impl(host: CHandle, index: c_int, type_id: *const c_char) -> Result<()> {
|
||||
unsafe fn node_effect_insert_impl(
|
||||
host: CHandle,
|
||||
index: c_int,
|
||||
type_id: *const c_char,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
// The host must be able to host effects.
|
||||
let host_input = effect_input_of(host)?;
|
||||
@@ -4170,7 +4152,11 @@ pub unsafe extern "C" fn oakengine_node_effect_remove(
|
||||
} else {
|
||||
Some(chain.get(pos - 1))
|
||||
};
|
||||
let downstream = if pos + 1 == len { host } else { chain.get(pos + 1) };
|
||||
let downstream = if pos + 1 == len {
|
||||
host
|
||||
} else {
|
||||
chain.get(pos + 1)
|
||||
};
|
||||
let downstream_input = effect_input_of(downstream)?;
|
||||
|
||||
// All nodes are already in the project: a plain multi command.
|
||||
@@ -4214,7 +4200,11 @@ pub unsafe extern "C" fn oakengine_node_effect_remove(
|
||||
// The guard releases every command handle on error paths; on success
|
||||
// `push_multi_commands` consumes them all.
|
||||
let children = HandleGuard::new(children);
|
||||
push_multi_commands(&children.into_inner(), std::ptr::null_mut(), "Remove Effect")
|
||||
push_multi_commands(
|
||||
&children.into_inner(),
|
||||
std::ptr::null_mut(),
|
||||
"Remove Effect",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4262,7 +4252,11 @@ pub unsafe extern "C" fn oakengine_node_effect_move(
|
||||
} else {
|
||||
Some(chain.get(from - 1))
|
||||
};
|
||||
let downstream = if from + 1 == len { host } else { chain.get(from + 1) };
|
||||
let downstream = if from + 1 == len {
|
||||
host
|
||||
} else {
|
||||
chain.get(from + 1)
|
||||
};
|
||||
let downstream_input = effect_input_of(downstream)?;
|
||||
let eff_input = effect_input_of(eff)?;
|
||||
if upstream.is_some() {
|
||||
@@ -4360,7 +4354,11 @@ pub unsafe extern "C" fn oakengine_node_effect_move(
|
||||
children.0.push(cmd);
|
||||
}
|
||||
|
||||
push_multi_commands(&children.into_inner(), std::ptr::null_mut(), "Reorder Effect")
|
||||
push_multi_commands(
|
||||
&children.into_inner(),
|
||||
std::ptr::null_mut(),
|
||||
"Reorder Effect",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4389,8 +4387,11 @@ pub unsafe extern "C" fn oakengine_node_group_get_inner(
|
||||
inout_element: *mut c_int,
|
||||
) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if inout_node.is_null() || (*inout_node).is_null() || inout_input.is_null()
|
||||
|| inout_input_size <= 0 || inout_element.is_null()
|
||||
if inout_node.is_null()
|
||||
|| (*inout_node).is_null()
|
||||
|| inout_input.is_null()
|
||||
|| inout_input_size <= 0
|
||||
|| inout_element.is_null()
|
||||
{
|
||||
return Ok(0);
|
||||
}
|
||||
@@ -4417,8 +4418,7 @@ pub unsafe extern "C" fn oakengine_node_group_get_inner(
|
||||
return Ok(0);
|
||||
}
|
||||
// One level only: if the resolved node is the same, nothing moved.
|
||||
if n::oaknode_node_identity(out_node) == n::oaknode_node_identity(node)
|
||||
{
|
||||
if n::oaknode_node_identity(out_node) == n::oaknode_node_identity(node) {
|
||||
return Ok(0);
|
||||
}
|
||||
*inout_node = box_handle::<OakEngineNode>(out_node);
|
||||
@@ -4882,9 +4882,7 @@ pub extern "C" fn oakengine_multicam_input_sequence_type() -> *const c_char {
|
||||
|
||||
/// `oakengine_multicam_get_source_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_multicam_get_source_count(
|
||||
self_: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_multicam_get_source_count(self_: *const OakEngineNode) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -4910,7 +4908,11 @@ pub unsafe extern "C" fn oakengine_multicam_get_rows_and_columns(
|
||||
if source_count < 0 || rows.is_null() || cols.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
Error::from_module(n::oaknode_multicam_get_rows_and_columns(source_count, rows, cols))
|
||||
Error::from_module(n::oaknode_multicam_get_rows_and_columns(
|
||||
source_count,
|
||||
rows,
|
||||
cols,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4928,11 +4930,7 @@ pub unsafe extern "C" fn oakengine_multicam_index_to_row_cols(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
Error::from_module(n::oaknode_multicam_index_to_row_cols(
|
||||
index,
|
||||
rows,
|
||||
cols,
|
||||
out_row,
|
||||
out_col,
|
||||
index, rows, cols, out_row, out_col,
|
||||
))
|
||||
})
|
||||
}
|
||||
@@ -5143,7 +5141,11 @@ pub unsafe extern "C" fn oakengine_nodes_delete_many_ex(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let _ = *edge_outputs.add(i);
|
||||
let _ = if edge_input_elements.is_null() { -1 } else { *edge_input_elements.add(i) };
|
||||
let _ = if edge_input_elements.is_null() {
|
||||
-1
|
||||
} else {
|
||||
*edge_input_elements.add(i)
|
||||
};
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_disconnect_undoable(unbox(input)?, input_id, &mut cmd);
|
||||
if rc != 0 {
|
||||
@@ -5153,7 +5155,8 @@ pub unsafe extern "C" fn oakengine_nodes_delete_many_ex(
|
||||
}
|
||||
// Reconnect edges run AFTER the deletion inside the same command.
|
||||
for i in 0..reconnect_count as usize {
|
||||
if reconnect_outputs.is_null() || reconnect_input_nodes.is_null()
|
||||
if reconnect_outputs.is_null()
|
||||
|| reconnect_input_nodes.is_null()
|
||||
|| reconnect_input_ids.is_null()
|
||||
{
|
||||
set_node_error(&format!("invalid reconnect edge at index {}", i));
|
||||
@@ -5172,7 +5175,8 @@ pub unsafe extern "C" fn oakengine_nodes_delete_many_ex(
|
||||
*reconnect_input_elements.add(i)
|
||||
};
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_connect_undoable(unbox(out)?, unbox(input)?, input_id, &mut cmd);
|
||||
let rc =
|
||||
n::oaknode_node_connect_undoable(unbox(out)?, unbox(input)?, input_id, &mut cmd);
|
||||
if rc != 0 {
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
@@ -5459,7 +5463,15 @@ pub unsafe extern "C" fn oakengine_node_keyframes_at_time(
|
||||
) -> c_int {
|
||||
// Stub: see `oakengine_node_keyframe_count`.
|
||||
guard_int(|| {
|
||||
let _ = (self_, input_id, element, time_num, time_den, out_handles, max_handles);
|
||||
let _ = (
|
||||
self_,
|
||||
input_id,
|
||||
element,
|
||||
time_num,
|
||||
time_den,
|
||||
out_handles,
|
||||
max_handles,
|
||||
);
|
||||
Ok(0)
|
||||
})
|
||||
}
|
||||
@@ -5558,9 +5570,7 @@ pub unsafe extern "C" fn oakengine_keyframe_get_input_id(
|
||||
|
||||
/// `oakengine_keyframe_get_track`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_track(
|
||||
self_: *const OakEngineKeyframe,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_track(self_: *const OakEngineKeyframe) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(-1);
|
||||
@@ -5573,9 +5583,7 @@ pub unsafe extern "C" fn oakengine_keyframe_get_track(
|
||||
|
||||
/// `oakengine_keyframe_get_element`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_element(
|
||||
self_: *const OakEngineKeyframe,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_element(self_: *const OakEngineKeyframe) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(-1);
|
||||
@@ -5606,9 +5614,7 @@ pub unsafe extern "C" fn oakengine_keyframe_get_node(
|
||||
|
||||
/// `oakengine_keyframe_get_type` — facade easing type.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_type(
|
||||
self_: *const OakEngineKeyframe,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_keyframe_get_type(self_: *const OakEngineKeyframe) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(-1);
|
||||
@@ -5680,12 +5686,7 @@ pub unsafe extern "C" fn oakengine_keyframe_has_sibling_at_time(
|
||||
}
|
||||
let mut value: c_int = 0;
|
||||
// The capi passes the timestamp as seconds with denominator 1.
|
||||
let rc = n::oaknode_keyframe_has_sibling_at_time(
|
||||
unbox(self_)?,
|
||||
time_ts,
|
||||
1,
|
||||
&mut value,
|
||||
);
|
||||
let rc = n::oaknode_keyframe_has_sibling_at_time(unbox(self_)?, time_ts, 1, &mut value);
|
||||
if rc != 0 {
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
@@ -5826,16 +5827,8 @@ pub unsafe extern "C" fn oakengine_keyframe_create(
|
||||
let h = unbox(node)?;
|
||||
let tb = time_base_for(h);
|
||||
let (t_num, t_den) = ts_to_time(time_ts, tb);
|
||||
let kf = n::oaknode_keyframe_create(
|
||||
t_num,
|
||||
t_den,
|
||||
value,
|
||||
type_,
|
||||
track,
|
||||
element,
|
||||
input_id,
|
||||
h,
|
||||
);
|
||||
let kf =
|
||||
n::oaknode_keyframe_create(t_num, t_den, value, type_, track, element, input_id, h);
|
||||
if kf.ctx.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
@@ -5944,7 +5937,11 @@ pub unsafe extern "C" fn oakengine_dragger_end(
|
||||
"Drag Input".to_string()
|
||||
} else {
|
||||
let s = read_cstr(undo_name);
|
||||
if s.is_empty() { "Drag Input".to_string() } else { s }
|
||||
if s.is_empty() {
|
||||
"Drag Input".to_string()
|
||||
} else {
|
||||
s
|
||||
}
|
||||
};
|
||||
let name_c = std::ffi::CString::new(name.as_str())
|
||||
.map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
@@ -5954,9 +5951,7 @@ pub unsafe extern "C" fn oakengine_dragger_end(
|
||||
|
||||
/// `oakengine_dragger_is_started`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_dragger_is_started(
|
||||
self_: *const OakEngineNodeDragger,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_dragger_is_started(self_: *const OakEngineNodeDragger) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -6075,7 +6070,12 @@ pub unsafe extern "C" fn oakengine_node_link_command(
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
let mut cmd: CHandle = CHandle::null();
|
||||
let rc = n::oaknode_node_link_undoable(unbox(a)?, unbox(b)?, if link != 0 { 1 } else { 0 }, &mut cmd);
|
||||
let rc = n::oaknode_node_link_undoable(
|
||||
unbox(a)?,
|
||||
unbox(b)?,
|
||||
if link != 0 { 1 } else { 0 },
|
||||
&mut cmd,
|
||||
);
|
||||
if rc != 0 {
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
@@ -6379,19 +6379,19 @@ pub unsafe extern "C" fn oakengine_node_is_track(self_: *const OakEngineNode) ->
|
||||
|
||||
/// `oakengine_node_is_viewer_output` — Sequence or Footage.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_is_viewer_output(
|
||||
self_: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_node_is_viewer_output(self_: *const OakEngineNode) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
}
|
||||
let h = unbox(self_)?;
|
||||
Ok(if is_node_type(h, TYPE_ID_SEQUENCE) || is_node_type(h, TYPE_ID_FOOTAGE) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
})
|
||||
Ok(
|
||||
if is_node_type(h, TYPE_ID_SEQUENCE) || is_node_type(h, TYPE_ID_FOOTAGE) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6533,9 +6533,7 @@ pub unsafe extern "C" fn oakengine_block_get_length_rational(
|
||||
num: *mut c_int,
|
||||
den: *mut c_int,
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
block_rational(block, "length", num, den)
|
||||
})
|
||||
guard(|| unsafe { block_rational(block, "length", num, den) })
|
||||
}
|
||||
|
||||
/// `oakengine_block_get_in_rational`.
|
||||
@@ -6545,9 +6543,7 @@ pub unsafe extern "C" fn oakengine_block_get_in_rational(
|
||||
num: *mut c_int,
|
||||
den: *mut c_int,
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
block_rational(block, "in", num, den)
|
||||
})
|
||||
guard(|| unsafe { block_rational(block, "in", num, den) })
|
||||
}
|
||||
|
||||
/// `oakengine_block_get_out_rational`.
|
||||
@@ -6557,13 +6553,16 @@ pub unsafe extern "C" fn oakengine_block_get_out_rational(
|
||||
num: *mut c_int,
|
||||
den: *mut c_int,
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
block_rational(block, "out", num, den)
|
||||
})
|
||||
guard(|| unsafe { block_rational(block, "out", num, den) })
|
||||
}
|
||||
|
||||
/// Shared body of the block rational getters.
|
||||
unsafe fn block_rational(block: *const OakEngineNode, which: &str, num: *mut c_int, den: *mut c_int) -> Result<()> {
|
||||
unsafe fn block_rational(
|
||||
block: *const OakEngineNode,
|
||||
which: &str,
|
||||
num: *mut c_int,
|
||||
den: *mut c_int,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
if block.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -6762,7 +6761,10 @@ pub unsafe extern "C" fn oakengine_node_output_connection_count(
|
||||
return Ok(0);
|
||||
}
|
||||
let mut count: c_int = 0;
|
||||
Error::from_module(n::oaknode_node_output_connection_count(unbox(self_)?, &mut count))?;
|
||||
Error::from_module(n::oaknode_node_output_connection_count(
|
||||
unbox(self_)?,
|
||||
&mut count,
|
||||
))?;
|
||||
Ok(count)
|
||||
})
|
||||
}
|
||||
@@ -6797,12 +6799,8 @@ pub unsafe extern "C" fn oakengine_node_output_connection_at(
|
||||
*input_node = box_handle::<OakEngineNode>(out);
|
||||
}
|
||||
}
|
||||
let rc = n::oaknode_node_output_connection_input_id_at(
|
||||
h,
|
||||
index,
|
||||
input_id_buf,
|
||||
input_id_size,
|
||||
);
|
||||
let rc =
|
||||
n::oaknode_node_output_connection_input_id_at(h, index, input_id_buf, input_id_size);
|
||||
if rc < 0 {
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
@@ -6880,7 +6878,15 @@ pub unsafe extern "C" fn oakengine_node_input_connection_at_all(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let _ = unbox(self_)?;
|
||||
let _ = (index, input_node, input_id_buf, input_id_size, element, source_node, hidden);
|
||||
let _ = (
|
||||
index,
|
||||
input_node,
|
||||
input_id_buf,
|
||||
input_id_size,
|
||||
element,
|
||||
source_node,
|
||||
hidden,
|
||||
);
|
||||
Err(Error::NotFound)
|
||||
})
|
||||
}
|
||||
@@ -7002,9 +7008,7 @@ pub unsafe extern "C" fn oakengine_node_has_plugin(self_: *const OakEngineNode)
|
||||
|
||||
/// `oakengine_node_plugin_message_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_plugin_message_count(
|
||||
self_: *const OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_node_plugin_message_count(self_: *const OakEngineNode) -> c_int {
|
||||
// Stub: see `oakengine_node_has_plugin`.
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
@@ -7037,9 +7041,7 @@ pub unsafe extern "C" fn oakengine_node_plugin_message_at(
|
||||
|
||||
/// `oakengine_node_plugin_clear_messages`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_node_plugin_clear_messages(
|
||||
self_: *mut OakEngineNode,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_node_plugin_clear_messages(self_: *mut OakEngineNode) -> c_int {
|
||||
// Stub: see `oakengine_node_has_plugin`.
|
||||
guard(|| unsafe {
|
||||
if self_.is_null() {
|
||||
@@ -7124,9 +7126,7 @@ fn probe_project() -> CHandle {
|
||||
|
||||
/// `oakengine_footage_probe` — probe a media file without a project.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_probe(
|
||||
path: *const c_char,
|
||||
) -> *mut OakEngineFootage {
|
||||
pub unsafe extern "C" fn oakengine_footage_probe(path: *const c_char) -> *mut OakEngineFootage {
|
||||
guard_ptr(|| unsafe {
|
||||
set_footage_error("");
|
||||
if path.is_null() {
|
||||
@@ -7139,7 +7139,10 @@ pub unsafe extern "C" fn oakengine_footage_probe(
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
let filename = path_str;
|
||||
let footage = n::oaknode_footage_create(probe_project(), std::ffi::CString::new(filename.as_str()).unwrap().as_ptr());
|
||||
let footage = n::oaknode_footage_create(
|
||||
probe_project(),
|
||||
std::ffi::CString::new(filename.as_str()).unwrap().as_ptr(),
|
||||
);
|
||||
if footage.ctx.is_null() {
|
||||
set_footage_error(&format!("failed to probe \"{}\"", filename));
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -7323,23 +7326,24 @@ pub unsafe extern "C" fn oakengine_footage_get_duration(
|
||||
if rc != 0 {
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
*seconds = if den != 0 { num as f64 / den as f64 } else { 0.0 };
|
||||
*seconds = if den != 0 {
|
||||
num as f64 / den as f64
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// `oakengine_footage_is_online` — 1 when the media file exists.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_is_online(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_is_online(self_: *mut OakEngineFootage) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let h = unbox(self_)?;
|
||||
let filename =
|
||||
module_string(|buf, size| n::oaknode_footage_filename(h, buf, size))?;
|
||||
let filename = module_string(|buf, size| n::oaknode_footage_filename(h, buf, size))?;
|
||||
Ok(if std::path::Path::new(&filename).exists() {
|
||||
1
|
||||
} else {
|
||||
@@ -7515,8 +7519,7 @@ pub unsafe extern "C" fn oakengine_project_find_offline_footage(
|
||||
if node.is_null() || !is_node_type(node, TYPE_ID_FOOTAGE) {
|
||||
continue;
|
||||
}
|
||||
let filename =
|
||||
module_string(|buf, size| n::oaknode_footage_filename(node, buf, size))?;
|
||||
let filename = module_string(|buf, size| n::oaknode_footage_filename(node, buf, size))?;
|
||||
if filename.is_empty() || std::path::Path::new(&filename).exists() {
|
||||
continue;
|
||||
}
|
||||
@@ -7540,9 +7543,7 @@ pub unsafe extern "C" fn oakengine_project_find_offline_footage(
|
||||
|
||||
/// `oakengine_footage_proxy_get_state`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_get_state(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_get_state(self_: *mut OakEngineFootage) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -7553,9 +7554,7 @@ pub unsafe extern "C" fn oakengine_footage_proxy_get_state(
|
||||
|
||||
/// `oakengine_footage_proxy_generate`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_generate(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_generate(self_: *mut OakEngineFootage) -> c_int {
|
||||
// Stub: the oaknode module has no ProxyManager / proxy task surface.
|
||||
guard(|| unsafe {
|
||||
set_footage_error("");
|
||||
@@ -7570,9 +7569,7 @@ pub unsafe extern "C" fn oakengine_footage_proxy_generate(
|
||||
|
||||
/// `oakengine_footage_proxy_delete`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_delete(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_delete(self_: *mut OakEngineFootage) -> c_int {
|
||||
guard(|| unsafe {
|
||||
set_footage_error("");
|
||||
let h = unbox(self_)?;
|
||||
@@ -7584,9 +7581,7 @@ pub unsafe extern "C" fn oakengine_footage_proxy_delete(
|
||||
|
||||
/// `oakengine_footage_proxy_is_enabled`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_is_enabled(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_proxy_is_enabled(self_: *mut OakEngineFootage) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -7604,7 +7599,10 @@ pub unsafe extern "C" fn oakengine_footage_proxy_set_enabled(
|
||||
guard(|| unsafe {
|
||||
set_footage_error("");
|
||||
let h = unbox(self_)?;
|
||||
Error::from_module(n::oaknode_footage_set_proxy_enabled(h, if enabled != 0 { 1 } else { 0 }))
|
||||
Error::from_module(n::oaknode_footage_set_proxy_enabled(
|
||||
h,
|
||||
if enabled != 0 { 1 } else { 0 },
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7697,7 +7695,10 @@ pub unsafe extern "C" fn oakengine_footage_set_video_stream_overrides(
|
||||
c::oakcommon_videoparams_set_interlacing(params, interlacing);
|
||||
}
|
||||
if premultiplied >= 0 {
|
||||
c::oakcommon_videoparams_set_premultiplied_alpha(params, if premultiplied != 0 { 1 } else { 0 });
|
||||
c::oakcommon_videoparams_set_premultiplied_alpha(
|
||||
params,
|
||||
if premultiplied != 0 { 1 } else { 0 },
|
||||
);
|
||||
}
|
||||
let rc = n::oaknode_footage_set_video_params(h, stream_index, ¶ms);
|
||||
let mut h2 = params;
|
||||
@@ -7930,9 +7931,7 @@ pub unsafe extern "C" fn oakengine_footage_get_source_start_time_source(
|
||||
|
||||
/// `oakengine_footage_colorspace_count`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_colorspace_count(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_colorspace_count(self_: *mut OakEngineFootage) -> c_int {
|
||||
// Stub: the module has no color-config surface.
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
@@ -8058,7 +8057,12 @@ pub unsafe extern "C" fn oakengine_footage_describe_video_stream(
|
||||
c::oakcommon_videoparams_get_height(params, &mut height);
|
||||
c::oakcommon_videoparams_get_frame_rate(params, &mut fr_num, &mut fr_den);
|
||||
let desc = if fr_den != 0 {
|
||||
format!("{}x{}, {:.3} fps", width, height, fr_num as f64 / fr_den as f64)
|
||||
format!(
|
||||
"{}x{}, {:.3} fps",
|
||||
width,
|
||||
height,
|
||||
fr_num as f64 / fr_den as f64
|
||||
)
|
||||
} else {
|
||||
format!("{}x{}", width, height)
|
||||
};
|
||||
@@ -8215,9 +8219,7 @@ pub unsafe extern "C" fn oakengine_footage_set_proxy(
|
||||
|
||||
/// `oakengine_footage_clear_proxy`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_clear_proxy(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_clear_proxy(self_: *mut OakEngineFootage) -> c_int {
|
||||
guard(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Err(Error::Invalid);
|
||||
@@ -8228,9 +8230,7 @@ pub unsafe extern "C" fn oakengine_footage_clear_proxy(
|
||||
|
||||
/// `oakengine_footage_invalidate` — force a re-probe on next use.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_footage_invalidate(
|
||||
self_: *mut OakEngineFootage,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_footage_invalidate(self_: *mut OakEngineFootage) -> c_int {
|
||||
// Stub: the module's footage has no clear/reprobe cascade; accepted
|
||||
// as a no-op.
|
||||
guard(|| unsafe {
|
||||
|
||||
@@ -35,12 +35,16 @@ pub type ActiveViewerFn =
|
||||
unsafe extern "C" fn(userdata: *mut c_void) -> *mut crate::handle::OakEngineNode;
|
||||
|
||||
/// `oakengine_plugin_reporter_create_fn` — creates a UI progress reporter.
|
||||
pub type ReporterCreateFn =
|
||||
unsafe extern "C" fn(message: *const c_char, title: *const c_char, userdata: *mut c_void) -> *mut c_void;
|
||||
pub type ReporterCreateFn = unsafe extern "C" fn(
|
||||
message: *const c_char,
|
||||
title: *const c_char,
|
||||
userdata: *mut c_void,
|
||||
) -> *mut c_void;
|
||||
/// `oakengine_plugin_reporter_destroy_fn` — destroys a reporter.
|
||||
pub type ReporterDestroyFn = unsafe extern "C" fn(reporter: *mut c_void, userdata: *mut c_void);
|
||||
/// `oakengine_plugin_reporter_is_cancelled_fn` — 1 when cancelled.
|
||||
pub type ReporterIsCancelledFn = unsafe extern "C" fn(reporter: *mut c_void, userdata: *mut c_void) -> c_int;
|
||||
pub type ReporterIsCancelledFn =
|
||||
unsafe extern "C" fn(reporter: *mut c_void, userdata: *mut c_void) -> c_int;
|
||||
/// `oakengine_plugin_reporter_set_progress_fn` — progress update.
|
||||
pub type ReporterSetProgressFn =
|
||||
unsafe extern "C" fn(reporter: *mut c_void, progress: f64, userdata: *mut c_void);
|
||||
@@ -92,7 +96,13 @@ pub extern "C" fn oakengine_plugin_set_progress_reporter_factory(
|
||||
) -> c_int {
|
||||
guard(|| {
|
||||
let mut s = state().lock().unwrap_or_else(|e| e.into_inner());
|
||||
s.reporter = Some((create, destroy, is_cancelled, set_progress, userdata as usize));
|
||||
s.reporter = Some((
|
||||
create,
|
||||
destroy,
|
||||
is_cancelled,
|
||||
set_progress,
|
||||
userdata as usize,
|
||||
));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,7 +93,9 @@ pub unsafe extern "C" fn oakengine_render_cache_set_display_color_processor(
|
||||
|
||||
/// `oakengine_render_cache_set_multicam_node` — NULL clears.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_render_cache_set_multicam_node(node: *mut OakEngineNode) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_render_cache_set_multicam_node(
|
||||
node: *mut OakEngineNode,
|
||||
) -> c_int {
|
||||
guard(|| unsafe {
|
||||
let n = if node.is_null() {
|
||||
CHandle::null()
|
||||
@@ -190,7 +192,8 @@ pub unsafe extern "C" fn oakengine_renderer_create(
|
||||
output_colorspace: *const c_char,
|
||||
) -> *mut OakEngineRenderer {
|
||||
guard_ptr(|| unsafe {
|
||||
if seq.is_null() || width <= 0 || height <= 0 || frame_rate_num <= 0 || frame_rate_den <= 0 {
|
||||
if seq.is_null() || width <= 0 || height <= 0 || frame_rate_num <= 0 || frame_rate_den <= 0
|
||||
{
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
// Validate the pixel format against the oakcore enum. The
|
||||
@@ -482,7 +485,9 @@ pub unsafe extern "C" fn oakengine_audio_sample_rate(_self_: *const OakEngineAud
|
||||
|
||||
/// `oakengine_audio_channel_count` — 0.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_audio_channel_count(_self_: *const OakEngineAudioBuffer) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_audio_channel_count(
|
||||
_self_: *const OakEngineAudioBuffer,
|
||||
) -> c_int {
|
||||
0
|
||||
}
|
||||
|
||||
@@ -729,7 +734,8 @@ pub unsafe extern "C" fn oakengine_color_manager_compliant_transform(
|
||||
|
||||
/// `oakengine_color_config_load_default` — **not backed**. NULL.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn oakengine_color_config_load_default() -> *mut crate::handle::OakEngineColorConfig {
|
||||
pub extern "C" fn oakengine_color_config_load_default() -> *mut crate::handle::OakEngineColorConfig
|
||||
{
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
|
||||
@@ -802,13 +808,29 @@ pub unsafe extern "C" fn oakengine_color_processor_create(
|
||||
let empty = crate::common::empty_cstr();
|
||||
let ct = if (*dest).is_display != 0 {
|
||||
crate::bridge::common::oakcommon_colortransform_init_display(
|
||||
if (*dest).output.is_null() { empty } else { (*dest).output },
|
||||
if (*dest).view.is_null() { empty } else { (*dest).view },
|
||||
if (*dest).look.is_null() { empty } else { (*dest).look },
|
||||
if (*dest).output.is_null() {
|
||||
empty
|
||||
} else {
|
||||
(*dest).output
|
||||
},
|
||||
if (*dest).view.is_null() {
|
||||
empty
|
||||
} else {
|
||||
(*dest).view
|
||||
},
|
||||
if (*dest).look.is_null() {
|
||||
empty
|
||||
} else {
|
||||
(*dest).look
|
||||
},
|
||||
)
|
||||
} else {
|
||||
crate::bridge::common::oakcommon_colortransform_init_output(
|
||||
if (*dest).output.is_null() { empty } else { (*dest).output },
|
||||
if (*dest).output.is_null() {
|
||||
empty
|
||||
} else {
|
||||
(*dest).output
|
||||
},
|
||||
)
|
||||
};
|
||||
if ct.is_null() {
|
||||
@@ -820,12 +842,7 @@ pub unsafe extern "C" fn oakengine_color_processor_create(
|
||||
} else {
|
||||
unbox(mgr.cast::<crate::handle::OakEngineColorManager>())?
|
||||
};
|
||||
let proc = r::oakrender_color_processor_create_transform(
|
||||
mgr_handle,
|
||||
input,
|
||||
ct,
|
||||
direction,
|
||||
);
|
||||
let proc = r::oakrender_color_processor_create_transform(mgr_handle, input, ct, direction);
|
||||
let mut ct_handle = ct;
|
||||
crate::bridge::common::oakcommon_colortransform_free(&mut ct_handle);
|
||||
if proc.is_null() {
|
||||
|
||||
@@ -43,7 +43,7 @@ use std::ffi::{c_char, c_int, c_void};
|
||||
use std::sync::{Mutex, OnceLock};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::bridge::codec::{EncodingParamsPOD, zeroed_encoding_params};
|
||||
use crate::bridge::codec::{zeroed_encoding_params, EncodingParamsPOD};
|
||||
use crate::bridge::node as n;
|
||||
use crate::bridge::task as t;
|
||||
use crate::codec::OakEngineEncodingParams;
|
||||
@@ -353,11 +353,16 @@ pub unsafe extern "C" fn oakengine_task_start_time(task: *mut OakEngineTask) ->
|
||||
pub unsafe extern "C" fn oakengine_task_is_cancelled(task: *mut OakEngineTask) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
let h = unbox(task)?;
|
||||
Ok(if meta_get(h.ctx as usize).map(|m| m.cancelled).unwrap_or(false) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
})
|
||||
Ok(
|
||||
if meta_get(h.ctx as usize)
|
||||
.map(|m| m.cancelled)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
1
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -509,9 +514,12 @@ pub unsafe extern "C" fn oakengine_task_create_project_save_otio(
|
||||
if filename.is_empty() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
let c_filename =
|
||||
std::ffi::CString::new(filename).map_err(|_| Error::Failed("invalid filename".into()))?;
|
||||
Ok(box_task(t::oaktask_create_project_save_otio(ph, c_filename.as_ptr())))
|
||||
let c_filename = std::ffi::CString::new(filename)
|
||||
.map_err(|_| Error::Failed("invalid filename".into()))?;
|
||||
Ok(box_task(t::oaktask_create_project_save_otio(
|
||||
ph,
|
||||
c_filename.as_ptr(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -655,22 +663,27 @@ fn export_params_pod(params: *const OakEngineEncodingParams) -> Result<EncodingP
|
||||
// filename (two-stage; writes NUL-terminated into `buf`)
|
||||
let mut buf = [0 as c_char; 1024];
|
||||
let rc = unsafe {
|
||||
crate::codec::oakengine_encoding_params_filename(params, buf.as_mut_ptr(), buf.len() as c_int)
|
||||
crate::codec::oakengine_encoding_params_filename(
|
||||
params,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len() as c_int,
|
||||
)
|
||||
};
|
||||
if rc < 0 {
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let len = buf.iter().position(|&c| c == 0).unwrap_or(buf.len());
|
||||
unsafe { std::ptr::copy_nonoverlapping(buf.as_ptr() as *const u8, pod.filename.as_mut_ptr(), len) };
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(buf.as_ptr() as *const u8, pod.filename.as_mut_ptr(), len)
|
||||
};
|
||||
|
||||
pod.format = unsafe { crate::codec::oakengine_encoding_params_format(params) };
|
||||
pod.video_enabled = unsafe { crate::codec::oakengine_encoding_params_video_enabled(params) };
|
||||
pod.video_codec = unsafe { crate::codec::oakengine_encoding_params_video_codec(params) };
|
||||
pod.audio_enabled = unsafe { crate::codec::oakengine_encoding_params_audio_enabled(params) };
|
||||
pod.audio_codec = unsafe { crate::codec::oakengine_encoding_params_audio_codec(params) };
|
||||
pod.subtitles_enabled = unsafe {
|
||||
crate::codec::oakengine_encoding_params_subtitles_enabled(params)
|
||||
};
|
||||
pod.subtitles_enabled =
|
||||
unsafe { crate::codec::oakengine_encoding_params_subtitles_enabled(params) };
|
||||
unsafe {
|
||||
crate::codec::oakengine_encoding_params_get_export_length(
|
||||
params,
|
||||
@@ -741,7 +754,9 @@ pub unsafe extern "C" fn oakengine_task_import_file_count(task: *mut OakEngineTa
|
||||
/// run, after a cancelled run, or on a second call). Ownership detaches
|
||||
/// from the task; push it with `oakengine_undo_push` or free it.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_task_import_get_command(task: *mut OakEngineTask) -> *mut c_void {
|
||||
pub unsafe extern "C" fn oakengine_task_import_get_command(
|
||||
task: *mut OakEngineTask,
|
||||
) -> *mut c_void {
|
||||
guard_ptr(|| unsafe {
|
||||
let h = unbox(task)?;
|
||||
let cmd = t::oaktask_import_take_command(h);
|
||||
@@ -839,7 +854,9 @@ pub unsafe extern "C" fn oakengine_task_import_invalid_file_at(
|
||||
/// Each call returns a fresh borrowed handle the caller releases with
|
||||
/// `oakengine_project_free`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_task_save_get_project(task: *mut OakEngineTask) -> *mut OakEngineProject {
|
||||
pub unsafe extern "C" fn oakengine_task_save_get_project(
|
||||
task: *mut OakEngineTask,
|
||||
) -> *mut OakEngineProject {
|
||||
guard_ptr(|| unsafe {
|
||||
let h = unbox(task)?;
|
||||
match meta_get(h.ctx as usize).and_then(|m| m.save_project) {
|
||||
|
||||
+298
-183
@@ -30,15 +30,15 @@ use std::ffi::{c_char, c_int, c_void};
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::bridge::undo::OakUndoCommandVtable;
|
||||
use crate::bridge::{audio as a, common as c, node as n, timeline as tl, undo as u};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::handle::{
|
||||
box_handle, free_box, guard, guard_int, guard_ptr, guard_void, read_cstr, string_result,
|
||||
unbox, write_string, CHandle, OakEngineBlock, OakEngineClip, OakEngineClipboard,
|
||||
OakEngineFootage, OakEngineMarker, OakEngineMarkerList, OakEngineNode, OakEngineProject,
|
||||
OakEngineSequence, OakEngineTrack, OakEngineTrackList, OakEngineWorkarea,
|
||||
box_handle, free_box, guard, guard_int, guard_ptr, guard_void, read_cstr, string_result, unbox,
|
||||
write_string, CHandle, OakEngineBlock, OakEngineClip, OakEngineClipboard, OakEngineFootage,
|
||||
OakEngineMarker, OakEngineMarkerList, OakEngineNode, OakEngineProject, OakEngineSequence,
|
||||
OakEngineTrack, OakEngineTrackList, OakEngineWorkarea,
|
||||
};
|
||||
use crate::bridge::undo::OakUndoCommandVtable;
|
||||
use crate::undo::push_or_run;
|
||||
|
||||
/// `engine/include/oakengine/timeline.h` — POD mirror of
|
||||
@@ -198,8 +198,8 @@ fn command_box(cmd: CHandle) -> Result<*mut OakEngineClipboard> {
|
||||
unsafe fn push_command(cmd: CHandle, name: &str) -> Result<()> {
|
||||
unsafe {
|
||||
let boxed = command_box(cmd)?;
|
||||
let name_c = std::ffi::CString::new(name)
|
||||
.map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
let name_c =
|
||||
std::ffi::CString::new(name).map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
push_or_run(boxed, name_c.as_ptr())
|
||||
}
|
||||
}
|
||||
@@ -227,8 +227,8 @@ unsafe fn push_multi_commands(children: &[CHandle], name: &str) -> Result<()> {
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
}
|
||||
let name_c = std::ffi::CString::new(name)
|
||||
.map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
let name_c =
|
||||
std::ffi::CString::new(name).map_err(|_| Error::Failed("invalid undo name".into()))?;
|
||||
push_or_run(multi_box, name_c.as_ptr())
|
||||
}
|
||||
}
|
||||
@@ -681,8 +681,7 @@ unsafe fn clip_at_index(list: CHandle, track_index: c_int, clip_index: c_int) ->
|
||||
return CHandle::null();
|
||||
}
|
||||
let mut track = CHandle::null();
|
||||
if n::oaknode_tracklist_get_track_at(list, track_index, &mut track) != 0
|
||||
|| track.is_null()
|
||||
if n::oaknode_tracklist_get_track_at(list, track_index, &mut track) != 0 || track.is_null()
|
||||
{
|
||||
return CHandle::null();
|
||||
}
|
||||
@@ -777,8 +776,7 @@ unsafe fn nearest_block_before(track: CHandle, num: i64, den: i64) -> CHandle {
|
||||
let mut out_num: c_int = 0;
|
||||
let mut out_den: c_int = 0;
|
||||
if n::oaknode_block_get_out(b, &mut out_num, &mut out_den) == 0
|
||||
&& rat_cmp(out_num as i64, out_den as i64, num, den)
|
||||
== std::cmp::Ordering::Less
|
||||
&& rat_cmp(out_num as i64, out_den as i64, num, den) == std::cmp::Ordering::Less
|
||||
{
|
||||
if !best.is_null() {
|
||||
release_handle(best);
|
||||
@@ -838,8 +836,8 @@ pub unsafe extern "C" fn oakengine_sequence_new(
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
let label = read_cstr(name);
|
||||
let label_c = std::ffi::CString::new(label)
|
||||
.map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
let label_c =
|
||||
std::ffi::CString::new(label).map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
let seq_node = n::oaknode_sequence_as_node(seq);
|
||||
let rc = n::oaknode_node_set_label(seq_node, label_c.as_ptr());
|
||||
release_handle(seq_node);
|
||||
@@ -1053,7 +1051,8 @@ pub unsafe extern "C" fn oakengine_sequence_get_video_params_ex(
|
||||
}
|
||||
if !interlacing.is_null() {
|
||||
Error::from_module(c::oakcommon_videoparams_get_interlacing(
|
||||
params, interlacing,
|
||||
params,
|
||||
interlacing,
|
||||
))?;
|
||||
}
|
||||
if !format.is_null() {
|
||||
@@ -1093,13 +1092,19 @@ pub unsafe extern "C" fn oakengine_sequence_set_video_params(
|
||||
set_seq_error(&format!("invalid video size {}x{}", width, height));
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
if (fps_num == -1) != (fps_den == -1) || fps_num < -1 || fps_num == 0 || fps_den < -1
|
||||
if (fps_num == -1) != (fps_den == -1)
|
||||
|| fps_num < -1
|
||||
|| fps_num == 0
|
||||
|| fps_den < -1
|
||||
|| fps_den == 0
|
||||
{
|
||||
set_seq_error(&format!("invalid frame rate {}/{}", fps_num, fps_den));
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
if (par_num == -1) != (par_den == -1) || par_num < -1 || par_num == 0 || par_den < -1
|
||||
if (par_num == -1) != (par_den == -1)
|
||||
|| par_num < -1
|
||||
|| par_num == 0
|
||||
|| par_den < -1
|
||||
|| par_den == 0
|
||||
{
|
||||
set_seq_error(&format!("invalid pixel aspect {}/{}", par_num, par_den));
|
||||
@@ -1140,10 +1145,7 @@ pub unsafe extern "C" fn oakengine_sequence_set_video_params(
|
||||
}
|
||||
c::oakcommon_videoparams_set_width(new, if width >= 0 { width } else { cur_w });
|
||||
c::oakcommon_videoparams_set_height(new, if height >= 0 { height } else { cur_h });
|
||||
c::oakcommon_videoparams_set_format(
|
||||
new,
|
||||
if format >= 0 { format } else { cur_fmt },
|
||||
);
|
||||
c::oakcommon_videoparams_set_format(new, if format >= 0 { format } else { cur_fmt });
|
||||
c::oakcommon_videoparams_set_frame_rate(
|
||||
new,
|
||||
if fps_num >= 0 { fps_num } else { cur_fn },
|
||||
@@ -1164,7 +1166,12 @@ pub unsafe extern "C" fn oakengine_sequence_set_video_params(
|
||||
old_params: current,
|
||||
new_params: new,
|
||||
}));
|
||||
let cmd = vtable_command(video_params_redo, video_params_undo, video_params_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
video_params_redo,
|
||||
video_params_undo,
|
||||
video_params_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
push_command(cmd, "Set Sequence Video Parameters")
|
||||
} else {
|
||||
let rc = n::oaknode_sequence_set_video_params(seq, 0, new);
|
||||
@@ -1232,8 +1239,16 @@ pub unsafe extern "C" fn oakengine_sequence_set_audio_params(
|
||||
let cur_format = a::oakcore_audioparams_format(current);
|
||||
a::oakcore_audioparams_free(current);
|
||||
|
||||
let new_rate = if sample_rate <= 0 { cur_rate } else { sample_rate };
|
||||
let new_layout = if channel_layout == 0 { cur_layout } else { channel_layout };
|
||||
let new_rate = if sample_rate <= 0 {
|
||||
cur_rate
|
||||
} else {
|
||||
sample_rate
|
||||
};
|
||||
let new_layout = if channel_layout == 0 {
|
||||
cur_layout
|
||||
} else {
|
||||
channel_layout
|
||||
};
|
||||
if new_rate == cur_rate && new_layout == cur_layout {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -1252,8 +1267,12 @@ pub unsafe extern "C" fn oakengine_sequence_set_audio_params(
|
||||
old_params: old,
|
||||
new_params: new,
|
||||
}));
|
||||
let cmd =
|
||||
vtable_command(audio_params_redo, audio_params_undo, audio_params_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
audio_params_redo,
|
||||
audio_params_undo,
|
||||
audio_params_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
push_command(cmd, "Set Sequence Audio Parameters")
|
||||
} else {
|
||||
let r = n::oaknode_sequence_set_audio_params(seq, 0, new);
|
||||
@@ -1378,10 +1397,18 @@ pub unsafe extern "C" fn oakengine_sequence_track_count(
|
||||
guard(|| unsafe {
|
||||
let h = unbox(self_)?;
|
||||
if !video.is_null() {
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(h, TRACK_TYPE_VIDEO, video))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(
|
||||
h,
|
||||
TRACK_TYPE_VIDEO,
|
||||
video,
|
||||
))?;
|
||||
}
|
||||
if !audio.is_null() {
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(h, TRACK_TYPE_AUDIO, audio))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(
|
||||
h,
|
||||
TRACK_TYPE_AUDIO,
|
||||
audio,
|
||||
))?;
|
||||
}
|
||||
if !subtitle.is_null() {
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(
|
||||
@@ -1548,9 +1575,7 @@ pub unsafe extern "C" fn oakengine_sequence_set_workarea(
|
||||
|
||||
/// `oakengine_sequence_marker_count` — number of timeline markers.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_sequence_marker_count(
|
||||
self_: *const OakEngineSequence,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_sequence_marker_count(self_: *const OakEngineSequence) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -1617,10 +1642,7 @@ pub unsafe extern "C" fn oakengine_sequence_marker_at(
|
||||
|
||||
/// `oakengine_sequence_last_error` — last editing error for this thread.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_sequence_last_error(
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_sequence_last_error(buf: *mut c_char, buf_size: c_int) -> c_int {
|
||||
SEQ_LAST_ERROR.with(|e| unsafe { write_string(&e.borrow(), buf, buf_size) })
|
||||
}
|
||||
|
||||
@@ -1638,7 +1660,9 @@ pub unsafe extern "C" fn oakengine_sequence_add_track(
|
||||
}
|
||||
let seq = unbox(self_)?;
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(seq, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
seq, track_type, &mut list,
|
||||
))?;
|
||||
// The module's TimelineAddTrackCommand redo only appends the
|
||||
// sequence's track array element; it never registers the created
|
||||
// track node in the list's `tracks`, so the count/at queries would
|
||||
@@ -1657,7 +1681,9 @@ pub unsafe extern "C" fn oakengine_sequence_add_track(
|
||||
}
|
||||
Error::from_module(n::oaknode_tracklist_add_track(list, track))?;
|
||||
let mut count: c_int = 0;
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(seq, track_type, &mut count))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_count(
|
||||
seq, track_type, &mut count,
|
||||
))?;
|
||||
release_handle(list);
|
||||
Ok(count - 1)
|
||||
})
|
||||
@@ -1678,7 +1704,9 @@ pub unsafe extern "C" fn oakengine_sequence_add_track_command(
|
||||
}
|
||||
let seq = unbox(self_)?;
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(seq, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
seq, track_type, &mut list,
|
||||
))?;
|
||||
let cmd = tl::oaktimeline_add_track_command(list);
|
||||
if cmd.is_null() {
|
||||
release_handle(list);
|
||||
@@ -1717,7 +1745,10 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_tracks_command(
|
||||
movement_mode: c_int,
|
||||
) -> *mut c_void {
|
||||
guard_ptr(|| {
|
||||
if self_.is_null() || infos.is_null() || info_count <= 0 || movement_den == 0
|
||||
if self_.is_null()
|
||||
|| infos.is_null()
|
||||
|| info_count <= 0
|
||||
|| movement_den == 0
|
||||
|| track_type < TRACK_TYPE_VIDEO
|
||||
|| track_type > TRACK_TYPE_SUBTITLE
|
||||
|| movement_mode < 0
|
||||
@@ -1728,7 +1759,15 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_tracks_command(
|
||||
// Stub: the oaktimeline module implements TrackListRippleToolCommand
|
||||
// internally (undoripple.rs) but exposes no C creator for it; the
|
||||
// facade bridge accordingly has no `oaktimeline_ripple_tracks_command`.
|
||||
let _ = (self_, track_type, infos, info_count, movement_num, movement_den, movement_mode);
|
||||
let _ = (
|
||||
self_,
|
||||
track_type,
|
||||
infos,
|
||||
info_count,
|
||||
movement_num,
|
||||
movement_den,
|
||||
movement_mode,
|
||||
);
|
||||
Ok(std::ptr::null_mut())
|
||||
})
|
||||
}
|
||||
@@ -1772,7 +1811,10 @@ pub unsafe extern "C" fn oakengine_sequence_add_footage_clip(
|
||||
let mut foot_project = CHandle::null();
|
||||
let rc2 = n::oaknode_node_get_project(footage_h, &mut foot_project);
|
||||
release_handle(seq_node);
|
||||
if rc != 0 || rc2 != 0 || seq_project.is_null() || foot_project.is_null()
|
||||
if rc != 0
|
||||
|| rc2 != 0
|
||||
|| seq_project.is_null()
|
||||
|| foot_project.is_null()
|
||||
|| seq_project.ctx != foot_project.ctx
|
||||
{
|
||||
release_handle(seq_project);
|
||||
@@ -1806,7 +1848,10 @@ pub unsafe extern "C" fn oakengine_sequence_add_footage_clip(
|
||||
|| track_index >= track_count
|
||||
{
|
||||
release_handle(list);
|
||||
set_seq_error(&format!("track index {} out of range ({} tracks)", track_index, track_count));
|
||||
set_seq_error(&format!(
|
||||
"track index {} out of range ({} tracks)",
|
||||
track_index, track_count
|
||||
));
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
|
||||
@@ -1846,7 +1891,12 @@ pub unsafe extern "C" fn oakengine_sequence_add_footage_clip(
|
||||
// whole add fails like the C++ would on a bad edge.
|
||||
let clip_node = n::oaknode_block_as_node(clip);
|
||||
let mut edge = CHandle::null();
|
||||
let rc = n::oaknode_node_connect_undoable(footage_h, clip_node, c"buffer_in".as_ptr(), &mut edge);
|
||||
let rc = n::oaknode_node_connect_undoable(
|
||||
footage_h,
|
||||
clip_node,
|
||||
c"buffer_in".as_ptr(),
|
||||
&mut edge,
|
||||
);
|
||||
release_handle(clip_node);
|
||||
if rc != 0 {
|
||||
for child in &children {
|
||||
@@ -1857,13 +1907,8 @@ pub unsafe extern "C" fn oakengine_sequence_add_footage_clip(
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
children.push(edge);
|
||||
let place_cmd = tl::oaktimeline_place_block_command(
|
||||
list,
|
||||
track_index,
|
||||
clip,
|
||||
in_num,
|
||||
in_den,
|
||||
);
|
||||
let place_cmd =
|
||||
tl::oaktimeline_place_block_command(list, track_index, clip, in_num, in_den);
|
||||
if place_cmd.is_null() {
|
||||
for child in &children {
|
||||
release_handle(*child);
|
||||
@@ -1920,7 +1965,11 @@ pub unsafe extern "C" fn oakengine_sequence_clip_count(
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_tracklist_get_track_at(list, track_index, &mut track))?;
|
||||
Error::from_module(n::oaknode_tracklist_get_track_at(
|
||||
list,
|
||||
track_index,
|
||||
&mut track,
|
||||
))?;
|
||||
let mut block_count: c_int = 0;
|
||||
Error::from_module(n::oaknode_track_get_block_count(track, &mut block_count))?;
|
||||
let mut count: c_int = 0;
|
||||
@@ -1951,7 +2000,9 @@ pub unsafe extern "C" fn oakengine_sequence_clip_at(
|
||||
clip_index: c_int,
|
||||
) -> *mut OakEngineClip {
|
||||
guard_ptr(|| unsafe {
|
||||
if self_.is_null() || track_type < TRACK_TYPE_VIDEO || track_type > TRACK_TYPE_SUBTITLE
|
||||
if self_.is_null()
|
||||
|| track_type < TRACK_TYPE_VIDEO
|
||||
|| track_type > TRACK_TYPE_SUBTITLE
|
||||
|| clip_index < 0
|
||||
{
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -2085,11 +2136,16 @@ pub unsafe extern "C" fn oakengine_sequence_split_clip(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let clip = clip_at_index(list, track_index, clip_index);
|
||||
release_handle(list);
|
||||
if clip.is_null() {
|
||||
set_seq_error(&format!("no clip at track {} index {}", track_index, clip_index));
|
||||
set_seq_error(&format!(
|
||||
"no clip at track {} index {}",
|
||||
track_index, clip_index
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let tb = match seq_time_base(sequence) {
|
||||
@@ -2109,7 +2165,10 @@ pub unsafe extern "C" fn oakengine_sequence_split_clip(
|
||||
let cmp_in = rat_cmp(point_num, point_den, in_num as i64, in_den as i64);
|
||||
let cmp_out = rat_cmp(point_num, point_den, out_num as i64, out_den as i64);
|
||||
if cmp_in != std::cmp::Ordering::Greater || cmp_out != std::cmp::Ordering::Less {
|
||||
set_seq_error(&format!("split time {} is not strictly inside the clip", time));
|
||||
set_seq_error(&format!(
|
||||
"split time {} is not strictly inside the clip",
|
||||
time
|
||||
));
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let cmd = tl::oaktimeline_split_command(&clip, 1, point_num, point_den);
|
||||
@@ -2151,17 +2210,25 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_delete_clip(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let clip = clip_at_index(list, track_index, clip_index);
|
||||
release_handle(list);
|
||||
if clip.is_null() {
|
||||
set_seq_error(&format!("no clip at track {} index {}", track_index, clip_index));
|
||||
set_seq_error(&format!(
|
||||
"no clip at track {} index {}",
|
||||
track_index, clip_index
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_block_get_track(clip, &mut track);
|
||||
if rc != 0 || track.is_null() {
|
||||
set_seq_error(&format!("no clip at track {} index {}", track_index, clip_index));
|
||||
set_seq_error(&format!(
|
||||
"no clip at track {} index {}",
|
||||
track_index, clip_index
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let mut in_num: c_int = 0;
|
||||
@@ -2262,7 +2329,8 @@ pub unsafe extern "C" fn oakengine_clip_trim(
|
||||
if new_in != old_in {
|
||||
// in-trim: length = block out - new in (out anchored).
|
||||
let (new_in_num, new_in_den) = ts_to_rational(new_in, tb);
|
||||
let (new_num, new_den) = rat_sub(out_num as i64, out_den as i64, new_in_num, new_in_den);
|
||||
let (new_num, new_den) =
|
||||
rat_sub(out_num as i64, out_den as i64, new_in_num, new_in_den);
|
||||
let cmd = trim_cmd(
|
||||
h,
|
||||
MOVEMENT_MODE_TRIM_IN,
|
||||
@@ -2297,7 +2365,15 @@ pub unsafe extern "C" fn oakengine_clip_trim(
|
||||
})
|
||||
}
|
||||
|
||||
/// `oakengine_sequence_move_clip` — move the addressed clip to `new_in`.
|
||||
/// `oakengine_sequence_move_clip` — move the addressed clip so its in
|
||||
/// point becomes `new_in` (frame units in the sequence's timebase).
|
||||
///
|
||||
/// Mirrors the capi: the clip's old spot is replaced with a gap and the
|
||||
/// clip is placed at the destination, both as ONE undoable entry ("Move
|
||||
/// Clip"). The destination track is the addressed track itself (the
|
||||
/// capi passes `track_index` straight through to the place command), so
|
||||
/// this is a time-only move within the same track; length and media-in
|
||||
/// point are preserved.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_sequence_move_clip(
|
||||
seq: *mut OakEngineSequence,
|
||||
@@ -2320,28 +2396,36 @@ pub unsafe extern "C" fn oakengine_sequence_move_clip(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let clip = clip_at_index(list, track_index, clip_index);
|
||||
release_handle(list);
|
||||
if clip.is_null() {
|
||||
set_seq_error(&format!("no clip at track {} index {}", track_index, clip_index));
|
||||
set_seq_error(&format!(
|
||||
"no clip at track {} index {}",
|
||||
track_index, clip_index
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_block_get_track(clip, &mut track);
|
||||
if rc != 0 || track.is_null() {
|
||||
set_seq_error(&format!("no clip at track {} index {}", track_index, clip_index));
|
||||
set_seq_error(&format!(
|
||||
"no clip at track {} index {}",
|
||||
track_index, clip_index
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
release_handle(track);
|
||||
// Stub: the module's gap+place composition
|
||||
// (`TrackReplaceBlockWithGapCommand` then `TrackPlaceBlockCommand`)
|
||||
// faults with a memory error in the module world after accumulated
|
||||
// timeline edits (and the two commands pushed as ONE undoable entry,
|
||||
// as the capi does, faults even on a fresh clip), so the move cannot
|
||||
// be performed safely.
|
||||
set_seq_error("clip moves are not supported by the module");
|
||||
Err(Error::State)
|
||||
let tb = seq_time_base(sequence)?;
|
||||
let (new_in_num, new_in_den) = ts_to_rational(new_in, tb);
|
||||
// NOTE: `list`/`clip`/`track` are borrowed module handles; the
|
||||
// move command keeps copies of `list` and `clip` for the whole undo
|
||||
// entry, so their shells must not be released here (the same
|
||||
// convention as the other command-creating family functions). The
|
||||
// destination is the addressed track itself.
|
||||
let cmd =
|
||||
tl::oaktimeline_move_block_command(list, track_index, clip, new_in_num, new_in_den);
|
||||
push_command(cmd, "Move Clip")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2452,7 +2536,9 @@ pub unsafe extern "C" fn oakengine_sequence_delete_clips(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
};
|
||||
if clip_count < 0 || (clip_count > 0 && clips.is_null()) || ripple_range_count < 0
|
||||
if clip_count < 0
|
||||
|| (clip_count > 0 && clips.is_null())
|
||||
|| ripple_range_count < 0
|
||||
|| (ripple_range_count > 0 && ripple_ranges_ts.is_null())
|
||||
{
|
||||
set_seq_error("invalid arguments");
|
||||
@@ -2539,7 +2625,10 @@ pub unsafe extern "C" fn oakengine_sequence_delete_clips(
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, rindex as c_int, &mut track);
|
||||
release_handle(list);
|
||||
if rc != 0 || track.is_null() {
|
||||
set_seq_error(&format!("no track at index {} in ripple range {}", rindex, i));
|
||||
set_seq_error(&format!(
|
||||
"no track at index {} in ripple range {}",
|
||||
rindex, i
|
||||
));
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let (in_num, in_den) = ts_to_rational(*range.add(2), tb);
|
||||
@@ -2621,25 +2710,21 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_delete_range(
|
||||
let (in_num, in_den) = ts_to_rational(in_ts, tb);
|
||||
let (out_num, out_den) = ts_to_rational(out_ts, tb);
|
||||
let mut all_count: c_int = 0;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(sequence, &mut all_count))?;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(
|
||||
sequence,
|
||||
&mut all_count,
|
||||
))?;
|
||||
let mut children: Vec<CHandle> = Vec::new();
|
||||
for i in 0..all_count {
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(
|
||||
sequence,
|
||||
i,
|
||||
&mut track,
|
||||
sequence, i, &mut track,
|
||||
))?;
|
||||
if track.is_null() {
|
||||
continue;
|
||||
}
|
||||
let cmd = tl::oaktimeline_ripple_remove_area_command(
|
||||
track,
|
||||
in_num,
|
||||
in_den,
|
||||
out_num,
|
||||
out_den,
|
||||
);
|
||||
let cmd =
|
||||
tl::oaktimeline_ripple_remove_area_command(track, in_num, in_den, out_num, out_den);
|
||||
// NOTE: `track` is intentionally NOT released — the module
|
||||
// command stores the borrowed handle for its whole lifetime (see
|
||||
// `oakengine_sequence_ripple_delete_clip`).
|
||||
@@ -2689,7 +2774,12 @@ pub unsafe extern "C" fn oakengine_clip_toggle_enabled(
|
||||
old_enabled: enabled,
|
||||
new_enabled: if enabled != 0 { 0 } else { 1 },
|
||||
}));
|
||||
let cmd = vtable_command(block_enabled_redo, block_enabled_undo, block_enabled_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
block_enabled_redo,
|
||||
block_enabled_undo,
|
||||
block_enabled_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
children.push(cmd);
|
||||
}
|
||||
push_multi_commands(&children, "Toggle Clips Enabled")?;
|
||||
@@ -2733,12 +2823,7 @@ pub unsafe extern "C" fn oakengine_clip_set_linked(
|
||||
for i in 0..handles.len() {
|
||||
for j in (i + 1)..handles.len() {
|
||||
let mut cmd = CHandle::null();
|
||||
let rc = n::oaknode_node_link_undoable(
|
||||
handles[i],
|
||||
handles[j],
|
||||
linked,
|
||||
&mut cmd,
|
||||
);
|
||||
let rc = n::oaknode_node_link_undoable(handles[i], handles[j], linked, &mut cmd);
|
||||
if rc == 0 && !cmd.is_null() {
|
||||
children.push(cmd);
|
||||
} else if rc != 0 {
|
||||
@@ -2868,19 +2953,13 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_delete_in_to_out(
|
||||
for i in 0..all_count {
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(
|
||||
sequence,
|
||||
i,
|
||||
&mut track,
|
||||
sequence, i, &mut track,
|
||||
))?;
|
||||
if track.is_null() {
|
||||
continue;
|
||||
}
|
||||
let cmd = tl::oaktimeline_ripple_remove_area_command(
|
||||
track,
|
||||
in_num,
|
||||
in_den,
|
||||
out_num,
|
||||
out_den,
|
||||
track, in_num, in_den, out_num, out_den,
|
||||
);
|
||||
// NOTE: `track` is intentionally NOT released — the module
|
||||
// command stores the borrowed handle for its whole lifetime
|
||||
@@ -2902,9 +2981,7 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_delete_in_to_out(
|
||||
for i in 0..all_count {
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(
|
||||
sequence,
|
||||
i,
|
||||
&mut track,
|
||||
sequence, i, &mut track,
|
||||
))?;
|
||||
if track.is_null() {
|
||||
continue;
|
||||
@@ -2940,13 +3017,8 @@ pub unsafe extern "C" fn oakengine_sequence_ripple_delete_in_to_out(
|
||||
len_den as c_int,
|
||||
);
|
||||
let add_cmd = n::oaknode_command_create_add_node(project, gap);
|
||||
let place_cmd = tl::oaktimeline_place_block_command(
|
||||
list,
|
||||
tindex,
|
||||
gap,
|
||||
in_num,
|
||||
in_den,
|
||||
);
|
||||
let place_cmd =
|
||||
tl::oaktimeline_place_block_command(list, tindex, gap, in_num, in_den);
|
||||
release_handle(project);
|
||||
release_handle(list);
|
||||
release_handle(track);
|
||||
@@ -3006,10 +3078,15 @@ pub unsafe extern "C" fn oakengine_sequence_trim_clips_to(
|
||||
let mut children: Vec<CHandle> = Vec::new();
|
||||
let mut trimmed: c_int = 0;
|
||||
let mut all_count: c_int = 0;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(sequence, &mut all_count))?;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(
|
||||
sequence,
|
||||
&mut all_count,
|
||||
))?;
|
||||
for i in 0..all_count {
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(sequence, i, &mut track))?;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(
|
||||
sequence, i, &mut track,
|
||||
))?;
|
||||
if track.is_null() {
|
||||
continue;
|
||||
}
|
||||
@@ -3057,7 +3134,11 @@ pub unsafe extern "C" fn oakengine_sequence_trim_clips_to(
|
||||
};
|
||||
let mut old_len_num: c_int = 0;
|
||||
let mut old_len_den: c_int = 0;
|
||||
Error::from_module(n::oaknode_block_get_length(block, &mut old_len_num, &mut old_len_den))?;
|
||||
Error::from_module(n::oaknode_block_get_length(
|
||||
block,
|
||||
&mut old_len_num,
|
||||
&mut old_len_den,
|
||||
))?;
|
||||
// Trim the addressed block itself (`trim_cmd` anchors on the
|
||||
// block handle; passing the track used to silently reject the
|
||||
// trim in the module).
|
||||
@@ -3108,10 +3189,15 @@ pub unsafe extern "C" fn oakengine_sequence_delete_empty_tracks(
|
||||
let mut to_remove: Vec<(CHandle, CHandle)> = Vec::new();
|
||||
let mut removed: c_int = 0;
|
||||
let mut all_count: c_int = 0;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(sequence, &mut all_count))?;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_count(
|
||||
sequence,
|
||||
&mut all_count,
|
||||
))?;
|
||||
for i in 0..all_count {
|
||||
let mut track = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(sequence, i, &mut track))?;
|
||||
Error::from_module(n::oaknode_sequence_get_all_track_at(
|
||||
sequence, i, &mut track,
|
||||
))?;
|
||||
if track.is_null() {
|
||||
continue;
|
||||
}
|
||||
@@ -3123,9 +3209,7 @@ pub unsafe extern "C" fn oakengine_sequence_delete_empty_tracks(
|
||||
}
|
||||
}
|
||||
let mut block_count: c_int = 0;
|
||||
if n::oaknode_track_get_block_count(track, &mut block_count) != 0
|
||||
|| block_count != 0
|
||||
{
|
||||
if n::oaknode_track_get_block_count(track, &mut block_count) != 0 || block_count != 0 {
|
||||
release_handle(track);
|
||||
continue;
|
||||
}
|
||||
@@ -3252,7 +3336,9 @@ pub unsafe extern "C" fn oakengine_sequence_remove_track(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -3302,7 +3388,9 @@ pub unsafe extern "C" fn oakengine_sequence_move_track(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut count: c_int = 0;
|
||||
Error::from_module(n::oaknode_tracklist_get_track_count(list, &mut count))?;
|
||||
release_handle(list);
|
||||
@@ -3348,7 +3436,9 @@ pub unsafe extern "C" fn oakengine_track_get_height(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -3384,7 +3474,9 @@ pub unsafe extern "C" fn oakengine_track_set_height(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -3452,7 +3544,9 @@ pub unsafe extern "C" fn oakengine_track_set_muted(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -3520,7 +3614,9 @@ pub unsafe extern "C" fn oakengine_track_set_locked(
|
||||
return Err(Error::Invalid);
|
||||
}
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -3683,9 +3779,7 @@ pub unsafe extern "C" fn oakengine_sequence_marker_rename(
|
||||
|
||||
/// `oakengine_marker_list_count` — number of markers in the list.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_marker_list_count(
|
||||
list: *const OakEngineMarkerList,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_marker_list_count(list: *const OakEngineMarkerList) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if list.is_null() {
|
||||
return Ok(0);
|
||||
@@ -3813,8 +3907,8 @@ pub unsafe extern "C" fn oakengine_marker_list_add_existing(
|
||||
return Err(Error::Module(rc));
|
||||
}
|
||||
let name = read_cstr(name_buf.as_ptr());
|
||||
let name_c = std::ffi::CString::new(name)
|
||||
.map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
let name_c =
|
||||
std::ffi::CString::new(name).map_err(|_| Error::Failed("invalid name".into()))?;
|
||||
let cmd = tl::oaktimeline_marker_add_command(
|
||||
lh,
|
||||
in_num,
|
||||
@@ -3942,15 +4036,7 @@ pub unsafe extern "C" fn oakengine_marker_get_name(
|
||||
let mut d1: c_int = 0;
|
||||
let mut color: c_int = 0;
|
||||
let rc = tl::oaktimeline_marker_at(
|
||||
list,
|
||||
index,
|
||||
&mut n0,
|
||||
&mut d0,
|
||||
&mut n1,
|
||||
&mut d1,
|
||||
&mut color,
|
||||
buf,
|
||||
buf_size,
|
||||
list, index, &mut n0, &mut d0, &mut n1, &mut d1, &mut color, buf, buf_size,
|
||||
);
|
||||
if rc < 0 {
|
||||
Err(Error::Module(rc))
|
||||
@@ -3962,9 +4048,7 @@ pub unsafe extern "C" fn oakengine_marker_get_name(
|
||||
|
||||
/// `oakengine_marker_get_color` — the marker's color index (-1 on NULL).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_marker_get_color(
|
||||
self_: *const OakEngineMarker,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_marker_get_color(self_: *const OakEngineMarker) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(-1);
|
||||
@@ -4317,14 +4401,7 @@ pub unsafe extern "C" fn oakengine_workarea_get(
|
||||
let mut n1: c_int = 0;
|
||||
let mut d1: c_int = 0;
|
||||
let mut en: c_int = 0;
|
||||
let rc = tl::oaktimeline_workarea_get(
|
||||
h,
|
||||
&mut n0,
|
||||
&mut d0,
|
||||
&mut n1,
|
||||
&mut d1,
|
||||
&mut en,
|
||||
);
|
||||
let rc = tl::oaktimeline_workarea_get(h, &mut n0, &mut d0, &mut n1, &mut d1, &mut en);
|
||||
Error::from_module(rc)?;
|
||||
if !in_num.is_null() {
|
||||
*in_num = n0 as i64;
|
||||
@@ -4497,7 +4574,8 @@ pub unsafe extern "C" fn oakengine_clip_get_media_range_rational(
|
||||
Error::from_module(n::oaknode_block_get_length(h, &mut len_num, &mut len_den))?;
|
||||
// media_out = media_in + length (speed/reverse ignored, like the
|
||||
// capi).
|
||||
let (mo_num, mo_den) = rat_add(mi_num as i64, mi_den as i64, len_num as i64, len_den as i64);
|
||||
let (mo_num, mo_den) =
|
||||
rat_add(mi_num as i64, mi_den as i64, len_num as i64, len_den as i64);
|
||||
if !in_num.is_null() {
|
||||
*in_num = mi_num as i64;
|
||||
}
|
||||
@@ -4587,12 +4665,21 @@ pub unsafe extern "C" fn oakengine_clip_set_media_in(
|
||||
///
|
||||
/// # Safety
|
||||
/// `clip` must be a live module clip handle.
|
||||
unsafe fn apply_clip_media_in(clip: CHandle, num: c_int, den: c_int, undoable: c_int) -> Result<()> {
|
||||
unsafe fn apply_clip_media_in(
|
||||
clip: CHandle,
|
||||
num: c_int,
|
||||
den: c_int,
|
||||
undoable: c_int,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
if undoable != 0 {
|
||||
let mut old_num: c_int = 0;
|
||||
let mut old_den: c_int = 0;
|
||||
Error::from_module(n::oaknode_clip_get_media_in(clip, &mut old_num, &mut old_den))?;
|
||||
Error::from_module(n::oaknode_clip_get_media_in(
|
||||
clip,
|
||||
&mut old_num,
|
||||
&mut old_den,
|
||||
))?;
|
||||
let data = Box::into_raw(Box::new(ClipMediaInCmdData {
|
||||
clip: clip.addref(),
|
||||
old_num,
|
||||
@@ -4600,7 +4687,12 @@ unsafe fn apply_clip_media_in(clip: CHandle, num: c_int, den: c_int, undoable: c
|
||||
new_num: num,
|
||||
new_den: den,
|
||||
}));
|
||||
let cmd = vtable_command(clip_media_in_redo, clip_media_in_undo, clip_media_in_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
clip_media_in_redo,
|
||||
clip_media_in_undo,
|
||||
clip_media_in_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
push_command(cmd, "Set Media In")
|
||||
} else {
|
||||
Error::from_module(n::oaknode_clip_set_media_in(clip, num, den))
|
||||
@@ -4731,9 +4823,7 @@ pub unsafe extern "C" fn oakengine_clip_request_invalidate_connected(
|
||||
|
||||
/// `oakengine_block_is_enabled` — 1 if the block is enabled.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_block_is_enabled(
|
||||
self_: *const OakEngineBlock,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_block_is_enabled(self_: *const OakEngineBlock) -> c_int {
|
||||
guard_int(|| unsafe {
|
||||
if self_.is_null() {
|
||||
return Ok(0);
|
||||
@@ -4763,7 +4853,12 @@ pub unsafe extern "C" fn oakengine_block_set_enabled(
|
||||
old_enabled,
|
||||
new_enabled: enabled,
|
||||
}));
|
||||
let cmd = vtable_command(block_enabled_redo, block_enabled_undo, block_enabled_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
block_enabled_redo,
|
||||
block_enabled_undo,
|
||||
block_enabled_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
push_command(cmd, "Set Block Enabled")
|
||||
})
|
||||
}
|
||||
@@ -4828,12 +4923,8 @@ pub unsafe extern "C" fn oakengine_track_block_at_time(
|
||||
release_handle(sequence);
|
||||
let (num, den) = ts_to_rational(timestamp, tb);
|
||||
let mut block = CHandle::null();
|
||||
let rc = n::oaknode_track_get_block_containing_time(
|
||||
h,
|
||||
num as c_int,
|
||||
den as c_int,
|
||||
&mut block,
|
||||
);
|
||||
let rc =
|
||||
n::oaknode_track_get_block_containing_time(h, num as c_int, den as c_int, &mut block);
|
||||
if rc != 0 || block.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
@@ -4954,8 +5045,7 @@ pub unsafe extern "C" fn oakengine_track_nearest_block_after(
|
||||
let mut in_num: c_int = 0;
|
||||
let mut in_den: c_int = 0;
|
||||
let after = n::oaknode_block_get_in(b, &mut in_num, &mut in_den) == 0
|
||||
&& rat_cmp(in_num as i64, in_den as i64, num, den)
|
||||
== std::cmp::Ordering::Greater;
|
||||
&& rat_cmp(in_num as i64, in_den as i64, num, den) == std::cmp::Ordering::Greater;
|
||||
if after {
|
||||
best = b;
|
||||
break;
|
||||
@@ -4976,7 +5066,13 @@ pub unsafe extern "C" fn oakengine_track_nearest_block_before_or_at(
|
||||
track: *const OakEngineTrack,
|
||||
timestamp: i64,
|
||||
) -> *mut OakEngineBlock {
|
||||
unsafe { track_nearest_boxed(track, timestamp, n::oaknode_track_get_nearest_block_before_or_at) }
|
||||
unsafe {
|
||||
track_nearest_boxed(
|
||||
track,
|
||||
timestamp,
|
||||
n::oaknode_track_get_nearest_block_before_or_at,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// `oakengine_track_nearest_block_after_or_at` — nearest block whose
|
||||
@@ -4986,7 +5082,13 @@ pub unsafe extern "C" fn oakengine_track_nearest_block_after_or_at(
|
||||
track: *const OakEngineTrack,
|
||||
timestamp: i64,
|
||||
) -> *mut OakEngineBlock {
|
||||
unsafe { track_nearest_boxed(track, timestamp, n::oaknode_track_get_nearest_block_after_or_at) }
|
||||
unsafe {
|
||||
track_nearest_boxed(
|
||||
track,
|
||||
timestamp,
|
||||
n::oaknode_track_get_nearest_block_after_or_at,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// `oakengine_block_is_gap` — 1 if the block is a GapBlock.
|
||||
@@ -5040,9 +5142,7 @@ pub unsafe extern "C" fn oakengine_block_get_track(
|
||||
|
||||
/// `oakengine_block_next` — next block in the track's linked list.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_block_next(
|
||||
block: *const OakEngineBlock,
|
||||
) -> *mut OakEngineBlock {
|
||||
pub unsafe extern "C" fn oakengine_block_next(block: *const OakEngineBlock) -> *mut OakEngineBlock {
|
||||
guard_ptr(|| unsafe {
|
||||
if block.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -5059,9 +5159,7 @@ pub unsafe extern "C" fn oakengine_block_next(
|
||||
|
||||
/// `oakengine_block_prev` — previous block in the track's linked list.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_block_prev(
|
||||
block: *const OakEngineBlock,
|
||||
) -> *mut OakEngineBlock {
|
||||
pub unsafe extern "C" fn oakengine_block_prev(block: *const OakEngineBlock) -> *mut OakEngineBlock {
|
||||
guard_ptr(|| unsafe {
|
||||
if block.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -5321,7 +5419,8 @@ pub unsafe extern "C" fn oakengine_sequence_add_sequence_clip(
|
||||
// the nested-sequence connection cannot be built.
|
||||
let clip_node = n::oaknode_block_as_node(clip);
|
||||
let mut edge = CHandle::null();
|
||||
let rc = n::oaknode_node_connect_undoable(nested_h, clip_node, c"buffer_in".as_ptr(), &mut edge);
|
||||
let rc =
|
||||
n::oaknode_node_connect_undoable(nested_h, clip_node, c"buffer_in".as_ptr(), &mut edge);
|
||||
release_handle(clip_node);
|
||||
if rc != 0 {
|
||||
release_handle(add_cmd);
|
||||
@@ -5330,7 +5429,8 @@ pub unsafe extern "C" fn oakengine_sequence_add_sequence_clip(
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
let (in_num, in_den) = ts_to_rational(in_, tb);
|
||||
let place_cmd = tl::oaktimeline_place_block_command(list, track_index, clip, in_num, in_den);
|
||||
let place_cmd =
|
||||
tl::oaktimeline_place_block_command(list, track_index, clip, in_num, in_den);
|
||||
release_handle(list);
|
||||
if place_cmd.is_null() {
|
||||
release_handle(add_cmd);
|
||||
@@ -5340,7 +5440,10 @@ pub unsafe extern "C" fn oakengine_sequence_add_sequence_clip(
|
||||
}
|
||||
let children = [add_cmd, edge, place_cmd];
|
||||
if let Err(e) = push_multi_commands(&children, "Add Sequence Clip") {
|
||||
set_seq_error(&format!("failed to push add-sequence-clip command: {:?}", e));
|
||||
set_seq_error(&format!(
|
||||
"failed to push add-sequence-clip command: {:?}",
|
||||
e
|
||||
));
|
||||
return Err(e);
|
||||
}
|
||||
Ok(box_handle::<OakEngineClip>(clip))
|
||||
@@ -5406,7 +5509,9 @@ pub unsafe extern "C" fn oakengine_track_get_length(
|
||||
}
|
||||
};
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -5455,7 +5560,9 @@ pub unsafe extern "C" fn oakengine_track_is_range_free(
|
||||
}
|
||||
};
|
||||
let mut list = CHandle::null();
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(sequence, track_type, &mut list))?;
|
||||
Error::from_module(n::oaknode_sequence_get_track_list(
|
||||
sequence, track_type, &mut list,
|
||||
))?;
|
||||
let mut track = CHandle::null();
|
||||
let rc = n::oaknode_tracklist_get_track_at(list, track_index, &mut track);
|
||||
release_handle(list);
|
||||
@@ -5533,7 +5640,9 @@ pub extern "C" fn oakengine_track_height_minimum() -> f64 {
|
||||
/// `oakengine_clip_find_multicam` — find the MultiCamNode ancestor of a
|
||||
/// node.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_clip_find_multicam(node: *mut OakEngineNode) -> *mut OakEngineNode {
|
||||
pub unsafe extern "C" fn oakengine_clip_find_multicam(
|
||||
node: *mut OakEngineNode,
|
||||
) -> *mut OakEngineNode {
|
||||
guard_ptr(|| {
|
||||
// Stub: the C++ walks the clip's buffer-input chain looking for a
|
||||
// MultiCamNode; module clips have no buffer input, so no ancestor can
|
||||
@@ -5614,7 +5723,8 @@ pub unsafe extern "C" fn oakengine_track_visible_block_at_time(
|
||||
release_handle(sequence);
|
||||
let (num, den) = ts_to_rational(time_ts, tb);
|
||||
let mut block = CHandle::null();
|
||||
let rc = n::oaknode_track_get_visible_block_at_time(h, num as c_int, den as c_int, &mut block);
|
||||
let rc =
|
||||
n::oaknode_track_get_visible_block_at_time(h, num as c_int, den as c_int, &mut block);
|
||||
if rc != 0 || block.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
}
|
||||
@@ -5698,7 +5808,12 @@ pub unsafe extern "C" fn oakengine_block_set_length_and_media_out(
|
||||
new_num: num as c_int,
|
||||
new_den: den as c_int,
|
||||
}));
|
||||
let cmd = vtable_command(block_resize_redo, block_resize_undo, block_resize_free, data as *mut c_void)?;
|
||||
let cmd = vtable_command(
|
||||
block_resize_redo,
|
||||
block_resize_undo,
|
||||
block_resize_free,
|
||||
data as *mut c_void,
|
||||
)?;
|
||||
push_command(cmd, "Set Block Length")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ use std::sync::{Mutex, OnceLock};
|
||||
|
||||
use crate::bridge::undo as u;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::handle::{
|
||||
box_handle, free_box, guard, guard_void, unbox, CHandle, OakEngineClipboard,
|
||||
};
|
||||
use crate::handle::{box_handle, free_box, guard, guard_void, unbox, CHandle, OakEngineClipboard};
|
||||
|
||||
/// The process-wide undo stack handle (oakundo `OakUndoStack`), created
|
||||
/// lazily and kept for the process lifetime.
|
||||
@@ -73,7 +71,10 @@ fn group_lock() -> std::sync::MutexGuard<'static, Option<OpenGroup>> {
|
||||
///
|
||||
/// # Safety
|
||||
/// `command_box` must be a live box created by a facade command creator.
|
||||
pub(crate) unsafe fn push_or_run(command_box: *mut OakEngineClipboard, name: *const c_char) -> Result<()> {
|
||||
pub(crate) unsafe fn push_or_run(
|
||||
command_box: *mut OakEngineClipboard,
|
||||
name: *const c_char,
|
||||
) -> Result<()> {
|
||||
let cmd = unsafe { unbox(command_box)? };
|
||||
let label = unsafe { crate::handle::read_cstr(name) };
|
||||
let g = group_lock();
|
||||
@@ -90,7 +91,11 @@ pub(crate) unsafe fn push_or_run(command_box: *mut OakEngineClipboard, name: *co
|
||||
let rc = unsafe { u::oakundo_command_multi_add_child(group.multi, cmd) };
|
||||
drop(g);
|
||||
unsafe { free_box(command_box) };
|
||||
return if rc == 0 { Ok(()) } else { Err(Error::Module(rc)) };
|
||||
return if rc == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Module(rc))
|
||||
};
|
||||
}
|
||||
let stack = *global_stack();
|
||||
// The module treats a NULL name like an empty label, but an empty Rust
|
||||
@@ -269,7 +274,11 @@ pub unsafe extern "C" fn oakengine_undo_command_create(
|
||||
) -> *mut c_void {
|
||||
crate::handle::guard_ptr(|| unsafe {
|
||||
let _ = crate::handle::read_cstr(name);
|
||||
let vtable = crate::bridge::undo::OakUndoCommandVtable { redo, undo, free_fn };
|
||||
let vtable = crate::bridge::undo::OakUndoCommandVtable {
|
||||
redo,
|
||||
undo,
|
||||
free_fn,
|
||||
};
|
||||
let cmd = u::oakundo_command_init(&vtable, userdata);
|
||||
if cmd.is_null() {
|
||||
return Ok(std::ptr::null_mut());
|
||||
@@ -381,7 +390,11 @@ pub unsafe extern "C" fn oakengine_undo_command_text(
|
||||
pub extern "C" fn oakengine_undo_command_is_done(row: i64) -> c_int {
|
||||
crate::handle::guard_int(|| unsafe {
|
||||
let mut value: c_int = 0;
|
||||
Error::from_module(u::oakundo_undostack_command_is_done(*global_stack(), row, &mut value))?;
|
||||
Error::from_module(u::oakundo_undostack_command_is_done(
|
||||
*global_stack(),
|
||||
row,
|
||||
&mut value,
|
||||
))?;
|
||||
Ok(value)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -188,8 +188,9 @@ impl Renderer {
|
||||
log_error(&format!(
|
||||
"failed to initialize dynamic {backend} backend: {first}; falling back to direct OpenGL renderer"
|
||||
));
|
||||
Self::create_opengl()
|
||||
.map_err(|second| format!("{first}; direct OpenGL fallback also failed: {second}"))
|
||||
Self::create_opengl().map_err(|second| {
|
||||
format!("{first}; direct OpenGL fallback also failed: {second}")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +220,8 @@ impl Renderer {
|
||||
}
|
||||
// SAFETY: `handle` is live and owned by us; NULL gl_context makes
|
||||
// the backend use its default device/context path.
|
||||
let rc = unsafe { render_ffi::oakrender_display_renderer_init(handle, std::ptr::null_mut()) };
|
||||
let rc =
|
||||
unsafe { render_ffi::oakrender_display_renderer_init(handle, std::ptr::null_mut()) };
|
||||
if rc != 0 {
|
||||
// SAFETY: the handle is still owned by us (init failed).
|
||||
unsafe { render_ffi::oakrender_display_renderer_destroy(&mut handle) };
|
||||
@@ -364,7 +366,10 @@ impl WorkerSession {
|
||||
self.shutdown_requested = true;
|
||||
None
|
||||
}
|
||||
other => Some(error_message(&format!("unknown message type: {other}"), None)),
|
||||
other => Some(error_message(
|
||||
&format!("unknown message type: {other}"),
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +400,8 @@ impl WorkerSession {
|
||||
self.output_pool = None;
|
||||
self.output_region = None;
|
||||
|
||||
let bytes = FrameSlotPool::bytes_needed(hs.output_slots as u32, hs.slot_data_bytes as usize);
|
||||
let bytes =
|
||||
FrameSlotPool::bytes_needed(hs.output_slots as u32, hs.slot_data_bytes as usize);
|
||||
let mut output_region = SharedMemoryRegion::new();
|
||||
if !output_region.open(&hs.shm_key, bytes, ShmMode::Attach) {
|
||||
return Some(error_message(
|
||||
@@ -422,12 +428,17 @@ impl WorkerSession {
|
||||
None,
|
||||
));
|
||||
}
|
||||
let input_bytes =
|
||||
FrameSlotPool::bytes_needed(hs.input_slots as u32, hs.input_slot_data_bytes as usize);
|
||||
let input_bytes = FrameSlotPool::bytes_needed(
|
||||
hs.input_slots as u32,
|
||||
hs.input_slot_data_bytes as usize,
|
||||
);
|
||||
let mut input_region = SharedMemoryRegion::new();
|
||||
if !input_region.open(&hs.input_shm_key, input_bytes, ShmMode::Attach) {
|
||||
return Some(error_message(
|
||||
&format!("failed to attach input shared memory: {}", input_region.error()),
|
||||
&format!(
|
||||
"failed to attach input shared memory: {}",
|
||||
input_region.error()
|
||||
),
|
||||
None,
|
||||
));
|
||||
}
|
||||
@@ -509,8 +520,8 @@ impl HandshakeMsg {
|
||||
/// Write one NDJSON message line (compact JSON + `\n`), the Rust port of
|
||||
/// `ipcmessage.cpp write_message()`.
|
||||
fn write_message(w: &mut impl Write, msg: &Value) -> io::Result<()> {
|
||||
let line = serde_json::to_string(msg)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
let line =
|
||||
serde_json::to_string(msg).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
w.write_all(line.as_bytes())?;
|
||||
w.write_all(b"\n")
|
||||
}
|
||||
@@ -529,8 +540,7 @@ fn parse_backend(argc: c_int, argv: *mut *mut c_char) -> String {
|
||||
let arg = unsafe { crate::handle::read_cstr(args[i]) };
|
||||
if arg == "--backend" && i + 1 < args.len() {
|
||||
// SAFETY: `args[i + 1]` is a valid NUL-terminated C string.
|
||||
backend = unsafe { crate::handle::read_cstr(args[i + 1]) }
|
||||
.to_ascii_lowercase();
|
||||
backend = unsafe { crate::handle::read_cstr(args[i + 1]) }.to_ascii_lowercase();
|
||||
i += 2;
|
||||
} else {
|
||||
i += 1;
|
||||
@@ -636,8 +646,8 @@ pub unsafe extern "C" fn oakengine_worker_session_create(
|
||||
) -> *mut OakWorkerSession {
|
||||
crate::handle::guard_ptr(|| unsafe {
|
||||
let backend = crate::handle::read_cstr(backend);
|
||||
let session = WorkerSession::create(&backend)
|
||||
.map_err(|e| crate::error::Error::Failed(e))?;
|
||||
let session =
|
||||
WorkerSession::create(&backend).map_err(|e| crate::error::Error::Failed(e))?;
|
||||
Ok(Box::into_raw(Box::new(session)) as *mut OakWorkerSession)
|
||||
})
|
||||
}
|
||||
@@ -696,8 +706,8 @@ pub unsafe extern "C" fn oakengine_worker_session_startup_handshake(
|
||||
}
|
||||
let session = &*(self_ as *const WorkerSession);
|
||||
let json = session.startup_handshake();
|
||||
let line = serde_json::to_string(&json)
|
||||
.map_err(|e| crate::error::Error::Failed(e.to_string()))?;
|
||||
let line =
|
||||
serde_json::to_string(&json).map_err(|e| crate::error::Error::Failed(e.to_string()))?;
|
||||
Ok(crate::handle::write_string(&line, buf, buf_size))
|
||||
})
|
||||
}
|
||||
@@ -723,7 +733,11 @@ pub unsafe extern "C" fn oakengine_worker_session_handle_json(
|
||||
Some(response) => {
|
||||
let json = serde_json::to_string(&response)
|
||||
.map_err(|e| crate::error::Error::Failed(e.to_string()))?;
|
||||
Ok(crate::handle::write_string(&json, response_buf, response_buf_size))
|
||||
Ok(crate::handle::write_string(
|
||||
&json,
|
||||
response_buf,
|
||||
response_buf_size,
|
||||
))
|
||||
}
|
||||
None => Ok(0),
|
||||
}
|
||||
@@ -748,10 +762,7 @@ pub unsafe extern "C" fn oakengine_worker_session_shutdown_requested(
|
||||
/// stdin/stdout NDJSON loop until a shutdown message or EOF. Returns the
|
||||
/// process exit code.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oakengine_worker_main(
|
||||
argc: c_int,
|
||||
argv: *mut *mut c_char,
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn oakengine_worker_main(argc: c_int, argv: *mut *mut c_char) -> c_int {
|
||||
crate::handle::guard_int(|| {
|
||||
let backend = parse_backend(argc, argv);
|
||||
Ok(worker_main(&backend))
|
||||
@@ -793,7 +804,8 @@ mod tests {
|
||||
out_region.error()
|
||||
);
|
||||
// SAFETY: live mapping sized by bytes_needed.
|
||||
let _pool = unsafe { FrameSlotPool::create(out_region.data(), slots as u32, slot_bytes as usize) };
|
||||
let _pool =
|
||||
unsafe { FrameSlotPool::create(out_region.data(), slots as u32, slot_bytes as usize) };
|
||||
|
||||
let (in_key, in_bytes, in_region) = if input {
|
||||
let in_key = test_key("in");
|
||||
@@ -801,7 +813,9 @@ mod tests {
|
||||
let mut in_region = SharedMemoryRegion::new();
|
||||
assert!(in_region.open(&in_key, in_bytes, ShmMode::Create));
|
||||
// SAFETY: live mapping.
|
||||
let _ = unsafe { FrameSlotPool::create(in_region.data(), slots as u32, slot_bytes as usize) };
|
||||
let _ = unsafe {
|
||||
FrameSlotPool::create(in_region.data(), slots as u32, slot_bytes as usize)
|
||||
};
|
||||
(Some(in_key), Some(in_bytes), Some(in_region))
|
||||
} else {
|
||||
(None, None, None)
|
||||
@@ -834,12 +848,12 @@ mod tests {
|
||||
// Build a tiny fake argv the way the C runtime would: an array of
|
||||
// NUL-terminated strings.
|
||||
let make = |args: &[&str]| -> (Vec<std::ffi::CString>, Vec<*mut c_char>) {
|
||||
let cstrings: Vec<std::ffi::CString> =
|
||||
args.iter().map(|s| std::ffi::CString::new(*s).unwrap()).collect();
|
||||
let mut ptrs: Vec<*mut c_char> = cstrings
|
||||
let cstrings: Vec<std::ffi::CString> = args
|
||||
.iter()
|
||||
.map(|c| c.as_ptr() as *mut c_char)
|
||||
.map(|s| std::ffi::CString::new(*s).unwrap())
|
||||
.collect();
|
||||
let mut ptrs: Vec<*mut c_char> =
|
||||
cstrings.iter().map(|c| c.as_ptr() as *mut c_char).collect();
|
||||
(cstrings, ptrs)
|
||||
};
|
||||
let (_keep, mut argv) = make(&["oak-worker"]);
|
||||
@@ -852,13 +866,7 @@ mod tests {
|
||||
assert_eq!(parse_backend(3, argv.as_mut_ptr()), "none");
|
||||
|
||||
// Last flag wins (the C++ loop keeps scanning).
|
||||
let (_keep, mut argv) = make(&[
|
||||
"oak-worker",
|
||||
"--backend",
|
||||
"vulkan",
|
||||
"--backend",
|
||||
"opengl",
|
||||
]);
|
||||
let (_keep, mut argv) = make(&["oak-worker", "--backend", "vulkan", "--backend", "opengl"]);
|
||||
assert_eq!(parse_backend(5, argv.as_mut_ptr()), "opengl");
|
||||
|
||||
// A missing value is ignored (the C++ only consumes it when
|
||||
@@ -999,14 +1007,16 @@ mod tests {
|
||||
let mut s = WorkerSession::create("none").unwrap();
|
||||
// A key that was never created.
|
||||
let resp = s
|
||||
.handle_line(&json!({
|
||||
"type": "handshake",
|
||||
"protocol_version": 1,
|
||||
"shm_key": format!("olive-rw-{}-missing", std::process::id()),
|
||||
"output_slots": 4,
|
||||
"slot_data_bytes": 4096,
|
||||
})
|
||||
.to_string())
|
||||
.handle_line(
|
||||
&json!({
|
||||
"type": "handshake",
|
||||
"protocol_version": 1,
|
||||
"shm_key": format!("olive-rw-{}-missing", std::process::id()),
|
||||
"output_slots": 4,
|
||||
"slot_data_bytes": 4096,
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(resp["type"], "error");
|
||||
assert!(resp["message"]
|
||||
@@ -1027,14 +1037,16 @@ mod tests {
|
||||
let mut region = SharedMemoryRegion::new();
|
||||
assert!(region.open(&key, bytes, ShmMode::Create));
|
||||
let resp = s
|
||||
.handle_line(&json!({
|
||||
"type": "handshake",
|
||||
"protocol_version": 1,
|
||||
"shm_key": key,
|
||||
"output_slots": 4,
|
||||
"slot_data_bytes": 4096,
|
||||
})
|
||||
.to_string())
|
||||
.handle_line(
|
||||
&json!({
|
||||
"type": "handshake",
|
||||
"protocol_version": 1,
|
||||
"shm_key": key,
|
||||
"output_slots": 4,
|
||||
"slot_data_bytes": 4096,
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resp["message"],
|
||||
@@ -1063,12 +1075,17 @@ mod tests {
|
||||
let resp = s
|
||||
.handle_line(&json!({ "type": "load_graph", "path": missing }).to_string())
|
||||
.unwrap();
|
||||
assert_eq!(resp["message"], format!("graph file does not exist: {missing}"));
|
||||
assert_eq!(
|
||||
resp["message"],
|
||||
format!("graph file does not exist: {missing}")
|
||||
);
|
||||
|
||||
let empty = std::env::temp_dir().join("oak_facade_worker_test_empty.ove");
|
||||
std::fs::write(&empty, b"").unwrap();
|
||||
let resp = s
|
||||
.handle_line(&json!({ "type": "load_graph", "path": empty.display().to_string() }).to_string())
|
||||
.handle_line(
|
||||
&json!({ "type": "load_graph", "path": empty.display().to_string() }).to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resp["message"],
|
||||
@@ -1079,7 +1096,9 @@ mod tests {
|
||||
let real = std::env::temp_dir().join("oak_facade_worker_test_graph.ove");
|
||||
std::fs::write(&real, b"<root/>").unwrap();
|
||||
let resp = s
|
||||
.handle_line(&json!({ "type": "load_graph", "path": real.display().to_string() }).to_string())
|
||||
.handle_line(
|
||||
&json!({ "type": "load_graph", "path": real.display().to_string() }).to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(resp["message"]
|
||||
.as_str()
|
||||
@@ -1113,9 +1132,12 @@ mod tests {
|
||||
let mut buf = [0 as c_char; 512];
|
||||
let n = unsafe { oakengine_worker_session_startup_handshake(s, buf.as_mut_ptr(), 512) };
|
||||
assert!(n > 0);
|
||||
let hs: Value =
|
||||
serde_json::from_str(unsafe { std::ffi::CStr::from_ptr(buf.as_ptr()) }.to_str().unwrap())
|
||||
.unwrap();
|
||||
let hs: Value = serde_json::from_str(
|
||||
unsafe { std::ffi::CStr::from_ptr(buf.as_ptr()) }
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(hs["type"], "handshake");
|
||||
assert_eq!(hs["protocol_version"], 1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user