Added ability to enable workaround for dxva2 decoding using older ATI cards
authorJoakim Plate <elupus@ecce.se>
Mon, 4 Jul 2011 22:18:32 +0000 (00:18 +0200)
committerJoakim Plate <elupus@ecce.se>
Sat, 9 Jul 2011 15:21:31 +0000 (17:21 +0200)
The workaround need to be enabled per pci id which can not
be detected inside ffmpeg. So this adds a flag that enabled
the alternate behavior.

libavcodec/dxva2.h
libavcodec/dxva2_h264.c

index 5c5fe21..6eb494b 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <dxva2api.h>
 
+#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
+
 /**
  * This structure is used to provides the necessary configurations and data
  * to the DXVA2 FFmpeg HWAccel implementation.
index bc80e98..21157bf 100644 (file)
@@ -113,6 +113,9 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
 
     pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
     pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
+    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
+        pp->Reserved16Bits            = 0;
+    else
     pp->Reserved16Bits                = 3; /* FIXME is there a way to detect the right mode ? */
     pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
     pp->CurrFieldOrderCnt[0] = 0;
@@ -150,10 +153,19 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
     //pp->SliceGroupMap[810];               /* XXX not implemented by FFmpeg */
 }
 
-static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm)
+static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
 {
     unsigned i, j;
     memset(qm, 0, sizeof(*qm));
+    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
+        for (i = 0; i < 6; i++)
+            for (j = 0; j < 16; j++)
+                qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
+
+        for (i = 0; i < 2; i++)
+            for (j = 0; j < 64; j++)
+                qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j];
+    } else {
     for (i = 0; i < 6; i++)
         for (j = 0; j < 16; j++)
             qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]];
@@ -161,6 +173,7 @@ static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm)
     for (i = 0; i < 2; i++)
         for (j = 0; j < 64; j++)
             qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]];
+    }
 }
 
 static int is_slice_short(struct dxva_context *ctx)
@@ -370,7 +383,7 @@ static int start_frame(AVCodecContext *avctx,
     fill_picture_parameters(ctx, h, &ctx_pic->pp);
 
     /* Fill up DXVA_Qmatrix_H264 */
-    fill_scaling_lists(h, &ctx_pic->qm);
+    fill_scaling_lists(ctx, h, &ctx_pic->qm);
 
     ctx_pic->slice_count    = 0;
     ctx_pic->bitstream_size = 0;