Commit | Line | Data |
---|---|---|
fcbed3c7 SS |
1 | /* |
2 | * copyright (c) 2007 Bobby Bingham | |
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 | /** | |
ba87f080 | 22 | * @file |
dc264e77 | 23 | * format and noformat video filters |
fcbed3c7 SS |
24 | */ |
25 | ||
718c7b18 | 26 | #include "libavutil/pixdesc.h" |
fcbed3c7 SS |
27 | #include "avfilter.h" |
28 | ||
29 | typedef struct { | |
30 | /** | |
31 | * List of flags telling if a given image format has been listed | |
32 | * as argument to the filter. | |
33 | */ | |
34 | int listed_pix_fmt_flags[PIX_FMT_NB]; | |
35 | } FormatContext; | |
36 | ||
37 | #define PIX_FMT_NAME_MAXSIZE 32 | |
38 | ||
39 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | |
40 | { | |
41 | FormatContext *format = ctx->priv; | |
42 | const char *cur, *sep; | |
43 | char pix_fmt_name[PIX_FMT_NAME_MAXSIZE]; | |
44 | int pix_fmt_name_len; | |
45 | enum PixelFormat pix_fmt; | |
46 | ||
47 | /* parse the list of formats */ | |
48 | for (cur = args; cur; cur = sep ? sep+1 : NULL) { | |
49 | if (!(sep = strchr(cur, ':'))) | |
50 | pix_fmt_name_len = strlen(cur); | |
51 | else | |
52 | pix_fmt_name_len = sep - cur; | |
53 | if (pix_fmt_name_len >= PIX_FMT_NAME_MAXSIZE) { | |
54 | av_log(ctx, AV_LOG_ERROR, "Format name too long\n"); | |
55 | return -1; | |
56 | } | |
57 | ||
58 | memcpy(pix_fmt_name, cur, pix_fmt_name_len); | |
59 | pix_fmt_name[pix_fmt_name_len] = 0; | |
718c7b18 | 60 | pix_fmt = av_get_pix_fmt(pix_fmt_name); |
fcbed3c7 SS |
61 | |
62 | if (pix_fmt == PIX_FMT_NONE) { | |
63 | av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name); | |
64 | return -1; | |
65 | } | |
66 | ||
67 | format->listed_pix_fmt_flags[pix_fmt] = 1; | |
68 | } | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | static AVFilterFormats *make_format_list(FormatContext *format, int flag) | |
74 | { | |
75 | AVFilterFormats *formats; | |
76 | enum PixelFormat pix_fmt; | |
77 | ||
78 | formats = av_mallocz(sizeof(AVFilterFormats)); | |
79 | formats->formats = av_malloc(sizeof(enum PixelFormat) * PIX_FMT_NB); | |
80 | ||
81 | for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) | |
82 | if (format->listed_pix_fmt_flags[pix_fmt] == flag) | |
83 | formats->formats[formats->format_count++] = pix_fmt; | |
84 | ||
85 | return formats; | |
86 | } | |
87 | ||
c0bc2fed | 88 | #if CONFIG_FORMAT_FILTER |
55fd1bbc BB |
89 | static int query_formats_format(AVFilterContext *ctx) |
90 | { | |
91 | avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); | |
92 | return 0; | |
93 | } | |
94 | ||
fcbed3c7 SS |
95 | AVFilter avfilter_vf_format = { |
96 | .name = "format", | |
97 | .description = "Convert the input video to one of the specified pixel formats.", | |
98 | ||
99 | .init = init, | |
100 | ||
101 | .query_formats = query_formats_format, | |
102 | ||
103 | .priv_size = sizeof(FormatContext), | |
104 | ||
105 | .inputs = (AVFilterPad[]) {{ .name = "default", | |
72415b2a | 106 | .type = AVMEDIA_TYPE_VIDEO, |
d313e17a BB |
107 | .get_video_buffer= avfilter_null_get_video_buffer, |
108 | .start_frame = avfilter_null_start_frame, | |
109 | .draw_slice = avfilter_null_draw_slice, | |
110 | .end_frame = avfilter_null_end_frame, }, | |
fcbed3c7 SS |
111 | { .name = NULL}}, |
112 | .outputs = (AVFilterPad[]) {{ .name = "default", | |
72415b2a | 113 | .type = AVMEDIA_TYPE_VIDEO }, |
fcbed3c7 SS |
114 | { .name = NULL}}, |
115 | }; | |
c0bc2fed | 116 | #endif /* CONFIG_FORMAT_FILTER */ |
fcbed3c7 | 117 | |
c0bc2fed | 118 | #if CONFIG_NOFORMAT_FILTER |
55fd1bbc BB |
119 | static int query_formats_noformat(AVFilterContext *ctx) |
120 | { | |
121 | avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); | |
122 | return 0; | |
123 | } | |
124 | ||
fcbed3c7 SS |
125 | AVFilter avfilter_vf_noformat = { |
126 | .name = "noformat", | |
09da1781 | 127 | .description = "Force libavfilter not to use any of the specified pixel formats for the input to the next filter.", |
fcbed3c7 SS |
128 | |
129 | .init = init, | |
130 | ||
131 | .query_formats = query_formats_noformat, | |
132 | ||
133 | .priv_size = sizeof(FormatContext), | |
134 | ||
135 | .inputs = (AVFilterPad[]) {{ .name = "default", | |
72415b2a | 136 | .type = AVMEDIA_TYPE_VIDEO, |
d313e17a BB |
137 | .get_video_buffer= avfilter_null_get_video_buffer, |
138 | .start_frame = avfilter_null_start_frame, | |
139 | .draw_slice = avfilter_null_draw_slice, | |
140 | .end_frame = avfilter_null_end_frame, }, | |
fcbed3c7 SS |
141 | { .name = NULL}}, |
142 | .outputs = (AVFilterPad[]) {{ .name = "default", | |
72415b2a | 143 | .type = AVMEDIA_TYPE_VIDEO }, |
fcbed3c7 SS |
144 | { .name = NULL}}, |
145 | }; | |
c0bc2fed BB |
146 | #endif /* CONFIG_NOFORMAT_FILTER */ |
147 |