mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-06-04 05:57:49 +02:00
avfilter/vf_w3fdif: add two more useful options
This commit is contained in:
parent
fde5593c7c
commit
b112c86a2e
@ -20931,6 +20931,35 @@ More-complex filter coefficient set.
|
|||||||
@end table
|
@end table
|
||||||
Default value is @samp{complex}.
|
Default value is @samp{complex}.
|
||||||
|
|
||||||
|
@item mode
|
||||||
|
The interlacing mode to adopt. It accepts one of the following values:
|
||||||
|
|
||||||
|
@table @option
|
||||||
|
@item frame
|
||||||
|
Output one frame for each frame.
|
||||||
|
@item field
|
||||||
|
Output one frame for each field.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The default value is @code{field}.
|
||||||
|
|
||||||
|
@item parity
|
||||||
|
The picture field parity assumed for the input interlaced video. It accepts one
|
||||||
|
of the following values:
|
||||||
|
|
||||||
|
@table @option
|
||||||
|
@item tff
|
||||||
|
Assume the top field is first.
|
||||||
|
@item bff
|
||||||
|
Assume the bottom field is first.
|
||||||
|
@item auto
|
||||||
|
Enable automatic detection of field parity.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The default value is @code{auto}.
|
||||||
|
If the interlacing is unknown or the decoder does not export this information,
|
||||||
|
top field first will be assumed.
|
||||||
|
|
||||||
@item deint
|
@item deint
|
||||||
Specify which frames to deinterlace. Accepts one of the following values:
|
Specify which frames to deinterlace. Accepts one of the following values:
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
typedef struct W3FDIFContext {
|
typedef struct W3FDIFContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
int filter; ///< 0 is simple, 1 is more complex
|
int filter; ///< 0 is simple, 1 is more complex
|
||||||
|
int mode; ///< 0 is frame, 1 is field
|
||||||
|
int parity; ///< frame field parity
|
||||||
int deint; ///< which frames to deinterlace
|
int deint; ///< which frames to deinterlace
|
||||||
int linesize[4]; ///< bytes of pixel data per line for each plane
|
int linesize[4]; ///< bytes of pixel data per line for each plane
|
||||||
int planeheight[4]; ///< height of each plane
|
int planeheight[4]; ///< height of each plane
|
||||||
@ -56,6 +58,13 @@ static const AVOption w3fdif_options[] = {
|
|||||||
{ "filter", "specify the filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "filter" },
|
{ "filter", "specify the filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "filter" },
|
||||||
CONST("simple", NULL, 0, "filter"),
|
CONST("simple", NULL, 0, "filter"),
|
||||||
CONST("complex", NULL, 1, "filter"),
|
CONST("complex", NULL, 1, "filter"),
|
||||||
|
{ "mode", "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode"},
|
||||||
|
CONST("frame", "send one frame for each frame", 0, "mode"),
|
||||||
|
CONST("field", "send one frame for each field", 1, "mode"),
|
||||||
|
{ "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "parity" },
|
||||||
|
CONST("tff", "assume top field first", 0, "parity"),
|
||||||
|
CONST("bff", "assume bottom field first", 1, "parity"),
|
||||||
|
CONST("auto", "auto detect parity", -1, "parity"),
|
||||||
{ "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "deint" },
|
{ "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "deint" },
|
||||||
CONST("all", "deinterlace all frames", 0, "deint"),
|
CONST("all", "deinterlace all frames", 0, "deint"),
|
||||||
CONST("interlaced", "only deinterlace frames marked as interlaced", 1, "deint"),
|
CONST("interlaced", "only deinterlace frames marked as interlaced", 1, "deint"),
|
||||||
@ -372,10 +381,11 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_
|
|||||||
const int start = (height * jobnr) / nb_jobs;
|
const int start = (height * jobnr) / nb_jobs;
|
||||||
const int end = (height * (jobnr+1)) / nb_jobs;
|
const int end = (height * (jobnr+1)) / nb_jobs;
|
||||||
const int max = s->max;
|
const int max = s->max;
|
||||||
|
const int tff = s->field == (s->parity == -1 ? cur->top_field_first == 1 : s->parity == 0 ? 1 : 0);
|
||||||
int j, y_in, y_out;
|
int j, y_in, y_out;
|
||||||
|
|
||||||
/* copy unchanged the lines of the field */
|
/* copy unchanged the lines of the field */
|
||||||
y_out = start + ((s->field == cur->top_field_first) ^ (start & 1));
|
y_out = start + (tff ^ (start & 1));
|
||||||
|
|
||||||
in_line = cur_data + (y_out * cur_line_stride);
|
in_line = cur_data + (y_out * cur_line_stride);
|
||||||
out_line = dst_data + (y_out * dst_line_stride);
|
out_line = dst_data + (y_out * dst_line_stride);
|
||||||
@ -388,7 +398,7 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* interpolate other lines of the field */
|
/* interpolate other lines of the field */
|
||||||
y_out = start + ((s->field != cur->top_field_first) ^ (start & 1));
|
y_out = start + ((!tff) ^ (start & 1));
|
||||||
|
|
||||||
out_line = dst_data + (y_out * dst_line_stride);
|
out_line = dst_data + (y_out * dst_line_stride);
|
||||||
|
|
||||||
@ -489,7 +499,8 @@ static int filter(AVFilterContext *ctx, int is_second)
|
|||||||
ctx->internal->execute(ctx, deinterlace_slice, &td, NULL, FFMIN(s->planeheight[plane], s->nb_threads));
|
ctx->internal->execute(ctx, deinterlace_slice, &td, NULL, FFMIN(s->planeheight[plane], s->nb_threads));
|
||||||
}
|
}
|
||||||
|
|
||||||
s->field = !s->field;
|
if (s->mode)
|
||||||
|
s->field = !s->field;
|
||||||
|
|
||||||
return ff_filter_frame(outlink, out);
|
return ff_filter_frame(outlink, out);
|
||||||
}
|
}
|
||||||
@ -526,7 +537,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = filter(ctx, 0);
|
ret = filter(ctx, 0);
|
||||||
if (ret < 0)
|
if (ret < 0 || s->mode == 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return filter(ctx, 1);
|
return filter(ctx, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user