summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungha Yang <seungha@centricular.com>2020-12-30 01:15:16 +0900
committerTim-Philipp Müller <tim@centricular.com>2021-01-03 23:39:50 +0000
commitb08d11fb172683822e33a21de5ec0105bc214654 (patch)
tree8aa59fd396238b6806c26e51e03e5db282ee7125
parent1145015dc12e817c7dea66c7183f204b90558654 (diff)
downloadgst-libav-b08d11fb172683822e33a21de5ec0105bc214654.tar.gz
avauddec: Drain decoder on decoding failure
... and call finish_frame() so that baseclass can reset internal status. Otherwise baseclass will keep holding the status for decoding failed frame which will result in outputting buffer with wrong timestamp. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-libav/-/merge_requests/113>
-rw-r--r--ext/libav/gstavauddec.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/ext/libav/gstavauddec.c b/ext/libav/gstavauddec.c
index 6801bbd..baf7aa5 100644
--- a/ext/libav/gstavauddec.c
+++ b/ext/libav/gstavauddec.c
@@ -57,7 +57,8 @@ static GstFlowReturn gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder,
static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
AVCodecContext * context, AVFrame * frame, gboolean force);
-static GstFlowReturn gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
+static GstFlowReturn gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec,
+ gboolean force);
#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
@@ -319,7 +320,7 @@ gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
/* close old session */
if (ffmpegdec->opened) {
GST_OBJECT_UNLOCK (ffmpegdec);
- gst_ffmpegauddec_drain (ffmpegdec);
+ gst_ffmpegauddec_drain (ffmpegdec, FALSE);
GST_OBJECT_LOCK (ffmpegdec);
if (!gst_ffmpegauddec_close (ffmpegdec, TRUE)) {
GST_OBJECT_UNLOCK (ffmpegdec);
@@ -595,7 +596,7 @@ no_codec:
}
static GstFlowReturn
-gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
+gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec, gboolean force)
{
GstFlowReturn ret = GST_FLOW_OK;
gboolean got_any_frames = FALSE;
@@ -619,7 +620,7 @@ gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
if (ret == GST_FLOW_EOS)
ret = GST_FLOW_OK;
- if (got_any_frames) {
+ if (got_any_frames || force) {
GstFlowReturn new_ret =
gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec), NULL, 1);
@@ -665,7 +666,7 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
goto not_negotiated;
if (inbuf == NULL) {
- return gst_ffmpegauddec_drain (ffmpegdec);
+ return gst_ffmpegauddec_drain (ffmpegdec, FALSE);
}
inbuf = gst_buffer_ref (inbuf);
@@ -771,6 +772,11 @@ not_negotiated:
send_packet_failed:
{
GST_WARNING_OBJECT (ffmpegdec, "decoding error");
+ /* Even if ffmpeg was not able to decode current audio frame,
+ * we should call gst_audio_decoder_finish_frame() so that baseclass
+ * can clear its internal status and can respect timestamp of later
+ * incoming buffers */
+ ret = gst_ffmpegauddec_drain (ffmpegdec, TRUE);
goto unmap;
}
}