From 5aa97faedd6e7b286801aab8fc02f33d5a8de787 Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 3 Mar 2023 09:27:51 +0800 Subject: [PATCH] Fix stride align Signed-off-by: fufesou --- libs/scrap/src/common/codec.rs | 6 ++++-- libs/scrap/src/common/hwcodec.rs | 10 +++++----- libs/scrap/src/common/mediacodec.rs | 3 ++- libs/scrap/src/common/vpxcodec.rs | 16 +++++++++------- src/common.rs | 4 +++- src/flutter.rs | 4 ++-- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 868a93f5a..1aada72e2 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -380,6 +380,7 @@ impl Decoder { fn handle_hw_video_frame( decoder: &mut HwDecoder, frames: &EncodedVideoFrames, + stride_align: usize, fmt: ImageFormat, raw: &mut Vec, i420: &mut Vec, @@ -388,7 +389,7 @@ impl Decoder { for h264 in frames.frames.iter() { for image in decoder.decode(&h264.data)? { // TODO: just process the last frame - if image.to_fmt(fmt, raw, i420).is_ok() { + if image.to_fmt(stride_align, fmt, raw, i420).is_ok() { ret = true; } } @@ -400,12 +401,13 @@ impl Decoder { fn handle_mediacodec_video_frame( decoder: &mut MediaCodecDecoder, frames: &EncodedVideoFrames, + stride_align: usize, fmt: ImageFormat, raw: &mut Vec, ) -> ResultType { let mut ret = false; for h264 in frames.frames.iter() { - return decoder.decode(&h264.data, fmt, raw); + return decoder.decode(&h264.data, stride_align, fmt, raw); } return Ok(false); } diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index d2b9f414f..82f8b7283 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -236,7 +236,7 @@ pub struct HwDecoderImage<'a> { } impl HwDecoderImage<'_> { - pub fn to_fmt(&self, fmt: ImageFormat, fmt_data: &mut Vec, i420: &mut Vec) -> ResultType<()> { + pub fn to_fmt(&self, stride_align: usize, fmt: ImageFormat, fmt_data: &mut Vec, i420: &mut Vec) -> ResultType<()> { let frame = self.frame; match frame.pixfmt { AVPixelFormat::AV_PIX_FMT_NV12 => hw::hw_nv12_to( @@ -269,12 +269,12 @@ impl HwDecoderImage<'_> { } } - pub fn bgra(&self, bgra: &mut Vec, i420: &mut Vec) -> ResultType<()> { - self.to_fmt(ImageFormat::ARGB, bgra, i420) + pub fn bgra(&self, stride_align: usize, bgra: &mut Vec, i420: &mut Vec) -> ResultType<()> { + self.to_fmt(stride_align, ImageFormat::ARGB, bgra, i420) } - pub fn rgba(&self, rgba: &mut Vec, i420: &mut Vec) -> ResultType<()> { - self.to_fmt(ImageFormat::ABGR, rgba, i420) + pub fn rgba(&self, stride_align: usize, rgba: &mut Vec, i420: &mut Vec) -> ResultType<()> { + self.to_fmt(stride_align, ImageFormat::ABGR, rgba, i420) } } diff --git a/libs/scrap/src/common/mediacodec.rs b/libs/scrap/src/common/mediacodec.rs index 7bda0b69d..694a5e3ed 100644 --- a/libs/scrap/src/common/mediacodec.rs +++ b/libs/scrap/src/common/mediacodec.rs @@ -50,7 +50,8 @@ impl MediaCodecDecoder { MediaCodecDecoders { h264, h265 } } - pub fn decode(&mut self, data: &[u8], fmt: ImageFormat, raw: &mut Vec) -> ResultType { + // to-do: apply stride_align to raw output data + pub fn decode(&mut self, data: &[u8], stride_align: usize, fmt: ImageFormat, raw: &mut Vec) -> ResultType { match self.dequeue_input_buffer(Duration::from_millis(10))? { Some(mut input_buffer) => { let mut buf = input_buffer.buffer_mut(); diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs index 7a65b193d..a94db61b4 100644 --- a/libs/scrap/src/common/vpxcodec.rs +++ b/libs/scrap/src/common/vpxcodec.rs @@ -541,13 +541,15 @@ impl Image { pub fn to(&self, fmt: ImageFormat, stride_align: usize, dst: &mut Vec) { let h = self.height(); - let mut w = self.width(); - let bps = match fmt { + let w = self.width(); + let bytes_per_pixel = match fmt { ImageFormat::Raw => 3, ImageFormat::ARGB | ImageFormat::ABGR => 4, }; - w = (w + stride_align - 1) & !(stride_align - 1); - dst.resize(h * w * bps, 0); + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128 + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129 + let bytes_per_row = (w * bytes_per_pixel + stride_align - 1) & !(stride_align - 1); + dst.resize(h * bytes_per_row, 0); let img = self.inner(); unsafe { match fmt { @@ -560,7 +562,7 @@ impl Image { img.planes[2], img.stride[2], dst.as_mut_ptr(), - (w * bps) as _, + bytes_per_row as _, self.width() as _, self.height() as _, ); @@ -574,7 +576,7 @@ impl Image { img.planes[2], img.stride[2], dst.as_mut_ptr(), - (w * bps) as _, + bytes_per_row as _, self.width() as _, self.height() as _, ); @@ -588,7 +590,7 @@ impl Image { img.planes[2], img.stride[2], dst.as_mut_ptr(), - (w * bps) as _, + bytes_per_row as _, self.width() as _, self.height() as _, ); diff --git a/src/common.rs b/src/common.rs index a6ef0142b..181f283e1 100644 --- a/src/common.rs +++ b/src/common.rs @@ -40,7 +40,9 @@ pub const CLIPBOARD_INTERVAL: u64 = 333; pub const SYNC_PEER_INFO_DISPLAYS: i32 = 1; #[cfg(all(target_os = "macos", feature = "flutter_texture_render"))] -pub const STRIDE_ALIGN: usize = 16; +// https://developer.apple.com/forums/thread/712709 +// Memory alignment should be multiple of 64. +pub const STRIDE_ALIGN: usize = 64; #[cfg(not(all(target_os = "macos", feature = "flutter_texture_render")))] pub const STRIDE_ALIGN: usize = 1; diff --git a/src/flutter.rs b/src/flutter.rs index 6d4f143fb..4984dbdb4 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -207,8 +207,8 @@ impl VideoRenderer { self.height = height; self.data_len = if width > 0 && height > 0 { let sa1 = crate::common::STRIDE_ALIGN - 1; - let w = (width as usize + sa1) & !sa1; - w * (height as usize) * 4 + let row_bytes = (width as usize * 4 + sa1) & !sa1; + row_bytes * height as usize } else { 0 };