diff --git a/src/rust/src/electron.rs b/src/rust/src/electron.rs index ad19d435..13ee4e86 100644 --- a/src/rust/src/electron.rs +++ b/src/rust/src/electron.rs @@ -9,7 +9,7 @@ use std::{ convert::TryFrom, fmt::Formatter, sync::{ - Arc, Mutex, + Arc, Mutex, Once, atomic::AtomicBool, mpsc::{Receiver, Sender, channel}, }, @@ -1441,7 +1441,13 @@ fn receive_video_frame<'a>( if let Some(frame) = frame { let frame = frame.apply_rotation(); - frame.to_rgba(rgba_buffer.as_mut_slice(cx)); + if !frame.to_rgba(rgba_buffer.as_mut_slice(cx)) { + static TO_RGBA_FAILED_ONCE: Once = Once::new(); + TO_RGBA_FAILED_ONCE.call_once(|| { + error!("receive_video_frame(): to_rgba failed, frame is likely not i420"); + }); + return Ok(cx.undefined().upcast()); + } let js_width = cx.number(frame.width()); let js_height = cx.number(frame.height()); let result = JsArray::new(cx, 2); diff --git a/src/rust/src/webrtc/ffi/media.rs b/src/rust/src/webrtc/ffi/media.rs index 540949da..85d64e21 100644 --- a/src/rust/src/webrtc/ffi/media.rs +++ b/src/rust/src/webrtc/ffi/media.rs @@ -97,7 +97,7 @@ unsafe extern "C" { pub fn Rust_convertVideoFrameBufferToRgba( buffer: webrtc::ptr::BorrowedRc, rgba_out: *mut u8, - ); + ) -> bool; pub fn Rust_getVideoFrameBufferAsI420( buffer: webrtc::ptr::BorrowedRc, ) -> webrtc::ptr::Borrowed; diff --git a/src/rust/src/webrtc/media.rs b/src/rust/src/webrtc/media.rs index f2daa760..be1ac1a1 100644 --- a/src/rust/src/webrtc/media.rs +++ b/src/rust/src/webrtc/media.rs @@ -150,17 +150,21 @@ impl VideoFrame { #[must_use] pub fn apply_rotation(self) -> Self { - if self.metadata.rotation == VideoRotation::None { + if self.metadata.rotation == VideoRotation::None || self.rffi_buffer.is_null() { + return self; + } + let rotated = unsafe { + media::Rust_copyAndRotateVideoFrameBuffer( + self.rffi_buffer.as_borrowed(), + self.metadata.rotation, + ) + }; + if rotated.is_null() { return self; } Self { metadata: self.metadata.apply_rotation(), - rffi_buffer: webrtc::Arc::from_owned(unsafe { - media::Rust_copyAndRotateVideoFrameBuffer( - self.rffi_buffer.as_borrowed(), - self.metadata.rotation, - ) - }), + rffi_buffer: webrtc::Arc::from_owned(rotated), } } @@ -200,7 +204,7 @@ impl VideoFrame { Self::from_buffer(metadata, rffi_buffer) } - pub fn to_rgba(&self, rgba_buffer: &mut [u8]) { + pub fn to_rgba(&self, rgba_buffer: &mut [u8]) -> bool { unsafe { media::Rust_convertVideoFrameBufferToRgba( self.rffi_buffer.as_borrowed(), diff --git a/src/rust/src/webrtc/sim/media.rs b/src/rust/src/webrtc/sim/media.rs index e2cdbd31..b55ea2ad 100644 --- a/src/rust/src/webrtc/sim/media.rs +++ b/src/rust/src/webrtc/sim/media.rs @@ -100,8 +100,9 @@ pub unsafe fn Rust_copyVideoFrameBufferFromRgba( pub unsafe fn Rust_convertVideoFrameBufferToRgba( _buffer: webrtc::ptr::BorrowedRc, _rgba_out: *mut u8, -) { +) -> bool { info!("Rust_convertVideoFrameBufferToRgba()"); + true } #[allow(non_snake_case, clippy::missing_safety_doc)]