vapoursynth4_rs/node/
internal.rs
1use std::{
2 ffi::{c_int, c_void},
3 mem::ManuallyDrop,
4 panic::AssertUnwindSafe,
5 ptr::null,
6};
7
8use crate::{
9 api::Api,
10 core::CoreRef,
11 frame::{Frame, FrameContext},
12 map::MapRef,
13 utils::ToCString,
14};
15
16use super::{Filter, ffi};
17
18pub trait FilterExtern: Filter {
19 unsafe extern "system-unwind" fn filter_create(
20 in_: *const ffi::VSMap,
21 out: *mut ffi::VSMap,
22 user_data: *mut c_void,
23 core: *mut ffi::VSCore,
24 vsapi: *const ffi::VSAPI,
25 ) {
26 unsafe {
27 let api = Api::from_ptr(vsapi);
28
29 let input = MapRef::from_ptr(in_, api);
30 let mut output = MapRef::from_ptr(out, api);
31 let core = CoreRef::from_ptr(core, api);
32 let data = if user_data.is_null() {
33 None
34 } else {
35 Some(Box::from_raw(user_data.cast()))
36 };
37
38 match std::panic::catch_unwind(AssertUnwindSafe(|| {
39 Self::create(input, output, data, core)
40 })) {
41 Ok(Err(e)) => {
42 output.set_error(e.as_ref());
43 }
44 Err(p) => {
45 let e = p.downcast::<&str>().unwrap_unchecked();
46 output.set_error(&e.into_cstring_lossy());
47 }
48 _ => {}
49 }
50 }
51 }
52
53 unsafe extern "system-unwind" fn filter_get_frame(
54 n: c_int,
55 activation_reason: ffi::VSActivationReason,
56 instance_data: *mut c_void,
57 frame_data: *mut *mut c_void,
58 frame_ctx: *mut ffi::VSFrameContext,
59 core: *mut ffi::VSCore,
60 vsapi: *const ffi::VSAPI,
61 ) -> *const ffi::VSFrame {
62 unsafe {
63 let api = Api::from_ptr(vsapi);
64 let filter = instance_data.cast::<Self>().as_mut().unwrap_unchecked();
65 let mut ctx = AssertUnwindSafe(FrameContext::from_ptr(frame_ctx, api));
66 let core = CoreRef::from_ptr(core, api);
67
68 let frame = std::panic::catch_unwind(|| {
69 filter.get_frame(n, activation_reason, frame_data, *ctx, core)
70 });
71 match frame {
72 Ok(Ok(Some(frame))) => {
73 let frame = ManuallyDrop::new(frame);
75 return frame.as_ptr();
76 }
77 Ok(Err(e)) => {
78 ctx.set_filter_error(e.as_ref());
79 }
80 Err(p) => {
81 let e = p.downcast::<&str>().unwrap_unchecked();
82 ctx.set_filter_error(&e.into_cstring_lossy());
83 }
84 _ => {}
85 }
86 }
87
88 null()
89 }
90
91 unsafe extern "system-unwind" fn filter_free(
92 instance_data: *mut c_void,
93 core: *mut ffi::VSCore,
94 vsapi: *const ffi::VSAPI,
95 ) {
96 unsafe {
97 let api = Api::from_ptr(vsapi);
98 let filter = Box::from_raw(instance_data.cast::<Self>());
99 let core = CoreRef::from_ptr(core, api);
100
101 filter.free(core);
102 }
103 }
104}
105
106impl<F> FilterExtern for F where F: Filter {}