Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: h264: Store all fields into the unordered list

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>

authored by

Nicolas Dufresne and committed by
Mauro Carvalho Chehab
e5991e1f adc8a8d6

+52 -21
+1 -1
drivers/media/platform/nvidia/tegra-vde/h264.c
··· 820 820 if (err) 821 821 return err; 822 822 823 - if (b.refs[dpb_idx].pic_order_count < b.cur_pic_order_count) 823 + if (b.refs[dpb_idx].top_field_order_cnt < b.cur_pic_order_count) 824 824 h264->dpb_ref_frames_with_earlier_poc_nb++; 825 825 } 826 826
+47 -18
drivers/media/v4l2-core/v4l2-h264.c
··· 47 47 } 48 48 49 49 for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { 50 - u32 pic_order_count; 51 - 52 50 if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) 53 51 continue; 54 52 ··· 57 59 /* 58 60 * Handle frame_num wraparound as described in section 59 61 * '8.2.4.1 Decoding process for picture numbers' of the spec. 60 - * TODO: This logic will have to be adjusted when we start 61 - * supporting interlaced content. 62 62 * For long term references, frame_num is set to 63 63 * long_term_frame_idx which requires no wrapping. 64 64 */ ··· 66 70 else 67 71 b->refs[i].frame_num = dpb[i].frame_num; 68 72 69 - if (dpb[i].fields == V4L2_H264_FRAME_REF) 70 - pic_order_count = min(dpb[i].top_field_order_cnt, 71 - dpb[i].bottom_field_order_cnt); 72 - else if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) 73 - pic_order_count = dpb[i].bottom_field_order_cnt; 74 - else 75 - pic_order_count = dpb[i].top_field_order_cnt; 73 + b->refs[i].top_field_order_cnt = dpb[i].top_field_order_cnt; 74 + b->refs[i].bottom_field_order_cnt = dpb[i].bottom_field_order_cnt; 76 75 77 - b->refs[i].pic_order_count = pic_order_count; 78 - b->unordered_reflist[b->num_valid].index = i; 79 - b->num_valid++; 76 + if (b->cur_pic_fields == V4L2_H264_FRAME_REF) { 77 + u8 fields = V4L2_H264_FRAME_REF; 78 + 79 + b->unordered_reflist[b->num_valid].index = i; 80 + b->unordered_reflist[b->num_valid].fields = fields; 81 + b->num_valid++; 82 + continue; 83 + } 84 + 85 + if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF) { 86 + u8 fields = V4L2_H264_TOP_FIELD_REF; 87 + 88 + b->unordered_reflist[b->num_valid].index = i; 89 + b->unordered_reflist[b->num_valid].fields = fields; 90 + b->num_valid++; 91 + } 92 + 93 + if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) { 94 + u8 fields = V4L2_H264_BOTTOM_FIELD_REF; 95 + 96 + b->unordered_reflist[b->num_valid].index = i; 97 + b->unordered_reflist[b->num_valid].fields = fields; 98 + b->num_valid++; 99 + } 80 100 } 81 101 82 102 for (i = b->num_valid; i < ARRAY_SIZE(b->unordered_reflist); i++) 83 103 b->unordered_reflist[i].index = i; 84 104 } 85 105 EXPORT_SYMBOL_GPL(v4l2_h264_init_reflist_builder); 106 + 107 + static s32 v4l2_h264_get_poc(const struct v4l2_h264_reflist_builder *b, 108 + const struct v4l2_h264_reference *ref) 109 + { 110 + switch (ref->fields) { 111 + case V4L2_H264_FRAME_REF: 112 + return min(b->refs[ref->index].top_field_order_cnt, 113 + b->refs[ref->index].bottom_field_order_cnt); 114 + case V4L2_H264_TOP_FIELD_REF: 115 + return b->refs[ref->index].top_field_order_cnt; 116 + case V4L2_H264_BOTTOM_FIELD_REF: 117 + return b->refs[ref->index].bottom_field_order_cnt; 118 + } 119 + 120 + /* not reached */ 121 + return 0; 122 + } 86 123 87 124 static int v4l2_h264_p_ref_list_cmp(const void *ptra, const void *ptrb, 88 125 const void *data) ··· 179 150 builder->refs[idxb].pic_num ? 180 151 -1 : 1; 181 152 182 - poca = builder->refs[idxa].pic_order_count; 183 - pocb = builder->refs[idxb].pic_order_count; 153 + poca = v4l2_h264_get_poc(builder, ptra); 154 + pocb = v4l2_h264_get_poc(builder, ptrb); 184 155 185 156 /* 186 157 * Short term pics with POC < cur POC first in POC descending order ··· 224 195 builder->refs[idxb].pic_num ? 225 196 -1 : 1; 226 197 227 - poca = builder->refs[idxa].pic_order_count; 228 - pocb = builder->refs[idxb].pic_order_count; 198 + poca = v4l2_h264_get_poc(builder, ptra); 199 + pocb = v4l2_h264_get_poc(builder, ptrb); 229 200 230 201 /* 231 202 * Short term pics with POC > cur POC first in POC ascending order
+4 -2
include/media/v4l2-h264.h
··· 15 15 /** 16 16 * struct v4l2_h264_reflist_builder - Reference list builder object 17 17 * 18 - * @refs.pic_order_count: reference picture order count 18 + * @refs.top_field_order_cnt: top field order count 19 + * @refs.bottom_field_order_cnt: bottom field order count 19 20 * @refs.frame_num: reference frame number 20 21 * @refs.pic_num: reference picture number 21 22 * @refs.longterm: set to true for a long term reference ··· 33 32 */ 34 33 struct v4l2_h264_reflist_builder { 35 34 struct { 36 - s32 pic_order_count; 35 + s32 top_field_order_cnt; 36 + s32 bottom_field_order_cnt; 37 37 int frame_num; 38 38 u32 pic_num; 39 39 u16 longterm : 1;