2222#define POC_BUFFER_SIZE 34
2323#define SCALING_LIST_SIZE (6 * 16 + 2 * 64)
2424
25+ /*
26+ * For valid and long term reference marking, index are reversed, so bit 31
27+ * indicates the status of the picture 0.
28+ */
29+ #define REF_BIT (i ) BIT(32 - 1 - (i))
30+
2531/* Data structure describing auxiliary buffer format. */
2632struct hantro_h264_dec_priv_tbl {
2733 u32 cabac_table [CABAC_INIT_BUFFER_SIZE ];
@@ -227,6 +233,7 @@ static void prepare_table(struct hantro_ctx *ctx)
227233{
228234 const struct hantro_h264_dec_ctrls * ctrls = & ctx -> h264_dec .ctrls ;
229235 const struct v4l2_ctrl_h264_decode_params * dec_param = ctrls -> decode ;
236+ const struct v4l2_ctrl_h264_sps * sps = ctrls -> sps ;
230237 struct hantro_h264_dec_priv_tbl * tbl = ctx -> h264_dec .priv .cpu ;
231238 const struct v4l2_h264_dpb_entry * dpb = ctx -> h264_dec .dpb ;
232239 u32 dpb_longterm = 0 ;
@@ -237,20 +244,45 @@ static void prepare_table(struct hantro_ctx *ctx)
237244 tbl -> poc [i * 2 ] = dpb [i ].top_field_order_cnt ;
238245 tbl -> poc [i * 2 + 1 ] = dpb [i ].bottom_field_order_cnt ;
239246
247+ if (!(dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_VALID ))
248+ continue ;
249+
240250 /*
241251 * Set up bit maps of valid and long term DPBs.
242- * NOTE: The bits are reversed, i.e. MSb is DPB 0.
252+ * NOTE: The bits are reversed, i.e. MSb is DPB 0. For frame
253+ * decoding, bit 31 to 15 are used, while for field decoding,
254+ * all bits are used, with bit 31 being a top field, 30 a bottom
255+ * field and so on.
243256 */
244- if (dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE )
245- dpb_valid |= BIT (HANTRO_H264_DPB_SIZE - 1 - i );
246- if (dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM )
247- dpb_longterm |= BIT (HANTRO_H264_DPB_SIZE - 1 - i );
257+ if (dec_param -> flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC ) {
258+ if (dpb [i ].fields & V4L2_H264_TOP_FIELD_REF )
259+ dpb_valid |= REF_BIT (i * 2 );
260+
261+ if (dpb [i ].fields & V4L2_H264_BOTTOM_FIELD_REF )
262+ dpb_valid |= REF_BIT (i * 2 + 1 );
263+
264+ if (dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM ) {
265+ dpb_longterm |= REF_BIT (i * 2 );
266+ dpb_longterm |= REF_BIT (i * 2 + 1 );
267+ }
268+ } else {
269+ dpb_valid |= REF_BIT (i );
270+
271+ if (dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM )
272+ dpb_longterm |= REF_BIT (i );
273+ }
274+ }
275+ ctx -> h264_dec .dpb_valid = dpb_valid ;
276+ ctx -> h264_dec .dpb_longterm = dpb_longterm ;
277+
278+ if ((dec_param -> flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC ) ||
279+ !(sps -> flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD )) {
280+ tbl -> poc [32 ] = ctx -> h264_dec .cur_poc ;
281+ tbl -> poc [33 ] = 0 ;
282+ } else {
283+ tbl -> poc [32 ] = dec_param -> top_field_order_cnt ;
284+ tbl -> poc [33 ] = dec_param -> bottom_field_order_cnt ;
248285 }
249- ctx -> h264_dec .dpb_valid = dpb_valid << 16 ;
250- ctx -> h264_dec .dpb_longterm = dpb_longterm << 16 ;
251-
252- tbl -> poc [32 ] = dec_param -> top_field_order_cnt ;
253- tbl -> poc [33 ] = dec_param -> bottom_field_order_cnt ;
254286
255287 assemble_scaling_list (ctx );
256288}
@@ -326,6 +358,8 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
326358{
327359 struct v4l2_h264_dpb_entry * dpb = ctx -> h264_dec .dpb ;
328360 dma_addr_t dma_addr = 0 ;
361+ s32 cur_poc = ctx -> h264_dec .cur_poc ;
362+ u32 flags ;
329363
330364 if (dpb [dpb_idx ].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE )
331365 dma_addr = hantro_get_ref (ctx , dpb [dpb_idx ].reference_ts );
@@ -343,7 +377,12 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
343377 dma_addr = hantro_get_dec_buf_addr (ctx , buf );
344378 }
345379
346- return dma_addr ;
380+ flags = dpb [dpb_idx ].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD ? 0x2 : 0 ;
381+ flags |= abs (dpb [dpb_idx ].top_field_order_cnt - cur_poc ) <
382+ abs (dpb [dpb_idx ].bottom_field_order_cnt - cur_poc ) ?
383+ 0x1 : 0 ;
384+
385+ return dma_addr | flags ;
347386}
348387
349388u16 hantro_h264_get_ref_nbr (struct hantro_ctx * ctx , unsigned int dpb_idx )
@@ -355,6 +394,47 @@ u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, unsigned int dpb_idx)
355394 return dpb -> frame_num ;
356395}
357396
397+ /*
398+ * Removes all references with the same parity as the current picture from the
399+ * reference list. The remaining list will have references with the opposite
400+ * parity. This is effectively a deduplication of references since each buffer
401+ * stores two fields. For this reason, each buffer is found twice in the
402+ * reference list.
403+ *
404+ * This technique has been chosen through trial and error. This simple approach
405+ * resulted in the highest conformance score. Note that this method may suffer
406+ * worse quality in the case an opposite reference frame has been lost. If this
407+ * becomes a problem in the future, it should be possible to add a preprocessing
408+ * to identify un-paired fields and avoid removing them.
409+ */
410+ static void deduplicate_reflist (struct v4l2_h264_reflist_builder * b ,
411+ struct v4l2_h264_reference * reflist )
412+ {
413+ int write_idx = 0 ;
414+ int i ;
415+
416+ if (b -> cur_pic_fields == V4L2_H264_FRAME_REF ) {
417+ write_idx = b -> num_valid ;
418+ goto done ;
419+ }
420+
421+ for (i = 0 ; i < b -> num_valid ; i ++ ) {
422+ if (!(b -> cur_pic_fields == reflist [i ].fields )) {
423+ reflist [write_idx ++ ] = reflist [i ];
424+ continue ;
425+ }
426+ }
427+
428+ done :
429+ /* Should not happen unless we have a bug in the reflist builder. */
430+ if (WARN_ON (write_idx > 16 ))
431+ write_idx = 16 ;
432+
433+ /* Clear the remaining, some streams fails otherwise */
434+ for (; write_idx < 16 ; write_idx ++ )
435+ reflist [write_idx ].index = 15 ;
436+ }
437+
358438int hantro_h264_dec_prepare_run (struct hantro_ctx * ctx )
359439{
360440 struct hantro_h264_dec_hw_ctx * h264_ctx = & ctx -> h264_dec ;
@@ -386,15 +466,29 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx)
386466 /* Update the DPB with new refs. */
387467 update_dpb (ctx );
388468
389- /* Prepare data in memory. */
390- prepare_table (ctx );
391-
392469 /* Build the P/B{0,1} ref lists. */
393470 v4l2_h264_init_reflist_builder (& reflist_builder , ctrls -> decode ,
394471 ctrls -> sps , ctx -> h264_dec .dpb );
472+ h264_ctx -> cur_poc = reflist_builder .cur_pic_order_count ;
473+
474+ /* Prepare data in memory. */
475+ prepare_table (ctx );
476+
395477 v4l2_h264_build_p_ref_list (& reflist_builder , h264_ctx -> reflists .p );
396478 v4l2_h264_build_b_ref_lists (& reflist_builder , h264_ctx -> reflists .b0 ,
397479 h264_ctx -> reflists .b1 );
480+
481+ /*
482+ * Reduce ref lists to at most 16 entries, Hantro hardware will deduce
483+ * the actual picture lists in field through the dpb_valid,
484+ * dpb_longterm bitmap along with the current frame parity.
485+ */
486+ if (reflist_builder .cur_pic_fields != V4L2_H264_FRAME_REF ) {
487+ deduplicate_reflist (& reflist_builder , h264_ctx -> reflists .p );
488+ deduplicate_reflist (& reflist_builder , h264_ctx -> reflists .b0 );
489+ deduplicate_reflist (& reflist_builder , h264_ctx -> reflists .b1 );
490+ }
491+
398492 return 0 ;
399493}
400494
0 commit comments