diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2023-10-18 19:04:45 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2023-11-13 11:29:25 +0300 |
commit | 99d7cce0d6ca3ed2142ddb269039d7e34c812f81 (patch) | |
tree | df4573df73971acb935fdaa860dd726062f46e5f /net | |
parent | eb137ec6dc842d61acf4d903275942b49bfcf479 (diff) |
ndi: Refactor frame structs to have static lifetimes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1365>
Diffstat (limited to 'net')
-rw-r--r-- | net/ndi/src/ndi.rs | 392 | ||||
-rw-r--r-- | net/ndi/src/ndisink/imp.rs | 16 |
2 files changed, 214 insertions, 194 deletions
diff --git a/net/ndi/src/ndi.rs b/net/ndi/src/ndi.rs index b06ed41b2..fa0131fa3 100644 --- a/net/ndi/src/ndi.rs +++ b/net/ndi/src/ndi.rs @@ -6,6 +6,7 @@ use std::ffi; use std::fmt; use std::mem; use std::ptr; +use std::sync::Arc; use byte_slice_cast::*; @@ -247,14 +248,32 @@ impl<'a> RecvBuilder<'a> { if ptr.is_null() { None } else { - Some(RecvInstance(ptr::NonNull::new_unchecked(ptr))) + #[allow(clippy::arc_with_non_send_sync)] + Some(RecvInstance(Arc::new(RecvInstancePtr( + ptr::NonNull::new_unchecked(ptr), + )))) } } } } +#[derive(Debug, Clone)] +struct RecvInstancePtr(ptr::NonNull<::std::os::raw::c_void>); + +impl Drop for RecvInstancePtr { + fn drop(&mut self) { + unsafe { NDIlib_recv_destroy(self.0.as_ptr() as *mut _) } + } +} + +impl RecvInstancePtr { + fn as_ptr(&self) -> *mut ::std::os::raw::c_void { + self.0.as_ptr() + } +} + #[derive(Debug)] -pub struct RecvInstance(ptr::NonNull<::std::os::raw::c_void>); +pub struct RecvInstance(Arc<RecvInstancePtr>); unsafe impl Send for RecvInstance {} @@ -318,15 +337,17 @@ impl RecvInstance { ); match res { - NDIlib_frame_type_e::NDIlib_frame_type_audio => Ok(Some(Frame::Audio( - AudioFrame::BorrowedRecv(audio_frame, self), - ))), - NDIlib_frame_type_e::NDIlib_frame_type_video => Ok(Some(Frame::Video( - VideoFrame::BorrowedRecv(video_frame, self), - ))), - NDIlib_frame_type_e::NDIlib_frame_type_metadata => Ok(Some(Frame::Metadata( - MetadataFrame::Borrowed(metadata_frame, self), - ))), + NDIlib_frame_type_e::NDIlib_frame_type_audio => Ok(Some(Frame::Audio(AudioFrame( + AudioFrameInner::BorrowedRecv(audio_frame, Arc::clone(&self.0)), + )))), + NDIlib_frame_type_e::NDIlib_frame_type_video => Ok(Some(Frame::Video(VideoFrame( + VideoFrameInner::BorrowedRecv(video_frame, Arc::clone(&self.0)), + )))), + NDIlib_frame_type_e::NDIlib_frame_type_metadata => { + Ok(Some(Frame::Metadata(MetadataFrame( + MetadataFrameInner::Borrowed(metadata_frame, Arc::clone(&self.0)), + )))) + } NDIlib_frame_type_e::NDIlib_frame_type_error => Err(ReceiveError), _ => Ok(None), } @@ -334,12 +355,6 @@ impl RecvInstance { } } -impl Drop for RecvInstance { - fn drop(&mut self) { - unsafe { NDIlib_recv_destroy(self.0.as_ptr() as *mut _) } - } -} - #[derive(Debug)] pub struct SendBuilder<'a> { ndi_name: &'a str, @@ -420,7 +435,6 @@ impl Drop for SendInstance { #[derive(Debug)] pub struct Tally(NDIlib_tally_t); -unsafe impl Send for Tally {} impl Default for Tally { fn default() -> Self { @@ -449,23 +463,40 @@ impl Tally { } #[derive(Debug)] -pub enum Frame<'a> { - Video(VideoFrame<'a>), - Audio(AudioFrame<'a>), - Metadata(MetadataFrame<'a>), +pub enum Frame { + Video(VideoFrame), + Audio(AudioFrame), + Metadata(MetadataFrame), } #[derive(Debug)] -pub enum VideoFrame<'a> { +pub struct VideoFrame(VideoFrameInner); + +#[derive(Debug)] +enum VideoFrameInner { //Owned(NDIlib_video_frame_v2_t, Option<ffi::CString>, Option<Vec<u8>>), - BorrowedRecv(NDIlib_video_frame_v2_t, &'a RecvInstance), + BorrowedRecv(NDIlib_video_frame_v2_t, Arc<RecvInstancePtr>), BorrowedGst( NDIlib_video_frame_v2_t, - &'a gst_video::VideoFrameRef<&'a gst::BufferRef>, - Option<&'a std::ffi::CStr>, + gst_video::VideoFrame<gst_video::video_frame::Readable>, + Option<std::ffi::CString>, ), } +impl Drop for VideoFrameInner { + #[allow(irrefutable_let_patterns)] + fn drop(&mut self) { + if let VideoFrameInner::BorrowedRecv(ref mut frame, ref recv) = *self { + unsafe { + NDIlib_recv_free_video_v2(recv.0.as_ptr() as *mut _, frame); + } + } + } +} + +unsafe impl Send for VideoFrameInner {} +unsafe impl Sync for VideoFrameInner {} + #[derive(Debug, Copy, Clone)] pub struct TryFromVideoFrameError; @@ -477,60 +508,55 @@ impl fmt::Display for TryFromVideoFrameError { impl std::error::Error for TryFromVideoFrameError {} -impl<'a> VideoFrame<'a> { +impl VideoFrame { pub fn xres(&self) -> i32 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.xres - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.xres, } } pub fn yres(&self) -> i32 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.yres - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.yres, } } pub fn fourcc(&self) -> NDIlib_FourCC_video_type_e { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.FourCC - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.FourCC, } } pub fn frame_rate(&self) -> (i32, i32) { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => { (frame.frame_rate_N, frame.frame_rate_D) } } } pub fn picture_aspect_ratio(&self) -> f32 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.picture_aspect_ratio - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.picture_aspect_ratio, } } pub fn frame_format_type(&self) -> NDIlib_frame_format_type_e { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.frame_format_type - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.frame_format_type, } } pub fn timecode(&self) -> i64 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.timecode - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.timecode, } } @@ -566,9 +592,9 @@ impl<'a> VideoFrame<'a> { return unsafe { use std::slice; - match self { - VideoFrame::BorrowedRecv(ref frame, ..) - | VideoFrame::BorrowedGst(ref frame, ..) => Some(slice::from_raw_parts( + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, ..) + | VideoFrameInner::BorrowedGst(ref frame, ..) => Some(slice::from_raw_parts( frame.p_data as *const u8, frame_size as usize, )), @@ -589,9 +615,9 @@ impl<'a> VideoFrame<'a> { { return unsafe { use std::slice; - match self { - VideoFrame::BorrowedRecv(ref frame, ..) - | VideoFrame::BorrowedGst(ref frame, ..) => Some(slice::from_raw_parts( + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, ..) + | VideoFrameInner::BorrowedGst(ref frame, ..) => Some(slice::from_raw_parts( frame.p_data as *const u8, frame.line_stride_or_data_size_in_bytes as usize, )), @@ -626,9 +652,9 @@ impl<'a> VideoFrame<'a> { return None; } - let data = match self { - VideoFrame::BorrowedRecv(ref frame, ..) - | VideoFrame::BorrowedGst(ref frame, ..) => slice::from_raw_parts( + let data = match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, ..) + | VideoFrameInner::BorrowedGst(ref frame, ..) => slice::from_raw_parts( frame.p_data as *const u8, frame.line_stride_or_data_size_in_bytes as usize, ), @@ -675,8 +701,9 @@ impl<'a> VideoFrame<'a> { } pub fn line_stride_or_data_size_in_bytes(&self) -> i32 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => { let stride = frame.line_stride_or_data_size_in_bytes; if stride != 0 { @@ -705,8 +732,9 @@ impl<'a> VideoFrame<'a> { pub fn metadata(&self) -> Option<&str> { unsafe { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => { if frame.p_metadata.is_null() { None } else { @@ -718,24 +746,22 @@ impl<'a> VideoFrame<'a> { } pub fn timestamp(&self) -> i64 { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame.timestamp - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame.timestamp, } } pub fn as_ptr(&self) -> *const NDIlib_video_frame_v2_t { - match self { - VideoFrame::BorrowedRecv(ref frame, _) | VideoFrame::BorrowedGst(ref frame, ..) => { - frame - } + match self.0 { + VideoFrameInner::BorrowedRecv(ref frame, _) + | VideoFrameInner::BorrowedGst(ref frame, ..) => frame, } } pub fn try_from_video_frame( - frame: &'a gst_video::VideoFrameRef<&'a gst::BufferRef>, - metadata: Option<&'a std::ffi::CStr>, + frame: gst_video::VideoFrame<gst_video::video_frame::Readable>, + metadata: Option<std::ffi::CString>, timecode: i64, ) -> Result<Self, TryFromVideoFrameError> { // Planar formats must be in contiguous memory @@ -841,35 +867,43 @@ impl<'a> VideoFrame<'a> { timecode, p_data: frame.plane_data(0).unwrap().as_ptr() as *const ::std::os::raw::c_char, line_stride_or_data_size_in_bytes: frame.plane_stride()[0], - p_metadata: metadata.map_or(ptr::null(), |meta| meta.as_ptr()), + p_metadata: metadata.as_ref().map_or(ptr::null(), |meta| meta.as_ptr()), timestamp: 0, }; - Ok(VideoFrame::BorrowedGst(ndi_frame, frame, metadata)) + Ok(VideoFrame(VideoFrameInner::BorrowedGst( + ndi_frame, frame, metadata, + ))) } } -impl<'a> Drop for VideoFrame<'a> { - #[allow(irrefutable_let_patterns)] - fn drop(&mut self) { - if let VideoFrame::BorrowedRecv(ref mut frame, recv) = *self { - unsafe { - NDIlib_recv_free_video_v2(recv.0.as_ptr() as *mut _, frame); - } - } - } -} +#[derive(Debug)] +pub struct AudioFrame(AudioFrameInner); #[derive(Debug)] -pub enum AudioFrame<'a> { +enum AudioFrameInner { Owned( NDIlib_audio_frame_v3_t, Option<ffi::CString>, Option<Vec<f32>>, ), - BorrowedRecv(NDIlib_audio_frame_v3_t, &'a RecvInstance), + BorrowedRecv(NDIlib_audio_frame_v3_t, Arc<RecvInstancePtr>), +} + +impl Drop for AudioFrameInner { + #[allow(irrefutable_let_patterns)] + fn drop(&mut self) { + if let AudioFrameInner::BorrowedRecv(ref mut frame, ref recv) = *self { + unsafe { + NDIlib_recv_free_audio_v3(recv.0.as_ptr() as *mut _, frame); + } + } + } } +unsafe impl Send for AudioFrameInner {} +unsafe impl Sync for AudioFrameInner {} + #[derive(Debug, Copy, Clone)] pub struct TryFromAudioBufferError; @@ -881,44 +915,39 @@ impl fmt::Display for TryFromAudioBufferError { impl std::error::Error for TryFromAudioBufferError {} -impl<'a> AudioFrame<'a> { +impl AudioFrame { pub fn sample_rate(&self) -> i32 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.sample_rate - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.sample_rate, } } pub fn no_channels(&self) -> i32 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.no_channels - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.no_channels, } } pub fn no_samples(&self) -> i32 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.no_samples - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.no_samples, } } pub fn timecode(&self) -> i64 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.timecode - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.timecode, } } pub fn fourcc(&self) -> NDIlib_FourCC_audio_type_e { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.FourCC - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.FourCC, } } @@ -929,26 +958,23 @@ impl<'a> AudioFrame<'a> { let fourcc = self.fourcc(); if [NDIlib_FourCC_audio_type_FLTp].contains(&fourcc) { - return match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - Some(slice::from_raw_parts( - frame.p_data as *const u8, - (frame.no_channels * frame.channel_stride_or_data_size_in_bytes) - as usize, - )) - } + return match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => Some(slice::from_raw_parts( + frame.p_data as *const u8, + (frame.no_channels * frame.channel_stride_or_data_size_in_bytes) as usize, + )), }; } #[cfg(feature = "advanced-sdk")] if [NDIlib_FourCC_audio_type_Opus].contains(&fourcc) { - return match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - Some(slice::from_raw_parts( - frame.p_data as *const u8, - frame.channel_stride_or_data_size_in_bytes as usize, - )) - } + return match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => Some(slice::from_raw_parts( + frame.p_data as *const u8, + frame.channel_stride_or_data_size_in_bytes as usize, + )), }; } @@ -969,13 +995,12 @@ impl<'a> AudioFrame<'a> { return None; } - let data = match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - slice::from_raw_parts( - frame.p_data as *const u8, - frame.channel_stride_or_data_size_in_bytes as usize, - ) - } + let data = match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => slice::from_raw_parts( + frame.p_data as *const u8, + frame.channel_stride_or_data_size_in_bytes as usize, + ), }; let mut cursor = Cursor::new(data); @@ -1019,17 +1044,17 @@ impl<'a> AudioFrame<'a> { } pub fn channel_stride_or_data_size_in_bytes(&self) -> i32 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.channel_stride_or_data_size_in_bytes - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.channel_stride_or_data_size_in_bytes, } } pub fn metadata(&self) -> Option<&str> { unsafe { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => { if frame.p_metadata.is_null() { None } else { @@ -1041,16 +1066,16 @@ impl<'a> AudioFrame<'a> { } pub fn timestamp(&self) -> i64 { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => { - frame.timestamp - } + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame.timestamp, } } pub fn as_ptr(&self) -> *const NDIlib_audio_frame_v3_t { - match self { - AudioFrame::BorrowedRecv(ref frame, _) | AudioFrame::Owned(ref frame, _, _) => frame, + match self.0 { + AudioFrameInner::BorrowedRecv(ref frame, _) + | AudioFrameInner::Owned(ref frame, _, _) => frame, } } @@ -1099,18 +1124,11 @@ impl<'a> AudioFrame<'a> { timestamp: 0, }; - Ok(AudioFrame::Owned(dest, None, Some(dest_data))) - } -} - -impl<'a> Drop for AudioFrame<'a> { - #[allow(irrefutable_let_patterns)] - fn drop(&mut self) { - if let AudioFrame::BorrowedRecv(ref mut frame, recv) = *self { - unsafe { - NDIlib_recv_free_audio_v3(recv.0.as_ptr() as *mut _, frame); - } - } + Ok(AudioFrame(AudioFrameInner::Owned( + dest, + None, + Some(dest_data), + ))) } } @@ -1125,16 +1143,32 @@ pub struct CompressedPacket<'a> { } #[derive(Debug)] -pub enum MetadataFrame<'a> { +pub struct MetadataFrame(MetadataFrameInner); + +#[derive(Debug)] +enum MetadataFrameInner { Owned(NDIlib_metadata_frame_t, Option<ffi::CString>), - Borrowed(NDIlib_metadata_frame_t, &'a RecvInstance), + Borrowed(NDIlib_metadata_frame_t, Arc<RecvInstancePtr>), +} + +impl Drop for MetadataFrameInner { + fn drop(&mut self) { + if let MetadataFrameInner::Borrowed(ref mut frame, ref recv) = *self { + unsafe { + NDIlib_recv_free_metadata(recv.0.as_ptr() as *mut _, frame); + } + } + } } -impl<'a> MetadataFrame<'a> { +unsafe impl Send for MetadataFrameInner {} +unsafe impl Sync for MetadataFrameInner {} + +impl MetadataFrame { pub fn new(timecode: i64, data: Option<&str>) -> Self { let data = data.map(|s| ffi::CString::new(s).unwrap()); - MetadataFrame::Owned( + MetadataFrame(MetadataFrameInner::Owned( NDIlib_metadata_frame_t { length: data .as_ref() @@ -1147,23 +1181,23 @@ impl<'a> MetadataFrame<'a> { .unwrap_or(ptr::null_mut()), }, data, - ) + )) } pub fn timecode(&self) -> i64 { - match self { - MetadataFrame::Owned(ref frame, _) => frame.timecode, - MetadataFrame::Borrowed(ref frame, _) => frame.timecode, + match self.0 { + MetadataFrameInner::Owned(ref frame, _) => frame.timecode, + MetadataFrameInner::Borrowed(ref frame, _) => frame.timecode, } } pub fn metadata(&self) -> Option<&str> { unsafe { - match self { - MetadataFrame::Owned(_, ref metadata) => { + match self.0 { + MetadataFrameInner::Owned(_, ref metadata) => { metadata.as_ref().map(|s| s.to_str().unwrap()) } - MetadataFrame::Borrowed(ref frame, _) => { + MetadataFrameInner::Borrowed(ref frame, _) => { if frame.p_data.is_null() || frame.length == 0 { None } else if frame.length != 0 { @@ -1186,33 +1220,23 @@ impl<'a> MetadataFrame<'a> { } pub fn as_ptr(&self) -> *const NDIlib_metadata_frame_t { - match self { - MetadataFrame::Owned(ref frame, _) => frame, - MetadataFrame::Borrowed(ref frame, _) => frame, + match self.0 { + MetadataFrameInner::Owned(ref frame, _) => frame, + MetadataFrameInner::Borrowed(ref frame, _) => frame, } } } -impl<'a> Default for MetadataFrame<'a> { +impl Default for MetadataFrame { fn default() -> Self { - MetadataFrame::Owned( + MetadataFrame(MetadataFrameInner::Owned( NDIlib_metadata_frame_t { length: 0, timecode: 0, //NDIlib_send_timecode_synthesize, p_data: ptr::null(), }, None, - ) - } -} - -impl<'a> Drop for MetadataFrame<'a> { - fn drop(&mut self) { - if let MetadataFrame::Borrowed(ref mut frame, recv) = *self { - unsafe { - NDIlib_recv_free_metadata(recv.0.as_ptr() as *mut _, frame); - } - } + )) } } diff --git a/net/ndi/src/ndisink/imp.rs b/net/ndi/src/ndisink/imp.rs index ba7b86b77..c33d6e140 100644 --- a/net/ndi/src/ndisink/imp.rs +++ b/net/ndi/src/ndisink/imp.rs @@ -315,21 +315,17 @@ impl BaseSinkImpl for NdiSink { ndi_meta = ndi_cc_encoder.encode(buffer); } - let frame = gst_video::VideoFrameRef::from_buffer_ref_readable(buffer, info) + let frame = gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info) .map_err(|_| { gst::error!(CAT, imp: self, "Failed to map buffer"); gst::FlowError::Error })?; - let frame = crate::ndi::VideoFrame::try_from_video_frame( - &frame, - ndi_meta.as_deref(), - timecode, - ) - .map_err(|_| { - gst::error!(CAT, imp: self, "Unsupported video frame"); - gst::FlowError::NotNegotiated - })?; + let frame = crate::ndi::VideoFrame::try_from_video_frame(frame, ndi_meta, timecode) + .map_err(|_| { + gst::error!(CAT, imp: self, "Unsupported video frame"); + gst::FlowError::NotNegotiated + })?; gst::trace!( CAT, |