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/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     ret = av_mallocz(sizeof(AVFilterFormats));
00053 
00054     
00055     ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
00056                                                            b->format_count));
00057     for (i = 0; i < a->format_count; i++)
00058         for (j = 0; j < b->format_count; j++)
00059             if (a->formats[i] == b->formats[j]){
00060                 if(k >= FFMIN(a->format_count, b->format_count)){
00061                     av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n");
00062                     av_free(ret->formats);
00063                     av_free(ret);
00064                     return NULL;
00065                 }
00066                 ret->formats[k++] = a->formats[i];
00067             }
00068 
00069     ret->format_count = k;
00070     
00071     if (!ret->format_count) {
00072         av_free(ret->formats);
00073         av_free(ret);
00074         return NULL;
00075     }
00076 
00077     ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
00078 
00079     merge_ref(ret, a);
00080     merge_ref(ret, b);
00081 
00082     return ret;
00083 }
00084 
00085 int ff_fmt_is_in(int fmt, const int *fmts)
00086 {
00087     const int *p;
00088 
00089     for (p = fmts; *p != -1; p++) {
00090         if (fmt == *p)
00091             return 1;
00092     }
00093     return 0;
00094 }
00095 
00096 #define MAKE_FORMAT_LIST()                                              \
00097     AVFilterFormats *formats;                                           \
00098     int count = 0;                                                      \
00099     if (fmts)                                                           \
00100         for (count = 0; fmts[count] != -1; count++)                     \
00101             ;                                                           \
00102     formats = av_mallocz(sizeof(AVFilterFormats));                      \
00103     if (!formats) return NULL;                                          \
00104     formats->format_count = count;                                      \
00105     if (count) {                                                        \
00106         formats->formats = av_malloc(sizeof(*formats->formats)*count);  \
00107         if (!formats->formats) {                                        \
00108             av_free(formats);                                           \
00109             return NULL;                                                \
00110         }                                                               \
00111     }
00112 
00113 AVFilterFormats *avfilter_make_format_list(const int *fmts)
00114 {
00115     MAKE_FORMAT_LIST();
00116     while (count--)
00117         formats->formats[count] = fmts[count];
00118 
00119     return formats;
00120 }
00121 
00122 AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts)
00123 {
00124     MAKE_FORMAT_LIST();
00125     if (count)
00126         memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
00127 
00128     return formats;
00129 }
00130 
00131 int avfilter_add_format(AVFilterFormats **avff, int64_t fmt)
00132 {
00133     int64_t *fmts;
00134 
00135     if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats))))
00136         return AVERROR(ENOMEM);
00137 
00138     fmts = av_realloc((*avff)->formats,
00139                       sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
00140     if (!fmts)
00141         return AVERROR(ENOMEM);
00142 
00143     (*avff)->formats = fmts;
00144     (*avff)->formats[(*avff)->format_count++] = fmt;
00145     return 0;
00146 }
00147 
00148 #if FF_API_OLD_ALL_FORMATS_API
00149 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
00150 {
00151     return avfilter_make_all_formats(type);
00152 }
00153 #endif
00154 
00155 AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
00156 {
00157     AVFilterFormats *ret = NULL;
00158     int fmt;
00159     int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB    :
00160                       type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
00161 
00162     for (fmt = 0; fmt < num_formats; fmt++)
00163         if ((type != AVMEDIA_TYPE_VIDEO) ||
00164             (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
00165             avfilter_add_format(&ret, fmt);
00166 
00167     return ret;
00168 }
00169 
00170 const int64_t avfilter_all_channel_layouts[] = {
00171 #include "all_channel_layouts.h"
00172     -1
00173 };
00174 
00175 AVFilterFormats *avfilter_make_all_channel_layouts(void)
00176 {
00177     return avfilter_make_format64_list(avfilter_all_channel_layouts);
00178 }
00179 
00180 AVFilterFormats *avfilter_make_all_packing_formats(void)
00181 {
00182     static const int packing[] = {
00183         AVFILTER_PACKED,
00184         AVFILTER_PLANAR,
00185         -1,
00186     };
00187 
00188     return avfilter_make_format_list(packing);
00189 }
00190 
00191 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
00192 {
00193     *ref = f;
00194     f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
00195     f->refs[f->refcount-1] = ref;
00196 }
00197 
00198 static int find_ref_index(AVFilterFormats **ref)
00199 {
00200     int i;
00201     for (i = 0; i < (*ref)->refcount; i++)
00202         if ((*ref)->refs[i] == ref)
00203             return i;
00204     return -1;
00205 }
00206 
00207 void avfilter_formats_unref(AVFilterFormats **ref)
00208 {
00209     int idx;
00210 
00211     if (!*ref)
00212         return;
00213 
00214     idx = find_ref_index(ref);
00215 
00216     if (idx >= 0)
00217         memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
00218             sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
00219 
00220     if (!--(*ref)->refcount) {
00221         av_free((*ref)->formats);
00222         av_free((*ref)->refs);
00223         av_free(*ref);
00224     }
00225     *ref = NULL;
00226 }
00227 
00228 void avfilter_formats_changeref(AVFilterFormats **oldref,
00229                                 AVFilterFormats **newref)
00230 {
00231     int idx = find_ref_index(oldref);
00232 
00233     if (idx >= 0) {
00234         (*oldref)->refs[idx] = newref;
00235         *newref = *oldref;
00236         *oldref = NULL;
00237     }
00238 }
00239 
00240 
00241 
00242 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
00243 {
00244     char *tail;
00245     int pix_fmt = av_get_pix_fmt(arg);
00246     if (pix_fmt == PIX_FMT_NONE) {
00247         pix_fmt = strtol(arg, &tail, 0);
00248         if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
00249             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
00250             return AVERROR(EINVAL);
00251         }
00252     }
00253     *ret = pix_fmt;
00254     return 0;
00255 }
00256 
00257 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
00258 {
00259     char *tail;
00260     int sfmt = av_get_sample_fmt(arg);
00261     if (sfmt == AV_SAMPLE_FMT_NONE) {
00262         sfmt = strtol(arg, &tail, 0);
00263         if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
00264             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
00265             return AVERROR(EINVAL);
00266         }
00267     }
00268     *ret = sfmt;
00269     return 0;
00270 }
00271 
00272 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
00273 {
00274     char *tail;
00275     double srate = av_strtod(arg, &tail);
00276     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
00277         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
00278         return AVERROR(EINVAL);
00279     }
00280     *ret = srate;
00281     return 0;
00282 }
00283 
00284 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
00285 {
00286     char *tail;
00287     int64_t chlayout = av_get_channel_layout(arg);
00288     if (chlayout == 0) {
00289         chlayout = strtol(arg, &tail, 10);
00290         if (*tail || chlayout == 0) {
00291             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
00292             return AVERROR(EINVAL);
00293         }
00294     }
00295     *ret = chlayout;
00296     return 0;
00297 }
00298 
00299 int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx)
00300 {
00301     char *tail;
00302     int planar = strtol(arg, &tail, 10);
00303     if (*tail) {
00304         planar = !strcmp(arg, "packed") ? 0:
00305                  !strcmp(arg, "planar") ? 1: -1;
00306     }
00307 
00308     if (planar != 0 && planar != 1) {
00309         av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg);
00310         return AVERROR(EINVAL);
00311     }
00312     *ret = planar;
00313     return 0;
00314 }
00315 
00316 #ifdef TEST
00317 
00318 #undef printf
00319 
00320 int main(void)
00321 {
00322     const int64_t *cl;
00323     char buf[512];
00324 
00325     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
00326         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
00327         printf("%s\n", buf);
00328     }
00329 
00330     return 0;
00331 }
00332 
00333 #endif