]> git.sesse.net Git - ffmpeg/blob - libavfilter/formats.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavfilter / formats.c
1 /*
2  * Filter layer - format negotiation
3  * Copyright (c) 2007 Bobby Bingham
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/eval.h"
23 #include "libavutil/pixdesc.h"
24 #include "libavutil/audioconvert.h"
25 #include "avfilter.h"
26 #include "internal.h"
27
28 /**
29  * Add all refs from a to ret and destroy a.
30  */
31 static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
32 {
33     int i;
34
35     for (i = 0; i < a->refcount; i++) {
36         ret->refs[ret->refcount] = a->refs[i];
37         *ret->refs[ret->refcount++] = ret;
38     }
39
40     av_free(a->refs);
41     av_free(a->formats);
42     av_free(a);
43 }
44
45 AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
46 {
47     AVFilterFormats *ret;
48     unsigned i, j, k = 0;
49
50     if (a == b) return a;
51
52     ret = av_mallocz(sizeof(AVFilterFormats));
53
54     /* merge list of formats */
55     ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
56                                                            b->format_count));
57     for (i = 0; i < a->format_count; i++)
58         for (j = 0; j < b->format_count; j++)
59             if (a->formats[i] == b->formats[j]){
60                 if(k >= FFMIN(a->format_count, b->format_count)){
61                     av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n");
62                     av_free(ret->formats);
63                     av_free(ret);
64                     return NULL;
65                 }
66                 ret->formats[k++] = a->formats[i];
67             }
68
69     ret->format_count = k;
70     /* check that there was at least one common format */
71     if (!ret->format_count) {
72         av_free(ret->formats);
73         av_free(ret);
74         return NULL;
75     }
76
77     ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
78
79     merge_ref(ret, a);
80     merge_ref(ret, b);
81
82     return ret;
83 }
84
85 int ff_fmt_is_in(int fmt, const int *fmts)
86 {
87     const int *p;
88
89     for (p = fmts; *p != -1; p++) {
90         if (fmt == *p)
91             return 1;
92     }
93     return 0;
94 }
95
96 #define COPY_INT_LIST(list_copy, list, type) {                          \
97     int count = 0;                                                      \
98     if (list)                                                           \
99         for (count = 0; list[count] != -1; count++)                     \
100             ;                                                           \
101     list_copy = av_calloc(count+1, sizeof(type));                       \
102     if (list_copy) {                                                    \
103         memcpy(list_copy, list, sizeof(type) * count);                  \
104         list_copy[count] = -1;                                          \
105     }                                                                   \
106 }
107
108 int *ff_copy_int_list(const int * const list)
109 {
110     int *ret = NULL;
111     COPY_INT_LIST(ret, list, int);
112     return ret;
113 }
114
115 int64_t *ff_copy_int64_list(const int64_t * const list)
116 {
117     int64_t *ret = NULL;
118     COPY_INT_LIST(ret, list, int64_t);
119     return ret;
120 }
121
122 #define MAKE_FORMAT_LIST()                                              \
123     AVFilterFormats *formats;                                           \
124     int count = 0;                                                      \
125     if (fmts)                                                           \
126         for (count = 0; fmts[count] != -1; count++)                     \
127             ;                                                           \
128     formats = av_mallocz(sizeof(AVFilterFormats));                      \
129     if (!formats) return NULL;                                          \
130     formats->format_count = count;                                      \
131     if (count) {                                                        \
132         formats->formats = av_malloc(sizeof(*formats->formats)*count);  \
133         if (!formats->formats) {                                        \
134             av_free(formats);                                           \
135             return NULL;                                                \
136         }                                                               \
137     }
138
139 AVFilterFormats *avfilter_make_format_list(const int *fmts)
140 {
141     MAKE_FORMAT_LIST();
142     while (count--)
143         formats->formats[count] = fmts[count];
144
145     return formats;
146 }
147
148 AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts)
149 {
150     MAKE_FORMAT_LIST();
151     if (count)
152         memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
153
154     return formats;
155 }
156
157 int avfilter_add_format(AVFilterFormats **avff, int64_t fmt)
158 {
159     int64_t *fmts;
160
161     if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats))))
162         return AVERROR(ENOMEM);
163
164     fmts = av_realloc((*avff)->formats,
165                       sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
166     if (!fmts)
167         return AVERROR(ENOMEM);
168
169     (*avff)->formats = fmts;
170     (*avff)->formats[(*avff)->format_count++] = fmt;
171     return 0;
172 }
173
174 #if FF_API_OLD_ALL_FORMATS_API
175 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
176 {
177     return avfilter_make_all_formats(type);
178 }
179 #endif
180
181 AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
182 {
183     AVFilterFormats *ret = NULL;
184     int fmt;
185     int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB    :
186                       type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
187
188     for (fmt = 0; fmt < num_formats; fmt++)
189         if ((type != AVMEDIA_TYPE_VIDEO) ||
190             (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
191             avfilter_add_format(&ret, fmt);
192
193     return ret;
194 }
195
196 const int64_t avfilter_all_channel_layouts[] = {
197 #include "all_channel_layouts.h"
198     -1
199 };
200
201 AVFilterFormats *avfilter_make_all_channel_layouts(void)
202 {
203     return avfilter_make_format64_list(avfilter_all_channel_layouts);
204 }
205
206 AVFilterFormats *avfilter_make_all_packing_formats(void)
207 {
208     static const int packing[] = {
209         AVFILTER_PACKED,
210         AVFILTER_PLANAR,
211         -1,
212     };
213
214     return avfilter_make_format_list(packing);
215 }
216
217 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
218 {
219     *ref = f;
220     f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
221     f->refs[f->refcount-1] = ref;
222 }
223
224 static int find_ref_index(AVFilterFormats **ref)
225 {
226     int i;
227     for (i = 0; i < (*ref)->refcount; i++)
228         if ((*ref)->refs[i] == ref)
229             return i;
230     return -1;
231 }
232
233 void avfilter_formats_unref(AVFilterFormats **ref)
234 {
235     int idx;
236
237     if (!*ref)
238         return;
239
240     idx = find_ref_index(ref);
241
242     if (idx >= 0)
243         memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
244             sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
245
246     if (!--(*ref)->refcount) {
247         av_free((*ref)->formats);
248         av_free((*ref)->refs);
249         av_free(*ref);
250     }
251     *ref = NULL;
252 }
253
254 void avfilter_formats_changeref(AVFilterFormats **oldref,
255                                 AVFilterFormats **newref)
256 {
257     int idx = find_ref_index(oldref);
258
259     if (idx >= 0) {
260         (*oldref)->refs[idx] = newref;
261         *newref = *oldref;
262         *oldref = NULL;
263     }
264 }
265
266 /* internal functions for parsing audio format arguments */
267
268 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
269 {
270     char *tail;
271     int pix_fmt = av_get_pix_fmt(arg);
272     if (pix_fmt == PIX_FMT_NONE) {
273         pix_fmt = strtol(arg, &tail, 0);
274         if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
275             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
276             return AVERROR(EINVAL);
277         }
278     }
279     *ret = pix_fmt;
280     return 0;
281 }
282
283 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
284 {
285     char *tail;
286     int sfmt = av_get_sample_fmt(arg);
287     if (sfmt == AV_SAMPLE_FMT_NONE) {
288         sfmt = strtol(arg, &tail, 0);
289         if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
290             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
291             return AVERROR(EINVAL);
292         }
293     }
294     *ret = sfmt;
295     return 0;
296 }
297
298 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
299 {
300     char *tail;
301     double srate = av_strtod(arg, &tail);
302     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
303         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
304         return AVERROR(EINVAL);
305     }
306     *ret = srate;
307     return 0;
308 }
309
310 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
311 {
312     char *tail;
313     int64_t chlayout = av_get_channel_layout(arg);
314     if (chlayout == 0) {
315         chlayout = strtol(arg, &tail, 10);
316         if (*tail || chlayout == 0) {
317             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
318             return AVERROR(EINVAL);
319         }
320     }
321     *ret = chlayout;
322     return 0;
323 }
324
325 int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx)
326 {
327     char *tail;
328     int planar = strtol(arg, &tail, 10);
329     if (*tail) {
330         planar = !strcmp(arg, "packed") ? 0:
331                  !strcmp(arg, "planar") ? 1: -1;
332     }
333
334     if (planar != 0 && planar != 1) {
335         av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg);
336         return AVERROR(EINVAL);
337     }
338     *ret = planar;
339     return 0;
340 }
341
342 #ifdef TEST
343
344 #undef printf
345
346 int main(void)
347 {
348     const int64_t *cl;
349     char buf[512];
350
351     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
352         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
353         printf("%s\n", buf);
354     }
355
356     return 0;
357 }
358
359 #endif