00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/channel_layout.h"
00023 #include "libavutil/common.h"
00024 #include "libavutil/eval.h"
00025 #include "libavutil/pixdesc.h"
00026 #include "libavutil/parseutils.h"
00027 #include "avfilter.h"
00028 #include "internal.h"
00029 #include "formats.h"
00030
00034 #define MERGE_REF(ret, a, fmts, type, fail) \
00035 do { \
00036 type ***tmp; \
00037 int i; \
00038 \
00039 if (!(tmp = av_realloc(ret->refs, \
00040 sizeof(*tmp) * (ret->refcount + a->refcount)))) \
00041 goto fail; \
00042 ret->refs = tmp; \
00043 \
00044 for (i = 0; i < a->refcount; i ++) { \
00045 ret->refs[ret->refcount] = a->refs[i]; \
00046 *ret->refs[ret->refcount++] = ret; \
00047 } \
00048 \
00049 av_freep(&a->refs); \
00050 av_freep(&a->fmts); \
00051 av_freep(&a); \
00052 } while (0)
00053
00058 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
00059 do { \
00060 int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
00061 \
00062 if (!(ret = av_mallocz(sizeof(*ret)))) \
00063 goto fail; \
00064 \
00065 if (count) { \
00066 if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
00067 goto fail; \
00068 for (i = 0; i < a->nb; i++) \
00069 for (j = 0; j < b->nb; j++) \
00070 if (a->fmts[i] == b->fmts[j]) { \
00071 if(k >= FFMIN(a->nb, b->nb)){ \
00072 av_log(NULL, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \
00073 av_free(ret->fmts); \
00074 av_free(ret); \
00075 return NULL; \
00076 } \
00077 ret->fmts[k++] = a->fmts[i]; \
00078 } \
00079 } \
00080 ret->nb = k; \
00081 \
00082 if (!ret->nb) \
00083 goto fail; \
00084 \
00085 MERGE_REF(ret, a, fmts, type, fail); \
00086 MERGE_REF(ret, b, fmts, type, fail); \
00087 } while (0)
00088
00089 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
00090 {
00091 AVFilterFormats *ret = NULL;
00092
00093 if (a == b)
00094 return a;
00095
00096 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
00097
00098 return ret;
00099 fail:
00100 if (ret) {
00101 av_freep(&ret->refs);
00102 av_freep(&ret->formats);
00103 }
00104 av_freep(&ret);
00105 return NULL;
00106 }
00107
00108 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
00109 AVFilterFormats *b)
00110 {
00111 AVFilterFormats *ret = NULL;
00112
00113 if (a == b) return a;
00114
00115 if (a->format_count && b->format_count) {
00116 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
00117 } else if (a->format_count) {
00118 MERGE_REF(a, b, formats, AVFilterFormats, fail);
00119 ret = a;
00120 } else {
00121 MERGE_REF(b, a, formats, AVFilterFormats, fail);
00122 ret = b;
00123 }
00124
00125 return ret;
00126 fail:
00127 if (ret) {
00128 av_freep(&ret->refs);
00129 av_freep(&ret->formats);
00130 }
00131 av_freep(&ret);
00132 return NULL;
00133 }
00134
00135 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
00136 AVFilterChannelLayouts *b)
00137 {
00138 AVFilterChannelLayouts *ret = NULL;
00139
00140 if (a == b) return a;
00141
00142 if (a->nb_channel_layouts && b->nb_channel_layouts) {
00143 MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
00144 AVFilterChannelLayouts, fail);
00145 } else if (a->nb_channel_layouts) {
00146 MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
00147 ret = a;
00148 } else {
00149 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
00150 ret = b;
00151 }
00152
00153 return ret;
00154 fail:
00155 if (ret) {
00156 av_freep(&ret->refs);
00157 av_freep(&ret->channel_layouts);
00158 }
00159 av_freep(&ret);
00160 return NULL;
00161 }
00162
00163 int ff_fmt_is_in(int fmt, const int *fmts)
00164 {
00165 const int *p;
00166
00167 for (p = fmts; *p != -1; p++) {
00168 if (fmt == *p)
00169 return 1;
00170 }
00171 return 0;
00172 }
00173
00174 #define COPY_INT_LIST(list_copy, list, type) { \
00175 int count = 0; \
00176 if (list) \
00177 for (count = 0; list[count] != -1; count++) \
00178 ; \
00179 list_copy = av_calloc(count+1, sizeof(type)); \
00180 if (list_copy) { \
00181 memcpy(list_copy, list, sizeof(type) * count); \
00182 list_copy[count] = -1; \
00183 } \
00184 }
00185
00186 int *ff_copy_int_list(const int * const list)
00187 {
00188 int *ret = NULL;
00189 COPY_INT_LIST(ret, list, int);
00190 return ret;
00191 }
00192
00193 int64_t *ff_copy_int64_list(const int64_t * const list)
00194 {
00195 int64_t *ret = NULL;
00196 COPY_INT_LIST(ret, list, int64_t);
00197 return ret;
00198 }
00199
00200 #define MAKE_FORMAT_LIST(type, field, count_field) \
00201 type *formats; \
00202 int count = 0; \
00203 if (fmts) \
00204 for (count = 0; fmts[count] != -1; count++) \
00205 ; \
00206 formats = av_mallocz(sizeof(*formats)); \
00207 if (!formats) return NULL; \
00208 formats->count_field = count; \
00209 if (count) { \
00210 formats->field = av_malloc(sizeof(*formats->field)*count); \
00211 if (!formats->field) { \
00212 av_free(formats); \
00213 return NULL; \
00214 } \
00215 }
00216
00217 AVFilterFormats *ff_make_format_list(const int *fmts)
00218 {
00219 MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
00220 while (count--)
00221 formats->formats[count] = fmts[count];
00222
00223 return formats;
00224 }
00225
00226 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
00227 {
00228 MAKE_FORMAT_LIST(AVFilterChannelLayouts,
00229 channel_layouts, nb_channel_layouts);
00230 if (count)
00231 memcpy(formats->channel_layouts, fmts,
00232 sizeof(*formats->channel_layouts) * count);
00233
00234 return formats;
00235 }
00236
00237 #define ADD_FORMAT(f, fmt, type, list, nb) \
00238 do { \
00239 type *fmts; \
00240 \
00241 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
00242 return AVERROR(ENOMEM); \
00243 \
00244 fmts = av_realloc((*f)->list, \
00245 sizeof(*(*f)->list) * ((*f)->nb + 1));\
00246 if (!fmts) \
00247 return AVERROR(ENOMEM); \
00248 \
00249 (*f)->list = fmts; \
00250 (*f)->list[(*f)->nb++] = fmt; \
00251 return 0; \
00252 } while (0)
00253
00254 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
00255 {
00256 ADD_FORMAT(avff, fmt, int, formats, format_count);
00257 }
00258
00259 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
00260 {
00261 ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
00262 }
00263
00264 AVFilterFormats *ff_all_formats(enum AVMediaType type)
00265 {
00266 AVFilterFormats *ret = NULL;
00267 int fmt;
00268 int num_formats = type == AVMEDIA_TYPE_VIDEO ? AV_PIX_FMT_NB :
00269 type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
00270
00271 for (fmt = 0; fmt < num_formats; fmt++) {
00272 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
00273 if ((type != AVMEDIA_TYPE_VIDEO) ||
00274 (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
00275 ff_add_format(&ret, fmt);
00276 }
00277
00278 return ret;
00279 }
00280
00281 const int64_t avfilter_all_channel_layouts[] = {
00282 #include "all_channel_layouts.inc"
00283 -1
00284 };
00285
00286
00287
00288
00289
00290
00291 AVFilterFormats *ff_planar_sample_fmts(void)
00292 {
00293 AVFilterFormats *ret = NULL;
00294 int fmt;
00295
00296 for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
00297 if (av_sample_fmt_is_planar(fmt))
00298 ff_add_format(&ret, fmt);
00299
00300 return ret;
00301 }
00302
00303 AVFilterFormats *ff_all_samplerates(void)
00304 {
00305 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
00306 return ret;
00307 }
00308
00309 AVFilterChannelLayouts *ff_all_channel_layouts(void)
00310 {
00311 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
00312 return ret;
00313 }
00314
00315 #define FORMATS_REF(f, ref) \
00316 do { \
00317 *ref = f; \
00318 f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
00319 f->refs[f->refcount-1] = ref; \
00320 } while (0)
00321
00322 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
00323 {
00324 FORMATS_REF(f, ref);
00325 }
00326
00327 void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
00328 {
00329 FORMATS_REF(f, ref);
00330 }
00331
00332 #define FIND_REF_INDEX(ref, idx) \
00333 do { \
00334 int i; \
00335 for (i = 0; i < (*ref)->refcount; i ++) \
00336 if((*ref)->refs[i] == ref) { \
00337 idx = i; \
00338 break; \
00339 } \
00340 } while (0)
00341
00342 #define FORMATS_UNREF(ref, list) \
00343 do { \
00344 int idx = -1; \
00345 \
00346 if (!*ref) \
00347 return; \
00348 \
00349 FIND_REF_INDEX(ref, idx); \
00350 \
00351 if (idx >= 0) \
00352 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
00353 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
00354 \
00355 if(!--(*ref)->refcount) { \
00356 av_free((*ref)->list); \
00357 av_free((*ref)->refs); \
00358 av_free(*ref); \
00359 } \
00360 *ref = NULL; \
00361 } while (0)
00362
00363 void ff_formats_unref(AVFilterFormats **ref)
00364 {
00365 FORMATS_UNREF(ref, formats);
00366 }
00367
00368 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
00369 {
00370 FORMATS_UNREF(ref, channel_layouts);
00371 }
00372
00373 #define FORMATS_CHANGEREF(oldref, newref) \
00374 do { \
00375 int idx = -1; \
00376 \
00377 FIND_REF_INDEX(oldref, idx); \
00378 \
00379 if (idx >= 0) { \
00380 (*oldref)->refs[idx] = newref; \
00381 *newref = *oldref; \
00382 *oldref = NULL; \
00383 } \
00384 } while (0)
00385
00386 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
00387 AVFilterChannelLayouts **newref)
00388 {
00389 FORMATS_CHANGEREF(oldref, newref);
00390 }
00391
00392 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
00393 {
00394 FORMATS_CHANGEREF(oldref, newref);
00395 }
00396
00397 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
00398 { \
00399 int count = 0, i; \
00400 \
00401 for (i = 0; i < ctx->nb_inputs; i++) { \
00402 if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \
00403 ref(fmts, &ctx->inputs[i]->out_fmts); \
00404 count++; \
00405 } \
00406 } \
00407 for (i = 0; i < ctx->nb_outputs; i++) { \
00408 if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \
00409 ref(fmts, &ctx->outputs[i]->in_fmts); \
00410 count++; \
00411 } \
00412 } \
00413 \
00414 if (!count) { \
00415 av_freep(&fmts->list); \
00416 av_freep(&fmts->refs); \
00417 av_freep(&fmts); \
00418 } \
00419 }
00420
00421 void ff_set_common_channel_layouts(AVFilterContext *ctx,
00422 AVFilterChannelLayouts *layouts)
00423 {
00424 SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
00425 ff_channel_layouts_ref, channel_layouts);
00426 }
00427
00428 void ff_set_common_samplerates(AVFilterContext *ctx,
00429 AVFilterFormats *samplerates)
00430 {
00431 SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
00432 ff_formats_ref, formats);
00433 }
00434
00440 void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
00441 {
00442 SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
00443 ff_formats_ref, formats);
00444 }
00445
00446 int ff_default_query_formats(AVFilterContext *ctx)
00447 {
00448 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
00449 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
00450 AVMEDIA_TYPE_VIDEO;
00451
00452 ff_set_common_formats(ctx, ff_all_formats(type));
00453 if (type == AVMEDIA_TYPE_AUDIO) {
00454 ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
00455 ff_set_common_samplerates(ctx, ff_all_samplerates());
00456 }
00457
00458 return 0;
00459 }
00460
00461
00462
00463 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
00464 {
00465 char *tail;
00466 int pix_fmt = av_get_pix_fmt(arg);
00467 if (pix_fmt == AV_PIX_FMT_NONE) {
00468 pix_fmt = strtol(arg, &tail, 0);
00469 if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) {
00470 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
00471 return AVERROR(EINVAL);
00472 }
00473 }
00474 *ret = pix_fmt;
00475 return 0;
00476 }
00477
00478 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
00479 {
00480 char *tail;
00481 int sfmt = av_get_sample_fmt(arg);
00482 if (sfmt == AV_SAMPLE_FMT_NONE) {
00483 sfmt = strtol(arg, &tail, 0);
00484 if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
00485 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
00486 return AVERROR(EINVAL);
00487 }
00488 }
00489 *ret = sfmt;
00490 return 0;
00491 }
00492
00493 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
00494 {
00495 AVRational r;
00496 if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) {
00497 av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
00498 return AVERROR(EINVAL);
00499 }
00500 *ret = r;
00501 return 0;
00502 }
00503
00504 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
00505 {
00506 char *tail;
00507 double srate = av_strtod(arg, &tail);
00508 if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
00509 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
00510 return AVERROR(EINVAL);
00511 }
00512 *ret = srate;
00513 return 0;
00514 }
00515
00516 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
00517 {
00518 char *tail;
00519 int64_t chlayout = av_get_channel_layout(arg);
00520 if (chlayout == 0) {
00521 chlayout = strtol(arg, &tail, 10);
00522 if (*tail || chlayout == 0) {
00523 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
00524 return AVERROR(EINVAL);
00525 }
00526 }
00527 *ret = chlayout;
00528 return 0;
00529 }
00530
00531 #ifdef TEST
00532
00533 #undef printf
00534
00535 int main(void)
00536 {
00537 const int64_t *cl;
00538 char buf[512];
00539
00540 for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
00541 av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
00542 printf("%s\n", buf);
00543 }
00544
00545 return 0;
00546 }
00547
00548 #endif
00549