decoder: output decoded frames only once.

Make sure to output the decoded picture, and push the associated
GstVideoCodecFrame, only once. The frame fully represents what needs
to be output, included for interlaced streams. Otherwise, the base
GstVideoDecoder class would release the frame twice.

Anyway, the general process is to output decoded frames only when
they are complete. By complete, we mean a full frame was decoded or
both fields of a frame were decoded.
This commit is contained in:
Gwenole Beauchesne 2014-06-30 18:34:45 +02:00
parent 8bdef56cd4
commit f040f4f8b4

View file

@ -294,6 +294,17 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture)
return TRUE; return TRUE;
} }
/* Mark picture as output for internal purposes only. Don't push frame out */
static void
do_output_internal (GstVaapiPicture * picture)
{
if (GST_VAAPI_PICTURE_IS_OUTPUT (picture))
return;
gst_video_codec_frame_clear (&picture->frame);
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_OUTPUT);
}
static gboolean static gboolean
do_output (GstVaapiPicture * picture) do_output (GstVaapiPicture * picture)
{ {
@ -350,10 +361,14 @@ gst_vaapi_picture_output (GstVaapiPicture * picture)
break; break;
if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (parent_picture)) if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (parent_picture))
break; break;
GST_VAAPI_PICTURE_FLAG_SET (parent_picture, if (parent_picture->frame == picture->frame)
GST_VAAPI_PICTURE_FLAG_SKIPPED); do_output_internal (parent_picture);
if (!do_output (parent_picture)) else {
return FALSE; GST_VAAPI_PICTURE_FLAG_SET (parent_picture,
GST_VAAPI_PICTURE_FLAG_SKIPPED);
if (!do_output (parent_picture))
return FALSE;
}
} while (0); } while (0);
} }
return do_output (picture); return do_output (picture);