Skip to content

Commit

Permalink
re-implement changes to generalize frame copying
Browse files Browse the repository at this point in the history
  • Loading branch information
Xaeroxe committed Jul 16, 2024
1 parent 3679a9a commit 0e42f26
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 16 deletions.
29 changes: 13 additions & 16 deletions xcoder/xcoder-quadra/src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use av_traits::{EncodedFrameType, EncodedVideoFrame, RawVideoFrame, VideoEncoder
use scopeguard::{guard, ScopeGuard};
use snafu::Snafu;
use std::{
collections::VecDeque,
mem::{self, MaybeUninit},
os::raw::c_void,
array, collections::VecDeque, mem::{self, MaybeUninit}, os::raw::c_void, ptr::null_mut
};
use xcoder_quadra_sys::{self as sys, ni_packet_t, ni_xcoder_params_t};

Expand Down Expand Up @@ -233,7 +231,7 @@ impl<F> XcoderEncoder<F> {
sys::ni_get_frame_dim(
config.width as _,
config.height as _,
if config.bit_depth > 8 { 2 } else { 1 }, // bit depth factor
config.pixel_format.repr(),
frame_data_strides.as_mut_ptr(),
frame_data_heights.as_mut_ptr(),
);
Expand Down Expand Up @@ -462,23 +460,22 @@ impl<F: RawVideoFrame<u8>> XcoderEncoder<F> {
}

let mut dst_data = [frame.p_data[0], frame.p_data[1], frame.p_data[2]];

let mut src_data = [
f.samples(0).as_ptr() as *mut u8,
f.samples(1).as_ptr() as *mut u8,
f.samples(2).as_ptr() as *mut u8,
];
let mut src_strides = [self.config.width as i32, self.config.width as i32 / 2, self.config.width as i32 / 2];
let mut src_heights = [self.config.height as i32, self.config.height as i32 / 2, self.config.height as i32 / 2];

let mut src_data: [*mut u8; 3] = array::from_fn(|i| if i < self.config.pixel_format.plane_count() {
f.samples(i).as_ptr() as *mut u8
} else {
null_mut()
});
let mut src_strides = self.config.pixel_format.strides(self.config.width as i32);
let mut src_heights = self.config.pixel_format.heights(self.config.height as i32);
let factor = if self.config.pixel_format.ten_bit() { 2 } else { 1 };
unsafe {
sys::ni_copy_hw_yuv420p(
sys::ni_copy_frame_data(
dst_data.as_mut_ptr(),
src_data.as_mut_ptr(),
self.config.width as _,
self.config.height as _,
1,
0,
factor,
self.config.pixel_format.repr(),
0,
self.frame_data_strides.as_mut_ptr(),
self.frame_data_heights.as_mut_ptr(),
Expand Down
67 changes: 67 additions & 0 deletions xcoder/xcoder-quadra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,73 @@ mod linux_impl {
Uyvy422 = sys::ni_pix_fmt_t_NI_PIX_FMT_UYVY422,
None = sys::ni_pix_fmt_t_NI_PIX_FMT_NONE,
}

impl XcoderPixelFormat {
pub fn ten_bit(&self) -> bool {
use XcoderPixelFormat::*;
matches!(self, Yuv420Planar10BitLittleEndian | P010LittleEndian)
}

/// Returns how many planes are in the layout. For semi-planar formats, a plane containing multiple
/// types of data is still considered to be one plane.
pub fn plane_count(&self) -> usize {
match self {
XcoderPixelFormat::Yuv420Planar |
XcoderPixelFormat::Yuv420Planar10BitLittleEndian => 3,
XcoderPixelFormat::Nv12 |
XcoderPixelFormat::Nv16 |
XcoderPixelFormat::P010LittleEndian => 2,
XcoderPixelFormat::Rgba |
XcoderPixelFormat::Bgra |
XcoderPixelFormat::Argb |
XcoderPixelFormat::Abgr |
XcoderPixelFormat::Bgr0 |
XcoderPixelFormat::Bgrp |
XcoderPixelFormat::Yuyv422 |
XcoderPixelFormat::Uyvy422 => 1,
XcoderPixelFormat::None => 0,
}
}

pub fn strides(&self, width: i32) -> [i32; 3] {
match self {
XcoderPixelFormat::Yuv420Planar => [width, width / 2, width / 2],
XcoderPixelFormat::Yuv420Planar10BitLittleEndian => [width * 2, width, width],
XcoderPixelFormat::Nv12 => [width, width, 0],
XcoderPixelFormat::P010LittleEndian => [width * 2, width * 2, 0],
XcoderPixelFormat::Rgba |
XcoderPixelFormat::Bgra |
XcoderPixelFormat::Argb |
XcoderPixelFormat::Abgr |
XcoderPixelFormat::Bgr0 => [width * 4, 0, 0],
XcoderPixelFormat::Bgrp => [width * 3, 0, 0],
XcoderPixelFormat::Nv16 |
XcoderPixelFormat::Yuyv422 |
XcoderPixelFormat::Uyvy422 => [width, width / 2, 0],
XcoderPixelFormat::None => [0; 3],
}
}

pub fn heights(&self, height: i32) -> [i32; 3] {
match self {
XcoderPixelFormat::Yuv420Planar |
XcoderPixelFormat::Yuv420Planar10BitLittleEndian => [height, height / 2, height / 2],
XcoderPixelFormat::Nv12 |
XcoderPixelFormat::P010LittleEndian => [height, height / 2, 0],
XcoderPixelFormat::Rgba |
XcoderPixelFormat::Bgra |
XcoderPixelFormat::Argb |
XcoderPixelFormat::Abgr |
XcoderPixelFormat::Bgr0 |
XcoderPixelFormat::Bgrp => [height, 0, 0],
XcoderPixelFormat::Nv16 |
XcoderPixelFormat::Yuyv422 |
XcoderPixelFormat::Uyvy422 => [height, height, 0],
XcoderPixelFormat::None => [0; 3],
}
}

}
}

#[cfg(target_os = "linux")]
Expand Down

0 comments on commit 0e42f26

Please sign in to comment.