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 if (a == b)
00053 return a;
00054
00055 ret = av_mallocz(sizeof(AVFilterFormats));
00056
00057
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
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
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