yading@10
|
1 /*
|
yading@10
|
2 * Filter layer - format negotiation
|
yading@10
|
3 * Copyright (c) 2007 Bobby Bingham
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 #include "libavutil/avassert.h"
|
yading@10
|
23 #include "libavutil/channel_layout.h"
|
yading@10
|
24 #include "libavutil/common.h"
|
yading@10
|
25 #include "libavutil/eval.h"
|
yading@10
|
26 #include "libavutil/pixdesc.h"
|
yading@10
|
27 #include "libavutil/parseutils.h"
|
yading@10
|
28 #include "avfilter.h"
|
yading@10
|
29 #include "internal.h"
|
yading@10
|
30 #include "formats.h"
|
yading@10
|
31
|
yading@10
|
32 #define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */
|
yading@10
|
33
|
yading@10
|
34 /**
|
yading@10
|
35 * Add all refs from a to ret and destroy a.
|
yading@10
|
36 */
|
yading@10
|
37 #define MERGE_REF(ret, a, fmts, type, fail) \
|
yading@10
|
38 do { \
|
yading@10
|
39 type ***tmp; \
|
yading@10
|
40 int i; \
|
yading@10
|
41 \
|
yading@10
|
42 if (!(tmp = av_realloc(ret->refs, \
|
yading@10
|
43 sizeof(*tmp) * (ret->refcount + a->refcount)))) \
|
yading@10
|
44 goto fail; \
|
yading@10
|
45 ret->refs = tmp; \
|
yading@10
|
46 \
|
yading@10
|
47 for (i = 0; i < a->refcount; i ++) { \
|
yading@10
|
48 ret->refs[ret->refcount] = a->refs[i]; \
|
yading@10
|
49 *ret->refs[ret->refcount++] = ret; \
|
yading@10
|
50 } \
|
yading@10
|
51 \
|
yading@10
|
52 av_freep(&a->refs); \
|
yading@10
|
53 av_freep(&a->fmts); \
|
yading@10
|
54 av_freep(&a); \
|
yading@10
|
55 } while (0)
|
yading@10
|
56
|
yading@10
|
57 /**
|
yading@10
|
58 * Add all formats common for a and b to ret, copy the refs and destroy
|
yading@10
|
59 * a and b.
|
yading@10
|
60 */
|
yading@10
|
61 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
|
yading@10
|
62 do { \
|
yading@10
|
63 int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
|
yading@10
|
64 \
|
yading@10
|
65 if (!(ret = av_mallocz(sizeof(*ret)))) \
|
yading@10
|
66 goto fail; \
|
yading@10
|
67 \
|
yading@10
|
68 if (count) { \
|
yading@10
|
69 if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
|
yading@10
|
70 goto fail; \
|
yading@10
|
71 for (i = 0; i < a->nb; i++) \
|
yading@10
|
72 for (j = 0; j < b->nb; j++) \
|
yading@10
|
73 if (a->fmts[i] == b->fmts[j]) { \
|
yading@10
|
74 if(k >= FFMIN(a->nb, b->nb)){ \
|
yading@10
|
75 av_log(NULL, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \
|
yading@10
|
76 av_free(ret->fmts); \
|
yading@10
|
77 av_free(ret); \
|
yading@10
|
78 return NULL; \
|
yading@10
|
79 } \
|
yading@10
|
80 ret->fmts[k++] = a->fmts[i]; \
|
yading@10
|
81 } \
|
yading@10
|
82 } \
|
yading@10
|
83 ret->nb = k; \
|
yading@10
|
84 /* check that there was at least one common format */ \
|
yading@10
|
85 if (!ret->nb) \
|
yading@10
|
86 goto fail; \
|
yading@10
|
87 \
|
yading@10
|
88 MERGE_REF(ret, a, fmts, type, fail); \
|
yading@10
|
89 MERGE_REF(ret, b, fmts, type, fail); \
|
yading@10
|
90 } while (0)
|
yading@10
|
91
|
yading@10
|
92 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
|
yading@10
|
93 enum AVMediaType type)
|
yading@10
|
94 {
|
yading@10
|
95 AVFilterFormats *ret = NULL;
|
yading@10
|
96 int i, j;
|
yading@10
|
97 int alpha1=0, alpha2=0;
|
yading@10
|
98 int chroma1=0, chroma2=0;
|
yading@10
|
99
|
yading@10
|
100 if (a == b)
|
yading@10
|
101 return a;
|
yading@10
|
102
|
yading@10
|
103 /* Do not lose chroma or alpha in merging.
|
yading@10
|
104 It happens if both lists have formats with chroma (resp. alpha), but
|
yading@10
|
105 the only formats in common do not have it (e.g. YUV+gray vs.
|
yading@10
|
106 RGB+gray): in that case, the merging would select the gray format,
|
yading@10
|
107 possibly causing a lossy conversion elsewhere in the graph.
|
yading@10
|
108 To avoid that, pretend that there are no common formats to force the
|
yading@10
|
109 insertion of a conversion filter. */
|
yading@10
|
110 if (type == AVMEDIA_TYPE_VIDEO)
|
yading@10
|
111 for (i = 0; i < a->format_count; i++)
|
yading@10
|
112 for (j = 0; j < b->format_count; j++) {
|
yading@10
|
113 const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
|
yading@10
|
114 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
|
yading@10
|
115 alpha2 |= adesc->flags & bdesc->flags & PIX_FMT_ALPHA;
|
yading@10
|
116 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
|
yading@10
|
117 if (a->formats[i] == b->formats[j]) {
|
yading@10
|
118 alpha1 |= adesc->flags & PIX_FMT_ALPHA;
|
yading@10
|
119 chroma1|= adesc->nb_components > 1;
|
yading@10
|
120 }
|
yading@10
|
121 }
|
yading@10
|
122
|
yading@10
|
123 // If chroma or alpha can be lost through merging then do not merge
|
yading@10
|
124 if (alpha2 > alpha1 || chroma2 > chroma1)
|
yading@10
|
125 return NULL;
|
yading@10
|
126
|
yading@10
|
127 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
|
yading@10
|
128
|
yading@10
|
129 return ret;
|
yading@10
|
130 fail:
|
yading@10
|
131 if (ret) {
|
yading@10
|
132 av_freep(&ret->refs);
|
yading@10
|
133 av_freep(&ret->formats);
|
yading@10
|
134 }
|
yading@10
|
135 av_freep(&ret);
|
yading@10
|
136 return NULL;
|
yading@10
|
137 }
|
yading@10
|
138
|
yading@10
|
139 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
|
yading@10
|
140 AVFilterFormats *b)
|
yading@10
|
141 {
|
yading@10
|
142 AVFilterFormats *ret = NULL;
|
yading@10
|
143
|
yading@10
|
144 if (a == b) return a;
|
yading@10
|
145
|
yading@10
|
146 if (a->format_count && b->format_count) {
|
yading@10
|
147 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
|
yading@10
|
148 } else if (a->format_count) {
|
yading@10
|
149 MERGE_REF(a, b, formats, AVFilterFormats, fail);
|
yading@10
|
150 ret = a;
|
yading@10
|
151 } else {
|
yading@10
|
152 MERGE_REF(b, a, formats, AVFilterFormats, fail);
|
yading@10
|
153 ret = b;
|
yading@10
|
154 }
|
yading@10
|
155
|
yading@10
|
156 return ret;
|
yading@10
|
157 fail:
|
yading@10
|
158 if (ret) {
|
yading@10
|
159 av_freep(&ret->refs);
|
yading@10
|
160 av_freep(&ret->formats);
|
yading@10
|
161 }
|
yading@10
|
162 av_freep(&ret);
|
yading@10
|
163 return NULL;
|
yading@10
|
164 }
|
yading@10
|
165
|
yading@10
|
166 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
|
yading@10
|
167 AVFilterChannelLayouts *b)
|
yading@10
|
168 {
|
yading@10
|
169 AVFilterChannelLayouts *ret = NULL;
|
yading@10
|
170 unsigned a_all = a->all_layouts + a->all_counts;
|
yading@10
|
171 unsigned b_all = b->all_layouts + b->all_counts;
|
yading@10
|
172 int ret_max, ret_nb = 0, i, j, round;
|
yading@10
|
173
|
yading@10
|
174 if (a == b) return a;
|
yading@10
|
175
|
yading@10
|
176 /* Put the most generic set in a, to avoid doing everything twice */
|
yading@10
|
177 if (a_all < b_all) {
|
yading@10
|
178 FFSWAP(AVFilterChannelLayouts *, a, b);
|
yading@10
|
179 FFSWAP(unsigned, a_all, b_all);
|
yading@10
|
180 }
|
yading@10
|
181 if (a_all) {
|
yading@10
|
182 if (a_all == 1 && !b_all) {
|
yading@10
|
183 /* keep only known layouts in b; works also for b_all = 1 */
|
yading@10
|
184 for (i = j = 0; i < b->nb_channel_layouts; i++)
|
yading@10
|
185 if (KNOWN(b->channel_layouts[i]))
|
yading@10
|
186 b->channel_layouts[j++] = b->channel_layouts[i];
|
yading@10
|
187 /* Not optimal: the unknown layouts of b may become known after
|
yading@10
|
188 another merge. */
|
yading@10
|
189 if (!j)
|
yading@10
|
190 return NULL;
|
yading@10
|
191 b->nb_channel_layouts = j;
|
yading@10
|
192 }
|
yading@10
|
193 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
|
yading@10
|
194 return b;
|
yading@10
|
195 }
|
yading@10
|
196
|
yading@10
|
197 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
|
yading@10
|
198 if (!(ret = av_mallocz(sizeof(*ret))) ||
|
yading@10
|
199 !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) *
|
yading@10
|
200 ret_max)))
|
yading@10
|
201 goto fail;
|
yading@10
|
202
|
yading@10
|
203 /* a[known] intersect b[known] */
|
yading@10
|
204 for (i = 0; i < a->nb_channel_layouts; i++) {
|
yading@10
|
205 if (!KNOWN(a->channel_layouts[i]))
|
yading@10
|
206 continue;
|
yading@10
|
207 for (j = 0; j < b->nb_channel_layouts; j++) {
|
yading@10
|
208 if (a->channel_layouts[i] == b->channel_layouts[j]) {
|
yading@10
|
209 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
|
yading@10
|
210 a->channel_layouts[i] = b->channel_layouts[j] = 0;
|
yading@10
|
211 }
|
yading@10
|
212 }
|
yading@10
|
213 }
|
yading@10
|
214 /* 1st round: a[known] intersect b[generic]
|
yading@10
|
215 2nd round: a[generic] intersect b[known] */
|
yading@10
|
216 for (round = 0; round < 2; round++) {
|
yading@10
|
217 for (i = 0; i < a->nb_channel_layouts; i++) {
|
yading@10
|
218 uint64_t fmt = a->channel_layouts[i], bfmt;
|
yading@10
|
219 if (!fmt || !KNOWN(fmt))
|
yading@10
|
220 continue;
|
yading@10
|
221 bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
|
yading@10
|
222 for (j = 0; j < b->nb_channel_layouts; j++)
|
yading@10
|
223 if (b->channel_layouts[j] == bfmt)
|
yading@10
|
224 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
|
yading@10
|
225 }
|
yading@10
|
226 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
|
yading@10
|
227 FFSWAP(AVFilterChannelLayouts *, a, b);
|
yading@10
|
228 }
|
yading@10
|
229 /* a[generic] intersect b[generic] */
|
yading@10
|
230 for (i = 0; i < a->nb_channel_layouts; i++) {
|
yading@10
|
231 if (KNOWN(a->channel_layouts[i]))
|
yading@10
|
232 continue;
|
yading@10
|
233 for (j = 0; j < b->nb_channel_layouts; j++)
|
yading@10
|
234 if (a->channel_layouts[i] == b->channel_layouts[j])
|
yading@10
|
235 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
|
yading@10
|
236 }
|
yading@10
|
237
|
yading@10
|
238 ret->nb_channel_layouts = ret_nb;
|
yading@10
|
239 if (!ret->nb_channel_layouts)
|
yading@10
|
240 goto fail;
|
yading@10
|
241 MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail);
|
yading@10
|
242 MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail);
|
yading@10
|
243 return ret;
|
yading@10
|
244
|
yading@10
|
245 fail:
|
yading@10
|
246 if (ret) {
|
yading@10
|
247 av_freep(&ret->refs);
|
yading@10
|
248 av_freep(&ret->channel_layouts);
|
yading@10
|
249 }
|
yading@10
|
250 av_freep(&ret);
|
yading@10
|
251 return NULL;
|
yading@10
|
252 }
|
yading@10
|
253
|
yading@10
|
254 int ff_fmt_is_in(int fmt, const int *fmts)
|
yading@10
|
255 {
|
yading@10
|
256 const int *p;
|
yading@10
|
257
|
yading@10
|
258 for (p = fmts; *p != -1; p++) {
|
yading@10
|
259 if (fmt == *p)
|
yading@10
|
260 return 1;
|
yading@10
|
261 }
|
yading@10
|
262 return 0;
|
yading@10
|
263 }
|
yading@10
|
264
|
yading@10
|
265 #define COPY_INT_LIST(list_copy, list, type) { \
|
yading@10
|
266 int count = 0; \
|
yading@10
|
267 if (list) \
|
yading@10
|
268 for (count = 0; list[count] != -1; count++) \
|
yading@10
|
269 ; \
|
yading@10
|
270 list_copy = av_calloc(count+1, sizeof(type)); \
|
yading@10
|
271 if (list_copy) { \
|
yading@10
|
272 memcpy(list_copy, list, sizeof(type) * count); \
|
yading@10
|
273 list_copy[count] = -1; \
|
yading@10
|
274 } \
|
yading@10
|
275 }
|
yading@10
|
276
|
yading@10
|
277 int *ff_copy_int_list(const int * const list)
|
yading@10
|
278 {
|
yading@10
|
279 int *ret = NULL;
|
yading@10
|
280 COPY_INT_LIST(ret, list, int);
|
yading@10
|
281 return ret;
|
yading@10
|
282 }
|
yading@10
|
283
|
yading@10
|
284 int64_t *ff_copy_int64_list(const int64_t * const list)
|
yading@10
|
285 {
|
yading@10
|
286 int64_t *ret = NULL;
|
yading@10
|
287 COPY_INT_LIST(ret, list, int64_t);
|
yading@10
|
288 return ret;
|
yading@10
|
289 }
|
yading@10
|
290
|
yading@10
|
291 #define MAKE_FORMAT_LIST(type, field, count_field) \
|
yading@10
|
292 type *formats; \
|
yading@10
|
293 int count = 0; \
|
yading@10
|
294 if (fmts) \
|
yading@10
|
295 for (count = 0; fmts[count] != -1; count++) \
|
yading@10
|
296 ; \
|
yading@10
|
297 formats = av_mallocz(sizeof(*formats)); \
|
yading@10
|
298 if (!formats) return NULL; \
|
yading@10
|
299 formats->count_field = count; \
|
yading@10
|
300 if (count) { \
|
yading@10
|
301 formats->field = av_malloc(sizeof(*formats->field)*count); \
|
yading@10
|
302 if (!formats->field) { \
|
yading@10
|
303 av_free(formats); \
|
yading@10
|
304 return NULL; \
|
yading@10
|
305 } \
|
yading@10
|
306 }
|
yading@10
|
307
|
yading@10
|
308 AVFilterFormats *ff_make_format_list(const int *fmts)
|
yading@10
|
309 {
|
yading@10
|
310 MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
|
yading@10
|
311 while (count--)
|
yading@10
|
312 formats->formats[count] = fmts[count];
|
yading@10
|
313
|
yading@10
|
314 return formats;
|
yading@10
|
315 }
|
yading@10
|
316
|
yading@10
|
317 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
|
yading@10
|
318 {
|
yading@10
|
319 MAKE_FORMAT_LIST(AVFilterChannelLayouts,
|
yading@10
|
320 channel_layouts, nb_channel_layouts);
|
yading@10
|
321 if (count)
|
yading@10
|
322 memcpy(formats->channel_layouts, fmts,
|
yading@10
|
323 sizeof(*formats->channel_layouts) * count);
|
yading@10
|
324
|
yading@10
|
325 return formats;
|
yading@10
|
326 }
|
yading@10
|
327
|
yading@10
|
328 #define ADD_FORMAT(f, fmt, type, list, nb) \
|
yading@10
|
329 do { \
|
yading@10
|
330 type *fmts; \
|
yading@10
|
331 \
|
yading@10
|
332 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
|
yading@10
|
333 return AVERROR(ENOMEM); \
|
yading@10
|
334 \
|
yading@10
|
335 fmts = av_realloc((*f)->list, \
|
yading@10
|
336 sizeof(*(*f)->list) * ((*f)->nb + 1));\
|
yading@10
|
337 if (!fmts) \
|
yading@10
|
338 return AVERROR(ENOMEM); \
|
yading@10
|
339 \
|
yading@10
|
340 (*f)->list = fmts; \
|
yading@10
|
341 (*f)->list[(*f)->nb++] = fmt; \
|
yading@10
|
342 } while (0)
|
yading@10
|
343
|
yading@10
|
344 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
|
yading@10
|
345 {
|
yading@10
|
346 ADD_FORMAT(avff, fmt, int, formats, format_count);
|
yading@10
|
347 return 0;
|
yading@10
|
348 }
|
yading@10
|
349
|
yading@10
|
350 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
|
yading@10
|
351 {
|
yading@10
|
352 av_assert1(!(*l && (*l)->all_layouts));
|
yading@10
|
353 ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
|
yading@10
|
354 return 0;
|
yading@10
|
355 }
|
yading@10
|
356
|
yading@10
|
357 AVFilterFormats *ff_all_formats(enum AVMediaType type)
|
yading@10
|
358 {
|
yading@10
|
359 AVFilterFormats *ret = NULL;
|
yading@10
|
360 int fmt;
|
yading@10
|
361 int num_formats = type == AVMEDIA_TYPE_VIDEO ? AV_PIX_FMT_NB :
|
yading@10
|
362 type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
|
yading@10
|
363
|
yading@10
|
364 for (fmt = 0; fmt < num_formats; fmt++) {
|
yading@10
|
365 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
|
yading@10
|
366 if ((type != AVMEDIA_TYPE_VIDEO) ||
|
yading@10
|
367 (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
|
yading@10
|
368 ff_add_format(&ret, fmt);
|
yading@10
|
369 }
|
yading@10
|
370
|
yading@10
|
371 return ret;
|
yading@10
|
372 }
|
yading@10
|
373
|
yading@10
|
374 const int64_t avfilter_all_channel_layouts[] = {
|
yading@10
|
375 #include "all_channel_layouts.inc"
|
yading@10
|
376 -1
|
yading@10
|
377 };
|
yading@10
|
378
|
yading@10
|
379 // AVFilterFormats *avfilter_make_all_channel_layouts(void)
|
yading@10
|
380 // {
|
yading@10
|
381 // return avfilter_make_format64_list(avfilter_all_channel_layouts);
|
yading@10
|
382 // }
|
yading@10
|
383
|
yading@10
|
384 AVFilterFormats *ff_planar_sample_fmts(void)
|
yading@10
|
385 {
|
yading@10
|
386 AVFilterFormats *ret = NULL;
|
yading@10
|
387 int fmt;
|
yading@10
|
388
|
yading@10
|
389 for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
|
yading@10
|
390 if (av_sample_fmt_is_planar(fmt))
|
yading@10
|
391 ff_add_format(&ret, fmt);
|
yading@10
|
392
|
yading@10
|
393 return ret;
|
yading@10
|
394 }
|
yading@10
|
395
|
yading@10
|
396 AVFilterFormats *ff_all_samplerates(void)
|
yading@10
|
397 {
|
yading@10
|
398 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
|
yading@10
|
399 return ret;
|
yading@10
|
400 }
|
yading@10
|
401
|
yading@10
|
402 AVFilterChannelLayouts *ff_all_channel_layouts(void)
|
yading@10
|
403 {
|
yading@10
|
404 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
|
yading@10
|
405 if (!ret)
|
yading@10
|
406 return NULL;
|
yading@10
|
407 ret->all_layouts = 1;
|
yading@10
|
408 return ret;
|
yading@10
|
409 }
|
yading@10
|
410
|
yading@10
|
411 AVFilterChannelLayouts *ff_all_channel_counts(void)
|
yading@10
|
412 {
|
yading@10
|
413 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
|
yading@10
|
414 if (!ret)
|
yading@10
|
415 return NULL;
|
yading@10
|
416 ret->all_layouts = ret->all_counts = 1;
|
yading@10
|
417 return ret;
|
yading@10
|
418 }
|
yading@10
|
419
|
yading@10
|
420 #define FORMATS_REF(f, ref) \
|
yading@10
|
421 do { \
|
yading@10
|
422 *ref = f; \
|
yading@10
|
423 f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
|
yading@10
|
424 f->refs[f->refcount-1] = ref; \
|
yading@10
|
425 } while (0)
|
yading@10
|
426
|
yading@10
|
427 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
|
yading@10
|
428 {
|
yading@10
|
429 FORMATS_REF(f, ref);
|
yading@10
|
430 }
|
yading@10
|
431
|
yading@10
|
432 void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
|
yading@10
|
433 {
|
yading@10
|
434 FORMATS_REF(f, ref);
|
yading@10
|
435 }
|
yading@10
|
436
|
yading@10
|
437 #define FIND_REF_INDEX(ref, idx) \
|
yading@10
|
438 do { \
|
yading@10
|
439 int i; \
|
yading@10
|
440 for (i = 0; i < (*ref)->refcount; i ++) \
|
yading@10
|
441 if((*ref)->refs[i] == ref) { \
|
yading@10
|
442 idx = i; \
|
yading@10
|
443 break; \
|
yading@10
|
444 } \
|
yading@10
|
445 } while (0)
|
yading@10
|
446
|
yading@10
|
447 #define FORMATS_UNREF(ref, list) \
|
yading@10
|
448 do { \
|
yading@10
|
449 int idx = -1; \
|
yading@10
|
450 \
|
yading@10
|
451 if (!*ref) \
|
yading@10
|
452 return; \
|
yading@10
|
453 \
|
yading@10
|
454 FIND_REF_INDEX(ref, idx); \
|
yading@10
|
455 \
|
yading@10
|
456 if (idx >= 0) \
|
yading@10
|
457 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
|
yading@10
|
458 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
|
yading@10
|
459 \
|
yading@10
|
460 if(!--(*ref)->refcount) { \
|
yading@10
|
461 av_free((*ref)->list); \
|
yading@10
|
462 av_free((*ref)->refs); \
|
yading@10
|
463 av_free(*ref); \
|
yading@10
|
464 } \
|
yading@10
|
465 *ref = NULL; \
|
yading@10
|
466 } while (0)
|
yading@10
|
467
|
yading@10
|
468 void ff_formats_unref(AVFilterFormats **ref)
|
yading@10
|
469 {
|
yading@10
|
470 FORMATS_UNREF(ref, formats);
|
yading@10
|
471 }
|
yading@10
|
472
|
yading@10
|
473 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
|
yading@10
|
474 {
|
yading@10
|
475 FORMATS_UNREF(ref, channel_layouts);
|
yading@10
|
476 }
|
yading@10
|
477
|
yading@10
|
478 #define FORMATS_CHANGEREF(oldref, newref) \
|
yading@10
|
479 do { \
|
yading@10
|
480 int idx = -1; \
|
yading@10
|
481 \
|
yading@10
|
482 FIND_REF_INDEX(oldref, idx); \
|
yading@10
|
483 \
|
yading@10
|
484 if (idx >= 0) { \
|
yading@10
|
485 (*oldref)->refs[idx] = newref; \
|
yading@10
|
486 *newref = *oldref; \
|
yading@10
|
487 *oldref = NULL; \
|
yading@10
|
488 } \
|
yading@10
|
489 } while (0)
|
yading@10
|
490
|
yading@10
|
491 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
|
yading@10
|
492 AVFilterChannelLayouts **newref)
|
yading@10
|
493 {
|
yading@10
|
494 FORMATS_CHANGEREF(oldref, newref);
|
yading@10
|
495 }
|
yading@10
|
496
|
yading@10
|
497 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
|
yading@10
|
498 {
|
yading@10
|
499 FORMATS_CHANGEREF(oldref, newref);
|
yading@10
|
500 }
|
yading@10
|
501
|
yading@10
|
502 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
|
yading@10
|
503 { \
|
yading@10
|
504 int count = 0, i; \
|
yading@10
|
505 \
|
yading@10
|
506 for (i = 0; i < ctx->nb_inputs; i++) { \
|
yading@10
|
507 if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \
|
yading@10
|
508 ref(fmts, &ctx->inputs[i]->out_fmts); \
|
yading@10
|
509 count++; \
|
yading@10
|
510 } \
|
yading@10
|
511 } \
|
yading@10
|
512 for (i = 0; i < ctx->nb_outputs; i++) { \
|
yading@10
|
513 if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \
|
yading@10
|
514 ref(fmts, &ctx->outputs[i]->in_fmts); \
|
yading@10
|
515 count++; \
|
yading@10
|
516 } \
|
yading@10
|
517 } \
|
yading@10
|
518 \
|
yading@10
|
519 if (!count) { \
|
yading@10
|
520 av_freep(&fmts->list); \
|
yading@10
|
521 av_freep(&fmts->refs); \
|
yading@10
|
522 av_freep(&fmts); \
|
yading@10
|
523 } \
|
yading@10
|
524 }
|
yading@10
|
525
|
yading@10
|
526 void ff_set_common_channel_layouts(AVFilterContext *ctx,
|
yading@10
|
527 AVFilterChannelLayouts *layouts)
|
yading@10
|
528 {
|
yading@10
|
529 SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
|
yading@10
|
530 ff_channel_layouts_ref, channel_layouts);
|
yading@10
|
531 }
|
yading@10
|
532
|
yading@10
|
533 void ff_set_common_samplerates(AVFilterContext *ctx,
|
yading@10
|
534 AVFilterFormats *samplerates)
|
yading@10
|
535 {
|
yading@10
|
536 SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
|
yading@10
|
537 ff_formats_ref, formats);
|
yading@10
|
538 }
|
yading@10
|
539
|
yading@10
|
540 /**
|
yading@10
|
541 * A helper for query_formats() which sets all links to the same list of
|
yading@10
|
542 * formats. If there are no links hooked to this filter, the list of formats is
|
yading@10
|
543 * freed.
|
yading@10
|
544 */
|
yading@10
|
545 void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
|
yading@10
|
546 {
|
yading@10
|
547 SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
|
yading@10
|
548 ff_formats_ref, formats);
|
yading@10
|
549 }
|
yading@10
|
550
|
yading@10
|
551 static int default_query_formats_common(AVFilterContext *ctx,
|
yading@10
|
552 AVFilterChannelLayouts *(layouts)(void))
|
yading@10
|
553 {
|
yading@10
|
554 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
|
yading@10
|
555 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
|
yading@10
|
556 AVMEDIA_TYPE_VIDEO;
|
yading@10
|
557
|
yading@10
|
558 ff_set_common_formats(ctx, ff_all_formats(type));
|
yading@10
|
559 if (type == AVMEDIA_TYPE_AUDIO) {
|
yading@10
|
560 ff_set_common_channel_layouts(ctx, layouts());
|
yading@10
|
561 ff_set_common_samplerates(ctx, ff_all_samplerates());
|
yading@10
|
562 }
|
yading@10
|
563
|
yading@10
|
564 return 0;
|
yading@10
|
565 }
|
yading@10
|
566
|
yading@10
|
567 int ff_default_query_formats(AVFilterContext *ctx)
|
yading@10
|
568 {
|
yading@10
|
569 return default_query_formats_common(ctx, ff_all_channel_layouts);
|
yading@10
|
570 }
|
yading@10
|
571
|
yading@10
|
572 int ff_query_formats_all(AVFilterContext *ctx)
|
yading@10
|
573 {
|
yading@10
|
574 return default_query_formats_common(ctx, ff_all_channel_counts);
|
yading@10
|
575 }
|
yading@10
|
576
|
yading@10
|
577 /* internal functions for parsing audio format arguments */
|
yading@10
|
578
|
yading@10
|
579 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
|
yading@10
|
580 {
|
yading@10
|
581 char *tail;
|
yading@10
|
582 int pix_fmt = av_get_pix_fmt(arg);
|
yading@10
|
583 if (pix_fmt == AV_PIX_FMT_NONE) {
|
yading@10
|
584 pix_fmt = strtol(arg, &tail, 0);
|
yading@10
|
585 if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) {
|
yading@10
|
586 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
|
yading@10
|
587 return AVERROR(EINVAL);
|
yading@10
|
588 }
|
yading@10
|
589 }
|
yading@10
|
590 *ret = pix_fmt;
|
yading@10
|
591 return 0;
|
yading@10
|
592 }
|
yading@10
|
593
|
yading@10
|
594 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
|
yading@10
|
595 {
|
yading@10
|
596 char *tail;
|
yading@10
|
597 int sfmt = av_get_sample_fmt(arg);
|
yading@10
|
598 if (sfmt == AV_SAMPLE_FMT_NONE) {
|
yading@10
|
599 sfmt = strtol(arg, &tail, 0);
|
yading@10
|
600 if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
|
yading@10
|
601 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
|
yading@10
|
602 return AVERROR(EINVAL);
|
yading@10
|
603 }
|
yading@10
|
604 }
|
yading@10
|
605 *ret = sfmt;
|
yading@10
|
606 return 0;
|
yading@10
|
607 }
|
yading@10
|
608
|
yading@10
|
609 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
|
yading@10
|
610 {
|
yading@10
|
611 AVRational r;
|
yading@10
|
612 if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) {
|
yading@10
|
613 av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
|
yading@10
|
614 return AVERROR(EINVAL);
|
yading@10
|
615 }
|
yading@10
|
616 *ret = r;
|
yading@10
|
617 return 0;
|
yading@10
|
618 }
|
yading@10
|
619
|
yading@10
|
620 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
|
yading@10
|
621 {
|
yading@10
|
622 char *tail;
|
yading@10
|
623 double srate = av_strtod(arg, &tail);
|
yading@10
|
624 if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
|
yading@10
|
625 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
|
yading@10
|
626 return AVERROR(EINVAL);
|
yading@10
|
627 }
|
yading@10
|
628 *ret = srate;
|
yading@10
|
629 return 0;
|
yading@10
|
630 }
|
yading@10
|
631
|
yading@10
|
632 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
|
yading@10
|
633 {
|
yading@10
|
634 char *tail;
|
yading@10
|
635 int64_t chlayout = av_get_channel_layout(arg);
|
yading@10
|
636 if (chlayout == 0) {
|
yading@10
|
637 chlayout = strtol(arg, &tail, 10);
|
yading@10
|
638 if (*tail || chlayout == 0) {
|
yading@10
|
639 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
|
yading@10
|
640 return AVERROR(EINVAL);
|
yading@10
|
641 }
|
yading@10
|
642 }
|
yading@10
|
643 *ret = chlayout;
|
yading@10
|
644 return 0;
|
yading@10
|
645 }
|
yading@10
|
646
|
yading@10
|
647 #ifdef TEST
|
yading@10
|
648
|
yading@10
|
649 #undef printf
|
yading@10
|
650
|
yading@10
|
651 int main(void)
|
yading@10
|
652 {
|
yading@10
|
653 const int64_t *cl;
|
yading@10
|
654 char buf[512];
|
yading@10
|
655
|
yading@10
|
656 for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
|
yading@10
|
657 av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
|
yading@10
|
658 printf("%s\n", buf);
|
yading@10
|
659 }
|
yading@10
|
660
|
yading@10
|
661 return 0;
|
yading@10
|
662 }
|
yading@10
|
663
|
yading@10
|
664 #endif
|
yading@10
|
665
|