summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleix Conchillo Flaqué <aleix@oblong.com>2014-08-11 14:16:55 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-08-11 18:06:33 +0300
commit1307b31e1cf9548ad3c9896fc0e9afe3d0516e40 (patch)
tree5ed5f76848de5fbd5e4ada592566b5044908a214
parentdc1e69dbea9687f05779884cd106edfd38d8df1b (diff)
avviddec: Don't lose frames on EOS
have_data is not propagated from gst_ffmpegviddec_video_frame to gst_ffmpegviddec_frame. have_data is only set to 1 in gst_ffmpegviddec_frame if a frame pointer is passed. However, this is not true while draining, which means that have_data from libav will be ignored. https://bugzilla.gnome.org/show_bug.cgi?id=734608
-rw-r--r--ext/libav/gstavviddec.c40
1 files changed, 15 insertions, 25 deletions
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c
index 94dfa58..3db0be1 100644
--- a/ext/libav/gstavviddec.c
+++ b/ext/libav/gstavviddec.c
@@ -1083,7 +1083,7 @@ gst_ffmpegviddec_do_qos (GstFFMpegVidDec * ffmpegdec,
frame);
/* if we don't have timing info, then we don't do QoS */
- if (G_UNLIKELY(diff == G_MAXINT64))
+ if (G_UNLIKELY (diff == G_MAXINT64))
return;
GST_DEBUG_OBJECT (ffmpegdec, "decoding time %" G_GINT64_FORMAT, diff);
@@ -1181,10 +1181,10 @@ gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
*/
static gint
gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
- guint8 * data, guint size, GstVideoCodecFrame * frame, GstFlowReturn * ret)
+ guint8 * data, guint size, gint * have_data, GstVideoCodecFrame * frame,
+ GstFlowReturn * ret)
{
gint len = -1;
- gint have_data;
gboolean mode_switch;
GstVideoCodecFrame *out_frame;
GstFFMpegVidDecVideoFrame *out_dframe;
@@ -1239,10 +1239,10 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
}
len = avcodec_decode_video2 (ffmpegdec->context,
- ffmpegdec->picture, &have_data, &packet);
+ ffmpegdec->picture, have_data, &packet);
GST_DEBUG_OBJECT (ffmpegdec, "after decode: len %d, have_data %d",
- len, have_data);
+ len, *have_data);
/* when we are in skip_frame mode, don't complain when ffmpeg returned
* no data because we told it to skip stuff. */
@@ -1250,7 +1250,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
len = 0;
/* no data, we're done */
- if (len < 0 || have_data <= 0)
+ if (len < 0 || *have_data == 0)
goto beach;
/* get the output picture timing info again */
@@ -1390,11 +1390,11 @@ negotiation_error:
static gint
gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
- guint8 * data, guint size, gint * got_data, GstVideoCodecFrame * frame,
+ guint8 * data, guint size, gint * have_data, GstVideoCodecFrame * frame,
GstFlowReturn * ret)
{
GstFFMpegVidDecClass *oclass;
- gint have_data = 0, len = 0;
+ gint len = 0;
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
goto no_codec;
@@ -1406,27 +1406,16 @@ gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
- len = gst_ffmpegviddec_video_frame (ffmpegdec, data, size, frame, ret);
-
- if (frame && frame->output_buffer)
- have_data = 1;
+ len =
+ gst_ffmpegviddec_video_frame (ffmpegdec, data, size, have_data, frame,
+ ret);
- if (len < 0 || have_data < 0) {
+ if (len < 0) {
GST_WARNING_OBJECT (ffmpegdec,
"avdec_%s: decoding error (len: %d, have_data: %d)",
- oclass->in_plugin->name, len, have_data);
- *got_data = 0;
- goto beach;
- }
- if (len == 0 && have_data == 0) {
- *got_data = 0;
- goto beach;
+ oclass->in_plugin->name, len, *have_data);
}
- /* this is where I lost my last clue on ffmpeg... */
- *got_data = 1;
-
-beach:
return len;
/* ERRORS */
@@ -1458,6 +1447,7 @@ gst_ffmpegviddec_drain (GstFFMpegVidDec * ffmpegdec)
GstFlowReturn ret;
len = gst_ffmpegviddec_frame (ffmpegdec, NULL, 0, &have_data, NULL, &ret);
+
if (len < 0 || have_data == 0)
break;
} while (try++ < 10);
@@ -1544,7 +1534,7 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
break;
}
- if (len == 0 && !have_data) {
+ if (len == 0 && have_data == 0) {
/* nothing was decoded, this could be because no data was available or
* because we were skipping frames.
* If we have no context we must exit and wait for more data, we keep the