mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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:
parent
99932049e4
commit
5975def8ab
3 changed files with 45 additions and 0 deletions
|
@ -238,6 +238,14 @@ gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
|
||||||
return klass->add(dpb, 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 --- */
|
/* --- MPEG-2 Decoded Picture Buffer --- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -103,6 +103,10 @@ gboolean
|
||||||
gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
|
gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
|
guint
|
||||||
|
gst_vaapi_dpb_size(GstVaapiDpb *dpb)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
static inline gpointer
|
static inline gpointer
|
||||||
gst_vaapi_dpb_ref(gpointer ptr)
|
gst_vaapi_dpb_ref(gpointer ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -700,6 +700,39 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
||||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||||
break;
|
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;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue