@@ -167,7 +167,7 @@ pub fn vapoursynth_plugin(_args: TokenStream, input: TokenStream) -> TokenStream
167167#[ proc_macro_attribute]
168168pub fn vapoursynth_filter ( arg : TokenStream , input : TokenStream ) -> TokenStream {
169169 let input = parse_macro_input ! ( input as DeriveInput ) ;
170- match generate_vs_filter ( input, arg) {
170+ match generate_vs_filter ( input, arg) {
171171 Ok ( tokens) => tokens. into ( ) ,
172172 Err ( err) => err. to_compile_error ( ) . into ( ) ,
173173 }
@@ -201,11 +201,11 @@ fn generate_vs_plugin(input: ItemMod) -> syn::Result<proc_macro2::TokenStream> {
201201
202202 api. configPlugin. expect( "configPlugin is null" ) (
203203 identifier. as_ptr( ) ,
204- namespace. as_ptr( ) ,
204+ namespace. as_ptr( ) ,
205205 name. as_ptr( ) ,
206- plugin_version,
207- api_version,
208- flags,
206+ plugin_version,
207+ api_version,
208+ flags,
209209 plugin
210210 ) ;
211211 // Register all filters in this plugin
@@ -216,7 +216,10 @@ fn generate_vs_plugin(input: ItemMod) -> syn::Result<proc_macro2::TokenStream> {
216216 Ok ( expanded)
217217}
218218
219- fn generate_vs_filter ( input : DeriveInput , arg : TokenStream ) -> syn:: Result < proc_macro2:: TokenStream > {
219+ fn generate_vs_filter (
220+ input : DeriveInput ,
221+ arg : TokenStream ,
222+ ) -> syn:: Result < proc_macro2:: TokenStream > {
220223 let struct_name = & input. ident ;
221224
222225 // Generate unique C function names based on struct name
@@ -229,136 +232,144 @@ fn generate_vs_filter(input: DeriveInput, arg: TokenStream) -> syn::Result<proc_
229232 let free_ident = syn:: Ident :: new ( & free_name, struct_name. span ( ) ) ;
230233
231234 let create = match arg. to_string ( ) . as_str ( ) {
232- "video" => { quote ! {
233- // Filter creation function - the real workhorse
234- #[ no_mangle]
235- pub unsafe extern "C" fn #create_ident(
236- in_: * const rustsynth:: ffi:: VSMap ,
237- out: * mut rustsynth:: ffi:: VSMap ,
238- user_data: * mut std:: os:: raw:: c_void,
239- core: * mut rustsynth:: ffi:: VSCore ,
240- vsapi: * const rustsynth:: ffi:: VSAPI ,
241- ) {
242- rustsynth:: init_api( vsapi) ;
243- let api = & * vsapi;
244- let core_ref = rustsynth:: core:: CoreRef :: from_ptr( core) ;
245- let in_map = rustsynth:: map:: Map :: from_ptr( in_) ;
246- // Create filter instance from arguments
247- match #struct_name:: from_args( & in_map, & core_ref) {
248- Ok ( filter_data) => {
249- let deps = filter_data. get_dependencies( ) ;
250- let deps_ffi: Vec <rustsynth:: ffi:: VSFilterDependency > = deps. iter( )
251- . map( |d| d. as_ffi( ) )
252- . collect( ) ;
253-
254- // Get filter mode from const
255- let filter_mode = #struct_name:: MODE ;
256- let media_info = match filter_data. get_video_info( ) {
257- Ok ( ai) => ai,
258- Err ( error_msg) => {
259- let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
260- std:: ffi:: CString :: new( "Failed to video info" ) . unwrap( )
261- } ) ;
262- api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
263- return ;
264- }
265- } ;
266-
267- // Allocate filter data on heap
268- let data_ptr = Box :: into_raw( Box :: new( filter_data) ) as * mut std:: os:: raw:: c_void;
269-
270- let filter_name = std:: ffi:: CString :: new( #struct_name:: NAME ) . unwrap( ) ;
271- api. createVideoFilter. unwrap( ) (
272- out,
273- filter_name. as_ptr( ) ,
274- & media_info. as_ptr( ) as * const rustsynth:: ffi:: VSVideoInfo ,
275- Some ( #getframe_ident) ,
276- Some ( #free_ident) ,
277- filter_mode. as_ptr( ) as i32 ,
278- deps_ffi. as_ptr( ) ,
279- deps_ffi. len( ) as i32 ,
280- data_ptr,
281- core,
282- ) ;
283-
284- } ,
285- Err ( error_msg) => {
286- eprintln!( "{}" , error_msg) ;
235+ "video" => {
236+ quote ! {
237+ // Filter creation function - the real workhorse
238+ #[ no_mangle]
239+ pub unsafe extern "C" fn #create_ident(
240+ in_: * const rustsynth:: ffi:: VSMap ,
241+ out: * mut rustsynth:: ffi:: VSMap ,
242+ user_data: * mut std:: os:: raw:: c_void,
243+ core: * mut rustsynth:: ffi:: VSCore ,
244+ vsapi: * const rustsynth:: ffi:: VSAPI ,
245+ ) {
246+ rustsynth:: init_api( vsapi) ;
247+ let api = & * vsapi;
248+ let core_ref = rustsynth:: core:: CoreRef :: from_ptr( core) ;
249+ let in_map = rustsynth:: map:: Map :: from_ptr( in_) ;
250+ // Create filter instance from arguments
251+ match #struct_name:: from_args( & in_map, & core_ref) {
252+ Ok ( filter_data) => {
253+ let deps = filter_data. get_dependencies( ) ;
254+ let deps_ffi: Vec <rustsynth:: ffi:: VSFilterDependency > = deps. iter( )
255+ . map( |d| d. as_ffi( ) )
256+ . collect( ) ;
257+
258+ // Get filter mode from const
259+ let filter_mode = #struct_name:: MODE ;
260+ let media_info = match filter_data. get_video_info( ) {
261+ Ok ( ai) => ai,
262+ Err ( error_msg) => {
263+ let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
264+ std:: ffi:: CString :: new( "Failed to video info" ) . unwrap( )
265+ } ) ;
266+ api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
267+ return ;
268+ }
269+ } ;
270+
271+ // Allocate filter data on heap
272+ let data_ptr = Box :: into_raw( Box :: new( filter_data) ) as * mut std:: os:: raw:: c_void;
273+
274+ let filter_name = std:: ffi:: CString :: new( #struct_name:: NAME ) . unwrap( ) ;
275+ api. createVideoFilter. unwrap( ) (
276+ out,
277+ filter_name. as_ptr( ) ,
278+ & media_info. as_ptr( ) as * const rustsynth:: ffi:: VSVideoInfo ,
279+ Some ( #getframe_ident) ,
280+ Some ( #free_ident) ,
281+ filter_mode. as_ptr( ) as i32 ,
282+ deps_ffi. as_ptr( ) ,
283+ deps_ffi. len( ) as i32 ,
284+ data_ptr,
285+ core,
286+ ) ;
287+
288+ } ,
289+ Err ( error_msg) => {
290+ eprintln!( "{}" , error_msg) ;
291+ }
287292 }
288- }
293+ }
294+ }
289295 }
290- } } ,
291- "audio" => { quote ! {
292- // Filter creation function - the real workhorse
293- #[ no_mangle]
294- pub unsafe extern "C" fn #create_ident(
295- in_: * const rustsynth:: ffi:: VSMap ,
296- out: * mut rustsynth:: ffi:: VSMap ,
297- user_data: * mut std:: os:: raw:: c_void,
298- core: * mut rustsynth:: ffi:: VSCore ,
299- vsapi: * const rustsynth:: ffi:: VSAPI ,
300- ) {
301- let api = & * vsapi;
302- rustsynth:: init_api( vsapi) ;
303- std:: panic:: catch_unwind( || {
304- // Create rustsynth wrapper objects
305- let core_ref = rustsynth:: core:: CoreRef :: from_ptr( core) ;
306- let in_map = rustsynth:: map:: Map :: from_ptr( in_) ;
307-
308- // Create filter instance from arguments
309- match #struct_name:: from_args( & in_map, & core_ref) {
310- Ok ( filter_data) => {
311- let deps = filter_data. get_dependencies( ) ;
312- let deps_ffi: Vec <rustsynth:: ffi:: VSFilterDependency > = deps. iter( )
313- . map( |d| d. as_ffi( ) )
314- . collect( ) ;
315-
316- // Get filter mode from const
317- let filter_mode = #struct_name:: MODE ;
318- let media_info = match filter_data. get_audio_info( ) {
319- Ok ( ai) => ai,
320- Err ( error_msg) => {
321- let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
322- std:: ffi:: CString :: new( "Failed to get audio info" ) . unwrap( )
323- } ) ;
324- api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
325- return ;
326- }
327- } ;
328- // Allocate filter data on heap
329- let data_ptr = Box :: into_raw( Box :: new( filter_data) ) as * mut std:: os:: raw:: c_void;
330-
331-
332- let filter_name = std:: ffi:: CString :: new( #struct_name:: NAME ) . unwrap( ) ;
333- api. createAudioFilter. unwrap( ) (
334- out,
335- filter_name. as_ptr( ) ,
336- & media_info,
337- Some ( #getframe_ident) ,
338- Some ( #free_ident) ,
339- * filter_mode. as_ptr( ) ,
340- deps_ffi. as_ptr( ) ,
341- deps_ffi. len( ) as i32 ,
342- data_ptr,
343- core,
344- ) ;
345- } ,
346- Err ( error_msg) => {
347- let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
348- std:: ffi:: CString :: new( "Filter creation failed" ) . unwrap( )
349- } ) ;
350- api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
296+ "audio" => {
297+ quote ! {
298+ // Filter creation function - the real workhorse
299+ #[ no_mangle]
300+ pub unsafe extern "C" fn #create_ident(
301+ in_: * const rustsynth:: ffi:: VSMap ,
302+ out: * mut rustsynth:: ffi:: VSMap ,
303+ user_data: * mut std:: os:: raw:: c_void,
304+ core: * mut rustsynth:: ffi:: VSCore ,
305+ vsapi: * const rustsynth:: ffi:: VSAPI ,
306+ ) {
307+ let api = & * vsapi;
308+ rustsynth:: init_api( vsapi) ;
309+ std:: panic:: catch_unwind( || {
310+ // Create rustsynth wrapper objects
311+ let core_ref = rustsynth:: core:: CoreRef :: from_ptr( core) ;
312+ let in_map = rustsynth:: map:: Map :: from_ptr( in_) ;
313+
314+ // Create filter instance from arguments
315+ match #struct_name:: from_args( & in_map, & core_ref) {
316+ Ok ( filter_data) => {
317+ let deps = filter_data. get_dependencies( ) ;
318+ let deps_ffi: Vec <rustsynth:: ffi:: VSFilterDependency > = deps. iter( )
319+ . map( |d| d. as_ffi( ) )
320+ . collect( ) ;
321+
322+ // Get filter mode from const
323+ let filter_mode = #struct_name:: MODE ;
324+ let media_info = match filter_data. get_audio_info( ) {
325+ Ok ( ai) => ai,
326+ Err ( error_msg) => {
327+ let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
328+ std:: ffi:: CString :: new( "Failed to get audio info" ) . unwrap( )
329+ } ) ;
330+ api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
331+ return ;
332+ }
333+ } ;
334+ // Allocate filter data on heap
335+ let data_ptr = Box :: into_raw( Box :: new( filter_data) ) as * mut std:: os:: raw:: c_void;
336+
337+
338+ let filter_name = std:: ffi:: CString :: new( #struct_name:: NAME ) . unwrap( ) ;
339+ api. createAudioFilter. unwrap( ) (
340+ out,
341+ filter_name. as_ptr( ) ,
342+ & media_info,
343+ Some ( #getframe_ident) ,
344+ Some ( #free_ident) ,
345+ * filter_mode. as_ptr( ) ,
346+ deps_ffi. as_ptr( ) ,
347+ deps_ffi. len( ) as i32 ,
348+ data_ptr,
349+ core,
350+ ) ;
351+ } ,
352+ Err ( error_msg) => {
353+ let error_cstr = std:: ffi:: CString :: new( error_msg) . unwrap_or_else( |_| {
354+ std:: ffi:: CString :: new( "Filter creation failed" ) . unwrap( )
355+ } ) ;
356+ api. mapSetError. unwrap( ) ( out, error_cstr. as_ptr( ) ) ;
357+ }
351358 }
352- }
353- } ) . unwrap_or_else( |_| {
354- api. mapSetError. unwrap( ) ( out, b"Filter creation panicked\0 " . as_ptr( ) as * const std:: os:: raw:: c_char) ;
355- } ) ;
359+ } ) . unwrap_or_else( |_| {
360+ api. mapSetError. unwrap( ) ( out, b"Filter creation panicked\0 " . as_ptr( ) as * const std:: os:: raw:: c_char) ;
361+ } ) ;
362+ }
363+ }
364+ }
365+ _ => {
366+ return Err ( syn:: Error :: new_spanned (
367+ & arg. to_string ( ) ,
368+ "Unsupported filter type. Use 'video' or 'audio'" ,
369+ ) )
356370 }
357- } }
358- _ => return Err ( syn:: Error :: new_spanned ( & arg. to_string ( ) , "Unsupported filter type. Use 'video' or 'audio'" ) )
359371 } ;
360372
361-
362373 let expanded = quote ! {
363374 // Original struct definition
364375 #input
0 commit comments