mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
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
This commit is contained in:
parent
dc1e69dbea
commit
1307b31e1c
1 changed files with 15 additions and 25 deletions
|
@ -1083,7 +1083,7 @@ gst_ffmpegviddec_do_qos (GstFFMpegVidDec * ffmpegdec,
|
||||||
frame);
|
frame);
|
||||||
|
|
||||||
/* if we don't have timing info, then we don't do QoS */
|
/* 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;
|
return;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ffmpegdec, "decoding time %" G_GINT64_FORMAT, diff);
|
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
|
static gint
|
||||||
gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
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 len = -1;
|
||||||
gint have_data;
|
|
||||||
gboolean mode_switch;
|
gboolean mode_switch;
|
||||||
GstVideoCodecFrame *out_frame;
|
GstVideoCodecFrame *out_frame;
|
||||||
GstFFMpegVidDecVideoFrame *out_dframe;
|
GstFFMpegVidDecVideoFrame *out_dframe;
|
||||||
|
@ -1239,10 +1239,10 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
}
|
}
|
||||||
|
|
||||||
len = avcodec_decode_video2 (ffmpegdec->context,
|
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",
|
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
|
/* when we are in skip_frame mode, don't complain when ffmpeg returned
|
||||||
* no data because we told it to skip stuff. */
|
* no data because we told it to skip stuff. */
|
||||||
|
@ -1250,7 +1250,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
/* no data, we're done */
|
/* no data, we're done */
|
||||||
if (len < 0 || have_data <= 0)
|
if (len < 0 || *have_data == 0)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
/* get the output picture timing info again */
|
/* get the output picture timing info again */
|
||||||
|
@ -1390,11 +1390,11 @@ negotiation_error:
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
|
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)
|
GstFlowReturn * ret)
|
||||||
{
|
{
|
||||||
GstFFMpegVidDecClass *oclass;
|
GstFFMpegVidDecClass *oclass;
|
||||||
gint have_data = 0, len = 0;
|
gint len = 0;
|
||||||
|
|
||||||
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
||||||
goto no_codec;
|
goto no_codec;
|
||||||
|
@ -1406,27 +1406,16 @@ gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
|
||||||
|
|
||||||
oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
||||||
|
|
||||||
len = gst_ffmpegviddec_video_frame (ffmpegdec, data, size, frame, ret);
|
len =
|
||||||
|
gst_ffmpegviddec_video_frame (ffmpegdec, data, size, have_data, frame,
|
||||||
|
ret);
|
||||||
|
|
||||||
if (frame && frame->output_buffer)
|
if (len < 0) {
|
||||||
have_data = 1;
|
|
||||||
|
|
||||||
if (len < 0 || have_data < 0) {
|
|
||||||
GST_WARNING_OBJECT (ffmpegdec,
|
GST_WARNING_OBJECT (ffmpegdec,
|
||||||
"avdec_%s: decoding error (len: %d, have_data: %d)",
|
"avdec_%s: decoding error (len: %d, have_data: %d)",
|
||||||
oclass->in_plugin->name, len, have_data);
|
oclass->in_plugin->name, len, *have_data);
|
||||||
*got_data = 0;
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
if (len == 0 && have_data == 0) {
|
|
||||||
*got_data = 0;
|
|
||||||
goto beach;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is where I lost my last clue on ffmpeg... */
|
|
||||||
*got_data = 1;
|
|
||||||
|
|
||||||
beach:
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -1458,6 +1447,7 @@ gst_ffmpegviddec_drain (GstFFMpegVidDec * ffmpegdec)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
len = gst_ffmpegviddec_frame (ffmpegdec, NULL, 0, &have_data, NULL, &ret);
|
len = gst_ffmpegviddec_frame (ffmpegdec, NULL, 0, &have_data, NULL, &ret);
|
||||||
|
|
||||||
if (len < 0 || have_data == 0)
|
if (len < 0 || have_data == 0)
|
||||||
break;
|
break;
|
||||||
} while (try++ < 10);
|
} while (try++ < 10);
|
||||||
|
@ -1544,7 +1534,7 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0 && !have_data) {
|
if (len == 0 && have_data == 0) {
|
||||||
/* nothing was decoded, this could be because no data was available or
|
/* nothing was decoded, this could be because no data was available or
|
||||||
* because we were skipping frames.
|
* because we were skipping frames.
|
||||||
* If we have no context we must exit and wait for more data, we keep the
|
* If we have no context we must exit and wait for more data, we keep the
|
||||||
|
|
Loading…
Reference in a new issue