Handle format reset and decode errors.

This change fixes two issues with the error handling of the
Symphonia decode loop.

1) `Error::ResetRequired` should always be propagated to jump
    to the next Spotify track.

2) On a decode error, get a new packet and try again instead of
   propagating the error and jumping to the next track.
This commit is contained in:
Philip Deljanov 2022-01-05 00:03:54 -05:00
parent 3e09eff906
commit 5d44f910f3

View file

@ -171,43 +171,44 @@ impl AudioDecoder for SymphoniaDecoder {
} }
fn next_packet(&mut self) -> DecoderResult<Option<(u32, AudioPacket)>> { fn next_packet(&mut self) -> DecoderResult<Option<(u32, AudioPacket)>> {
let packet = match self.format.next_packet() { loop {
Ok(packet) => packet, let packet = match self.format.next_packet() {
Err(Error::IoError(err)) => { Ok(packet) => packet,
if err.kind() == io::ErrorKind::UnexpectedEof { Err(Error::IoError(err)) => {
return Ok(None); if err.kind() == io::ErrorKind::UnexpectedEof {
} else { return Ok(None);
return Err(DecoderError::SymphoniaDecoder(err.to_string())); } else {
return Err(DecoderError::SymphoniaDecoder(err.to_string()));
}
} }
} Err(err) => {
Err(Error::ResetRequired) => { return Err(err.into());
self.decoder.reset();
return self.next_packet();
}
Err(err) => {
return Err(err.into());
}
};
let position_ms = self.ts_to_ms(packet.pts());
match self.decoder.decode(&packet) {
Ok(decoded) => {
if self.sample_buffer.is_none() {
let spec = *decoded.spec();
let duration = decoded.capacity() as u64;
self.sample_buffer
.replace(SampleBuffer::new(duration, spec));
} }
};
let sample_buffer = self.sample_buffer.as_mut().unwrap(); // guaranteed above let position_ms = self.ts_to_ms(packet.pts());
sample_buffer.copy_interleaved_ref(decoded);
let samples = AudioPacket::Samples(sample_buffer.samples().to_vec()); match self.decoder.decode(&packet) {
Ok(Some((position_ms, samples))) Ok(decoded) => {
if self.sample_buffer.is_none() {
let spec = *decoded.spec();
let duration = decoded.capacity() as u64;
self.sample_buffer
.replace(SampleBuffer::new(duration, spec));
}
let sample_buffer = self.sample_buffer.as_mut().unwrap(); // guaranteed above
sample_buffer.copy_interleaved_ref(decoded);
let samples = AudioPacket::Samples(sample_buffer.samples().to_vec());
return Ok(Some((position_ms, samples)));
}
Err(Error::DecodeError(_)) => {
// The packet failed to decode due to corrupted or invalid data, get a new
// packet and try again.
continue;
}
Err(err) => return Err(err.into()),
} }
// Also propagate `ResetRequired` errors from the decoder to the player,
// so that it will skip to the next track and reload the entire Symphonia decoder.
Err(err) => Err(err.into()),
} }
} }
} }