00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "libavutil/common.h"
00023 #include "libavutil/eval.h"
00024 #include "libavutil/pixdesc.h"
00025 #include "libavutil/parseutils.h"
00026 #include "libavutil/audioconvert.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(0, 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 ? PIX_FMT_NB    :
00269                       type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
00270 
00271     for (fmt = 0; fmt < num_formats; fmt++)
00272         if ((type != AVMEDIA_TYPE_VIDEO) ||
00273             (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
00274             ff_add_format(&ret, fmt);
00275 
00276     return ret;
00277 }
00278 
00279 const int64_t avfilter_all_channel_layouts[] = {
00280 #include "all_channel_layouts.inc"
00281     -1
00282 };
00283 
00284 
00285 
00286 
00287 
00288 
00289 AVFilterFormats *ff_planar_sample_fmts(void)
00290 {
00291     AVFilterFormats *ret = NULL;
00292     int fmt;
00293 
00294     for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
00295         if (av_sample_fmt_is_planar(fmt))
00296             ff_add_format(&ret, fmt);
00297 
00298     return ret;
00299 }
00300 
00301 AVFilterFormats *ff_all_samplerates(void)
00302 {
00303     AVFilterFormats *ret = av_mallocz(sizeof(*ret));
00304     return ret;
00305 }
00306 
00307 AVFilterChannelLayouts *ff_all_channel_layouts(void)
00308 {
00309     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
00310     return ret;
00311 }
00312 
00313 #define FORMATS_REF(f, ref)                                          \
00314 do {                                                                 \
00315     *ref = f;                                                        \
00316     f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
00317     f->refs[f->refcount-1] = ref;                                    \
00318 } while (0)
00319 
00320 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
00321 {
00322     FORMATS_REF(f, ref);
00323 }
00324 
00325 void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
00326 {
00327     FORMATS_REF(f, ref);
00328 }
00329 
00330 #define FIND_REF_INDEX(ref, idx)            \
00331 do {                                        \
00332     int i;                                  \
00333     for (i = 0; i < (*ref)->refcount; i ++) \
00334         if((*ref)->refs[i] == ref) {        \
00335             idx = i;                        \
00336             break;                          \
00337         }                                   \
00338 } while (0)
00339 
00340 #define FORMATS_UNREF(ref, list)                                   \
00341 do {                                                               \
00342     int idx = -1;                                                  \
00343                                                                    \
00344     if (!*ref)                                                     \
00345         return;                                                    \
00346                                                                    \
00347     FIND_REF_INDEX(ref, idx);                                      \
00348                                                                    \
00349     if (idx >= 0)                                                  \
00350         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
00351             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
00352                                                                    \
00353     if(!--(*ref)->refcount) {                                      \
00354         av_free((*ref)->list);                                     \
00355         av_free((*ref)->refs);                                     \
00356         av_free(*ref);                                             \
00357     }                                                              \
00358     *ref = NULL;                                                   \
00359 } while (0)
00360 
00361 void ff_formats_unref(AVFilterFormats **ref)
00362 {
00363     FORMATS_UNREF(ref, formats);
00364 }
00365 
00366 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
00367 {
00368     FORMATS_UNREF(ref, channel_layouts);
00369 }
00370 
00371 #define FORMATS_CHANGEREF(oldref, newref)       \
00372 do {                                            \
00373     int idx = -1;                               \
00374                                                 \
00375     FIND_REF_INDEX(oldref, idx);                \
00376                                                 \
00377     if (idx >= 0) {                             \
00378         (*oldref)->refs[idx] = newref;          \
00379         *newref = *oldref;                      \
00380         *oldref = NULL;                         \
00381     }                                           \
00382 } while (0)
00383 
00384 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
00385                                   AVFilterChannelLayouts **newref)
00386 {
00387     FORMATS_CHANGEREF(oldref, newref);
00388 }
00389 
00390 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
00391 {
00392     FORMATS_CHANGEREF(oldref, newref);
00393 }
00394 
00395 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
00396 {                                                                   \
00397     int count = 0, i;                                               \
00398                                                                     \
00399     for (i = 0; i < ctx->nb_inputs; i++) {                          \
00400         if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
00401             ref(fmts, &ctx->inputs[i]->out_fmts);                   \
00402             count++;                                                \
00403         }                                                           \
00404     }                                                               \
00405     for (i = 0; i < ctx->nb_outputs; i++) {                         \
00406         if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
00407             ref(fmts, &ctx->outputs[i]->in_fmts);                   \
00408             count++;                                                \
00409         }                                                           \
00410     }                                                               \
00411                                                                     \
00412     if (!count) {                                                   \
00413         av_freep(&fmts->list);                                      \
00414         av_freep(&fmts->refs);                                      \
00415         av_freep(&fmts);                                            \
00416     }                                                               \
00417 }
00418 
00419 void ff_set_common_channel_layouts(AVFilterContext *ctx,
00420                                    AVFilterChannelLayouts *layouts)
00421 {
00422     SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
00423                        ff_channel_layouts_ref, channel_layouts);
00424 }
00425 
00426 void ff_set_common_samplerates(AVFilterContext *ctx,
00427                                AVFilterFormats *samplerates)
00428 {
00429     SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
00430                        ff_formats_ref, formats);
00431 }
00432 
00438 void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
00439 {
00440     SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
00441                        ff_formats_ref, formats);
00442 }
00443 
00444 int ff_default_query_formats(AVFilterContext *ctx)
00445 {
00446     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
00447                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
00448                             AVMEDIA_TYPE_VIDEO;
00449 
00450     ff_set_common_formats(ctx, ff_all_formats(type));
00451     if (type == AVMEDIA_TYPE_AUDIO) {
00452         ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
00453         ff_set_common_samplerates(ctx, ff_all_samplerates());
00454     }
00455 
00456     return 0;
00457 }
00458 
00459 
00460 
00461 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
00462 {
00463     char *tail;
00464     int pix_fmt = av_get_pix_fmt(arg);
00465     if (pix_fmt == PIX_FMT_NONE) {
00466         pix_fmt = strtol(arg, &tail, 0);
00467         if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
00468             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
00469             return AVERROR(EINVAL);
00470         }
00471     }
00472     *ret = pix_fmt;
00473     return 0;
00474 }
00475 
00476 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
00477 {
00478     char *tail;
00479     int sfmt = av_get_sample_fmt(arg);
00480     if (sfmt == AV_SAMPLE_FMT_NONE) {
00481         sfmt = strtol(arg, &tail, 0);
00482         if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
00483             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
00484             return AVERROR(EINVAL);
00485         }
00486     }
00487     *ret = sfmt;
00488     return 0;
00489 }
00490 
00491 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
00492 {
00493     AVRational r;
00494     if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
00495         av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
00496         return AVERROR(EINVAL);
00497     }
00498     *ret = r;
00499     return 0;
00500 }
00501 
00502 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
00503 {
00504     char *tail;
00505     double srate = av_strtod(arg, &tail);
00506     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
00507         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
00508         return AVERROR(EINVAL);
00509     }
00510     *ret = srate;
00511     return 0;
00512 }
00513 
00514 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
00515 {
00516     char *tail;
00517     int64_t chlayout = av_get_channel_layout(arg);
00518     if (chlayout == 0) {
00519         chlayout = strtol(arg, &tail, 10);
00520         if (*tail || chlayout == 0) {
00521             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
00522             return AVERROR(EINVAL);
00523         }
00524     }
00525     *ret = chlayout;
00526     return 0;
00527 }
00528 
00529 #ifdef TEST
00530 
00531 #undef printf
00532 
00533 int main(void)
00534 {
00535     const int64_t *cl;
00536     char buf[512];
00537 
00538     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
00539         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
00540         printf("%s\n", buf);
00541     }
00542 
00543     return 0;
00544 }
00545 
00546 #endif
00547