From 0e15f47bdf302e15097cc844a2f5f3ea2921661d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 2 Oct 2014 16:33:30 +0300 Subject: [PATCH] openh264dec: Try to handle frame reordering As openh264 has no way to attach any IDs to input frames that we then get on the output frames, we have to assume that the input has valid PTS. We just take the frame with the oldest PTS, and if there is no PTS information we take the one with the oldest DTS. --- ext/openh264/gstopenh264dec.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ext/openh264/gstopenh264dec.cpp b/ext/openh264/gstopenh264dec.cpp index 08691090dd..2bb317a8e2 100644 --- a/ext/openh264/gstopenh264dec.cpp +++ b/ext/openh264/gstopenh264dec.cpp @@ -228,6 +228,32 @@ static gboolean gst_openh264dec_reset(GstVideoDecoder *decoder, gboolean hard) return TRUE; } +static GstVideoCodecFrame * +get_oldest_pts_frame (GstVideoDecoder * decoder) +{ + GList *frames, *l; + GstVideoCodecFrame *oldest = NULL; + + frames = gst_video_decoder_get_frames (decoder); + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = (GstVideoCodecFrame *) l->data; + + if (tmp->pts != GST_CLOCK_TIME_NONE && + (oldest == NULL || oldest->pts > tmp->pts)) + oldest = tmp; + } + + if (oldest) + gst_video_codec_frame_ref (oldest); + else + oldest = gst_video_decoder_get_oldest_frame (decoder); + + g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL); + g_list_free (frames); + + return oldest; +} + static GstFlowReturn gst_openh264dec_handle_frame(GstVideoDecoder *decoder, GstVideoCodecFrame *frame) { GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder); @@ -277,7 +303,7 @@ static GstFlowReturn gst_openh264dec_handle_frame(GstVideoDecoder *decoder, GstV return GST_FLOW_EOS; } - frame = gst_video_decoder_get_oldest_frame (decoder); + frame = get_oldest_pts_frame (decoder); if (!frame) { /* Can only happen in finish() */ return GST_FLOW_EOS;