From 8b2a130d3fe61e348092714dffa425b63c4d796c Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Tue, 4 Mar 2014 08:28:39 +0100 Subject: [PATCH] dxva2_h264: add a workaround for old intel GPUs Old Intel GPUs expect the reference frame index to the actual surface, instead of the index into RefFrameList as specified by the spec. This workaround should be set when using one of the "ClearVideo" decoder devices. Signed-off-by: Michael Niedermayer --- libavcodec/dxva2.h | 1 + libavcodec/dxva2_h264.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h index ac39e06917..2639d89d90 100644 --- a/libavcodec/dxva2.h +++ b/libavcodec/dxva2.h @@ -49,6 +49,7 @@ */ #define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for DXVA2 and old Intel GPUs with ClearVideo interface /** * This structure is used to provides the necessary configurations and data diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index 2484486a11..d7bad26424 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -115,6 +115,8 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) pp->Reserved16Bits = 0; + else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) + pp->Reserved16Bits = 0x34c; else pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ pp->StatusReportFeedbackNumber = 1 + ctx->report_id++; @@ -238,7 +240,11 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, if (list < h->list_count && i < h->ref_count[list]) { const Picture *r = &h->ref_list[list][i]; unsigned plane; - unsigned index = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, r)); + unsigned index; + if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) + index = ff_dxva2_get_surface_index(ctx, r); + else + index = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, r)); fill_picture_entry(&slice->RefPicList[list][i], index, r->reference == PICT_BOTTOM_FIELD); for (plane = 0; plane < 3; plane++) {