// Oak Video Editor - Non-Linear Video Editor // Copyright (C) 2026 Oak Team // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Oak Video Editor - Non-Linear Video Editor // Copyright (C) 2026 Oak Team // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //! oakrender C ABI imports. The task module reaches the render side through //! `include/render/cancelatom.h` (task cancellation), `include/render/ticket.h` //! (frame/audio render tickets), `include/render/copier.h` (export project //! copy) and `include/render/color.h` (color processor). Signatures mirror //! the headers verbatim. //! //! Resolution is at link time (the crate's existing pattern, see //! `bridge/codec.rs`): the symbols are satisfied by the real `liboakrender` //! when it is linked into the same binary (the app links the module dylibs; //! the `real-oakrender` integration test links the oakrender crate directly), //! and by the `#[no_mangle]` stubs in `tests/common/mod.rs` in plain //! `cargo test`. The real-oakrender ticket contract — in particular the //! 2-argument `oakrender_ticket_finished_fn` — is verified by //! `tests/render_real_integration_test.rs` against the actual exports. use std::ffi::{c_char, c_int, c_void}; use crate::bridge::codec::OakFrame; use crate::bridge::common::{OakAudioParams, OakColorTransform, OakVideoParams}; use crate::bridge::node::{OakNodeColorManager, OakNodeNode, OakNodeProject}; use crate::handle::CHandle; /// Mirror of `OakCancelAtom` (`include/render/cancelatom.h`). pub type OakCancelAtom = oakrender::ffi::OakCancelAtom; /// Mirror of `OakRenderTicket` (`include/render/ticket.h`). pub type OakRenderTicket = oakrender::ffi::OakRenderTicket; /// Mirror of `OakRenderCache` (`include/render/cache.h`). pub type OakRenderCache = oakrender::ffi::OakRenderCache; /// Mirror of `OakRenderProjectCopier` (`include/render/copier.h`). pub type OakRenderProjectCopier = oakrender::ffi::OakRenderProjectCopier; /// Mirror of `OakColorProcessor` (`include/render/color.h`). pub type OakColorProcessor = oakrender::ffi::OakColorProcessor; /// Mirror of `oakrender_ticket_finished_fn` (`include/render/ticket.h`). /// /// Two arguments — `(ticket, userdata)` — mirroring the header verbatim and /// matching the oakrender implementation (`src/render/rust/src/ffi.rs`). /// The ticket is a borrowed copy of the submitter's handle (the submitter /// keeps ownership and releases it); cancelled tickets fire with a NULL /// result observed through `oakrender_ticket_get_frame`. pub type OakRenderTicketFinishedFn = unsafe extern "C" fn(ticket: OakRenderTicket, userdata: *mut c_void); /// Mirror of `oakrender_video_ticket_params` (`include/render/ticket.h`). pub type OakRenderVideoTicketParams = oakrender::ffi::OakVideoTicketParams; /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cancelatom_init() -> OakCancelAtom { unsafe { oakrender::ffi::cancelatom::oakrender_cancelatom_init() } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cancelatom_free(atom: *mut OakCancelAtom) { unsafe { oakrender::ffi::cancelatom::oakrender_cancelatom_free(atom) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cancelatom_cancel(atom: OakCancelAtom) -> c_int { unsafe { oakrender::ffi::cancelatom::oakrender_cancelatom_cancel(atom) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cancelatom_is_cancelled(atom: OakCancelAtom, cancelled: *mut c_int) -> c_int { unsafe { oakrender::ffi::cancelatom::oakrender_cancelatom_is_cancelled(atom, cancelled) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cancelatom_heard_cancel(atom: OakCancelAtom, heard: *mut c_int) -> c_int { unsafe { oakrender::ffi::cancelatom::oakrender_cancelatom_heard_cancel(atom, heard) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_render_frame( params: *const OakRenderVideoTicketParams, cb: Option, userdata: *mut c_void, ) -> OakRenderTicket { unsafe { oakrender::ffi::ticket::oakrender_ticket_render_frame(params, cb, userdata) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_render_audio( output_node: OakNodeNode, in_num: i64, in_den: i64, out_num: i64, out_den: i64, params: *const OakAudioParams, mode: c_int, cb: Option, userdata: *mut c_void, ) -> OakRenderTicket { unsafe { oakrender::ffi::ticket::oakrender_ticket_render_audio(output_node, in_num, in_den, out_num, out_den, params, mode, cb, userdata) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_is_finished(ticket: OakRenderTicket) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_is_finished(ticket) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_wait(ticket: OakRenderTicket) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_wait(ticket) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_cancel(ticket: OakRenderTicket) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_cancel(ticket) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_get_type(ticket: OakRenderTicket) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_get_type(ticket) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_get_frame(ticket: OakRenderTicket, out: *mut OakFrame) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_get_frame(ticket, out) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_get_time(ticket: OakRenderTicket, out_num: *mut i64, out_den: *mut i64) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_get_time(ticket, out_num, out_den) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_get_range( ticket: OakRenderTicket, in_num: *mut i64, in_den: *mut i64, out_num: *mut i64, out_den: *mut i64, ) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_get_range(ticket, in_num, in_den, out_num, out_den) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_get_samples(ticket: OakRenderTicket, out: *mut *mut std::ffi::c_void) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_ticket_get_samples(ticket, out) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_ticket_free(ticket: *mut OakRenderTicket) { unsafe { oakrender::ffi::ticket::oakrender_ticket_free(ticket) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_project_copier_create() -> OakRenderProjectCopier { unsafe { oakrender::ffi::copier::oakrender_project_copier_create() } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_project_copier_free(copier: *mut OakRenderProjectCopier) { unsafe { oakrender::ffi::copier::oakrender_project_copier_free(copier) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_project_copier_set_project( copier: OakRenderProjectCopier, project: OakNodeProject, ) -> c_int { unsafe { oakrender::ffi::copier::oakrender_project_copier_set_project(copier, project) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_project_copier_get_copy( copier: OakRenderProjectCopier, original: OakNodeNode, ) -> OakNodeNode { unsafe { oakrender::ffi::copier::oakrender_project_copier_get_copy(copier, original) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_project_copier_get_copied_project( copier: OakRenderProjectCopier, ) -> OakNodeProject { unsafe { oakrender::ffi::copier::oakrender_project_copier_get_copied_project(copier) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_color_processor_create( src_space: *const c_char, dst_transform: *const c_char, direction: c_int, ) -> OakColorProcessor { unsafe { oakrender::ffi::color::oakrender_color_processor_create(src_space, dst_transform, direction) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_color_processor_free(processor: *mut OakColorProcessor) { unsafe { oakrender::ffi::color::oakrender_color_processor_free(processor) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_color_processor_is_valid(processor: OakColorProcessor) -> c_int { unsafe { oakrender::ffi::color::oakrender_color_processor_is_valid(processor) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_codec_frame_free(frame: *mut crate::bridge::codec::OakFrame) { unsafe { oakrender::ffi::renderer::oakrender_codec_frame_free(frame) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_manager_set_aggressive_gc(enabled: c_int) -> c_int { unsafe { oakrender::ffi::ticket::oakrender_manager_set_aggressive_gc(enabled) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cache_get_invalidated_ranges( cache: OakRenderCache, in_num: i64, in_den: i64, out_num: i64, out_den: i64, flat: *mut i64, flat_size: c_int, ) -> c_int { unsafe { oakrender::ffi::cache::oakrender_cache_get_invalidated_ranges(cache, in_num, in_den, out_num, out_den, flat, flat_size) } } /// Direct call into the `oakrender` crate (single-lib unification). pub fn oakrender_cache_free(cache: *mut OakRenderCache) { unsafe { oakrender::ffi::cache::oakrender_cache_free(cache) } }