opt.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. * AVOptions
  3. * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. /**
  23. * @file opt.c
  24. * AVOptions
  25. * @author Michael Niedermayer <michaelni@gmx.at>
  26. */
  27. #include "avcodec.h"
  28. #include "opt.h"
  29. #include "eval.h"
  30. //FIXME order them and do a bin search
  31. const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags){
  32. AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
  33. const AVOption *o= c->option;
  34. for(;o && o->name; o++){
  35. if(!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags )
  36. return o;
  37. }
  38. return NULL;
  39. }
  40. const AVOption *av_next_option(void *obj, const AVOption *last){
  41. if(last && last[1].name) return ++last;
  42. else if(last) return NULL;
  43. else return (*(AVClass**)obj)->option;
  44. }
  45. static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
  46. const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
  47. void *dst;
  48. if(!o || o->offset<=0)
  49. return NULL;
  50. if(o->max*den < num*intnum || o->min*den > num*intnum) {
  51. av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name);
  52. return NULL;
  53. }
  54. dst= ((uint8_t*)obj) + o->offset;
  55. switch(o->type){
  56. case FF_OPT_TYPE_FLAGS:
  57. case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break;
  58. case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break;
  59. case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
  60. case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
  61. case FF_OPT_TYPE_RATIONAL:
  62. if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
  63. else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
  64. default:
  65. return NULL;
  66. }
  67. return o;
  68. }
  69. static const AVOption *set_all_opt(void *v, const char *unit, double d){
  70. AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
  71. const AVOption *o= c->option;
  72. const AVOption *ret=NULL;
  73. for(;o && o->name; o++){
  74. if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){
  75. double tmp= d;
  76. if(o->type == FF_OPT_TYPE_FLAGS)
  77. tmp= av_get_int(v, o->name, NULL) | (int64_t)d;
  78. av_set_number(v, o->name, tmp, 1, 1);
  79. ret= o;
  80. }
  81. }
  82. return ret;
  83. }
  84. static double const_values[]={
  85. M_PI,
  86. M_E,
  87. FF_QP2LAMBDA,
  88. 0
  89. };
  90. static const char *const_names[]={
  91. "PI",
  92. "E",
  93. "QP2LAMBDA",
  94. 0
  95. };
  96. const AVOption *av_set_string(void *obj, const char *name, const char *val){
  97. const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
  98. if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
  99. return set_all_opt(obj, o->unit, o->default_val);
  100. }
  101. if(!o || !val || o->offset<=0)
  102. return NULL;
  103. if(o->type != FF_OPT_TYPE_STRING){
  104. for(;;){
  105. int i;
  106. char buf[256];
  107. int cmd=0;
  108. double d;
  109. char *error = NULL;
  110. if(*val == '+' || *val == '-')
  111. cmd= *(val++);
  112. for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
  113. buf[i]= val[i];
  114. buf[i]=0;
  115. val+= i;
  116. d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error);
  117. if(isnan(d)) {
  118. const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
  119. if(o_named && o_named->type == FF_OPT_TYPE_CONST)
  120. d= o_named->default_val;
  121. else if(!strcmp(buf, "default")) d= o->default_val;
  122. else if(!strcmp(buf, "max" )) d= o->max;
  123. else if(!strcmp(buf, "min" )) d= o->min;
  124. else if(!strcmp(buf, "none" )) d= 0;
  125. else if(!strcmp(buf, "all" )) d= ~0;
  126. else {
  127. if (!error)
  128. av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
  129. return NULL;
  130. }
  131. }
  132. if(o->type == FF_OPT_TYPE_FLAGS){
  133. if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
  134. else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
  135. }else if(cmd=='-')
  136. d= -d;
  137. av_set_number(obj, name, d, 1, 1);
  138. if(!*val)
  139. return o;
  140. }
  141. return NULL;
  142. }
  143. memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val));
  144. return o;
  145. }
  146. const AVOption *av_set_double(void *obj, const char *name, double n){
  147. return av_set_number(obj, name, n, 1, 1);
  148. }
  149. const AVOption *av_set_q(void *obj, const char *name, AVRational n){
  150. return av_set_number(obj, name, n.num, n.den, 1);
  151. }
  152. const AVOption *av_set_int(void *obj, const char *name, int64_t n){
  153. return av_set_number(obj, name, 1, 1, n);
  154. }
  155. /**
  156. *
  157. * @param buf a buffer which is used for returning non string values as strings, can be NULL
  158. * @param buf_len allocated length in bytes of buf
  159. */
  160. const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){
  161. const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
  162. void *dst;
  163. if(!o || o->offset<=0)
  164. return NULL;
  165. if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
  166. return NULL;
  167. dst= ((uint8_t*)obj) + o->offset;
  168. if(o_out) *o_out= o;
  169. if(o->type == FF_OPT_TYPE_STRING)
  170. return dst;
  171. switch(o->type){
  172. case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
  173. case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
  174. case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
  175. case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
  176. case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
  177. case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
  178. default: return NULL;
  179. }
  180. return buf;
  181. }
  182. static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum){
  183. const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
  184. void *dst;
  185. if(!o || o->offset<=0)
  186. goto error;
  187. dst= ((uint8_t*)obj) + o->offset;
  188. if(o_out) *o_out= o;
  189. switch(o->type){
  190. case FF_OPT_TYPE_FLAGS:
  191. case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0;
  192. case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0;
  193. case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0;
  194. case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0;
  195. case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num;
  196. *den = ((AVRational*)dst)->den;
  197. return 0;
  198. }
  199. error:
  200. *den=*intnum=0;
  201. return -1;
  202. }
  203. double av_get_double(void *obj, const char *name, const AVOption **o_out){
  204. int64_t intnum=1;
  205. double num=1;
  206. int den=1;
  207. av_get_number(obj, name, o_out, &num, &den, &intnum);
  208. return num*intnum/den;
  209. }
  210. AVRational av_get_q(void *obj, const char *name, const AVOption **o_out){
  211. int64_t intnum=1;
  212. double num=1;
  213. int den=1;
  214. av_get_number(obj, name, o_out, &num, &den, &intnum);
  215. if(num == 1.0 && (int)intnum == intnum)
  216. return (AVRational){intnum, den};
  217. else
  218. return av_d2q(num*intnum/den, 1<<24);
  219. }
  220. int64_t av_get_int(void *obj, const char *name, const AVOption **o_out){
  221. int64_t intnum=1;
  222. double num=1;
  223. int den=1;
  224. av_get_number(obj, name, o_out, &num, &den, &intnum);
  225. return num*intnum/den;
  226. }
  227. static void opt_list(void *obj, void *av_log_obj, const char *unit)
  228. {
  229. const AVOption *opt=NULL;
  230. while((opt= av_next_option(obj, opt))){
  231. if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
  232. continue;
  233. /* Don't print CONST's on level one.
  234. * Don't print anything but CONST's on level two.
  235. * Only print items from the requested unit.
  236. */
  237. if (!unit && opt->type==FF_OPT_TYPE_CONST)
  238. continue;
  239. else if (unit && opt->type!=FF_OPT_TYPE_CONST)
  240. continue;
  241. else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit))
  242. continue;
  243. else if (unit && opt->type == FF_OPT_TYPE_CONST)
  244. av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
  245. else
  246. av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
  247. switch( opt->type )
  248. {
  249. case FF_OPT_TYPE_FLAGS:
  250. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" );
  251. break;
  252. case FF_OPT_TYPE_INT:
  253. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" );
  254. break;
  255. case FF_OPT_TYPE_INT64:
  256. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" );
  257. break;
  258. case FF_OPT_TYPE_DOUBLE:
  259. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" );
  260. break;
  261. case FF_OPT_TYPE_FLOAT:
  262. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" );
  263. break;
  264. case FF_OPT_TYPE_STRING:
  265. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" );
  266. break;
  267. case FF_OPT_TYPE_RATIONAL:
  268. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
  269. break;
  270. case FF_OPT_TYPE_CONST:
  271. default:
  272. av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
  273. break;
  274. }
  275. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
  276. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
  277. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
  278. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
  279. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
  280. if(opt->help)
  281. av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
  282. av_log(av_log_obj, AV_LOG_INFO, "\n");
  283. if (opt->unit && opt->type != FF_OPT_TYPE_CONST) {
  284. opt_list(obj, av_log_obj, opt->unit);
  285. }
  286. }
  287. }
  288. int av_opt_show(void *obj, void *av_log_obj){
  289. if(!obj)
  290. return -1;
  291. av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
  292. opt_list(obj, av_log_obj, NULL);
  293. return 0;
  294. }
  295. /** Set the values of the AVCodecContext or AVFormatContext structure.
  296. * They are set to the defaults specified in the according AVOption options
  297. * array default_val field.
  298. *
  299. * @param s AVCodecContext or AVFormatContext for which the defaults will be set
  300. */
  301. void av_opt_set_defaults2(void *s, int mask, int flags)
  302. {
  303. const AVOption *opt = NULL;
  304. while ((opt = av_next_option(s, opt)) != NULL) {
  305. if((opt->flags & mask) != flags)
  306. continue;
  307. switch(opt->type) {
  308. case FF_OPT_TYPE_CONST:
  309. /* Nothing to be done here */
  310. break;
  311. case FF_OPT_TYPE_FLAGS:
  312. case FF_OPT_TYPE_INT: {
  313. int val;
  314. val = opt->default_val;
  315. av_set_int(s, opt->name, val);
  316. }
  317. break;
  318. case FF_OPT_TYPE_FLOAT: {
  319. double val;
  320. val = opt->default_val;
  321. av_set_double(s, opt->name, val);
  322. }
  323. break;
  324. case FF_OPT_TYPE_RATIONAL: {
  325. AVRational val;
  326. val = av_d2q(opt->default_val, INT_MAX);
  327. av_set_q(s, opt->name, val);
  328. }
  329. break;
  330. case FF_OPT_TYPE_STRING:
  331. /* Cannot set default for string as default_val is of type * double */
  332. break;
  333. default:
  334. av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
  335. }
  336. }
  337. }
  338. void av_opt_set_defaults(void *s){
  339. av_opt_set_defaults2(s, 0, 0);
  340. }