PR #22386 opened by Steven Xiao (younengxiao)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22386
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22386.patch
This commit update deinterlace_d3d12 filter options name.
Currently it follows the options name with "deinterlace_vaapi",
In this commit, it will follow filters such as "yadif" and "w3fdif".
Sample command lines:
1. Software decode with hwupload:
ffmpeg -init_hw_device d3d12va=d3d12 -i interlaced.ts \
-vf
"format=nv12,hwupload,deinterlace_d3d12=method=default,hwdownload,format=nv12" \
-c:v libx264 output.mp4
2. Full hardware pipeline:
ffmpeg -hwaccel d3d12va -hwaccel_output_format d3d12 -i interlaced.ts \
-vf "deinterlace_d3d12=method=custom:mode=field" \
-c:v h264_d3d12va output.mp4
>From 43a9f46f338928c20b10987d26c71915732b80fb Mon Sep 17 00:00:00 2001
From: stevxiao <[email protected]>
Date: Thu, 5 Mar 2026 01:00:39 -0500
Subject: [PATCH] avfilter: update deinterlace_d3d12 filter options name
This commit update deinterlace_d3d12 filter options name.
Currently it follows the options name with "deinterlace_vaapi",
In this commit, it will follow filters such as "yadif" and "w3fdif".
Sample command lines:
1. Software decode with hwupload:
ffmpeg -init_hw_device d3d12va=d3d12 -i interlaced.ts \
-vf
"format=nv12,hwupload,deinterlace_d3d12=method=default,hwdownload,format=nv12" \
-c:v libx264 output.mp4
2. Full hardware pipeline:
ffmpeg -hwaccel d3d12va -hwaccel_output_format d3d12 -i interlaced.ts \
-vf "deinterlace_d3d12=method=custom:mode=field" \
-c:v h264_d3d12va output.mp4
Signed-off-by: younengxiao <[email protected]>
---
libavfilter/vf_deinterlace_d3d12.c | 82 ++++++++++++++++--------------
1 file changed, 43 insertions(+), 39 deletions(-)
diff --git a/libavfilter/vf_deinterlace_d3d12.c
b/libavfilter/vf_deinterlace_d3d12.c
index 44513c6370..2ac7a0c122 100644
--- a/libavfilter/vf_deinterlace_d3d12.c
+++ b/libavfilter/vf_deinterlace_d3d12.c
@@ -37,19 +37,19 @@
* Deinterlace mode enumeration
* Maps to D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG values
*/
-enum DeinterlaceD3D12Mode {
- DEINT_D3D12_MODE_DEFAULT = 0, // Use best available mode
- DEINT_D3D12_MODE_BOB = 1, // Bob deinterlacing (simple field
interpolation)
- DEINT_D3D12_MODE_CUSTOM = 2, // Driver-defined advanced
deinterlacing
+enum DeinterlaceD3D12Method {
+ DEINT_D3D12_METHOD_DEFAULT = 0, // Use best available method
+ DEINT_D3D12_METHOD_BOB = 1, // Bob deinterlacing (simple field
interpolation)
+ DEINT_D3D12_METHOD_CUSTOM = 2, // Driver-defined advanced
deinterlacing
};
typedef struct DeinterlaceD3D12Context {
const AVClass *classCtx;
/* Filter options */
- int mode; // Deinterlace mode (default, bob, custom)
- int field_rate; // Output field rate (1 = frame rate, 2 = field rate)
- int auto_enable; // Only deinterlace interlaced frames
+ int method; // Deinterlace method (default, bob, custom)
+ int mode; // Output mode (0 = frame rate, 1 = field rate)
+ int deint; // Which frames to deinterlace (0 = all, 1 =
interlaced only)
/* D3D12 objects */
ID3D12Device *device;
@@ -225,14 +225,14 @@ static D3D12_VIDEO_PROCESS_DEINTERLACE_FLAGS
get_deint_mode(DeinterlaceD3D12Cont
{
D3D12_VIDEO_PROCESS_DEINTERLACE_FLAGS mode_flag;
- switch (s->mode) {
- case DEINT_D3D12_MODE_BOB:
+ switch (s->method) {
+ case DEINT_D3D12_METHOD_BOB:
mode_flag = D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_BOB;
break;
- case DEINT_D3D12_MODE_CUSTOM:
+ case DEINT_D3D12_METHOD_CUSTOM:
mode_flag = D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_CUSTOM;
break;
- case DEINT_D3D12_MODE_DEFAULT:
+ case DEINT_D3D12_METHOD_DEFAULT:
default:
/* Select best available mode */
if (s->supported_deint_flags &
D3D12_VIDEO_PROCESS_DEINTERLACE_FLAG_CUSTOM) {
@@ -314,7 +314,7 @@ static int
deint_d3d12_configure_processor(DeinterlaceD3D12Context *s,
s->process_support.OutputFormat.Format = s->input_format;
s->process_support.OutputFormat.ColorSpace = s->input_colorspace;
- s->process_support.OutputFrameRate.Numerator = s->input_framerate.num
* s->field_rate;
+ s->process_support.OutputFrameRate.Numerator = s->input_framerate.num
* (s->mode + 1);
s->process_support.OutputFrameRate.Denominator = s->input_framerate.den;
s->process_support.OutputStereoFormat =
D3D12_VIDEO_FRAME_STEREO_FORMAT_NONE;
@@ -356,7 +356,7 @@ static int
deint_d3d12_configure_processor(DeinterlaceD3D12Context *s,
.Filters = D3D12_VIDEO_PROCESS_FILTER_FLAG_NONE,
.FeatureSupport = D3D12_VIDEO_PROCESS_FEATURE_FLAG_NONE,
.InputFrameRate = { s->input_framerate.num, s->input_framerate.den
},
- .OutputFrameRate = { s->input_framerate.num * s->field_rate,
s->input_framerate.den },
+ .OutputFrameRate = { s->input_framerate.num * (s->mode + 1),
s->input_framerate.den },
.EnableAutoProcessing = FALSE,
};
@@ -387,7 +387,7 @@ static int
deint_d3d12_configure_processor(DeinterlaceD3D12Context *s,
#endif
/* May need 1 extra slot for PTS calculation.*/
- s->extra_delay_for_timestamps = (s->field_rate == 2 &&
s->num_future_frames == 0) ? 1 : 0;
+ s->extra_delay_for_timestamps = (s->mode && s->num_future_frames == 0) ? 1
: 0;
s->queue_depth = s->num_past_frames + s->num_future_frames +
s->extra_delay_for_timestamps + 1;
@@ -409,7 +409,7 @@ static int
deint_d3d12_configure_processor(DeinterlaceD3D12Context *s,
.AlphaFillMode =
D3D12_VIDEO_PROCESS_ALPHA_FILL_MODE_OPAQUE,
.AlphaFillModeSourceStreamIndex = 0,
.BackgroundColor = { 0.0f, 0.0f, 0.0f, 1.0f },
- .FrameRate = { s->input_framerate.num *
s->field_rate, s->input_framerate.den },
+ .FrameRate = { s->input_framerate.num * (s->mode
+ 1), s->input_framerate.den },
.EnableStereo = FALSE,
};
@@ -756,7 +756,7 @@ static int deint_d3d12_process_frame(AVFilterContext *ctx,
out->flags &= ~AV_FRAME_FLAG_INTERLACED;
/* Calculate output PTS for field rate output */
- if (s->field_rate == 2 && queue_idx >= 0) {
+ if (s->mode && queue_idx >= 0) {
AVFrame *next_frame = (queue_idx + 1 < s->queue_count) ?
s->frame_queue[queue_idx + 1] : NULL;
@@ -816,7 +816,7 @@ static int deint_d3d12_filter_frame(AVFilterLink *inlink,
AVFrame *in)
while (flush_idx < s->queue_count) {
input_frame = s->frame_queue[flush_idx];
if (input_frame) {
- for (field = 0; field < s->field_rate; field++) {
+ for (field = 0; field <= s->mode; field++) {
ret = deint_d3d12_process_frame(ctx, outlink,
input_frame, field, flush_idx);
if (ret < 0)
return ret;
@@ -878,7 +878,7 @@ static int deint_d3d12_filter_frame(AVFilterLink *inlink,
AVFrame *in)
}
/* Auto mode: pass through progressive frames by processing them as-is */
- if (s->auto_enable && !(in->flags & AV_FRAME_FLAG_INTERLACED)) {
+ if (s->deint && !(in->flags & AV_FRAME_FLAG_INTERLACED)) {
av_log(ctx, AV_LOG_DEBUG, "Progressive frame, processing as
pass-through\n");
ret = deint_d3d12_process_frame(ctx, outlink, in, 0, -1);
av_frame_free(&in);
@@ -923,7 +923,7 @@ static int deint_d3d12_filter_frame(AVFilterLink *inlink,
AVFrame *in)
input_frame = s->frame_queue[i];
if (!input_frame)
continue;
- for (field = 0; field < s->field_rate; field++) {
+ for (field = 0; field <= s->mode; field++) {
ret = deint_d3d12_process_frame(ctx, outlink, input_frame,
field, i);
if (ret < 0)
return ret;
@@ -946,7 +946,7 @@ static int deint_d3d12_filter_frame(AVFilterLink *inlink,
AVFrame *in)
if (!input_frame)
return 0;
- for (field = 0; field < s->field_rate; field++) {
+ for (field = 0; field <= s->mode; field++) {
ret = deint_d3d12_process_frame(ctx, outlink, input_frame, field,
s->current_frame_index);
if (ret < 0)
break;
@@ -1000,8 +1000,8 @@ static int deint_d3d12_config_output(AVFilterLink
*outlink)
s->height = inlink->h;
/* Adjust time base and frame rate for field rate output */
- outlink->time_base = av_mul_q(inlink->time_base, (AVRational){ 1,
s->field_rate });
- outl->frame_rate = av_mul_q(inl->frame_rate, (AVRational){
s->field_rate, 1 });
+ outlink->time_base = av_mul_q(inlink->time_base, (AVRational){ 1, s->mode
+ 1 });
+ outl->frame_rate = av_mul_q(inl->frame_rate, (AVRational){ s->mode + 1,
1 });
if (!inl->hw_frames_ctx) {
av_log(ctx, AV_LOG_ERROR, "No hw_frames_ctx available on input
link\n");
@@ -1047,8 +1047,8 @@ static int deint_d3d12_config_output(AVFilterLink
*outlink)
if (!outl->hw_frames_ctx)
return AVERROR(ENOMEM);
- av_log(ctx, AV_LOG_VERBOSE, "D3D12 deinterlace config: %dx%d,
field_rate=%d\n",
- outlink->w, outlink->h, s->field_rate);
+ av_log(ctx, AV_LOG_VERBOSE, "D3D12 deinterlace config: %dx%d, mode=%s\n",
+ outlink->w, outlink->h, s->mode ? "field" : "frame");
return 0;
}
@@ -1085,25 +1085,29 @@ static const AVFilterPad deint_d3d12_outputs[] = {
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
static const AVOption deinterlace_d3d12_options[] = {
- { "mode", "Deinterlacing mode",
- OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = DEINT_D3D12_MODE_DEFAULT },
- DEINT_D3D12_MODE_DEFAULT, DEINT_D3D12_MODE_CUSTOM, FLAGS, .unit = "mode"
},
- { "default", "Use best available deinterlacing mode",
- 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_MODE_DEFAULT }, 0, 0, FLAGS,
.unit = "mode" },
+ { "method", "Deinterlacing method",
+ OFFSET(method), AV_OPT_TYPE_INT, { .i64 = DEINT_D3D12_METHOD_DEFAULT },
+ DEINT_D3D12_METHOD_DEFAULT, DEINT_D3D12_METHOD_CUSTOM, FLAGS, .unit =
"method" },
+ { "default", "Use best available deinterlacing method",
+ 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_METHOD_DEFAULT }, 0, 0,
FLAGS, .unit = "method" },
{ "bob", "Bob deinterlacing (simple field interpolation)",
- 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_MODE_BOB }, 0, 0, FLAGS,
.unit = "mode" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_METHOD_BOB }, 0, 0, FLAGS,
.unit = "method" },
{ "custom", "Driver-defined advanced deinterlacing",
- 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_MODE_CUSTOM }, 0, 0, FLAGS,
.unit = "mode" },
+ 0, AV_OPT_TYPE_CONST, { .i64 = DEINT_D3D12_METHOD_CUSTOM }, 0, 0, FLAGS,
.unit = "method" },
- { "rate", "Generate output at frame rate or field rate",
- OFFSET(field_rate), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 2, FLAGS, .unit =
"rate" },
- { "frame", "Output at frame rate (one frame for each field-pair)",
- 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "rate" },
- { "field", "Output at field rate (one frame for each field)",
- 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, .unit = "rate" },
+ { "mode", "Specify the interlacing mode",
+ OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "mode"
},
+ { "frame", "Send one frame for each frame",
+ 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "mode" },
+ { "field", "Send one frame for each field",
+ 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "mode" },
- { "auto", "Only deinterlace interlaced frames, pass through progressive",
- OFFSET(auto_enable), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+ { "deint", "Specify which frames to deinterlace",
+ OFFSET(deint), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit =
"deint" },
+ { "all", "Deinterlace all frames",
+ 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "deint" },
+ { "interlaced", "Only deinterlace frames marked as interlaced",
+ 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "deint" },
{ NULL }
};
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]