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 
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->format_count; i++)
112  for (j = 0; j < b->format_count; 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 & PIX_FMT_ALPHA;
116  chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
117  if (a->formats[i] == b->formats[j]) {
118  alpha1 |= adesc->flags & PIX_FMT_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, format_count, 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->format_count && b->format_count) {
147  MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
148  } else if (a->format_count) {
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 {
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  b->nb_channel_layouts = j;
188  }
189  MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
190  return b;
191  }
192 
193  ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
194  if (!(ret = av_mallocz(sizeof(*ret))) ||
195  !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) *
196  ret_max)))
197  goto fail;
198 
199  /* a[known] intersect b[known] */
200  for (i = 0; i < a->nb_channel_layouts; i++) {
201  if (!KNOWN(a->channel_layouts[i]))
202  continue;
203  for (j = 0; j < b->nb_channel_layouts; j++) {
204  if (a->channel_layouts[i] == b->channel_layouts[j]) {
205  ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
206  a->channel_layouts[i] = b->channel_layouts[j] = 0;
207  }
208  }
209  }
210  /* 1st round: a[known] intersect b[generic]
211  2nd round: a[generic] intersect b[known] */
212  for (round = 0; round < 2; round++) {
213  for (i = 0; i < a->nb_channel_layouts; i++) {
214  uint64_t fmt = a->channel_layouts[i], bfmt;
215  if (!fmt || !KNOWN(fmt))
216  continue;
218  for (j = 0; j < b->nb_channel_layouts; j++)
219  if (b->channel_layouts[j] == bfmt)
220  ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
221  }
222  /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
224  }
225  /* a[generic] intersect b[generic] */
226  for (i = 0; i < a->nb_channel_layouts; i++) {
227  if (KNOWN(a->channel_layouts[i]))
228  continue;
229  for (j = 0; j < b->nb_channel_layouts; j++)
230  if (a->channel_layouts[i] == b->channel_layouts[j])
231  ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
232  }
233 
234  ret->nb_channel_layouts = ret_nb;
235  if (!ret->nb_channel_layouts)
236  goto fail;
237  MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail);
238  MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail);
239  return ret;
240 
241 fail:
242  if (ret) {
243  av_freep(&ret->refs);
244  av_freep(&ret->channel_layouts);
245  }
246  av_freep(&ret);
247  return NULL;
248 }
249 
250 int ff_fmt_is_in(int fmt, const int *fmts)
251 {
252  const int *p;
253 
254  for (p = fmts; *p != -1; p++) {
255  if (fmt == *p)
256  return 1;
257  }
258  return 0;
259 }
260 
261 #define COPY_INT_LIST(list_copy, list, type) { \
262  int count = 0; \
263  if (list) \
264  for (count = 0; list[count] != -1; count++) \
265  ; \
266  list_copy = av_calloc(count+1, sizeof(type)); \
267  if (list_copy) { \
268  memcpy(list_copy, list, sizeof(type) * count); \
269  list_copy[count] = -1; \
270  } \
271 }
272 
273 int *ff_copy_int_list(const int * const list)
274 {
275  int *ret = NULL;
276  COPY_INT_LIST(ret, list, int);
277  return ret;
278 }
279 
280 int64_t *ff_copy_int64_list(const int64_t * const list)
281 {
282  int64_t *ret = NULL;
283  COPY_INT_LIST(ret, list, int64_t);
284  return ret;
285 }
286 
287 #define MAKE_FORMAT_LIST(type, field, count_field) \
288  type *formats; \
289  int count = 0; \
290  if (fmts) \
291  for (count = 0; fmts[count] != -1; count++) \
292  ; \
293  formats = av_mallocz(sizeof(*formats)); \
294  if (!formats) return NULL; \
295  formats->count_field = count; \
296  if (count) { \
297  formats->field = av_malloc(sizeof(*formats->field)*count); \
298  if (!formats->field) { \
299  av_free(formats); \
300  return NULL; \
301  } \
302  }
303 
305 {
306  MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
307  while (count--)
308  formats->formats[count] = fmts[count];
309 
310  return formats;
311 }
312 
314 {
316  channel_layouts, nb_channel_layouts);
317  if (count)
318  memcpy(formats->channel_layouts, fmts,
319  sizeof(*formats->channel_layouts) * count);
320 
321  return formats;
322 }
323 
324 #define ADD_FORMAT(f, fmt, type, list, nb) \
325 do { \
326  type *fmts; \
327  \
328  if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
329  return AVERROR(ENOMEM); \
330  \
331  fmts = av_realloc((*f)->list, \
332  sizeof(*(*f)->list) * ((*f)->nb + 1));\
333  if (!fmts) \
334  return AVERROR(ENOMEM); \
335  \
336  (*f)->list = fmts; \
337  (*f)->list[(*f)->nb++] = fmt; \
338 } while (0)
339 
340 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
341 {
342  ADD_FORMAT(avff, fmt, int, formats, format_count);
343  return 0;
344 }
345 
346 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
347 {
348  av_assert1(!(*l && (*l)->all_layouts));
349  ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
350  return 0;
351 }
352 
354 {
355  AVFilterFormats *ret = NULL;
356  int fmt;
357  int num_formats = type == AVMEDIA_TYPE_VIDEO ? AV_PIX_FMT_NB :
358  type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
359 
360  for (fmt = 0; fmt < num_formats; fmt++) {
361  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
362  if ((type != AVMEDIA_TYPE_VIDEO) ||
363  (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
364  ff_add_format(&ret, fmt);
365  }
366 
367  return ret;
368 }
369 
370 const int64_t avfilter_all_channel_layouts[] = {
371 #include "all_channel_layouts.inc"
372  -1
373 };
374 
375 // AVFilterFormats *avfilter_make_all_channel_layouts(void)
376 // {
377 // return avfilter_make_format64_list(avfilter_all_channel_layouts);
378 // }
379 
381 {
382  AVFilterFormats *ret = NULL;
383  int fmt;
384 
385  for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
386  if (av_sample_fmt_is_planar(fmt))
387  ff_add_format(&ret, fmt);
388 
389  return ret;
390 }
391 
393 {
394  AVFilterFormats *ret = av_mallocz(sizeof(*ret));
395  return ret;
396 }
397 
399 {
400  AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
401  if (!ret)
402  return NULL;
403  ret->all_layouts = 1;
404  return ret;
405 }
406 
408 {
409  AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
410  if (!ret)
411  return NULL;
412  ret->all_layouts = ret->all_counts = 1;
413  return ret;
414 }
415 
416 #define FORMATS_REF(f, ref) \
417 do { \
418  *ref = f; \
419  f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
420  f->refs[f->refcount-1] = ref; \
421 } while (0)
422 
424 {
425  FORMATS_REF(f, ref);
426 }
427 
429 {
430  FORMATS_REF(f, ref);
431 }
432 
433 #define FIND_REF_INDEX(ref, idx) \
434 do { \
435  int i; \
436  for (i = 0; i < (*ref)->refcount; i ++) \
437  if((*ref)->refs[i] == ref) { \
438  idx = i; \
439  break; \
440  } \
441 } while (0)
442 
443 #define FORMATS_UNREF(ref, list) \
444 do { \
445  int idx = -1; \
446  \
447  if (!*ref) \
448  return; \
449  \
450  FIND_REF_INDEX(ref, idx); \
451  \
452  if (idx >= 0) \
453  memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
454  sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
455  \
456  if(!--(*ref)->refcount) { \
457  av_free((*ref)->list); \
458  av_free((*ref)->refs); \
459  av_free(*ref); \
460  } \
461  *ref = NULL; \
462 } while (0)
463 
465 {
466  FORMATS_UNREF(ref, formats);
467 }
468 
470 {
471  FORMATS_UNREF(ref, channel_layouts);
472 }
473 
474 #define FORMATS_CHANGEREF(oldref, newref) \
475 do { \
476  int idx = -1; \
477  \
478  FIND_REF_INDEX(oldref, idx); \
479  \
480  if (idx >= 0) { \
481  (*oldref)->refs[idx] = newref; \
482  *newref = *oldref; \
483  *oldref = NULL; \
484  } \
485 } while (0)
486 
488  AVFilterChannelLayouts **newref)
489 {
490  FORMATS_CHANGEREF(oldref, newref);
491 }
492 
494 {
495  FORMATS_CHANGEREF(oldref, newref);
496 }
497 
498 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
499 { \
500  int count = 0, i; \
501  \
502  for (i = 0; i < ctx->nb_inputs; i++) { \
503  if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \
504  ref(fmts, &ctx->inputs[i]->out_fmts); \
505  count++; \
506  } \
507  } \
508  for (i = 0; i < ctx->nb_outputs; i++) { \
509  if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \
510  ref(fmts, &ctx->outputs[i]->in_fmts); \
511  count++; \
512  } \
513  } \
514  \
515  if (!count) { \
516  av_freep(&fmts->list); \
517  av_freep(&fmts->refs); \
518  av_freep(&fmts); \
519  } \
520 }
521 
524 {
525  SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
526  ff_channel_layouts_ref, channel_layouts);
527 }
528 
530  AVFilterFormats *samplerates)
531 {
532  SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
534 }
535 
536 /**
537  * A helper for query_formats() which sets all links to the same list of
538  * formats. If there are no links hooked to this filter, the list of formats is
539  * freed.
540  */
542 {
543  SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
544  ff_formats_ref, formats);
545 }
546 
549 {
550  enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
551  ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
553 
555  if (type == AVMEDIA_TYPE_AUDIO) {
558  }
559 
560  return 0;
561 }
562 
564 {
566 }
567 
569 {
571 }
572 
573 /* internal functions for parsing audio format arguments */
574 
575 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
576 {
577  char *tail;
578  int pix_fmt = av_get_pix_fmt(arg);
579  if (pix_fmt == AV_PIX_FMT_NONE) {
580  pix_fmt = strtol(arg, &tail, 0);
581  if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) {
582  av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
583  return AVERROR(EINVAL);
584  }
585  }
586  *ret = pix_fmt;
587  return 0;
588 }
589 
590 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
591 {
592  char *tail;
593  int sfmt = av_get_sample_fmt(arg);
594  if (sfmt == AV_SAMPLE_FMT_NONE) {
595  sfmt = strtol(arg, &tail, 0);
596  if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
597  av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
598  return AVERROR(EINVAL);
599  }
600  }
601  *ret = sfmt;
602  return 0;
603 }
604 
605 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
606 {
607  AVRational r;
608  if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) {
609  av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
610  return AVERROR(EINVAL);
611  }
612  *ret = r;
613  return 0;
614 }
615 
616 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
617 {
618  char *tail;
619  double srate = av_strtod(arg, &tail);
620  if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
621  av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
622  return AVERROR(EINVAL);
623  }
624  *ret = srate;
625  return 0;
626 }
627 
628 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
629 {
630  char *tail;
631  int64_t chlayout = av_get_channel_layout(arg);
632  if (chlayout == 0) {
633  chlayout = strtol(arg, &tail, 10);
634  if (*tail || chlayout == 0) {
635  av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
636  return AVERROR(EINVAL);
637  }
638  }
639  *ret = chlayout;
640  return 0;
641 }
642 
643 #ifdef TEST
644 
645 #undef printf
646 
647 int main(void)
648 {
649  const int64_t *cl;
650  char buf[512];
651 
652  for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
653  av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
654  printf("%s\n", buf);
655  }
656 
657  return 0;
658 }
659 
660 #endif
661