FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
formats.c
Go to the documentation of this file.
1 /*
2  * Filter layer - format negotiation
3  * Copyright (c) 2007 Bobby Bingham
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
23 #include "libavutil/common.h"
24 #include "libavutil/eval.h"
25 #include "libavutil/pixdesc.h"
26 #include "libavutil/parseutils.h"
27 #include "avfilter.h"
28 #include "internal.h"
29 #include "formats.h"
30 
31 /**
32  * Add all refs from a to ret and destroy a.
33  */
34 #define MERGE_REF(ret, a, fmts, type, fail) \
35 do { \
36  type ***tmp; \
37  int i; \
38  \
39  if (!(tmp = av_realloc(ret->refs, \
40  sizeof(*tmp) * (ret->refcount + a->refcount)))) \
41  goto fail; \
42  ret->refs = tmp; \
43  \
44  for (i = 0; i < a->refcount; i ++) { \
45  ret->refs[ret->refcount] = a->refs[i]; \
46  *ret->refs[ret->refcount++] = ret; \
47  } \
48  \
49  av_freep(&a->refs); \
50  av_freep(&a->fmts); \
51  av_freep(&a); \
52 } while (0)
53 
54 /**
55  * Add all formats common for a and b to ret, copy the refs and destroy
56  * a and b.
57  */
58 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
59 do { \
60  int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
61  \
62  if (!(ret = av_mallocz(sizeof(*ret)))) \
63  goto fail; \
64  \
65  if (count) { \
66  if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
67  goto fail; \
68  for (i = 0; i < a->nb; i++) \
69  for (j = 0; j < b->nb; j++) \
70  if (a->fmts[i] == b->fmts[j]) { \
71  if(k >= FFMIN(a->nb, b->nb)){ \
72  av_log(NULL, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \
73  av_free(ret->fmts); \
74  av_free(ret); \
75  return NULL; \
76  } \
77  ret->fmts[k++] = a->fmts[i]; \
78  } \
79  } \
80  ret->nb = k; \
81  /* check that there was at least one common format */ \
82  if (!ret->nb) \
83  goto fail; \
84  \
85  MERGE_REF(ret, a, fmts, type, fail); \
86  MERGE_REF(ret, b, fmts, type, fail); \
87 } while (0)
88 
90 {
91  AVFilterFormats *ret = NULL;
92 
93  if (a == b)
94  return a;
95 
96  MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
97 
98  return ret;
99 fail:
100  if (ret) {
101  av_freep(&ret->refs);
102  av_freep(&ret->formats);
103  }
104  av_freep(&ret);
105  return NULL;
106 }
107 
110 {
111  AVFilterFormats *ret = NULL;
112 
113  if (a == b) return a;
114 
115  if (a->format_count && b->format_count) {
116  MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
117  } else if (a->format_count) {
118  MERGE_REF(a, b, formats, AVFilterFormats, fail);
119  ret = a;
120  } else {
121  MERGE_REF(b, a, formats, AVFilterFormats, fail);
122  ret = b;
123  }
124 
125  return ret;
126 fail:
127  if (ret) {
128  av_freep(&ret->refs);
129  av_freep(&ret->formats);
130  }
131  av_freep(&ret);
132  return NULL;
133 }
134 
137 {
139 
140  if (a == b) return a;
141 
142  if (a->nb_channel_layouts && b->nb_channel_layouts) {
143  MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
144  AVFilterChannelLayouts, fail);
145  } else if (a->nb_channel_layouts) {
146  MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
147  ret = a;
148  } else {
149  MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
150  ret = b;
151  }
152 
153  return ret;
154 fail:
155  if (ret) {
156  av_freep(&ret->refs);
157  av_freep(&ret->channel_layouts);
158  }
159  av_freep(&ret);
160  return NULL;
161 }
162 
163 int ff_fmt_is_in(int fmt, const int *fmts)
164 {
165  const int *p;
166 
167  for (p = fmts; *p != -1; p++) {
168  if (fmt == *p)
169  return 1;
170  }
171  return 0;
172 }
173 
174 #define COPY_INT_LIST(list_copy, list, type) { \
175  int count = 0; \
176  if (list) \
177  for (count = 0; list[count] != -1; count++) \
178  ; \
179  list_copy = av_calloc(count+1, sizeof(type)); \
180  if (list_copy) { \
181  memcpy(list_copy, list, sizeof(type) * count); \
182  list_copy[count] = -1; \
183  } \
184 }
185 
186 int *ff_copy_int_list(const int * const list)
187 {
188  int *ret = NULL;
189  COPY_INT_LIST(ret, list, int);
190  return ret;
191 }
192 
193 int64_t *ff_copy_int64_list(const int64_t * const list)
194 {
195  int64_t *ret = NULL;
196  COPY_INT_LIST(ret, list, int64_t);
197  return ret;
198 }
199 
200 #define MAKE_FORMAT_LIST(type, field, count_field) \
201  type *formats; \
202  int count = 0; \
203  if (fmts) \
204  for (count = 0; fmts[count] != -1; count++) \
205  ; \
206  formats = av_mallocz(sizeof(*formats)); \
207  if (!formats) return NULL; \
208  formats->count_field = count; \
209  if (count) { \
210  formats->field = av_malloc(sizeof(*formats->field)*count); \
211  if (!formats->field) { \
212  av_free(formats); \
213  return NULL; \
214  } \
215  }
216 
218 {
219  MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
220  while (count--)
221  formats->formats[count] = fmts[count];
222 
223  return formats;
224 }
225 
227 {
229  channel_layouts, nb_channel_layouts);
230  if (count)
231  memcpy(formats->channel_layouts, fmts,
232  sizeof(*formats->channel_layouts) * count);
233 
234  return formats;
235 }
236 
237 #define ADD_FORMAT(f, fmt, type, list, nb) \
238 do { \
239  type *fmts; \
240  \
241  if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
242  return AVERROR(ENOMEM); \
243  \
244  fmts = av_realloc((*f)->list, \
245  sizeof(*(*f)->list) * ((*f)->nb + 1));\
246  if (!fmts) \
247  return AVERROR(ENOMEM); \
248  \
249  (*f)->list = fmts; \
250  (*f)->list[(*f)->nb++] = fmt; \
251  return 0; \
252 } while (0)
253 
254 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
255 {
256  ADD_FORMAT(avff, fmt, int, formats, format_count);
257 }
258 
259 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
260 {
261  ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
262 }
263 
265 {
266  AVFilterFormats *ret = NULL;
267  int fmt;
268  int num_formats = type == AVMEDIA_TYPE_VIDEO ? AV_PIX_FMT_NB :
269  type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
270 
271  for (fmt = 0; fmt < num_formats; fmt++) {
272  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
273  if ((type != AVMEDIA_TYPE_VIDEO) ||
274  (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
275  ff_add_format(&ret, fmt);
276  }
277 
278  return ret;
279 }
280 
281 const int64_t avfilter_all_channel_layouts[] = {
282 #include "all_channel_layouts.inc"
283  -1
284 };
285 
286 // AVFilterFormats *avfilter_make_all_channel_layouts(void)
287 // {
288 // return avfilter_make_format64_list(avfilter_all_channel_layouts);
289 // }
290 
292 {
293  AVFilterFormats *ret = NULL;
294  int fmt;
295 
296  for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
297  if (av_sample_fmt_is_planar(fmt))
298  ff_add_format(&ret, fmt);
299 
300  return ret;
301 }
302 
304 {
305  AVFilterFormats *ret = av_mallocz(sizeof(*ret));
306  return ret;
307 }
308 
310 {
311  AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
312  return ret;
313 }
314 
315 #define FORMATS_REF(f, ref) \
316 do { \
317  *ref = f; \
318  f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
319  f->refs[f->refcount-1] = ref; \
320 } while (0)
321 
323 {
324  FORMATS_REF(f, ref);
325 }
326 
328 {
329  FORMATS_REF(f, ref);
330 }
331 
332 #define FIND_REF_INDEX(ref, idx) \
333 do { \
334  int i; \
335  for (i = 0; i < (*ref)->refcount; i ++) \
336  if((*ref)->refs[i] == ref) { \
337  idx = i; \
338  break; \
339  } \
340 } while (0)
341 
342 #define FORMATS_UNREF(ref, list) \
343 do { \
344  int idx = -1; \
345  \
346  if (!*ref) \
347  return; \
348  \
349  FIND_REF_INDEX(ref, idx); \
350  \
351  if (idx >= 0) \
352  memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
353  sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
354  \
355  if(!--(*ref)->refcount) { \
356  av_free((*ref)->list); \
357  av_free((*ref)->refs); \
358  av_free(*ref); \
359  } \
360  *ref = NULL; \
361 } while (0)
362 
364 {
365  FORMATS_UNREF(ref, formats);
366 }
367 
369 {
370  FORMATS_UNREF(ref, channel_layouts);
371 }
372 
373 #define FORMATS_CHANGEREF(oldref, newref) \
374 do { \
375  int idx = -1; \
376  \
377  FIND_REF_INDEX(oldref, idx); \
378  \
379  if (idx >= 0) { \
380  (*oldref)->refs[idx] = newref; \
381  *newref = *oldref; \
382  *oldref = NULL; \
383  } \
384 } while (0)
385 
387  AVFilterChannelLayouts **newref)
388 {
389  FORMATS_CHANGEREF(oldref, newref);
390 }
391 
393 {
394  FORMATS_CHANGEREF(oldref, newref);
395 }
396 
397 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
398 { \
399  int count = 0, i; \
400  \
401  for (i = 0; i < ctx->nb_inputs; i++) { \
402  if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \
403  ref(fmts, &ctx->inputs[i]->out_fmts); \
404  count++; \
405  } \
406  } \
407  for (i = 0; i < ctx->nb_outputs; i++) { \
408  if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \
409  ref(fmts, &ctx->outputs[i]->in_fmts); \
410  count++; \
411  } \
412  } \
413  \
414  if (!count) { \
415  av_freep(&fmts->list); \
416  av_freep(&fmts->refs); \
417  av_freep(&fmts); \
418  } \
419 }
420 
423 {
424  SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
425  ff_channel_layouts_ref, channel_layouts);
426 }
427 
429  AVFilterFormats *samplerates)
430 {
431  SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
433 }
434 
435 /**
436  * A helper for query_formats() which sets all links to the same list of
437  * formats. If there are no links hooked to this filter, the list of formats is
438  * freed.
439  */
441 {
442  SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
443  ff_formats_ref, formats);
444 }
445 
447 {
448  enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
449  ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
451 
453  if (type == AVMEDIA_TYPE_AUDIO) {
456  }
457 
458  return 0;
459 }
460 
461 /* internal functions for parsing audio format arguments */
462 
463 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
464 {
465  char *tail;
466  int pix_fmt = av_get_pix_fmt(arg);
467  if (pix_fmt == AV_PIX_FMT_NONE) {
468  pix_fmt = strtol(arg, &tail, 0);
469  if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) {
470  av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
471  return AVERROR(EINVAL);
472  }
473  }
474  *ret = pix_fmt;
475  return 0;
476 }
477 
478 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
479 {
480  char *tail;
481  int sfmt = av_get_sample_fmt(arg);
482  if (sfmt == AV_SAMPLE_FMT_NONE) {
483  sfmt = strtol(arg, &tail, 0);
484  if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
485  av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
486  return AVERROR(EINVAL);
487  }
488  }
489  *ret = sfmt;
490  return 0;
491 }
492 
493 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
494 {
495  AVRational r;
496  if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) {
497  av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
498  return AVERROR(EINVAL);
499  }
500  *ret = r;
501  return 0;
502 }
503 
504 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
505 {
506  char *tail;
507  double srate = av_strtod(arg, &tail);
508  if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
509  av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
510  return AVERROR(EINVAL);
511  }
512  *ret = srate;
513  return 0;
514 }
515 
516 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
517 {
518  char *tail;
519  int64_t chlayout = av_get_channel_layout(arg);
520  if (chlayout == 0) {
521  chlayout = strtol(arg, &tail, 10);
522  if (*tail || chlayout == 0) {
523  av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
524  return AVERROR(EINVAL);
525  }
526  }
527  *ret = chlayout;
528  return 0;
529 }
530 
531 #ifdef TEST
532 
533 #undef printf
534 
535 int main(void)
536 {
537  const int64_t *cl;
538  char buf[512];
539 
540  for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
541  av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
542  printf("%s\n", buf);
543  }
544 
545  return 0;
546 }
547 
548 #endif
549