modify decode trait to allow for signalling missing packets

This commit is contained in:
Hailey Somerville 2023-12-27 15:57:58 +11:00
parent 8229256c16
commit 4ccd209df7
4 changed files with 28 additions and 11 deletions

View file

@ -47,13 +47,14 @@ impl Decoder {
&self.decode as &dyn Display
}
pub fn decode(&mut self, packet: &Audio, out: &mut SampleBuffer) -> Result<(), DecodeError> {
self.decode.decode_packet(packet.buffer_bytes(), out)
pub fn decode(&mut self, packet: Option<&Audio>, out: &mut SampleBuffer) -> Result<(), DecodeError> {
let bytes = packet.map(|packet| packet.buffer_bytes());
self.decode.decode_packet(bytes, out)
}
}
trait Decode: Display {
fn decode_packet(&mut self, bytes: &[u8], out: &mut SampleBuffer) -> Result<(), DecodeError>;
fn decode_packet(&mut self, bytes: Option<&[u8]>, out: &mut SampleBuffer) -> Result<(), DecodeError>;
}
enum DecodeFormat {
@ -63,7 +64,7 @@ enum DecodeFormat {
}
impl Decode for DecodeFormat {
fn decode_packet(&mut self, bytes: &[u8], out: &mut SampleBuffer) -> Result<(), DecodeError> {
fn decode_packet(&mut self, bytes: Option<&[u8]>, out: &mut SampleBuffer) -> Result<(), DecodeError> {
match self {
DecodeFormat::S16LE(dec) => dec.decode_packet(bytes, out),
DecodeFormat::F32LE(dec) => dec.decode_packet(bytes, out),

View file

@ -26,11 +26,20 @@ impl Display for OpusDecoder {
}
impl Decode for OpusDecoder {
fn decode_packet(&mut self, bytes: &[u8], out: &mut SampleBuffer) -> Result<(), DecodeError> {
fn decode_packet(&mut self, bytes: Option<&[u8]>, out: &mut SampleBuffer) -> Result<(), DecodeError> {
let expected = out.len() / 2;
let length = self.opus.decode_float(bytes, out, false)?;
let length;
log::debug!("opus decode: bytes={} -> frames={}", bytes.len(), length);
match bytes {
Some(bytes) => {
length = self.opus.decode_float(bytes, out, false)?;
log::debug!("opus decode: bytes={} -> frames={}", bytes.len(), length);
}
None => {
length = self.opus.decode_float(&[], out, false)?;
log::debug!("opus decode: correcting packet loss! frames={}", length);
}
};
if expected != length {
return Err(DecodeError::WrongLength { length, expected });

View file

@ -11,7 +11,7 @@ impl Display for S16LEDecoder {
}
impl Decode for S16LEDecoder {
fn decode_packet(&mut self, bytes: &[u8], out: &mut SampleBuffer) -> Result<(), DecodeError> {
fn decode_packet(&mut self, bytes: Option<&[u8]>, out: &mut SampleBuffer) -> Result<(), DecodeError> {
decode_packed(bytes, out, |bytes| {
let input = i16::from_le_bytes(bytes);
let scale = i16::MAX as f32;
@ -29,16 +29,23 @@ impl Display for F32LEDecoder {
}
impl Decode for F32LEDecoder {
fn decode_packet(&mut self, bytes: &[u8], out: &mut SampleBuffer) -> Result<(), DecodeError> {
fn decode_packet(&mut self, bytes: Option<&[u8]>, out: &mut SampleBuffer) -> Result<(), DecodeError> {
decode_packed(bytes, out, f32::from_le_bytes)
}
}
fn decode_packed<const N: usize>(
bytes: &[u8],
bytes: Option<&[u8]>,
out: &mut SampleBuffer,
func: impl Fn([u8; N]) -> f32,
) -> Result<(), DecodeError> {
let Some(bytes) = bytes else {
// PCM codecs have no packet loss correction
// just zero fill and return
out.fill(0.0);
return Ok(());
};
check_length(bytes, out.len() * N)?;
for (input, output) in bytes.chunks_exact(N).zip(out) {

View file

@ -203,7 +203,7 @@ impl Receiver {
// decode packet
let mut decode_buffer: SampleBuffer = array::from_fn(|_| 0.0);
if let Some(decoder) = stream.decoder.as_mut() {
match decoder.decode(&packet, &mut decode_buffer) {
match decoder.decode(Some(&packet), &mut decode_buffer) {
Ok(()) => {}
Err(e) => {
log::warn!("error in decoder, skipping packet: {e}");