FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vf_format.c
Go to the documentation of this file.
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 /**
22  * @file
23  * format and noformat video filters
24  */
25 
26 #include <string.h>
27 
28 #include "libavutil/internal.h"
29 #include "libavutil/mem.h"
30 #include "libavutil/pixdesc.h"
31 #include "libavutil/opt.h"
32 
33 #include "avfilter.h"
34 #include "internal.h"
35 #include "formats.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 typedef struct {
40  const AVClass *class;
41  char *pix_fmts;
42  /**
43  * List of flags telling if a given image format has been listed
44  * as argument to the filter.
45  */
46  int listed_pix_fmt_flags[AV_PIX_FMT_NB];
48 
49 #define AV_PIX_FMT_NAME_MAXSIZE 32
50 
51 static av_cold int init(AVFilterContext *ctx)
52 {
53  FormatContext *s = ctx->priv;
54  const char *cur, *sep;
55  char pix_fmt_name[AV_PIX_FMT_NAME_MAXSIZE];
56  int pix_fmt_name_len, ret;
58 
59  /* parse the list of formats */
60  for (cur = s->pix_fmts; cur; cur = sep ? sep + 1 : NULL) {
61  if (!(sep = strchr(cur, '|')))
62  pix_fmt_name_len = strlen(cur);
63  else
64  pix_fmt_name_len = sep - cur;
65  if (pix_fmt_name_len >= AV_PIX_FMT_NAME_MAXSIZE) {
66  av_log(ctx, AV_LOG_ERROR, "Format name too long\n");
67  return -1;
68  }
69 
70  memcpy(pix_fmt_name, cur, pix_fmt_name_len);
71  pix_fmt_name[pix_fmt_name_len] = 0;
72 
73  if ((ret = ff_parse_pixel_format(&pix_fmt, pix_fmt_name, ctx)) < 0)
74  return ret;
75 
77  }
78 
79  return 0;
80 }
81 
83 {
84  AVFilterFormats *formats = NULL;
86 
87  for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
88  if (s->listed_pix_fmt_flags[pix_fmt] == flag) {
89  int ret = ff_add_format(&formats, pix_fmt);
90  if (ret < 0) {
91  ff_formats_unref(&formats);
92  return NULL;
93  }
94  }
95 
96  return formats;
97 }
98 
99 #define OFFSET(x) offsetof(FormatContext, x)
100 static const AVOption options[] = {
101  { "pix_fmts", "A '|'-separated list of pixel formats", OFFSET(pix_fmts), AV_OPT_TYPE_STRING, .flags = AV_OPT_FLAG_VIDEO_PARAM },
102  { NULL },
103 };
104 
105 #if CONFIG_FORMAT_FILTER
106 static int query_formats_format(AVFilterContext *ctx)
107 {
109  return 0;
110 }
111 
112 #define format_options options
113 AVFILTER_DEFINE_CLASS(format);
114 
115 static const AVFilterPad avfilter_vf_format_inputs[] = {
116  {
117  .name = "default",
118  .type = AVMEDIA_TYPE_VIDEO,
119  .get_video_buffer = ff_null_get_video_buffer,
120  },
121  { NULL }
122 };
123 
124 static const AVFilterPad avfilter_vf_format_outputs[] = {
125  {
126  .name = "default",
127  .type = AVMEDIA_TYPE_VIDEO
128  },
129  { NULL }
130 };
131 
132 AVFilter avfilter_vf_format = {
133  .name = "format",
134  .description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."),
135 
136  .init = init,
137 
138  .query_formats = query_formats_format,
139 
140  .priv_size = sizeof(FormatContext),
141  .priv_class = &format_class,
142 
143  .inputs = avfilter_vf_format_inputs,
144  .outputs = avfilter_vf_format_outputs,
145 };
146 #endif /* CONFIG_FORMAT_FILTER */
147 
148 #if CONFIG_NOFORMAT_FILTER
149 static int query_formats_noformat(AVFilterContext *ctx)
150 {
152  return 0;
153 }
154 
155 #define noformat_options options
156 AVFILTER_DEFINE_CLASS(noformat);
157 
158 static const AVFilterPad avfilter_vf_noformat_inputs[] = {
159  {
160  .name = "default",
161  .type = AVMEDIA_TYPE_VIDEO,
162  .get_video_buffer = ff_null_get_video_buffer,
163  },
164  { NULL }
165 };
166 
167 static const AVFilterPad avfilter_vf_noformat_outputs[] = {
168  {
169  .name = "default",
170  .type = AVMEDIA_TYPE_VIDEO
171  },
172  { NULL }
173 };
174 
175 AVFilter avfilter_vf_noformat = {
176  .name = "noformat",
177  .description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."),
178 
179  .init = init,
180 
181  .query_formats = query_formats_noformat,
182 
183  .priv_size = sizeof(FormatContext),
184  .priv_class = &noformat_class,
185 
186  .inputs = avfilter_vf_noformat_inputs,
187  .outputs = avfilter_vf_noformat_outputs,
188 };
189 #endif /* CONFIG_NOFORMAT_FILTER */