[vlc-commits] contrib: ffmpeg: add DXVA code to handle extra data for HEVC Range Extension

Steve Lhomme git at videolan.org
Fri Mar 13 10:28:39 CET 2020


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Fri Dec 13 12:01:00 2019 +0100| [ef400315cd2d34edf1aabc0975de6593d472c03c] | committer: Steve Lhomme

contrib: ffmpeg: add DXVA code to handle extra data for HEVC Range Extension

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ef400315cd2d34edf1aabc0975de6593d472c03c
---

 ...a2_hevc-add-support-for-parsing-HEVC-Rang.patch | 164 +++++++++++++++++++++
 ...cdec-allow-HEVC-444-8-10-12-bits-decoding.patch |  46 ++++++
 ...cdec-allow-HEVC-422-10-12-bits-decoding-w.patch |  34 +++++
 contrib/src/ffmpeg/rules.mak                       |   3 +
 4 files changed, 247 insertions(+)

diff --git a/contrib/src/ffmpeg/0001-avcodec-dxva2_hevc-add-support-for-parsing-HEVC-Rang.patch b/contrib/src/ffmpeg/0001-avcodec-dxva2_hevc-add-support-for-parsing-HEVC-Rang.patch
new file mode 100644
index 0000000000..a5ca25da9e
--- /dev/null
+++ b/contrib/src/ffmpeg/0001-avcodec-dxva2_hevc-add-support-for-parsing-HEVC-Rang.patch
@@ -0,0 +1,164 @@
+From 5cbf399500744af87ab8f29a70080af2255994da Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 3 Oct 2019 14:05:40 +0200
+Subject: [PATCH] avcodec/dxva2_hevc: add support for parsing HEVC Range
+ Extension data
+
+---
+ libavcodec/d3d11va.h    |  1 +
+ libavcodec/dxva2.h      |  1 +
+ libavcodec/dxva2_hevc.c | 79 ++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 76 insertions(+), 5 deletions(-)
+
+diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
+index 6816b6c1e6..68a69c372d 100644
+--- a/libavcodec/d3d11va.h
++++ b/libavcodec/d3d11va.h
+@@ -47,6 +47,7 @@
+ 
+ #define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards
+ #define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO    2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface
++#define FF_DXVA2_WORKAROUND_HEVC_REXT           4 ///< Signal the D3D11VA decoder is using the HEVC Rext picture structure
+ 
+ /**
+  * This structure is used to provides the necessary configurations and data
+diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
+index 22c93992f2..024999239d 100644
+--- a/libavcodec/dxva2.h
++++ b/libavcodec/dxva2.h
+@@ -47,6 +47,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
++#define FF_DXVA2_WORKAROUND_HEVC_REXT           4 ///< Signal the DXVA2 decoder is using the HEVC Rext picture structure
+ 
+ /**
+  * This structure is used to provides the necessary configurations and data
+diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
+index dbb701fb1c..98b3e74bd7 100644
+--- a/libavcodec/dxva2_hevc.c
++++ b/libavcodec/dxva2_hevc.c
+@@ -26,10 +26,47 @@
+ #include "hevc_data.h"
+ #include "hevcdec.h"
+ 
++#pragma pack(push, 1)
++typedef struct
++{
++    DXVA_PicParams_HEVC main;
++
++    // HEVC Range Extension
++    __C89_NAMELESS union {
++        __C89_NAMELESS struct {
++            UINT32 transform_skip_rotation_enabled_flag : 1;
++            UINT32 transform_skip_context_enabled_flag : 1;
++            UINT32 implicit_rdpcm_enabled_flag : 1;
++            UINT32 explicit_rdpcm_enabled_flag : 1;
++            UINT32 extended_precision_processing_flag : 1;
++            UINT32 intra_smoothing_disabled_flag : 1;
++            UINT32 high_precision_offsets_enabled_flag : 1;
++            UINT32 persistent_rice_adaptation_enabled_flag : 1;
++            UINT32 cabac_bypass_alignment_enabled_flag : 1;
++            UINT32 cross_component_prediction_enabled_flag : 1;
++            UINT32 chroma_qp_offset_list_enabled_flag : 1;
++            UINT32 BitDepthLuma16 : 1; // TODO merge in ReservedBits5 if not needed
++            UINT32 BitDepthChroma16 : 1; // TODO merge in ReservedBits5 if not needed
++            UINT32 ReservedBits8 : 19;
++        };
++        UINT32 dwRangeExtensionFlags;
++    };
++
++    UCHAR diff_cu_chroma_qp_offset_depth;
++    UCHAR chroma_qp_offset_list_len_minus1;
++    UCHAR log2_sao_offset_scale_luma;
++    UCHAR log2_sao_offset_scale_chroma;
++    UCHAR log2_max_transform_skip_block_size_minus2;
++    CHAR cb_qp_offset_list[6];
++    CHAR cr_qp_offset_list[6];
++
++} DXVA_PicParams_HEVC_Rext;
++#pragma pack(pop)
++
+ #define MAX_SLICES 256
+ 
+ struct hevc_dxva2_picture_context {
+-    DXVA_PicParams_HEVC   pp;
++    DXVA_PicParams_HEVC_Rext pp;
+     DXVA_Qmatrix_HEVC     qm;
+     unsigned              slice_count;
+     DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
+@@ -55,18 +92,48 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
+ }
+ 
+ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h,
+-                                    DXVA_PicParams_HEVC *pp)
++                                    DXVA_PicParams_HEVC_Rext *ppext)
+ {
+     const HEVCFrame *current_picture = h->ref;
+     const HEVCSPS *sps = h->ps.sps;
+     const HEVCPPS *pps = h->ps.pps;
+     int i, j;
++    DXVA_PicParams_HEVC *pp = &ppext->main;
+ 
+-    memset(pp, 0, sizeof(*pp));
++    memset(ppext, 0, sizeof(*ppext));
+ 
+     pp->PicWidthInMinCbsY  = sps->min_cb_width;
+     pp->PicHeightInMinCbsY = sps->min_cb_height;
+ 
++    if (sps->sps_range_extension_flag) {
++        ppext->dwRangeExtensionFlags |= (sps->transform_skip_rotation_enabled_flag     <<  0) |
++                                        (sps->transform_skip_context_enabled_flag      <<  1) |
++                                        (sps->implicit_rdpcm_enabled_flag              <<  2) |
++                                        (sps->explicit_rdpcm_enabled_flag              <<  3) |
++                                        (sps->extended_precision_processing_flag       <<  4) |
++                                        (sps->intra_smoothing_disabled_flag            <<  5) |
++                                        (sps->high_precision_offsets_enabled_flag      <<  5) |
++                                        (sps->persistent_rice_adaptation_enabled_flag  <<  7) |
++                                        (sps->cabac_bypass_alignment_enabled_flag      <<  8);
++    }
++    if (pps->pps_range_extensions_flag) {
++        ppext->dwRangeExtensionFlags |= (pps->cross_component_prediction_enabled_flag  <<  9) |
++                                        (pps->chroma_qp_offset_list_enabled_flag       << 10);
++        if (pps->chroma_qp_offset_list_enabled_flag) {
++            ppext->diff_cu_chroma_qp_offset_depth   = pps->diff_cu_chroma_qp_offset_depth;
++            ppext->chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1;
++            for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
++                ppext->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
++                ppext->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
++            }
++        }
++        ppext->log2_sao_offset_scale_luma   = pps->log2_sao_offset_scale_luma;
++        ppext->log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma;
++        if (pps->transform_skip_enabled_flag) {
++            ppext->log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size - 2;
++        }
++    }
++
+     pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc             <<  0) |
+                                       (sps->separate_colour_plane_flag    <<  2) |
+                                       ((sps->bit_depth - 8)               <<  3) |
+@@ -402,16 +469,18 @@ static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
+ 
+ static int dxva2_hevc_end_frame(AVCodecContext *avctx)
+ {
++    AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
+     HEVCContext *h = avctx->priv_data;
+     struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
+-    int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
++    int scale = ctx_pic->pp.main.dwCodingParamToolFlags & 1;
++    int rext = (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_HEVC_REXT);
+     int ret;
+ 
+     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+         return -1;
+ 
+     ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
+-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
++                                    &ctx_pic->pp, rext ? sizeof(ctx_pic->pp) : sizeof(ctx_pic->pp.main),
+                                     scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
+                                     commit_bitstream_and_slice_buffer);
+     return ret;
+-- 
+2.19.1.windows.1
+
diff --git a/contrib/src/ffmpeg/0002-avcodec-hevcdec-allow-HEVC-444-8-10-12-bits-decoding.patch b/contrib/src/ffmpeg/0002-avcodec-hevcdec-allow-HEVC-444-8-10-12-bits-decoding.patch
new file mode 100644
index 0000000000..1161ecd593
--- /dev/null
+++ b/contrib/src/ffmpeg/0002-avcodec-hevcdec-allow-HEVC-444-8-10-12-bits-decoding.patch
@@ -0,0 +1,46 @@
+From 664c8dd63b8fc90019e279bc34d3415deb542bcf Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Tue, 20 Aug 2019 13:10:24 +0200
+Subject: [PATCH 2/3] avcodec/hevcdec: allow HEVC 444 8/10/12 bits decoding
+ with DXVA2/D3D11VA
+
+And 4:2:0 12 bits as well.
+---
+ libavcodec/hevcdec.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
+index 8f1c162ace..04496a002b 100644
+--- a/libavcodec/hevcdec.c
++++ b/libavcodec/hevcdec.c
+@@ -420,6 +420,13 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
+ #endif
+         break;
+     case AV_PIX_FMT_YUV444P:
++#if CONFIG_HEVC_DXVA2_HWACCEL
++        *fmt++ = AV_PIX_FMT_DXVA2_VLD;
++#endif
++#if CONFIG_HEVC_D3D11VA_HWACCEL
++        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
++        *fmt++ = AV_PIX_FMT_D3D11;
++#endif
+ #if CONFIG_HEVC_VDPAU_HWACCEL
+         *fmt++ = AV_PIX_FMT_VDPAU;
+ #endif
+@@ -430,6 +437,13 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
+     case AV_PIX_FMT_YUV420P12:
+     case AV_PIX_FMT_YUV444P10:
+     case AV_PIX_FMT_YUV444P12:
++#if CONFIG_HEVC_DXVA2_HWACCEL
++        *fmt++ = AV_PIX_FMT_DXVA2_VLD;
++#endif
++#if CONFIG_HEVC_D3D11VA_HWACCEL
++        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
++        *fmt++ = AV_PIX_FMT_D3D11;
++#endif
+ #if CONFIG_HEVC_NVDEC_HWACCEL
+         *fmt++ = AV_PIX_FMT_CUDA;
+ #endif
+-- 
+2.19.1.windows.1
+
diff --git a/contrib/src/ffmpeg/0003-avcodec-hevcdec-allow-HEVC-422-10-12-bits-decoding-w.patch b/contrib/src/ffmpeg/0003-avcodec-hevcdec-allow-HEVC-422-10-12-bits-decoding-w.patch
new file mode 100644
index 0000000000..2b81b71852
--- /dev/null
+++ b/contrib/src/ffmpeg/0003-avcodec-hevcdec-allow-HEVC-422-10-12-bits-decoding-w.patch
@@ -0,0 +1,34 @@
+From b95fd27cf95683b00d1612b62c0c5a5104a7ba01 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 4 Oct 2019 12:42:11 +0200
+Subject: [PATCH 3/3] avcodec/hevcdec: allow HEVC 422 10/12 bits decoding with
+ DXVA2/D3D11VA
+
+---
+ libavcodec/hevcdec.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
+index 04496a002b..4c1650c416 100644
+--- a/libavcodec/hevcdec.c
++++ b/libavcodec/hevcdec.c
+@@ -432,6 +432,16 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
+ #endif
+ #if CONFIG_HEVC_NVDEC_HWACCEL
+         *fmt++ = AV_PIX_FMT_CUDA;
++#endif
++        break;
++    case AV_PIX_FMT_YUV422P10:
++    case AV_PIX_FMT_YUV422P12:
++#if CONFIG_HEVC_DXVA2_HWACCEL
++        *fmt++ = AV_PIX_FMT_DXVA2_VLD;
++#endif
++#if CONFIG_HEVC_D3D11VA_HWACCEL
++        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
++        *fmt++ = AV_PIX_FMT_D3D11;
+ #endif
+         break;
+     case AV_PIX_FMT_YUV420P12:
+-- 
+2.19.1.windows.1
+
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index a1e77da515..d78b93ecb6 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -239,6 +239,9 @@ ifdef USE_FFMPEG
 	$(APPLY) $(SRC)/ffmpeg/armv7_fixup.patch
 	$(APPLY) $(SRC)/ffmpeg/dxva_vc1_crash.patch
 	$(APPLY) $(SRC)/ffmpeg/h264_early_SAR.patch
+	$(APPLY) $(SRC)/ffmpeg/0001-avcodec-dxva2_hevc-add-support-for-parsing-HEVC-Rang.patch
+	$(APPLY) $(SRC)/ffmpeg/0002-avcodec-hevcdec-allow-HEVC-444-8-10-12-bits-decoding.patch
+	$(APPLY) $(SRC)/ffmpeg/0003-avcodec-hevcdec-allow-HEVC-422-10-12-bits-decoding-w.patch
 endif
 ifdef USE_LIBAV
 	$(APPLY) $(SRC)/ffmpeg/libav_gsm.patch



More information about the vlc-commits mailing list