@@ -8,7 +8,7 @@ use futures::FutureExt;
88use image:: ImageBuffer ;
99use serde:: Deserialize ;
1010use specta:: Type ;
11- use std:: { path:: PathBuf , time:: Duration } ;
11+ use std:: { path:: PathBuf , sync :: Arc , time:: Duration } ;
1212use tracing:: { info, trace, warn} ;
1313
1414#[ derive( Deserialize , Type , Clone , Copy , Debug ) ]
@@ -58,28 +58,16 @@ impl Mp4ExportSettings {
5858
5959 let fps = self . fps ;
6060
61- let raw_output_size = ProjectUniforms :: get_output_size (
61+ let output_size = ProjectUniforms :: get_output_size (
6262 & base. render_constants . options ,
6363 & base. project_config ,
6464 self . resolution_base ,
6565 ) ;
6666
67- let output_size = ( ( raw_output_size. 0 + 3 ) & !3 , ( raw_output_size. 1 + 1 ) & !1 ) ;
68-
69- if output_size != raw_output_size {
70- info ! (
71- raw_width = raw_output_size. 0 ,
72- raw_height = raw_output_size. 1 ,
73- aligned_width = output_size. 0 ,
74- aligned_height = output_size. 1 ,
75- "Aligned output dimensions for NV12 GPU path"
76- ) ;
77- }
78-
7967 info ! (
8068 width = output_size. 0 ,
8169 height = output_size. 1 ,
82- "Using GPU NV12 export path (reduced readback + no CPU swscale )"
70+ "Exporting with NV12 pipeline (GPU when possible, CPU fallback otherwise )"
8371 ) ;
8472 self . export_nv12 ( base, output_size, fps, on_progress) . await
8573 }
@@ -247,14 +235,16 @@ impl Mp4ExportSettings {
247235 return Err ( "Export cancelled" . to_string ( ) ) ;
248236 }
249237
238+ let frame_width = frame. width ;
239+ let frame_height = frame. height ;
250240 let nv12_data = ensure_nv12_data ( frame) ;
251241
252242 if frame_count == 0 {
253243 first_frame_data = Some ( FirstFrameNv12 {
254244 data : nv12_data. clone ( ) ,
255- width : output_size . 0 ,
256- height : output_size . 1 ,
257- y_stride : output_size . 0 ,
245+ width : frame_width ,
246+ height : frame_height ,
247+ y_stride : frame_width ,
258248 } ) ;
259249 if let Some ( audio) = & mut audio_renderer {
260250 audio. set_playhead ( 0.0 , & project) ;
@@ -280,9 +270,9 @@ impl Mp4ExportSettings {
280270 . send ( Nv12ExportFrame {
281271 audio : audio_frame,
282272 nv12_data,
283- width : output_size . 0 ,
284- height : output_size . 1 ,
285- y_stride : output_size . 0 ,
273+ width : frame_width ,
274+ height : frame_height ,
275+ y_stride : frame_width ,
286276 pts : frame_number as i64 ,
287277 } )
288278 . is_err ( )
@@ -349,26 +339,26 @@ impl Mp4ExportSettings {
349339}
350340
351341struct FirstFrameNv12 {
352- data : Vec < u8 > ,
342+ data : Arc < Vec < u8 > > ,
353343 width : u32 ,
354344 height : u32 ,
355345 y_stride : u32 ,
356346}
357347
358348struct Nv12ExportFrame {
359- nv12_data : Vec < u8 > ,
349+ nv12_data : Arc < Vec < u8 > > ,
360350 width : u32 ,
361351 height : u32 ,
362352 y_stride : u32 ,
363353 pts : i64 ,
364354 audio : Option < ffmpeg:: frame:: Audio > ,
365355}
366356
367- fn ensure_nv12_data ( frame : Nv12RenderedFrame ) -> Vec < u8 > {
357+ fn ensure_nv12_data ( frame : Nv12RenderedFrame ) -> Arc < Vec < u8 > > {
368358 use cap_rendering:: GpuOutputFormat ;
369359
370360 if frame. format != GpuOutputFormat :: Rgba {
371- return frame. into_data ( ) ;
361+ return frame. data ;
372362 }
373363
374364 tracing:: warn!(
@@ -429,15 +419,15 @@ fn ensure_nv12_data(frame: Nv12RenderedFrame) -> Vec<u8> {
429419 }
430420 }
431421
432- return result;
422+ return Arc :: new ( result) ;
433423 }
434424 }
435425
436426 tracing:: error!(
437427 frame_number = frame. frame_number,
438428 "swscale RGBA to NV12 conversion failed, using zeroed NV12"
439429 ) ;
440- vec ! [ 0u8 ; width as usize * height as usize * 3 / 2 ]
430+ Arc :: new ( vec ! [ 0u8 ; width as usize * height as usize * 3 / 2 ] )
441431}
442432
443433fn fill_nv12_frame ( frame : & mut ffmpeg:: frame:: Video , input : & Nv12ExportFrame ) {
@@ -577,7 +567,7 @@ mod tests {
577567 }
578568
579569 let input = Nv12ExportFrame {
580- nv12_data : nv12_data. clone ( ) ,
570+ nv12_data : Arc :: new ( nv12_data. clone ( ) ) ,
581571 width,
582572 height,
583573 y_stride : width,
@@ -613,7 +603,7 @@ mod tests {
613603
614604 let data = vec ! [ 1u8 , 2 , 3 , 4 , 5 , 6 ] ;
615605 let frame = Nv12RenderedFrame {
616- data : data. clone ( ) ,
606+ data : std :: sync :: Arc :: new ( data. clone ( ) ) ,
617607 width : 4 ,
618608 height : 2 ,
619609 y_stride : 4 ,
@@ -623,7 +613,7 @@ mod tests {
623613 } ;
624614
625615 let result = ensure_nv12_data ( frame) ;
626- assert_eq ! ( result, data) ;
616+ assert_eq ! ( * result, data) ;
627617 }
628618
629619 #[ test]
0 commit comments