]> git.sesse.net Git - ffmpeg/blob - libavfilter/vf_setparams.c
avfilter/setparams : merge setfield and setrange filter to setparams filter
[ffmpeg] / libavfilter / vf_setparams.c
1 /*
2  * Copyright (c) 2012 Stefano Sabatini
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "libavutil/pixfmt.h"
22 #include "libavutil/opt.h"
23 #include "avfilter.h"
24 #include "internal.h"
25 #include "video.h"
26
27 enum SetFieldMode {
28     MODE_AUTO = -1,
29     MODE_BFF,
30     MODE_TFF,
31     MODE_PROG,
32 };
33
34 typedef struct SetParamsContext {
35     const AVClass *class;
36     int field_mode;
37     int color_range;
38 } SetParamsContext;
39
40 #define OFFSET(x) offsetof(SetParamsContext, x)
41 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
42
43 static const AVOption setparams_options[] = {
44     {"field_mode", "select interlace mode", OFFSET(field_mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"},
45     {"auto", "keep the same input field",  0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"},
46     {"bff",  "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
47     {"tff",  "mark as top-field-first",    0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
48     {"prog", "mark as progressive",        0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"},
49
50     {"range", "select color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64=-1},-1, AVCOL_RANGE_NB-1, FLAGS, "range"},
51     {"auto",  "keep the same color range",   0, AV_OPT_TYPE_CONST, {.i64=-1},                       0, 0, FLAGS, "range"},
52     {"unspecified",                  NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, FLAGS, "range"},
53     {"unknown",                      NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, FLAGS, "range"},
54     {"limited",                      NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
55     {"tv",                           NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
56     {"mpeg",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
57     {"full",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
58     {"pc",                           NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
59     {"jpeg",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
60     {NULL}
61 };
62
63 AVFILTER_DEFINE_CLASS(setparams);
64
65 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
66 {
67     AVFilterContext *ctx = inlink->dst;
68     SetParamsContext *s = ctx->priv;
69
70     /* set field */
71     if (s->field_mode == MODE_PROG) {
72         frame->interlaced_frame = 0;
73     } else if (s->field_mode != MODE_AUTO) {
74         frame->interlaced_frame = 1;
75         frame->top_field_first = s->field_mode;
76     }
77
78     /* set range */
79     if (s->color_range >= 0)
80         frame->color_range = s->color_range;
81     return ff_filter_frame(ctx->outputs[0], frame);
82 }
83
84 static const AVFilterPad inputs[] = {
85     {
86         .name         = "default",
87         .type         = AVMEDIA_TYPE_VIDEO,
88         .filter_frame = filter_frame,
89     },
90     { NULL }
91 };
92
93 static const AVFilterPad outputs[] = {
94     {
95         .name = "default",
96         .type = AVMEDIA_TYPE_VIDEO,
97     },
98     { NULL }
99 };
100
101 AVFilter ff_vf_setparams = {
102     .name        = "setparams",
103     .description = NULL_IF_CONFIG_SMALL("Force field, or color range for the output video frame."),
104     .priv_size   = sizeof(SetParamsContext),
105     .priv_class  = &setparams_class,
106     .inputs      = inputs,
107     .outputs     = outputs,
108 };
109
110 #if CONFIG_SETRANGE_FILTER
111
112 static const AVOption setrange_options[] = {
113     {"range", "select color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64=-1},-1, AVCOL_RANGE_NB-1, FLAGS, "range"},
114     {"auto",  "keep the same color range",   0, AV_OPT_TYPE_CONST, {.i64=-1},                       0, 0, FLAGS, "range"},
115     {"unspecified",                  NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, FLAGS, "range"},
116     {"unknown",                      NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, FLAGS, "range"},
117     {"limited",                      NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
118     {"tv",                           NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
119     {"mpeg",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, FLAGS, "range"},
120     {"full",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
121     {"pc",                           NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
122     {"jpeg",                         NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, FLAGS, "range"},
123     {NULL}
124 };
125
126 AVFILTER_DEFINE_CLASS(setrange);
127
128 static av_cold int init_setrange(AVFilterContext *ctx)
129 {
130     SetParamsContext *s = ctx->priv;
131
132     s->field_mode = MODE_AUTO;/* set field mode to auto */
133     return 0;
134 }
135
136 AVFilter ff_vf_setrange = {
137     .name        = "setrange",
138     .description = NULL_IF_CONFIG_SMALL("Force color range for the output video frame."),
139     .priv_size   = sizeof(SetParamsContext),
140     .init        = init_setrange,
141     .priv_class  = &setrange_class,
142     .inputs      = inputs,
143     .outputs     = outputs,
144 };
145 #endif /* CONFIG_SETRANGE_FILTER */
146
147 #if CONFIG_SETFIELD_FILTER
148 static const AVOption setfield_options[] = {
149     {"mode", "select interlace mode", OFFSET(field_mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"},
150     {"auto", "keep the same input field",  0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"},
151     {"bff",  "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
152     {"tff",  "mark as top-field-first",    0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
153     {"prog", "mark as progressive",        0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"},
154     {NULL}
155 };
156
157 AVFILTER_DEFINE_CLASS(setfield);
158
159 static av_cold int init_setfield(AVFilterContext *ctx)
160 {
161     SetParamsContext *s = ctx->priv;
162
163     s->color_range = -1;/* set range mode to auto */
164     return 0;
165 }
166
167 AVFilter ff_vf_setfield = {
168     .name        = "setfield",
169     .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
170     .priv_size   = sizeof(SetParamsContext),
171     .init        = init_setfield,
172     .priv_class  = &setfield_class,
173     .inputs      = inputs,
174     .outputs     = outputs,
175 };
176 #endif /* CONFIG_SETFIELD_FILTER */