00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libavutil/opt.h"
00027 #include "avfilter.h"
00028 #include "internal.h"
00029 #include "video.h"
00030
00031 enum SetFieldMode {
00032 MODE_AUTO = -1,
00033 MODE_BFF,
00034 MODE_TFF,
00035 MODE_PROG,
00036 };
00037
00038 typedef struct {
00039 const AVClass *class;
00040 enum SetFieldMode mode;
00041 } SetFieldContext;
00042
00043 #define OFFSET(x) offsetof(SetFieldContext, x)
00044 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
00045
00046 static const AVOption setfield_options[] = {
00047 {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"},
00048 {"auto", "keep the same input field", 0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"},
00049 {"bff", "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF}, INT_MIN, INT_MAX, FLAGS, "mode"},
00050 {"tff", "mark as top-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF}, INT_MIN, INT_MAX, FLAGS, "mode"},
00051 {"prog", "mark as progressive", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"},
00052 {NULL}
00053 };
00054
00055 AVFILTER_DEFINE_CLASS(setfield);
00056
00057 static av_cold int init(AVFilterContext *ctx, const char *args)
00058 {
00059 SetFieldContext *setfield = ctx->priv;
00060 static const char *shorthand[] = { "mode", NULL };
00061
00062 setfield->class = &setfield_class;
00063 av_opt_set_defaults(setfield);
00064
00065 return av_opt_set_from_string(setfield, args, shorthand, "=", ":");
00066 }
00067
00068 static av_cold void uninit(AVFilterContext *ctx)
00069 {
00070 SetFieldContext *setfield = ctx->priv;
00071 av_opt_free(setfield);
00072 }
00073
00074 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
00075 {
00076 SetFieldContext *setfield = inlink->dst->priv;
00077
00078 if (setfield->mode == MODE_PROG) {
00079 picref->video->interlaced = 0;
00080 } else if (setfield->mode != MODE_AUTO) {
00081 picref->video->interlaced = 1;
00082 picref->video->top_field_first = setfield->mode;
00083 }
00084 return ff_filter_frame(inlink->dst->outputs[0], picref);
00085 }
00086
00087 static const AVFilterPad setfield_inputs[] = {
00088 {
00089 .name = "default",
00090 .type = AVMEDIA_TYPE_VIDEO,
00091 .get_video_buffer = ff_null_get_video_buffer,
00092 .filter_frame = filter_frame,
00093 },
00094 { NULL }
00095 };
00096
00097 static const AVFilterPad setfield_outputs[] = {
00098 {
00099 .name = "default",
00100 .type = AVMEDIA_TYPE_VIDEO,
00101 },
00102 { NULL }
00103 };
00104
00105 AVFilter avfilter_vf_setfield = {
00106 .name = "setfield",
00107 .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
00108 .init = init,
00109 .uninit = uninit,
00110
00111 .priv_size = sizeof(SetFieldContext),
00112 .inputs = setfield_inputs,
00113 .outputs = setfield_outputs,
00114 .priv_class = &setfield_class,
00115 };