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