Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / 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)
51         return a;
52
53     ret = av_mallocz(sizeof(*ret));
54
55     /* merge list of formats */
56     ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
57                                                            b->format_count));
58     for (i = 0; i < a->format_count; i++)
59         for (j = 0; j < b->format_count; j++)
60             if (a->formats[i] == b->formats[j]){
61                 if(k >= FFMIN(a->format_count, b->format_count)){
62                     av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n");
63                     av_free(ret->formats);
64                     av_free(ret);
65                     return NULL;
66                 }
67                 ret->formats[k++] = a->formats[i];
68             }
69
70     ret->format_count = k;
71     /* check that there was at least one common format */
72     if (!ret->format_count) {
73         av_free(ret->formats);
74         av_free(ret);
75         return NULL;
76     }
77
78     ret->refs = av_malloc(sizeof(*ret->refs) * (a->refcount + b->refcount));
79
80     merge_ref(ret, a);
81     merge_ref(ret, b);
82
83     return ret;
84 }
85
86 int ff_fmt_is_in(int fmt, const int *fmts)
87 {
88     const int *p;
89
90     for (p = fmts; *p != -1; p++) {
91         if (fmt == *p)
92             return 1;
93     }
94     return 0;
95 }
96
97 #define COPY_INT_LIST(list_copy, list, type) {                          \
98     int count = 0;                                                      \
99     if (list)                                                           \
100         for (count = 0; list[count] != -1; count++)                     \
101             ;                                                           \
102     list_copy = av_calloc(count+1, sizeof(type));                       \
103     if (list_copy) {                                                    \
104         memcpy(list_copy, list, sizeof(type) * count);                  \
105         list_copy[count] = -1;                                          \
106     }                                                                   \
107 }
108
109 int *ff_copy_int_list(const int * const list)
110 {
111     int *ret = NULL;
112     COPY_INT_LIST(ret, list, int);
113     return ret;
114 }
115
116 int64_t *ff_copy_int64_list(const int64_t * const list)
117 {
118     int64_t *ret = NULL;
119     COPY_INT_LIST(ret, list, int64_t);
120     return ret;
121 }
122
123 #define MAKE_FORMAT_LIST()                                              \
124     AVFilterFormats *formats;                                           \
125     int count = 0;                                                      \
126     if (fmts)                                                           \
127         for (count = 0; fmts[count] != -1; count++)                     \
128             ;                                                           \
129     formats = av_mallocz(sizeof(AVFilterFormats));                      \
130     if (!formats) return NULL;                                          \
131     formats->format_count = count;                                      \
132     if (count) {                                                        \
133         formats->formats = av_malloc(sizeof(*formats->formats)*count);  \
134         if (!formats->formats) {                                        \
135             av_free(formats);                                           \
136             return NULL;                                                \
137         }                                                               \
138     }
139
140 AVFilterFormats *avfilter_make_format_list(const int *fmts)
141 {
142     MAKE_FORMAT_LIST();
143     while (count--)
144         formats->formats[count] = fmts[count];
145
146     return formats;
147 }
148
149 AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts)
150 {
151     MAKE_FORMAT_LIST();
152     if (count)
153         memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
154
155     return formats;
156 }
157
158 int avfilter_add_format(AVFilterFormats **avff, int64_t fmt)
159 {
160     int64_t *fmts;
161
162     if (!(*avff) && !(*avff = av_mallocz(sizeof(**avff))))
163         return AVERROR(ENOMEM);
164
165     fmts = av_realloc((*avff)->formats,
166                       sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
167     if (!fmts)
168         return AVERROR(ENOMEM);
169
170     (*avff)->formats = fmts;
171     (*avff)->formats[(*avff)->format_count++] = fmt;
172     return 0;
173 }
174
175 #if FF_API_OLD_ALL_FORMATS_API
176 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
177 {
178     return avfilter_make_all_formats(type);
179 }
180 #endif
181
182 AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
183 {
184     AVFilterFormats *ret = NULL;
185     int fmt;
186     int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB    :
187                       type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
188
189     for (fmt = 0; fmt < num_formats; fmt++)
190         if ((type != AVMEDIA_TYPE_VIDEO) ||
191             (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
192             avfilter_add_format(&ret, fmt);
193
194     return ret;
195 }
196
197 const int64_t avfilter_all_channel_layouts[] = {
198 #include "all_channel_layouts.h"
199     -1
200 };
201
202 AVFilterFormats *avfilter_make_all_channel_layouts(void)
203 {
204     return avfilter_make_format64_list(avfilter_all_channel_layouts);
205 }
206
207 AVFilterFormats *avfilter_make_all_packing_formats(void)
208 {
209     static const int packing[] = {
210         AVFILTER_PACKED,
211         AVFILTER_PLANAR,
212         -1,
213     };
214
215     return avfilter_make_format_list(packing);
216 }
217
218 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
219 {
220     *ref = f;
221     f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount);
222     f->refs[f->refcount-1] = ref;
223 }
224
225 static int find_ref_index(AVFilterFormats **ref)
226 {
227     int i;
228     for (i = 0; i < (*ref)->refcount; i++)
229         if ((*ref)->refs[i] == ref)
230             return i;
231     return -1;
232 }
233
234 void avfilter_formats_unref(AVFilterFormats **ref)
235 {
236     int idx;
237
238     if (!*ref)
239         return;
240
241     idx = find_ref_index(ref);
242
243     if(idx >= 0)
244         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,
245             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1));
246
247     if (!--(*ref)->refcount) {
248         av_free((*ref)->formats);
249         av_free((*ref)->refs);
250         av_free(*ref);
251     }
252     *ref = NULL;
253 }
254
255 void avfilter_formats_changeref(AVFilterFormats **oldref,
256                                 AVFilterFormats **newref)
257 {
258     int idx = find_ref_index(oldref);
259
260     if (idx >= 0) {
261         (*oldref)->refs[idx] = newref;
262         *newref = *oldref;
263         *oldref = NULL;
264     }
265 }
266
267 /* internal functions for parsing audio format arguments */
268
269 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
270 {
271     char *tail;
272     int pix_fmt = av_get_pix_fmt(arg);
273     if (pix_fmt == PIX_FMT_NONE) {
274         pix_fmt = strtol(arg, &tail, 0);
275         if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
276             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
277             return AVERROR(EINVAL);
278         }
279     }
280     *ret = pix_fmt;
281     return 0;
282 }
283
284 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
285 {
286     char *tail;
287     int sfmt = av_get_sample_fmt(arg);
288     if (sfmt == AV_SAMPLE_FMT_NONE) {
289         sfmt = strtol(arg, &tail, 0);
290         if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
291             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
292             return AVERROR(EINVAL);
293         }
294     }
295     *ret = sfmt;
296     return 0;
297 }
298
299 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
300 {
301     char *tail;
302     double srate = av_strtod(arg, &tail);
303     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
304         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
305         return AVERROR(EINVAL);
306     }
307     *ret = srate;
308     return 0;
309 }
310
311 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
312 {
313     char *tail;
314     int64_t chlayout = av_get_channel_layout(arg);
315     if (chlayout == 0) {
316         chlayout = strtol(arg, &tail, 10);
317         if (*tail || chlayout == 0) {
318             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
319             return AVERROR(EINVAL);
320         }
321     }
322     *ret = chlayout;
323     return 0;
324 }
325
326 int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx)
327 {
328     char *tail;
329     int planar = strtol(arg, &tail, 10);
330     if (*tail) {
331         planar = !strcmp(arg, "packed") ? 0:
332                  !strcmp(arg, "planar") ? 1: -1;
333     }
334
335     if (planar != 0 && planar != 1) {
336         av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg);
337         return AVERROR(EINVAL);
338     }
339     *ret = planar;
340     return 0;
341 }
342
343 #ifdef TEST
344
345 #undef printf
346
347 int main(void)
348 {
349     const int64_t *cl;
350     char buf[512];
351
352     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
353         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
354         printf("%s\n", buf);
355     }
356
357     return 0;
358 }
359
360 #endif
361