mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-13 15:12:58 +00:00
vkh264dec: enable h264 interlaced decoding
First the slot_index shall have the same value for the first and second fields. Also, the reference frames are only those with both fields. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7854>
This commit is contained in:
parent
f5f20ce85e
commit
3090cefbc5
1 changed files with 23 additions and 11 deletions
|
@ -1001,7 +1001,7 @@ _fill_h264_pic (const GstH264Picture * picture, const GstH264Slice * slice,
|
|||
}
|
||||
|
||||
static gint32
|
||||
_find_next_slot_idx (GArray * dpb)
|
||||
_find_next_slot_idx (GstH264Picture * picture, GArray * dpb)
|
||||
{
|
||||
gint32 i;
|
||||
guint len;
|
||||
|
@ -1014,6 +1014,8 @@ _find_next_slot_idx (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;
|
||||
|
@ -1022,7 +1024,8 @@ _find_next_slot_idx (GArray * dpb)
|
|||
|
||||
/* let's return the smallest available / not ref index */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!arr[i])
|
||||
if (!arr[i]
|
||||
|| (picture->second_field && picture->other_field == arr[i]))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -1037,10 +1040,8 @@ _fill_h264_slot (GstH264Picture * picture,
|
|||
/* *INDENT-OFF* */
|
||||
*stdh264_ref = (StdVideoDecodeH264ReferenceInfo) {
|
||||
.flags = {
|
||||
.top_field_flag =
|
||||
(picture->field == GST_H264_PICTURE_FIELD_TOP_FIELD),
|
||||
.bottom_field_flag =
|
||||
(picture->field == GST_H264_PICTURE_FIELD_BOTTOM_FIELD),
|
||||
.top_field_flag = 0,
|
||||
.bottom_field_flag = 0,
|
||||
.is_non_existing = picture->nonexisting,
|
||||
.used_for_long_term_reference =
|
||||
GST_H264_PICTURE_IS_LONG_TERM_REF (picture),
|
||||
|
@ -1054,19 +1055,25 @@ _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;
|
||||
case GST_H264_PICTURE_FIELD_BOTTOM_FIELD:
|
||||
if (picture->other_field)
|
||||
stdh264_ref->flags.bottom_field_flag = 1;
|
||||
if (picture->other_field) {
|
||||
stdh264_ref->PicOrderCnt[0] = picture->other_field->top_field_order_cnt;
|
||||
else
|
||||
stdh264_ref->flags.top_field_flag = 1;
|
||||
} else
|
||||
stdh264_ref->PicOrderCnt[0] = 0;
|
||||
stdh264_ref->PicOrderCnt[1] = picture->bottom_field_order_cnt;
|
||||
break;
|
||||
case GST_H264_PICTURE_FIELD_TOP_FIELD:
|
||||
stdh264_ref->PicOrderCnt[0] = picture->top_field_order_cnt;
|
||||
stdh264_ref->flags.top_field_flag = 1;
|
||||
if (picture->other_field) {
|
||||
stdh264_ref->flags.bottom_field_flag = 1;
|
||||
stdh264_ref->PicOrderCnt[1] =
|
||||
picture->other_field->bottom_field_order_cnt;
|
||||
} else {
|
||||
|
@ -1141,6 +1148,7 @@ gst_vulkan_h264_decoder_start_picture (GstH264Decoder * decoder,
|
|||
GstVulkanH264Picture *pic;
|
||||
GArray *refs;
|
||||
guint i, j;
|
||||
gboolean interlaced;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Start picture");
|
||||
|
||||
|
@ -1158,12 +1166,14 @@ gst_vulkan_h264_decoder_start_picture (GstH264Decoder * decoder,
|
|||
g_assert (pic);
|
||||
|
||||
_fill_h264_pic (picture, slice, &pic->vk_h264pic, &pic->std_h264pic);
|
||||
pic->slot_idx = _find_next_slot_idx (refs);
|
||||
pic->slot_idx = _find_next_slot_idx (picture, refs);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Fill in short-term references */
|
||||
|
@ -1176,13 +1186,15 @@ gst_vulkan_h264_decoder_start_picture (GstH264Decoder * decoder,
|
|||
&pic->base.refs[j]);
|
||||
j++;
|
||||
}
|
||||
/* FIXME: do it in O(n) rather O(2n) */
|
||||
}
|
||||
|
||||
/* Fill in long-term refs */
|
||||
for (i = 0; i < refs->len; i++) {
|
||||
GstH264Picture *picture = g_array_index (refs, GstH264Picture *, i);
|
||||
/* XXX: shall we add non existing and second fields? */
|
||||
|
||||
if (picture->second_field || (interlaced && !picture->other_field))
|
||||
continue;
|
||||
|
||||
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],
|
||||
|
|
Loading…
Reference in a new issue