diff options
author | Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | 2012-04-30 14:40:02 +0100 |
---|---|---|
committer | Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | 2012-05-24 22:56:41 +0100 |
commit | 69b19a7d47d8affcb61ae0d59f84ea039343d71f (patch) | |
tree | 697c3afda04c5eaca05bfa7a83c0ed9b198571b9 /ext/opus | |
parent | 1efe1cf95a293f7a6d691c59b9093bab09e2c737 (diff) |
opusdec: fix lost packet handling for FEC/PLC
The base audio decoder sends zero size packets, not NULL buffers,
to signal dropped packets.
Diffstat (limited to 'ext/opus')
-rw-r--r-- | ext/opus/gstopusdec.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c index a21b1878b..626e785af 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: |