From 0619168e2a242e468b07bd475675ea9ad8cbd31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 16 Aug 2018 19:37:33 +0300 Subject: [PATCH] vorbisdec: Always handle in-band header packets once the first non-header packet arrives And clean up any old pending headers if we receive a new identification header, or if we receive a new set of headers via caps. Otherwise it might happen that we receive one or more header but not all, and then afterwards all headers again, and libvorbis does not like getting headers passed multiple times and would error out. It only makes sense to pass the very latest headers to the decoder at the time we can actually make use of them. https://bugzilla.gnome.org/show_bug.cgi?id=796980 --- ext/vorbis/gstvorbisdec.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index f4e563c138..eaa38482fb 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -399,6 +399,14 @@ vorbis_dec_handle_header_caps (GstVorbisDec * vd) GstBuffer *buf = NULL; gint i = 0; + if (vd->pending_headers) { + GST_DEBUG_OBJECT (vd, + "got new headers from caps, discarding old pending headers"); + + g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref); + vd->pending_headers = NULL; + } + while (result == GST_FLOW_OK && i < gst_value_array_get_size (array)) { value = gst_value_array_get_value (array, i); buf = gst_value_get_buffer (value); @@ -672,20 +680,17 @@ vorbis_dec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer) /* switch depending on packet type */ if ((gst_ogg_packet_data (packet))[0] & 1) { - /* If we get a new initialization packet after being initialized, - * store it. - * When the next non-header buffer comes in, we will check whether - * those pending headers are correct and if so reset ourselves */ - if (vd->initialized) { - GST_LOG_OBJECT (vd, "storing header for later analyzis"); - vd->pending_headers = - g_list_append (vd->pending_headers, gst_buffer_ref (buffer)); - goto done; + GST_LOG_OBJECT (vd, "storing header for later analyzis"); + if (vd->pending_headers && (gst_ogg_packet_data (packet))[0] == 0x01) { + GST_DEBUG_OBJECT (vd, + "got new identification header packet, discarding old pending headers"); + + g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref); + vd->pending_headers = NULL; } - result = vorbis_handle_header_packet (vd, packet); - if (result != GST_FLOW_OK) - goto done; - /* consumer header packet/frame */ + + vd->pending_headers = + g_list_append (vd->pending_headers, gst_buffer_ref (buffer)); result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1); } else { GstClockTime timestamp, duration;