mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
decoder: h264: fix detection of top-field-first (TFF) flag.
Use the SEI pic_timing() message to track the pic_struct variable when present, or infer it from the regular slice header flags field_pic_flag and bottom_field_flag. This fixes temporal sequence ordering when the output pictures are to be displayed. https://bugzilla.gnome.org/show_bug.cgi?id=739291
This commit is contained in:
parent
c4f42114b4
commit
415d5df7ee
1 changed files with 56 additions and 9 deletions
|
@ -369,7 +369,9 @@ gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
|
||||||
|
|
||||||
g_return_val_if_fail(fs->num_buffers == 1, FALSE);
|
g_return_val_if_fail(fs->num_buffers == 1, FALSE);
|
||||||
|
|
||||||
first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
|
first_field->base.structure = GST_VAAPI_PICTURE_IS_TFF(first_field) ?
|
||||||
|
GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD :
|
||||||
|
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
|
||||||
GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
|
GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
|
||||||
|
|
||||||
second_field = gst_vaapi_picture_h264_new_field(first_field);
|
second_field = gst_vaapi_picture_h264_new_field(first_field);
|
||||||
|
@ -490,6 +492,7 @@ struct _GstVaapiDecoderH264Private {
|
||||||
guint nal_length_size;
|
guint nal_length_size;
|
||||||
guint mb_width;
|
guint mb_width;
|
||||||
guint mb_height;
|
guint mb_height;
|
||||||
|
guint pic_structure; // pic_struct (from SEI pic_timing() or inferred)
|
||||||
gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
|
gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
|
||||||
gint32 poc_msb; // PicOrderCntMsb
|
gint32 poc_msb; // PicOrderCntMsb
|
||||||
gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
|
gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
|
||||||
|
@ -1490,6 +1493,7 @@ decode_current_picture(GstVaapiDecoderH264 *decoder)
|
||||||
if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE))
|
if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE))
|
||||||
goto drop_frame;
|
goto drop_frame;
|
||||||
priv->decoder_state = 0;
|
priv->decoder_state = 0;
|
||||||
|
priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME;
|
||||||
|
|
||||||
if (!picture)
|
if (!picture)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
@ -1510,6 +1514,7 @@ error:
|
||||||
|
|
||||||
drop_frame:
|
drop_frame:
|
||||||
priv->decoder_state = 0;
|
priv->decoder_state = 0;
|
||||||
|
priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME;
|
||||||
return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1705,6 +1710,34 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstVaapiDecoderStatus
|
||||||
|
decode_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderH264Private * const priv = &decoder->priv;
|
||||||
|
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
GST_DEBUG("decode SEI messages");
|
||||||
|
|
||||||
|
for (i = 0; i < pi->data.sei->len; i++) {
|
||||||
|
const GstH264SEIMessage * const sei =
|
||||||
|
&g_array_index(pi->data.sei, GstH264SEIMessage, i);
|
||||||
|
|
||||||
|
switch (sei->payloadType) {
|
||||||
|
case GST_H264_SEI_PIC_TIMING: {
|
||||||
|
const GstH264PicTiming * const pic_timing =
|
||||||
|
&sei->payload.pic_timing;
|
||||||
|
if (pic_timing->pic_struct_present_flag)
|
||||||
|
priv->pic_structure = pic_timing->pic_struct;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_sequence_end(GstVaapiDecoderH264 *decoder)
|
decode_sequence_end(GstVaapiDecoderH264 *decoder)
|
||||||
{
|
{
|
||||||
|
@ -2881,14 +2914,28 @@ init_picture(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize picture structure */
|
/* Initialize picture structure */
|
||||||
if (!slice_hdr->field_pic_flag)
|
if (slice_hdr->field_pic_flag) {
|
||||||
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
|
||||||
else {
|
|
||||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
|
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
|
||||||
if (!slice_hdr->bottom_field_flag)
|
priv->pic_structure = slice_hdr->bottom_field_flag ?
|
||||||
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
|
GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD :
|
||||||
else
|
GST_H264_SEI_PIC_STRUCT_TOP_FIELD;
|
||||||
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
|
}
|
||||||
|
|
||||||
|
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||||
|
switch (priv->pic_structure) {
|
||||||
|
case GST_H264_SEI_PIC_STRUCT_TOP_FIELD:
|
||||||
|
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
|
||||||
|
if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture))
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF);
|
||||||
|
break;
|
||||||
|
case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
|
||||||
|
base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
|
||||||
|
break;
|
||||||
|
case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
|
||||||
|
case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM:
|
||||||
|
if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture))
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
picture->structure = base_picture->structure;
|
picture->structure = base_picture->structure;
|
||||||
|
|
||||||
|
@ -3781,7 +3828,7 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
status = decode_sequence_end(decoder);
|
status = decode_sequence_end(decoder);
|
||||||
break;
|
break;
|
||||||
case GST_H264_NAL_SEI:
|
case GST_H264_NAL_SEI:
|
||||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
status = decode_sei(decoder, unit);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
|
GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
|
||||||
|
|
Loading…
Reference in a new issue