media: hantro: HEVC: Fix reference frames management
authorBenjamin Gaignard <benjamin.gaignard@collabora.com>
Tue, 3 May 2022 13:51:38 +0000 (15:51 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 13 May 2022 09:02:22 +0000 (11:02 +0200)
PoC shall be int the range of -2^31 to 2^31 -1
(HEVC spec section 8.3.1 Decoding process for picture order count).
The current way to know if an entry in reference picture array is free
is to test if PoC = UNUSED_REF. Since UNUSED_REF is defined as '-1' that
could lead to decode issue if one PoC also equal '-1'.
PoC with value = '-1' exists in conformance test SLIST_B_Sony_9.

Change the way unused entries are managed in reference pictures array to
avoid using PoC to detect then.

This patch doesn't change fluster HEVC score.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/staging/media/hantro/hantro_g2_hevc_dec.c
drivers/staging/media/hantro/hantro_hevc.c
drivers/staging/media/hantro/hantro_hw.h

index 41185d1..34da4bf 100644 (file)
@@ -420,7 +420,7 @@ static int set_ref(struct hantro_ctx *ctx)
        set_ref_pic_list(ctx);
 
        /* We will only keep the reference pictures that are still used */
-       ctx->hevc_dec.ref_bufs_used = 0;
+       hantro_hevc_ref_init(ctx);
 
        /* Set up addresses of DPB buffers */
        dpb_longterm_e = 0;
@@ -461,8 +461,6 @@ static int set_ref(struct hantro_ctx *ctx)
        hantro_write_addr(vpu, G2_OUT_CHROMA_ADDR, chroma_addr);
        hantro_write_addr(vpu, G2_OUT_MV_ADDR, mv_addr);
 
-       hantro_hevc_ref_remove_unused(ctx);
-
        for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
                hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), 0);
                hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), 0);
index b3a057b..f86c98e 100644 (file)
 #define MAX_TILE_COLS 20
 #define MAX_TILE_ROWS 22
 
-#define UNUSED_REF     -1
-
-static void hantro_hevc_ref_init(struct hantro_ctx *ctx)
+void hantro_hevc_ref_init(struct hantro_ctx *ctx)
 {
        struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
-       int i;
 
-       for (i = 0;  i < NUM_REF_PICTURES; i++)
-               hevc_dec->ref_bufs_poc[i] = UNUSED_REF;
+       hevc_dec->ref_bufs_used = 0;
 }
 
 dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
@@ -60,7 +56,7 @@ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
 
        /* Add a new reference buffer */
        for (i = 0; i < NUM_REF_PICTURES; i++) {
-               if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF) {
+               if (!(hevc_dec->ref_bufs_used & 1 << i)) {
                        hevc_dec->ref_bufs_used |= 1 << i;
                        hevc_dec->ref_bufs_poc[i] = poc;
                        hevc_dec->ref_bufs[i].dma = addr;
@@ -71,23 +67,6 @@ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
        return -EINVAL;
 }
 
-void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx)
-{
-       struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
-       int i;
-
-       /* Just tag buffer as unused, do not free them */
-       for (i = 0;  i < NUM_REF_PICTURES; i++) {
-               if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF)
-                       continue;
-
-               if (hevc_dec->ref_bufs_used & (1 << i))
-                       continue;
-
-               hevc_dec->ref_bufs_poc[i] = UNUSED_REF;
-       }
-}
-
 static int tile_buffer_reallocate(struct hantro_ctx *ctx)
 {
        struct hantro_dev *vpu = ctx->dev;
index 594f318..04844bb 100644 (file)
@@ -342,9 +342,9 @@ int hantro_hevc_dec_init(struct hantro_ctx *ctx);
 void hantro_hevc_dec_exit(struct hantro_ctx *ctx);
 int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
 int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
+void hantro_hevc_ref_init(struct hantro_ctx *ctx);
 dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
 int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
-void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
 
 static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
 {