vkh264dec: enhance interlaced content support
- Use frame_num instead of pic_num to set the long_term_pic_num fixing 10 interlaced tests in fluster test suite: JVT-AVC_V1 - Send the slice offset only once in case of interlaced content. Fixing 5 interlaced tests in fluster test suite: JVT-AVC_V1. - The default value for top and bottom field flag should be 0 in the case of a progressive content. - Use short and long term refs helper getter method to retrieve the reference frames according its none existing and interlaced state - Reorganize the find_next_slot_idx code to be easier to read. Co-authored-by: Daniel Almeida <daniel.almeida@collabora.com> Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7854>
This commit is contained in:
parent
3090cefbc5
commit
ee7d41f76b
@ -1013,13 +1013,10 @@ _find_next_slot_idx (GstH264Picture * picture, GArray * dpb)
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
GstH264Picture *pic = g_array_index (dpb, GstH264Picture *, i);
|
||||
if (!pic->nonexisting) {
|
||||
if (pic->second_field)
|
||||
continue;
|
||||
GstVulkanH264Picture *h264_pic = gst_h264_picture_get_user_data (pic);
|
||||
if (h264_pic)
|
||||
arr[h264_pic->slot_idx] = pic;
|
||||
}
|
||||
GstVulkanH264Picture *h264_pic = gst_h264_picture_get_user_data (pic);
|
||||
if (pic->nonexisting || pic->second_field)
|
||||
continue;
|
||||
arr[h264_pic->slot_idx] = pic;
|
||||
}
|
||||
|
||||
/* let's return the smallest available / not ref index */
|
||||
@ -1047,7 +1044,7 @@ _fill_h264_slot (GstH264Picture * picture,
|
||||
GST_H264_PICTURE_IS_LONG_TERM_REF (picture),
|
||||
},
|
||||
.FrameNum = GST_H264_PICTURE_IS_LONG_TERM_REF (picture) ?
|
||||
picture->long_term_pic_num : picture->pic_num,
|
||||
picture->long_term_pic_num : picture->frame_num,
|
||||
/* .reserved = */
|
||||
/* .PicOrderCnt = */
|
||||
};
|
||||
@ -1055,8 +1052,6 @@ _fill_h264_slot (GstH264Picture * picture,
|
||||
|
||||
switch (picture->field) {
|
||||
case GST_H264_PICTURE_FIELD_FRAME:
|
||||
stdh264_ref->flags.top_field_flag = 1;
|
||||
stdh264_ref->flags.bottom_field_flag = 1;
|
||||
stdh264_ref->PicOrderCnt[0] = picture->top_field_order_cnt;
|
||||
stdh264_ref->PicOrderCnt[1] = picture->bottom_field_order_cnt;
|
||||
break;
|
||||
@ -1148,61 +1143,58 @@ gst_vulkan_h264_decoder_start_picture (GstH264Decoder * decoder,
|
||||
GstVulkanH264Picture *pic;
|
||||
GArray *refs;
|
||||
guint i, j;
|
||||
gboolean interlaced;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Start picture");
|
||||
|
||||
|
||||
ret = _update_parameters (self, self->need_sps_update ? sps : NULL, pps);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
if (self->need_sps_update)
|
||||
self->need_sps_update = FALSE;
|
||||
|
||||
|
||||
refs = gst_h264_dpb_get_pictures_all (dpb);
|
||||
|
||||
pic = gst_h264_picture_get_user_data (picture);
|
||||
g_assert (pic);
|
||||
|
||||
_fill_h264_pic (picture, slice, &pic->vk_h264pic, &pic->std_h264pic);
|
||||
/* Search for the next slot index in all available refs */
|
||||
pic->slot_idx = _find_next_slot_idx (picture, refs);
|
||||
|
||||
g_array_unref (refs);
|
||||
/* Create a new refs array to retrieve short-term and long term refs */
|
||||
refs = g_array_sized_new (FALSE, TRUE, sizeof (GstH264Picture *), 16);
|
||||
g_array_set_clear_func (refs, (GDestroyNotify) gst_clear_h264_picture);
|
||||
|
||||
/* fill main slot */
|
||||
_fill_ref_slot (self, picture, &pic->base.slot,
|
||||
&pic->base.pic_res, &pic->vk_slot, &pic->std_ref, NULL);
|
||||
|
||||
interlaced = GST_VIDEO_INFO_INTERLACE_MODE (&self->output_state->info)
|
||||
!= GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
|
||||
j = 0;
|
||||
|
||||
gst_h264_dpb_get_pictures_short_term_ref (dpb, FALSE, FALSE, refs);
|
||||
/* Fill in short-term references */
|
||||
j = 0;
|
||||
for (i = 0; i < refs->len; i++) {
|
||||
GstH264Picture *picture = g_array_index (refs, GstH264Picture *, i);
|
||||
/* XXX: shall we add second fields? */
|
||||
if (!picture->nonexisting && GST_H264_PICTURE_IS_SHORT_TERM_REF (picture)) {
|
||||
_fill_ref_slot (self, picture, &pic->base.slots[j],
|
||||
&pic->base.pics_res[j], &pic->vk_slots[j], &pic->std_refs[j],
|
||||
&pic->base.refs[j]);
|
||||
j++;
|
||||
}
|
||||
|
||||
_fill_ref_slot (self, picture, &pic->base.slots[j],
|
||||
&pic->base.pics_res[j], &pic->vk_slots[j], &pic->std_refs[j],
|
||||
&pic->base.refs[j]);
|
||||
j++;
|
||||
}
|
||||
|
||||
g_array_set_size (refs, 0);
|
||||
gst_h264_dpb_get_pictures_long_term_ref (dpb, FALSE, refs);
|
||||
/* Fill in long-term refs */
|
||||
for (i = 0; i < refs->len; i++) {
|
||||
GstH264Picture *picture = g_array_index (refs, GstH264Picture *, i);
|
||||
|
||||
if (picture->second_field || (interlaced && !picture->other_field))
|
||||
continue;
|
||||
_fill_ref_slot (self, picture, &pic->base.slots[j],
|
||||
&pic->base.pics_res[j], &pic->vk_slots[j], &pic->std_refs[j],
|
||||
&pic->base.refs[j]);
|
||||
j++;
|
||||
|
||||
if (GST_H264_PICTURE_IS_LONG_TERM_REF (picture)) {
|
||||
_fill_ref_slot (self, picture, &pic->base.slots[j],
|
||||
&pic->base.pics_res[j], &pic->vk_slots[j], &pic->std_refs[j],
|
||||
&pic->base.refs[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
g_array_set_size (refs, 0);
|
||||
g_array_unref (refs);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@ -1290,6 +1282,9 @@ gst_vulkan_h264_decoder_end_picture (GstH264Decoder * decoder,
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
/* do not send the same slice data again */
|
||||
g_clear_pointer (&pic->base.slice_offs, g_array_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user