mpeg2: allocate dummy picture for first field based I-frame.

In P-pictures, prediction shall be made from the two most recently
decoded reference fields. However, when the first I-frame is a field,
the next field of the current picture could be a P-picture but only a
single field was decoded so far. In this case, create a dummy picture
with POC = -1 that will be used as reference.

Some VA drivers would error out if P-pictures don't have a forward
reference picture. This is true in general but not in this very specific
initial case.
This commit is contained in:
Gwenole Beauchesne 2012-04-02 11:29:53 +02:00
parent 99932049e4
commit 5975def8ab
3 changed files with 45 additions and 0 deletions

View file

@ -238,6 +238,14 @@ gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
return klass->add(dpb, picture);
}
guint
gst_vaapi_dpb_size(GstVaapiDpb *dpb)
{
g_return_val_if_fail(GST_VAAPI_IS_DPB(dpb), 0);
return dpb->num_pictures;
}
/* ------------------------------------------------------------------------- */
/* --- MPEG-2 Decoded Picture Buffer --- */
/* ------------------------------------------------------------------------- */

View file

@ -103,6 +103,10 @@ gboolean
gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
attribute_hidden;
guint
gst_vaapi_dpb_size(GstVaapiDpb *dpb)
attribute_hidden;
static inline gpointer
gst_vaapi_dpb_ref(gpointer ptr)
{

View file

@ -700,6 +700,39 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
break;
}
/* Allocate dummy picture for first field based I-frame */
if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
!GST_VAAPI_PICTURE_IS_FRAME(picture) &&
gst_vaapi_dpb_size(priv->dpb) == 0) {
GstVaapiPicture *dummy_picture;
gboolean success;
dummy_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder);
if (!dummy_picture) {
GST_ERROR("failed to allocate dummy picture");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
}
dummy_picture->type = GST_VAAPI_PICTURE_TYPE_I;
dummy_picture->pts = GST_CLOCK_TIME_NONE;
dummy_picture->poc = -1;
dummy_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
GST_VAAPI_PICTURE_FLAG_SET(
dummy_picture,
(GST_VAAPI_PICTURE_FLAG_SKIPPED |
GST_VAAPI_PICTURE_FLAG_REFERENCE)
);
success = gst_vaapi_dpb_add(priv->dpb, dummy_picture);
gst_vaapi_picture_unref(dummy_picture);
if (!success) {
GST_ERROR("failed to add dummy picture into DPB");
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
}
GST_INFO("allocated dummy picture for first field based I-frame");
}
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}