annotate ffmpeg/libavfilter/formats.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
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