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