merge vpx/aom code
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
836323c9f4
commit
a11dee30ae
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/aom_ffi.rs"));
|
include!(concat!(env!("OUT_DIR"), "/aom_ffi.rs"));
|
||||||
|
|
||||||
use crate::{codec::EncoderApi, EncodeFrame, ImageFormat, ImageRgb, STRIDE_ALIGN};
|
use crate::{codec::EncoderApi, EncodeFrame, STRIDE_ALIGN};
|
||||||
|
use crate::{common::GoogleImage, generate_call_macro, generate_call_ptr_macro, Error, Result};
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
anyhow::{anyhow, Context},
|
anyhow::{anyhow, Context},
|
||||||
bytes::Bytes,
|
bytes::Bytes,
|
||||||
@ -15,6 +16,9 @@ use hbb_common::{
|
|||||||
};
|
};
|
||||||
use std::{ptr, slice};
|
use std::{ptr, slice};
|
||||||
|
|
||||||
|
generate_call_macro!(call_aom);
|
||||||
|
generate_call_ptr_macro!(call_aom_ptr);
|
||||||
|
|
||||||
impl Default for aom_codec_enc_cfg_t {
|
impl Default for aom_codec_enc_cfg_t {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
unsafe { std::mem::zeroed() }
|
unsafe { std::mem::zeroed() }
|
||||||
@ -33,60 +37,6 @@ impl Default for aom_image_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
FailedCall(String),
|
|
||||||
BadPtr(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
|
|
||||||
write!(f, "{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
||||||
|
|
||||||
macro_rules! call_aom {
|
|
||||||
($x:expr) => {{
|
|
||||||
let result = unsafe { $x }; // original expression
|
|
||||||
let result_int = unsafe { std::mem::transmute::<_, i32>(result) };
|
|
||||||
if result_int != 0 {
|
|
||||||
return Err(Error::FailedCall(format!(
|
|
||||||
"errcode={} {}:{}:{}:{}",
|
|
||||||
result_int,
|
|
||||||
module_path!(),
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
column!()
|
|
||||||
))
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! call_aom_ptr {
|
|
||||||
($x:expr) => {{
|
|
||||||
let result = unsafe { $x }; // original expression
|
|
||||||
let result_int = unsafe { std::mem::transmute::<_, isize>(result) };
|
|
||||||
if result_int == 0 {
|
|
||||||
return Err(Error::BadPtr(format!(
|
|
||||||
"errcode={} {}:{}:{}:{}",
|
|
||||||
result_int,
|
|
||||||
module_path!(),
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
column!()
|
|
||||||
))
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct AomEncoderConfig {
|
pub struct AomEncoderConfig {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
@ -508,16 +458,6 @@ impl Image {
|
|||||||
self.0.is_null()
|
self.0.is_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn width(&self) -> usize {
|
|
||||||
self.inner().d_w as _
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn height(&self) -> usize {
|
|
||||||
self.inner().d_h as _
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn format(&self) -> aom_img_fmt_t {
|
pub fn format(&self) -> aom_img_fmt_t {
|
||||||
self.inner().fmt
|
self.inner().fmt
|
||||||
@ -527,90 +467,27 @@ impl Image {
|
|||||||
pub fn inner(&self) -> &aom_image_t {
|
pub fn inner(&self) -> &aom_image_t {
|
||||||
unsafe { &*self.0 }
|
unsafe { &*self.0 }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GoogleImage for Image {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn stride(&self, iplane: usize) -> i32 {
|
fn width(&self) -> usize {
|
||||||
self.inner().stride[iplane]
|
self.inner().d_w as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize {
|
fn height(&self) -> usize {
|
||||||
let bytes_per_pixel = match fmt {
|
self.inner().d_h as _
|
||||||
ImageFormat::Raw => 3,
|
|
||||||
ImageFormat::ARGB | ImageFormat::ABGR => 4,
|
|
||||||
};
|
|
||||||
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128
|
|
||||||
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129
|
|
||||||
(w * bytes_per_pixel + stride - 1) & !(stride - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// rgb [in/out] fmt and stride must be set in ImageRgb
|
|
||||||
pub fn to(&self, rgb: &mut ImageRgb) {
|
|
||||||
rgb.w = self.width();
|
|
||||||
rgb.h = self.height();
|
|
||||||
let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride());
|
|
||||||
rgb.raw.resize(rgb.h * bytes_per_row, 0);
|
|
||||||
let img = self.inner();
|
|
||||||
unsafe {
|
|
||||||
match rgb.fmt() {
|
|
||||||
ImageFormat::Raw => {
|
|
||||||
super::I420ToRAW(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ImageFormat::ARGB => {
|
|
||||||
super::I420ToARGB(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ImageFormat::ABGR => {
|
|
||||||
super::I420ToABGR(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn data(&self) -> (&[u8], &[u8], &[u8]) {
|
fn stride(&self) -> Vec<i32> {
|
||||||
unsafe {
|
self.inner().stride.iter().map(|x| *x as i32).collect()
|
||||||
let img = self.inner();
|
}
|
||||||
let h = (img.d_h as usize + 1) & !1;
|
|
||||||
let n = img.stride[0] as usize * h;
|
#[inline]
|
||||||
let y = slice::from_raw_parts(img.planes[0], n);
|
fn planes(&self) -> Vec<*mut u8> {
|
||||||
let n = img.stride[1] as usize * (h >> 1);
|
self.inner().planes.iter().map(|p| *p as *mut u8).collect()
|
||||||
let u = slice::from_raw_parts(img.planes[1], n);
|
|
||||||
let v = slice::from_raw_parts(img.planes[2], n);
|
|
||||||
(y, u, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ use crate::mediacodec::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
aom::{self, AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig},
|
aom::{self, AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig},
|
||||||
|
common::GoogleImage,
|
||||||
vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId},
|
vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId},
|
||||||
CodecName, ImageRgb,
|
CodecName, ImageRgb,
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
pub use self::vpxcodec::*;
|
pub use self::vpxcodec::*;
|
||||||
use hbb_common::message_proto::{video_frame, VideoFrame};
|
use hbb_common::message_proto::{video_frame, VideoFrame};
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(quartz)] {
|
if #[cfg(quartz)] {
|
||||||
@ -185,3 +186,151 @@ impl ToString for CodecFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
FailedCall(String),
|
||||||
|
BadPtr(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! generate_call_macro {
|
||||||
|
($func_name:ident) => {
|
||||||
|
macro_rules! $func_name {
|
||||||
|
($x:expr) => {{
|
||||||
|
let result = unsafe { $x };
|
||||||
|
let result_int = unsafe { std::mem::transmute::<_, i32>(result) };
|
||||||
|
if result_int != 0 {
|
||||||
|
return Err(crate::Error::FailedCall(format!(
|
||||||
|
"errcode={} {}:{}:{}:{}",
|
||||||
|
result_int,
|
||||||
|
module_path!(),
|
||||||
|
file!(),
|
||||||
|
line!(),
|
||||||
|
column!()
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! generate_call_ptr_macro {
|
||||||
|
($func_name:ident) => {
|
||||||
|
macro_rules! $func_name {
|
||||||
|
($x:expr) => {{
|
||||||
|
let result = unsafe { $x };
|
||||||
|
let result_int = unsafe { std::mem::transmute::<_, isize>(result) };
|
||||||
|
if result_int == 0 {
|
||||||
|
return Err(crate::Error::BadPtr(format!(
|
||||||
|
"errcode={} {}:{}:{}:{}",
|
||||||
|
result_int,
|
||||||
|
module_path!(),
|
||||||
|
file!(),
|
||||||
|
line!(),
|
||||||
|
column!()
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GoogleImage {
|
||||||
|
fn width(&self) -> usize;
|
||||||
|
fn height(&self) -> usize;
|
||||||
|
fn stride(&self) -> Vec<i32>;
|
||||||
|
fn planes(&self) -> Vec<*mut u8>;
|
||||||
|
fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize {
|
||||||
|
let bytes_per_pixel = match fmt {
|
||||||
|
ImageFormat::Raw => 3,
|
||||||
|
ImageFormat::ARGB | ImageFormat::ABGR => 4,
|
||||||
|
};
|
||||||
|
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128
|
||||||
|
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129
|
||||||
|
(w * bytes_per_pixel + stride - 1) & !(stride - 1)
|
||||||
|
}
|
||||||
|
// rgb [in/out] fmt and stride must be set in ImageRgb
|
||||||
|
fn to(&self, rgb: &mut ImageRgb) {
|
||||||
|
rgb.w = self.width();
|
||||||
|
rgb.h = self.height();
|
||||||
|
let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride());
|
||||||
|
rgb.raw.resize(rgb.h * bytes_per_row, 0);
|
||||||
|
let stride = self.stride();
|
||||||
|
let planes = self.planes();
|
||||||
|
unsafe {
|
||||||
|
match rgb.fmt() {
|
||||||
|
ImageFormat::Raw => {
|
||||||
|
super::I420ToRAW(
|
||||||
|
planes[0],
|
||||||
|
stride[0],
|
||||||
|
planes[1],
|
||||||
|
stride[1],
|
||||||
|
planes[2],
|
||||||
|
stride[2],
|
||||||
|
rgb.raw.as_mut_ptr(),
|
||||||
|
bytes_per_row as _,
|
||||||
|
self.width() as _,
|
||||||
|
self.height() as _,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImageFormat::ARGB => {
|
||||||
|
super::I420ToARGB(
|
||||||
|
planes[0],
|
||||||
|
stride[0],
|
||||||
|
planes[1],
|
||||||
|
stride[1],
|
||||||
|
planes[2],
|
||||||
|
stride[2],
|
||||||
|
rgb.raw.as_mut_ptr(),
|
||||||
|
bytes_per_row as _,
|
||||||
|
self.width() as _,
|
||||||
|
self.height() as _,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImageFormat::ABGR => {
|
||||||
|
super::I420ToABGR(
|
||||||
|
planes[0],
|
||||||
|
stride[0],
|
||||||
|
planes[1],
|
||||||
|
stride[1],
|
||||||
|
planes[2],
|
||||||
|
stride[2],
|
||||||
|
rgb.raw.as_mut_ptr(),
|
||||||
|
bytes_per_row as _,
|
||||||
|
self.width() as _,
|
||||||
|
self.height() as _,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn data(&self) -> (&[u8], &[u8], &[u8]) {
|
||||||
|
unsafe {
|
||||||
|
let stride = self.stride();
|
||||||
|
let planes = self.planes();
|
||||||
|
let h = (self.height() as usize + 1) & !1;
|
||||||
|
let n = stride[0] as usize * h;
|
||||||
|
let y = slice::from_raw_parts(planes[0], n);
|
||||||
|
let n = stride[1] as usize * (h >> 1);
|
||||||
|
let u = slice::from_raw_parts(planes[1], n);
|
||||||
|
let v = slice::from_raw_parts(planes[2], n);
|
||||||
|
(y, u, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,14 +6,18 @@ use hbb_common::anyhow::{anyhow, Context};
|
|||||||
use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame};
|
use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame};
|
||||||
use hbb_common::ResultType;
|
use hbb_common::ResultType;
|
||||||
|
|
||||||
use crate::STRIDE_ALIGN;
|
use crate::codec::EncoderApi;
|
||||||
use crate::{codec::EncoderApi, ImageFormat, ImageRgb};
|
use crate::{GoogleImage, STRIDE_ALIGN};
|
||||||
|
|
||||||
use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *};
|
use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *};
|
||||||
|
use crate::{generate_call_macro, generate_call_ptr_macro, Error, Result};
|
||||||
use hbb_common::bytes::Bytes;
|
use hbb_common::bytes::Bytes;
|
||||||
use std::os::raw::{c_int, c_uint};
|
use std::os::raw::{c_int, c_uint};
|
||||||
use std::{ptr, slice};
|
use std::{ptr, slice};
|
||||||
|
|
||||||
|
generate_call_macro!(call_vpx);
|
||||||
|
generate_call_ptr_macro!(call_vpx_ptr);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum VpxVideoCodecId {
|
pub enum VpxVideoCodecId {
|
||||||
VP8,
|
VP8,
|
||||||
@ -37,60 +41,6 @@ pub struct VpxDecoder {
|
|||||||
ctx: vpx_codec_ctx_t,
|
ctx: vpx_codec_ctx_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
FailedCall(String),
|
|
||||||
BadPtr(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
|
|
||||||
write!(f, "{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
||||||
|
|
||||||
macro_rules! call_vpx {
|
|
||||||
($x:expr) => {{
|
|
||||||
let result = unsafe { $x }; // original expression
|
|
||||||
let result_int = unsafe { std::mem::transmute::<_, i32>(result) };
|
|
||||||
if result_int != 0 {
|
|
||||||
return Err(Error::FailedCall(format!(
|
|
||||||
"errcode={} {}:{}:{}:{}",
|
|
||||||
result_int,
|
|
||||||
module_path!(),
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
column!()
|
|
||||||
))
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! call_vpx_ptr {
|
|
||||||
($x:expr) => {{
|
|
||||||
let result = unsafe { $x }; // original expression
|
|
||||||
let result_int = unsafe { std::mem::transmute::<_, isize>(result) };
|
|
||||||
if result_int == 0 {
|
|
||||||
return Err(Error::BadPtr(format!(
|
|
||||||
"errcode={} {}:{}:{}:{}",
|
|
||||||
result_int,
|
|
||||||
module_path!(),
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
column!()
|
|
||||||
))
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EncoderApi for VpxEncoder {
|
impl EncoderApi for VpxEncoder {
|
||||||
fn new(cfg: crate::codec::EncoderCfg) -> ResultType<Self>
|
fn new(cfg: crate::codec::EncoderCfg) -> ResultType<Self>
|
||||||
where
|
where
|
||||||
@ -495,16 +445,6 @@ impl Image {
|
|||||||
self.0.is_null()
|
self.0.is_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn width(&self) -> usize {
|
|
||||||
self.inner().d_w as _
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn height(&self) -> usize {
|
|
||||||
self.inner().d_h as _
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn format(&self) -> vpx_img_fmt_t {
|
pub fn format(&self) -> vpx_img_fmt_t {
|
||||||
// VPX_IMG_FMT_I420
|
// VPX_IMG_FMT_I420
|
||||||
@ -515,90 +455,27 @@ impl Image {
|
|||||||
pub fn inner(&self) -> &vpx_image_t {
|
pub fn inner(&self) -> &vpx_image_t {
|
||||||
unsafe { &*self.0 }
|
unsafe { &*self.0 }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GoogleImage for Image {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn stride(&self, iplane: usize) -> i32 {
|
fn width(&self) -> usize {
|
||||||
self.inner().stride[iplane]
|
self.inner().d_w as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize {
|
fn height(&self) -> usize {
|
||||||
let bytes_per_pixel = match fmt {
|
self.inner().d_h as _
|
||||||
ImageFormat::Raw => 3,
|
|
||||||
ImageFormat::ARGB | ImageFormat::ABGR => 4,
|
|
||||||
};
|
|
||||||
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128
|
|
||||||
// https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129
|
|
||||||
(w * bytes_per_pixel + stride - 1) & !(stride - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// rgb [in/out] fmt and stride must be set in ImageRgb
|
|
||||||
pub fn to(&self, rgb: &mut ImageRgb) {
|
|
||||||
rgb.w = self.width();
|
|
||||||
rgb.h = self.height();
|
|
||||||
let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride());
|
|
||||||
rgb.raw.resize(rgb.h * bytes_per_row, 0);
|
|
||||||
let img = self.inner();
|
|
||||||
unsafe {
|
|
||||||
match rgb.fmt() {
|
|
||||||
ImageFormat::Raw => {
|
|
||||||
super::I420ToRAW(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ImageFormat::ARGB => {
|
|
||||||
super::I420ToARGB(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ImageFormat::ABGR => {
|
|
||||||
super::I420ToABGR(
|
|
||||||
img.planes[0],
|
|
||||||
img.stride[0],
|
|
||||||
img.planes[1],
|
|
||||||
img.stride[1],
|
|
||||||
img.planes[2],
|
|
||||||
img.stride[2],
|
|
||||||
rgb.raw.as_mut_ptr(),
|
|
||||||
bytes_per_row as _,
|
|
||||||
self.width() as _,
|
|
||||||
self.height() as _,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn data(&self) -> (&[u8], &[u8], &[u8]) {
|
fn stride(&self) -> Vec<i32> {
|
||||||
unsafe {
|
self.inner().stride.iter().map(|x| *x as i32).collect()
|
||||||
let img = self.inner();
|
}
|
||||||
let h = (img.d_h as usize + 1) & !1;
|
|
||||||
let n = img.stride[0] as usize * h;
|
#[inline]
|
||||||
let y = slice::from_raw_parts(img.planes[0], n);
|
fn planes(&self) -> Vec<*mut u8> {
|
||||||
let n = img.stride[1] as usize * (h >> 1);
|
self.inner().planes.iter().map(|p| *p as *mut u8).collect()
|
||||||
let u = slice::from_raw_parts(img.planes[1], n);
|
|
||||||
let v = slice::from_raw_parts(img.planes[2], n);
|
|
||||||
(y, u, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user