00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avcodec.h"
00029 #include "opt.h"
00030 #include "eval.h"
00031
00032
00033 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags){
00034 AVClass *c= *(AVClass**)v;
00035 const AVOption *o= c->option;
00036
00037 for(;o && o->name; o++){
00038 if(!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags )
00039 return o;
00040 }
00041 return NULL;
00042 }
00043
00044 const AVOption *av_next_option(void *obj, const AVOption *last){
00045 if(last && last[1].name) return ++last;
00046 else if(last) return NULL;
00047 else return (*(AVClass**)obj)->option;
00048 }
00049
00050 static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
00051 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00052 void *dst;
00053 if(!o || o->offset<=0)
00054 return NULL;
00055
00056 if(o->max*den < num*intnum || o->min*den > num*intnum) {
00057 av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name);
00058 return NULL;
00059 }
00060
00061 dst= ((uint8_t*)obj) + o->offset;
00062
00063 switch(o->type){
00064 case FF_OPT_TYPE_FLAGS:
00065 case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break;
00066 case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break;
00067 case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
00068 case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
00069 case FF_OPT_TYPE_RATIONAL:
00070 if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
00071 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
00072 default:
00073 return NULL;
00074 }
00075 return o;
00076 }
00077
00078 static const AVOption *set_all_opt(void *v, const char *unit, double d){
00079 AVClass *c= *(AVClass**)v;
00080 const AVOption *o= c->option;
00081 const AVOption *ret=NULL;
00082
00083 for(;o && o->name; o++){
00084 if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){
00085 double tmp= d;
00086 if(o->type == FF_OPT_TYPE_FLAGS)
00087 tmp= av_get_int(v, o->name, NULL) | (int64_t)d;
00088
00089 av_set_number(v, o->name, tmp, 1, 1);
00090 ret= o;
00091 }
00092 }
00093 return ret;
00094 }
00095
00096 static double const_values[]={
00097 M_PI,
00098 M_E,
00099 FF_QP2LAMBDA,
00100 0
00101 };
00102
00103 static const char *const_names[]={
00104 "PI",
00105 "E",
00106 "QP2LAMBDA",
00107 0
00108 };
00109
00110 const AVOption *av_set_string(void *obj, const char *name, const char *val){
00111 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00112 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
00113 return set_all_opt(obj, o->unit, o->default_val);
00114 }
00115 if(!o || !val || o->offset<=0)
00116 return NULL;
00117 if(o->type != FF_OPT_TYPE_STRING){
00118 for(;;){
00119 int i;
00120 char buf[256];
00121 int cmd=0;
00122 double d;
00123 char *error = NULL;
00124
00125 if(*val == '+' || *val == '-')
00126 cmd= *(val++);
00127
00128 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
00129 buf[i]= val[i];
00130 buf[i]=0;
00131 val+= i;
00132
00133 d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error);
00134 if(isnan(d)) {
00135 const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
00136 if(o_named && o_named->type == FF_OPT_TYPE_CONST)
00137 d= o_named->default_val;
00138 else if(!strcmp(buf, "default")) d= o->default_val;
00139 else if(!strcmp(buf, "max" )) d= o->max;
00140 else if(!strcmp(buf, "min" )) d= o->min;
00141 else if(!strcmp(buf, "none" )) d= 0;
00142 else if(!strcmp(buf, "all" )) d= ~0;
00143 else {
00144 if (!error)
00145 av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
00146 return NULL;
00147 }
00148 }
00149 if(o->type == FF_OPT_TYPE_FLAGS){
00150 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
00151 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
00152 }else if(cmd=='-')
00153 d= -d;
00154
00155 av_set_number(obj, name, d, 1, 1);
00156 if(!*val)
00157 return o;
00158 }
00159 return NULL;
00160 }
00161
00162 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val));
00163 return o;
00164 }
00165
00166 const AVOption *av_set_double(void *obj, const char *name, double n){
00167 return av_set_number(obj, name, n, 1, 1);
00168 }
00169
00170 const AVOption *av_set_q(void *obj, const char *name, AVRational n){
00171 return av_set_number(obj, name, n.num, n.den, 1);
00172 }
00173
00174 const AVOption *av_set_int(void *obj, const char *name, int64_t n){
00175 return av_set_number(obj, name, 1, 1, n);
00176 }
00177
00183 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){
00184 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00185 void *dst;
00186 if(!o || o->offset<=0)
00187 return NULL;
00188 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
00189 return NULL;
00190
00191 dst= ((uint8_t*)obj) + o->offset;
00192 if(o_out) *o_out= o;
00193
00194 if(o->type == FF_OPT_TYPE_STRING)
00195 return dst;
00196
00197 switch(o->type){
00198 case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
00199 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
00200 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
00201 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
00202 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
00203 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
00204 default: return NULL;
00205 }
00206 return buf;
00207 }
00208
00209 static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum){
00210 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00211 void *dst;
00212 if(!o || o->offset<=0)
00213 goto error;
00214
00215 dst= ((uint8_t*)obj) + o->offset;
00216
00217 if(o_out) *o_out= o;
00218
00219 switch(o->type){
00220 case FF_OPT_TYPE_FLAGS:
00221 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0;
00222 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0;
00223 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0;
00224 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0;
00225 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num;
00226 *den = ((AVRational*)dst)->den;
00227 return 0;
00228 }
00229 error:
00230 *den=*intnum=0;
00231 return -1;
00232 }
00233
00234 double av_get_double(void *obj, const char *name, const AVOption **o_out){
00235 int64_t intnum=1;
00236 double num=1;
00237 int den=1;
00238
00239 av_get_number(obj, name, o_out, &num, &den, &intnum);
00240 return num*intnum/den;
00241 }
00242
00243 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out){
00244 int64_t intnum=1;
00245 double num=1;
00246 int den=1;
00247
00248 av_get_number(obj, name, o_out, &num, &den, &intnum);
00249 if(num == 1.0 && (int)intnum == intnum)
00250 return (AVRational){intnum, den};
00251 else
00252 return av_d2q(num*intnum/den, 1<<24);
00253 }
00254
00255 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out){
00256 int64_t intnum=1;
00257 double num=1;
00258 int den=1;
00259
00260 av_get_number(obj, name, o_out, &num, &den, &intnum);
00261 return num*intnum/den;
00262 }
00263
00264 static void opt_list(void *obj, void *av_log_obj, const char *unit)
00265 {
00266 const AVOption *opt=NULL;
00267
00268 while((opt= av_next_option(obj, opt))){
00269 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
00270 continue;
00271
00272
00273
00274
00275
00276 if (!unit && opt->type==FF_OPT_TYPE_CONST)
00277 continue;
00278 else if (unit && opt->type!=FF_OPT_TYPE_CONST)
00279 continue;
00280 else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit))
00281 continue;
00282 else if (unit && opt->type == FF_OPT_TYPE_CONST)
00283 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
00284 else
00285 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
00286
00287 switch( opt->type )
00288 {
00289 case FF_OPT_TYPE_FLAGS:
00290 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" );
00291 break;
00292 case FF_OPT_TYPE_INT:
00293 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" );
00294 break;
00295 case FF_OPT_TYPE_INT64:
00296 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" );
00297 break;
00298 case FF_OPT_TYPE_DOUBLE:
00299 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" );
00300 break;
00301 case FF_OPT_TYPE_FLOAT:
00302 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" );
00303 break;
00304 case FF_OPT_TYPE_STRING:
00305 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" );
00306 break;
00307 case FF_OPT_TYPE_RATIONAL:
00308 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
00309 break;
00310 case FF_OPT_TYPE_CONST:
00311 default:
00312 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
00313 break;
00314 }
00315 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
00316 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
00317 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
00318 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
00319 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
00320
00321 if(opt->help)
00322 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
00323 av_log(av_log_obj, AV_LOG_INFO, "\n");
00324 if (opt->unit && opt->type != FF_OPT_TYPE_CONST) {
00325 opt_list(obj, av_log_obj, opt->unit);
00326 }
00327 }
00328 }
00329
00330 int av_opt_show(void *obj, void *av_log_obj){
00331 if(!obj)
00332 return -1;
00333
00334 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
00335
00336 opt_list(obj, av_log_obj, NULL);
00337
00338 return 0;
00339 }
00340
00347 void av_opt_set_defaults2(void *s, int mask, int flags)
00348 {
00349 const AVOption *opt = NULL;
00350 while ((opt = av_next_option(s, opt)) != NULL) {
00351 if((opt->flags & mask) != flags)
00352 continue;
00353 switch(opt->type) {
00354 case FF_OPT_TYPE_CONST:
00355
00356 break;
00357 case FF_OPT_TYPE_FLAGS:
00358 case FF_OPT_TYPE_INT: {
00359 int val;
00360 val = opt->default_val;
00361 av_set_int(s, opt->name, val);
00362 }
00363 break;
00364 case FF_OPT_TYPE_FLOAT: {
00365 double val;
00366 val = opt->default_val;
00367 av_set_double(s, opt->name, val);
00368 }
00369 break;
00370 case FF_OPT_TYPE_RATIONAL: {
00371 AVRational val;
00372 val = av_d2q(opt->default_val, INT_MAX);
00373 av_set_q(s, opt->name, val);
00374 }
00375 break;
00376 case FF_OPT_TYPE_STRING:
00377
00378 break;
00379 default:
00380 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
00381 }
00382 }
00383 }
00384
00385 void av_opt_set_defaults(void *s){
00386 av_opt_set_defaults2(s, 0, 0);
00387 }
00388