22
22
#define POC_BUFFER_SIZE 34
23
23
#define SCALING_LIST_SIZE (6 * 16 + 2 * 64)
24
24
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
+
25
31
/* Data structure describing auxiliary buffer format. */
26
32
struct hantro_h264_dec_priv_tbl {
27
33
u32 cabac_table [CABAC_INIT_BUFFER_SIZE ];
@@ -227,6 +233,7 @@ static void prepare_table(struct hantro_ctx *ctx)
227
233
{
228
234
const struct hantro_h264_dec_ctrls * ctrls = & ctx -> h264_dec .ctrls ;
229
235
const struct v4l2_ctrl_h264_decode_params * dec_param = ctrls -> decode ;
236
+ const struct v4l2_ctrl_h264_sps * sps = ctrls -> sps ;
230
237
struct hantro_h264_dec_priv_tbl * tbl = ctx -> h264_dec .priv .cpu ;
231
238
const struct v4l2_h264_dpb_entry * dpb = ctx -> h264_dec .dpb ;
232
239
u32 dpb_longterm = 0 ;
@@ -237,20 +244,45 @@ static void prepare_table(struct hantro_ctx *ctx)
237
244
tbl -> poc [i * 2 ] = dpb [i ].top_field_order_cnt ;
238
245
tbl -> poc [i * 2 + 1 ] = dpb [i ].bottom_field_order_cnt ;
239
246
247
+ if (!(dpb [i ].flags & V4L2_H264_DPB_ENTRY_FLAG_VALID ))
248
+ continue ;
249
+
240
250
/*
241
251
* 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.
243
256
*/
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 ;
248
285
}
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 ;
254
286
255
287
assemble_scaling_list (ctx );
256
288
}
@@ -326,6 +358,8 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
326
358
{
327
359
struct v4l2_h264_dpb_entry * dpb = ctx -> h264_dec .dpb ;
328
360
dma_addr_t dma_addr = 0 ;
361
+ s32 cur_poc = ctx -> h264_dec .cur_poc ;
362
+ u32 flags ;
329
363
330
364
if (dpb [dpb_idx ].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE )
331
365
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,
343
377
dma_addr = hantro_get_dec_buf_addr (ctx , buf );
344
378
}
345
379
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 ;
347
386
}
348
387
349
388
u16 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)
355
394
return dpb -> frame_num ;
356
395
}
357
396
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
+
358
438
int hantro_h264_dec_prepare_run (struct hantro_ctx * ctx )
359
439
{
360
440
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)
386
466
/* Update the DPB with new refs. */
387
467
update_dpb (ctx );
388
468
389
- /* Prepare data in memory. */
390
- prepare_table (ctx );
391
-
392
469
/* Build the P/B{0,1} ref lists. */
393
470
v4l2_h264_init_reflist_builder (& reflist_builder , ctrls -> decode ,
394
471
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
+
395
477
v4l2_h264_build_p_ref_list (& reflist_builder , h264_ctx -> reflists .p );
396
478
v4l2_h264_build_b_ref_lists (& reflist_builder , h264_ctx -> reflists .b0 ,
397
479
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
+
398
492
return 0 ;
399
493
}
400
494
0 commit comments