diff --git a/src/state_portal.rs b/src/state_portal.rs index 21e28af..06ffd0d 100644 --- a/src/state_portal.rs +++ b/src/state_portal.rs @@ -188,19 +188,22 @@ impl StatePortal { (*hw_frame.as_mut_ptr()).pts = pts; } - // 8. Encode - enc.encode_frame(&hw_frame)?; - - // 9. Clean up: recover the Boxed descriptor from raw_frame to prevent leak. - // Video::drop calls av_frame_free which does NOT free data[0]. + // 8. Recover the Boxed descriptor from raw_frame *before* encoding. + // av_hwframe_transfer_data has already imported the DMA-BUF into the + // VAAPI surface, so FFmpeg no longer references the descriptor struct. + // Doing this before encode_frame ensures the descriptor is reclaimed + // even if encode_frame returns early via `?`. unsafe { let desc_ptr = (*raw_frame.as_ptr()).data[0] as *mut ffi::AVDRMFrameDescriptor; if !desc_ptr.is_null() { let _ = Box::from_raw(desc_ptr); } } - // raw_frame and hw_frame drop here via Video::drop → av_frame_free + // 9. Encode — safe to early-return via `?` now that descriptor is recovered. + enc.encode_frame(&hw_frame)?; + + // raw_frame and hw_frame drop here via Video::drop → av_frame_free Ok(()) }