[vlc-devel] [PATCH 6/6] contrib: ffmpeg/libav: fix the D3D11 slice index used by the decoder
Steve Lhomme
robux4 at videolabs.io
Wed Oct 5 10:02:00 CEST 2016
This allows arbitrary slice index in the output buffer we provide the decoder.
--
replaces https://patches.videolan.org/patch/14626/
* clean libavcodec patch
---
.../0001-d3d11va-use-the-proper-slice-index.patch | 89 ++++++++++++++++++++++
...d3d11va-use-the-proper-slice-index.patch.ffmpeg | 89 ++++++++++++++++++++++
contrib/src/ffmpeg/rules.mak | 2 +
modules/codec/avcodec/d3d11va.c | 2 +
4 files changed, 182 insertions(+)
create mode 100644 contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch
create mode 100644 contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch.ffmpeg
diff --git a/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch b/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch
new file mode 100644
index 0000000..9f682a7
--- /dev/null
+++ b/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch
@@ -0,0 +1,89 @@
+From f71e0b2d9dc1c6a8b357fa43b811875e57ea1881 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Tue, 4 Oct 2016 16:41:22 +0200
+Subject: [PATCH] d3d11va: use the proper slice index
+
+The slice index expected by D3D11VA is the one from the texture not from the
+array or texture/slices.
+
+In VLC the slices we provide the decoder don't start from 0 and thus pictures
+appear in bogus order. With possible crashes and corruptions when using an
+invalid index.
+
+--
+* forgot to bump the micro version
+* get rid of DXVA_CONTEXT_SURFACE
+---
+ libavcodec/dxva2.c | 12 +++++++++++-
+ libavcodec/dxva2_internal.h | 3 ---
+ libavcodec/version.h | 2 +-
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
+index 9157094..2fc5f47 100644
+--- a/libavcodec/dxva2.c
++++ b/libavcodec/dxva2.c
+@@ -42,8 +42,18 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
+ unsigned i;
+
+ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
+- if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)
++#if CONFIG_D3D11VA
++ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface)
++ {
++ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
++ ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc);
++ return viewDesc.Texture2D.ArraySlice;
++ }
++#endif
++#if CONFIG_DXVA2
++ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
+ return i;
++#endif
+
+ assert(0);
+ return 0;
+diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
+index 30aec8b..f0fe3d6 100644
+--- a/libavcodec/dxva2_internal.h
++++ b/libavcodec/dxva2_internal.h
+@@ -69,7 +69,6 @@ typedef union {
+ #if CONFIG_D3D11VA && CONFIG_DXVA2
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface_count : ctx->dxva2.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface[i] : ctx->dxva2.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.decoder : ctx->dxva2.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? &ctx->d3d11va.report_id : &ctx->dxva2.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg : ctx->dxva2.cfg)
+@@ -79,7 +78,6 @@ typedef union {
+ #elif CONFIG_DXVA2
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->dxva2.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->dxva2.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->dxva2.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->dxva2.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->dxva2.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->dxva2.cfg)
+@@ -89,7 +87,6 @@ typedef union {
+ #elif CONFIG_D3D11VA
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->d3d11va.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->d3d11va.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->d3d11va.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->d3d11va.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->d3d11va.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->d3d11va.cfg)
+diff --git a/libavcodec/version.h b/libavcodec/version.h
+index 71ec9ce..6f439c0 100644
+--- a/libavcodec/version.h
++++ b/libavcodec/version.h
+@@ -28,7 +28,7 @@
+ #include "libavutil/version.h"
+
+ #define LIBAVCODEC_VERSION_MAJOR 57
+-#define LIBAVCODEC_VERSION_MINOR 27
++#define LIBAVCODEC_VERSION_MINOR 28
+ #define LIBAVCODEC_VERSION_MICRO 1
+
+ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
+--
+2.7.2.windows.1
+
diff --git a/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch.ffmpeg b/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch.ffmpeg
new file mode 100644
index 0000000..dc52750
--- /dev/null
+++ b/contrib/src/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch.ffmpeg
@@ -0,0 +1,89 @@
+From c5d58c2efb4c8d017b51de5d12d17866563416bb Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Tue, 4 Oct 2016 16:40:54 +0200
+Subject: [PATCH] d3d11va: use the proper slice index
+
+The slice index expected by D3D11VA is the one from the texture not from the
+array or texture/slices.
+
+In VLC the slices we provide the decoder don't start from 0 and thus pictures
+appear in bogus order. With possible crashes and corruptions when using an
+invalid index.
+
+--
+* forgot to bump the micro version
+* get rid of DXVA_CONTEXT_SURFACE
+---
+ libavcodec/dxva2.c | 12 +++++++++++-
+ libavcodec/dxva2_internal.h | 3 ---
+ libavcodec/version.h | 2 +-
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
+index f68df86..e168233 100644
+--- a/libavcodec/dxva2.c
++++ b/libavcodec/dxva2.c
+@@ -42,8 +42,18 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
+ unsigned i;
+
+ for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
+- if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)
++#if CONFIG_D3D11VA
++ if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface)
++ {
++ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
++ ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc);
++ return viewDesc.Texture2D.ArraySlice;
++ }
++#endif
++#if CONFIG_DXVA2
++ if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
+ return i;
++#endif
+
+ assert(0);
+ return 0;
+diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
+index ad89f82..24adb99 100644
+--- a/libavcodec/dxva2_internal.h
++++ b/libavcodec/dxva2_internal.h
+@@ -70,7 +70,6 @@ typedef union {
+ #if CONFIG_D3D11VA && CONFIG_DXVA2
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface_count : ctx->dxva2.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface[i] : ctx->dxva2.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.decoder : ctx->dxva2.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? &ctx->d3d11va.report_id : &ctx->dxva2.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg : ctx->dxva2.cfg)
+@@ -80,7 +79,6 @@ typedef union {
+ #elif CONFIG_DXVA2
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->dxva2.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->dxva2.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->dxva2.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->dxva2.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->dxva2.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->dxva2.cfg)
+@@ -90,7 +88,6 @@ typedef union {
+ #elif CONFIG_D3D11VA
+ #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->d3d11va.workaround)
+ #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->d3d11va.surface_count)
+-#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->d3d11va.surface[i])
+ #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->d3d11va.decoder)
+ #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->d3d11va.report_id))
+ #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->d3d11va.cfg)
+diff --git a/libavcodec/version.h b/libavcodec/version.h
+index de7280f..7e30a16 100644
+--- a/libavcodec/version.h
++++ b/libavcodec/version.h
+@@ -28,7 +28,7 @@
+ #include "libavutil/version.h"
+
+ #define LIBAVCODEC_VERSION_MAJOR 57
+-#define LIBAVCODEC_VERSION_MINOR 60
++#define LIBAVCODEC_VERSION_MINOR 61
+ #define LIBAVCODEC_VERSION_MICRO 101
+
+ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
+--
+2.7.2.windows.1
+
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index e4178c6..e82b652 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -8,6 +8,7 @@ ifdef USE_FFMPEG
FFMPEG_HASH=HEAD
FFMPEG_SNAPURL := http://git.videolan.org/?p=ffmpeg.git;a=snapshot;h=$(FFMPEG_HASH);sf=tgz
FFMPEG_GITURL := git://git.videolan.org/ffmpeg.git
+PATCH_SUFFIX =.ffmpeg
else
FFMPEG_HASH=HEAD
FFMPEG_SNAPURL := http://git.libav.org/?p=libav.git;a=snapshot;h=$(FFMPEG_HASH);sf=tgz
@@ -216,6 +217,7 @@ ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.xz .sum-ffmpeg
rm -Rf $@ $@-$(FFMPEG_HASH)
mkdir -p $@-$(FFMPEG_HASH)
$(XZCAT) "$<" | (cd $@-$(FFMPEG_HASH) && tar xv --strip-components=1)
+ $(APPLY) $(SRC)/ffmpeg/0001-d3d11va-use-the-proper-slice-index.patch$(PATCH_SUFFIX)
$(MOVE)
.ffmpeg: ffmpeg
diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 98e9e03..dffe253 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -1007,6 +1007,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
assert(texDesc.Format == sys->render);
assert(texDesc.BindFlags & D3D11_BIND_DECODER);
+#if !LIBAVCODEC_VERSION_CHECK( 57, 28 ,0, 61 ,100 )
if (pic->p_sys->slice_index != surface_idx)
{
msg_Warn(va, "d3d11va requires decoding slices to be the first in the texture (%d/%d)",
@@ -1014,6 +1015,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
sys->b_extern_pool = false;
break;
}
+#endif
viewDesc.Texture2D.ArraySlice = pic->p_sys->slice_index;
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
--
2.7.2.windows.1
More information about the vlc-devel
mailing list