feat: add publishing & audio to ffi (#46)

- Divide FFI protocol into multiple files
- Audio support
- AV Streams/Sources
- Create tracks
- Use Dashmap to store handles
- Add a capture test
     - Ignored by GHA atm
This commit is contained in:
Théo Monnom
2023-05-08 23:12:37 +02:00
committed by GitHub
parent a5caf12902
commit 1c12e749f2
58 changed files with 3046 additions and 1188 deletions
+14 -3
View File
@@ -1,7 +1,18 @@
#[derive(Debug, Clone)]
pub struct AudioFrame {
pub data: Vec<i16>,
pub sample_rate_hz: u32,
pub num_channels: usize,
pub samples_per_channel: usize,
pub sample_rate: u32,
pub num_channels: u32,
pub samples_per_channel: u32,
}
impl AudioFrame {
pub fn new(sample_rate: u32, num_channels: u32, samples_per_channel: u32) -> Self {
Self {
data: vec![0; (num_channels * samples_per_channel) as usize],
sample_rate,
num_channels,
samples_per_channel,
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ pub mod native {
}
impl NativeAudioSource {
pub fn capture_frame(&self, frame: AudioFrame) {
pub fn capture_frame(&self, frame: &AudioFrame) {
self.handle.capture_frame(frame)
}
}
+4 -4
View File
@@ -20,14 +20,14 @@ impl NativeAudioSource {
self.sys_handle.clone()
}
pub fn capture_frame(&self, frame: AudioFrame) {
pub fn capture_frame(&self, frame: &AudioFrame) {
// TODO(theomonnom): Should we check for 10ms worth of data here?
unsafe {
self.sys_handle.on_captured_frame(
frame.data.as_ptr(),
frame.sample_rate_hz as i32,
frame.num_channels,
frame.samples_per_channel,
frame.sample_rate as i32,
frame.num_channels as usize,
frame.samples_per_channel as usize,
)
}
}
+3 -3
View File
@@ -72,9 +72,9 @@ impl sys_ms::AudioSink for AudioTrackObserver {
// TODO(theomonnom): Should we avoid copy here?
let _ = self.frame_tx.send(AudioFrame {
data: data.to_owned(),
sample_rate_hz: sample_rate as u32,
num_channels: nb_channels,
samples_per_channel: nb_frames,
sample_rate: sample_rate as u32,
num_channels: nb_channels as u32,
samples_per_channel: nb_frames as u32,
});
}
}
+51 -51
View File
@@ -149,11 +149,11 @@ impl NativeBuffer {
&*self.sys_handle
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
self.sys_handle.width()
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
self.sys_handle.height()
}
@@ -167,7 +167,7 @@ impl NativeBuffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -192,49 +192,49 @@ impl I420Buffer {
unsafe { &*recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb) }
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).width()
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).height()
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv);
(*ptr).stride_y()
}
}
pub fn stride_u(&self) -> i32 {
pub fn stride_u(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv);
(*ptr).stride_u()
}
}
pub fn stride_v(&self) -> i32 {
pub fn stride_v(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv);
(*ptr).stride_v()
@@ -258,7 +258,7 @@ impl I420Buffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -292,56 +292,56 @@ impl I420ABuffer {
unsafe { &*recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb) }
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).width()
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).height()
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv);
(*ptr).stride_y()
}
}
pub fn stride_u(&self) -> i32 {
pub fn stride_u(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv);
(*ptr).stride_u()
}
}
pub fn stride_v(&self) -> i32 {
pub fn stride_v(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv);
(*ptr).stride_v()
}
}
pub fn stride_a(&self) -> i32 {
pub fn stride_a(&self) -> u32 {
self.sys_handle.stride_a()
}
@@ -359,7 +359,7 @@ impl I420ABuffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -391,49 +391,49 @@ impl I422Buffer {
unsafe { &*recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb) }
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).width()
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).height()
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv);
(*ptr).stride_y()
}
}
pub fn stride_u(&self) -> i32 {
pub fn stride_u(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv);
(*ptr).stride_u()
}
}
pub fn stride_v(&self) -> i32 {
pub fn stride_v(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv);
(*ptr).stride_v()
@@ -453,7 +453,7 @@ impl I422Buffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -477,49 +477,49 @@ impl I444Buffer {
unsafe { &*recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb) }
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).width()
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb);
(*ptr).height()
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv);
(*ptr).stride_y()
}
}
pub fn stride_u(&self) -> i32 {
pub fn stride_u(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv);
(*ptr).stride_u()
}
}
pub fn stride_v(&self) -> i32 {
pub fn stride_v(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv);
(*ptr).stride_v()
@@ -539,7 +539,7 @@ impl I444Buffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -564,49 +564,49 @@ impl I010Buffer {
unsafe { &*recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb) }
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb);
(*ptr).width()
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb);
(*ptr).height()
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv);
(*ptr).stride_y()
}
}
pub fn stride_u(&self) -> i32 {
pub fn stride_u(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv);
(*ptr).stride_u()
}
}
pub fn stride_v(&self) -> i32 {
pub fn stride_v(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv);
(*ptr).stride_v()
@@ -627,7 +627,7 @@ impl I010Buffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -669,7 +669,7 @@ impl NV12Buffer {
}
}
pub fn width(&self) -> i32 {
pub fn width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(
&*self.sys_handle,
@@ -681,7 +681,7 @@ impl NV12Buffer {
}
}
pub fn height(&self) -> i32 {
pub fn height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(
&*self.sys_handle,
@@ -693,28 +693,28 @@ impl NV12Buffer {
}
}
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv);
(*ptr).chroma_width()
}
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv);
(*ptr).chroma_height()
}
}
pub fn stride_y(&self) -> i32 {
pub fn stride_y(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv);
(*ptr).stride_y()
}
}
pub fn stride_uv(&self) -> i32 {
pub fn stride_uv(&self) -> u32 {
unsafe {
let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv);
(*ptr).stride_uv()
@@ -739,7 +739,7 @@ impl NV12Buffer {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
+2 -2
View File
@@ -21,12 +21,12 @@ impl NativeVideoSource {
self.sys_handle.clone()
}
pub fn capture_frame<T: VideoFrameBuffer>(&self, frame: &VideoFrame<T>) {
pub fn capture_frame<T: AsRef<dyn VideoFrameBuffer>>(&self, frame: &VideoFrame<T>) {
let mut builder = vf_sys::ffi::new_video_frame_builder();
builder.pin_mut().set_rotation(frame.rotation.into());
builder
.pin_mut()
.set_video_frame_buffer(frame.buffer.sys_handle());
.set_video_frame_buffer(frame.buffer.as_ref().sys_handle());
let frame = builder.pin_mut().build();
self.sys_handle.on_captured_frame(&frame);
+29 -27
View File
@@ -10,11 +10,12 @@ pub enum ConvertError {
#[inline]
fn argb_assert_safety(
src: &[u8],
src_stride: i32,
src_stride: u32,
_width: i32,
height: i32,
) -> Result<(), ConvertError> {
let min = (src_stride * height) as usize;
let height_abs = height.abs() as u32;
let min = (src_stride * height_abs) as usize;
if src.len() < min {
return Err(ConvertError::Convert("dst isn't large enough"));
@@ -26,16 +27,17 @@ fn argb_assert_safety(
#[inline]
fn i420_assert_safety(
src_y: &[u8],
src_stride_y: i32,
src_stride_y: u32,
src_u: &[u8],
src_stride_u: i32,
src_stride_u: u32,
src_v: &[u8],
src_stride_v: i32,
src_stride_v: u32,
_width: i32,
height: i32,
) -> Result<(), ConvertError> {
let chroma_height = (height + 1) / 2;
let min_y = (src_stride_y * height) as usize;
let height_abs = height.abs() as u32;
let chroma_height = (height_abs + 1) / 2;
let min_y = (src_stride_y * height_abs) as usize;
let min_u = (src_stride_u * chroma_height) as usize;
let min_v = (src_stride_v * chroma_height) as usize;
@@ -58,13 +60,13 @@ macro_rules! i420_to_x {
($x:ident) => {
pub fn $x(
src_y: &[u8],
src_stride_y: i32,
src_stride_y: u32,
src_u: &[u8],
src_stride_u: i32,
src_stride_u: u32,
src_v: &[u8],
src_stride_v: i32,
src_stride_v: u32,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
width: i32,
height: i32,
) -> Result<(), ConvertError> {
@@ -83,13 +85,13 @@ macro_rules! i420_to_x {
unsafe {
yuv_sys::ffi::$x(
src_y.as_ptr(),
src_stride_y,
src_stride_y as i32,
src_u.as_ptr(),
src_stride_u,
src_stride_u as i32,
src_v.as_ptr(),
src_stride_v,
src_stride_v as i32,
dst.as_mut_ptr(),
dst_stride,
dst_stride as i32,
width,
height,
)
@@ -105,13 +107,13 @@ macro_rules! x_to_i420 {
($x:ident) => {
pub fn $x(
src_argb: &[u8],
src_stride_argb: i32,
src_stride_argb: u32,
dst_y: &mut [u8],
dst_stride_y: i32,
dst_stride_y: u32,
dst_u: &mut [u8],
dst_stride_u: i32,
dst_stride_u: u32,
dst_v: &mut [u8],
dst_stride_v: i32,
dst_stride_v: u32,
width: i32,
height: i32,
) -> Result<(), ConvertError> {
@@ -130,13 +132,13 @@ macro_rules! x_to_i420 {
unsafe {
yuv_sys::ffi::$x(
src_argb.as_ptr(),
src_stride_argb,
src_stride_argb as i32,
dst_y.as_mut_ptr(),
dst_stride_y,
dst_stride_y as i32,
dst_u.as_mut_ptr(),
dst_stride_u,
dst_stride_u as i32,
dst_v.as_mut_ptr(),
dst_stride_v,
dst_stride_v as i32,
width,
height,
)
@@ -150,9 +152,9 @@ macro_rules! x_to_i420 {
pub fn argb_to_rgb24(
src_argb: &[u8],
src_stride_argb: i32,
src_stride_argb: u32,
dst_rgb24: &mut [u8],
dst_stride_rgb24: i32,
dst_stride_rgb24: u32,
width: i32,
height: i32,
) -> Result<(), ConvertError> {
@@ -162,9 +164,9 @@ pub fn argb_to_rgb24(
unsafe {
yuv_sys::ffi::argb_to_rgb24(
src_argb.as_ptr(),
src_stride_argb,
src_stride_argb as i32,
dst_rgb24.as_mut_ptr(),
dst_stride_rgb24,
dst_stride_rgb24 as i32,
width,
height,
)
+122 -178
View File
@@ -40,80 +40,20 @@ pub enum VideoFrameBufferType {
#[derive(Debug)]
pub struct VideoFrame<T>
where
T: VideoFrameBuffer,
T: AsRef<dyn VideoFrameBuffer>,
{
pub rotation: VideoRotation,
pub timestamp: i64, // When the frame was captured
pub buffer: T,
}
pub type BoxVideoFrame = VideoFrame<Box<dyn VideoFrameBuffer + Send + Sync>>;
macro_rules! new_buffer_type {
($type:ident, $variant:ident, $as:ident) => {
pub struct $type {
pub(crate) handle: vf_imp::$type,
}
impl $crate::video_frame::internal::BufferInternal for $type {
#[cfg(not(target_arch = "wasm32"))]
fn sys_handle(&self) -> &webrtc_sys::video_frame_buffer::ffi::VideoFrameBuffer {
self.handle.sys_handle()
}
#[cfg(not(target_arch = "wasm32"))]
fn to_i420(&self) -> I420Buffer {
I420Buffer {
handle: self.handle.to_i420(),
}
}
#[cfg(not(target_arch = "wasm32"))]
fn to_argb(
&self,
format: VideoFormatType,
dst: &mut [u8],
stride: i32,
width: i32,
height: i32,
) -> Result<(), $crate::video_frame::native::ConvertError> {
self.handle.to_argb(format, dst, stride, width, height)
}
}
impl VideoFrameBuffer for $type {
fn width(&self) -> i32 {
self.handle.width()
}
fn height(&self) -> i32 {
self.handle.height()
}
fn buffer_type(&self) -> VideoFrameBufferType {
VideoFrameBufferType::$variant
}
fn $as(&self) -> Option<&$type> {
Some(self)
}
}
impl Debug for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(stringify!($type))
.field("width", &self.width())
.field("height", &self.height())
.finish()
}
}
};
}
pub type BoxVideoFrameBuffer = Box<dyn VideoFrameBuffer>;
pub type BoxVideoFrame = VideoFrame<BoxVideoFrameBuffer>;
pub(crate) mod internal {
use super::{I420Buffer, VideoFormatType};
pub trait BufferInternal {
pub trait BufferSealed: Send + Sync {
#[cfg(not(target_arch = "wasm32"))]
fn sys_handle(&self) -> &webrtc_sys::video_frame_buffer::ffi::VideoFrameBuffer;
@@ -125,16 +65,16 @@ pub(crate) mod internal {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), super::native::ConvertError>;
}
}
pub trait VideoFrameBuffer: internal::BufferInternal + Debug {
fn width(&self) -> i32;
fn height(&self) -> i32;
pub trait VideoFrameBuffer: internal::BufferSealed + Debug {
fn width(&self) -> u32;
fn height(&self) -> u32;
fn buffer_type(&self) -> VideoFrameBufferType;
#[cfg(not(target_arch = "wasm32"))]
@@ -167,6 +107,73 @@ pub trait VideoFrameBuffer: internal::BufferInternal + Debug {
}
}
macro_rules! new_buffer_type {
($type:ident, $variant:ident, $as:ident) => {
pub struct $type {
pub(crate) handle: vf_imp::$type,
}
impl $crate::video_frame::internal::BufferSealed for $type {
#[cfg(not(target_arch = "wasm32"))]
fn sys_handle(&self) -> &webrtc_sys::video_frame_buffer::ffi::VideoFrameBuffer {
self.handle.sys_handle()
}
#[cfg(not(target_arch = "wasm32"))]
fn to_i420(&self) -> I420Buffer {
I420Buffer {
handle: self.handle.to_i420(),
}
}
#[cfg(not(target_arch = "wasm32"))]
fn to_argb(
&self,
format: VideoFormatType,
dst: &mut [u8],
stride: u32,
width: i32,
height: i32,
) -> Result<(), $crate::video_frame::native::ConvertError> {
self.handle.to_argb(format, dst, stride, width, height)
}
}
impl VideoFrameBuffer for $type {
fn width(&self) -> u32 {
self.handle.width()
}
fn height(&self) -> u32 {
self.handle.height()
}
fn buffer_type(&self) -> VideoFrameBufferType {
VideoFrameBufferType::$variant
}
fn $as(&self) -> Option<&$type> {
Some(self)
}
}
impl Debug for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(stringify!($type))
.field("width", &self.width())
.field("height", &self.height())
.finish()
}
}
impl AsRef<dyn VideoFrameBuffer> for $type {
fn as_ref(&self) -> &(dyn VideoFrameBuffer + 'static) {
self
}
}
};
}
new_buffer_type!(I420Buffer, I420, as_i420);
new_buffer_type!(I420ABuffer, I420A, as_i420a);
new_buffer_type!(I422Buffer, I422, as_i422);
@@ -175,24 +182,20 @@ new_buffer_type!(I010Buffer, I010, as_i010);
new_buffer_type!(NV12Buffer, NV12, as_nv12);
impl I420Buffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_u(&self) -> i32 {
self.handle.stride_u()
}
pub fn stride_v(&self) -> i32 {
self.handle.stride_v()
pub fn strides(&self) -> (u32, u32, u32) {
(
self.handle.stride_y(),
self.handle.stride_u(),
self.handle.stride_v(),
)
}
pub fn data(&self) -> (&[u8], &[u8], &[u8]) {
@@ -212,28 +215,21 @@ impl I420Buffer {
}
impl I420ABuffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_u(&self) -> i32 {
self.handle.stride_u()
}
pub fn stride_v(&self) -> i32 {
self.handle.stride_v()
}
pub fn stride_a(&self) -> i32 {
self.handle.stride_a()
pub fn strides(&self) -> (u32, u32, u32, u32) {
(
self.handle.stride_y(),
self.handle.stride_u(),
self.handle.stride_v(),
self.handle.stride_a(),
)
}
pub fn data(&self) -> (&[u8], &[u8], &[u8], Option<&[u8]>) {
@@ -256,24 +252,20 @@ impl I420ABuffer {
}
impl I422Buffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_u(&self) -> i32 {
self.handle.stride_u()
}
pub fn stride_v(&self) -> i32 {
self.handle.stride_v()
pub fn strides(&self) -> (u32, u32, u32) {
(
self.handle.stride_y(),
self.handle.stride_u(),
self.handle.stride_v(),
)
}
pub fn data(&self) -> (&[u8], &[u8], &[u8]) {
@@ -293,24 +285,20 @@ impl I422Buffer {
}
impl I444Buffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_u(&self) -> i32 {
self.handle.stride_u()
}
pub fn stride_v(&self) -> i32 {
self.handle.stride_v()
pub fn strides(&self) -> (u32, u32, u32) {
(
self.handle.stride_y(),
self.handle.stride_u(),
self.handle.stride_v(),
)
}
pub fn data(&self) -> (&[u8], &[u8], &[u8]) {
@@ -330,24 +318,20 @@ impl I444Buffer {
}
impl I010Buffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_u(&self) -> i32 {
self.handle.stride_u()
}
pub fn stride_v(&self) -> i32 {
self.handle.stride_v()
pub fn strides(&self) -> (u32, u32, u32) {
(
self.handle.stride_y(),
self.handle.stride_u(),
self.handle.stride_v(),
)
}
pub fn data(&self) -> (&[u16], &[u16], &[u16]) {
@@ -367,20 +351,16 @@ impl I010Buffer {
}
impl NV12Buffer {
pub fn chroma_width(&self) -> i32 {
pub fn chroma_width(&self) -> u32 {
self.handle.chroma_width()
}
pub fn chroma_height(&self) -> i32 {
pub fn chroma_height(&self) -> u32 {
self.handle.chroma_height()
}
pub fn stride_y(&self) -> i32 {
self.handle.stride_y()
}
pub fn stride_uv(&self) -> i32 {
self.handle.stride_uv()
pub fn strides(&self) -> (u32, u32) {
(self.handle.stride_y(), self.handle.stride_uv())
}
pub fn data(&self) -> (&[u8], &[u8]) {
@@ -423,7 +403,7 @@ pub mod native {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError>;
@@ -438,7 +418,7 @@ pub mod native {
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_stride: u32,
dst_width: i32,
dst_height: i32,
) -> Result<(), ConvertError> {
@@ -447,42 +427,6 @@ pub mod native {
}
}
impl<T: VideoFrameBuffer + ?Sized> internal::BufferInternal for Box<T> {
fn sys_handle(&self) -> &webrtc_sys::video_frame_buffer::ffi::VideoFrameBuffer {
self.as_ref().sys_handle()
}
fn to_i420(&self) -> I420Buffer {
self.as_ref().to_i420()
}
fn to_argb(
&self,
format: VideoFormatType,
dst: &mut [u8],
dst_stride: i32,
dst_width: i32,
dst_height: i32,
) -> Result<(), self::native::ConvertError> {
self.as_ref()
.to_argb(format, dst, dst_stride, dst_width, dst_height)
}
}
impl<T: VideoFrameBuffer + ?Sized> VideoFrameBuffer for Box<T> {
fn width(&self) -> i32 {
self.as_ref().width()
}
fn height(&self) -> i32 {
self.as_ref().height()
}
fn buffer_type(&self) -> VideoFrameBufferType {
self.as_ref().buffer_type()
}
}
#[cfg(target_arch = "wasm32")]
pub mod web {
use super::VideoFrameBuffer;
+1 -1
View File
@@ -18,7 +18,7 @@ pub mod native {
}
impl NativeVideoSource {
pub fn capture_frame<T: VideoFrameBuffer>(&self, frame: &VideoFrame<T>) {
pub fn capture_frame<T: AsRef<dyn VideoFrameBuffer>>(&self, frame: &VideoFrame<T>) {
self.handle.capture_frame(frame)
}
}