]> git.baikalelectronics.ru Git - kernel.git/commitdiff
media: h264: Store all fields into the unordered list
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 13 May 2022 20:29:06 +0000 (22:29 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Tue, 17 May 2022 08:01:10 +0000 (10:01 +0200)
When the current picture is a field, store each field into the
unordered_list and preserve both top and bottom picture order
count.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/nvidia/tegra-vde/h264.c
drivers/media/v4l2-core/v4l2-h264.c
include/media/v4l2-h264.h

index 4fb0aaad16d6aef0ab243c57b4e5a0540ac14a83..88f81a134ba01eb261796e6728b4a12af3b79e09 100644 (file)
@@ -820,7 +820,7 @@ static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
                if (err)
                        return err;
 
-               if (b.refs[dpb_idx].pic_order_count < b.cur_pic_order_count)
+               if (b.refs[dpb_idx].top_field_order_cnt < b.cur_pic_order_count)
                        h264->dpb_ref_frames_with_earlier_poc_nb++;
        }
 
index 58f18bb0afb6c5e61f19c12a1cd7748da60b4e95..38d8dbda00458272b537e587cd8cfbd745ff0604 100644 (file)
@@ -47,8 +47,6 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b,
        }
 
        for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) {
-               u32 pic_order_count;
-
                if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
                        continue;
 
@@ -59,8 +57,6 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b,
                /*
                 * Handle frame_num wraparound as described in section
                 * '8.2.4.1 Decoding process for picture numbers' of the spec.
-                * TODO: This logic will have to be adjusted when we start
-                * supporting interlaced content.
                 * For long term references, frame_num is set to
                 * long_term_frame_idx which requires no wrapping.
                 */
@@ -70,17 +66,33 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b,
                else
                        b->refs[i].frame_num = dpb[i].frame_num;
 
-               if (dpb[i].fields == V4L2_H264_FRAME_REF)
-                       pic_order_count = min(dpb[i].top_field_order_cnt,
-                                             dpb[i].bottom_field_order_cnt);
-               else if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)
-                       pic_order_count = dpb[i].bottom_field_order_cnt;
-               else
-                       pic_order_count = dpb[i].top_field_order_cnt;
+               b->refs[i].top_field_order_cnt = dpb[i].top_field_order_cnt;
+               b->refs[i].bottom_field_order_cnt = dpb[i].bottom_field_order_cnt;
+
+               if (b->cur_pic_fields == V4L2_H264_FRAME_REF) {
+                       u8 fields = V4L2_H264_FRAME_REF;
+
+                       b->unordered_reflist[b->num_valid].index = i;
+                       b->unordered_reflist[b->num_valid].fields = fields;
+                       b->num_valid++;
+                       continue;
+               }
+
+               if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF) {
+                       u8 fields = V4L2_H264_TOP_FIELD_REF;
+
+                       b->unordered_reflist[b->num_valid].index = i;
+                       b->unordered_reflist[b->num_valid].fields = fields;
+                       b->num_valid++;
+               }
 
-               b->refs[i].pic_order_count = pic_order_count;
-               b->unordered_reflist[b->num_valid].index = i;
-               b->num_valid++;
+               if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) {
+                       u8 fields = V4L2_H264_BOTTOM_FIELD_REF;
+
+                       b->unordered_reflist[b->num_valid].index = i;
+                       b->unordered_reflist[b->num_valid].fields = fields;
+                       b->num_valid++;
+               }
        }
 
        for (i = b->num_valid; i < ARRAY_SIZE(b->unordered_reflist); i++)
@@ -88,6 +100,23 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b,
 }
 EXPORT_SYMBOL_GPL(v4l2_h264_init_reflist_builder);
 
+static s32 v4l2_h264_get_poc(const struct v4l2_h264_reflist_builder *b,
+                            const struct v4l2_h264_reference *ref)
+{
+       switch (ref->fields) {
+       case V4L2_H264_FRAME_REF:
+               return min(b->refs[ref->index].top_field_order_cnt,
+                               b->refs[ref->index].bottom_field_order_cnt);
+       case V4L2_H264_TOP_FIELD_REF:
+               return b->refs[ref->index].top_field_order_cnt;
+       case V4L2_H264_BOTTOM_FIELD_REF:
+               return b->refs[ref->index].bottom_field_order_cnt;
+       }
+
+       /* not reached */
+       return 0;
+}
+
 static int v4l2_h264_p_ref_list_cmp(const void *ptra, const void *ptrb,
                                    const void *data)
 {
@@ -150,8 +179,8 @@ static int v4l2_h264_b0_ref_list_cmp(const void *ptra, const void *ptrb,
                       builder->refs[idxb].pic_num ?
                       -1 : 1;
 
-       poca = builder->refs[idxa].pic_order_count;
-       pocb = builder->refs[idxb].pic_order_count;
+       poca = v4l2_h264_get_poc(builder, ptra);
+       pocb = v4l2_h264_get_poc(builder, ptrb);
 
        /*
         * Short term pics with POC < cur POC first in POC descending order
@@ -195,8 +224,8 @@ static int v4l2_h264_b1_ref_list_cmp(const void *ptra, const void *ptrb,
                       builder->refs[idxb].pic_num ?
                       -1 : 1;
 
-       poca = builder->refs[idxa].pic_order_count;
-       pocb = builder->refs[idxb].pic_order_count;
+       poca = v4l2_h264_get_poc(builder, ptra);
+       pocb = v4l2_h264_get_poc(builder, ptrb);
 
        /*
         * Short term pics with POC > cur POC first in POC ascending order
index e165a54c68fa2cd7168c75ac2b5fcfa88f1e894f..4cef717b3f18aa4cd9f3cb11e2eafd96d090c612 100644 (file)
@@ -15,7 +15,8 @@
 /**
  * struct v4l2_h264_reflist_builder - Reference list builder object
  *
- * @refs.pic_order_count: reference picture order count
+ * @refs.top_field_order_cnt: top field order count
+ * @refs.bottom_field_order_cnt: bottom field order count
  * @refs.frame_num: reference frame number
  * @refs.pic_num: reference picture number
  * @refs.longterm: set to true for a long term reference
@@ -32,7 +33,8 @@
  */
 struct v4l2_h264_reflist_builder {
        struct {
-               s32 pic_order_count;
+               s32 top_field_order_cnt;
+               s32 bottom_field_order_cnt;
                int frame_num;
                u32 pic_num;
                u16 longterm : 1;