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:
2026-08-11 23:04:48 +08:00
parent a209f63d52
commit 18ff60f147
351 changed files with 32880 additions and 15939 deletions
+10 -11
View File
@@ -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);
+138 -70
View File
@@ -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,
)
}
}
+37 -28
View File
@@ -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) }
}
+294 -144
View File
@@ -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)
}
}
+3 -3
View File
@@ -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;
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -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) }
}
+54 -39
View File
@@ -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) }
}
+49 -15
View File
@@ -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) }
}
+246 -132
View File
@@ -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,
)
}
}
+14 -24
View File
@@ -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) }
}
+70 -20
View File
@@ -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
}
+33 -16
View File
@@ -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
View File
@@ -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);
+10 -2
View File
@@ -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
View File
@@ -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, &params);
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 {
+14 -4
View File
@@ -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(())
})
}
+31 -14
View File
@@ -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() {
+33 -16
View File
@@ -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
View File
@@ -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")
})
}
+20 -7
View File
@@ -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)
})
}
+78 -56
View File
@@ -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);