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 break;
00073 default:
00074 return NULL;
00075 }
00076 return o;
00077 }
00078
00079 static const AVOption *set_all_opt(void *v, const char *unit, double d){
00080 AVClass *c= *(AVClass**)v;
00081 const AVOption *o= c->option;
00082 const AVOption *ret=NULL;
00083
00084 for(;o && o->name; o++){
00085 if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){
00086 double tmp= d;
00087 if(o->type == FF_OPT_TYPE_FLAGS)
00088 tmp= av_get_int(v, o->name, NULL) | (int64_t)d;
00089
00090 av_set_number(v, o->name, tmp, 1, 1);
00091 ret= o;
00092 }
00093 }
00094 return ret;
00095 }
00096
00097 static double const_values[]={
00098 M_PI,
00099 M_E,
00100 FF_QP2LAMBDA,
00101 0
00102 };
00103
00104 static const char *const_names[]={
00105 "PI",
00106 "E",
00107 "QP2LAMBDA",
00108 0
00109 };
00110
00111 static int hexchar2int(char c) {
00112 if (c >= '0' && c <= '9') return c - '0';
00113 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
00114 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
00115 return -1;
00116 }
00117
00118 const AVOption *av_set_string(void *obj, const char *name, const char *val){
00119 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00120 if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
00121 return set_all_opt(obj, o->unit, o->default_val);
00122 }
00123 if(!o || !val || o->offset<=0)
00124 return NULL;
00125 if(o->type == FF_OPT_TYPE_BINARY){
00126 uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset);
00127 int *lendst = (int *)(dst + 1);
00128 uint8_t *bin, *ptr;
00129 int len = strlen(val);
00130 av_freep(dst);
00131 *lendst = 0;
00132 if (len & 1) return NULL;
00133 len /= 2;
00134 ptr = bin = av_malloc(len);
00135 while (*val) {
00136 int a = hexchar2int(*val++);
00137 int b = hexchar2int(*val++);
00138 if (a < 0 || b < 0) {
00139 av_free(bin);
00140 return NULL;
00141 }
00142 *ptr++ = (a << 4) | b;
00143 }
00144 *dst = bin;
00145 *lendst = len;
00146 return o;
00147 }
00148 if(o->type != FF_OPT_TYPE_STRING){
00149 for(;;){
00150 int i;
00151 char buf[256];
00152 int cmd=0;
00153 double d;
00154 char *error = NULL;
00155
00156 if(*val == '+' || *val == '-')
00157 cmd= *(val++);
00158
00159 for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
00160 buf[i]= val[i];
00161 buf[i]=0;
00162 val+= i;
00163
00164 d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error);
00165 if(isnan(d)) {
00166 const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
00167 if(o_named && o_named->type == FF_OPT_TYPE_CONST)
00168 d= o_named->default_val;
00169 else if(!strcmp(buf, "default")) d= o->default_val;
00170 else if(!strcmp(buf, "max" )) d= o->max;
00171 else if(!strcmp(buf, "min" )) d= o->min;
00172 else if(!strcmp(buf, "none" )) d= 0;
00173 else if(!strcmp(buf, "all" )) d= ~0;
00174 else {
00175 if (!error)
00176 av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
00177 return NULL;
00178 }
00179 }
00180 if(o->type == FF_OPT_TYPE_FLAGS){
00181 if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
00182 else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
00183 }else if(cmd=='-')
00184 d= -d;
00185
00186 av_set_number(obj, name, d, 1, 1);
00187 if(!*val)
00188 return o;
00189 }
00190 return NULL;
00191 }
00192
00193 memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val));
00194 return o;
00195 }
00196
00197 const AVOption *av_set_double(void *obj, const char *name, double n){
00198 return av_set_number(obj, name, n, 1, 1);
00199 }
00200
00201 const AVOption *av_set_q(void *obj, const char *name, AVRational n){
00202 return av_set_number(obj, name, n.num, n.den, 1);
00203 }
00204
00205 const AVOption *av_set_int(void *obj, const char *name, int64_t n){
00206 return av_set_number(obj, name, 1, 1, n);
00207 }
00208
00214 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){
00215 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00216 void *dst;
00217 uint8_t *bin;
00218 int len, i;
00219 if(!o || o->offset<=0)
00220 return NULL;
00221 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
00222 return NULL;
00223
00224 dst= ((uint8_t*)obj) + o->offset;
00225 if(o_out) *o_out= o;
00226
00227 switch(o->type){
00228 case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
00229 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
00230 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
00231 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
00232 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
00233 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
00234 case FF_OPT_TYPE_STRING: return *(void**)dst;
00235 case FF_OPT_TYPE_BINARY:
00236 len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
00237 if(len >= (buf_len + 1)/2) return NULL;
00238 bin = *(uint8_t**)dst;
00239 for(i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
00240 break;
00241 default: return NULL;
00242 }
00243 return buf;
00244 }
00245
00246 static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum){
00247 const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
00248 void *dst;
00249 if(!o || o->offset<=0)
00250 goto error;
00251
00252 dst= ((uint8_t*)obj) + o->offset;
00253
00254 if(o_out) *o_out= o;
00255
00256 switch(o->type){
00257 case FF_OPT_TYPE_FLAGS:
00258 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0;
00259 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0;
00260 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0;
00261 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0;
00262 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num;
00263 *den = ((AVRational*)dst)->den;
00264 return 0;
00265 }
00266 error:
00267 *den=*intnum=0;
00268 return -1;
00269 }
00270
00271 double av_get_double(void *obj, const char *name, const AVOption **o_out){
00272 int64_t intnum=1;
00273 double num=1;
00274 int den=1;
00275
00276 av_get_number(obj, name, o_out, &num, &den, &intnum);
00277 return num*intnum/den;
00278 }
00279
00280 AVRational av_get_q(void *obj, const char *name, const AVOption **o_out){
00281 int64_t intnum=1;
00282 double num=1;
00283 int den=1;
00284
00285 av_get_number(obj, name, o_out, &num, &den, &intnum);
00286 if(num == 1.0 && (int)intnum == intnum)
00287 return (AVRational){intnum, den};
00288 else
00289 return av_d2q(num*intnum/den, 1<<24);
00290 }
00291
00292 int64_t av_get_int(void *obj, const char *name, const AVOption **o_out){
00293 int64_t intnum=1;
00294 double num=1;
00295 int den=1;
00296
00297 av_get_number(obj, name, o_out, &num, &den, &intnum);
00298 return num*intnum/den;
00299 }
00300
00301 static void opt_list(void *obj, void *av_log_obj, const char *unit)
00302 {
00303 const AVOption *opt=NULL;
00304
00305 while((opt= av_next_option(obj, opt))){
00306 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
00307 continue;
00308
00309
00310
00311
00312
00313 if (!unit && opt->type==FF_OPT_TYPE_CONST)
00314 continue;
00315 else if (unit && opt->type!=FF_OPT_TYPE_CONST)
00316 continue;
00317 else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit))
00318 continue;
00319 else if (unit && opt->type == FF_OPT_TYPE_CONST)
00320 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
00321 else
00322 av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
00323
00324 switch( opt->type )
00325 {
00326 case FF_OPT_TYPE_FLAGS:
00327 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" );
00328 break;
00329 case FF_OPT_TYPE_INT:
00330 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" );
00331 break;
00332 case FF_OPT_TYPE_INT64:
00333 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" );
00334 break;
00335 case FF_OPT_TYPE_DOUBLE:
00336 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" );
00337 break;
00338 case FF_OPT_TYPE_FLOAT:
00339 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" );
00340 break;
00341 case FF_OPT_TYPE_STRING:
00342 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" );
00343 break;
00344 case FF_OPT_TYPE_RATIONAL:
00345 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
00346 break;
00347 case FF_OPT_TYPE_BINARY:
00348 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>" );
00349 break;
00350 case FF_OPT_TYPE_CONST:
00351 default:
00352 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
00353 break;
00354 }
00355 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
00356 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
00357 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
00358 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
00359 av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
00360
00361 if(opt->help)
00362 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
00363 av_log(av_log_obj, AV_LOG_INFO, "\n");
00364 if (opt->unit && opt->type != FF_OPT_TYPE_CONST) {
00365 opt_list(obj, av_log_obj, opt->unit);
00366 }
00367 }
00368 }
00369
00370 int av_opt_show(void *obj, void *av_log_obj){
00371 if(!obj)
00372 return -1;
00373
00374 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
00375
00376 opt_list(obj, av_log_obj, NULL);
00377
00378 return 0;
00379 }
00380
00387 void av_opt_set_defaults2(void *s, int mask, int flags)
00388 {
00389 const AVOption *opt = NULL;
00390 while ((opt = av_next_option(s, opt)) != NULL) {
00391 if((opt->flags & mask) != flags)
00392 continue;
00393 switch(opt->type) {
00394 case FF_OPT_TYPE_CONST:
00395
00396 break;
00397 case FF_OPT_TYPE_FLAGS:
00398 case FF_OPT_TYPE_INT: {
00399 int val;
00400 val = opt->default_val;
00401 av_set_int(s, opt->name, val);
00402 }
00403 break;
00404 case FF_OPT_TYPE_FLOAT: {
00405 double val;
00406 val = opt->default_val;
00407 av_set_double(s, opt->name, val);
00408 }
00409 break;
00410 case FF_OPT_TYPE_RATIONAL: {
00411 AVRational val;
00412 val = av_d2q(opt->default_val, INT_MAX);
00413 av_set_q(s, opt->name, val);
00414 }
00415 break;
00416 case FF_OPT_TYPE_STRING:
00417 case FF_OPT_TYPE_BINARY:
00418
00419 break;
00420 default:
00421 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
00422 }
00423 }
00424 }
00425
00426 void av_opt_set_defaults(void *s){
00427 av_opt_set_defaults2(s, 0, 0);
00428 }
00429