mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
mpeg2: add support for interlaced streams.
Pictures are submitted to the HW for rendering only when both fields are decoded or current picture is a full frame.
This commit is contained in:
parent
ac4fc0d36c
commit
7a9410f826
2 changed files with 36 additions and 8 deletions
|
@ -340,9 +340,11 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
|
|||
if (picture) {
|
||||
if (!gst_vaapi_picture_decode(picture))
|
||||
return FALSE;
|
||||
if (!gst_vaapi_dpb_add(priv->dpb, picture))
|
||||
return FALSE;
|
||||
gst_vaapi_picture_replace(&priv->current_picture, NULL);
|
||||
if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) {
|
||||
if (!gst_vaapi_dpb_add(priv->dpb, picture))
|
||||
return FALSE;
|
||||
gst_vaapi_picture_replace(&priv->current_picture, NULL);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -389,6 +391,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
|||
}
|
||||
priv->has_seq_ext = TRUE;
|
||||
priv->progressive_sequence = seq_ext->progressive;
|
||||
gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
|
||||
|
||||
width = (priv->width & 0x0fff) | ((guint32)seq_ext->horiz_size_ext << 12);
|
||||
height = (priv->height & 0x0fff) | ((guint32)seq_ext->vert_size_ext << 12);
|
||||
|
@ -506,12 +509,24 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
|||
if (priv->current_picture && !decode_current_picture(decoder))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
priv->current_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder);
|
||||
if (!priv->current_picture) {
|
||||
GST_DEBUG("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
if (priv->current_picture) {
|
||||
/* Re-use current picture where the first field was decoded */
|
||||
picture = gst_vaapi_picture_new_field(priv->current_picture);
|
||||
if (!picture) {
|
||||
GST_ERROR("failed to allocate field picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
}
|
||||
picture = priv->current_picture;
|
||||
else {
|
||||
/* Create new picture */
|
||||
picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder);
|
||||
if (!picture) {
|
||||
GST_ERROR("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
}
|
||||
gst_vaapi_picture_replace(&priv->current_picture, picture);
|
||||
gst_vaapi_picture_unref(picture);
|
||||
|
||||
status = ensure_quant_matrix(decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
|
||||
|
@ -570,6 +585,12 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
|||
pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME;
|
||||
}
|
||||
|
||||
if (!priv->progressive_sequence && !pic_ext->progressive_frame) {
|
||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
|
||||
if (pic_ext->top_field_first)
|
||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF);
|
||||
}
|
||||
|
||||
switch (pic_ext->picture_structure) {
|
||||
case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD:
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
|
||||
|
|
|
@ -120,6 +120,13 @@ enum {
|
|||
#define GST_VAAPI_PICTURE_IS_TFF(picture) \
|
||||
GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_FRAME(picture) \
|
||||
(GST_VAAPI_PICTURE(picture)->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME)
|
||||
|
||||
#define GST_VAAPI_PICTURE_IS_COMPLETE(picture) \
|
||||
(GST_VAAPI_PICTURE_IS_FRAME(picture) || \
|
||||
!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture))
|
||||
|
||||
/**
|
||||
* GstVaapiPicture:
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue