[FFmpeg-devel] [PATCH] Added ability to enable workaround for dxva2 decoding using older ATI cards

Laurent Aimar fenrir at elivagar.org
Mon Jul 4 00:51:51 CEST 2011


Hi,

On Sun, Jul 03, 2011 at 05:23:28PM +0200, elupus wrote:
> This was submitted to xbmc tracker http://trac.xbmc.org/ticket/11636 by
> isidrogar a while back. I've not verified it but maybe somebody with some
> more dxva2 experience could have a look at it.
> 
> It will not break any other cards since it's only enabled by a workaround
> flag. I'll push a reindent after if it seems okey.

> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -1441,6 +1441,7 @@ typedef struct AVCodecContext {
>  #define FF_BUG_DC_CLIP          4096
>  #define FF_BUG_MS               8192 ///< Work around various bugs in Microsoft's broken decoders.
>  #define FF_BUG_TRUNCATED       16384
> +#define FF_BUG_DXVA2_SCALING_LIST_ZIGZAG 32768 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
>  //#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%.

 To avoid putting it into the global flags, I did add a field
dxva_context::workaround
for such pupose.

>  
>      /**
> diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
> index bc80e98..3ad8fcf 100644
> --- a/libavcodec/dxva2_h264.c
> +++ b/libavcodec/dxva2_h264.c
> @@ -150,10 +150,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(AVCodecContext *avctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
>  {
>      unsigned i, j;
>      memset(qm, 0, sizeof(*qm));
> +    if (avctx->workaround_bugs & FF_BUG_DXVA2_SCALING_LIST_ZIGZAG) {  // For old UVD/UVD+ ATI cards
> +    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 +170,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]];
> +    }
>  }
I am not sure that with recent enough driver this is needed.
But if it is, I am pretty sure (but I haven't checked) that in this case,
you also need to change:
 pp->Reserved16Bits                = 3; /* FIXME is there a way to detect the right mode ? */
(from fill_picture_parameters)
into
 pp->Reserved16Bits = 0;
when you enable the workaround (and only when you enable it).

-- 
fenrir



More information about the ffmpeg-devel mailing list