3 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * @author Michael Niedermayer <michaelni@gmx.at>
30 static double av_parse_num(const char *name
, char **tail
){
32 d
= strtod(name
, tail
);
33 if(*tail
>name
&& (**tail
=='/' || **tail
==':'))
34 d
/=strtod((*tail
)+1, tail
);
38 //FIXME order them and do a bin search
39 static AVOption
*find_opt(void *v
, const char *name
, const char *unit
){
40 AVClass
*c
= *(AVClass
**)v
; //FIXME silly way of storing AVClass
41 AVOption
*o
= c
->option
;
43 for(;o
&& o
->name
; o
++){
44 if(!strcmp(o
->name
, name
) && (!unit
|| !strcmp(o
->unit
, unit
)) )
50 AVOption
*av_next_option(void *obj
, AVOption
*last
){
51 if(last
&& last
[1].name
) return ++last
;
52 else if(last
) return NULL
;
53 else return (*(AVClass
**)obj
)->option
;
56 static AVOption
*av_set_number(void *obj
, const char *name
, double num
, int den
, int64_t intnum
){
57 AVOption
*o
= find_opt(obj
, name
, NULL
);
59 if(!o
|| o
->offset
<=0)
62 if(o
->max
*den
< num
*intnum
|| o
->min
*den
> num
*intnum
)
65 dst
= ((uint8_t*)obj
) + o
->offset
;
68 case FF_OPT_TYPE_FLAGS
:
69 case FF_OPT_TYPE_INT
: *(int *)dst
= lrintf(num
/den
)*intnum
; break;
70 case FF_OPT_TYPE_INT64
: *(int64_t *)dst
= lrintf(num
/den
)*intnum
; break;
71 case FF_OPT_TYPE_FLOAT
: *(float *)dst
= num
*intnum
/den
; break;
72 case FF_OPT_TYPE_DOUBLE
:*(double *)dst
= num
*intnum
/den
; break;
73 case FF_OPT_TYPE_RATIONAL
:
74 if((int)num
== num
) *(AVRational
*)dst
= (AVRational
){num
*intnum
, den
};
75 else *(AVRational
*)dst
= av_d2q(num
*intnum
/den
, 1<<24);
82 static AVOption
*set_all_opt(void *v
, const char *unit
, double d
){
83 AVClass
*c
= *(AVClass
**)v
; //FIXME silly way of storing AVClass
84 AVOption
*o
= c
->option
;
87 for(;o
&& o
->name
; o
++){
88 if(o
->type
!= FF_OPT_TYPE_CONST
&& o
->unit
&& !strcmp(o
->unit
, unit
)){
90 if(o
->type
== FF_OPT_TYPE_FLAGS
)
91 tmp
= av_get_int(v
, o
->name
, NULL
) | (int64_t)d
;
93 av_set_number(v
, o
->name
, tmp
, 1, 1);
100 //FIXME use eval.c maybe?
101 AVOption
*av_set_string(void *obj
, const char *name
, const char *val
){
102 AVOption
*o
= find_opt(obj
, name
, NULL
);
103 if(o
&& o
->offset
==0 && o
->type
== FF_OPT_TYPE_CONST
&& o
->unit
){
104 return set_all_opt(obj
, o
->unit
, o
->default_val
);
106 if(!o
|| !val
|| o
->offset
<=0)
108 if(o
->type
!= FF_OPT_TYPE_STRING
){
111 char buf
[256], *tail
;
115 if(*val
== '+' || *val
== '-')
118 for(i
=0; i
<sizeof(buf
)-1 && val
[i
] && val
[i
]!='+' && val
[i
]!='-'; i
++)
123 d
= av_parse_num(buf
, &tail
);
125 AVOption
*o_named
= find_opt(obj
, buf
, o
->unit
);
126 if(o_named
&& o_named
->type
== FF_OPT_TYPE_CONST
)
127 d
= o_named
->default_val
;
128 else if(!strcmp(buf
, "default")) d
= o
->default_val
;
129 else if(!strcmp(buf
, "max" )) d
= o
->max
;
130 else if(!strcmp(buf
, "min" )) d
= o
->min
;
133 if(o
->type
== FF_OPT_TYPE_FLAGS
){
134 if (cmd
=='+') d
= av_get_int(obj
, name
, NULL
) | (int64_t)d
;
135 else if(cmd
=='-') d
= av_get_int(obj
, name
, NULL
) &~(int64_t)d
;
139 av_set_number(obj
, name
, d
, 1, 1);
146 memcpy(((uint8_t*)obj
) + o
->offset
, val
, sizeof(val
));
150 AVOption
*av_set_double(void *obj
, const char *name
, double n
){
151 return av_set_number(obj
, name
, n
, 1, 1);
154 AVOption
*av_set_q(void *obj
, const char *name
, AVRational n
){
155 return av_set_number(obj
, name
, n
.num
, n
.den
, 1);
158 AVOption
*av_set_int(void *obj
, const char *name
, int64_t n
){
159 return av_set_number(obj
, name
, 1, 1, n
);
164 * @param buf a buffer which is used for returning non string values as strings, can be NULL
165 * @param buf_len allocated length in bytes of buf
167 const char *av_get_string(void *obj
, const char *name
, AVOption
**o_out
, char *buf
, int buf_len
){
168 AVOption
*o
= find_opt(obj
, name
, NULL
);
170 if(!o
|| o
->offset
<=0)
172 if(o
->type
!= FF_OPT_TYPE_STRING
&& (!buf
|| !buf_len
))
175 dst
= ((uint8_t*)obj
) + o
->offset
;
178 if(o
->type
== FF_OPT_TYPE_STRING
)
182 case FF_OPT_TYPE_FLAGS
: snprintf(buf
, buf_len
, "0x%08X",*(int *)dst
);break;
183 case FF_OPT_TYPE_INT
: snprintf(buf
, buf_len
, "%d" , *(int *)dst
);break;
184 case FF_OPT_TYPE_INT64
: snprintf(buf
, buf_len
, "%"PRId64
, *(int64_t*)dst
);break;
185 case FF_OPT_TYPE_FLOAT
: snprintf(buf
, buf_len
, "%f" , *(float *)dst
);break;
186 case FF_OPT_TYPE_DOUBLE
: snprintf(buf
, buf_len
, "%f" , *(double *)dst
);break;
187 case FF_OPT_TYPE_RATIONAL
: snprintf(buf
, buf_len
, "%d/%d", ((AVRational
*)dst
)->num
, ((AVRational
*)dst
)->den
);break;
188 default: return NULL
;
193 static int av_get_number(void *obj
, const char *name
, AVOption
**o_out
, double *num
, int *den
, int64_t *intnum
){
194 AVOption
*o
= find_opt(obj
, name
, NULL
);
196 if(!o
|| o
->offset
<=0)
199 dst
= ((uint8_t*)obj
) + o
->offset
;
204 case FF_OPT_TYPE_FLAGS
:
205 case FF_OPT_TYPE_INT
: *intnum
= *(int *)dst
;return 0;
206 case FF_OPT_TYPE_INT64
: *intnum
= *(int64_t*)dst
;return 0;
207 case FF_OPT_TYPE_FLOAT
: *num
= *(float *)dst
;return 0;
208 case FF_OPT_TYPE_DOUBLE
: *num
= *(double *)dst
;return 0;
209 case FF_OPT_TYPE_RATIONAL
: *intnum
= ((AVRational
*)dst
)->num
;
210 *den
= ((AVRational
*)dst
)->den
;
218 double av_get_double(void *obj
, const char *name
, AVOption
**o_out
){
223 av_get_number(obj
, name
, o_out
, &num
, &den
, &intnum
);
224 return num
*intnum
/den
;
227 AVRational
av_get_q(void *obj
, const char *name
, AVOption
**o_out
){
232 av_get_number(obj
, name
, o_out
, &num
, &den
, &intnum
);
233 if(num
== 1.0 && (int)intnum
== intnum
)
234 return (AVRational
){intnum
, den
};
236 return av_d2q(num
*intnum
/den
, 1<<24);
239 int64_t av_get_int(void *obj
, const char *name
, AVOption
**o_out
){
244 av_get_number(obj
, name
, o_out
, &num
, &den
, &intnum
);
245 return num
*intnum
/den
;
248 int av_opt_show(void *obj
, void *av_log_obj
){
254 av_log(av_log_obj
, AV_LOG_INFO
, "%s AVOptions:\n", (*(AVClass
**)obj
)->class_name
);
256 while((opt
= av_next_option(obj
, opt
))){
257 if(!(opt
->flags
& (AV_OPT_FLAG_ENCODING_PARAM
|AV_OPT_FLAG_DECODING_PARAM
)))
260 av_log(av_log_obj
, AV_LOG_INFO
, "-%-17s ", opt
->name
);
264 case FF_OPT_TYPE_FLAGS
:
265 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<flags>" );
267 case FF_OPT_TYPE_INT
:
268 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<int>" );
270 case FF_OPT_TYPE_INT64
:
271 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<int64>" );
273 case FF_OPT_TYPE_DOUBLE
:
274 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<double>" );
276 case FF_OPT_TYPE_FLOAT
:
277 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<float>" );
279 case FF_OPT_TYPE_STRING
:
280 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<string>" );
282 case FF_OPT_TYPE_RATIONAL
:
283 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "<rational>" );
285 case FF_OPT_TYPE_CONST
:
287 av_log( av_log_obj
, AV_LOG_INFO
, "%-7s ", "" );
290 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_ENCODING_PARAM
) ? 'E' : '.');
291 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_DECODING_PARAM
) ? 'D' : '.');
292 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_VIDEO_PARAM
) ? 'V' : '.');
293 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_AUDIO_PARAM
) ? 'A' : '.');
294 av_log(av_log_obj
, AV_LOG_INFO
, "%c", (opt
->flags
& AV_OPT_FLAG_SUBTITLE_PARAM
) ? 'S' : '.');
297 av_log(av_log_obj
, AV_LOG_INFO
, " %s", opt
->help
);
298 av_log(av_log_obj
, AV_LOG_INFO
, "\n");