From bfc89c9e740afc4630aa14f501944e10759c0dc3 Mon Sep 17 00:00:00 2001 From: gnattu Date: Sun, 21 Jun 2026 20:32:08 +0800 Subject: [PATCH] extract d3d11 common helpers --- .../0093-add-d3d11-deinterlace-filter.patch | 336 ++++++++---------- ...-processor-overlay-transpose-filters.patch | 279 +++------------ .../0096-add-d3d11-tonemap-filter.patch | 255 +++---------- ...add-scale-d3d11-p010-shader-fallback.patch | 290 +++------------ 4 files changed, 294 insertions(+), 866 deletions(-) diff --git a/debian/patches/0093-add-d3d11-deinterlace-filter.patch b/debian/patches/0093-add-d3d11-deinterlace-filter.patch index 75663ae24..1bc7038ae 100644 --- a/debian/patches/0093-add-d3d11-deinterlace-filter.patch +++ b/debian/patches/0093-add-d3d11-deinterlace-filter.patch @@ -27,7 +27,7 @@ Index: FFmpeg/libavfilter/Makefile OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER) += vf_avgblur_opencl.o opencl.o \ opencl/avgblur.o boxblur.o OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o bwdifdsp.o yadif_common.o -+OBJS-$(CONFIG_BWDIF_D3D11_FILTER) += vf_yadif_d3d11.o yadif_common.o d3d11/deint.o ++OBJS-$(CONFIG_BWDIF_D3D11_FILTER) += vf_yadif_d3d11.o yadif_common.o d3d11/deint.o d3d11_filter.o OBJS-$(CONFIG_BWDIF_CUDA_FILTER) += vf_bwdif_cuda.o vf_bwdif_cuda.ptx.o \ yadif_common.o OBJS-$(CONFIG_BWDIF_OPENCL_FILTER) += vf_bwdif_opencl.o opencl.o opencl/bwdif.o \ @@ -35,7 +35,7 @@ Index: FFmpeg/libavfilter/Makefile OBJS-$(CONFIG_XPSNR_FILTER) += vf_xpsnr.o framesync.o psnr.o OBJS-$(CONFIG_XSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o yadif_common.o -+OBJS-$(CONFIG_YADIF_D3D11_FILTER) += vf_yadif_d3d11.o yadif_common.o d3d11/deint.o ++OBJS-$(CONFIG_YADIF_D3D11_FILTER) += vf_yadif_d3d11.o yadif_common.o d3d11/deint.o d3d11_filter.o OBJS-$(CONFIG_YADIF_CUDA_FILTER) += vf_yadif_cuda.o vf_yadif_cuda.ptx.o \ yadif_common.o cuda/load_helper.o OBJS-$(CONFIG_YADIF_OPENCL_FILTER) += vf_yadif_opencl.o opencl.o opencl/yadif.o \ @@ -81,7 +81,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c =================================================================== --- /dev/null +++ FFmpeg/libavfilter/vf_yadif_d3d11.c -@@ -0,0 +1,804 @@ +@@ -0,0 +1,660 @@ +/* + * D3D11 YADIF/BWDIF deinterlacing filters + * @@ -109,7 +109,6 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c +#define COBJMACROS +#endif +#include -+#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" @@ -124,21 +123,11 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c +#include "yadif.h" +#include "vf_yadif_d3d11.h" +#include "d3d11_source.h" -+ -+#define D3D11_RELEASE(p) do { if (p) { (p)->lpVtbl->Release(p); (p) = NULL; } } while (0) -+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 -+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) -+#endif -+ ++#include "d3d11_filter.h" + +#define DEINT_D3D11_ALG_YADIF 0 +#define DEINT_D3D11_ALG_BWDIF 1 + -+typedef HRESULT (WINAPI *D3DCompileProc)(LPCVOID, SIZE_T, LPCSTR, -+ const D3D_SHADER_MACRO *, ID3DInclude *, -+ LPCSTR, LPCSTR, UINT, UINT, -+ ID3D10Blob **, ID3D10Blob **); -+ +typedef struct DeintD3D11Params { + int width; + int height; @@ -163,7 +152,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + ID3D11Device *device; + ID3D11DeviceContext *context; + HMODULE d3dcompiler; -+ D3DCompileProc D3DCompile; ++ FFD3DCompileProc D3DCompile; + + ID3D11ComputeShader *cs_y; + ID3D11ComputeShader *cs_uv; @@ -181,95 +170,43 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + +static void release_d3d11_resources(DeintD3D11Context *s) +{ -+ D3D11_RELEASE(s->cs_y); -+ D3D11_RELEASE(s->cs_uv); -+ D3D11_RELEASE(s->params_buf); -+ D3D11_RELEASE(s->prev_tex); -+ D3D11_RELEASE(s->cur_tex); -+ D3D11_RELEASE(s->next_tex); -+ D3D11_RELEASE(s->work_tex); ++ FF_D3D11_RELEASE(s->cs_y); ++ FF_D3D11_RELEASE(s->cs_uv); ++ FF_D3D11_RELEASE(s->params_buf); ++ FF_D3D11_RELEASE(s->prev_tex); ++ FF_D3D11_RELEASE(s->cur_tex); ++ FF_D3D11_RELEASE(s->next_tex); ++ FF_D3D11_RELEASE(s->work_tex); + s->tex_w = s->tex_h = 0; +} + +static int compile_shader(AVFilterContext *ctx, const char *entry, ID3D11ComputeShader **shader) +{ + DeintD3D11Context *s = ctx->priv; -+ ID3D10Blob *cs_blob = NULL; -+ ID3D10Blob *err_blob = NULL; -+ HRESULT hr; + -+ hr = s->D3DCompile(ff_source_deint_hlsl, strlen(ff_source_deint_hlsl), -+ NULL, NULL, NULL, entry, "cs_5_0", -+ D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &cs_blob, &err_blob); -+ if (FAILED(hr)) { -+ if (err_blob) { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 deinterlace shader %s: %.*s\n", -+ entry, (int)err_blob->lpVtbl->GetBufferSize(err_blob), -+ (char *)err_blob->lpVtbl->GetBufferPointer(err_blob)); -+ } else { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 deinterlace shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ } -+ D3D11_RELEASE(err_blob); -+ return AVERROR_EXTERNAL; -+ } -+ -+ hr = s->device->lpVtbl->CreateComputeShader(s->device, -+ cs_blob->lpVtbl->GetBufferPointer(cs_blob), -+ cs_blob->lpVtbl->GetBufferSize(cs_blob), -+ NULL, shader); -+ D3D11_RELEASE(cs_blob); -+ D3D11_RELEASE(err_blob); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 deinterlace shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_compile_shader(ctx, s->device, s->D3DCompile, ++ ff_source_deint_hlsl, NULL, entry, ++ "cs_5_0", "D3D11 deinterlace", shader); +} + +static int init_shaders(AVFilterContext *ctx) +{ + DeintD3D11Context *s = ctx->priv; -+ D3D11_BUFFER_DESC bd = { 0 }; -+ HRESULT hr; + int ret; + + if (s->cs_y) + return 0; + -+ if (!s->d3dcompiler) { -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); -+ if (!s->d3dcompiler) -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); -+ } -+ if (!s->d3dcompiler) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading d3dcompiler DLL\n"); -+ return AVERROR_EXTERNAL; -+ } -+ -+ s->D3DCompile = (D3DCompileProc)GetProcAddress(s->d3dcompiler, "D3DCompile"); -+ if (!s->D3DCompile) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading D3DCompile\n"); -+ return AVERROR_EXTERNAL; -+ } ++ ret = ff_d3d11_load_shader_compiler(ctx, &s->d3dcompiler, &s->D3DCompile); ++ if (ret < 0) ++ return ret; + + if ((ret = compile_shader(ctx, "deint_y", &s->cs_y)) < 0 || + (ret = compile_shader(ctx, "deint_uv", &s->cs_uv)) < 0) + return ret; + -+ bd.ByteWidth = sizeof(DeintD3D11Params); -+ bd.Usage = D3D11_USAGE_DYNAMIC; -+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; -+ bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; -+ hr = s->device->lpVtbl->CreateBuffer(s->device, &bd, NULL, &s->params_buf); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 deinterlace constant buffer: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ -+ return 0; ++ return ff_d3d11_create_const_buffer(ctx, s->device, sizeof(DeintD3D11Params), ++ "D3D11 deinterlace", &s->params_buf); +} + +static int ensure_textures(AVFilterContext *ctx, int w, int h) @@ -281,10 +218,10 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + if (s->prev_tex && s->cur_tex && s->next_tex && s->work_tex && s->tex_w == w && s->tex_h == h) + return 0; + -+ D3D11_RELEASE(s->prev_tex); -+ D3D11_RELEASE(s->cur_tex); -+ D3D11_RELEASE(s->next_tex); -+ D3D11_RELEASE(s->work_tex); ++ FF_D3D11_RELEASE(s->prev_tex); ++ FF_D3D11_RELEASE(s->cur_tex); ++ FF_D3D11_RELEASE(s->next_tex); ++ FF_D3D11_RELEASE(s->work_tex); + + desc.Width = w; + desc.Height = h; @@ -316,65 +253,15 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + return AVERROR_EXTERNAL; +} + -+static void fill_tex2d_srv_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_SHADER_RESOURCE_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0; -+ UINT array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MostDetailedMip = mip_slice; -+ desc->Texture2DArray.MipLevels = 1; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; -+} -+ -+static void fill_tex2d_uav_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0; -+ UINT array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MipSlice = mip_slice; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; -+} -+ +static int create_nv12_srv_view(AVFilterContext *ctx, ID3D11Texture2D *tex, + UINT subresource, int plane, int log_level, + ID3D11ShaderResourceView **srv) +{ + DeintD3D11Context *s = ctx->priv; -+ D3D11_SHADER_RESOURCE_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ fill_tex2d_srv_desc(tex, subresource, plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM, &desc); -+ -+ hr = s->device->lpVtbl->CreateShaderResourceView(s->device, (ID3D11Resource *)tex, -+ &desc, srv); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 deinterlace SRV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_srv(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(AV_PIX_FMT_NV12, plane), ++ log_level, "D3D11 deinterlace", srv); +} + +static int create_nv12_srv(AVFilterContext *ctx, ID3D11Texture2D *tex, int plane, @@ -388,19 +275,10 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + ID3D11UnorderedAccessView **uav) +{ + DeintD3D11Context *s = ctx->priv; -+ D3D11_UNORDERED_ACCESS_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ fill_tex2d_uav_desc(tex, subresource, plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM, &desc); -+ -+ hr = s->device->lpVtbl->CreateUnorderedAccessView(s->device, (ID3D11Resource *)tex, -+ &desc, uav); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 deinterlace UAV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_uav(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(AV_PIX_FMT_NV12, plane), ++ log_level, "D3D11 deinterlace", uav); +} + +static int create_nv12_uav(AVFilterContext *ctx, ID3D11Texture2D *tex, int plane, @@ -409,27 +287,6 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + return create_nv12_uav_view(ctx, tex, 0, plane, AV_LOG_ERROR, uav); +} + -+static void copy_frame_to_texture(DeintD3D11Context *s, AVFrame *src, ID3D11Texture2D *dst) -+{ -+ ID3D11Texture2D *src_tex = (ID3D11Texture2D *)src->data[0]; -+ UINT src_sub = (UINT)(uintptr_t)src->data[1]; -+ D3D11_BOX box = { 0, 0, 0, src->width, src->height, 1 }; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst, 0, -+ 0, 0, 0, (ID3D11Resource *)src_tex, -+ src_sub, &box); -+} -+ -+static void copy_texture_to_frame(DeintD3D11Context *s, ID3D11Texture2D *src, AVFrame *dst) -+{ -+ ID3D11Texture2D *dst_tex = (ID3D11Texture2D *)dst->data[0]; -+ UINT dst_sub = (UINT)(uintptr_t)dst->data[1]; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst_tex, -+ dst_sub, 0, 0, 0, (ID3D11Resource *)src, -+ 0, NULL); -+} -+ +static int create_frame_srvs(AVFilterContext *ctx, AVFrame *frame, + ID3D11ShaderResourceView **srv_y, + ID3D11ShaderResourceView **srv_uv) @@ -443,7 +300,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + return ret; + ret = create_nv12_srv_view(ctx, tex, subresource, 1, AV_LOG_DEBUG, srv_uv); + if (ret < 0) -+ D3D11_RELEASE(*srv_y); ++ FF_D3D11_RELEASE(*srv_y); + return ret; +} + @@ -467,15 +324,15 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + return 0; + } + for (int i = 0; i < 6; i++) -+ D3D11_RELEASE(srvs[i]); ++ FF_D3D11_RELEASE(srvs[i]); + if (s->direct_input_srv < 0) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader input: copied to internal SRV texture\n"); + s->direct_input_srv = 0; + } + -+ copy_frame_to_texture(s, y->prev, s->prev_tex); -+ copy_frame_to_texture(s, y->cur, s->cur_tex); -+ copy_frame_to_texture(s, y->next, s->next_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, y->prev, s->prev_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, y->cur, s->cur_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, y->next, s->next_tex); + +#define MAKE_SRV(tex, plane, idx) do { ret = create_nv12_srv(ctx, tex, plane, &srvs[idx]); if (ret < 0) goto fail; } while (0) + MAKE_SRV(s->prev_tex, 0, 0); @@ -491,7 +348,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c +fail: +#undef MAKE_SRV + for (int i = 0; i < 6; i++) -+ D3D11_RELEASE(srvs[i]); ++ FF_D3D11_RELEASE(srvs[i]); + return ret; +} + @@ -512,8 +369,8 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + *direct = 1; + return 0; + } -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + if (s->direct_output_uav < 0) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: copied from internal UAV texture\n"); + s->direct_output_uav = 0; @@ -524,7 +381,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + return ret; + ret = create_nv12_uav(ctx, s->work_tex, 1, &uavs[1]); + if (ret < 0) -+ D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[0]); + return ret; +} + @@ -559,8 +416,8 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + ret = create_nv12_uav_view(ctx, tex, subresource, 1, AV_LOG_DEBUG, &uavs[1]); + +done: -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&frame); + return ret; +} @@ -632,7 +489,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); + + if (!direct_output) -+ copy_texture_to_frame(s, s->work_tex, dst); ++ ff_d3d11_copy_texture_to_frame(s->context, s->work_tex, dst); + +fail: + s->context->lpVtbl->CSSetShader(s->context, NULL, NULL, 0); @@ -640,9 +497,9 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + s->context->lpVtbl->CSSetUnorderedAccessViews(s->context, 0, 2, null_uavs, NULL); + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); + for (int i = 0; i < 6; i++) -+ D3D11_RELEASE(srvs[i]); -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[i]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + return ret; +} + @@ -667,8 +524,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c + av_buffer_unref(&s->input_frames_ref); + s->hwctx = NULL; + s->input_frames = NULL; -+ if (s->d3dcompiler) -+ FreeLibrary(s->d3dcompiler); ++ ff_d3d11_unload_shader_compiler(&s->d3dcompiler, &s->D3DCompile); +} + +static int config_input(AVFilterLink *inlink) @@ -1332,3 +1188,103 @@ Index: FFmpeg/libavfilter/d3d11_source.h +extern const char *ff_source_deint_hlsl; + +#endif /* AVFILTER_D3D11_SOURCE_H */ +Index: FFmpeg/libavfilter/d3d11_filter.c +=================================================================== +--- FFmpeg.orig/libavfilter/d3d11_filter.c ++++ FFmpeg/libavfilter/d3d11_filter.c +@@ -11,6 +11,9 @@ + + #include "config.h" + ++#include ++#include ++ + #include "libavutil/error.h" + #include "libavutil/log.h" + #include "libavutil/mem.h" +Index: FFmpeg/libavfilter/d3d11_filter.h +=================================================================== +--- /dev/null ++++ FFmpeg/libavfilter/d3d11_filter.h +@@ -0,0 +1,81 @@ ++/* ++ * Common D3D11 filter helpers ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ */ ++ ++#ifndef AVFILTER_D3D11_FILTER_H ++#define AVFILTER_D3D11_FILTER_H ++ ++#include ++#ifndef COBJMACROS ++#define COBJMACROS ++#endif ++#include ++#include ++ ++#include "libavutil/frame.h" ++#include "libavutil/pixfmt.h" ++#include "avfilter.h" ++ ++#define FF_D3D11_RELEASE(p) do { if (p) { (p)->lpVtbl->Release(p); (p) = NULL; } } while (0) ++ ++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 ++#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) ++#endif ++ ++typedef HRESULT (WINAPI *FFD3DCompileProc)(LPCVOID, SIZE_T, LPCSTR, ++ const D3D_SHADER_MACRO *, ID3DInclude *, ++ LPCSTR, LPCSTR, UINT, UINT, ++ ID3D10Blob **, ID3D10Blob **); ++ ++int ff_d3d11_load_shader_compiler(AVFilterContext *ctx, HMODULE *d3dcompiler, ++ FFD3DCompileProc *compile); ++void ff_d3d11_unload_shader_compiler(HMODULE *d3dcompiler, FFD3DCompileProc *compile); ++ ++int ff_d3d11_compile_shader(AVFilterContext *ctx, ID3D11Device *device, ++ FFD3DCompileProc compile, const char *source, ++ const D3D_SHADER_MACRO *macros, const char *entry, ++ const char *target, const char *name, ++ ID3D11ComputeShader **shader); ++ ++int ff_d3d11_create_const_buffer(AVFilterContext *ctx, ID3D11Device *device, ++ size_t size, const char *name, ++ ID3D11Buffer **buffer); ++ ++DXGI_FORMAT ff_d3d11_texture_format(enum AVPixelFormat fmt); ++DXGI_FORMAT ff_d3d11_plane_format(enum AVPixelFormat fmt, int plane); ++ ++int ff_d3d11_ensure_texture(AVFilterContext *ctx, ID3D11Device *device, ++ ID3D11Texture2D **tex, int *cur_w, int *cur_h, ++ DXGI_FORMAT *cur_fmt, int w, int h, ++ DXGI_FORMAT fmt, UINT bind_flags, ++ const char *name); ++ ++void ff_d3d11_fill_srv_desc(ID3D11Texture2D *tex, UINT subresource, ++ DXGI_FORMAT fmt, D3D11_SHADER_RESOURCE_VIEW_DESC *desc); ++void ff_d3d11_fill_uav_desc(ID3D11Texture2D *tex, UINT subresource, ++ DXGI_FORMAT fmt, D3D11_UNORDERED_ACCESS_VIEW_DESC *desc); ++ ++int ff_d3d11_create_srv(AVFilterContext *ctx, ID3D11Device *device, ++ ID3D11Texture2D *tex, UINT subresource, ++ DXGI_FORMAT fmt, int log_level, const char *name, ++ ID3D11ShaderResourceView **srv); ++int ff_d3d11_create_uav(AVFilterContext *ctx, ID3D11Device *device, ++ ID3D11Texture2D *tex, UINT subresource, ++ DXGI_FORMAT fmt, int log_level, const char *name, ++ ID3D11UnorderedAccessView **uav); ++ ++void ff_d3d11_copy_frame_to_texture(ID3D11DeviceContext *context, AVFrame *src, ++ ID3D11Texture2D *dst); ++void ff_d3d11_copy_texture_to_frame(ID3D11DeviceContext *context, ID3D11Texture2D *src, ++ AVFrame *dst); ++void ff_d3d11_copy_frame_to_frame(ID3D11DeviceContext *context, AVFrame *src, ++ AVFrame *dst); ++ ++#endif /* AVFILTER_D3D11_FILTER_H */ diff --git a/debian/patches/0094-add-d3d11-video-processor-overlay-transpose-filters.patch b/debian/patches/0094-add-d3d11-video-processor-overlay-transpose-filters.patch index 8d8324682..b07a96907 100644 --- a/debian/patches/0094-add-d3d11-video-processor-overlay-transpose-filters.patch +++ b/debian/patches/0094-add-d3d11-video-processor-overlay-transpose-filters.patch @@ -28,7 +28,7 @@ Index: FFmpeg/libavfilter/Makefile OBJS-$(CONFIG_OCIO_FILTER) += vf_opencolorio.o ocio_wrapper.o OBJS-$(CONFIG_OSCILLOSCOPE_FILTER) += vf_datascope.o OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync.o -+OBJS-$(CONFIG_OVERLAY_D3D11_FILTER) += vf_overlay_d3d11.o framesync.o d3d11/overlay.o ++OBJS-$(CONFIG_OVERLAY_D3D11_FILTER) += vf_overlay_d3d11.o framesync.o d3d11/overlay.o d3d11_filter.o OBJS-$(CONFIG_OVERLAY_CUDA_FILTER) += vf_overlay_cuda.o framesync.o vf_overlay_cuda.ptx.o \ cuda/load_helper.o OBJS-$(CONFIG_OVERLAY_OPENCL_FILTER) += vf_overlay_opencl.o opencl.o \ @@ -64,7 +64,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c =================================================================== --- /dev/null +++ FFmpeg/libavfilter/vf_overlay_d3d11.c -@@ -0,0 +1,976 @@ +@@ -0,0 +1,793 @@ +/* + * D3D11 overlay filter + * @@ -92,7 +92,6 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c +#define COBJMACROS +#endif +#include -+#include + +#include "libavutil/common.h" +#include "libavutil/eval.h" @@ -104,6 +103,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + +#include "vf_overlay_d3d11.h" +#include "d3d11_source.h" ++#include "d3d11_filter.h" +#include "filters.h" +#include "framesync.h" +#include "video.h" @@ -111,11 +111,6 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c +#define MAIN 0 +#define OVERLAY 1 + -+#define D3D11_RELEASE(p) do { if (p) { (p)->lpVtbl->Release(p); (p) = NULL; } } while (0) -+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 -+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) -+#endif -+ +enum var_name { + VAR_MAIN_IW, VAR_MW, + VAR_MAIN_IH, VAR_MH, @@ -128,11 +123,6 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + VAR_VARS_NB +}; + -+typedef HRESULT (WINAPI *D3DCompileProc)(LPCVOID, SIZE_T, LPCSTR, -+ const D3D_SHADER_MACRO *, ID3DInclude *, -+ LPCSTR, LPCSTR, UINT, UINT, -+ ID3D10Blob **, ID3D10Blob **); -+ +typedef struct OverlayD3D11Context { + const AVClass *classCtx; + FFFrameSync fs; @@ -151,7 +141,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + ID3D11Device *device; + ID3D11DeviceContext *context; + HMODULE d3dcompiler; -+ D3DCompileProc D3DCompile; ++ FFD3DCompileProc D3DCompile; + + ID3D11ComputeShader *cs_bgra_y; + ID3D11ComputeShader *cs_bgra_uv; @@ -190,12 +180,12 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + +static void overlay_d3d11_release_resources(OverlayD3D11Context *s) +{ -+ D3D11_RELEASE(s->cs_bgra_y); -+ D3D11_RELEASE(s->cs_bgra_uv); -+ D3D11_RELEASE(s->params_buf); -+ D3D11_RELEASE(s->main_tex); -+ D3D11_RELEASE(s->work_tex); -+ D3D11_RELEASE(s->overlay_tex); ++ FF_D3D11_RELEASE(s->cs_bgra_y); ++ FF_D3D11_RELEASE(s->cs_bgra_uv); ++ FF_D3D11_RELEASE(s->params_buf); ++ FF_D3D11_RELEASE(s->main_tex); ++ FF_D3D11_RELEASE(s->work_tex); ++ FF_D3D11_RELEASE(s->overlay_tex); + s->main_tex_w = s->main_tex_h = 0; + s->work_w = s->work_h = 0; + s->overlay_tex_w = s->overlay_tex_h = 0; @@ -240,82 +230,30 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c +static int compile_shader(AVFilterContext *ctx, const char *entry, ID3D11ComputeShader **shader) +{ + OverlayD3D11Context *s = ctx->priv; -+ ID3D10Blob *cs_blob = NULL; -+ ID3D10Blob *err_blob = NULL; -+ HRESULT hr; + -+ hr = s->D3DCompile(ff_source_overlay_hlsl, strlen(ff_source_overlay_hlsl), -+ NULL, NULL, NULL, entry, "cs_5_0", -+ D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &cs_blob, &err_blob); -+ if (FAILED(hr)) { -+ if (err_blob) { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling overlay shader %s: %.*s\n", -+ entry, (int)err_blob->lpVtbl->GetBufferSize(err_blob), -+ (char *)err_blob->lpVtbl->GetBufferPointer(err_blob)); -+ } else { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling overlay shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ } -+ D3D11_RELEASE(err_blob); -+ return AVERROR_EXTERNAL; -+ } -+ -+ hr = s->device->lpVtbl->CreateComputeShader(s->device, -+ cs_blob->lpVtbl->GetBufferPointer(cs_blob), -+ cs_blob->lpVtbl->GetBufferSize(cs_blob), -+ NULL, shader); -+ D3D11_RELEASE(cs_blob); -+ D3D11_RELEASE(err_blob); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating overlay shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_compile_shader(ctx, s->device, s->D3DCompile, ++ ff_source_overlay_hlsl, NULL, entry, ++ "cs_5_0", "D3D11 overlay", shader); +} + +static int overlay_d3d11_init_shader(AVFilterContext *ctx) +{ + OverlayD3D11Context *s = ctx->priv; -+ D3D11_BUFFER_DESC bd = { 0 }; -+ HRESULT hr; + int ret; + + if (s->cs_bgra_y) + return 0; + -+ if (!s->d3dcompiler) { -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); -+ if (!s->d3dcompiler) -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); -+ } -+ if (!s->d3dcompiler) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading d3dcompiler DLL\n"); -+ return AVERROR_EXTERNAL; -+ } -+ -+ s->D3DCompile = (D3DCompileProc)GetProcAddress(s->d3dcompiler, "D3DCompile"); -+ if (!s->D3DCompile) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading D3DCompile\n"); -+ return AVERROR_EXTERNAL; -+ } ++ ret = ff_d3d11_load_shader_compiler(ctx, &s->d3dcompiler, &s->D3DCompile); ++ if (ret < 0) ++ return ret; + + if ((ret = compile_shader(ctx, "bgra_y", &s->cs_bgra_y)) < 0 || + (ret = compile_shader(ctx, "bgra_uv", &s->cs_bgra_uv)) < 0) + return ret; + -+ bd.ByteWidth = sizeof(OverlayD3D11Params); -+ bd.Usage = D3D11_USAGE_DYNAMIC; -+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; -+ bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; -+ hr = s->device->lpVtbl->CreateBuffer(s->device, &bd, NULL, &s->params_buf); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating overlay constant buffer: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ -+ return 0; ++ return ff_d3d11_create_const_buffer(ctx, s->device, sizeof(OverlayD3D11Params), ++ "D3D11 overlay", &s->params_buf); +} + +static int ensure_texture(AVFilterContext *ctx, ID3D11Texture2D **tex, @@ -323,76 +261,9 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + int w, int h, DXGI_FORMAT fmt, UINT bind_flags) +{ + OverlayD3D11Context *s = ctx->priv; -+ D3D11_TEXTURE2D_DESC desc = { 0 }; -+ HRESULT hr; + -+ if (*tex && *cur_w == w && *cur_h == h && (!cur_fmt || *cur_fmt == fmt)) -+ return 0; -+ -+ D3D11_RELEASE(*tex); -+ -+ desc.Width = w; -+ desc.Height = h; -+ desc.MipLevels = 1; -+ desc.ArraySize = 1; -+ desc.Format = fmt; -+ desc.SampleDesc.Count = 1; -+ desc.Usage = D3D11_USAGE_DEFAULT; -+ desc.BindFlags = bind_flags; -+ -+ hr = s->device->lpVtbl->CreateTexture2D(s->device, &desc, NULL, tex); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating overlay texture %dx%d format %u: HRESULT 0x%lX\n", -+ w, h, fmt, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ -+ *cur_w = w; -+ *cur_h = h; -+ if (cur_fmt) -+ *cur_fmt = fmt; -+ return 0; -+} -+ -+static void fill_tex2d_srv_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_SHADER_RESOURCE_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0; -+ UINT array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MostDetailedMip = mip_slice; -+ desc->Texture2DArray.MipLevels = 1; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; -+} -+ -+static void fill_tex2d_uav_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0; -+ UINT array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MipSlice = mip_slice; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; ++ return ff_d3d11_ensure_texture(ctx, s->device, tex, cur_w, cur_h, cur_fmt, ++ w, h, fmt, bind_flags, "D3D11 overlay"); +} + +static int create_nv12_uav_view(AVFilterContext *ctx, ID3D11Texture2D *tex, @@ -401,20 +272,10 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + ID3D11UnorderedAccessView **uav) +{ + OverlayD3D11Context *s = ctx->priv; -+ D3D11_UNORDERED_ACCESS_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ fill_tex2d_uav_desc(tex, subresource, plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM, &desc); -+ -+ hr = s->device->lpVtbl->CreateUnorderedAccessView(s->device, -+ (ID3D11Resource *)tex, -+ &desc, uav); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating NV12 plane %d UAV: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_uav(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(AV_PIX_FMT_NV12, plane), ++ log_level, "D3D11 overlay", uav); +} + +static int create_nv12_uav(AVFilterContext *ctx, ID3D11Texture2D *tex, int plane, @@ -429,22 +290,12 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + ID3D11ShaderResourceView **srv) +{ + OverlayD3D11Context *s = ctx->priv; -+ D3D11_SHADER_RESOURCE_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + + if (plane >= 0) -+ fmt = plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM; -+ fill_tex2d_srv_desc(tex, subresource, fmt, &desc); ++ fmt = ff_d3d11_plane_format(AV_PIX_FMT_NV12, plane); + -+ hr = s->device->lpVtbl->CreateShaderResourceView(s->device, -+ (ID3D11Resource *)tex, -+ &desc, srv); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating overlay SRV: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_srv(ctx, s->device, tex, subresource, fmt, ++ log_level, "D3D11 overlay", srv); +} + +static int create_srv(AVFilterContext *ctx, ID3D11Texture2D *tex, DXGI_FORMAT fmt, @@ -453,39 +304,6 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + return create_srv_view(ctx, tex, 0, fmt, plane, AV_LOG_ERROR, srv); +} + -+static void copy_frame_to_texture(OverlayD3D11Context *s, AVFrame *src, ID3D11Texture2D *dst) -+{ -+ ID3D11Texture2D *src_tex = (ID3D11Texture2D *)src->data[0]; -+ UINT src_sub = (UINT)(uintptr_t)src->data[1]; -+ D3D11_BOX box = { 0, 0, 0, src->width, src->height, 1 }; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst, 0, -+ 0, 0, 0, (ID3D11Resource *)src_tex, -+ src_sub, &box); -+} -+ -+static void copy_texture_to_frame(OverlayD3D11Context *s, ID3D11Texture2D *src, AVFrame *dst) -+{ -+ ID3D11Texture2D *dst_tex = (ID3D11Texture2D *)dst->data[0]; -+ UINT dst_sub = (UINT)(uintptr_t)dst->data[1]; -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst_tex, -+ dst_sub, 0, 0, 0, (ID3D11Resource *)src, -+ 0, NULL); -+} -+ -+static void copy_frame_to_frame(OverlayD3D11Context *s, AVFrame *src, AVFrame *dst) -+{ -+ ID3D11Texture2D *src_tex = (ID3D11Texture2D *)src->data[0]; -+ ID3D11Texture2D *dst_tex = (ID3D11Texture2D *)dst->data[0]; -+ UINT src_sub = (UINT)(uintptr_t)src->data[1]; -+ UINT dst_sub = (UINT)(uintptr_t)dst->data[1]; -+ D3D11_BOX box = { 0, 0, 0, src->width, src->height, 1 }; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst_tex, -+ dst_sub, 0, 0, 0, (ID3D11Resource *)src_tex, -+ src_sub, &box); -+} -+ +static int create_overlay_frame_srvs(AVFilterContext *ctx, AVFrame *overlay, + ID3D11ShaderResourceView **srvs) +{ @@ -510,7 +328,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + ret = create_srv_view(ctx, tex, subresource, DXGI_FORMAT_NV12, 1, + AV_LOG_DEBUG, &srvs[2]); + if (ret < 0) -+ D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(srvs[1]); + return ret; +} + @@ -539,14 +357,14 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + D3D11_BIND_SHADER_RESOURCE); + if (ret < 0) + return ret; -+ copy_frame_to_texture(s, main, s->main_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, main, s->main_tex); + + ret = create_srv(ctx, s->main_tex, DXGI_FORMAT_NV12, 0, &srvs[1]); + if (ret < 0) + return ret; + ret = create_srv(ctx, s->main_tex, DXGI_FORMAT_NV12, 1, &srvs[2]); + if (ret < 0) -+ D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(srvs[1]); + return ret; +} + @@ -575,7 +393,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_SHADER_RESOURCE); + if (ret < 0) + return ret; -+ copy_frame_to_texture(s, overlay, s->overlay_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, overlay, s->overlay_tex); + + return create_srv(ctx, s->overlay_tex, DXGI_FORMAT_B8G8R8A8_UNORM, -1, &srvs[0]); +} @@ -601,8 +419,8 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + *direct = 1; + return 0; + } -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + if (s->direct_output_uav < 0) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: copied from internal UAV texture\n"); + s->direct_output_uav = 0; @@ -618,7 +436,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + return ret; + ret = create_nv12_uav(ctx, s->work_tex, 1, &uavs[1]); + if (ret < 0) -+ D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[0]); + return ret; +} + @@ -653,8 +471,8 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + ret = create_nv12_uav_view(ctx, tex, subresource, 1, AV_LOG_DEBUG, &uavs[1]); + +done: -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&frame); + return ret; +} @@ -702,7 +520,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + out->format = AV_PIX_FMT_D3D11; + + if (!overlay) { -+ copy_frame_to_frame(s, main, out); ++ ff_d3d11_copy_frame_to_frame(s->context, main, out); + av_frame_free(&main); + return ff_filter_frame(outlink, out); + } @@ -761,13 +579,13 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); + + if (!direct_output) -+ copy_texture_to_frame(s, s->work_tex, out); ++ ff_d3d11_copy_texture_to_frame(s->context, s->work_tex, out); + -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); -+ D3D11_RELEASE(srvs[0]); -+ D3D11_RELEASE(srvs[1]); -+ D3D11_RELEASE(srvs[2]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(srvs[2]); + av_frame_free(&main); + + return ff_filter_frame(outlink, out); @@ -777,11 +595,11 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + s->context->lpVtbl->CSSetUnorderedAccessViews(s->context, 0, 2, null_uavs, NULL); + s->context->lpVtbl->CSSetShaderResources(s->context, 0, 3, null_srvs); + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); -+ D3D11_RELEASE(srvs[0]); -+ D3D11_RELEASE(srvs[1]); -+ D3D11_RELEASE(srvs[2]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(srvs[2]); + av_frame_free(&main); + av_frame_free(&out); + return ret; @@ -975,8 +793,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c + overlay_d3d11_release_resources(s); + av_buffer_unref(&s->hw_frames_ctx_out); + av_buffer_unref(&s->hw_device_ctx); -+ if (s->d3dcompiler) -+ FreeLibrary(s->d3dcompiler); ++ ff_d3d11_unload_shader_compiler(&s->d3dcompiler, &s->D3DCompile); + av_freep(&s->overlay_ox); + av_freep(&s->overlay_oy); + av_freep(&s->overlay_ow); diff --git a/debian/patches/0096-add-d3d11-tonemap-filter.patch b/debian/patches/0096-add-d3d11-tonemap-filter.patch index ff0f633fe..ee0e47653 100644 --- a/debian/patches/0096-add-d3d11-tonemap-filter.patch +++ b/debian/patches/0096-add-d3d11-tonemap-filter.patch @@ -18,7 +18,7 @@ Index: FFmpeg/libavfilter/Makefile OBJS-$(CONFIG_TONEMAPX_FILTER) += vf_tonemapx.o OBJS-$(CONFIG_TONEMAP_CUDA_FILTER) += vf_tonemap_cuda.o cuda/tonemap.ptx.o \ cuda/host_util.o cuda/load_helper.o -+OBJS-$(CONFIG_TONEMAP_D3D11_FILTER) += vf_tonemap_d3d11.o d3d11/tonemap.o ++OBJS-$(CONFIG_TONEMAP_D3D11_FILTER) += vf_tonemap_d3d11.o d3d11/tonemap.o d3d11_filter.o OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o opencl.o \ opencl/tonemap.o opencl/colorspace_common.o OBJS-$(CONFIG_TONEMAP_VAAPI_FILTER) += vf_tonemap_vaapi.o vaapi_vpp.o @@ -38,7 +38,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c =================================================================== --- /dev/null +++ FFmpeg/libavfilter/vf_tonemap_d3d11.c -@@ -0,0 +1,1267 @@ +@@ -0,0 +1,1094 @@ +/* + * D3D11 tonemap filter + * @@ -69,7 +69,6 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c +#define COBJMACROS +#endif +#include -+#include + +#include "libavutil/common.h" +#include "libavutil/mathematics.h" @@ -87,12 +86,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c +#include "video.h" +#include "vf_tonemap_d3d11.h" +#include "d3d11_source.h" ++#include "d3d11_filter.h" + +#define REF_WHITE_SCALE (REFERENCE_WHITE / REFERENCE_WHITE_ALT) -+#define D3D11_RELEASE(p) do { if (p) { (p)->lpVtbl->Release(p); (p) = NULL; } } while (0) -+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 -+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) -+#endif + +enum TonemapAlgorithm { + TONEMAP_NONE, @@ -115,11 +111,6 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + TONEMAP_MODE_COUNT, +}; + -+typedef HRESULT (WINAPI *D3DCompileProc)(LPCVOID, SIZE_T, LPCSTR, -+ const D3D_SHADER_MACRO *, ID3DInclude *, -+ LPCSTR, LPCSTR, UINT, UINT, -+ ID3D10Blob **, ID3D10Blob **); -+ +typedef struct TonemapD3D11Params { + int width; + int height; @@ -189,7 +180,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + ID3D11Device *device; + ID3D11DeviceContext *context; + HMODULE d3dcompiler; -+ D3DCompileProc D3DCompile; ++ FFD3DCompileProc D3DCompile; + ID3D11ComputeShader *cs; + ID3D11Buffer *params_buf; + ID3D11Texture2D *src_tex; @@ -242,28 +233,12 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + return fmt == AV_PIX_FMT_NV12 || fmt == AV_PIX_FMT_P010 || fmt == AV_PIX_FMT_P016; +} + -+static DXGI_FORMAT texture_format(enum AVPixelFormat fmt) -+{ -+ if (fmt == AV_PIX_FMT_P010) -+ return DXGI_FORMAT_P010; -+ if (fmt == AV_PIX_FMT_P016) -+ return DXGI_FORMAT_P016; -+ return DXGI_FORMAT_NV12; -+} -+ -+static DXGI_FORMAT plane_format(enum AVPixelFormat fmt, int plane) -+{ -+ if (fmt == AV_PIX_FMT_NV12) -+ return plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM; -+ return plane ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R16_UNORM; -+} -+ +static void release_d3d11_resources(TonemapD3D11Context *s) +{ -+ D3D11_RELEASE(s->cs); -+ D3D11_RELEASE(s->params_buf); -+ D3D11_RELEASE(s->src_tex); -+ D3D11_RELEASE(s->work_tex); ++ FF_D3D11_RELEASE(s->cs); ++ FF_D3D11_RELEASE(s->params_buf); ++ FF_D3D11_RELEASE(s->src_tex); ++ FF_D3D11_RELEASE(s->work_tex); + s->shader_tonemap = s->shader_mode = s->shader_trc_in = s->shader_trc_out = -1; + s->shader_full_in = s->shader_full_out = s->shader_out_depth = s->shader_skip = s->shader_dovi = -1; + s->src_w = s->src_h = 0; @@ -281,8 +256,6 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + int skip, int dovi) +{ + TonemapD3D11Context *s = ctx->priv; -+ ID3D10Blob *cs_blob = NULL; -+ ID3D10Blob *err_blob = NULL; + char tonemap_buf[16], mode_buf[16], trc_in_buf[16], trc_out_buf[16]; + char full_in_buf[16], full_out_buf[16], out_depth_buf[16], skip_buf[16], dovi_buf[16]; + D3D_SHADER_MACRO macros[] = { @@ -297,7 +270,6 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + { "APPLY_DOVI_VAL", dovi_buf }, + { NULL, NULL }, + }; -+ HRESULT hr; + + macro_int(tonemap_buf, sizeof(tonemap_buf), tonemap); + macro_int(mode_buf, sizeof(mode_buf), mode); @@ -309,34 +281,11 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + macro_int(skip_buf, sizeof(skip_buf), skip); + macro_int(dovi_buf, sizeof(dovi_buf), dovi); + -+ D3D11_RELEASE(s->cs); -+ hr = s->D3DCompile(ff_source_tonemap_hlsl, strlen(ff_source_tonemap_hlsl), -+ NULL, macros, NULL, "tonemap_main", "cs_5_0", -+ D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &cs_blob, &err_blob); -+ if (FAILED(hr)) { -+ if (err_blob) { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 tonemap shader: %.*s\n", -+ (int)err_blob->lpVtbl->GetBufferSize(err_blob), -+ (char *)err_blob->lpVtbl->GetBufferPointer(err_blob)); -+ } else { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 tonemap shader: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ } -+ D3D11_RELEASE(err_blob); ++ FF_D3D11_RELEASE(s->cs); ++ if (ff_d3d11_compile_shader(ctx, s->device, s->D3DCompile, ++ ff_source_tonemap_hlsl, macros, "tonemap_main", ++ "cs_5_0", "D3D11 tonemap", &s->cs) < 0) + return AVERROR_EXTERNAL; -+ } -+ -+ hr = s->device->lpVtbl->CreateComputeShader(s->device, -+ cs_blob->lpVtbl->GetBufferPointer(cs_blob), -+ cs_blob->lpVtbl->GetBufferSize(cs_blob), -+ NULL, &s->cs); -+ D3D11_RELEASE(cs_blob); -+ D3D11_RELEASE(err_blob); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 tonemap shader: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } + + s->shader_tonemap = tonemap; + s->shader_mode = mode; @@ -353,39 +302,17 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c +static int ensure_compiler_and_params(AVFilterContext *ctx) +{ + TonemapD3D11Context *s = ctx->priv; -+ D3D11_BUFFER_DESC bd = { 0 }; -+ HRESULT hr; ++ int ret; + -+ if (!s->d3dcompiler) { -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); -+ if (!s->d3dcompiler) -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); -+ } -+ if (!s->d3dcompiler) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading d3dcompiler DLL\n"); -+ return AVERROR_EXTERNAL; -+ } -+ -+ s->D3DCompile = (D3DCompileProc)GetProcAddress(s->d3dcompiler, "D3DCompile"); -+ if (!s->D3DCompile) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading D3DCompile\n"); -+ return AVERROR_EXTERNAL; -+ } ++ ret = ff_d3d11_load_shader_compiler(ctx, &s->d3dcompiler, &s->D3DCompile); ++ if (ret < 0) ++ return ret; + + if (s->params_buf) + return 0; + -+ bd.ByteWidth = sizeof(TonemapD3D11Params); -+ bd.Usage = D3D11_USAGE_DYNAMIC; -+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; -+ bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; -+ hr = s->device->lpVtbl->CreateBuffer(s->device, &bd, NULL, &s->params_buf); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 tonemap constant buffer: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_const_buffer(ctx, s->device, sizeof(TonemapD3D11Params), ++ "D3D11 tonemap", &s->params_buf); +} + +static int ensure_shader_variant(AVFilterContext *ctx, const TonemapD3D11Params *params) @@ -421,70 +348,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + enum AVPixelFormat fmt, UINT bind_flags) +{ + TonemapD3D11Context *s = ctx->priv; -+ D3D11_TEXTURE2D_DESC desc = { 0 }; -+ HRESULT hr; + -+ if (*tex && *cur_w == w && *cur_h == h) -+ return 0; -+ -+ D3D11_RELEASE(*tex); -+ desc.Width = w; -+ desc.Height = h; -+ desc.MipLevels = 1; -+ desc.ArraySize = 1; -+ desc.Format = texture_format(fmt); -+ desc.SampleDesc.Count = 1; -+ desc.Usage = D3D11_USAGE_DEFAULT; -+ desc.BindFlags = bind_flags; -+ -+ hr = s->device->lpVtbl->CreateTexture2D(s->device, &desc, NULL, tex); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 tonemap texture: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ *cur_w = w; -+ *cur_h = h; -+ return 0; -+} -+ -+static void fill_tex2d_srv_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_SHADER_RESOURCE_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0, array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MostDetailedMip = mip_slice; -+ desc->Texture2DArray.MipLevels = 1; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; -+} -+ -+static void fill_tex2d_uav_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0, array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MipSlice = mip_slice; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; ++ return ff_d3d11_ensure_texture(ctx, s->device, tex, cur_w, cur_h, NULL, ++ w, h, ff_d3d11_texture_format(fmt), bind_flags, ++ "D3D11 tonemap"); +} + +static int create_srv_view(AVFilterContext *ctx, ID3D11Texture2D *tex, @@ -492,18 +359,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + int log_level, ID3D11ShaderResourceView **srv) +{ + TonemapD3D11Context *s = ctx->priv; -+ D3D11_SHADER_RESOURCE_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ fill_tex2d_srv_desc(tex, subresource, plane_format(fmt, plane), &desc); -+ hr = s->device->lpVtbl->CreateShaderResourceView(s->device, (ID3D11Resource *)tex, -+ &desc, srv); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 tonemap SRV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_srv(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(fmt, plane), ++ log_level, "D3D11 tonemap", srv); +} + +static int create_uav_view(AVFilterContext *ctx, ID3D11Texture2D *tex, @@ -511,39 +370,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + int log_level, ID3D11UnorderedAccessView **uav) +{ + TonemapD3D11Context *s = ctx->priv; -+ D3D11_UNORDERED_ACCESS_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ fill_tex2d_uav_desc(tex, subresource, plane_format(fmt, plane), &desc); -+ hr = s->device->lpVtbl->CreateUnorderedAccessView(s->device, (ID3D11Resource *)tex, -+ &desc, uav); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 tonemap UAV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; -+} -+ -+static void copy_frame_to_texture(TonemapD3D11Context *s, AVFrame *src, ID3D11Texture2D *dst) -+{ -+ ID3D11Texture2D *src_tex = (ID3D11Texture2D *)src->data[0]; -+ UINT src_sub = (UINT)(uintptr_t)src->data[1]; -+ D3D11_BOX box = { 0, 0, 0, src->width, src->height, 1 }; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst, 0, -+ 0, 0, 0, (ID3D11Resource *)src_tex, -+ src_sub, &box); -+} -+ -+static void copy_texture_to_frame(TonemapD3D11Context *s, ID3D11Texture2D *src, AVFrame *dst) -+{ -+ ID3D11Texture2D *dst_tex = (ID3D11Texture2D *)dst->data[0]; -+ UINT dst_sub = (UINT)(uintptr_t)dst->data[1]; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst_tex, -+ dst_sub, 0, 0, 0, (ID3D11Resource *)src, -+ 0, NULL); ++ return ff_d3d11_create_uav(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(fmt, plane), ++ log_level, "D3D11 tonemap", uav); +} + +static int create_frame_srvs(AVFilterContext *ctx, AVFrame *frame, @@ -559,7 +389,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + return ret; + ret = create_srv_view(ctx, tex, subresource, s->in_fmt, 1, AV_LOG_DEBUG, &srvs[1]); + if (ret < 0) -+ D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[0]); + return ret; +} + @@ -589,13 +419,13 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + D3D11_BIND_SHADER_RESOURCE); + if (ret < 0) + return ret; -+ copy_frame_to_texture(s, input, s->src_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, input, s->src_tex); + ret = create_srv_view(ctx, s->src_tex, 0, s->in_fmt, 0, AV_LOG_ERROR, &srvs[0]); + if (ret < 0) + return ret; + ret = create_srv_view(ctx, s->src_tex, 0, s->in_fmt, 1, AV_LOG_ERROR, &srvs[1]); + if (ret < 0) -+ D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[0]); + return ret; +} + @@ -620,8 +450,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + *direct = 1; + return 0; + } -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + if (s->direct_output_uav < 0) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: copied from internal UAV texture\n"); + s->direct_output_uav = 0; @@ -637,7 +467,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + return ret; + ret = create_uav_view(ctx, s->work_tex, 0, s->out_fmt, 1, AV_LOG_ERROR, &uavs[1]); + if (ret < 0) -+ D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[0]); + return ret; +} + @@ -671,8 +501,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + ret = create_uav_view(ctx, tex, subresource, s->out_fmt, 1, AV_LOG_DEBUG, &uavs[1]); + +done: -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&frame); + return ret; +} @@ -881,17 +711,17 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); + + if (!direct_output) -+ copy_texture_to_frame(s, s->work_tex, output); ++ ff_d3d11_copy_texture_to_frame(s->context, s->work_tex, output); + +fail: + s->context->lpVtbl->CSSetShader(s->context, NULL, NULL, 0); + s->context->lpVtbl->CSSetShaderResources(s->context, 0, 2, null_srvs); + s->context->lpVtbl->CSSetUnorderedAccessViews(s->context, 0, 2, null_uavs, NULL); + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); -+ D3D11_RELEASE(srvs[0]); -+ D3D11_RELEASE(srvs[1]); -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + return ret; +} + @@ -1180,10 +1010,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_d3d11.c + release_d3d11_resources(s); + av_buffer_unref(&s->hw_device_ctx); + av_buffer_unref(&s->hw_frames_ctx_out); -+ if (s->d3dcompiler) { -+ FreeLibrary(s->d3dcompiler); -+ s->d3dcompiler = NULL; -+ } ++ ff_d3d11_unload_shader_compiler(&s->d3dcompiler, &s->D3DCompile); +} + +static int tonemap_d3d11_query_formats(AVFilterContext *avctx) diff --git a/debian/patches/0097-add-scale-d3d11-p010-shader-fallback.patch b/debian/patches/0097-add-scale-d3d11-p010-shader-fallback.patch index f88e534e4..6ba66374c 100644 --- a/debian/patches/0097-add-scale-d3d11-p010-shader-fallback.patch +++ b/debian/patches/0097-add-scale-d3d11-p010-shader-fallback.patch @@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c =================================================================== --- FFmpeg.orig/libavfilter/vf_scale_d3d11.c +++ FFmpeg/libavfilter/vf_scale_d3d11.c -@@ -21,7 +21,15 @@ +@@ -21,7 +21,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -11,31 +11,21 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c +#define COBJMACROS +#endif +#include -+#include + #include "libavutil/opt.h" +#include "libavutil/mem.h" #include "libavutil/pixdesc.h" #include "compat/w32dlfcn.h" -@@ -31,6 +39,26 @@ +@@ -31,6 +38,17 @@ #include "filters.h" #include "scale_eval.h" #include "video.h" +#include "d3d11_source.h" ++#include "d3d11_filter.h" + +#define SCALE_D3D11_TGX 16 +#define SCALE_D3D11_TGY 16 -+#define D3D11_RELEASE(p) do { if (p) { (p)->lpVtbl->Release(p); (p) = NULL; } } while (0) -+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 -+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) -+#endif -+ -+typedef HRESULT (WINAPI *D3DCompileProc)(LPCVOID, SIZE_T, LPCSTR, -+ const D3D_SHADER_MACRO *, ID3DInclude *, -+ LPCSTR, LPCSTR, UINT, UINT, -+ ID3D10Blob **, ID3D10Blob **); -+ +typedef struct ScaleD3D11Params { + int src_w; + int src_h; @@ -45,12 +35,12 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c typedef struct ScaleD3D11Context { const AVClass *classCtx; -@@ -47,12 +75,27 @@ typedef struct ScaleD3D11Context { +@@ -47,12 +65,27 @@ typedef struct ScaleD3D11Context { ID3D11VideoProcessorOutputView *outputView; ID3D11VideoProcessorInputView *inputView; + HMODULE d3dcompiler; -+ D3DCompileProc D3DCompile; ++ FFD3DCompileProc D3DCompile; + ID3D11ComputeShader *cs_y; + ID3D11ComputeShader *cs_uv; + ID3D11Buffer *params_buf; @@ -73,105 +63,44 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c int inputWidth, inputHeight; DXGI_FORMAT input_format; DXGI_FORMAT output_format; -@@ -83,6 +126,340 @@ static void release_d3d11_resources(Scal +@@ -83,6 +116,181 @@ static void release_d3d11_resources(Scal s->videoDevice->lpVtbl->Release(s->videoDevice); s->videoDevice = NULL; } + -+ D3D11_RELEASE(s->cs_y); -+ D3D11_RELEASE(s->cs_uv); -+ D3D11_RELEASE(s->params_buf); -+ D3D11_RELEASE(s->src_tex); -+ D3D11_RELEASE(s->work_tex); ++ FF_D3D11_RELEASE(s->cs_y); ++ FF_D3D11_RELEASE(s->cs_uv); ++ FF_D3D11_RELEASE(s->params_buf); ++ FF_D3D11_RELEASE(s->src_tex); ++ FF_D3D11_RELEASE(s->work_tex); + s->src_tex_w = s->src_tex_h = 0; + s->work_w = s->work_h = 0; +} + -+static DXGI_FORMAT scale_d3d11_texture_format(enum AVPixelFormat fmt) -+{ -+ return fmt == AV_PIX_FMT_P010 ? DXGI_FORMAT_P010 : DXGI_FORMAT_NV12; -+} -+ -+static DXGI_FORMAT scale_d3d11_plane_format(enum AVPixelFormat fmt, int plane) -+{ -+ if (fmt == AV_PIX_FMT_NV12) -+ return plane ? DXGI_FORMAT_R8G8_UNORM : DXGI_FORMAT_R8_UNORM; -+ return plane ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R16_UNORM; -+} -+ +static int scale_d3d11_compile_shader(AVFilterContext *ctx, const char *entry, + ID3D11ComputeShader **shader) +{ + ScaleD3D11Context *s = ctx->priv; -+ ID3D10Blob *cs_blob = NULL; -+ ID3D10Blob *err_blob = NULL; -+ HRESULT hr; + -+ hr = s->D3DCompile(ff_source_scale_hlsl, strlen(ff_source_scale_hlsl), -+ NULL, NULL, NULL, entry, "cs_5_0", -+ D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &cs_blob, &err_blob); -+ if (FAILED(hr)) { -+ if (err_blob) { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 scale shader %s: %.*s\n", -+ entry, (int)err_blob->lpVtbl->GetBufferSize(err_blob), -+ (char *)err_blob->lpVtbl->GetBufferPointer(err_blob)); -+ } else { -+ av_log(ctx, AV_LOG_ERROR, "Failed compiling D3D11 scale shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ } -+ D3D11_RELEASE(err_blob); -+ return AVERROR_EXTERNAL; -+ } -+ -+ hr = s->device->lpVtbl->CreateComputeShader(s->device, -+ cs_blob->lpVtbl->GetBufferPointer(cs_blob), -+ cs_blob->lpVtbl->GetBufferSize(cs_blob), -+ NULL, shader); -+ D3D11_RELEASE(cs_blob); -+ D3D11_RELEASE(err_blob); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 scale shader %s: HRESULT 0x%lX\n", -+ entry, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ -+ return 0; ++ return ff_d3d11_compile_shader(ctx, s->device, s->D3DCompile, ++ ff_source_scale_hlsl, NULL, entry, ++ "cs_5_0", "D3D11 scale", shader); +} + +static int scale_d3d11_ensure_shader(AVFilterContext *ctx) +{ + ScaleD3D11Context *s = ctx->priv; -+ D3D11_BUFFER_DESC bd = { 0 }; -+ HRESULT hr; + int ret; + -+ if (!s->d3dcompiler) { -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); -+ if (!s->d3dcompiler) -+ s->d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); -+ } -+ if (!s->d3dcompiler) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading d3dcompiler DLL\n"); -+ return AVERROR_EXTERNAL; -+ } -+ -+ s->D3DCompile = (D3DCompileProc)GetProcAddress(s->d3dcompiler, "D3DCompile"); -+ if (!s->D3DCompile) { -+ av_log(ctx, AV_LOG_ERROR, "Failed loading D3DCompile\n"); -+ return AVERROR_EXTERNAL; -+ } ++ ret = ff_d3d11_load_shader_compiler(ctx, &s->d3dcompiler, &s->D3DCompile); ++ if (ret < 0) ++ return ret; + + if (!s->params_buf) { -+ bd.ByteWidth = sizeof(ScaleD3D11Params); -+ bd.Usage = D3D11_USAGE_DYNAMIC; -+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; -+ bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; -+ hr = s->device->lpVtbl->CreateBuffer(s->device, &bd, NULL, &s->params_buf); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 scale constant buffer: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } ++ ret = ff_d3d11_create_const_buffer(ctx, s->device, sizeof(ScaleD3D11Params), ++ "D3D11 scale", &s->params_buf); ++ if (ret < 0) ++ return ret; + } + + if (!s->cs_y) { @@ -193,71 +122,10 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + enum AVPixelFormat fmt, UINT bind_flags) +{ + ScaleD3D11Context *s = ctx->priv; -+ D3D11_TEXTURE2D_DESC desc = { 0 }; -+ HRESULT hr; + -+ if (*tex && *cur_w == w && *cur_h == h) -+ return 0; -+ -+ D3D11_RELEASE(*tex); -+ desc.Width = w; -+ desc.Height = h; -+ desc.MipLevels = 1; -+ desc.ArraySize = 1; -+ desc.Format = scale_d3d11_texture_format(fmt); -+ desc.SampleDesc.Count = 1; -+ desc.Usage = D3D11_USAGE_DEFAULT; -+ desc.BindFlags = bind_flags; -+ -+ hr = s->device->lpVtbl->CreateTexture2D(s->device, &desc, NULL, tex); -+ if (FAILED(hr)) { -+ av_log(ctx, AV_LOG_ERROR, "Failed creating D3D11 scale texture: HRESULT 0x%lX\n", -+ (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ -+ *cur_w = w; -+ *cur_h = h; -+ return 0; -+} -+ -+static void scale_d3d11_fill_srv_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_SHADER_RESOURCE_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0, array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MostDetailedMip = mip_slice; -+ desc->Texture2DArray.MipLevels = 1; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; -+} -+ -+static void scale_d3d11_fill_uav_desc(ID3D11Texture2D *tex, UINT subresource, -+ DXGI_FORMAT fmt, D3D11_UNORDERED_ACCESS_VIEW_DESC *desc) -+{ -+ D3D11_TEXTURE2D_DESC tex_desc; -+ UINT mip_slice = 0, array_slice = 0; -+ -+ ID3D11Texture2D_GetDesc(tex, &tex_desc); -+ if (tex_desc.MipLevels) { -+ mip_slice = subresource % tex_desc.MipLevels; -+ array_slice = subresource / tex_desc.MipLevels; -+ } -+ -+ desc->Format = fmt; -+ desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; -+ desc->Texture2DArray.MipSlice = mip_slice; -+ desc->Texture2DArray.FirstArraySlice = array_slice; -+ desc->Texture2DArray.ArraySize = 1; ++ return ff_d3d11_ensure_texture(ctx, s->device, tex, cur_w, cur_h, NULL, ++ w, h, ff_d3d11_texture_format(fmt), bind_flags, ++ "D3D11 scale"); +} + +static int scale_d3d11_create_srv(AVFilterContext *ctx, ID3D11Texture2D *tex, @@ -265,18 +133,10 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + int log_level, ID3D11ShaderResourceView **srv) +{ + ScaleD3D11Context *s = ctx->priv; -+ D3D11_SHADER_RESOURCE_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ scale_d3d11_fill_srv_desc(tex, subresource, scale_d3d11_plane_format(fmt, plane), &desc); -+ hr = s->device->lpVtbl->CreateShaderResourceView(s->device, (ID3D11Resource *)tex, -+ &desc, srv); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 scale SRV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; ++ return ff_d3d11_create_srv(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(fmt, plane), ++ log_level, "D3D11 scale", srv); +} + +static int scale_d3d11_create_uav(AVFilterContext *ctx, ID3D11Texture2D *tex, @@ -284,39 +144,10 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + int log_level, ID3D11UnorderedAccessView **uav) +{ + ScaleD3D11Context *s = ctx->priv; -+ D3D11_UNORDERED_ACCESS_VIEW_DESC desc = { 0 }; -+ HRESULT hr; + -+ scale_d3d11_fill_uav_desc(tex, subresource, scale_d3d11_plane_format(fmt, plane), &desc); -+ hr = s->device->lpVtbl->CreateUnorderedAccessView(s->device, (ID3D11Resource *)tex, -+ &desc, uav); -+ if (FAILED(hr)) { -+ av_log(ctx, log_level, "Failed creating D3D11 scale UAV plane %d: HRESULT 0x%lX\n", -+ plane, (unsigned long)hr); -+ return AVERROR_EXTERNAL; -+ } -+ return 0; -+} -+ -+static void scale_d3d11_copy_frame_to_texture(ScaleD3D11Context *s, AVFrame *src, ID3D11Texture2D *dst) -+{ -+ ID3D11Texture2D *src_tex = (ID3D11Texture2D *)src->data[0]; -+ UINT src_sub = (UINT)(uintptr_t)src->data[1]; -+ D3D11_BOX box = { 0, 0, 0, src->width, src->height, 1 }; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst, 0, -+ 0, 0, 0, (ID3D11Resource *)src_tex, -+ src_sub, &box); -+} -+ -+static void scale_d3d11_copy_texture_to_frame(ScaleD3D11Context *s, ID3D11Texture2D *src, AVFrame *dst) -+{ -+ ID3D11Texture2D *dst_tex = (ID3D11Texture2D *)dst->data[0]; -+ UINT dst_sub = (UINT)(uintptr_t)dst->data[1]; -+ -+ s->context->lpVtbl->CopySubresourceRegion(s->context, (ID3D11Resource *)dst_tex, -+ dst_sub, 0, 0, 0, (ID3D11Resource *)src, -+ 0, NULL); ++ return ff_d3d11_create_uav(ctx, s->device, tex, subresource, ++ ff_d3d11_plane_format(fmt, plane), ++ log_level, "D3D11 scale", uav); +} + +static int scale_d3d11_create_frame_srvs(AVFilterContext *ctx, AVFrame *frame, @@ -332,7 +163,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + return ret; + ret = scale_d3d11_create_srv(ctx, tex, subresource, s->in_format, 1, AV_LOG_DEBUG, &srvs[1]); + if (ret < 0) -+ D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[0]); + return ret; +} + @@ -361,13 +192,13 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + D3D11_BIND_SHADER_RESOURCE); + if (ret < 0) + return ret; -+ scale_d3d11_copy_frame_to_texture(s, input, s->src_tex); ++ ff_d3d11_copy_frame_to_texture(s->context, input, s->src_tex); + ret = scale_d3d11_create_srv(ctx, s->src_tex, 0, s->in_format, 0, AV_LOG_ERROR, &srvs[0]); + if (ret < 0) + return ret; + ret = scale_d3d11_create_srv(ctx, s->src_tex, 0, s->in_format, 1, AV_LOG_ERROR, &srvs[1]); + if (ret < 0) -+ D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[0]); + return ret; +} + @@ -392,8 +223,8 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + *direct = 1; + return 0; + } -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + if (s->direct_output_uav < 0) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: copied from internal UAV texture\n"); + s->direct_output_uav = 0; @@ -409,12 +240,12 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + return ret; + ret = scale_d3d11_create_uav(ctx, s->work_tex, 0, s->format, 1, AV_LOG_ERROR, &uavs[1]); + if (ret < 0) -+ D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[0]); + return ret; } static int scale_d3d11_configure_processor(ScaleD3D11Context *s, AVFilterContext *ctx) { -@@ -144,6 +521,152 @@ static int scale_d3d11_configure_process +@@ -144,6 +352,152 @@ static int scale_d3d11_configure_process return 0; } @@ -448,8 +279,8 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + ret = scale_d3d11_create_uav(ctx, tex, subresource, s->format, 1, AV_LOG_DEBUG, &uavs[1]); + +done: -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&frame); + return ret; +} @@ -541,12 +372,12 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); + + if (!direct_output) -+ scale_d3d11_copy_texture_to_frame(s, s->work_tex, out); ++ ff_d3d11_copy_texture_to_frame(s->context, s->work_tex, out); + -+ D3D11_RELEASE(srvs[0]); -+ D3D11_RELEASE(srvs[1]); -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&in); + return ff_filter_frame(outlink, out); + @@ -555,10 +386,10 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + s->context->lpVtbl->CSSetShaderResources(s->context, 0, 2, null_srvs); + s->context->lpVtbl->CSSetUnorderedAccessViews(s->context, 0, 2, null_uavs, NULL); + s->context->lpVtbl->CSSetConstantBuffers(s->context, 0, 1, null_cb); -+ D3D11_RELEASE(srvs[0]); -+ D3D11_RELEASE(srvs[1]); -+ D3D11_RELEASE(uavs[0]); -+ D3D11_RELEASE(uavs[1]); ++ FF_D3D11_RELEASE(srvs[0]); ++ FF_D3D11_RELEASE(srvs[1]); ++ FF_D3D11_RELEASE(uavs[0]); ++ FF_D3D11_RELEASE(uavs[1]); + av_frame_free(&in); + av_frame_free(&out); + return ret; @@ -567,7 +398,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c static int scale_d3d11_filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; -@@ -185,6 +708,9 @@ static int scale_d3d11_filter_frame(AVFi +@@ -185,6 +539,9 @@ static int scale_d3d11_filter_frame(AVFi return AVERROR(EINVAL); } @@ -577,7 +408,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c ///< Allocate output frame out = av_frame_alloc(); if (!out) { -@@ -353,13 +879,6 @@ static int scale_d3d11_config_props(AVFi +@@ -353,13 +710,6 @@ static int scale_d3d11_config_props(AVFi return AVERROR(EINVAL); } @@ -591,7 +422,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c ///< Initialize filter's hardware device context if (!s->hw_device_ctx) { AVHWFramesContext *in_frames_ctx = (AVHWFramesContext *)inl->hw_frames_ctx->data; -@@ -382,6 +901,29 @@ static int scale_d3d11_config_props(AVFi +@@ -382,6 +732,29 @@ static int scale_d3d11_config_props(AVFi return AVERROR(EINVAL); } @@ -621,7 +452,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c ///< Create new hardware frames context for output s->hw_frames_ctx_out = av_hwframe_ctx_alloc(s->hw_device_ctx); if (!s->hw_frames_ctx_out) -@@ -399,16 +941,43 @@ static int scale_d3d11_config_props(AVFi +@@ -399,16 +772,43 @@ static int scale_d3d11_config_props(AVFi AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx; frames_hwctx->MiscFlags = 0; @@ -654,7 +485,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + } else if (s->shader_fallback) { + s->direct_output_uav = 0; + } -+ + + + if (s->shader_fallback) { + av_log(ctx, AV_LOG_VERBOSE, "D3D11 scale: using P010 output path\n"); @@ -663,24 +494,21 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c + else if (s->force_output_copy) + av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: forced copy from internal UAV texture\n"); + } - ++ + av_buffer_unref(&outl->hw_frames_ctx); outl->hw_frames_ctx = av_buffer_ref(s->hw_frames_ctx_out); if (!outl->hw_frames_ctx) return AVERROR(ENOMEM); -@@ -424,6 +993,11 @@ static av_cold void scale_d3d11_uninit(A +@@ -424,6 +824,8 @@ static av_cold void scale_d3d11_uninit(A ///< Release D3D11 resources release_d3d11_resources(s); -+ if (s->d3dcompiler) { -+ FreeLibrary(s->d3dcompiler); -+ s->d3dcompiler = NULL; -+ } ++ ff_d3d11_unload_shader_compiler(&s->d3dcompiler, &s->D3DCompile); + ///< Free the hardware device context reference av_buffer_unref(&s->hw_frames_ctx_out); av_buffer_unref(&s->hw_device_ctx); -@@ -453,9 +1027,12 @@ static const AVFilterPad scale_d3d11_out +@@ -453,9 +855,12 @@ static const AVFilterPad scale_d3d11_out #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) static const AVOption scale_d3d11_options[] = { @@ -693,7 +521,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c { NULL } }; -@@ -463,7 +1040,7 @@ AVFILTER_DEFINE_CLASS(scale_d3d11); +@@ -463,7 +868,7 @@ AVFILTER_DEFINE_CLASS(scale_d3d11); const FFFilter ff_vf_scale_d3d11 = { .p.name = "scale_d3d11", @@ -711,7 +539,7 @@ Index: FFmpeg/libavfilter/Makefile OBJS-$(CONFIG_SAB_FILTER) += vf_sab.o OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale_eval.o framesync.o -OBJS-$(CONFIG_SCALE_D3D11_FILTER) += vf_scale_d3d11.o scale_eval.o -+OBJS-$(CONFIG_SCALE_D3D11_FILTER) += vf_scale_d3d11.o scale_eval.o d3d11/scale.o ++OBJS-$(CONFIG_SCALE_D3D11_FILTER) += vf_scale_d3d11.o scale_eval.o d3d11/scale.o d3d11_filter.o OBJS-$(CONFIG_SCALE_D3D12_FILTER) += vf_scale_d3d12.o scale_eval.o OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \ vf_scale_cuda.ptx.o cuda/load_helper.o