From 69b19a7d47d8affcb61ae0d59f84ea039343d71f Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 30 Apr 2012 14:40:02 +0100 Subject: [PATCH] opusdec: fix lost packet handling for FEC/PLC The base audio decoder sends zero size packets, not NULL buffers, to signal dropped packets. --- ext/opus/gstopusdec.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c index a21b187..626e785 100644 --- a/ext/opus/gstopusdec.c +++ b/ext/opus/gstopusdec.c @@ -393,17 +393,20 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer) to potentially wait for next buffer to decode a missing buffer */ if (dec->use_inband_fec && !dec->primed) { GST_DEBUG_OBJECT (dec, "First buffer received in FEC mode, early out"); + gst_buffer_replace (&dec->last_buffer, buffer); + dec->primed = TRUE; goto done; } /* That's the buffer we'll be sending to the opus decoder. */ - buf = dec->use_inband_fec && dec->last_buffer ? dec->last_buffer : buffer; + buf = (dec->use_inband_fec + && gst_buffer_get_size (dec->last_buffer) > + 0) ? dec->last_buffer : buffer; - if (buf) { + if (buf && gst_buffer_get_size (buf) > 0) { gst_buffer_map (buf, &map, GST_MAP_READ); data = map.data; size = map.size; - GST_DEBUG_OBJECT (dec, "Using buffer of size %u", size); } else { /* concealment data, pass NULL as the bits parameters */ @@ -428,15 +431,18 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer) if (dec->use_inband_fec) { if (dec->last_buffer) { /* normal delayed decode */ + GST_LOG_OBJECT (dec, "FEC enabled, decoding last delayed buffer"); n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0); } else { /* FEC reconstruction decode */ + GST_LOG_OBJECT (dec, "FEC enabled, reconstructing last buffer"); n = opus_multistream_decode (dec->state, data, size, out_data, samples, 1); } } else { /* normal decode */ + GST_LOG_OBJECT (dec, "FEC disabled, decoding buffer"); n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0); } gst_buffer_unmap (outbuf, &omap); @@ -445,6 +451,7 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer) if (n < 0) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL)); + gst_buffer_unref (outbuf); return GST_FLOW_ERROR; } GST_DEBUG_OBJECT (dec, "decoded %d samples", n); @@ -495,17 +502,16 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer) gst_buffer_unmap (outbuf, &omap); } + if (dec->use_inband_fec) { + gst_buffer_replace (&dec->last_buffer, buffer); + } + res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), outbuf, 1); if (res != GST_FLOW_OK) GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res)); done: - if (dec->use_inband_fec) { - gst_buffer_replace (&dec->last_buffer, buffer); - dec->primed = TRUE; - } - return res; creation_failed: -- 2.7.4