[FFmpeg-devel,v2] lavc/vc1dec: add multi-slice decoding support for hwaccel.

Submitted by Jun Zhao on Nov. 16, 2016, 7:17 a.m.

Details

Message ID f55b0c7b-c97a-283f-b120-13c78f4ee6ef@gmail.com
State New
Headers show

Commit Message

Jun Zhao Nov. 16, 2016, 7:17 a.m.
V2: - in i965 + Skylake, after apply this fix, it's can decode vc1_sa20021/
    vc1_sa10091, but can't decode vc1_sa10143/vc1_ilaced_twomv, the root 
    cause is i965 driver can't support interlaced VC1 decode, I will open
    a issue to i965 driver.
   - used the cmd "make HWACCEL='vaapi -vaapi_device /dev/dri/renderD128 -hwaccel_output_format yuv420p' fate-vc1 -i" reproduce and verify
From fe93d69cf9ffe8a9a84c1371f185dc8d10d0aec4 Mon Sep 17 00:00:00 2001
From: Jun Zhao <mypopydev@gmail.com>
Date: Tue, 15 Nov 2016 15:09:50 +0800
Subject: [PATCH v2] lavc/vc1dec: add multi-slice decoding support for hwaccel.

add mutil-slice decoding support for hwaccel, after this fix
vaapi hwaccel decoder will support FATE test sample SA20021.vc1,
SA10091.vc1, and can't decode ilaced_twomv.vc1, SA10143.vc1

Signed-off-by: Wang, Yi A <yi.a.wang@intel.com>
Signed-off-by: Jun Zhao <jun.zhao@intel.com>
---
 libavcodec/vc1dec.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 4f78aa8..0c57f47 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -632,6 +632,8 @@  static int vc1_decode_frame(AVCodecContext *avctx, void *data,
     int mb_height, n_slices1=-1;
     struct {
         uint8_t *buf;
+        uint8_t *buf_start;
+        int buf_size;
         GetBitContext gb;
         int mby_start;
     } *slices = NULL, *tmp;
@@ -738,6 +740,10 @@  static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                         ret = AVERROR(ENOMEM);
                         goto err;
                     }
+
+                    slices[n_slices].buf_start = start;
+                    slices[n_slices].buf_size = size + 4;
+
                     buf_size3 = vc1_unescape_buffer(start + 4, size,
                                                     slices[n_slices].buf);
                     init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
@@ -951,10 +957,27 @@  static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                 goto err;
         } else {
             s->picture_structure = PICT_FRAME;
+            s->mb_y = 0;
             if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
                 goto err;
-            if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
-                goto err;
+            if (n_slices == 0) {
+                if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
+                    goto err;
+            } else {
+                int i;
+                ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].buf_start - buf_start);
+                if (ret < 0)
+                    goto err;
+                for (i = 0 ; i < n_slices; i++) {
+                     s->gb = slices[i].gb;
+                     s->mb_y = slices[i].mby_start;
+                     if (get_bits(&s->gb, 1))
+                         ff_vc1_parse_frame_header_adv(v, &s->gb);
+                     ret = avctx->hwaccel->decode_slice(avctx, slices[i].buf_start, slices[i].buf_size);
+                     if (ret < 0)
+                         goto err;
+                }
+            }
             if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
                 goto err;
         }