yading@11
|
1 /*
|
yading@11
|
2 * AVOptions
|
yading@11
|
3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
|
yading@11
|
4 *
|
yading@11
|
5 * This file is part of FFmpeg.
|
yading@11
|
6 *
|
yading@11
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
9 * License as published by the Free Software Foundation; either
|
yading@11
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
11 *
|
yading@11
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
15 * Lesser General Public License for more details.
|
yading@11
|
16 *
|
yading@11
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
20 */
|
yading@11
|
21
|
yading@11
|
22 /**
|
yading@11
|
23 * @file
|
yading@11
|
24 * AVOptions
|
yading@11
|
25 * @author Michael Niedermayer <michaelni@gmx.at>
|
yading@11
|
26 */
|
yading@11
|
27
|
yading@11
|
28 #include "avutil.h"
|
yading@11
|
29 #include "avstring.h"
|
yading@11
|
30 #include "common.h"
|
yading@11
|
31 #include "opt.h"
|
yading@11
|
32 #include "eval.h"
|
yading@11
|
33 #include "dict.h"
|
yading@11
|
34 #include "log.h"
|
yading@11
|
35 #include "parseutils.h"
|
yading@11
|
36 #include "pixdesc.h"
|
yading@11
|
37 #include "mathematics.h"
|
yading@11
|
38 #include "samplefmt.h"
|
yading@11
|
39
|
yading@11
|
40 #include <float.h>
|
yading@11
|
41
|
yading@11
|
42 #if FF_API_FIND_OPT
|
yading@11
|
43 //FIXME order them and do a bin search
|
yading@11
|
44 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
|
yading@11
|
45 {
|
yading@11
|
46 const AVOption *o = NULL;
|
yading@11
|
47
|
yading@11
|
48 while ((o = av_next_option(v, o))) {
|
yading@11
|
49 if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
|
yading@11
|
50 return o;
|
yading@11
|
51 }
|
yading@11
|
52 return NULL;
|
yading@11
|
53 }
|
yading@11
|
54 #endif
|
yading@11
|
55
|
yading@11
|
56 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
57 const AVOption *av_next_option(void *obj, const AVOption *last)
|
yading@11
|
58 {
|
yading@11
|
59 return av_opt_next(obj, last);
|
yading@11
|
60 }
|
yading@11
|
61 #endif
|
yading@11
|
62
|
yading@11
|
63 const AVOption *av_opt_next(void *obj, const AVOption *last)
|
yading@11
|
64 {
|
yading@11
|
65 AVClass *class = *(AVClass**)obj;
|
yading@11
|
66 if (!last && class->option && class->option[0].name)
|
yading@11
|
67 return class->option;
|
yading@11
|
68 if (last && last[1].name)
|
yading@11
|
69 return ++last;
|
yading@11
|
70 return NULL;
|
yading@11
|
71 }
|
yading@11
|
72
|
yading@11
|
73 static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
|
yading@11
|
74 {
|
yading@11
|
75 switch (o->type) {
|
yading@11
|
76 case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
|
yading@11
|
77 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
78 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
79 case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
|
yading@11
|
80 case AV_OPT_TYPE_DURATION:
|
yading@11
|
81 case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
|
yading@11
|
82 case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
|
yading@11
|
83 case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
|
yading@11
|
84 case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
|
yading@11
|
85 *den = ((AVRational*)dst)->den;
|
yading@11
|
86 return 0;
|
yading@11
|
87 case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0;
|
yading@11
|
88 }
|
yading@11
|
89 return AVERROR(EINVAL);
|
yading@11
|
90 }
|
yading@11
|
91
|
yading@11
|
92 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
|
yading@11
|
93 {
|
yading@11
|
94 if (o->max*den < num*intnum || o->min*den > num*intnum) {
|
yading@11
|
95 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
|
yading@11
|
96 num*intnum/den, o->name, o->min, o->max);
|
yading@11
|
97 return AVERROR(ERANGE);
|
yading@11
|
98 }
|
yading@11
|
99
|
yading@11
|
100 switch (o->type) {
|
yading@11
|
101 case AV_OPT_TYPE_FLAGS:
|
yading@11
|
102 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
103 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
104 case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
|
yading@11
|
105 case AV_OPT_TYPE_DURATION:
|
yading@11
|
106 case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
|
yading@11
|
107 case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
|
yading@11
|
108 case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
|
yading@11
|
109 case AV_OPT_TYPE_RATIONAL:
|
yading@11
|
110 if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
|
yading@11
|
111 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
|
yading@11
|
112 break;
|
yading@11
|
113 default:
|
yading@11
|
114 return AVERROR(EINVAL);
|
yading@11
|
115 }
|
yading@11
|
116 return 0;
|
yading@11
|
117 }
|
yading@11
|
118
|
yading@11
|
119 static const double const_values[] = {
|
yading@11
|
120 M_PI,
|
yading@11
|
121 M_E,
|
yading@11
|
122 FF_QP2LAMBDA,
|
yading@11
|
123 0
|
yading@11
|
124 };
|
yading@11
|
125
|
yading@11
|
126 static const char * const const_names[] = {
|
yading@11
|
127 "PI",
|
yading@11
|
128 "E",
|
yading@11
|
129 "QP2LAMBDA",
|
yading@11
|
130 0
|
yading@11
|
131 };
|
yading@11
|
132
|
yading@11
|
133 static int hexchar2int(char c) {
|
yading@11
|
134 if (c >= '0' && c <= '9') return c - '0';
|
yading@11
|
135 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
yading@11
|
136 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
yading@11
|
137 return -1;
|
yading@11
|
138 }
|
yading@11
|
139
|
yading@11
|
140 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
|
yading@11
|
141 {
|
yading@11
|
142 int *lendst = (int *)(dst + 1);
|
yading@11
|
143 uint8_t *bin, *ptr;
|
yading@11
|
144 int len = strlen(val);
|
yading@11
|
145
|
yading@11
|
146 av_freep(dst);
|
yading@11
|
147 *lendst = 0;
|
yading@11
|
148
|
yading@11
|
149 if (len & 1)
|
yading@11
|
150 return AVERROR(EINVAL);
|
yading@11
|
151 len /= 2;
|
yading@11
|
152
|
yading@11
|
153 ptr = bin = av_malloc(len);
|
yading@11
|
154 while (*val) {
|
yading@11
|
155 int a = hexchar2int(*val++);
|
yading@11
|
156 int b = hexchar2int(*val++);
|
yading@11
|
157 if (a < 0 || b < 0) {
|
yading@11
|
158 av_free(bin);
|
yading@11
|
159 return AVERROR(EINVAL);
|
yading@11
|
160 }
|
yading@11
|
161 *ptr++ = (a << 4) | b;
|
yading@11
|
162 }
|
yading@11
|
163 *dst = bin;
|
yading@11
|
164 *lendst = len;
|
yading@11
|
165
|
yading@11
|
166 return 0;
|
yading@11
|
167 }
|
yading@11
|
168
|
yading@11
|
169 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
|
yading@11
|
170 {
|
yading@11
|
171 av_freep(dst);
|
yading@11
|
172 *dst = av_strdup(val);
|
yading@11
|
173 return 0;
|
yading@11
|
174 }
|
yading@11
|
175
|
yading@11
|
176 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
|
yading@11
|
177 opt->type == AV_OPT_TYPE_CONST || \
|
yading@11
|
178 opt->type == AV_OPT_TYPE_FLAGS || \
|
yading@11
|
179 opt->type == AV_OPT_TYPE_INT) ? \
|
yading@11
|
180 opt->default_val.i64 : opt->default_val.dbl)
|
yading@11
|
181
|
yading@11
|
182 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
|
yading@11
|
183 {
|
yading@11
|
184 int ret = 0, notfirst = 0;
|
yading@11
|
185 for (;;) {
|
yading@11
|
186 int i, den = 1;
|
yading@11
|
187 char buf[256];
|
yading@11
|
188 int cmd = 0;
|
yading@11
|
189 double d, num = 1;
|
yading@11
|
190 int64_t intnum = 1;
|
yading@11
|
191
|
yading@11
|
192 i = 0;
|
yading@11
|
193 if (*val == '+' || *val == '-') {
|
yading@11
|
194 if (o->type == AV_OPT_TYPE_FLAGS)
|
yading@11
|
195 cmd = *(val++);
|
yading@11
|
196 else if (!notfirst)
|
yading@11
|
197 buf[i++] = *val;
|
yading@11
|
198 }
|
yading@11
|
199
|
yading@11
|
200 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
|
yading@11
|
201 buf[i] = val[i];
|
yading@11
|
202 buf[i] = 0;
|
yading@11
|
203
|
yading@11
|
204 {
|
yading@11
|
205 const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0);
|
yading@11
|
206 if (o_named && o_named->type == AV_OPT_TYPE_CONST)
|
yading@11
|
207 d = DEFAULT_NUMVAL(o_named);
|
yading@11
|
208 else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
|
yading@11
|
209 else if (!strcmp(buf, "max" )) d = o->max;
|
yading@11
|
210 else if (!strcmp(buf, "min" )) d = o->min;
|
yading@11
|
211 else if (!strcmp(buf, "none" )) d = 0;
|
yading@11
|
212 else if (!strcmp(buf, "all" )) d = ~0;
|
yading@11
|
213 else {
|
yading@11
|
214 int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
|
yading@11
|
215 if (res < 0) {
|
yading@11
|
216 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
|
yading@11
|
217 return res;
|
yading@11
|
218 }
|
yading@11
|
219 }
|
yading@11
|
220 }
|
yading@11
|
221 if (o->type == AV_OPT_TYPE_FLAGS) {
|
yading@11
|
222 read_number(o, dst, NULL, NULL, &intnum);
|
yading@11
|
223 if (cmd == '+') d = intnum | (int64_t)d;
|
yading@11
|
224 else if (cmd == '-') d = intnum &~(int64_t)d;
|
yading@11
|
225 } else {
|
yading@11
|
226 read_number(o, dst, &num, &den, &intnum);
|
yading@11
|
227 if (cmd == '+') d = notfirst*num*intnum/den + d;
|
yading@11
|
228 else if (cmd == '-') d = notfirst*num*intnum/den - d;
|
yading@11
|
229 }
|
yading@11
|
230
|
yading@11
|
231 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
|
yading@11
|
232 return ret;
|
yading@11
|
233 val += i;
|
yading@11
|
234 if (!*val)
|
yading@11
|
235 return 0;
|
yading@11
|
236 notfirst = 1;
|
yading@11
|
237 }
|
yading@11
|
238
|
yading@11
|
239 return 0;
|
yading@11
|
240 }
|
yading@11
|
241
|
yading@11
|
242 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
243 int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
|
yading@11
|
244 {
|
yading@11
|
245 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
|
yading@11
|
246 if (o_out)
|
yading@11
|
247 *o_out = o;
|
yading@11
|
248 return av_opt_set(obj, name, val, 0);
|
yading@11
|
249 }
|
yading@11
|
250 #endif
|
yading@11
|
251
|
yading@11
|
252 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
yading@11
|
253 {
|
yading@11
|
254 int ret;
|
yading@11
|
255 void *dst, *target_obj;
|
yading@11
|
256 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
257 if (!o || !target_obj)
|
yading@11
|
258 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
259 if (!val && (o->type != AV_OPT_TYPE_STRING &&
|
yading@11
|
260 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
|
yading@11
|
261 o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
|
yading@11
|
262 o->type != AV_OPT_TYPE_DURATION))
|
yading@11
|
263 return AVERROR(EINVAL);
|
yading@11
|
264
|
yading@11
|
265 dst = ((uint8_t*)target_obj) + o->offset;
|
yading@11
|
266 switch (o->type) {
|
yading@11
|
267 case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
|
yading@11
|
268 case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
|
yading@11
|
269 case AV_OPT_TYPE_FLAGS:
|
yading@11
|
270 case AV_OPT_TYPE_INT:
|
yading@11
|
271 case AV_OPT_TYPE_INT64:
|
yading@11
|
272 case AV_OPT_TYPE_FLOAT:
|
yading@11
|
273 case AV_OPT_TYPE_DOUBLE:
|
yading@11
|
274 case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
|
yading@11
|
275 case AV_OPT_TYPE_IMAGE_SIZE:
|
yading@11
|
276 if (!val || !strcmp(val, "none")) {
|
yading@11
|
277 *(int *)dst = *((int *)dst + 1) = 0;
|
yading@11
|
278 return 0;
|
yading@11
|
279 }
|
yading@11
|
280 ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
|
yading@11
|
281 if (ret < 0)
|
yading@11
|
282 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
|
yading@11
|
283 return ret;
|
yading@11
|
284 case AV_OPT_TYPE_VIDEO_RATE:
|
yading@11
|
285 if (!val) {
|
yading@11
|
286 ret = AVERROR(EINVAL);
|
yading@11
|
287 } else {
|
yading@11
|
288 ret = av_parse_video_rate(dst, val);
|
yading@11
|
289 }
|
yading@11
|
290 if (ret < 0)
|
yading@11
|
291 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
|
yading@11
|
292 return ret;
|
yading@11
|
293 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
294 if (!val || !strcmp(val, "none")) {
|
yading@11
|
295 ret = AV_PIX_FMT_NONE;
|
yading@11
|
296 } else {
|
yading@11
|
297 ret = av_get_pix_fmt(val);
|
yading@11
|
298 if (ret == AV_PIX_FMT_NONE) {
|
yading@11
|
299 char *tail;
|
yading@11
|
300 ret = strtol(val, &tail, 0);
|
yading@11
|
301 if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) {
|
yading@11
|
302 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
|
yading@11
|
303 return AVERROR(EINVAL);
|
yading@11
|
304 }
|
yading@11
|
305 }
|
yading@11
|
306 }
|
yading@11
|
307 *(enum AVPixelFormat *)dst = ret;
|
yading@11
|
308 return 0;
|
yading@11
|
309 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
310 if (!val || !strcmp(val, "none")) {
|
yading@11
|
311 ret = AV_SAMPLE_FMT_NONE;
|
yading@11
|
312 } else {
|
yading@11
|
313 ret = av_get_sample_fmt(val);
|
yading@11
|
314 if (ret == AV_SAMPLE_FMT_NONE) {
|
yading@11
|
315 char *tail;
|
yading@11
|
316 ret = strtol(val, &tail, 0);
|
yading@11
|
317 if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) {
|
yading@11
|
318 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val);
|
yading@11
|
319 return AVERROR(EINVAL);
|
yading@11
|
320 }
|
yading@11
|
321 }
|
yading@11
|
322 }
|
yading@11
|
323 *(enum AVSampleFormat *)dst = ret;
|
yading@11
|
324 return 0;
|
yading@11
|
325 case AV_OPT_TYPE_DURATION:
|
yading@11
|
326 if (!val) {
|
yading@11
|
327 *(int64_t *)dst = 0;
|
yading@11
|
328 return 0;
|
yading@11
|
329 } else {
|
yading@11
|
330 if ((ret = av_parse_time(dst, val, 1)) < 0)
|
yading@11
|
331 av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
|
yading@11
|
332 return ret;
|
yading@11
|
333 }
|
yading@11
|
334 }
|
yading@11
|
335
|
yading@11
|
336 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
|
yading@11
|
337 return AVERROR(EINVAL);
|
yading@11
|
338 }
|
yading@11
|
339
|
yading@11
|
340 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
|
yading@11
|
341 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
|
yading@11
|
342 {\
|
yading@11
|
343 if (!o || o->type != opttype)\
|
yading@11
|
344 return AVERROR(EINVAL);\
|
yading@11
|
345 return set_string_number(obj, obj, o, val, name ## _out);\
|
yading@11
|
346 }
|
yading@11
|
347
|
yading@11
|
348 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
|
yading@11
|
349 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
|
yading@11
|
350 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
|
yading@11
|
351 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
|
yading@11
|
352 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
|
yading@11
|
353 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
|
yading@11
|
354
|
yading@11
|
355 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
|
yading@11
|
356 int search_flags)
|
yading@11
|
357 {
|
yading@11
|
358 void *dst, *target_obj;
|
yading@11
|
359 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
360
|
yading@11
|
361 if (!o || !target_obj)
|
yading@11
|
362 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
363
|
yading@11
|
364 dst = ((uint8_t*)target_obj) + o->offset;
|
yading@11
|
365 return write_number(obj, o, dst, num, den, intnum);
|
yading@11
|
366 }
|
yading@11
|
367
|
yading@11
|
368 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
369 const AVOption *av_set_double(void *obj, const char *name, double n)
|
yading@11
|
370 {
|
yading@11
|
371 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
|
yading@11
|
372 if (set_number(obj, name, n, 1, 1, 0) < 0)
|
yading@11
|
373 return NULL;
|
yading@11
|
374 return o;
|
yading@11
|
375 }
|
yading@11
|
376
|
yading@11
|
377 const AVOption *av_set_q(void *obj, const char *name, AVRational n)
|
yading@11
|
378 {
|
yading@11
|
379 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
|
yading@11
|
380 if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
|
yading@11
|
381 return NULL;
|
yading@11
|
382 return o;
|
yading@11
|
383 }
|
yading@11
|
384
|
yading@11
|
385 const AVOption *av_set_int(void *obj, const char *name, int64_t n)
|
yading@11
|
386 {
|
yading@11
|
387 const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
|
yading@11
|
388 if (set_number(obj, name, 1, 1, n, 0) < 0)
|
yading@11
|
389 return NULL;
|
yading@11
|
390 return o;
|
yading@11
|
391 }
|
yading@11
|
392 #endif
|
yading@11
|
393
|
yading@11
|
394 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
|
yading@11
|
395 {
|
yading@11
|
396 return set_number(obj, name, 1, 1, val, search_flags);
|
yading@11
|
397 }
|
yading@11
|
398
|
yading@11
|
399 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
|
yading@11
|
400 {
|
yading@11
|
401 return set_number(obj, name, val, 1, 1, search_flags);
|
yading@11
|
402 }
|
yading@11
|
403
|
yading@11
|
404 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
|
yading@11
|
405 {
|
yading@11
|
406 return set_number(obj, name, val.num, val.den, 1, search_flags);
|
yading@11
|
407 }
|
yading@11
|
408
|
yading@11
|
409 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
|
yading@11
|
410 {
|
yading@11
|
411 void *target_obj;
|
yading@11
|
412 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
413 uint8_t *ptr;
|
yading@11
|
414 uint8_t **dst;
|
yading@11
|
415 int *lendst;
|
yading@11
|
416
|
yading@11
|
417 if (!o || !target_obj)
|
yading@11
|
418 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
419
|
yading@11
|
420 if (o->type != AV_OPT_TYPE_BINARY)
|
yading@11
|
421 return AVERROR(EINVAL);
|
yading@11
|
422
|
yading@11
|
423 ptr = len ? av_malloc(len) : NULL;
|
yading@11
|
424 if (len && !ptr)
|
yading@11
|
425 return AVERROR(ENOMEM);
|
yading@11
|
426
|
yading@11
|
427 dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
|
yading@11
|
428 lendst = (int *)(dst + 1);
|
yading@11
|
429
|
yading@11
|
430 av_free(*dst);
|
yading@11
|
431 *dst = ptr;
|
yading@11
|
432 *lendst = len;
|
yading@11
|
433 if (len)
|
yading@11
|
434 memcpy(ptr, val, len);
|
yading@11
|
435
|
yading@11
|
436 return 0;
|
yading@11
|
437 }
|
yading@11
|
438
|
yading@11
|
439 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
|
yading@11
|
440 {
|
yading@11
|
441 void *target_obj;
|
yading@11
|
442 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
443
|
yading@11
|
444 if (!o || !target_obj)
|
yading@11
|
445 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
446 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
|
yading@11
|
447 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
448 "The value set by option '%s' is not an image size.\n", o->name);
|
yading@11
|
449 return AVERROR(EINVAL);
|
yading@11
|
450 }
|
yading@11
|
451 if (w<0 || h<0) {
|
yading@11
|
452 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
453 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
|
yading@11
|
454 return AVERROR(EINVAL);
|
yading@11
|
455 }
|
yading@11
|
456 *(int *)(((uint8_t *)target_obj) + o->offset) = w;
|
yading@11
|
457 *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
|
yading@11
|
458 return 0;
|
yading@11
|
459 }
|
yading@11
|
460
|
yading@11
|
461 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
|
yading@11
|
462 {
|
yading@11
|
463 void *target_obj;
|
yading@11
|
464 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
465
|
yading@11
|
466 if (!o || !target_obj)
|
yading@11
|
467 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
468 if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
|
yading@11
|
469 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
470 "The value set by option '%s' is not a video rate.\n", o->name);
|
yading@11
|
471 return AVERROR(EINVAL);
|
yading@11
|
472 }
|
yading@11
|
473 if (val.num <= 0 || val.den <= 0)
|
yading@11
|
474 return AVERROR(EINVAL);
|
yading@11
|
475 return set_number(obj, name, val.num, val.den, 1, search_flags);
|
yading@11
|
476 }
|
yading@11
|
477
|
yading@11
|
478 static int set_format(void *obj, const char *name, int fmt, int search_flags,
|
yading@11
|
479 enum AVOptionType type, const char *desc, int nb_fmts)
|
yading@11
|
480 {
|
yading@11
|
481 void *target_obj;
|
yading@11
|
482 const AVOption *o = av_opt_find2(obj, name, NULL, 0,
|
yading@11
|
483 search_flags, &target_obj);
|
yading@11
|
484 int min, max;
|
yading@11
|
485 const AVClass *class = *(AVClass **)obj;
|
yading@11
|
486
|
yading@11
|
487 if (!o || !target_obj)
|
yading@11
|
488 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
489 if (o->type != type) {
|
yading@11
|
490 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
491 "The value set by option '%s' is not a %s format", name, desc);
|
yading@11
|
492 return AVERROR(EINVAL);
|
yading@11
|
493 }
|
yading@11
|
494
|
yading@11
|
495 #if LIBAVUTIL_VERSION_MAJOR < 53
|
yading@11
|
496 if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) {
|
yading@11
|
497 min = -1;
|
yading@11
|
498 max = nb_fmts-1;
|
yading@11
|
499 } else
|
yading@11
|
500 #endif
|
yading@11
|
501 {
|
yading@11
|
502 min = FFMIN(o->min, -1);
|
yading@11
|
503 max = FFMAX(o->max, nb_fmts-1);
|
yading@11
|
504 }
|
yading@11
|
505 if (fmt < min || fmt > max) {
|
yading@11
|
506 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
507 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
|
yading@11
|
508 fmt, name, desc, min, max);
|
yading@11
|
509 return AVERROR(ERANGE);
|
yading@11
|
510 }
|
yading@11
|
511 *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
|
yading@11
|
512 return 0;
|
yading@11
|
513 }
|
yading@11
|
514
|
yading@11
|
515 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
|
yading@11
|
516 {
|
yading@11
|
517 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
|
yading@11
|
518 }
|
yading@11
|
519
|
yading@11
|
520 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
|
yading@11
|
521 {
|
yading@11
|
522 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
|
yading@11
|
523 }
|
yading@11
|
524
|
yading@11
|
525 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
526 /**
|
yading@11
|
527 *
|
yading@11
|
528 * @param buf a buffer which is used for returning non string values as strings, can be NULL
|
yading@11
|
529 * @param buf_len allocated length in bytes of buf
|
yading@11
|
530 */
|
yading@11
|
531 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
|
yading@11
|
532 {
|
yading@11
|
533 const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
|
yading@11
|
534 void *dst;
|
yading@11
|
535 uint8_t *bin;
|
yading@11
|
536 int len, i;
|
yading@11
|
537 if (!o)
|
yading@11
|
538 return NULL;
|
yading@11
|
539 if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
|
yading@11
|
540 return NULL;
|
yading@11
|
541
|
yading@11
|
542 dst= ((uint8_t*)obj) + o->offset;
|
yading@11
|
543 if (o_out) *o_out= o;
|
yading@11
|
544
|
yading@11
|
545 switch (o->type) {
|
yading@11
|
546 case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
|
yading@11
|
547 case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
|
yading@11
|
548 case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
|
yading@11
|
549 case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
|
yading@11
|
550 case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
|
yading@11
|
551 case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
|
yading@11
|
552 case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
|
yading@11
|
553 case AV_OPT_TYPE_STRING: return *(void**)dst;
|
yading@11
|
554 case AV_OPT_TYPE_BINARY:
|
yading@11
|
555 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
|
yading@11
|
556 if (len >= (buf_len + 1)/2) return NULL;
|
yading@11
|
557 bin = *(uint8_t**)dst;
|
yading@11
|
558 for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
|
yading@11
|
559 break;
|
yading@11
|
560 default: return NULL;
|
yading@11
|
561 }
|
yading@11
|
562 return buf;
|
yading@11
|
563 }
|
yading@11
|
564 #endif
|
yading@11
|
565
|
yading@11
|
566 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
|
yading@11
|
567 {
|
yading@11
|
568 void *dst, *target_obj;
|
yading@11
|
569 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
570 uint8_t *bin, buf[128];
|
yading@11
|
571 int len, i, ret;
|
yading@11
|
572 int64_t i64;
|
yading@11
|
573
|
yading@11
|
574 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
|
yading@11
|
575 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
576
|
yading@11
|
577 dst = (uint8_t*)target_obj + o->offset;
|
yading@11
|
578
|
yading@11
|
579 buf[0] = 0;
|
yading@11
|
580 switch (o->type) {
|
yading@11
|
581 case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
|
yading@11
|
582 case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
|
yading@11
|
583 case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
|
yading@11
|
584 case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
|
yading@11
|
585 case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
|
yading@11
|
586 case AV_OPT_TYPE_VIDEO_RATE:
|
yading@11
|
587 case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
|
yading@11
|
588 case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break;
|
yading@11
|
589 case AV_OPT_TYPE_STRING:
|
yading@11
|
590 if (*(uint8_t**)dst)
|
yading@11
|
591 *out_val = av_strdup(*(uint8_t**)dst);
|
yading@11
|
592 else
|
yading@11
|
593 *out_val = av_strdup("");
|
yading@11
|
594 return 0;
|
yading@11
|
595 case AV_OPT_TYPE_BINARY:
|
yading@11
|
596 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
|
yading@11
|
597 if ((uint64_t)len*2 + 1 > INT_MAX)
|
yading@11
|
598 return AVERROR(EINVAL);
|
yading@11
|
599 if (!(*out_val = av_malloc(len*2 + 1)))
|
yading@11
|
600 return AVERROR(ENOMEM);
|
yading@11
|
601 bin = *(uint8_t**)dst;
|
yading@11
|
602 for (i = 0; i < len; i++)
|
yading@11
|
603 snprintf(*out_val + i*2, 3, "%02X", bin[i]);
|
yading@11
|
604 return 0;
|
yading@11
|
605 case AV_OPT_TYPE_IMAGE_SIZE:
|
yading@11
|
606 ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
|
yading@11
|
607 break;
|
yading@11
|
608 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
609 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
|
yading@11
|
610 break;
|
yading@11
|
611 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
612 ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
|
yading@11
|
613 break;
|
yading@11
|
614 case AV_OPT_TYPE_DURATION:
|
yading@11
|
615 i64 = *(int64_t *)dst;
|
yading@11
|
616 ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d",
|
yading@11
|
617 i64 / 3600000000, (int)((i64 / 60000000) % 60),
|
yading@11
|
618 (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
|
yading@11
|
619 break;
|
yading@11
|
620 default:
|
yading@11
|
621 return AVERROR(EINVAL);
|
yading@11
|
622 }
|
yading@11
|
623
|
yading@11
|
624 if (ret >= sizeof(buf))
|
yading@11
|
625 return AVERROR(EINVAL);
|
yading@11
|
626 *out_val = av_strdup(buf);
|
yading@11
|
627 return 0;
|
yading@11
|
628 }
|
yading@11
|
629
|
yading@11
|
630 static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
|
yading@11
|
631 int search_flags)
|
yading@11
|
632 {
|
yading@11
|
633 void *dst, *target_obj;
|
yading@11
|
634 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
635 if (!o || !target_obj)
|
yading@11
|
636 goto error;
|
yading@11
|
637
|
yading@11
|
638 dst = ((uint8_t*)target_obj) + o->offset;
|
yading@11
|
639
|
yading@11
|
640 if (o_out) *o_out= o;
|
yading@11
|
641
|
yading@11
|
642 return read_number(o, dst, num, den, intnum);
|
yading@11
|
643
|
yading@11
|
644 error:
|
yading@11
|
645 *den=*intnum=0;
|
yading@11
|
646 return -1;
|
yading@11
|
647 }
|
yading@11
|
648
|
yading@11
|
649 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
650 double av_get_double(void *obj, const char *name, const AVOption **o_out)
|
yading@11
|
651 {
|
yading@11
|
652 int64_t intnum=1;
|
yading@11
|
653 double num=1;
|
yading@11
|
654 int den=1;
|
yading@11
|
655
|
yading@11
|
656 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
|
yading@11
|
657 return NAN;
|
yading@11
|
658 return num*intnum/den;
|
yading@11
|
659 }
|
yading@11
|
660
|
yading@11
|
661 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
|
yading@11
|
662 {
|
yading@11
|
663 int64_t intnum=1;
|
yading@11
|
664 double num=1;
|
yading@11
|
665 int den=1;
|
yading@11
|
666
|
yading@11
|
667 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
|
yading@11
|
668 return (AVRational){0, 0};
|
yading@11
|
669 if (num == 1.0 && (int)intnum == intnum)
|
yading@11
|
670 return (AVRational){intnum, den};
|
yading@11
|
671 else
|
yading@11
|
672 return av_d2q(num*intnum/den, 1<<24);
|
yading@11
|
673 }
|
yading@11
|
674
|
yading@11
|
675 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
|
yading@11
|
676 {
|
yading@11
|
677 int64_t intnum=1;
|
yading@11
|
678 double num=1;
|
yading@11
|
679 int den=1;
|
yading@11
|
680
|
yading@11
|
681 if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
|
yading@11
|
682 return -1;
|
yading@11
|
683 return num*intnum/den;
|
yading@11
|
684 }
|
yading@11
|
685 #endif
|
yading@11
|
686
|
yading@11
|
687 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
|
yading@11
|
688 {
|
yading@11
|
689 int64_t intnum = 1;
|
yading@11
|
690 double num = 1;
|
yading@11
|
691 int ret, den = 1;
|
yading@11
|
692
|
yading@11
|
693 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
|
yading@11
|
694 return ret;
|
yading@11
|
695 *out_val = num*intnum/den;
|
yading@11
|
696 return 0;
|
yading@11
|
697 }
|
yading@11
|
698
|
yading@11
|
699 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
|
yading@11
|
700 {
|
yading@11
|
701 int64_t intnum = 1;
|
yading@11
|
702 double num = 1;
|
yading@11
|
703 int ret, den = 1;
|
yading@11
|
704
|
yading@11
|
705 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
|
yading@11
|
706 return ret;
|
yading@11
|
707 *out_val = num*intnum/den;
|
yading@11
|
708 return 0;
|
yading@11
|
709 }
|
yading@11
|
710
|
yading@11
|
711 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
|
yading@11
|
712 {
|
yading@11
|
713 int64_t intnum = 1;
|
yading@11
|
714 double num = 1;
|
yading@11
|
715 int ret, den = 1;
|
yading@11
|
716
|
yading@11
|
717 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
|
yading@11
|
718 return ret;
|
yading@11
|
719
|
yading@11
|
720 if (num == 1.0 && (int)intnum == intnum)
|
yading@11
|
721 *out_val = (AVRational){intnum, den};
|
yading@11
|
722 else
|
yading@11
|
723 *out_val = av_d2q(num*intnum/den, 1<<24);
|
yading@11
|
724 return 0;
|
yading@11
|
725 }
|
yading@11
|
726
|
yading@11
|
727 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
|
yading@11
|
728 {
|
yading@11
|
729 void *dst, *target_obj;
|
yading@11
|
730 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
731 if (!o || !target_obj)
|
yading@11
|
732 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
733 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
|
yading@11
|
734 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
735 "The value for option '%s' is not an image size.\n", name);
|
yading@11
|
736 return AVERROR(EINVAL);
|
yading@11
|
737 }
|
yading@11
|
738
|
yading@11
|
739 dst = ((uint8_t*)target_obj) + o->offset;
|
yading@11
|
740 if (w_out) *w_out = *(int *)dst;
|
yading@11
|
741 if (h_out) *h_out = *((int *)dst+1);
|
yading@11
|
742 return 0;
|
yading@11
|
743 }
|
yading@11
|
744
|
yading@11
|
745 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
|
yading@11
|
746 {
|
yading@11
|
747 int64_t intnum = 1;
|
yading@11
|
748 double num = 1;
|
yading@11
|
749 int ret, den = 1;
|
yading@11
|
750
|
yading@11
|
751 if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
|
yading@11
|
752 return ret;
|
yading@11
|
753
|
yading@11
|
754 if (num == 1.0 && (int)intnum == intnum)
|
yading@11
|
755 *out_val = (AVRational){intnum, den};
|
yading@11
|
756 else
|
yading@11
|
757 *out_val = av_d2q(num*intnum/den, 1<<24);
|
yading@11
|
758 return 0;
|
yading@11
|
759 }
|
yading@11
|
760
|
yading@11
|
761 static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
|
yading@11
|
762 enum AVOptionType type, const char *desc)
|
yading@11
|
763 {
|
yading@11
|
764 void *dst, *target_obj;
|
yading@11
|
765 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
|
yading@11
|
766 if (!o || !target_obj)
|
yading@11
|
767 return AVERROR_OPTION_NOT_FOUND;
|
yading@11
|
768 if (o->type != type) {
|
yading@11
|
769 av_log(obj, AV_LOG_ERROR,
|
yading@11
|
770 "The value for option '%s' is not a %s format.\n", desc, name);
|
yading@11
|
771 return AVERROR(EINVAL);
|
yading@11
|
772 }
|
yading@11
|
773
|
yading@11
|
774 dst = ((uint8_t*)target_obj) + o->offset;
|
yading@11
|
775 *out_fmt = *(int *)dst;
|
yading@11
|
776 return 0;
|
yading@11
|
777 }
|
yading@11
|
778
|
yading@11
|
779 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
|
yading@11
|
780 {
|
yading@11
|
781 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
|
yading@11
|
782 }
|
yading@11
|
783
|
yading@11
|
784 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
|
yading@11
|
785 {
|
yading@11
|
786 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
|
yading@11
|
787 }
|
yading@11
|
788
|
yading@11
|
789 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
|
yading@11
|
790 {
|
yading@11
|
791 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
|
yading@11
|
792 const AVOption *flag = av_opt_find(obj, flag_name,
|
yading@11
|
793 field ? field->unit : NULL, 0, 0);
|
yading@11
|
794 int64_t res;
|
yading@11
|
795
|
yading@11
|
796 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
|
yading@11
|
797 av_opt_get_int(obj, field_name, 0, &res) < 0)
|
yading@11
|
798 return 0;
|
yading@11
|
799 return res & flag->default_val.i64;
|
yading@11
|
800 }
|
yading@11
|
801
|
yading@11
|
802 static void log_value(void *av_log_obj, int level, double d)
|
yading@11
|
803 {
|
yading@11
|
804 if (d == INT_MAX) {
|
yading@11
|
805 av_log(av_log_obj, level, "INT_MAX");
|
yading@11
|
806 } else if (d == INT_MIN) {
|
yading@11
|
807 av_log(av_log_obj, level, "INT_MIN");
|
yading@11
|
808 } else if (d == (double)INT64_MAX) {
|
yading@11
|
809 av_log(av_log_obj, level, "I64_MAX");
|
yading@11
|
810 } else if (d == INT64_MIN) {
|
yading@11
|
811 av_log(av_log_obj, level, "I64_MIN");
|
yading@11
|
812 } else if (d == FLT_MAX) {
|
yading@11
|
813 av_log(av_log_obj, level, "FLT_MAX");
|
yading@11
|
814 } else if (d == FLT_MIN) {
|
yading@11
|
815 av_log(av_log_obj, level, "FLT_MIN");
|
yading@11
|
816 } else {
|
yading@11
|
817 av_log(av_log_obj, level, "%g", d);
|
yading@11
|
818 }
|
yading@11
|
819 }
|
yading@11
|
820
|
yading@11
|
821 static void opt_list(void *obj, void *av_log_obj, const char *unit,
|
yading@11
|
822 int req_flags, int rej_flags)
|
yading@11
|
823 {
|
yading@11
|
824 const AVOption *opt=NULL;
|
yading@11
|
825 AVOptionRanges *r;
|
yading@11
|
826 int i;
|
yading@11
|
827
|
yading@11
|
828 while ((opt = av_opt_next(obj, opt))) {
|
yading@11
|
829 if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
|
yading@11
|
830 continue;
|
yading@11
|
831
|
yading@11
|
832 /* Don't print CONST's on level one.
|
yading@11
|
833 * Don't print anything but CONST's on level two.
|
yading@11
|
834 * Only print items from the requested unit.
|
yading@11
|
835 */
|
yading@11
|
836 if (!unit && opt->type==AV_OPT_TYPE_CONST)
|
yading@11
|
837 continue;
|
yading@11
|
838 else if (unit && opt->type!=AV_OPT_TYPE_CONST)
|
yading@11
|
839 continue;
|
yading@11
|
840 else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
|
yading@11
|
841 continue;
|
yading@11
|
842 else if (unit && opt->type == AV_OPT_TYPE_CONST)
|
yading@11
|
843 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
|
yading@11
|
844 else
|
yading@11
|
845 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ",
|
yading@11
|
846 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-",
|
yading@11
|
847 opt->name);
|
yading@11
|
848
|
yading@11
|
849 switch (opt->type) {
|
yading@11
|
850 case AV_OPT_TYPE_FLAGS:
|
yading@11
|
851 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
|
yading@11
|
852 break;
|
yading@11
|
853 case AV_OPT_TYPE_INT:
|
yading@11
|
854 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
|
yading@11
|
855 break;
|
yading@11
|
856 case AV_OPT_TYPE_INT64:
|
yading@11
|
857 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
|
yading@11
|
858 break;
|
yading@11
|
859 case AV_OPT_TYPE_DOUBLE:
|
yading@11
|
860 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
|
yading@11
|
861 break;
|
yading@11
|
862 case AV_OPT_TYPE_FLOAT:
|
yading@11
|
863 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
|
yading@11
|
864 break;
|
yading@11
|
865 case AV_OPT_TYPE_STRING:
|
yading@11
|
866 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
|
yading@11
|
867 break;
|
yading@11
|
868 case AV_OPT_TYPE_RATIONAL:
|
yading@11
|
869 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
|
yading@11
|
870 break;
|
yading@11
|
871 case AV_OPT_TYPE_BINARY:
|
yading@11
|
872 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
|
yading@11
|
873 break;
|
yading@11
|
874 case AV_OPT_TYPE_IMAGE_SIZE:
|
yading@11
|
875 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
|
yading@11
|
876 break;
|
yading@11
|
877 case AV_OPT_TYPE_VIDEO_RATE:
|
yading@11
|
878 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
|
yading@11
|
879 break;
|
yading@11
|
880 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
881 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
|
yading@11
|
882 break;
|
yading@11
|
883 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
884 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
|
yading@11
|
885 break;
|
yading@11
|
886 case AV_OPT_TYPE_DURATION:
|
yading@11
|
887 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
|
yading@11
|
888 break;
|
yading@11
|
889 case AV_OPT_TYPE_CONST:
|
yading@11
|
890 default:
|
yading@11
|
891 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
|
yading@11
|
892 break;
|
yading@11
|
893 }
|
yading@11
|
894 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
|
yading@11
|
895 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
|
yading@11
|
896 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
|
yading@11
|
897 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
|
yading@11
|
898 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
|
yading@11
|
899 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
|
yading@11
|
900
|
yading@11
|
901 if (opt->help)
|
yading@11
|
902 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
|
yading@11
|
903
|
yading@11
|
904 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
|
yading@11
|
905 switch (opt->type) {
|
yading@11
|
906 case AV_OPT_TYPE_INT:
|
yading@11
|
907 case AV_OPT_TYPE_INT64:
|
yading@11
|
908 case AV_OPT_TYPE_DOUBLE:
|
yading@11
|
909 case AV_OPT_TYPE_FLOAT:
|
yading@11
|
910 case AV_OPT_TYPE_RATIONAL:
|
yading@11
|
911 for (i = 0; i < r->nb_ranges; i++) {
|
yading@11
|
912 av_log(av_log_obj, AV_LOG_INFO, " (from ");
|
yading@11
|
913 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
|
yading@11
|
914 av_log(av_log_obj, AV_LOG_INFO, " to ");
|
yading@11
|
915 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
|
yading@11
|
916 av_log(av_log_obj, AV_LOG_INFO, ")");
|
yading@11
|
917 }
|
yading@11
|
918 break;
|
yading@11
|
919 }
|
yading@11
|
920 av_opt_freep_ranges(&r);
|
yading@11
|
921 }
|
yading@11
|
922
|
yading@11
|
923 av_log(av_log_obj, AV_LOG_INFO, "\n");
|
yading@11
|
924 if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
|
yading@11
|
925 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
|
yading@11
|
926 }
|
yading@11
|
927 }
|
yading@11
|
928 }
|
yading@11
|
929
|
yading@11
|
930 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
|
yading@11
|
931 {
|
yading@11
|
932 if (!obj)
|
yading@11
|
933 return -1;
|
yading@11
|
934
|
yading@11
|
935 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
|
yading@11
|
936
|
yading@11
|
937 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
|
yading@11
|
938
|
yading@11
|
939 return 0;
|
yading@11
|
940 }
|
yading@11
|
941
|
yading@11
|
942 void av_opt_set_defaults(void *s)
|
yading@11
|
943 {
|
yading@11
|
944 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
945 av_opt_set_defaults2(s, 0, 0);
|
yading@11
|
946 }
|
yading@11
|
947
|
yading@11
|
948 void av_opt_set_defaults2(void *s, int mask, int flags)
|
yading@11
|
949 {
|
yading@11
|
950 #endif
|
yading@11
|
951 const AVClass *class = *(AVClass **)s;
|
yading@11
|
952 const AVOption *opt = NULL;
|
yading@11
|
953 while ((opt = av_opt_next(s, opt)) != NULL) {
|
yading@11
|
954 #if FF_API_OLD_AVOPTIONS
|
yading@11
|
955 if ((opt->flags & mask) != flags)
|
yading@11
|
956 continue;
|
yading@11
|
957 #endif
|
yading@11
|
958 switch (opt->type) {
|
yading@11
|
959 case AV_OPT_TYPE_CONST:
|
yading@11
|
960 /* Nothing to be done here */
|
yading@11
|
961 break;
|
yading@11
|
962 case AV_OPT_TYPE_FLAGS:
|
yading@11
|
963 case AV_OPT_TYPE_INT:
|
yading@11
|
964 case AV_OPT_TYPE_INT64:
|
yading@11
|
965 case AV_OPT_TYPE_DURATION:
|
yading@11
|
966 av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
|
yading@11
|
967 break;
|
yading@11
|
968 case AV_OPT_TYPE_DOUBLE:
|
yading@11
|
969 case AV_OPT_TYPE_FLOAT: {
|
yading@11
|
970 double val;
|
yading@11
|
971 val = opt->default_val.dbl;
|
yading@11
|
972 av_opt_set_double(s, opt->name, val, 0);
|
yading@11
|
973 }
|
yading@11
|
974 break;
|
yading@11
|
975 case AV_OPT_TYPE_RATIONAL: {
|
yading@11
|
976 AVRational val;
|
yading@11
|
977 val = av_d2q(opt->default_val.dbl, INT_MAX);
|
yading@11
|
978 av_opt_set_q(s, opt->name, val, 0);
|
yading@11
|
979 }
|
yading@11
|
980 break;
|
yading@11
|
981 case AV_OPT_TYPE_STRING:
|
yading@11
|
982 case AV_OPT_TYPE_IMAGE_SIZE:
|
yading@11
|
983 case AV_OPT_TYPE_VIDEO_RATE:
|
yading@11
|
984 av_opt_set(s, opt->name, opt->default_val.str, 0);
|
yading@11
|
985 break;
|
yading@11
|
986 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
987 #if LIBAVUTIL_VERSION_MAJOR < 53
|
yading@11
|
988 if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
|
yading@11
|
989 av_opt_set(s, opt->name, opt->default_val.str, 0);
|
yading@11
|
990 else
|
yading@11
|
991 #endif
|
yading@11
|
992 av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
|
yading@11
|
993 break;
|
yading@11
|
994 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
995 #if LIBAVUTIL_VERSION_MAJOR < 53
|
yading@11
|
996 if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
|
yading@11
|
997 av_opt_set(s, opt->name, opt->default_val.str, 0);
|
yading@11
|
998 else
|
yading@11
|
999 #endif
|
yading@11
|
1000 av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
|
yading@11
|
1001 break;
|
yading@11
|
1002 case AV_OPT_TYPE_BINARY:
|
yading@11
|
1003 /* Cannot set default for binary */
|
yading@11
|
1004 break;
|
yading@11
|
1005 default:
|
yading@11
|
1006 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
|
yading@11
|
1007 }
|
yading@11
|
1008 }
|
yading@11
|
1009 }
|
yading@11
|
1010
|
yading@11
|
1011 /**
|
yading@11
|
1012 * Store the value in the field in ctx that is named like key.
|
yading@11
|
1013 * ctx must be an AVClass context, storing is done using AVOptions.
|
yading@11
|
1014 *
|
yading@11
|
1015 * @param buf the string to parse, buf will be updated to point at the
|
yading@11
|
1016 * separator just after the parsed key/value pair
|
yading@11
|
1017 * @param key_val_sep a 0-terminated list of characters used to
|
yading@11
|
1018 * separate key from value
|
yading@11
|
1019 * @param pairs_sep a 0-terminated list of characters used to separate
|
yading@11
|
1020 * two pairs from each other
|
yading@11
|
1021 * @return 0 if the key/value pair has been successfully parsed and
|
yading@11
|
1022 * set, or a negative value corresponding to an AVERROR code in case
|
yading@11
|
1023 * of error:
|
yading@11
|
1024 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
|
yading@11
|
1025 * the error code issued by av_opt_set() if the key/value pair
|
yading@11
|
1026 * cannot be set
|
yading@11
|
1027 */
|
yading@11
|
1028 static int parse_key_value_pair(void *ctx, const char **buf,
|
yading@11
|
1029 const char *key_val_sep, const char *pairs_sep)
|
yading@11
|
1030 {
|
yading@11
|
1031 char *key = av_get_token(buf, key_val_sep);
|
yading@11
|
1032 char *val;
|
yading@11
|
1033 int ret;
|
yading@11
|
1034
|
yading@11
|
1035 if (!key)
|
yading@11
|
1036 return AVERROR(ENOMEM);
|
yading@11
|
1037
|
yading@11
|
1038 if (*key && strspn(*buf, key_val_sep)) {
|
yading@11
|
1039 (*buf)++;
|
yading@11
|
1040 val = av_get_token(buf, pairs_sep);
|
yading@11
|
1041 if (!val) {
|
yading@11
|
1042 av_freep(&key);
|
yading@11
|
1043 return AVERROR(ENOMEM);
|
yading@11
|
1044 }
|
yading@11
|
1045 } else {
|
yading@11
|
1046 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
|
yading@11
|
1047 av_free(key);
|
yading@11
|
1048 return AVERROR(EINVAL);
|
yading@11
|
1049 }
|
yading@11
|
1050
|
yading@11
|
1051 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
|
yading@11
|
1052
|
yading@11
|
1053 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
|
yading@11
|
1054 if (ret == AVERROR_OPTION_NOT_FOUND)
|
yading@11
|
1055 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
|
yading@11
|
1056
|
yading@11
|
1057 av_free(key);
|
yading@11
|
1058 av_free(val);
|
yading@11
|
1059 return ret;
|
yading@11
|
1060 }
|
yading@11
|
1061
|
yading@11
|
1062 int av_set_options_string(void *ctx, const char *opts,
|
yading@11
|
1063 const char *key_val_sep, const char *pairs_sep)
|
yading@11
|
1064 {
|
yading@11
|
1065 int ret, count = 0;
|
yading@11
|
1066
|
yading@11
|
1067 if (!opts)
|
yading@11
|
1068 return 0;
|
yading@11
|
1069
|
yading@11
|
1070 while (*opts) {
|
yading@11
|
1071 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
|
yading@11
|
1072 return ret;
|
yading@11
|
1073 count++;
|
yading@11
|
1074
|
yading@11
|
1075 if (*opts)
|
yading@11
|
1076 opts++;
|
yading@11
|
1077 }
|
yading@11
|
1078
|
yading@11
|
1079 return count;
|
yading@11
|
1080 }
|
yading@11
|
1081
|
yading@11
|
1082 #define WHITESPACES " \n\t"
|
yading@11
|
1083
|
yading@11
|
1084 static int is_key_char(char c)
|
yading@11
|
1085 {
|
yading@11
|
1086 return (unsigned)((c | 32) - 'a') < 26 ||
|
yading@11
|
1087 (unsigned)(c - '0') < 10 ||
|
yading@11
|
1088 c == '-' || c == '_' || c == '/' || c == '.';
|
yading@11
|
1089 }
|
yading@11
|
1090
|
yading@11
|
1091 /**
|
yading@11
|
1092 * Read a key from a string.
|
yading@11
|
1093 *
|
yading@11
|
1094 * The key consists of is_key_char characters and must be terminated by a
|
yading@11
|
1095 * character from the delim string; spaces are ignored.
|
yading@11
|
1096 *
|
yading@11
|
1097 * @return 0 for success (even with ellipsis), <0 for failure
|
yading@11
|
1098 */
|
yading@11
|
1099 static int get_key(const char **ropts, const char *delim, char **rkey)
|
yading@11
|
1100 {
|
yading@11
|
1101 const char *opts = *ropts;
|
yading@11
|
1102 const char *key_start, *key_end;
|
yading@11
|
1103
|
yading@11
|
1104 key_start = opts += strspn(opts, WHITESPACES);
|
yading@11
|
1105 while (is_key_char(*opts))
|
yading@11
|
1106 opts++;
|
yading@11
|
1107 key_end = opts;
|
yading@11
|
1108 opts += strspn(opts, WHITESPACES);
|
yading@11
|
1109 if (!*opts || !strchr(delim, *opts))
|
yading@11
|
1110 return AVERROR(EINVAL);
|
yading@11
|
1111 opts++;
|
yading@11
|
1112 if (!(*rkey = av_malloc(key_end - key_start + 1)))
|
yading@11
|
1113 return AVERROR(ENOMEM);
|
yading@11
|
1114 memcpy(*rkey, key_start, key_end - key_start);
|
yading@11
|
1115 (*rkey)[key_end - key_start] = 0;
|
yading@11
|
1116 *ropts = opts;
|
yading@11
|
1117 return 0;
|
yading@11
|
1118 }
|
yading@11
|
1119
|
yading@11
|
1120 int av_opt_get_key_value(const char **ropts,
|
yading@11
|
1121 const char *key_val_sep, const char *pairs_sep,
|
yading@11
|
1122 unsigned flags,
|
yading@11
|
1123 char **rkey, char **rval)
|
yading@11
|
1124 {
|
yading@11
|
1125 int ret;
|
yading@11
|
1126 char *key = NULL, *val;
|
yading@11
|
1127 const char *opts = *ropts;
|
yading@11
|
1128
|
yading@11
|
1129 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
|
yading@11
|
1130 !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
|
yading@11
|
1131 return AVERROR(EINVAL);
|
yading@11
|
1132 if (!(val = av_get_token(&opts, pairs_sep))) {
|
yading@11
|
1133 av_free(key);
|
yading@11
|
1134 return AVERROR(ENOMEM);
|
yading@11
|
1135 }
|
yading@11
|
1136 *ropts = opts;
|
yading@11
|
1137 *rkey = key;
|
yading@11
|
1138 *rval = val;
|
yading@11
|
1139 return 0;
|
yading@11
|
1140 }
|
yading@11
|
1141
|
yading@11
|
1142 int av_opt_set_from_string(void *ctx, const char *opts,
|
yading@11
|
1143 const char *const *shorthand,
|
yading@11
|
1144 const char *key_val_sep, const char *pairs_sep)
|
yading@11
|
1145 {
|
yading@11
|
1146 int ret, count = 0;
|
yading@11
|
1147 const char *dummy_shorthand = NULL;
|
yading@11
|
1148 char *av_uninit(parsed_key), *av_uninit(value);
|
yading@11
|
1149 const char *key;
|
yading@11
|
1150
|
yading@11
|
1151 if (!opts)
|
yading@11
|
1152 return 0;
|
yading@11
|
1153 if (!shorthand)
|
yading@11
|
1154 shorthand = &dummy_shorthand;
|
yading@11
|
1155
|
yading@11
|
1156 while (*opts) {
|
yading@11
|
1157 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
|
yading@11
|
1158 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
|
yading@11
|
1159 &parsed_key, &value);
|
yading@11
|
1160 if (ret < 0) {
|
yading@11
|
1161 if (ret == AVERROR(EINVAL))
|
yading@11
|
1162 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
|
yading@11
|
1163 else
|
yading@11
|
1164 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
|
yading@11
|
1165 av_err2str(ret));
|
yading@11
|
1166 return ret;
|
yading@11
|
1167 }
|
yading@11
|
1168 if (*opts)
|
yading@11
|
1169 opts++;
|
yading@11
|
1170 if (parsed_key) {
|
yading@11
|
1171 key = parsed_key;
|
yading@11
|
1172 while (*shorthand) /* discard all remaining shorthand */
|
yading@11
|
1173 shorthand++;
|
yading@11
|
1174 } else {
|
yading@11
|
1175 key = *(shorthand++);
|
yading@11
|
1176 }
|
yading@11
|
1177
|
yading@11
|
1178 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
|
yading@11
|
1179 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
|
yading@11
|
1180 if (ret == AVERROR_OPTION_NOT_FOUND)
|
yading@11
|
1181 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
|
yading@11
|
1182 av_free(value);
|
yading@11
|
1183 av_free(parsed_key);
|
yading@11
|
1184 return ret;
|
yading@11
|
1185 }
|
yading@11
|
1186
|
yading@11
|
1187 av_free(value);
|
yading@11
|
1188 av_free(parsed_key);
|
yading@11
|
1189 count++;
|
yading@11
|
1190 }
|
yading@11
|
1191 return count;
|
yading@11
|
1192 }
|
yading@11
|
1193
|
yading@11
|
1194 void av_opt_free(void *obj)
|
yading@11
|
1195 {
|
yading@11
|
1196 const AVOption *o = NULL;
|
yading@11
|
1197 while ((o = av_opt_next(obj, o)))
|
yading@11
|
1198 if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
|
yading@11
|
1199 av_freep((uint8_t *)obj + o->offset);
|
yading@11
|
1200 }
|
yading@11
|
1201
|
yading@11
|
1202 int av_opt_set_dict(void *obj, AVDictionary **options)
|
yading@11
|
1203 {
|
yading@11
|
1204 AVDictionaryEntry *t = NULL;
|
yading@11
|
1205 AVDictionary *tmp = NULL;
|
yading@11
|
1206 int ret = 0;
|
yading@11
|
1207
|
yading@11
|
1208 while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
yading@11
|
1209 ret = av_opt_set(obj, t->key, t->value, 0);
|
yading@11
|
1210 if (ret == AVERROR_OPTION_NOT_FOUND)
|
yading@11
|
1211 av_dict_set(&tmp, t->key, t->value, 0);
|
yading@11
|
1212 else if (ret < 0) {
|
yading@11
|
1213 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
|
yading@11
|
1214 break;
|
yading@11
|
1215 }
|
yading@11
|
1216 ret = 0;
|
yading@11
|
1217 }
|
yading@11
|
1218 av_dict_free(options);
|
yading@11
|
1219 *options = tmp;
|
yading@11
|
1220 return ret;
|
yading@11
|
1221 }
|
yading@11
|
1222
|
yading@11
|
1223 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
|
yading@11
|
1224 int opt_flags, int search_flags)
|
yading@11
|
1225 {
|
yading@11
|
1226 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
|
yading@11
|
1227 }
|
yading@11
|
1228
|
yading@11
|
1229 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
|
yading@11
|
1230 int opt_flags, int search_flags, void **target_obj)
|
yading@11
|
1231 {
|
yading@11
|
1232 const AVClass *c;
|
yading@11
|
1233 const AVOption *o = NULL;
|
yading@11
|
1234
|
yading@11
|
1235 if(!obj)
|
yading@11
|
1236 return NULL;
|
yading@11
|
1237
|
yading@11
|
1238 c= *(AVClass**)obj;
|
yading@11
|
1239
|
yading@11
|
1240 if (search_flags & AV_OPT_SEARCH_CHILDREN) {
|
yading@11
|
1241 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
|
yading@11
|
1242 const AVClass *child = NULL;
|
yading@11
|
1243 while (child = av_opt_child_class_next(c, child))
|
yading@11
|
1244 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
|
yading@11
|
1245 return o;
|
yading@11
|
1246 } else {
|
yading@11
|
1247 void *child = NULL;
|
yading@11
|
1248 while (child = av_opt_child_next(obj, child))
|
yading@11
|
1249 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
|
yading@11
|
1250 return o;
|
yading@11
|
1251 }
|
yading@11
|
1252 }
|
yading@11
|
1253
|
yading@11
|
1254 while (o = av_opt_next(obj, o)) {
|
yading@11
|
1255 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
|
yading@11
|
1256 ((!unit && o->type != AV_OPT_TYPE_CONST) ||
|
yading@11
|
1257 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
|
yading@11
|
1258 if (target_obj) {
|
yading@11
|
1259 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
|
yading@11
|
1260 *target_obj = obj;
|
yading@11
|
1261 else
|
yading@11
|
1262 *target_obj = NULL;
|
yading@11
|
1263 }
|
yading@11
|
1264 return o;
|
yading@11
|
1265 }
|
yading@11
|
1266 }
|
yading@11
|
1267 return NULL;
|
yading@11
|
1268 }
|
yading@11
|
1269
|
yading@11
|
1270 void *av_opt_child_next(void *obj, void *prev)
|
yading@11
|
1271 {
|
yading@11
|
1272 const AVClass *c = *(AVClass**)obj;
|
yading@11
|
1273 if (c->child_next)
|
yading@11
|
1274 return c->child_next(obj, prev);
|
yading@11
|
1275 return NULL;
|
yading@11
|
1276 }
|
yading@11
|
1277
|
yading@11
|
1278 const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
|
yading@11
|
1279 {
|
yading@11
|
1280 if (parent->child_class_next)
|
yading@11
|
1281 return parent->child_class_next(prev);
|
yading@11
|
1282 return NULL;
|
yading@11
|
1283 }
|
yading@11
|
1284
|
yading@11
|
1285 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
|
yading@11
|
1286 {
|
yading@11
|
1287 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
|
yading@11
|
1288 if(!opt)
|
yading@11
|
1289 return NULL;
|
yading@11
|
1290 return (uint8_t*)obj + opt->offset;
|
yading@11
|
1291 }
|
yading@11
|
1292
|
yading@11
|
1293 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
|
yading@11
|
1294 {
|
yading@11
|
1295 const AVClass *c = *(AVClass**)obj;
|
yading@11
|
1296 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
|
yading@11
|
1297
|
yading@11
|
1298 if (c->version > (52 << 16 | 11 << 8))
|
yading@11
|
1299 callback = c->query_ranges;
|
yading@11
|
1300
|
yading@11
|
1301 if (!callback)
|
yading@11
|
1302 callback = av_opt_query_ranges_default;
|
yading@11
|
1303
|
yading@11
|
1304 return callback(ranges_arg, obj, key, flags);
|
yading@11
|
1305 }
|
yading@11
|
1306
|
yading@11
|
1307 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
|
yading@11
|
1308 {
|
yading@11
|
1309 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
|
yading@11
|
1310 AVOptionRange **range_array = av_mallocz(sizeof(void*));
|
yading@11
|
1311 AVOptionRange *range = av_mallocz(sizeof(*range));
|
yading@11
|
1312 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
|
yading@11
|
1313 int ret;
|
yading@11
|
1314
|
yading@11
|
1315 *ranges_arg = NULL;
|
yading@11
|
1316
|
yading@11
|
1317 if (!ranges || !range || !range_array || !field) {
|
yading@11
|
1318 ret = AVERROR(ENOMEM);
|
yading@11
|
1319 goto fail;
|
yading@11
|
1320 }
|
yading@11
|
1321
|
yading@11
|
1322 ranges->range = range_array;
|
yading@11
|
1323 ranges->range[0] = range;
|
yading@11
|
1324 ranges->nb_ranges = 1;
|
yading@11
|
1325 range->is_range = 1;
|
yading@11
|
1326 range->value_min = field->min;
|
yading@11
|
1327 range->value_max = field->max;
|
yading@11
|
1328
|
yading@11
|
1329 switch (field->type) {
|
yading@11
|
1330 case AV_OPT_TYPE_INT:
|
yading@11
|
1331 case AV_OPT_TYPE_INT64:
|
yading@11
|
1332 case AV_OPT_TYPE_PIXEL_FMT:
|
yading@11
|
1333 case AV_OPT_TYPE_SAMPLE_FMT:
|
yading@11
|
1334 case AV_OPT_TYPE_FLOAT:
|
yading@11
|
1335 case AV_OPT_TYPE_DOUBLE:
|
yading@11
|
1336 case AV_OPT_TYPE_DURATION:
|
yading@11
|
1337 break;
|
yading@11
|
1338 case AV_OPT_TYPE_STRING:
|
yading@11
|
1339 range->component_min = 0;
|
yading@11
|
1340 range->component_max = 0x10FFFF; // max unicode value
|
yading@11
|
1341 range->value_min = -1;
|
yading@11
|
1342 range->value_max = INT_MAX;
|
yading@11
|
1343 break;
|
yading@11
|
1344 case AV_OPT_TYPE_RATIONAL:
|
yading@11
|
1345 range->component_min = INT_MIN;
|
yading@11
|
1346 range->component_max = INT_MAX;
|
yading@11
|
1347 break;
|
yading@11
|
1348 case AV_OPT_TYPE_IMAGE_SIZE:
|
yading@11
|
1349 range->component_min = 0;
|
yading@11
|
1350 range->component_max = INT_MAX/128/8;
|
yading@11
|
1351 range->value_min = 0;
|
yading@11
|
1352 range->value_max = INT_MAX/8;
|
yading@11
|
1353 break;
|
yading@11
|
1354 case AV_OPT_TYPE_VIDEO_RATE:
|
yading@11
|
1355 range->component_min = 1;
|
yading@11
|
1356 range->component_max = INT_MAX;
|
yading@11
|
1357 range->value_min = 1;
|
yading@11
|
1358 range->value_max = INT_MAX;
|
yading@11
|
1359 break;
|
yading@11
|
1360 default:
|
yading@11
|
1361 ret = AVERROR(ENOSYS);
|
yading@11
|
1362 goto fail;
|
yading@11
|
1363 }
|
yading@11
|
1364
|
yading@11
|
1365 *ranges_arg = ranges;
|
yading@11
|
1366 return 0;
|
yading@11
|
1367 fail:
|
yading@11
|
1368 av_free(ranges);
|
yading@11
|
1369 av_free(range);
|
yading@11
|
1370 av_free(range_array);
|
yading@11
|
1371 return ret;
|
yading@11
|
1372 }
|
yading@11
|
1373
|
yading@11
|
1374 void av_opt_freep_ranges(AVOptionRanges **rangesp)
|
yading@11
|
1375 {
|
yading@11
|
1376 int i;
|
yading@11
|
1377 AVOptionRanges *ranges = *rangesp;
|
yading@11
|
1378
|
yading@11
|
1379 for (i = 0; i < ranges->nb_ranges; i++) {
|
yading@11
|
1380 AVOptionRange *range = ranges->range[i];
|
yading@11
|
1381 av_freep(&range->str);
|
yading@11
|
1382 av_freep(&ranges->range[i]);
|
yading@11
|
1383 }
|
yading@11
|
1384 av_freep(&ranges->range);
|
yading@11
|
1385 av_freep(rangesp);
|
yading@11
|
1386 }
|
yading@11
|
1387
|
yading@11
|
1388 #ifdef TEST
|
yading@11
|
1389
|
yading@11
|
1390 typedef struct TestContext
|
yading@11
|
1391 {
|
yading@11
|
1392 const AVClass *class;
|
yading@11
|
1393 int num;
|
yading@11
|
1394 int toggle;
|
yading@11
|
1395 char *string;
|
yading@11
|
1396 int flags;
|
yading@11
|
1397 AVRational rational;
|
yading@11
|
1398 AVRational video_rate;
|
yading@11
|
1399 int w, h;
|
yading@11
|
1400 enum AVPixelFormat pix_fmt;
|
yading@11
|
1401 enum AVSampleFormat sample_fmt;
|
yading@11
|
1402 int64_t duration;
|
yading@11
|
1403 } TestContext;
|
yading@11
|
1404
|
yading@11
|
1405 #define OFFSET(x) offsetof(TestContext, x)
|
yading@11
|
1406
|
yading@11
|
1407 #define TEST_FLAG_COOL 01
|
yading@11
|
1408 #define TEST_FLAG_LAME 02
|
yading@11
|
1409 #define TEST_FLAG_MU 04
|
yading@11
|
1410
|
yading@11
|
1411 static const AVOption test_options[]= {
|
yading@11
|
1412 {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 },
|
yading@11
|
1413 {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
|
yading@11
|
1414 {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 },
|
yading@11
|
1415 {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX },
|
yading@11
|
1416 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
|
yading@11
|
1417 {"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
|
yading@11
|
1418 {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
|
yading@11
|
1419 {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
|
yading@11
|
1420 {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 },
|
yading@11
|
1421 {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1},
|
yading@11
|
1422 {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1},
|
yading@11
|
1423 {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 },
|
yading@11
|
1424 {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
|
yading@11
|
1425 {NULL},
|
yading@11
|
1426 };
|
yading@11
|
1427
|
yading@11
|
1428 static const char *test_get_name(void *ctx)
|
yading@11
|
1429 {
|
yading@11
|
1430 return "test";
|
yading@11
|
1431 }
|
yading@11
|
1432
|
yading@11
|
1433 static const AVClass test_class = {
|
yading@11
|
1434 "TestContext",
|
yading@11
|
1435 test_get_name,
|
yading@11
|
1436 test_options
|
yading@11
|
1437 };
|
yading@11
|
1438
|
yading@11
|
1439 int main(void)
|
yading@11
|
1440 {
|
yading@11
|
1441 int i;
|
yading@11
|
1442
|
yading@11
|
1443 printf("\nTesting av_set_options_string()\n");
|
yading@11
|
1444 {
|
yading@11
|
1445 TestContext test_ctx = { 0 };
|
yading@11
|
1446 const char *options[] = {
|
yading@11
|
1447 "",
|
yading@11
|
1448 ":",
|
yading@11
|
1449 "=",
|
yading@11
|
1450 "foo=:",
|
yading@11
|
1451 ":=foo",
|
yading@11
|
1452 "=foo",
|
yading@11
|
1453 "foo=",
|
yading@11
|
1454 "foo",
|
yading@11
|
1455 "foo=val",
|
yading@11
|
1456 "foo==val",
|
yading@11
|
1457 "toggle=:",
|
yading@11
|
1458 "string=:",
|
yading@11
|
1459 "toggle=1 : foo",
|
yading@11
|
1460 "toggle=100",
|
yading@11
|
1461 "toggle==1",
|
yading@11
|
1462 "flags=+mu-lame : num=42: toggle=0",
|
yading@11
|
1463 "num=42 : string=blahblah",
|
yading@11
|
1464 "rational=0 : rational=1/2 : rational=1/-1",
|
yading@11
|
1465 "rational=-1/0",
|
yading@11
|
1466 "size=1024x768",
|
yading@11
|
1467 "size=pal",
|
yading@11
|
1468 "size=bogus",
|
yading@11
|
1469 "pix_fmt=yuv420p",
|
yading@11
|
1470 "pix_fmt=2",
|
yading@11
|
1471 "pix_fmt=bogus",
|
yading@11
|
1472 "sample_fmt=s16",
|
yading@11
|
1473 "sample_fmt=2",
|
yading@11
|
1474 "sample_fmt=bogus",
|
yading@11
|
1475 "video_rate=pal",
|
yading@11
|
1476 "video_rate=25",
|
yading@11
|
1477 "video_rate=30000/1001",
|
yading@11
|
1478 "video_rate=30/1.001",
|
yading@11
|
1479 "video_rate=bogus",
|
yading@11
|
1480 "duration=bogus",
|
yading@11
|
1481 "duration=123.45",
|
yading@11
|
1482 "duration=1\\:23\\:45.67",
|
yading@11
|
1483 };
|
yading@11
|
1484
|
yading@11
|
1485 test_ctx.class = &test_class;
|
yading@11
|
1486 av_opt_set_defaults(&test_ctx);
|
yading@11
|
1487
|
yading@11
|
1488 av_log_set_level(AV_LOG_DEBUG);
|
yading@11
|
1489
|
yading@11
|
1490 for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
|
yading@11
|
1491 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
|
yading@11
|
1492 if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
|
yading@11
|
1493 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
|
yading@11
|
1494 printf("\n");
|
yading@11
|
1495 }
|
yading@11
|
1496 av_freep(&test_ctx.string);
|
yading@11
|
1497 }
|
yading@11
|
1498
|
yading@11
|
1499 printf("\nTesting av_opt_set_from_string()\n");
|
yading@11
|
1500 {
|
yading@11
|
1501 TestContext test_ctx = { 0 };
|
yading@11
|
1502 const char *options[] = {
|
yading@11
|
1503 "",
|
yading@11
|
1504 "5",
|
yading@11
|
1505 "5:hello",
|
yading@11
|
1506 "5:hello:size=pal",
|
yading@11
|
1507 "5:size=pal:hello",
|
yading@11
|
1508 ":",
|
yading@11
|
1509 "=",
|
yading@11
|
1510 " 5 : hello : size = pal ",
|
yading@11
|
1511 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
|
yading@11
|
1512 };
|
yading@11
|
1513 const char *shorthand[] = { "num", "string", NULL };
|
yading@11
|
1514
|
yading@11
|
1515 test_ctx.class = &test_class;
|
yading@11
|
1516 av_opt_set_defaults(&test_ctx);
|
yading@11
|
1517 test_ctx.string = av_strdup("default");
|
yading@11
|
1518
|
yading@11
|
1519 av_log_set_level(AV_LOG_DEBUG);
|
yading@11
|
1520
|
yading@11
|
1521 for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
|
yading@11
|
1522 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
|
yading@11
|
1523 if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
|
yading@11
|
1524 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
|
yading@11
|
1525 printf("\n");
|
yading@11
|
1526 }
|
yading@11
|
1527 av_freep(&test_ctx.string);
|
yading@11
|
1528 }
|
yading@11
|
1529
|
yading@11
|
1530 return 0;
|
yading@11
|
1531 }
|
yading@11
|
1532
|
yading@11
|
1533 #endif
|