Skip to content

Commit

Permalink
fix android get raw data (rustdesk#8171)
Browse files Browse the repository at this point in the history
If `std::ptr::copy_nonoverlapping` is not in `take`, it's not protected by the lock.

Signed-off-by: 21pages <[email protected]>
  • Loading branch information
21pages authored May 28, 2024
1 parent 278d593 commit 010b175
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
19 changes: 13 additions & 6 deletions libs/scrap/src/android/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>, last: &mut Vec<u8>) -> Option<()> {
if self.enable.not() {
return None;
}
Expand All @@ -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(())
}
}

Expand All @@ -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<u8>, last: &mut Vec<u8>) -> 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<u8>, last: &mut Vec<u8>) -> Option<()> {
AUDIO_RAW.lock().ok()?.take(dst, last)
}

#[no_mangle]
Expand Down
8 changes: 1 addition & 7 deletions libs/scrap/src/common/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,7 @@ impl Capturer {

impl crate::TraitCapturer for Capturer {
fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result<Frame<'a>> {
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(),
Expand Down
9 changes: 7 additions & 2 deletions src/server/audio_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ mod pa_impl {
);
#[cfg(target_os = "linux")]
let zero_audio_frame: Vec<f32> = 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));
Expand All @@ -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::<f32>(data.as_ptr() as _, data.len() / 4)
std::slice::from_raw_parts::<f32>(
android_data.as_ptr() as _,
android_data.len() / 4,
)
};
send_f32(data, &mut encoder, &sp);
} else {
Expand Down

0 comments on commit 010b175

Please sign in to comment.