diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 76fe929e5..63f6c804c 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -1228,10 +1228,10 @@ packages: dependency: "direct main" description: name: texture_rgba_renderer - sha256: fbb09b2c6b4ce71261927f9e7e4ea339af3e2f3f2b175f6fb921de1c66ec848d + sha256: ec8d124e4c1d7dfff854ae34e95d7d9d877b8f9d291c383c67686e4b15cf538e url: "https://pub.dev" source: hosted - version: "0.0.8" + version: "0.0.12" timing: dependency: transitive description: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 71a840c9c..ccb53cc9c 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -92,7 +92,7 @@ dependencies: password_strength: ^0.2.0 flutter_launcher_icons: ^0.11.0 flutter_keyboard_visibility: ^5.4.0 - texture_rgba_renderer: ^0.0.8 + texture_rgba_renderer: ^0.0.12 percent_indicator: ^4.2.2 dev_dependencies: diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 3adc24a14..9e4b6fce4 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -306,7 +306,7 @@ impl Decoder { pub fn handle_video_frame( &mut self, frame: &video_frame::Union, - fmt: ImageFormat, + fmt: (ImageFormat, usize), rgb: &mut Vec, ) -> ResultType { match frame { @@ -352,7 +352,7 @@ impl Decoder { fn handle_vp9s_video_frame( decoder: &mut VpxDecoder, vp9s: &EncodedVideoFrames, - fmt: ImageFormat, + fmt: (ImageFormat, usize), rgb: &mut Vec, ) -> ResultType { let mut last_frame = Image::new(); @@ -369,7 +369,7 @@ impl Decoder { if last_frame.is_null() { Ok(false) } else { - last_frame.to(fmt, 1, rgb); + last_frame.to(fmt.0, fmt.1, rgb); Ok(true) } } @@ -378,7 +378,7 @@ impl Decoder { fn handle_hw_video_frame( decoder: &mut HwDecoder, frames: &EncodedVideoFrames, - fmt: ImageFormat, + fmt: (ImageFormat, usize), raw: &mut Vec, i420: &mut Vec, ) -> ResultType { @@ -398,7 +398,7 @@ impl Decoder { fn handle_mediacodec_video_frame( decoder: &mut MediaCodecDecoder, frames: &EncodedVideoFrames, - fmt: ImageFormat, + fmt: (ImageFormat, usize), raw: &mut Vec, ) -> ResultType { let mut ret = false; diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index d2b9f414f..4425c412d 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -236,7 +236,13 @@ pub struct HwDecoderImage<'a> { } impl HwDecoderImage<'_> { - pub fn to_fmt(&self, fmt: ImageFormat, fmt_data: &mut Vec, i420: &mut Vec) -> ResultType<()> { + // take dst_stride into account when you convert + pub fn to_fmt( + &self, + (fmt, dst_stride): (ImageFormat, usize), + fmt_data: &mut Vec, + i420: &mut Vec, + ) -> ResultType<()> { let frame = self.frame; match frame.pixfmt { AVPixelFormat::AV_PIX_FMT_NV12 => hw::hw_nv12_to( diff --git a/libs/scrap/src/common/mediacodec.rs b/libs/scrap/src/common/mediacodec.rs index 7bda0b69d..a0272d867 100644 --- a/libs/scrap/src/common/mediacodec.rs +++ b/libs/scrap/src/common/mediacodec.rs @@ -1,4 +1,4 @@ -use hbb_common::{log, anyhow::Error, bail, ResultType}; +use hbb_common::{anyhow::Error, bail, log, ResultType}; use ndk::media::media_codec::{MediaCodec, MediaCodecDirection, MediaFormat}; use std::ops::Deref; use std::{ @@ -50,7 +50,13 @@ impl MediaCodecDecoder { MediaCodecDecoders { h264, h265 } } - pub fn decode(&mut self, data: &[u8], fmt: ImageFormat, raw: &mut Vec) -> ResultType { + // take dst_stride into account please + pub fn decode( + &mut self, + data: &[u8], + (fmt, dst_stride): (ImageFormat, usize), + 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/src/client.rs b/src/client.rs index 40a9f05b0..ab27c0185 100644 --- a/src/client.rs +++ b/src/client.rs @@ -44,8 +44,7 @@ pub use helper::*; use scrap::{ codec::{Decoder, DecoderCfg}, record::{Recorder, RecorderContext}, - VpxDecoderConfig, VpxVideoCodecId, - ImageFormat, + ImageFormat, VpxDecoderConfig, VpxVideoCodecId, }; use crate::{ @@ -944,12 +943,11 @@ impl VideoHandler { } match &vf.union { Some(frame) => { - // windows && flutter_texture_render, fmt is ImageFormat::ABGR - #[cfg(all(target_os = "windows", feature = "flutter_texture_render"))] - let fmt = ImageFormat::ABGR; - #[cfg(not(all(target_os = "windows", feature = "flutter_texture_render")))] - let fmt = ImageFormat::ARGB; - let res = self.decoder.handle_video_frame(frame, fmt, &mut self.rgb); + let res = self.decoder.handle_video_frame( + frame, + (ImageFormat::ARGB, crate::DST_STRIDE_RGBA), + &mut self.rgb, + ); if self.record { self.recorder .lock() @@ -2038,7 +2036,7 @@ pub trait Interface: Send + Clone + 'static + Sized { fn is_force_relay(&self) -> bool { self.get_login_config_handler().read().unwrap().force_relay } - fn swap_modifier_mouse(&self, _msg : &mut hbb_common::protos::message::MouseEvent) {} + fn swap_modifier_mouse(&self, _msg: &mut hbb_common::protos::message::MouseEvent) {} } /// Data used by the client interface. diff --git a/src/common.rs b/src/common.rs index 5f24fd5c3..28d8dddc4 100644 --- a/src/common.rs +++ b/src/common.rs @@ -39,6 +39,13 @@ pub const CLIPBOARD_INTERVAL: u64 = 333; pub const SYNC_PEER_INFO_DISPLAYS: i32 = 1; +#[cfg(all(target_os = "macos", feature = "flutter_texture_render"))] +// https://developer.apple.com/forums/thread/712709 +// Memory alignment should be multiple of 64. +pub const DST_STRIDE_RGBA: usize = 64; +#[cfg(not(all(target_os = "macos", feature = "flutter_texture_render")))] +pub const DST_STRIDE_RGBA: usize = 1; + // the executable name of the portable version pub const PORTABLE_APPNAME_RUNTIME_ENV_KEY: &str = "RUSTDESK_APPNAME"; diff --git a/src/flutter.rs b/src/flutter.rs index 2f660775f..c69c2f802 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -153,8 +153,13 @@ pub struct FlutterHandler { } #[cfg(feature = "flutter_texture_render")] -pub type FlutterRgbaRendererPluginOnRgba = - unsafe extern "C" fn(texture_rgba: *mut c_void, buffer: *const u8, width: c_int, height: c_int); +pub type FlutterRgbaRendererPluginOnRgba = unsafe extern "C" fn( + texture_rgba: *mut c_void, + buffer: *const u8, + width: c_int, + height: c_int, + dst_rgba_stride: c_int, +); // Video Texture Renderer in Flutter #[cfg(feature = "flutter_texture_render")] @@ -206,7 +211,9 @@ impl VideoRenderer { self.width = width; self.height = height; self.data_len = if width > 0 && height > 0 { - (width * height * 4) as usize + let sa1 = crate::DST_STRIDE_RGBA - 1; + let row_bytes = (width as usize * 4 + sa1) & !sa1; + row_bytes * height as usize } else { 0 }; @@ -223,6 +230,7 @@ impl VideoRenderer { rgba.as_ptr() as _, self.width as _, self.height as _, + crate::DST_STRIDE_RGBA as _, ) }; }