fix mis-align problem when converting &[u8] to &[f32] (#9986)
Some checks are pending
CI / ${{ matrix.job.target }} (${{ matrix.job.os }}) (map[os:ubuntu-20.04 target:x86_64-unknown-linux-gnu]) (push) Waiting to run
Full Flutter CI / run-ci (push) Waiting to run

* fix: windows, improve audio buffer (#9770)

* .

* fix statics does not record

and avoid channel changing when drio audio when audio is stero

* add some commence

* fix mis-align problem when converting &[u8] to &[f32]

* add safety commence

* revert client.rs

* avoid tmp lifetime extends

* avoid move in loop

* avoid use after drop

* another use after free

* another use after free

* make code more reasonable

---------

Co-authored-by: zylthinking <zhaoyulong@qianxin.com>
This commit is contained in:
zyl 2024-11-21 13:36:11 +08:00 committed by GitHub
parent d26fea41ee
commit 74dd0c8fa0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 0 deletions

View File

@ -27,6 +27,7 @@ pub use anyhow::{self, bail};
pub use futures_util; pub use futures_util;
pub mod config; pub mod config;
pub mod fs; pub mod fs;
pub mod mem;
pub use lazy_static; pub use lazy_static;
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use mac_address; pub use mac_address;

View File

@ -0,0 +1,14 @@
/// SAFETY: the returned Vec must not be resized or reserverd
pub unsafe fn aligned_u8_vec(cap: usize, align: usize) -> Vec<u8> {
use std::alloc::*;
let layout =
Layout::from_size_align(cap, align).expect("invalid aligned value, must be power of 2");
unsafe {
let ptr = alloc(layout);
if ptr.is_null() {
panic!("failed to allocate {} bytes", cap);
}
Vec::from_raw_parts(ptr, 0, cap)
}
}

View File

@ -78,6 +78,19 @@ pub fn restart() {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
mod pa_impl { mod pa_impl {
use super::*; use super::*;
// SAFETY: constrains of hbb_common::mem::aligned_u8_vec must be held
unsafe fn align_to_32(data: Vec<u8>) -> Vec<u8> {
if (data.as_ptr() as usize & 3) == 0 {
return data;
}
let mut buf = vec![];
buf = unsafe { hbb_common::mem::aligned_u8_vec(data.len(), 4) };
buf.extend_from_slice(data.as_ref());
buf
}
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
pub async fn run(sp: EmptyExtraFieldService) -> ResultType<()> { pub async fn run(sp: EmptyExtraFieldService) -> ResultType<()> {
hbb_common::sleep(0.1).await; // one moment to wait for _pa ipc hbb_common::sleep(0.1).await; // one moment to wait for _pa ipc
@ -106,23 +119,29 @@ mod pa_impl {
sps.send(create_format_msg(crate::platform::PA_SAMPLE_RATE, 2)); sps.send(create_format_msg(crate::platform::PA_SAMPLE_RATE, 2));
Ok(()) Ok(())
})?; })?;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
if let Ok(data) = stream.next_raw().await { if let Ok(data) = stream.next_raw().await {
if data.len() == 0 { if data.len() == 0 {
send_f32(&zero_audio_frame, &mut encoder, &sp); send_f32(&zero_audio_frame, &mut encoder, &sp);
continue; continue;
} }
if data.len() != AUDIO_DATA_SIZE_U8 { if data.len() != AUDIO_DATA_SIZE_U8 {
continue; continue;
} }
let data = unsafe { align_to_32(data.into()) };
let data = unsafe { let data = unsafe {
std::slice::from_raw_parts::<f32>(data.as_ptr() as _, data.len() / 4) std::slice::from_raw_parts::<f32>(data.as_ptr() as _, data.len() / 4)
}; };
send_f32(data, &mut encoder, &sp); send_f32(data, &mut encoder, &sp);
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
if scrap::android::ffi::get_audio_raw(&mut android_data, &mut vec![]).is_some() { if scrap::android::ffi::get_audio_raw(&mut android_data, &mut vec![]).is_some() {
let data = unsafe { let data = unsafe {
android_data = align_to_32(android_data);
std::slice::from_raw_parts::<f32>( std::slice::from_raw_parts::<f32>(
android_data.as_ptr() as _, android_data.as_ptr() as _,
android_data.len() / 4, android_data.len() / 4,