mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +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);
|
||||
|
||||
/* 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);
|
||||
len =
|
||||
gst_ffmpegviddec_video_frame (ffmpegdec, data, size, have_data, frame,
|
||||
ret);
|
||||
|
||||
if (frame && frame->output_buffer)
|
||||
have_data = 1;
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue