From 010b17509ae86cadfa29c2085fd0e641b155c8bb Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 28 May 2024 16:35:59 +0800 Subject: [PATCH] fix android get raw data (#8171) If `std::ptr::copy_nonoverlapping` is not in `take`, it's not protected by the lock. Signed-off-by: 21pages --- libs/scrap/src/android/ffi.rs | 19 +++++++++++++------ libs/scrap/src/common/android.rs | 8 +------- src/server/audio_service.rs | 9 +++++++-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs index 5a511a5dd..ca90b5986 100644 --- a/libs/scrap/src/android/ffi.rs +++ b/libs/scrap/src/android/ffi.rs @@ -65,7 +65,7 @@ impl FrameRaw { // take inner data as slice // release when success - fn take<'a>(&mut self) -> Option<&'a [u8]> { + fn take<'a>(&mut self, dst: &mut Vec, last: &mut Vec) -> Option<()> { if self.enable.not() { return None; } @@ -79,7 +79,14 @@ impl FrameRaw { } let slice = unsafe { std::slice::from_raw_parts(ptr, self.len) }; self.release(); - Some(slice) + if last.len() == slice.len() && crate::would_block_if_equal(last, slice).is_err() { + return None; + } + dst.resize(slice.len(), 0); + unsafe { + std::ptr::copy_nonoverlapping(slice.as_ptr(), dst.as_mut_ptr(), slice.len()); + } + Some(()) } } @@ -89,12 +96,12 @@ impl FrameRaw { } } -pub fn get_video_raw<'a>() -> Option<&'a [u8]> { - VIDEO_RAW.lock().ok()?.take() +pub fn get_video_raw<'a>(dst: &mut Vec, last: &mut Vec) -> Option<()> { + VIDEO_RAW.lock().ok()?.take(dst, last) } -pub fn get_audio_raw<'a>() -> Option<&'a [u8]> { - AUDIO_RAW.lock().ok()?.take() +pub fn get_audio_raw<'a>(dst: &mut Vec, last: &mut Vec) -> Option<()> { + AUDIO_RAW.lock().ok()?.take(dst, last) } #[no_mangle] diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs index f0aeeee4d..dffbc9ff7 100644 --- a/libs/scrap/src/common/android.rs +++ b/libs/scrap/src/common/android.rs @@ -36,13 +36,7 @@ impl Capturer { impl crate::TraitCapturer for Capturer { fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> { - if let Some(buf) = get_video_raw() { - crate::would_block_if_equal(&mut self.saved_raw_data, buf)?; - // Is it safe to directly return buf without copy? - self.rgba.resize(buf.len(), 0); - unsafe { - std::ptr::copy_nonoverlapping(buf.as_ptr(), self.rgba.as_mut_ptr(), buf.len()) - }; + if get_video_raw(&mut self.rgba, &mut self.saved_raw_data).is_some() { Ok(Frame::PixelBuffer(PixelBuffer::new( &self.rgba, self.width(), diff --git a/src/server/audio_service.rs b/src/server/audio_service.rs index 7b4feeb4f..031d4e673 100644 --- a/src/server/audio_service.rs +++ b/src/server/audio_service.rs @@ -68,6 +68,8 @@ mod pa_impl { ); #[cfg(target_os = "linux")] let zero_audio_frame: Vec = vec![0.; AUDIO_DATA_SIZE_U8 / 4]; + #[cfg(target_os = "android")] + let mut android_data = vec![]; while sp.ok() && !RESTARTING.load(Ordering::SeqCst) { sp.snapshot(|sps| { sps.send(create_format_msg(crate::platform::PA_SAMPLE_RATE, 2)); @@ -88,9 +90,12 @@ mod pa_impl { send_f32(data, &mut encoder, &sp); } #[cfg(target_os = "android")] - if let Some(data) = scrap::android::ffi::get_audio_raw() { + if scrap::android::ffi::get_audio_raw(&mut android_data, &mut vec![]).is_some() { let data = unsafe { - std::slice::from_raw_parts::(data.as_ptr() as _, data.len() / 4) + std::slice::from_raw_parts::( + android_data.as_ptr() as _, + android_data.len() / 4, + ) }; send_f32(data, &mut encoder, &sp); } else {