mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
opusdec: fix lost packet handling for FEC/PLC
The base audio decoder sends zero size packets, not NULL buffers, to signal dropped packets.
This commit is contained in:
parent
220687e602
commit
7d731ac155
1 changed files with 14 additions and 8 deletions
|
@ -393,17 +393,20 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
|
||||||
to potentially wait for next buffer to decode a missing buffer */
|
to potentially wait for next buffer to decode a missing buffer */
|
||||||
if (dec->use_inband_fec && !dec->primed) {
|
if (dec->use_inband_fec && !dec->primed) {
|
||||||
GST_DEBUG_OBJECT (dec, "First buffer received in FEC mode, early out");
|
GST_DEBUG_OBJECT (dec, "First buffer received in FEC mode, early out");
|
||||||
|
gst_buffer_replace (&dec->last_buffer, buffer);
|
||||||
|
dec->primed = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* That's the buffer we'll be sending to the opus decoder. */
|
/* 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);
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
data = map.data;
|
data = map.data;
|
||||||
size = map.size;
|
size = map.size;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "Using buffer of size %u", size);
|
GST_DEBUG_OBJECT (dec, "Using buffer of size %u", size);
|
||||||
} else {
|
} else {
|
||||||
/* concealment data, pass NULL as the bits parameters */
|
/* 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->use_inband_fec) {
|
||||||
if (dec->last_buffer) {
|
if (dec->last_buffer) {
|
||||||
/* normal delayed decode */
|
/* normal delayed decode */
|
||||||
|
GST_LOG_OBJECT (dec, "FEC enabled, decoding last delayed buffer");
|
||||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
/* FEC reconstruction decode */
|
/* FEC reconstruction decode */
|
||||||
|
GST_LOG_OBJECT (dec, "FEC enabled, reconstructing last buffer");
|
||||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* normal decode */
|
/* normal decode */
|
||||||
|
GST_LOG_OBJECT (dec, "FEC disabled, decoding buffer");
|
||||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0);
|
n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0);
|
||||||
}
|
}
|
||||||
gst_buffer_unmap (outbuf, &omap);
|
gst_buffer_unmap (outbuf, &omap);
|
||||||
|
@ -445,6 +451,7 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL));
|
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL));
|
||||||
|
gst_buffer_unref (outbuf);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (dec, "decoded %d samples", n);
|
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);
|
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);
|
res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), outbuf, 1);
|
||||||
|
|
||||||
if (res != GST_FLOW_OK)
|
if (res != GST_FLOW_OK)
|
||||||
GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
|
GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (dec->use_inband_fec) {
|
|
||||||
gst_buffer_replace (&dec->last_buffer, buffer);
|
|
||||||
dec->primed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
creation_failed:
|
creation_failed:
|
||||||
|
|
Loading…
Reference in a new issue