You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
7.1KB

  1. /*
  2. * LGPL
  3. */
  4. /*
  5. * typical parsed command line:
  6. * msmpeg4:bitrate=720000:qmax=16
  7. *
  8. */
  9. #include "avcodec.h"
  10. #ifdef OPTS_MAIN
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #endif
  15. /*
  16. * todo - use for decoder options also
  17. */
  18. static int parse_bool(avc_config_t* c, char* s)
  19. {
  20. int b = 1; /* by default -on- when present */
  21. if (s) {
  22. if (!strcasecmp(s, "off") || !strcasecmp(s, "false")
  23. || !strcmp(s, "0"))
  24. b = 0;
  25. else if (!strcasecmp(s, "on") || !strcasecmp(s, "true")
  26. || !strcmp(s, "1"))
  27. b = 1;
  28. else
  29. return -1;
  30. }
  31. if (c && c->val)
  32. *(int*)(c->val) = b;
  33. return 0;
  34. }
  35. static int parse_double(avc_config_t* c, char* s)
  36. {
  37. double d;
  38. if (!s)
  39. return -1;
  40. d = atof(s);
  41. if (c->min != c->max) {
  42. if (d < c->min || d > c->max) {
  43. fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n",
  44. c->name, d, c->min, c->max);
  45. return -1;
  46. }
  47. }
  48. if (c && c->val)
  49. *(double*)(c->val) = d;
  50. return 0;
  51. }
  52. static int parse_int(avc_config_t* c, char* s)
  53. {
  54. int i;
  55. if (!s)
  56. return -1;
  57. i = atoi(s);
  58. if (c->min != c->max) {
  59. if (i < (int)c->min || i > (int)c->max) {
  60. fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n",
  61. c->name, i, (int)c->min, (int)c->max);
  62. return -1;
  63. }
  64. }
  65. if (c && c->val)
  66. *(int*)(c->val) = i;
  67. return 0;
  68. }
  69. static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
  70. {
  71. if (!s)
  72. return -1;
  73. if (c->type == FF_CONF_TYPE_RCOVERIDE) {
  74. int sf, ef, qs;
  75. float qf;
  76. if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
  77. RcOverride* o;
  78. *((RcOverride**)c->val) =
  79. realloc(*((RcOverride**)c->val),
  80. sizeof(RcOverride) * (avctx->rc_override_count + 1));
  81. o = *((RcOverride**)c->val) + avctx->rc_override_count++;
  82. o->start_frame = sf;
  83. o->end_frame = ef;
  84. o->qscale = qs;
  85. o->quality_factor = qf;
  86. //printf("parsed Rc: %d,%d,%d,%f (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
  87. } else {
  88. printf("incorrect/unparsable Rc: \"%s\"\n", s);
  89. }
  90. } else
  91. (char*)(c->val) = strdup(s);
  92. return 0;
  93. }
  94. static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
  95. {
  96. while (str && *str) {
  97. avc_config_t* c = config;
  98. char* e = strchr(str, ':');
  99. char* p;
  100. if (e)
  101. *e++ = 0;
  102. p = strchr(str, '=');
  103. if (p)
  104. *p++ = 0;
  105. while (c->name) {
  106. if (!strcmp(c->name, str)) {
  107. switch (c->type & FF_CONF_TYPE_MASK) {
  108. case FF_CONF_TYPE_BOOL:
  109. parse_bool(c, p);
  110. break;
  111. case FF_CONF_TYPE_DOUBLE:
  112. parse_double(c, p);
  113. break;
  114. case FF_CONF_TYPE_INT:
  115. parse_int(c, p);
  116. break;
  117. case FF_CONF_TYPE_STRING:
  118. parse_string(avctx, c, p);
  119. break;
  120. default:
  121. abort();
  122. break;
  123. }
  124. }
  125. c++;
  126. }
  127. str = e;
  128. }
  129. return 0;
  130. }
  131. /**
  132. *
  133. * \param avctx where to store parsed results
  134. * \param str string with options for parsing
  135. * or selectional string (pick only options appliable
  136. * for codec - use ,msmpeg4, (with commas to avoid mismatch)
  137. * \param config allocated avc_config_t for external parsing
  138. * i.e. external program might learn about all available
  139. * options for given codec
  140. **/
  141. void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
  142. {
  143. AVCodecContext avctx_tmp;
  144. AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp;
  145. static const char* class_h263 = ",msmpeg4,";
  146. //"huffyuv,wmv1,msmpeg4v2,msmpeg4,mpeg4,mpeg1,mpeg1video,mjpeg,rv10,h263,h263p"
  147. avc_config_t cnf[] =
  148. {
  149. // FIXME: sorted by importance!!!
  150. // expert option should follow more common ones
  151. {
  152. "bitrate", "desired video bitrate",
  153. FF_CONF_TYPE_INT, &ctx->bit_rate, 4, 240000000, 800000, NULL, class_h263
  154. }, {
  155. "vhq", "very high quality",
  156. FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_HQ, 0, NULL, class_h263
  157. }, {
  158. "ratetol", "number of bits the bitstream is allowed to diverge from the reference"
  159. "the reference can be CBR (for CBR pass1) or VBR (for pass2)",
  160. FF_CONF_TYPE_INT, &ctx->bit_rate_tolerance, 4, 240000000, 8000, NULL, class_h263
  161. }, {
  162. "qmin", "minimum quantizer", FF_CONF_TYPE_INT, &ctx->qmin, 1, 31, 2, NULL, class_h263
  163. }, {
  164. "qmax", "maximum qunatizer", FF_CONF_TYPE_INT, &ctx->qmax, 1, 31, 31, NULL, class_h263
  165. }, {
  166. "rc_eq", "rate control equation",
  167. FF_CONF_TYPE_STRING, &ctx->rc_eq, 0, 0, 0, "tex^qComp" /* FILLME options */, class_h263
  168. }, {
  169. "rc_minrate", "rate control minimum bitrate",
  170. FF_CONF_TYPE_INT, &ctx->rc_min_rate, 4, 24000000, 0, NULL, class_h263
  171. }, {
  172. "rc_maxrate", "rate control maximum bitrate",
  173. FF_CONF_TYPE_INT, &ctx->rc_max_rate, 4, 24000000, 0, NULL, class_h263
  174. }, {
  175. "psnr", "calculate PSNR of compressed frames",
  176. FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_PSNR, 0, NULL, class_h263
  177. }, {
  178. "rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)",
  179. FF_CONF_TYPE_RCOVERIDE, &ctx->rc_override, 0, 0, 0, "0,0,0,0", class_h263
  180. },
  181. { NULL, NULL, 0, NULL, 0, 0, 0, NULL, NULL }
  182. };
  183. if (config) {
  184. *config = malloc(sizeof(cnf));
  185. if (*config) {
  186. avc_config_t* src = cnf;
  187. avc_config_t* dst = *config;
  188. while (src->name) {
  189. if (!str || !src->supported || strstr(src->supported, str))
  190. memcpy(dst++, src, sizeof(avc_config_t));
  191. src++;
  192. }
  193. memset(dst, 0, sizeof(avc_config_t));
  194. }
  195. } else if (str) {
  196. char* s = strdup(str);
  197. if (s) {
  198. parse(avctx, cnf, s);
  199. free(s);
  200. }
  201. }
  202. }
  203. #ifdef OPTS_MAIN
  204. /*
  205. * API test -
  206. * arg1: options
  207. * arg2: codec type
  208. *
  209. * compile standalone: make CFLAGS="-DOPTS_MAIN" opts
  210. */
  211. int main(int argc, char* argv[])
  212. {
  213. AVCodecContext avctx;
  214. avc_config_t* config;
  215. char* def = malloc(5000);
  216. const char* col = "";
  217. int i = 0;
  218. memset(&avctx, 0, sizeof(avctx));
  219. *def = 0;
  220. avcodec_getopt(&avctx, argv[1], NULL);
  221. avcodec_getopt(NULL, (argc > 2) ? argv[2] : NULL, &config);
  222. if (config)
  223. while (config->name) {
  224. int t = config->type & FF_CONF_TYPE_MASK;
  225. printf("Config %s %s\n", config->name,
  226. t == FF_CONF_TYPE_BOOL ? "bool" :
  227. t == FF_CONF_TYPE_DOUBLE ? "double" :
  228. t == FF_CONF_TYPE_INT ? "integer" :
  229. t == FF_CONF_TYPE_STRING ? "string" :
  230. "unknown??");
  231. switch (t) {
  232. case FF_CONF_TYPE_BOOL:
  233. i += sprintf(def + i, "%s%s=%s",
  234. col, config->name,
  235. config->defval != 0. ? "on" : "off");
  236. break;
  237. case FF_CONF_TYPE_DOUBLE:
  238. i += sprintf(def + i, "%s%s=%f",
  239. col, config->name, config->defval);
  240. break;
  241. case FF_CONF_TYPE_INT:
  242. i += sprintf(def + i, "%s%s=%d",
  243. col, config->name, (int) config->defval);
  244. break;
  245. case FF_CONF_TYPE_STRING:
  246. i += sprintf(def + i, "%s%s=%s",
  247. col, config->name, config->defstr);
  248. break;
  249. }
  250. col = ":";
  251. config++;
  252. }
  253. printf("Default Options: %s\n", def);
  254. return 0;
  255. }
  256. #endif