• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavfilter/formats.c

Go to the documentation of this file.
00001 /*
00002  * Filter layer - format negotiation
00003  * Copyright (c) 2007 Bobby Bingham
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "libavutil/eval.h"
00023 #include "libavutil/pixdesc.h"
00024 #include "libavutil/audioconvert.h"
00025 #include "avfilter.h"
00026 #include "internal.h"
00027 
00031 static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
00032 {
00033     int i;
00034 
00035     for (i = 0; i < a->refcount; i++) {
00036         ret->refs[ret->refcount] = a->refs[i];
00037         *ret->refs[ret->refcount++] = ret;
00038     }
00039 
00040     av_free(a->refs);
00041     av_free(a->formats);
00042     av_free(a);
00043 }
00044 
00045 AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
00046 {
00047     AVFilterFormats *ret;
00048     unsigned i, j, k = 0;
00049 
00050     if (a == b) return a;
00051 
00052     if (a == b)
00053         return a;
00054 
00055     ret = av_mallocz(sizeof(AVFilterFormats));
00056 
00057     /* merge list of formats */
00058     ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
00059                                                            b->format_count));
00060     for (i = 0; i < a->format_count; i++)
00061         for (j = 0; j < b->format_count; j++)
00062             if (a->formats[i] == b->formats[j]){
00063                 if(k >= FFMIN(a->format_count, b->format_count)){
00064                     av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n");
00065                     av_free(ret->formats);
00066                     av_free(ret);
00067                     return NULL;
00068                 }
00069                 ret->formats[k++] = a->formats[i];
00070             }
00071 
00072     ret->format_count = k;
00073     /* check that there was at least one common format */
00074     if (!ret->format_count) {
00075         av_free(ret->formats);
00076         av_free(ret);
00077         return NULL;
00078     }
00079 
00080     ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
00081 
00082     merge_ref(ret, a);
00083     merge_ref(ret, b);
00084 
00085     return ret;
00086 }
00087 
00088 int ff_fmt_is_in(int fmt, const int *fmts)
00089 {
00090     const int *p;
00091 
00092     for (p = fmts; *p != -1; p++) {
00093         if (fmt == *p)
00094             return 1;
00095     }
00096     return 0;
00097 }
00098 
00099 #define COPY_INT_LIST(list_copy, list, type) {                          \
00100     int count = 0;                                                      \
00101     if (list)                                                           \
00102         for (count = 0; list[count] != -1; count++)                     \
00103             ;                                                           \
00104     list_copy = av_calloc(count+1, sizeof(type));                       \
00105     if (list_copy) {                                                    \
00106         memcpy(list_copy, list, sizeof(type) * count);                  \
00107         list_copy[count] = -1;                                          \
00108     }                                                                   \
00109 }
00110 
00111 int *ff_copy_int_list(const int * const list)
00112 {
00113     int *ret = NULL;
00114     COPY_INT_LIST(ret, list, int);
00115     return ret;
00116 }
00117 
00118 int64_t *ff_copy_int64_list(const int64_t * const list)
00119 {
00120     int64_t *ret = NULL;
00121     COPY_INT_LIST(ret, list, int64_t);
00122     return ret;
00123 }
00124 
00125 #define MAKE_FORMAT_LIST()                                              \
00126     AVFilterFormats *formats;                                           \
00127     int count = 0;                                                      \
00128     if (fmts)                                                           \
00129         for (count = 0; fmts[count] != -1; count++)                     \
00130             ;                                                           \
00131     formats = av_mallocz(sizeof(AVFilterFormats));                      \
00132     if (!formats) return NULL;                                          \
00133     formats->format_count = count;                                      \
00134     if (count) {                                                        \
00135         formats->formats = av_malloc(sizeof(*formats->formats)*count);  \
00136         if (!formats->formats) {                                        \
00137             av_free(formats);                                           \
00138             return NULL;                                                \
00139         }                                                               \
00140     }
00141 
00142 AVFilterFormats *avfilter_make_format_list(const int *fmts)
00143 {
00144     MAKE_FORMAT_LIST();
00145     while (count--)
00146         formats->formats[count] = fmts[count];
00147 
00148     return formats;
00149 }
00150 
00151 AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts)
00152 {
00153     MAKE_FORMAT_LIST();
00154     if (count)
00155         memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
00156 
00157     return formats;
00158 }
00159 
00160 int avfilter_add_format(AVFilterFormats **avff, int64_t fmt)
00161 {
00162     int64_t *fmts;
00163 
00164     if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats))))
00165         return AVERROR(ENOMEM);
00166 
00167     fmts = av_realloc((*avff)->formats,
00168                       sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
00169     if (!fmts)
00170         return AVERROR(ENOMEM);
00171 
00172     (*avff)->formats = fmts;
00173     (*avff)->formats[(*avff)->format_count++] = fmt;
00174     return 0;
00175 }
00176 
00177 #if FF_API_OLD_ALL_FORMATS_API
00178 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
00179 {
00180     return avfilter_make_all_formats(type);
00181 }
00182 #endif
00183 
00184 AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
00185 {
00186     AVFilterFormats *ret = NULL;
00187     int fmt;
00188     int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB    :
00189                       type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
00190 
00191     for (fmt = 0; fmt < num_formats; fmt++)
00192         if ((type != AVMEDIA_TYPE_VIDEO) ||
00193             (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
00194             avfilter_add_format(&ret, fmt);
00195 
00196     return ret;
00197 }
00198 
00199 const int64_t avfilter_all_channel_layouts[] = {
00200 #include "all_channel_layouts.h"
00201     -1
00202 };
00203 
00204 AVFilterFormats *avfilter_make_all_channel_layouts(void)
00205 {
00206     return avfilter_make_format64_list(avfilter_all_channel_layouts);
00207 }
00208 
00209 AVFilterFormats *avfilter_make_all_packing_formats(void)
00210 {
00211     static const int packing[] = {
00212         AVFILTER_PACKED,
00213         AVFILTER_PLANAR,
00214         -1,
00215     };
00216 
00217     return avfilter_make_format_list(packing);
00218 }
00219 
00220 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
00221 {
00222     *ref = f;
00223     f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
00224     f->refs[f->refcount-1] = ref;
00225 }
00226 
00227 static int find_ref_index(AVFilterFormats **ref)
00228 {
00229     int i;
00230     for (i = 0; i < (*ref)->refcount; i++)
00231         if ((*ref)->refs[i] == ref)
00232             return i;
00233     return -1;
00234 }
00235 
00236 void avfilter_formats_unref(AVFilterFormats **ref)
00237 {
00238     int idx;
00239 
00240     if (!*ref)
00241         return;
00242 
00243     idx = find_ref_index(ref);
00244 
00245     if (idx >= 0)
00246         memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
00247             sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
00248 
00249     if (!--(*ref)->refcount) {
00250         av_free((*ref)->formats);
00251         av_free((*ref)->refs);
00252         av_free(*ref);
00253     }
00254     *ref = NULL;
00255 }
00256 
00257 void avfilter_formats_changeref(AVFilterFormats **oldref,
00258                                 AVFilterFormats **newref)
00259 {
00260     int idx = find_ref_index(oldref);
00261 
00262     if (idx >= 0) {
00263         (*oldref)->refs[idx] = newref;
00264         *newref = *oldref;
00265         *oldref = NULL;
00266     }
00267 }
00268 
00269 /* internal functions for parsing audio format arguments */
00270 
00271 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
00272 {
00273     char *tail;
00274     int pix_fmt = av_get_pix_fmt(arg);
00275     if (pix_fmt == PIX_FMT_NONE) {
00276         pix_fmt = strtol(arg, &tail, 0);
00277         if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
00278             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
00279             return AVERROR(EINVAL);
00280         }
00281     }
00282     *ret = pix_fmt;
00283     return 0;
00284 }
00285 
00286 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
00287 {
00288     char *tail;
00289     int sfmt = av_get_sample_fmt(arg);
00290     if (sfmt == AV_SAMPLE_FMT_NONE) {
00291         sfmt = strtol(arg, &tail, 0);
00292         if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
00293             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
00294             return AVERROR(EINVAL);
00295         }
00296     }
00297     *ret = sfmt;
00298     return 0;
00299 }
00300 
00301 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
00302 {
00303     char *tail;
00304     double srate = av_strtod(arg, &tail);
00305     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
00306         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
00307         return AVERROR(EINVAL);
00308     }
00309     *ret = srate;
00310     return 0;
00311 }
00312 
00313 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
00314 {
00315     char *tail;
00316     int64_t chlayout = av_get_channel_layout(arg);
00317     if (chlayout == 0) {
00318         chlayout = strtol(arg, &tail, 10);
00319         if (*tail || chlayout == 0) {
00320             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
00321             return AVERROR(EINVAL);
00322         }
00323     }
00324     *ret = chlayout;
00325     return 0;
00326 }
00327 
00328 int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx)
00329 {
00330     char *tail;
00331     int planar = strtol(arg, &tail, 10);
00332     if (*tail) {
00333         planar = !strcmp(arg, "packed") ? 0:
00334                  !strcmp(arg, "planar") ? 1: -1;
00335     }
00336 
00337     if (planar != 0 && planar != 1) {
00338         av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg);
00339         return AVERROR(EINVAL);
00340     }
00341     *ret = planar;
00342     return 0;
00343 }
00344 
00345 #ifdef TEST
00346 
00347 #undef printf
00348 
00349 int main(void)
00350 {
00351     const int64_t *cl;
00352     char buf[512];
00353 
00354     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
00355         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
00356         printf("%s\n", buf);
00357     }
00358 
00359     return 0;
00360 }
00361 
00362 #endif
Generated on Fri Feb 1 2013 14:34:48 for FFmpeg by doxygen 1.7.1