h264_metadata: Add option to delete filler data
[libav.git] / libavfilter / formats.c
1 /*
2 * Filter layer - format negotiation
3 * Copyright (c) 2007 Bobby Bingham
4 *
5 * This file is part of Libav.
6 *
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/common.h"
23 #include "libavutil/pixdesc.h"
24 #include "avfilter.h"
25 #include "internal.h"
26 #include "formats.h"
27
28 /**
29 * Add all refs from a to ret and destroy a.
30 */
31 #define MERGE_REF(ret, a, fmts, type, fail) \
32 do { \
33 type ***tmp; \
34 int i; \
35 \
36 if (!(tmp = av_realloc(ret->refs, \
37 sizeof(*tmp) * (ret->refcount + a->refcount)))) \
38 goto fail; \
39 ret->refs = tmp; \
40 \
41 for (i = 0; i < a->refcount; i ++) { \
42 ret->refs[ret->refcount] = a->refs[i]; \
43 *ret->refs[ret->refcount++] = ret; \
44 } \
45 \
46 av_freep(&a->refs); \
47 av_freep(&a->fmts); \
48 av_freep(&a); \
49 } while (0)
50
51 /**
52 * Add all formats common for a and b to ret, copy the refs and destroy
53 * a and b.
54 */
55 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
56 do { \
57 int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
58 \
59 if (!(ret = av_mallocz(sizeof(*ret)))) \
60 goto fail; \
61 \
62 if (count) { \
63 if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
64 goto fail; \
65 for (i = 0; i < a->nb; i++) \
66 for (j = 0; j < b->nb; j++) \
67 if (a->fmts[i] == b->fmts[j]) \
68 ret->fmts[k++] = a->fmts[i]; \
69 \
70 ret->nb = k; \
71 } \
72 /* check that there was at least one common format */ \
73 if (!ret->nb) \
74 goto fail; \
75 \
76 MERGE_REF(ret, a, fmts, type, fail); \
77 MERGE_REF(ret, b, fmts, type, fail); \
78 } while (0)
79
80 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
81 {
82 AVFilterFormats *ret = NULL;
83
84 if (a == b)
85 return a;
86
87 MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
88
89 return ret;
90 fail:
91 if (ret) {
92 av_freep(&ret->refs);
93 av_freep(&ret->formats);
94 }
95 av_freep(&ret);
96 return NULL;
97 }
98
99 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
100 AVFilterFormats *b)
101 {
102 AVFilterFormats *ret = NULL;
103
104 if (a == b) return a;
105
106 if (a->nb_formats && b->nb_formats) {
107 MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
108 } else if (a->nb_formats) {
109 MERGE_REF(a, b, formats, AVFilterFormats, fail);
110 ret = a;
111 } else {
112 MERGE_REF(b, a, formats, AVFilterFormats, fail);
113 ret = b;
114 }
115
116 return ret;
117 fail:
118 if (ret) {
119 av_freep(&ret->refs);
120 av_freep(&ret->formats);
121 }
122 av_freep(&ret);
123 return NULL;
124 }
125
126 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
127 AVFilterChannelLayouts *b)
128 {
129 AVFilterChannelLayouts *ret = NULL;
130
131 if (a == b) return a;
132
133 if (a->nb_channel_layouts && b->nb_channel_layouts) {
134 MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
135 AVFilterChannelLayouts, fail);
136 } else if (a->nb_channel_layouts) {
137 MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
138 ret = a;
139 } else {
140 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
141 ret = b;
142 }
143
144 return ret;
145 fail:
146 if (ret) {
147 av_freep(&ret->refs);
148 av_freep(&ret->channel_layouts);
149 }
150 av_freep(&ret);
151 return NULL;
152 }
153
154 int ff_fmt_is_in(int fmt, const int *fmts)
155 {
156 const int *p;
157
158 for (p = fmts; *p != AV_PIX_FMT_NONE; p++) {
159 if (fmt == *p)
160 return 1;
161 }
162 return 0;
163 }
164
165 AVFilterFormats *ff_make_format_list(const int *fmts)
166 {
167 AVFilterFormats *formats;
168 int count;
169
170 for (count = 0; fmts[count] != -1; count++)
171 ;
172
173 formats = av_mallocz(sizeof(*formats));
174 if (!formats)
175 return NULL;
176 if (count) {
177 formats->formats = av_malloc(sizeof(*formats->formats) * count);
178 if (!formats->formats) {
179 av_freep(&formats);
180 return NULL;
181 }
182 }
183 formats->nb_formats = count;
184 memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
185
186 return formats;
187 }
188
189 #define ADD_FORMAT(f, fmt, type, list, nb) \
190 do { \
191 type *fmts; \
192 \
193 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
194 return AVERROR(ENOMEM); \
195 \
196 fmts = av_realloc((*f)->list, \
197 sizeof(*(*f)->list) * ((*f)->nb + 1));\
198 if (!fmts) { \
199 av_freep(&f); \
200 return AVERROR(ENOMEM); \
201 } \
202 \
203 (*f)->list = fmts; \
204 (*f)->list[(*f)->nb++] = fmt; \
205 return 0; \
206 } while (0)
207
208 int ff_add_format(AVFilterFormats **avff, int fmt)
209 {
210 ADD_FORMAT(avff, fmt, int, formats, nb_formats);
211 }
212
213 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
214 {
215 ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
216 }
217
218 AVFilterFormats *ff_all_formats(enum AVMediaType type)
219 {
220 AVFilterFormats *ret = NULL;
221
222 if (type == AVMEDIA_TYPE_VIDEO) {
223 const AVPixFmtDescriptor *desc = NULL;
224 while ((desc = av_pix_fmt_desc_next(desc))) {
225 ff_add_format(&ret, av_pix_fmt_desc_get_id(desc));
226 }
227 } else if (type == AVMEDIA_TYPE_AUDIO) {
228 enum AVSampleFormat fmt = 0;
229 while (av_get_sample_fmt_name(fmt)) {
230 ff_add_format(&ret, fmt);
231 fmt++;
232 }
233 }
234
235 return ret;
236 }
237
238 AVFilterFormats *ff_planar_sample_fmts(void)
239 {
240 AVFilterFormats *ret = NULL;
241 int fmt;
242
243 for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
244 if (av_sample_fmt_is_planar(fmt))
245 ff_add_format(&ret, fmt);
246
247 return ret;
248 }
249
250 AVFilterFormats *ff_all_samplerates(void)
251 {
252 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
253 return ret;
254 }
255
256 AVFilterChannelLayouts *ff_all_channel_layouts(void)
257 {
258 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
259 return ret;
260 }
261
262 #define FORMATS_REF(f, ref) \
263 do { \
264 *ref = f; \
265 f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
266 if (!f->refs) \
267 return; \
268 f->refs[f->refcount-1] = ref; \
269 } while (0)
270
271 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
272 {
273 FORMATS_REF(f, ref);
274 }
275
276 void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
277 {
278 FORMATS_REF(f, ref);
279 }
280
281 #define FIND_REF_INDEX(ref, idx) \
282 do { \
283 int i; \
284 for (i = 0; i < (*ref)->refcount; i ++) \
285 if((*ref)->refs[i] == ref) { \
286 idx = i; \
287 break; \
288 } \
289 } while (0)
290
291 #define FORMATS_UNREF(ref, list) \
292 do { \
293 int idx = -1; \
294 \
295 if (!*ref) \
296 return; \
297 \
298 FIND_REF_INDEX(ref, idx); \
299 \
300 if (idx >= 0) \
301 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
302 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
303 \
304 if(!--(*ref)->refcount) { \
305 av_free((*ref)->list); \
306 av_free((*ref)->refs); \
307 av_free(*ref); \
308 } \
309 *ref = NULL; \
310 } while (0)
311
312 void ff_formats_unref(AVFilterFormats **ref)
313 {
314 FORMATS_UNREF(ref, formats);
315 }
316
317 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
318 {
319 FORMATS_UNREF(ref, channel_layouts);
320 }
321
322 #define FORMATS_CHANGEREF(oldref, newref) \
323 do { \
324 int idx = -1; \
325 \
326 FIND_REF_INDEX(oldref, idx); \
327 \
328 if (idx >= 0) { \
329 (*oldref)->refs[idx] = newref; \
330 *newref = *oldref; \
331 *oldref = NULL; \
332 } \
333 } while (0)
334
335 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
336 AVFilterChannelLayouts **newref)
337 {
338 FORMATS_CHANGEREF(oldref, newref);
339 }
340
341 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
342 {
343 FORMATS_CHANGEREF(oldref, newref);
344 }
345
346 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
347 { \
348 int count = 0, i; \
349 \
350 for (i = 0; i < ctx->nb_inputs; i++) { \
351 if (ctx->inputs[i]) { \
352 ref(fmts, &ctx->inputs[i]->out_fmts); \
353 count++; \
354 } \
355 } \
356 for (i = 0; i < ctx->nb_outputs; i++) { \
357 if (ctx->outputs[i]) { \
358 ref(fmts, &ctx->outputs[i]->in_fmts); \
359 count++; \
360 } \
361 } \
362 \
363 if (!count) { \
364 av_freep(&fmts->list); \
365 av_freep(&fmts->refs); \
366 av_freep(&fmts); \
367 } \
368 }
369
370 void ff_set_common_channel_layouts(AVFilterContext *ctx,
371 AVFilterChannelLayouts *layouts)
372 {
373 SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
374 ff_channel_layouts_ref, channel_layouts);
375 }
376
377 void ff_set_common_samplerates(AVFilterContext *ctx,
378 AVFilterFormats *samplerates)
379 {
380 SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
381 ff_formats_ref, formats);
382 }
383
384 /**
385 * A helper for query_formats() which sets all links to the same list of
386 * formats. If there are no links hooked to this filter, the list of formats is
387 * freed.
388 */
389 void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
390 {
391 SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
392 ff_formats_ref, formats);
393 }
394
395 int ff_default_query_formats(AVFilterContext *ctx)
396 {
397 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
398 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
399 AVMEDIA_TYPE_VIDEO;
400
401 ff_set_common_formats(ctx, ff_all_formats(type));
402 if (type == AVMEDIA_TYPE_AUDIO) {
403 ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
404 ff_set_common_samplerates(ctx, ff_all_samplerates());
405 }
406
407 return 0;
408 }