mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-04 06:08:26 +02:00
avfilter/vf_fieldhint: add pattern mode of filtering
This commit is contained in:
parent
c0f49378a9
commit
1ab83dd369
@ -12318,7 +12318,9 @@ case of @code{b} it will use only bottom field.
|
|||||||
If line starts with @code{#} or @code{;} that line is skipped.
|
If line starts with @code{#} or @code{;} that line is skipped.
|
||||||
|
|
||||||
@item mode
|
@item mode
|
||||||
Can be item @code{absolute} or @code{relative}. Default is @code{absolute}.
|
Can be item @code{absolute} or @code{relative} or @code{pattern}. Default is @code{absolute}.
|
||||||
|
The @code{pattern} mode is same as @code{relative} mode, except at last entry of file if there
|
||||||
|
are more frames to process than @code{hint} file is seek back to start.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Example of first several lines of @code{hint} file for @code{relative} mode:
|
Example of first several lines of @code{hint} file for @code{relative} mode:
|
||||||
|
@ -27,6 +27,13 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
enum HintModes {
|
||||||
|
ABSOLUTE_HINT,
|
||||||
|
RELATIVE_HINT,
|
||||||
|
PATTERN_HINT,
|
||||||
|
NB_HINTS,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct FieldHintContext {
|
typedef struct FieldHintContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
|
|
||||||
@ -48,9 +55,10 @@ typedef struct FieldHintContext {
|
|||||||
|
|
||||||
static const AVOption fieldhint_options[] = {
|
static const AVOption fieldhint_options[] = {
|
||||||
{ "hint", "set hint file", OFFSET(hint_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
|
{ "hint", "set hint file", OFFSET(hint_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
|
||||||
{ "mode", "set hint mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "mode" },
|
{ "mode", "set hint mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_HINTS-1, FLAGS, "mode" },
|
||||||
{ "absolute", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" },
|
{ "absolute", 0, 0, AV_OPT_TYPE_CONST, {.i64=ABSOLUTE_HINT}, 0, 0, FLAGS, "mode" },
|
||||||
{ "relative", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" },
|
{ "relative", 0, 0, AV_OPT_TYPE_CONST, {.i64=RELATIVE_HINT}, 0, 0, FLAGS, "mode" },
|
||||||
|
{ "pattern", 0, 0, AV_OPT_TYPE_CONST, {.i64=PATTERN_HINT}, 0, 0, FLAGS, "mode" },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,22 +149,30 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
switch (s->mode) {
|
switch (s->mode) {
|
||||||
case 0:
|
case ABSOLUTE_HINT:
|
||||||
if (tf > outlink->frame_count_in + 1 || tf < FFMAX(0, outlink->frame_count_in - 1) ||
|
if (tf > outlink->frame_count_in + 1 || tf < FFMAX(0, outlink->frame_count_in - 1) ||
|
||||||
bf > outlink->frame_count_in + 1 || bf < FFMAX(0, outlink->frame_count_in - 1)) {
|
bf > outlink->frame_count_in + 1 || bf < FFMAX(0, outlink->frame_count_in - 1)) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Out of range frames %"PRId64" and/or %"PRId64" on line %"PRId64" for %"PRId64". input frame.\n", tf, bf, s->line, inlink->frame_count_out);
|
av_log(ctx, AV_LOG_ERROR, "Out of range frames %"PRId64" and/or %"PRId64" on line %"PRId64" for %"PRId64". input frame.\n", tf, bf, s->line, inlink->frame_count_out);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case PATTERN_HINT:
|
||||||
|
case RELATIVE_HINT:
|
||||||
if (tf > 1 || tf < -1 ||
|
if (tf > 1 || tf < -1 ||
|
||||||
bf > 1 || bf < -1) {
|
bf > 1 || bf < -1) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Out of range %"PRId64" and/or %"PRId64" on line %"PRId64" for %"PRId64". input frame.\n", tf, bf, s->line, inlink->frame_count_out);
|
av_log(ctx, AV_LOG_ERROR, "Out of range %"PRId64" and/or %"PRId64" on line %"PRId64" for %"PRId64". input frame.\n", tf, bf, s->line, inlink->frame_count_out);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return AVERROR_BUG;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
if (s->mode == PATTERN_HINT) {
|
||||||
|
fseek(s->hint, 0, SEEK_SET);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
av_log(ctx, AV_LOG_ERROR, "Missing entry for %"PRId64". input frame.\n", inlink->frame_count_out);
|
av_log(ctx, AV_LOG_ERROR, "Missing entry for %"PRId64". input frame.\n", inlink->frame_count_out);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
@ -168,11 +184,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
av_frame_copy_props(out, s->frame[1]);
|
av_frame_copy_props(out, s->frame[1]);
|
||||||
|
|
||||||
switch (s->mode) {
|
switch (s->mode) {
|
||||||
case 0:
|
case ABSOLUTE_HINT:
|
||||||
top = s->frame[tf - outlink->frame_count_in + 1];
|
top = s->frame[tf - outlink->frame_count_in + 1];
|
||||||
bottom = s->frame[bf - outlink->frame_count_in + 1];
|
bottom = s->frame[bf - outlink->frame_count_in + 1];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case PATTERN_HINT:
|
||||||
|
case RELATIVE_HINT:
|
||||||
top = s->frame[1 + tf];
|
top = s->frame[1 + tf];
|
||||||
bottom = s->frame[1 + bf];
|
bottom = s->frame[1 + bf];
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user