mirror of
https://github.com/jellyfin/jellyfin-ffmpeg.git
synced 2026-09-02 21:03:08 +03:00
avfilter/d3d11: add output copy options to shader filters
This commit is contained in:
+34
-4
@@ -73,7 +73,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
@@ -0,0 +1,774 @@
|
||||
@@ -0,0 +1,804 @@
|
||||
+/*
|
||||
+ * D3D11 YADIF/BWDIF deinterlacing filters
|
||||
+ *
|
||||
@@ -168,6 +168,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
+ int tex_w, tex_h;
|
||||
+ int direct_input_srv;
|
||||
+ int direct_output_uav;
|
||||
+ int force_output_copy;
|
||||
+} DeintD3D11Context;
|
||||
+
|
||||
+static void release_d3d11_resources(DeintD3D11Context *s)
|
||||
@@ -712,7 +713,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
+ s->direct_input_srv = -1;
|
||||
+ s->direct_output_uav = -1;
|
||||
+
|
||||
+ for (int direct = 1; direct >= 0; direct--) {
|
||||
+ for (int direct = !s->force_output_copy; direct >= 0; direct--) {
|
||||
+ l->hw_frames_ctx = av_hwframe_ctx_alloc(s->device_ref);
|
||||
+ if (!l->hw_frames_ctx)
|
||||
+ return AVERROR(ENOMEM);
|
||||
@@ -753,6 +754,8 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
+ }
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ if (s->force_output_copy)
|
||||
+ av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: forced copy from internal UAV texture\n");
|
||||
+
|
||||
+ output_frames = (AVHWFramesContext *)l->hw_frames_ctx->data;
|
||||
+
|
||||
@@ -787,10 +790,37 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define DEINT_OFFSET(x) offsetof(DeintD3D11Context, x)
|
||||
+#define YADIF_OFFSET(x) offsetof(DeintD3D11Context, yadif.x)
|
||||
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
|
||||
+#define CONST(name, help, val, u) { name, help, 0, AV_OPT_TYPE_CONST, { .i64 = val }, INT_MIN, INT_MAX, FLAGS, .unit = u }
|
||||
+
|
||||
+static const AVOption deint_d3d11_options[] = {
|
||||
+ { "mode", "specify the interlacing mode", YADIF_OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = YADIF_MODE_SEND_FRAME }, 0, 3, FLAGS, .unit = "mode" },
|
||||
+ CONST("send_frame", "send one frame for each frame", YADIF_MODE_SEND_FRAME, "mode"),
|
||||
+ CONST("send_field", "send one frame for each field", YADIF_MODE_SEND_FIELD, "mode"),
|
||||
+ CONST("send_frame_nospatial", "send one frame for each frame, but skip spatial interlacing check", YADIF_MODE_SEND_FRAME_NOSPATIAL, "mode"),
|
||||
+ CONST("send_field_nospatial", "send one frame for each field, but skip spatial interlacing check", YADIF_MODE_SEND_FIELD_NOSPATIAL, "mode"),
|
||||
+ { "parity", "specify the assumed picture field parity", YADIF_OFFSET(parity), AV_OPT_TYPE_INT, { .i64 = YADIF_PARITY_AUTO }, -1, 1, FLAGS, .unit = "parity" },
|
||||
+ CONST("tff", "assume top field first", YADIF_PARITY_TFF, "parity"),
|
||||
+ CONST("bff", "assume bottom field first", YADIF_PARITY_BFF, "parity"),
|
||||
+ CONST("auto", "auto detect parity", YADIF_PARITY_AUTO, "parity"),
|
||||
+ { "deint", "specify which frames to deinterlace", YADIF_OFFSET(deint), AV_OPT_TYPE_INT, { .i64 = YADIF_DEINT_ALL }, 0, 1, FLAGS, .unit = "deint" },
|
||||
+ CONST("all", "deinterlace all frames", YADIF_DEINT_ALL, "deint"),
|
||||
+ CONST("interlaced", "only deinterlace frames marked as interlaced", YADIF_DEINT_INTERLACED, "deint"),
|
||||
+ { "force_output_copy", "Force output through an internal unordered-access texture", DEINT_OFFSET(force_output_copy), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
|
||||
+ { NULL }
|
||||
+};
|
||||
+
|
||||
+#undef CONST
|
||||
+#undef FLAGS
|
||||
+#undef YADIF_OFFSET
|
||||
+#undef DEINT_OFFSET
|
||||
+
|
||||
+static const AVClass yadif_d3d11_class = {
|
||||
+ .class_name = "yadif_d3d11",
|
||||
+ .item_name = av_default_item_name,
|
||||
+ .option = ff_yadif_options,
|
||||
+ .option = deint_d3d11_options,
|
||||
+ .version = LIBAVUTIL_VERSION_INT,
|
||||
+ .category = AV_CLASS_CATEGORY_FILTER,
|
||||
+};
|
||||
@@ -798,7 +828,7 @@ Index: FFmpeg/libavfilter/vf_yadif_d3d11.c
|
||||
+static const AVClass bwdif_d3d11_class = {
|
||||
+ .class_name = "bwdif_d3d11",
|
||||
+ .item_name = av_default_item_name,
|
||||
+ .option = ff_yadif_options,
|
||||
+ .option = deint_d3d11_options,
|
||||
+ .version = LIBAVUTIL_VERSION_INT,
|
||||
+ .category = AV_CLASS_CATEGORY_FILTER,
|
||||
+};
|
||||
|
||||
+1
-1
@@ -991,7 +991,7 @@ Index: FFmpeg/libavfilter/vf_overlay_d3d11.c
|
||||
+ { "w", "Overlay width", OFFSET(overlay_ow), AV_OPT_TYPE_STRING, { .str = "overlay_iw" }, 0, 255, FLAGS },
|
||||
+ { "h", "Overlay height", OFFSET(overlay_oh), AV_OPT_TYPE_STRING, { .str = "overlay_ih*overlay_w/overlay_iw" }, 0, 255, FLAGS },
|
||||
+ { "alpha", "Overlay global alpha", OFFSET(alpha), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 1.0, FLAGS },
|
||||
+ { "force_output_copy", "Force output through an internal unordered-access texture", OFFSET(force_output_copy), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
|
||||
+ { "force_output_copy", "Force output through an internal unordered-access texture", OFFSET(force_output_copy), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
|
||||
+ { "eof_action", "Action to take when encountering EOF from secondary input",
|
||||
+ OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
|
||||
+ EOF_ACTION_REPEAT, EOF_ACTION_PASS, FLAGS, .unit = "eof_action" },
|
||||
|
||||
+22
-13
@@ -45,7 +45,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
|
||||
typedef struct ScaleD3D11Context {
|
||||
const AVClass *classCtx;
|
||||
@@ -47,12 +75,26 @@ typedef struct ScaleD3D11Context {
|
||||
@@ -47,12 +75,27 @@ typedef struct ScaleD3D11Context {
|
||||
ID3D11VideoProcessorOutputView *outputView;
|
||||
ID3D11VideoProcessorInputView *inputView;
|
||||
|
||||
@@ -61,6 +61,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
+ int shader_fallback;
|
||||
+ int direct_input_srv;
|
||||
+ int direct_output_uav;
|
||||
+ int force_output_copy;
|
||||
+
|
||||
///< Buffer references
|
||||
AVBufferRef *hw_device_ctx;
|
||||
@@ -72,7 +73,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
int inputWidth, inputHeight;
|
||||
DXGI_FORMAT input_format;
|
||||
DXGI_FORMAT output_format;
|
||||
@@ -83,6 +125,340 @@ static void release_d3d11_resources(Scal
|
||||
@@ -83,6 +126,340 @@ static void release_d3d11_resources(Scal
|
||||
s->videoDevice->lpVtbl->Release(s->videoDevice);
|
||||
s->videoDevice = NULL;
|
||||
}
|
||||
@@ -413,7 +414,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
}
|
||||
|
||||
static int scale_d3d11_configure_processor(ScaleD3D11Context *s, AVFilterContext *ctx) {
|
||||
@@ -144,6 +520,152 @@ static int scale_d3d11_configure_process
|
||||
@@ -144,6 +521,152 @@ static int scale_d3d11_configure_process
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -566,7 +567,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
static int scale_d3d11_filter_frame(AVFilterLink *inlink, AVFrame *in)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
@@ -185,6 +707,9 @@ static int scale_d3d11_filter_frame(AVFi
|
||||
@@ -185,6 +708,9 @@ static int scale_d3d11_filter_frame(AVFi
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
@@ -576,7 +577,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
///< Allocate output frame
|
||||
out = av_frame_alloc();
|
||||
if (!out) {
|
||||
@@ -353,13 +878,6 @@ static int scale_d3d11_config_props(AVFi
|
||||
@@ -353,13 +879,6 @@ static int scale_d3d11_config_props(AVFi
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
@@ -590,7 +591,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 +900,29 @@ static int scale_d3d11_config_props(AVFi
|
||||
@@ -382,6 +901,29 @@ static int scale_d3d11_config_props(AVFi
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
@@ -620,7 +621,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 +940,38 @@ static int scale_d3d11_config_props(AVFi
|
||||
@@ -399,16 +941,43 @@ static int scale_d3d11_config_props(AVFi
|
||||
|
||||
AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
|
||||
frames_hwctx->MiscFlags = 0;
|
||||
@@ -629,8 +630,9 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
- frames_hwctx->BindFlags |= D3D11_BIND_VIDEO_ENCODER;
|
||||
+ if (s->shader_fallback) {
|
||||
+ frames_hwctx->BindFlags = D3D11_BIND_RENDER_TARGET |
|
||||
+ D3D11_BIND_SHADER_RESOURCE |
|
||||
+ D3D11_BIND_UNORDERED_ACCESS;
|
||||
+ D3D11_BIND_SHADER_RESOURCE;
|
||||
+ if (!s->force_output_copy)
|
||||
+ frames_hwctx->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||
+ } else {
|
||||
+ frames_hwctx->BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
+ if (frames_ctx->sw_format == AV_PIX_FMT_NV12)
|
||||
@@ -642,13 +644,15 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
av_buffer_unref(&s->hw_frames_ctx_out);
|
||||
return ret;
|
||||
}
|
||||
+ if (s->shader_fallback) {
|
||||
+ if (s->shader_fallback && !s->force_output_copy) {
|
||||
+ ret = scale_d3d11_probe_output_uav_pool(ctx, s->hw_frames_ctx_out);
|
||||
+ if (ret < 0) {
|
||||
+ av_buffer_unref(&s->hw_frames_ctx_out);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ s->direct_output_uav = 1;
|
||||
+ } else if (s->shader_fallback) {
|
||||
+ s->direct_output_uav = 0;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
@@ -656,13 +660,15 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
+ av_log(ctx, AV_LOG_VERBOSE, "D3D11 scale: using P010 output path\n");
|
||||
+ if (s->direct_output_uav > 0)
|
||||
+ av_log(ctx, AV_LOG_DEBUG, "D3D11 shader output: direct UAV\n");
|
||||
+ 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 +987,11 @@ static av_cold void scale_d3d11_uninit(A
|
||||
@@ -424,6 +993,11 @@ static av_cold void scale_d3d11_uninit(A
|
||||
///< Release D3D11 resources
|
||||
release_d3d11_resources(s);
|
||||
|
||||
@@ -674,7 +680,7 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
///< Free the hardware device context reference
|
||||
av_buffer_unref(&s->hw_frames_ctx_out);
|
||||
av_buffer_unref(&s->hw_device_ctx);
|
||||
@@ -453,7 +1021,9 @@ static const AVFilterPad scale_d3d11_out
|
||||
@@ -453,9 +1027,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[] = {
|
||||
@@ -683,8 +689,11 @@ Index: FFmpeg/libavfilter/vf_scale_d3d11.c
|
||||
+ { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
|
||||
{ "height", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
|
||||
{ "format", "Output video pixel format", OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, { .i64 = AV_PIX_FMT_NONE }, INT_MIN, INT_MAX, .flags=FLAGS },
|
||||
+ { "force_output_copy", "Force P010 shader output through an internal unordered-access texture", OFFSET(force_output_copy), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, .flags=FLAGS },
|
||||
{ NULL }
|
||||
@@ -463,7 +1033,7 @@ AVFILTER_DEFINE_CLASS(scale_d3d11);
|
||||
};
|
||||
|
||||
@@ -463,7 +1040,7 @@ AVFILTER_DEFINE_CLASS(scale_d3d11);
|
||||
|
||||
const FFFilter ff_vf_scale_d3d11 = {
|
||||
.p.name = "scale_d3d11",
|
||||
|
||||
Reference in New Issue
Block a user