Debug suite à revue de code

This commit is contained in:
2025-10-27 23:18:23 +01:00
parent f77376e07c
commit a1170a8689
5 changed files with 485 additions and 407 deletions

View File

@@ -153,6 +153,9 @@ where
let (info_tx, info_rx) = oneshot::channel::<Result<StreamInfo, AiffError>>();
let blocking_handle = tokio::task::spawn_blocking(move || -> Result<(), AiffError> {
let mut info_tx = Some(info_tx);
let result: Result<(), AiffError> = (|| {
let channel_reader = ChannelReader::<AiffError>::new(ingest_rx);
let mut aiff_reader = StreamingAiffReader::new(channel_reader);
@@ -197,7 +200,8 @@ where
return Err(AiffError::Decode("COMM chunk too small for AIFC".into()));
}
let channels = u16::from_be_bytes([data[0], data[1]]);
let num_frames = u32::from_be_bytes([data[2], data[3], data[4], data[5]]);
let num_frames =
u32::from_be_bytes([data[2], data[3], data[4], data[5]]);
let bits_per_sample = u16::from_be_bytes([data[6], data[7]]);
let sample_rate = parse_extended_f80(&data[8..18])?;
@@ -242,10 +246,12 @@ where
})?;
let header = aiff_reader.read_exact_vec(8)?;
let offset =
u32::from_be_bytes([header[0], header[1], header[2], header[3]]) as usize;
let _block_size =
u32::from_be_bytes([header[4], header[5], header[6], header[7]]) as usize;
let offset = u32::from_be_bytes([
header[0], header[1], header[2], header[3],
]) as usize;
let _block_size = u32::from_be_bytes([
header[4], header[5], header[6], header[7],
]) as usize;
if offset > 0 {
aiff_reader.skip(offset)?;
@@ -266,9 +272,11 @@ where
};
if !stream_info_sent {
if info_tx.send(Ok(info.clone())).is_err() {
if let Some(tx) = info_tx.take() {
if tx.send(Ok(info.clone())).is_err() {
return Ok(());
}
}
stream_info_sent = true;
}
@@ -323,6 +331,17 @@ where
}
Ok(())
})();
match result {
Ok(()) => Ok(()),
Err(err) => {
if let Some(tx) = info_tx.take() {
let _ = tx.send(Err(err.clone()));
}
Err(err)
}
}
});
let writer_handle = spawn_writer_task(pcm_rx, pcm_writer, blocking_handle, "aiff-decode");

View File

@@ -184,8 +184,12 @@ where
let (info_tx, info_rx) = oneshot::channel::<Result<StreamInfo, OggError>>();
let blocking_handle = tokio::task::spawn_blocking(move || -> Result<(), OggError> {
let mut info_tx = Some(info_tx);
let result: Result<(), OggError> = (|| {
let channel_reader = ChannelReader::<OggContainerError>::new(ingest_rx);
let mut packet_reader = OggPacketReader::new(channel_reader, OggReaderOptions::default());
let mut packet_reader =
OggPacketReader::new(channel_reader, OggReaderOptions::default());
// Read Vorbis headers (3 packets: identification, comment, setup)
let ident_packet = packet_reader
@@ -216,9 +220,11 @@ where
min_block_size: 1 << ident_hdr.blocksize_0,
};
if info_tx.send(Ok(info.clone())).is_err() {
if let Some(tx) = info_tx.take() {
if tx.send(Ok(info.clone())).is_err() {
return Ok(());
}
}
// Decode audio packets
let mut pcm_bytes = Vec::new();
@@ -259,6 +265,17 @@ where
}
Ok(())
})();
match result {
Ok(()) => Ok(()),
Err(err) => {
if let Some(tx) = info_tx.take() {
let _ = tx.send(Err(err.clone()));
}
Err(err)
}
}
});
let writer_handle = spawn_writer_task(pcm_rx, pcm_writer, blocking_handle, "ogg-decode");

View File

@@ -82,6 +82,7 @@ pub struct OggPacketReader {
finished: bool,
stream_serial: Option<u32>,
sync_buffer: Vec<u8>,
sync_bytes_read: usize,
synced: bool,
options: OggReaderOptions,
}
@@ -96,6 +97,7 @@ impl OggPacketReader {
finished: false,
stream_serial: None,
sync_buffer: Vec::new(),
sync_bytes_read: 0,
synced: !options.find_sync, // If we don't need to find sync, we're already synced
options,
}
@@ -183,14 +185,21 @@ impl OggPacketReader {
return Ok(());
}
while self.sync_buffer.len() < self.options.max_sync_search {
while self.sync_bytes_read < self.options.max_sync_search {
let mut chunk = [0u8; 1024];
let n = Read::read(&mut self.reader, &mut chunk).map_err(OggContainerError::from)?;
let remaining = self.options.max_sync_search - self.sync_bytes_read;
let to_read = remaining.min(chunk.len());
if to_read == 0 {
break;
}
let n = Read::read(&mut self.reader, &mut chunk[..to_read])
.map_err(OggContainerError::from)?;
if n == 0 {
return Err(OggContainerError::Decode(
"EOF reached while searching for Ogg sync pattern".into(),
));
}
self.sync_bytes_read += n;
self.sync_buffer.extend_from_slice(&chunk[..n]);
// Search for "OggS" pattern
@@ -205,9 +214,8 @@ impl OggPacketReader {
return Ok(());
}
// If buffer is getting large and still no sync, keep only last 3 bytes
// (in case "OggS" is split across chunk boundary)
if self.sync_buffer.len() >= self.options.max_sync_search {
// Keep the buffer compact to avoid unbounded growth.
if self.sync_buffer.len() > 3 {
let keep_len = 3.min(self.sync_buffer.len());
self.sync_buffer.drain(..self.sync_buffer.len() - keep_len);
}

View File

@@ -48,6 +48,9 @@ where
let (info_tx, info_rx) = oneshot::channel::<Result<StreamInfo, OggOpusError>>();
let blocking_handle = tokio::task::spawn_blocking(move || -> Result<(), OggOpusError> {
let mut info_tx = Some(info_tx);
let result: Result<(), OggOpusError> = (|| {
let channel_reader = ChannelReader::<OggContainerError>::new(ingest_rx);
let mut packet_reader = OggPacketReader::new(
channel_reader,
@@ -93,9 +96,11 @@ where
min_block_size: 0,
};
if info_tx.send(Ok(info.clone())).is_err() {
if let Some(tx) = info_tx.take() {
if tx.send(Ok(info.clone())).is_err() {
return Ok(());
}
}
let channels = header.channels as usize;
let mut pcm_buffer = vec![0i16; MAX_FRAME_SAMPLES * channels];
@@ -141,10 +146,11 @@ where
}
produced_audio = true;
let chunk = pcm_bytes.clone();
let chunk = std::mem::take(&mut pcm_bytes);
if pcm_tx.blocking_send(Ok(chunk)).is_err() {
break;
}
pcm_bytes = Vec::with_capacity(MAX_FRAME_SAMPLES * channels * 2);
}
if !produced_audio {
@@ -154,6 +160,17 @@ where
}
Ok(())
})();
match result {
Ok(()) => Ok(()),
Err(err) => {
if let Some(tx) = info_tx.take() {
let _ = tx.send(Err(err.clone()));
}
Err(err)
}
}
});
let writer_handle = spawn_writer_task(pcm_rx, pcm_writer, blocking_handle, "ogg-opus");

View File

@@ -157,6 +157,9 @@ where
let (info_tx, info_rx) = oneshot::channel::<Result<StreamInfo, WavError>>();
let blocking_handle = tokio::task::spawn_blocking(move || -> Result<(), WavError> {
let mut info_tx = Some(info_tx);
let result: Result<(), WavError> = (|| {
let channel_reader = ChannelReader::<WavError>::new(ingest_rx);
let mut wav_reader = StreamingWavReader::new(channel_reader);
@@ -196,7 +199,8 @@ where
}
let audio_format = u16::from_le_bytes([bytes[0], bytes[1]]);
let channels = u16::from_le_bytes([bytes[2], bytes[3]]);
let sample_rate = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let sample_rate =
u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let bits_per_sample = u16::from_le_bytes([bytes[14], bytes[15]]);
let fmt = FmtChunk {
audio_format,
@@ -211,9 +215,9 @@ where
}
}
b"data" => {
let fmt = fmt_chunk
.as_ref()
.ok_or_else(|| WavError::Decode("data chunk before fmt chunk".into()))?;
let fmt = fmt_chunk.as_ref().ok_or_else(|| {
WavError::Decode("data chunk before fmt chunk".into())
})?;
let info = StreamInfo {
sample_rate: fmt.sample_rate,
@@ -224,9 +228,11 @@ where
min_block_size: 0,
};
if info_tx.send(Ok(info.clone())).is_err() {
if let Some(tx) = info_tx.take() {
if tx.send(Ok(info.clone())).is_err() {
return Ok(());
}
}
let mut remaining = chunk_size;
let bytes_per_frame = fmt.bytes_per_sample() * fmt.channels as usize;
@@ -277,6 +283,17 @@ where
}
Ok(())
})();
match result {
Ok(()) => Ok(()),
Err(err) => {
if let Some(tx) = info_tx.take() {
let _ = tx.send(Err(err.clone()));
}
Err(err)
}
}
});
let writer_handle = spawn_writer_task(pcm_rx, pcm_writer, blocking_handle, "wav-decode");