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