ffmpeg backport: VC-1 DXVA2 improvements / Intel compat
authorShine <a.b@c.d>
Sun, 16 Feb 2014 10:45:41 +0000 (11:45 +0100)
committerShine <a.b@c.d>
Sun, 16 Feb 2014 10:59:37 +0000 (11:59 +0100)
lib/ffmpeg/libavcodec/dxva2_vc1.c
lib/ffmpeg/libavcodec/vc1.c
lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch [new file with mode: 0644]
lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch [new file with mode: 0644]
lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch [new file with mode: 0644]
lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch [new file with mode: 0644]
lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch [new file with mode: 0644]
lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch [new file with mode: 0644]

index 4f229a3..7a03614 100644 (file)
@@ -40,6 +40,15 @@ static void fill_picture_parameters(AVCodecContext *avctx,
     const Picture *current_picture = s->current_picture_ptr;
     BYTE bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type == 1;
     BYTE bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && v->bi_type == 0;
+    int intcomp = 0;
+
+    // determine if intensity compensation is needed
+    if (s->pict_type == AV_PICTURE_TYPE_P) {
+      if ((v->fcm == ILACE_FRAME && v->intcomp) || (v->fcm != ILACE_FRAME && v->mv_mode == MV_PMODE_INTENSITY_COMP)) {
+        if (v->lumscale != 32 || v->lumshift != 0 || (s->picture_structure != PICT_FRAME && (v->lumscale2 != 32 && v->lumshift2 != 0)))
+          intcomp = 1;
+      }
+    }
 
     memset(pp, 0, sizeof(*pp));
     pp->wDecodedPictureIndex    =
@@ -76,7 +85,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
     pp->bBidirectionalAveragingMode = (1                                           << 7) |
                                       ((ctx->cfg->ConfigIntraResidUnsigned != 0)   << 6) |
                                       ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
-                                      ((v->lumscale != 32 || v->lumshift != 0)     << 4) |
+                                      (intcomp                                     << 4) |
                                       ((v->profile == PROFILE_ADVANCED)            << 3);
     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
                                         (1                                       << 2) |
@@ -126,15 +135,25 @@ static void fill_picture_parameters(AVCodecContext *avctx,
                                   (v->range_mapuv_flag << 3) |
                                   (v->range_mapuv          );
     pp->bPicBinPB               = 0;
-    pp->bMV_RPS                 = 0;
-    pp->bReservedBits           = 0;
+    pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+    pp->bReservedBits           = v->pq;
     if (s->picture_structure == PICT_FRAME) {
-        pp->wBitstreamFcodes        = v->lumscale;
-        pp->wBitstreamPCEelements   = v->lumshift;
+        if (intcomp) {
+            pp->wBitstreamFcodes      = v->lumscale;
+            pp->wBitstreamPCEelements = v->lumshift;
+        } else {
+            pp->wBitstreamFcodes      = 32;
+            pp->wBitstreamPCEelements = 0;
+        }
     } else {
         /* Syntax: (top_field_param << 8) | bottom_field_param */
-        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
-        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
+        if (intcomp) {
+            pp->wBitstreamFcodes      = (v->lumscale << 8) | v->lumscale2;
+            pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift2;
+        } else {
+            pp->wBitstreamFcodes      = (32 << 8) | 32;
+            pp->wBitstreamPCEelements = 0;
+        }
     }
     pp->bBitstreamConcealmentNeed   = 0;
     pp->bBitstreamConcealmentMethod = 0;
@@ -152,8 +171,8 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
     slice->dwSliceBitsInBuffer = 8 * size;
     slice->dwSliceDataLocation = position;
     slice->bStartCodeBitOffset = 0;
-    slice->bReservedBits       = 0;
-    slice->wMBbitOffset        = get_bits_count(&s->gb);
+    slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+    slice->wMBbitOffset        = v->p_frame_skipped ? 0xffff : get_bits_count(&s->gb);
     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
     slice->wQuantizerScaleCode = v->pq;
     slice->wBadSliceChopping   = 0;
index a6a7bac..e2e90a8 100644 (file)
@@ -303,6 +303,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
         v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
         return decode_sequence_header_adv(v, gb);
     } else {
+           v->chromaformat = 1;
         v->zz_8x4 = ff_wmv2_scantableA;
         v->zz_4x8 = ff_wmv2_scantableB;
         v->res_y411   = get_bits1(gb);
diff --git a/lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch b/lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch
new file mode 100644 (file)
index 0000000..4492ccb
--- /dev/null
@@ -0,0 +1,26 @@
+From 8abdf46b380562d4716a78174076b1e67ae1f8da Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:48 +0100
+Subject: [PATCH] dxva2_vc1: set refdist value according to spec
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 2e9a00e..6ff5765 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -122,7 +122,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+                                   (v->range_mapuv_flag << 3) |
+                                   (v->range_mapuv          );
+     pp->bPicBinPB               = 0;
+-    pp->bMV_RPS                 = 0;
++    pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+     pp->bReservedBits           = 0;
+     if (s->picture_structure == PICT_FRAME) {
+         pp->wBitstreamFcodes        = v->lumscale;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch b/lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch
new file mode 100644 (file)
index 0000000..9886068
--- /dev/null
@@ -0,0 +1,26 @@
+From 3021d1be9ef1f863f880b5c667025936b45da065 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:49 +0100
+Subject: [PATCH] dxva2_vc1: set bfraction in slice info according to spec
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 6ff5765..33309b1 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -148,7 +148,7 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
+     slice->dwSliceBitsInBuffer = 8 * size;
+     slice->dwSliceDataLocation = position;
+     slice->bStartCodeBitOffset = 0;
+-    slice->bReservedBits       = 0;
++    slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+     slice->wMBbitOffset        = get_bits_count(&s->gb);
+     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
+     slice->wQuantizerScaleCode = v->pq;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch b/lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch
new file mode 100644 (file)
index 0000000..7e575e6
--- /dev/null
@@ -0,0 +1,26 @@
+From e1facd3f8198fc4bfd54f3a4097e66513e6bf3e4 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:50 +0100
+Subject: [PATCH] dxva2_vc1: set PQUANT as described by the 2010 spec update
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 33309b1..bf4e8e0 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -123,7 +123,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+                                   (v->range_mapuv          );
+     pp->bPicBinPB               = 0;
+     pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+-    pp->bReservedBits           = 0;
++    pp->bReservedBits           = v->pq;
+     if (s->picture_structure == PICT_FRAME) {
+         pp->wBitstreamFcodes        = v->lumscale;
+         pp->wBitstreamPCEelements   = v->lumshift;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch b/lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch
new file mode 100644 (file)
index 0000000..6df4296
--- /dev/null
@@ -0,0 +1,28 @@
+From 719f1ce5fb41493fe10edca1ba9223fa601b6165 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:51 +0100
+Subject: [PATCH] vc1: set chromaformat = 1 for simple/main profile
+
+1 is the only valid value for VC-1/WMV3, and setting it here makes sure
+no invalid value is send to a hw accelerator, for example.
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/vc1.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/vc1.c b/xbmc/lib/ffmpeg/libavcodec/vc1.c
+index fb33e6f..f8d3162 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/vc1.c
+@@ -293,6 +293,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
+         v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
+         return decode_sequence_header_adv(v, gb);
+     } else {
++        v->chromaformat = 1;
+         v->zz_8x4 = ff_wmv2_scantableA;
+         v->zz_4x8 = ff_wmv2_scantableB;
+         v->res_y411   = get_bits1(gb);
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch b/lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch
new file mode 100644 (file)
index 0000000..e4a17bb
--- /dev/null
@@ -0,0 +1,73 @@
+From c5562890c7c3e495a1995bfa64f730806020e8d6 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:52 +0100
+Subject: [PATCH] dxva2_vc1: fix signaling of intensity compensation values
+
+lumscale/lumshift don't get reset back to their default values if
+intensity compensation is not active, and a wrong signaling here can
+cause playback issues.
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index bf4e8e0..995b3e3 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -38,6 +38,15 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+ {
+     const MpegEncContext *s = &v->s;
+     const Picture *current_picture = s->current_picture_ptr;
++    int intcomp = 0;
++
++    // determine if intensity compensation is needed
++    if (s->pict_type == AV_PICTURE_TYPE_P) {
++      if ((v->fcm == ILACE_FRAME && v->intcomp) || (v->fcm != ILACE_FRAME && v->mv_mode == MV_PMODE_INTENSITY_COMP)) {
++        if (v->lumscale != 32 || v->lumshift != 0 || (s->picture_structure != PICT_FRAME && (v->lumscale2 != 32 && v->lumshift2 != 0)))
++          intcomp = 1;
++      }
++    }
+     memset(pp, 0, sizeof(*pp));
+     pp->wDecodedPictureIndex    =
+@@ -74,7 +83,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+     pp->bBidirectionalAveragingMode = (1                                           << 7) |
+                                       ((ctx->cfg->ConfigIntraResidUnsigned != 0)   << 6) |
+                                       ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
+-                                      ((v->lumscale != 32 || v->lumshift != 0)     << 4) |
++                                      (intcomp                                     << 4) |
+                                       ((v->profile == PROFILE_ADVANCED)            << 3);
+     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
+                                         (1                                       << 2) |
+@@ -125,12 +134,22 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+     pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+     pp->bReservedBits           = v->pq;
+     if (s->picture_structure == PICT_FRAME) {
+-        pp->wBitstreamFcodes        = v->lumscale;
+-        pp->wBitstreamPCEelements   = v->lumshift;
++        if (intcomp) {
++            pp->wBitstreamFcodes      = v->lumscale;
++            pp->wBitstreamPCEelements = v->lumshift;
++        } else {
++            pp->wBitstreamFcodes      = 32;
++            pp->wBitstreamPCEelements = 0;
++        }
+     } else {
+         /* Syntax: (top_field_param << 8) | bottom_field_param */
+-        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
+-        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
++        if (intcomp) {
++            pp->wBitstreamFcodes      = (v->lumscale << 8) | v->lumscale2;
++            pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift2;
++        } else {
++            pp->wBitstreamFcodes      = (32 << 8) | 32;
++            pp->wBitstreamPCEelements = 0;
++        }
+     }
+     pp->bBitstreamConcealmentNeed   = 0;
+     pp->bBitstreamConcealmentMethod = 0;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch b/lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch
new file mode 100644 (file)
index 0000000..44a4e50
--- /dev/null
@@ -0,0 +1,25 @@
+From 3d8eeea62009a85c88ee4a630da4d6037920aa6e Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:53 +0100
+Subject: [PATCH] dxva2_vc1: signal skipped p frames
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 995b3e3..a86d7cd 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -168,7 +168,7 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
+     slice->dwSliceDataLocation = position;
+     slice->bStartCodeBitOffset = 0;
+     slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+-    slice->wMBbitOffset        = get_bits_count(&s->gb);
++    slice->wMBbitOffset        = v->p_frame_skipped ? 0xffff : get_bits_count(&s->gb);
+     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
+     slice->wQuantizerScaleCode = v->pq;
+     slice->wBadSliceChopping   = 0;
+-- 
+1.8.5.1