From 32035af45022bd8553ded272b4b88917dd4fe89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Monnom?= Date: Tue, 6 Feb 2024 15:26:34 +0100 Subject: [PATCH] fix ptr align (#302) --- livekit-ffi/protocol/video_frame.proto | 5 +- livekit-ffi/src/livekit.proto.rs | 8 +- livekit-ffi/src/server/colorcvt/cvtimpl.rs | 428 ++++++++++++++----- livekit-ffi/src/server/colorcvt/mod.rs | 464 +++++++++------------ 4 files changed, 539 insertions(+), 366 deletions(-) diff --git a/livekit-ffi/protocol/video_frame.proto b/livekit-ffi/protocol/video_frame.proto index 28016b04..ffb2e0bd 100644 --- a/livekit-ffi/protocol/video_frame.proto +++ b/livekit-ffi/protocol/video_frame.proto @@ -100,7 +100,7 @@ enum VideoBufferType { message VideoBufferInfo { message ComponentInfo { - uint32 offset = 1; + uint64 data_ptr = 1; uint32 stride = 2; uint32 size = 3; } @@ -108,8 +108,7 @@ message VideoBufferInfo { uint32 width = 2; uint32 height = 3; uint64 data_ptr = 4; - uint32 data_len = 5; - uint32 stride = 6; // for packed formats + uint32 stride = 6; // only for packed formats repeated ComponentInfo components = 7; } diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 2a686643..289061e5 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -1619,9 +1619,7 @@ pub struct VideoBufferInfo { pub height: u32, #[prost(uint64, tag="4")] pub data_ptr: u64, - #[prost(uint32, tag="5")] - pub data_len: u32, - /// for packed formats + /// only for packed formats #[prost(uint32, tag="6")] pub stride: u32, #[prost(message, repeated, tag="7")] @@ -1632,8 +1630,8 @@ pub mod video_buffer_info { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ComponentInfo { - #[prost(uint32, tag="1")] - pub offset: u32, + #[prost(uint64, tag="1")] + pub data_ptr: u64, #[prost(uint32, tag="2")] pub stride: u32, #[prost(uint32, tag="3")] diff --git a/livekit-ffi/src/server/colorcvt/cvtimpl.rs b/livekit-ffi/src/server/colorcvt/cvtimpl.rs index c36503ff..0ddc6f21 100644 --- a/livekit-ffi/src/server/colorcvt/cvtimpl.rs +++ b/livekit-ffi/src/server/colorcvt/cvtimpl.rs @@ -29,7 +29,8 @@ pub unsafe fn cvt_rgba( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Rgba); - let proto::VideoBufferInfo { stride, width, height, data_ptr, data_len, .. } = buffer; + let proto::VideoBufferInfo { stride, width, height, data_ptr, .. } = buffer; + let data_len = (stride * height) as usize; let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; match dst_type { @@ -38,13 +39,28 @@ pub unsafe fn cvt_rgba( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dy, du, dv) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::abgr_to_i420( - data, stride, dy, width, du, chroma_w, dv, chroma_w, width, height, flip_y, + data, stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -59,7 +75,8 @@ pub unsafe fn cvt_abgr( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Rgba); - let proto::VideoBufferInfo { stride, width, height, data_ptr, data_len, .. } = buffer; + let proto::VideoBufferInfo { stride, width, height, data_ptr, .. } = buffer; + let data_len = (stride * height) as usize; let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; match dst_type { @@ -68,13 +85,28 @@ pub unsafe fn cvt_abgr( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; imgproc::colorcvt::rgba_to_i420( data, stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -89,7 +121,8 @@ pub unsafe fn cvt_argb( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Argb); - let proto::VideoBufferInfo { stride, width, height, data_ptr, data_len, .. } = buffer; + let proto::VideoBufferInfo { stride, width, height, data_ptr, .. } = buffer; + let data_len = (stride * height) as usize; let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; match dst_type { @@ -98,13 +131,27 @@ pub unsafe fn cvt_argb( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::bgra_to_i420( data, stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -119,7 +166,8 @@ pub unsafe fn cvt_bgra( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Bgra); - let proto::VideoBufferInfo { stride, width, height, data_ptr, data_len, .. } = buffer; + let proto::VideoBufferInfo { stride, width, height, data_ptr, .. } = buffer; + let data_len = (stride * height) as usize; let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; match dst_type { @@ -128,13 +176,27 @@ pub unsafe fn cvt_bgra( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::argb_to_i420( data, stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -149,7 +211,8 @@ pub unsafe fn cvt_rgb24( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Rgb24); - let proto::VideoBufferInfo { stride, width, height, data_ptr, data_len, .. } = buffer; + let proto::VideoBufferInfo { stride, width, height, data_ptr, .. } = buffer; + let data_len = (stride * height) as usize; let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; match dst_type { @@ -158,13 +221,27 @@ pub unsafe fn cvt_rgb24( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::raw_to_i420( data, stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -181,11 +258,16 @@ pub unsafe fn cvt_i420( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::I420); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i420(data, c0.stride, c1.stride, c2.stride, height); + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; match dst_type { proto::VideoBufferType::Rgba @@ -199,8 +281,8 @@ pub unsafe fn cvt_i420( ($rgba:expr, $fnc:ident) => { if dst_type == $rgba { colorcvt::$fnc( - y, c0.stride, u, c1.stride, v, c2.stride, &mut dst, stride, width, - height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, &mut dst, + stride, width, height, flip_y, ); } }; @@ -211,7 +293,7 @@ pub unsafe fn cvt_i420( cvt!(proto::VideoBufferType::Argb, i420_to_bgra); cvt!(proto::VideoBufferType::Bgra, i420_to_argb); - let info = rgba_info(&dst, dst_type, width, height); + let info = rgba_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::Rgb24 => { @@ -219,10 +301,11 @@ pub unsafe fn cvt_i420( let stride = width * 3; colorcvt::i420_to_raw( - y, c0.stride, u, c1.stride, v, c2.stride, &mut dst, stride, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, &mut dst, stride, width, + height, flip_y, ); - let info = rgb_info(&dst, dst_type, width, height); + let info = rgb_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::I420 => { @@ -230,14 +313,28 @@ pub unsafe fn cvt_i420( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i420_copy( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -254,11 +351,17 @@ pub unsafe fn cvt_i420a( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::I420a); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1, c2, c3) = (&components[0], &components[1], &components[2], &components[3]); - let (y, u, v, a) = split_i420a(data, c0.stride, c1.stride, c2.stride, c3.stride, height); + let (data_y, data_u, data_v, data_a) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + slice::from_raw_parts(c3.data_ptr as *const u8, c3.size as usize), + ) + }; match dst_type { proto::VideoBufferType::I420 => { @@ -266,13 +369,27 @@ pub unsafe fn cvt_i420a( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i420_copy( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, + ); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); Ok((dst, info)) } proto::VideoBufferType::I420a => { @@ -281,17 +398,25 @@ pub unsafe fn cvt_i420a( let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2 + width * height) as usize] .into_boxed_slice(); - let (dst_y, dst_u, dst_v, dst_a) = - split_i420a_mut(&mut dst, width, chroma_w, chroma_w, width, height); + + let (dst_y, dst_u, dst_v, dst_a) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, va) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + let (v, a) = va.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v, a) + }; colorcvt::i420a_copy( - y, c0.stride, u, c1.stride, v, c2.stride, a, c3.stride, dst_y, width, dst_u, - chroma_w, dst_v, chroma_w, dst_a, width, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, data_a, c3.stride, dst_y, + width, dst_u, chroma_w, dst_v, chroma_w, dst_a, width, width, height, flip_y, ); let info = i420a_info( - dst.as_ptr(), - dst.len(), + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + dst_a.as_ptr(), width, height, width, @@ -315,11 +440,16 @@ pub unsafe fn cvt_i422( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::I422); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i422(data, c0.stride, c1.stride, c2.stride, height); + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; match dst_type { proto::VideoBufferType::Rgba @@ -332,8 +462,8 @@ pub unsafe fn cvt_i422( ($rgba:expr, $fnc:ident) => { if dst_type == $rgba { colorcvt::$fnc( - y, c0.stride, u, c1.stride, v, c2.stride, &mut dst, stride, width, - height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, &mut dst, + stride, width, height, flip_y, ); } }; @@ -343,7 +473,7 @@ pub unsafe fn cvt_i422( cvt!(proto::VideoBufferType::Abgr, i422_to_rgba); cvt!(proto::VideoBufferType::Argb, i422_to_bgra); - let info = rgba_info(&dst, dst_type, width, height); + let info = rgba_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::I420 => { @@ -351,14 +481,28 @@ pub unsafe fn cvt_i422( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i422_to_i420( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } proto::VideoBufferType::I422 => { @@ -366,13 +510,27 @@ pub unsafe fn cvt_i422( let chroma_h = height; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i422_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i422_copy( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, + ); + let info = i422_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, ); - let info = i422_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); Ok((dst, info)) } _ => { @@ -389,11 +547,16 @@ pub unsafe fn cvt_i444( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::I444); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i444(data, c0.stride, c1.stride, c2.stride, height); + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; match dst_type { proto::VideoBufferType::Rgba | proto::VideoBufferType::Bgra => { @@ -404,8 +567,8 @@ pub unsafe fn cvt_i444( ($rgba:expr, $fnc:ident) => { if dst_type == $rgba { imgproc::colorcvt::$fnc( - y, c0.stride, u, c1.stride, v, c2.stride, &mut dst, stride, width, - height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, &mut dst, + stride, width, height, flip_y, ); } }; @@ -414,7 +577,7 @@ pub unsafe fn cvt_i444( cvt!(proto::VideoBufferType::Rgba, i444_to_abgr); cvt!(proto::VideoBufferType::Bgra, i444_to_argb); - let info = rgba_info(&dst, dst_type, width, height); + let info = rgba_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::I420 => { @@ -422,14 +585,28 @@ pub unsafe fn cvt_i444( let chroma_h = (height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i444_to_i420( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } proto::VideoBufferType::I444 => { @@ -437,14 +614,29 @@ pub unsafe fn cvt_i444( let chroma_h = height; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i444_mut(&mut dst, width, chroma_w, chroma_w, height); + + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; colorcvt::i444_copy( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i444_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i444_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + data_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -461,15 +653,16 @@ pub unsafe fn cvt_i010( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::I010); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i010(data, c0.stride, c1.stride, c2.stride, height); - - let (_, y, _) = unsafe { y.align_to::() }; - let (_, u, _) = unsafe { u.align_to::() }; - let (_, v, _) = unsafe { v.align_to::() }; + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u16, c0.size as usize / 2), + slice::from_raw_parts(c1.data_ptr as *const u16, c1.size as usize / 2), + slice::from_raw_parts(c2.data_ptr as *const u16, c2.size as usize / 2), + ) + }; match dst_type { proto::VideoBufferType::Rgba | proto::VideoBufferType::Bgra => { @@ -480,8 +673,8 @@ pub unsafe fn cvt_i010( ($rgba:expr, $fnc:ident) => { if dst_type == $rgba { imgproc::colorcvt::$fnc( - y, c0.stride, u, c1.stride, v, c2.stride, &mut dst, stride, width, - height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, &mut dst, + stride, width, height, flip_y, ); } }; @@ -490,7 +683,7 @@ pub unsafe fn cvt_i010( cvt!(proto::VideoBufferType::Rgba, i010_to_abgr); cvt!(proto::VideoBufferType::Bgra, i010_to_argb); - let info = rgba_info(&dst, dst_type, width, height); + let info = rgba_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::I420 => { @@ -498,14 +691,28 @@ pub unsafe fn cvt_i010( let chroma_h = (buffer.height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; imgproc::colorcvt::i010_to_i420( - y, c0.stride, u, c1.stride, v, c2.stride, dst_y, width, dst_u, chroma_w, dst_v, - chroma_w, width, height, flip_y, + data_y, c0.stride, data_u, c1.stride, data_v, c2.stride, dst_y, width, dst_u, + chroma_w, dst_v, chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } _ => { @@ -522,11 +729,15 @@ pub unsafe fn cvt_nv12( flip_y: bool, ) -> FfiResult<(Box<[u8]>, proto::VideoBufferInfo)> { assert_eq!(buffer.r#type(), proto::VideoBufferType::Nv12); - let proto::VideoBufferInfo { width, height, components, data_ptr, data_len, .. } = buffer; - let data = unsafe { slice::from_raw_parts(data_ptr as *const u8, data_len as usize) }; + let proto::VideoBufferInfo { width, height, components, .. } = buffer; let (c0, c1) = (&components[0], &components[1]); - let (y, uv) = split_nv12(data, c0.stride, c1.stride, height); + let (data_y, data_uv) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + ) + }; match dst_type { proto::VideoBufferType::Rgba | proto::VideoBufferType::Bgra => { @@ -537,7 +748,8 @@ pub unsafe fn cvt_nv12( ($rgba:expr, $fnc:ident) => { if dst_type == $rgba { imgproc::colorcvt::$fnc( - y, c0.stride, uv, c1.stride, &mut dst, stride, width, height, flip_y, + data_y, c0.stride, data_uv, c1.stride, &mut dst, stride, width, height, + flip_y, ); } }; @@ -546,7 +758,7 @@ pub unsafe fn cvt_nv12( cvt!(proto::VideoBufferType::Rgba, nv12_to_abgr); cvt!(proto::VideoBufferType::Bgra, nv12_to_argb); - let info = rgba_info(&dst, dst_type, width, height); + let info = rgba_info(dst.as_ptr(), dst_type, width, height); Ok((dst, info)) } proto::VideoBufferType::I420 => { @@ -554,14 +766,28 @@ pub unsafe fn cvt_nv12( let chroma_h = (buffer.height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_u, dst_v) = split_i420_mut(&mut dst, width, chroma_w, chroma_w, height); + let (dst_y, dst_u, dst_v) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + let (u, v) = chroma.split_at_mut((chroma_w * chroma_h) as usize); + (luma, u, v) + }; imgproc::colorcvt::nv12_to_i420( - y, c0.stride, uv, c1.stride, dst_y, width, dst_u, chroma_w, dst_v, chroma_w, width, - height, flip_y, + data_y, c0.stride, data_uv, c1.stride, dst_y, width, dst_u, chroma_w, dst_v, + chroma_w, width, height, flip_y, ); - let info = i420_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w, chroma_w); + let info = i420_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_u.as_ptr(), + dst_v.as_ptr(), + width, + height, + width, + chroma_w, + chroma_w, + ); Ok((dst, info)) } proto::VideoBufferType::Nv12 => { @@ -569,13 +795,25 @@ pub unsafe fn cvt_nv12( let chroma_h = (buffer.height + 1) / 2; let mut dst = vec![0u8; (width * height + chroma_w * chroma_h * 2) as usize].into_boxed_slice(); - let (dst_y, dst_uv) = split_nv12_mut(&mut dst, width, chroma_w, height); + let (dst_y, dst_uv) = { + let (luma, chroma) = dst.split_at_mut((width * height) as usize); + (luma, chroma) + }; imgproc::colorcvt::nv12_copy( - y, c0.stride, uv, c1.stride, dst_y, width, dst_uv, chroma_w, width, height, flip_y, + data_y, c0.stride, data_uv, c1.stride, dst_y, width, dst_uv, chroma_w, width, + height, flip_y, ); - let info = nv12_info(dst.as_ptr(), dst.len(), width, height, width, chroma_w); + let info = nv12_info( + dst_y.as_ptr(), + dst_y.as_ptr(), + dst_uv.as_ptr(), + width, + height, + width, + chroma_w, + ); Ok((dst, info)) } _ => { diff --git a/livekit-ffi/src/server/colorcvt/mod.rs b/livekit-ffi/src/server/colorcvt/mod.rs index 117eacae..0bb05349 100644 --- a/livekit-ffi/src/server/colorcvt/mod.rs +++ b/livekit-ffi/src/server/colorcvt/mod.rs @@ -5,109 +5,147 @@ use std::slice; pub mod cvtimpl; macro_rules! to_i420 { - ($buffer:ident, $data:expr) => {{ + ($buffer:ident) => {{ let proto::VideoBufferInfo { width, height, components, .. } = $buffer; let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i420($data, c0.stride, c1.stride, c2.stride, height); + + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; + let mut i420 = I420Buffer::with_strides(width, height, c0.stride, c1.stride, c2.stride); let (dy, du, dv) = i420.data_mut(); - dy.copy_from_slice(y); - du.copy_from_slice(u); - dv.copy_from_slice(v); + dy.copy_from_slice(data_y); + du.copy_from_slice(data_u); + dv.copy_from_slice(data_v); Box::new(i420) as BoxVideoBuffer }}; } pub unsafe fn to_libwebrtc_buffer(info: proto::VideoBufferInfo) -> BoxVideoBuffer { - let data = unsafe { slice::from_raw_parts(info.data_ptr as *const u8, info.data_len as usize) }; let r#type = info.r#type(); let proto::VideoBufferInfo { width, height, components, .. } = info.clone(); match r#type { // For rgba buffer, automatically convert to I420 proto::VideoBufferType::Rgba => { - let (data, info) = + let (_data, info) = cvtimpl::cvt_rgba(info, proto::VideoBufferType::I420, false).unwrap(); - to_i420!(info, &data) + to_i420!(info) } proto::VideoBufferType::Abgr => { - let (data, info) = + let (_data, info) = cvtimpl::cvt_abgr(info, proto::VideoBufferType::I420, false).unwrap(); - to_i420!(info, &data) + to_i420!(info) } proto::VideoBufferType::Argb => { - let (data, info) = + let (_data, info) = cvtimpl::cvt_argb(info, proto::VideoBufferType::I420, false).unwrap(); - to_i420!(info, &data) + to_i420!(info) } proto::VideoBufferType::Bgra => { - let (data, info) = + let (_data, info) = cvtimpl::cvt_bgra(info, proto::VideoBufferType::I420, false).unwrap(); - to_i420!(info, &data) + to_i420!(info) } proto::VideoBufferType::Rgb24 => { - let (data, info) = + let (_data, info) = cvtimpl::cvt_rgb24(info, proto::VideoBufferType::I420, false).unwrap(); - to_i420!(info, &data) + to_i420!(info) } proto::VideoBufferType::I420 | proto::VideoBufferType::I420a => { let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i420(data, c0.stride, c1.stride, c2.stride, height); + + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; let mut i420 = I420Buffer::with_strides(width, height, c0.stride, c1.stride, c2.stride); let (dy, du, dv) = i420.data_mut(); - dy.copy_from_slice(y); - du.copy_from_slice(u); - dv.copy_from_slice(v); + dy.copy_from_slice(data_y); + du.copy_from_slice(data_u); + dv.copy_from_slice(data_v); Box::new(i420) as BoxVideoBuffer } proto::VideoBufferType::I422 => { let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i422(data, c0.stride, c1.stride, c2.stride, height); + + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; + let mut i422 = I422Buffer::with_strides(width, height, c0.stride, c1.stride, c2.stride); let (dy, du, dv) = i422.data_mut(); - dy.copy_from_slice(y); - du.copy_from_slice(u); - dv.copy_from_slice(v); + dy.copy_from_slice(data_y); + du.copy_from_slice(data_u); + dv.copy_from_slice(data_v); Box::new(i422) as BoxVideoBuffer } proto::VideoBufferType::I444 => { let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i444(data, c0.stride, c1.stride, c2.stride, height); + + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + slice::from_raw_parts(c2.data_ptr as *const u8, c2.size as usize), + ) + }; let mut i444 = I444Buffer::with_strides(width, height, c0.stride, c1.stride, c2.stride); let (dy, du, dv) = i444.data_mut(); - dy.copy_from_slice(y); - du.copy_from_slice(u); - dv.copy_from_slice(v); + dy.copy_from_slice(data_y); + du.copy_from_slice(data_u); + dv.copy_from_slice(data_v); Box::new(i444) as BoxVideoBuffer } proto::VideoBufferType::I010 => { let (c0, c1, c2) = (&components[0], &components[1], &components[2]); - let (y, u, v) = split_i010(data, c0.stride, c1.stride, c2.stride, height); - let (_, y, _) = unsafe { y.align_to::() }; - let (_, u, _) = unsafe { u.align_to::() }; - let (_, v, _) = unsafe { v.align_to::() }; + let (data_y, data_u, data_v) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u16, c0.size as usize / 2), + slice::from_raw_parts(c1.data_ptr as *const u16, c1.size as usize / 2), + slice::from_raw_parts(c2.data_ptr as *const u16, c2.size as usize / 2), + ) + }; let mut i010 = I010Buffer::with_strides(width, height, c0.stride, c1.stride, c2.stride); let (dy, du, dv) = i010.data_mut(); - dy.copy_from_slice(y); - du.copy_from_slice(u); - dv.copy_from_slice(v); + dy.copy_from_slice(data_y); + du.copy_from_slice(data_u); + dv.copy_from_slice(data_v); Box::new(i010) as BoxVideoBuffer } proto::VideoBufferType::Nv12 => { let (c0, c1) = (&components[0], &components[1]); - let (y, uv) = split_nv12(data, c0.stride, c1.stride, info.height); + + let (data_y, data_uv) = unsafe { + ( + slice::from_raw_parts(c0.data_ptr as *const u8, c0.size as usize), + slice::from_raw_parts(c1.data_ptr as *const u8, c1.size as usize), + ) + }; let mut nv12 = NV12Buffer::with_strides(info.width, info.height, c0.stride, c1.stride); let (dy, duv) = nv12.data_mut(); - dy.copy_from_slice(y); - duv.copy_from_slice(uv); + dy.copy_from_slice(data_y); + duv.copy_from_slice(data_uv); Box::new(nv12) as BoxVideoBuffer } } @@ -122,40 +160,53 @@ pub fn to_video_buffer_info( // Convert Native buffer to I420 VideoBufferType::Native => { let i420 = rtcbuffer.to_i420(); + let (width, height) = (i420.width(), i420.height()); + let (data_y, data_u, data_v) = i420.data(); let (stride_y, stride_u, stride_v) = i420.strides(); - let ptr = i420.data().0.as_ptr() as *const u8; - let len = (stride_y * i420.height() - + stride_u * i420.chroma_height() - + stride_v * i420.chroma_height()) as usize; - let info = - i420_info(ptr, len, i420.width(), i420.height(), stride_y, stride_u, stride_v); + let info = i420_info( + data_y.as_ptr(), + data_y.as_ptr(), + data_u.as_ptr(), + data_v.as_ptr(), + width, + height, + stride_y, + stride_u, + stride_v, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::I420), false) } } VideoBufferType::I420 => { let i420 = rtcbuffer.as_i420().unwrap(); + let (width, height) = (i420.width(), i420.height()); + let (data_y, data_u, data_v) = i420.data(); let (stride_y, stride_u, stride_v) = i420.strides(); - let ptr = i420.data().0.as_ptr() as *const u8; - let len = (stride_y * i420.height() - + stride_u * i420.chroma_height() - + stride_v * i420.chroma_height()) as usize; - let info = - i420_info(ptr, len, i420.width(), i420.height(), stride_y, stride_u, stride_v); + let info = i420_info( + data_y.as_ptr(), + data_y.as_ptr(), + data_u.as_ptr(), + data_v.as_ptr(), + width, + height, + stride_y, + stride_u, + stride_v, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::I420), false) } } VideoBufferType::I420A => { let i420 = rtcbuffer.as_i420a().unwrap(); + let (width, height) = (i420.width(), i420.height()); let (stride_y, stride_u, stride_v, stride_a) = i420.strides(); - let ptr = i420.data().0.as_ptr() as *const u8; - let len = (stride_y * i420.height() - + stride_u * i420.chroma_height() - + stride_v * i420.chroma_height() - + stride_a * i420.height()) as usize; - + let (data_y, data_u, data_v, data_a) = i420.data(); let info = i420a_info( - ptr, - len, - i420.width(), - i420.height(), + data_y.as_ptr(), + data_y.as_ptr(), + data_u.as_ptr(), + data_v.as_ptr(), + data_a.unwrap().as_ptr(), + width, + height, stride_y, stride_u, stride_v, @@ -165,198 +216,83 @@ pub fn to_video_buffer_info( } VideoBufferType::I422 => { let i422 = rtcbuffer.as_i422().unwrap(); + let (width, height) = (i422.width(), i422.height()); let (stride_y, stride_u, stride_v) = i422.strides(); - let ptr = i422.data().0.as_ptr() as *const u8; - let len = (stride_y * i422.height() - + stride_u * i422.chroma_height() - + stride_v * i422.chroma_height()) as usize; - let info = - i422_info(ptr, len, i422.width(), i422.height(), stride_y, stride_u, stride_v); + let (data_y, data_u, data_v) = i422.data(); + let info = i422_info( + data_y.as_ptr(), + data_y.as_ptr(), + data_u.as_ptr(), + data_v.as_ptr(), + width, + height, + stride_y, + stride_u, + stride_v, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::I422), false) } } VideoBufferType::I444 => { let i444 = rtcbuffer.as_i444().unwrap(); + let (width, height) = (i444.width(), i444.height()); let (stride_y, stride_u, stride_v) = i444.strides(); - let ptr = i444.data().0.as_ptr() as *const u8; - let len = (stride_y * i444.height() - + stride_u * i444.chroma_height() - + stride_v * i444.chroma_height()) as usize; - let info = - i444_info(ptr, len, i444.width(), i444.height(), stride_y, stride_u, stride_v); + let (data_y, data_u, data_v) = i444.data(); + let info = i444_info( + data_y.as_ptr(), + data_y.as_ptr(), + data_u.as_ptr(), + data_v.as_ptr(), + width, + height, + stride_y, + stride_u, + stride_v, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::I444), false) } } VideoBufferType::I010 => { let i010 = rtcbuffer.as_i010().unwrap(); + let (width, height) = (i010.width(), i010.height()); let (stride_y, stride_u, stride_v) = i010.strides(); - let ptr = i010.data().0.as_ptr() as *const u8; - let len = (stride_y * i010.height() - + stride_u * i010.chroma_height() - + stride_v * i010.chroma_height()) as usize; - let info = - i010_info(ptr, len, i010.width(), i010.height(), stride_y, stride_u, stride_v); + let (data_y, data_u, data_v) = i010.data(); + let info = i010_info( + data_y.as_ptr() as *const u8, + data_y.as_ptr() as *const u8, + data_u.as_ptr() as *const u8, + data_v.as_ptr() as *const u8, + width, + height, + stride_y, + stride_u, + stride_v, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::I010), false) } } VideoBufferType::NV12 => { let nv12 = rtcbuffer.as_nv12().unwrap(); + let (width, height) = (nv12.width(), nv12.height()); let (stride_y, stride_uv) = nv12.strides(); - let ptr = nv12.data().0.as_ptr() as *const u8; - let len = stride_y * nv12.height() + stride_uv * nv12.chroma_height() * 2; - let info = - nv12_info(ptr, len as usize, nv12.width(), nv12.height(), stride_y, stride_uv); + let (data_y, data_uv) = nv12.data(); + let info = nv12_info( + data_y.as_ptr(), + data_y.as_ptr(), + data_uv.as_ptr(), + width, + height, + stride_y, + stride_uv, + ); unsafe { cvtimpl::cvt(info, dst_type.unwrap_or(proto::VideoBufferType::Nv12), false) } } _ => todo!(), } } -pub fn split_i420_mut( - src: &mut [u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&mut [u8], &mut [u8], &mut [u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - let (u, v) = chroma.split_at_mut((stride_u * chroma_height) as usize); - (luma, u, v) -} - -pub fn split_i420( - dst: &[u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&[u8], &[u8], &[u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = dst.split_at((stride_y * height) as usize); - let (u, v) = chroma.split_at((stride_u * chroma_height) as usize); - (luma, u, v) -} - -pub fn split_i420a( - src: &[u8], - stride_y: u32, - stride_u: u32, - stride_v: u32, - _stride_a: u32, - height: u32, -) -> (&[u8], &[u8], &[u8], &[u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = src.split_at((stride_y * height) as usize); - let (u, v) = chroma.split_at((stride_u * chroma_height) as usize); - let (v, a) = v.split_at((stride_v * chroma_height) as usize); - (luma, u, v, a) -} - -pub fn split_i420a_mut( - src: &mut [u8], - stride_y: u32, - stride_u: u32, - stride_v: u32, - _stride_a: u32, - height: u32, -) -> (&mut [u8], &mut [u8], &mut [u8], &mut [u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - let (u, v) = chroma.split_at_mut((stride_u * chroma_height) as usize); - let (v, a) = v.split_at_mut((stride_v * chroma_height) as usize); - (luma, u, v, a) -} - -pub fn split_i422( - src: &[u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&[u8], &[u8], &[u8]) { - let (luma, chroma) = src.split_at((stride_y * height) as usize); - let (u, v) = chroma.split_at((stride_u * height) as usize); - (luma, u, v) -} - -pub fn split_i422_mut( - src: &mut [u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&mut [u8], &mut [u8], &mut [u8]) { - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - let (u, v) = chroma.split_at_mut((stride_u * height) as usize); - (luma, u, v) -} - -pub fn split_i444( - src: &[u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&[u8], &[u8], &[u8]) { - let (luma, chroma) = src.split_at((stride_y * height) as usize); - let (u, v) = chroma.split_at((stride_u * height) as usize); - (luma, u, v) -} - -pub fn split_i444_mut( - src: &mut [u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&mut [u8], &mut [u8], &mut [u8]) { - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - let (u, v) = chroma.split_at_mut((stride_u * height) as usize); - (luma, u, v) -} - -pub fn split_i010( - src: &[u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&[u8], &[u8], &[u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = src.split_at((stride_y * height) as usize); - let (u, v) = chroma.split_at((stride_u * chroma_height) as usize); - (luma, u, v) -} - -pub fn split_i010_mut( - src: &mut [u8], - stride_y: u32, - stride_u: u32, - _stride_v: u32, - height: u32, -) -> (&mut [u8], &mut [u8], &mut [u8]) { - let chroma_height = (height + 1) / 2; - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - let (u, v) = chroma.split_at_mut((stride_u * chroma_height) as usize); - (luma, u, v) -} - -pub fn split_nv12(src: &[u8], stride_y: u32, _stride_uv: u32, height: u32) -> (&[u8], &[u8]) { - let (luma, chroma) = src.split_at((stride_y * height) as usize); - (luma, chroma) -} - -pub fn split_nv12_mut( - src: &mut [u8], - stride_y: u32, - _stride_uv: u32, - height: u32, -) -> (&mut [u8], &mut [u8]) { - let (luma, chroma) = src.split_at_mut((stride_y * height) as usize); - (luma, chroma) -} - pub fn i420_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_u: *const u8, + data_v: *const u8, width: u32, height: u32, stride_y: u32, @@ -367,19 +303,19 @@ pub fn i420_info( let mut components = Vec::with_capacity(3); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_u as u64, stride: stride_u, size: stride_u * chroma_height, }; let c3 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size, + data_ptr: data_v as u64, stride: stride_v, size: stride_v * chroma_height, }; @@ -391,14 +327,16 @@ pub fn i420_info( r#type: proto::VideoBufferType::I420.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn i420a_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_u: *const u8, + data_v: *const u8, + data_a: *const u8, width: u32, height: u32, stride_y: u32, @@ -410,25 +348,25 @@ pub fn i420a_info( let mut components = Vec::with_capacity(4); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_u as u64, stride: stride_u, size: stride_u * chroma_height, }; let c3 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size, + data_ptr: data_v as u64, stride: stride_v, size: stride_v * chroma_height, }; let c4 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size + c3.size, + data_ptr: data_a as u64, stride: stride_a, size: stride_a * height, }; @@ -440,14 +378,15 @@ pub fn i420a_info( r#type: proto::VideoBufferType::I420a.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn i422_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_u: *const u8, + data_v: *const u8, width: u32, height: u32, stride_y: u32, @@ -456,19 +395,19 @@ pub fn i422_info( ) -> proto::VideoBufferInfo { let mut components = Vec::with_capacity(3); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_u as u64, stride: stride_u, size: stride_u * height, }; let c3 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size, + data_ptr: data_v as u64, stride: stride_v, size: stride_v * height, }; @@ -480,14 +419,15 @@ pub fn i422_info( r#type: proto::VideoBufferType::I422.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn i444_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_u: *const u8, + data_v: *const u8, width: u32, height: u32, stride_y: u32, @@ -496,19 +436,19 @@ pub fn i444_info( ) -> proto::VideoBufferInfo { let mut components = Vec::with_capacity(3); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_u as u64, stride: stride_u, size: stride_u * height, }; let c3 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size, + data_ptr: data_v as u64, stride: stride_v, size: stride_v * height, }; @@ -520,14 +460,15 @@ pub fn i444_info( r#type: proto::VideoBufferType::I444.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn i010_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_u: *const u8, + data_v: *const u8, width: u32, height: u32, stride_y: u32, @@ -538,19 +479,19 @@ pub fn i010_info( let mut components = Vec::with_capacity(3); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_u as u64, stride: stride_u, size: stride_u * chroma_height, }; let c3 = proto::video_buffer_info::ComponentInfo { - offset: c1.size + c2.size, + data_ptr: data_v as u64, stride: stride_v, size: stride_v * chroma_height, }; @@ -562,14 +503,14 @@ pub fn i010_info( r#type: proto::VideoBufferType::I010.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn nv12_info( data_ptr: *const u8, - data_len: usize, + data_y: *const u8, + data_uv: *const u8, width: u32, height: u32, stride_y: u32, @@ -579,13 +520,13 @@ pub fn nv12_info( let mut components = Vec::with_capacity(2); let c1 = proto::video_buffer_info::ComponentInfo { - offset: 0, + data_ptr: data_y as u64, stride: stride_y, size: stride_y * height, }; let c2 = proto::video_buffer_info::ComponentInfo { - offset: c1.size, + data_ptr: data_uv as u64, stride: stride_uv, size: stride_uv * chroma_height * 2, }; @@ -597,13 +538,12 @@ pub fn nv12_info( r#type: proto::VideoBufferType::Nv12.into(), components, data_ptr: data_ptr as u64, - data_len: data_len as u32, stride: 0, } } pub fn rgba_info( - data: &[u8], + data_ptr: *const u8, r#type: proto::VideoBufferType, width: u32, height: u32, @@ -613,14 +553,13 @@ pub fn rgba_info( height, r#type: r#type.into(), components: Vec::default(), - data_ptr: data.as_ptr() as u64, - data_len: data.len() as u32, + data_ptr: data_ptr as u64, stride: width * 4, } } pub fn rgb_info( - data: &[u8], + data_ptr: *const u8, r#type: proto::VideoBufferType, width: u32, height: u32, @@ -630,8 +569,7 @@ pub fn rgb_info( height, r#type: r#type.into(), components: Vec::default(), - data_ptr: data.as_ptr() as u64, - data_len: data.len() as u32, + data_ptr: data_ptr as u64, stride: width * 3, } }