Browse code

vc1dec: support multiple slices in frame coded images with hwaccel

Based on a patch by Jun Zhao <mypopydev@gmail.com>

Hendrik Leppkes authored on 2016/11/15 18:28:10
Showing 3 changed files
... ...
@@ -43,6 +43,7 @@ version 3.2:
43 43
 - Matroska muxer now writes CRC32 elements by default in all Level 1 elements
44 44
 - sidedata video and asidedata audio filter
45 45
 - Changed mapping of rtp MIME type G726 to codec g726le.
46
+- spec compliant VAAPI/DXVA2 VC-1 decoding of slices in frame-coded images
46 47
 
47 48
 
48 49
 version 3.1:
... ...
@@ -634,6 +634,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
634 634
         uint8_t *buf;
635 635
         GetBitContext gb;
636 636
         int mby_start;
637
+        const uint8_t *rawbuf;
638
+        int raw_size;
637 639
     } *slices = NULL, *tmp;
638 640
 
639 641
     v->second_field = 0;
... ...
@@ -716,6 +718,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
716 716
                     /* assuming that the field marker is at the exact middle,
717 717
                        hope it's correct */
718 718
                     slices[n_slices].mby_start = s->mb_height + 1 >> 1;
719
+                    slices[n_slices].rawbuf = start;
720
+                    slices[n_slices].raw_size = size + 4;
719 721
                     n_slices1 = n_slices - 1; // index of the last slice of the first field
720 722
                     n_slices++;
721 723
                     break;
... ...
@@ -743,6 +747,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
743 743
                     init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
744 744
                                   buf_size3 << 3);
745 745
                     slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);
746
+                    slices[n_slices].rawbuf = start;
747
+                    slices[n_slices].raw_size = size + 4;
746 748
                     n_slices++;
747 749
                     break;
748 750
                 }
... ...
@@ -779,6 +785,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
779 779
                 init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
780 780
                               buf_size3 << 3);
781 781
                 slices[n_slices].mby_start = s->mb_height + 1 >> 1;
782
+                slices[n_slices].rawbuf = divider;
783
+                slices[n_slices].raw_size = buf + buf_size - divider;
782 784
                 n_slices1 = n_slices - 1;
783 785
                 n_slices++;
784 786
             }
... ...
@@ -921,6 +929,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
921 921
     } else
922 922
 #endif
923 923
     if (avctx->hwaccel) {
924
+        s->mb_y = 0;
924 925
         if (v->field_mode && buf_start_second_field) {
925 926
             // decode first field
926 927
             s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
... ...
@@ -953,8 +962,36 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
953 953
             s->picture_structure = PICT_FRAME;
954 954
             if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
955 955
                 goto err;
956
-            if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
957
-                goto err;
956
+
957
+            if (n_slices == 0) {
958
+                // no slices, decode the frame as-is
959
+                if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
960
+                    goto err;
961
+            } else {
962
+                // decode the frame part as the first slice
963
+                if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0)
964
+                    goto err;
965
+
966
+                // and process the slices as additional slices afterwards
967
+                for (i = 0 ; i < n_slices; i++) {
968
+                    s->gb = slices[i].gb;
969
+                    s->mb_y = slices[i].mby_start;
970
+
971
+                    v->pic_header_flag = get_bits1(&s->gb);
972
+                    if (v->pic_header_flag) {
973
+                        if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
974
+                            av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");
975
+                            ret = AVERROR_INVALIDDATA;
976
+                            if (avctx->err_recognition & AV_EF_EXPLODE)
977
+                                goto err;
978
+                            continue;
979
+                        }
980
+                    }
981
+
982
+                    if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0)
983
+                        goto err;
984
+                }
985
+            }
958 986
             if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
959 987
                 goto err;
960 988
         }
... ...
@@ -29,7 +29,7 @@
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR  57
31 31
 #define LIBAVCODEC_VERSION_MINOR  66
32
-#define LIBAVCODEC_VERSION_MICRO 107
32
+#define LIBAVCODEC_VERSION_MICRO 108
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
35 35
                                                LIBAVCODEC_VERSION_MINOR, \