* still unfinished code for Options
Originally committed as revision 1568 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
5c91a6755b
commit
97d96aaa76
@ -950,6 +950,42 @@ typedef struct AVCodecContext {
|
|||||||
enum PixelFormat (*get_format)(struct AVCodecContext *s, enum PixelFormat * fmt);
|
enum PixelFormat (*get_format)(struct AVCodecContext *s, enum PixelFormat * fmt);
|
||||||
} AVCodecContext;
|
} AVCodecContext;
|
||||||
|
|
||||||
|
//void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
|
||||||
|
|
||||||
|
typedef struct AVOption {
|
||||||
|
/** options' name */
|
||||||
|
const char *name; /* if name is NULL, it indicates a link to next */
|
||||||
|
/** short English text help */
|
||||||
|
const char *help;
|
||||||
|
/** offset to context structure where the parsed value should be stored */
|
||||||
|
int offset;
|
||||||
|
/** options' type */
|
||||||
|
int type;
|
||||||
|
#define FF_OPT_TYPE_BOOL 1 // boolean - true,1,on (or simply presence)
|
||||||
|
#define FF_OPT_TYPE_DOUBLE 2 // double
|
||||||
|
#define FF_OPT_TYPE_INT 3 // integer
|
||||||
|
#define FF_OPT_TYPE_STRING 4 // string (finished with \0)
|
||||||
|
#define FF_OPT_TYPE_MASK 0x1f // mask for types - upper bits are various flags
|
||||||
|
//#define FF_OPT_TYPE_EXPERT 0x20 // flag for expert option
|
||||||
|
#define FF_OPT_TYPE_FLAG (FF_OPT_TYPE_BOOL | 0x40)
|
||||||
|
#define FF_OPT_TYPE_RCOVERRIDE (FF_OPT_TYPE_STRING | 0x80)
|
||||||
|
/** min value (min == max -> no limits) */
|
||||||
|
double min;
|
||||||
|
/** maximum value for double/int */
|
||||||
|
double max;
|
||||||
|
/** default boo [0,1]l/double/int value */
|
||||||
|
double defval;
|
||||||
|
/**
|
||||||
|
* default string value (with optional semicolon delimited extra option-list
|
||||||
|
* i.e. option1;option2;option3
|
||||||
|
* defval might select other then first argument as default
|
||||||
|
*/
|
||||||
|
const char *defstr;
|
||||||
|
const struct AVOption *sub; /* used when name is NULL */
|
||||||
|
/* when it's NULL return to previous level (or finish reading) */
|
||||||
|
#define FF_OPT_MAX_DEPTH 10
|
||||||
|
} AVOption;
|
||||||
|
|
||||||
typedef struct AVCodec {
|
typedef struct AVCodec {
|
||||||
const char *name;
|
const char *name;
|
||||||
int type;
|
int type;
|
||||||
@ -961,6 +997,7 @@ typedef struct AVCodec {
|
|||||||
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
|
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
|
||||||
UINT8 *buf, int buf_size);
|
UINT8 *buf, int buf_size);
|
||||||
int capabilities;
|
int capabilities;
|
||||||
|
const AVOption *options;
|
||||||
struct AVCodec *next;
|
struct AVCodec *next;
|
||||||
} AVCodec;
|
} AVCodec;
|
||||||
|
|
||||||
@ -1135,40 +1172,7 @@ void avcodec_register_all(void);
|
|||||||
|
|
||||||
void avcodec_flush_buffers(AVCodecContext *avctx);
|
void avcodec_flush_buffers(AVCodecContext *avctx);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/** options' name with default value*/
|
|
||||||
const char* name;
|
|
||||||
/** English text help */
|
|
||||||
const char* help;
|
|
||||||
/** type of variable */
|
|
||||||
int type;
|
|
||||||
#define FF_CONF_TYPE_BOOL 1 // boolean - true,1,on (or simply presence)
|
|
||||||
#define FF_CONF_TYPE_DOUBLE 2 // double
|
|
||||||
#define FF_CONF_TYPE_INT 3 // integer
|
|
||||||
#define FF_CONF_TYPE_STRING 4 // string (finished with \0)
|
|
||||||
#define FF_CONF_TYPE_MASK 0x1f // mask for types - upper bits are various flags
|
|
||||||
#define FF_CONF_TYPE_EXPERT 0x20 // flag for expert option
|
|
||||||
#define FF_CONF_TYPE_FLAG (FF_CONF_TYPE_BOOL | 0x40)
|
|
||||||
#define FF_CONF_TYPE_RCOVERIDE (FF_CONF_TYPE_STRING | 0x80)
|
|
||||||
/** where the parsed value should be stored */
|
|
||||||
void* val;
|
|
||||||
/** min value (min == max -> no limits) */
|
|
||||||
double min;
|
|
||||||
/** maximum value for double/int */
|
|
||||||
double max;
|
|
||||||
/** default boo [0,1]l/double/int value */
|
|
||||||
double defval;
|
|
||||||
/**
|
|
||||||
* default string value (with optional semicolon delimited extra option-list
|
|
||||||
* i.e. option1;option2;option3
|
|
||||||
* defval might select other then first argument as default
|
|
||||||
*/
|
|
||||||
const char* defstr;
|
|
||||||
/** char* list of supported codecs (i.e. ",msmpeg4,h263," NULL - everything */
|
|
||||||
const char* supported;
|
|
||||||
} avc_config_t;
|
|
||||||
|
|
||||||
void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for 0.5.0 version
|
* Interface for 0.5.0 version
|
||||||
@ -1254,7 +1258,7 @@ void av_free(void *ptr);
|
|||||||
char *av_strdup(const char *s);
|
char *av_strdup(const char *s);
|
||||||
void __av_freep(void **ptr);
|
void __av_freep(void **ptr);
|
||||||
#define av_freep(p) __av_freep((void **)(p))
|
#define av_freep(p) __av_freep((void **)(p))
|
||||||
void *av_fast_realloc(void *ptr, int *size, int min_size);
|
void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
|
||||||
/* for static data only */
|
/* for static data only */
|
||||||
/* call av_free_static to release all staticaly allocated tables */
|
/* call av_free_static to release all staticaly allocated tables */
|
||||||
void av_free_static(void);
|
void av_free_static(void);
|
||||||
|
@ -9,17 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#ifdef OPTS_MAIN
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
extern const AVOption common_options[2];
|
||||||
* todo - use for decoder options also
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int parse_bool(avc_config_t* c, char* s)
|
const AVOption common_options[2] = {
|
||||||
|
AVOPTION_CODEC_INT("common", "test", bit_rate, 0, 10, 0),
|
||||||
|
AVOPTION_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_bool(const AVOption *c, char *s, int *var)
|
||||||
{
|
{
|
||||||
int b = 1; /* by default -on- when present */
|
int b = 1; /* by default -on- when present */
|
||||||
if (s) {
|
if (s) {
|
||||||
@ -33,12 +31,11 @@ static int parse_bool(avc_config_t* c, char* s)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c && c->val)
|
*var = b;
|
||||||
*(int*)(c->val) = b;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_double(avc_config_t* c, char* s)
|
static int parse_double(const AVOption *c, char *s, double *var)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
if (!s)
|
if (!s)
|
||||||
@ -51,12 +48,11 @@ static int parse_double(avc_config_t* c, char* s)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c && c->val)
|
*var = d;
|
||||||
*(double*)(c->val) = d;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_int(avc_config_t* c, char* s)
|
static int parse_int(const AVOption* c, char* s, int* var)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (!s)
|
if (!s)
|
||||||
@ -69,25 +65,23 @@ static int parse_int(avc_config_t* c, char* s)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c && c->val)
|
*var = i;
|
||||||
*(int*)(c->val) = i;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
|
static int parse_string(const AVOption *c, char *s, AVCodecContext *avctx, char **var)
|
||||||
{
|
{
|
||||||
if (!s)
|
if (!s)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (c->type == FF_CONF_TYPE_RCOVERIDE) {
|
if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
|
||||||
int sf, ef, qs;
|
int sf, ef, qs;
|
||||||
float qf;
|
float qf;
|
||||||
if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
|
if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
|
||||||
RcOverride* o;
|
RcOverride *o;
|
||||||
*((RcOverride**)c->val) =
|
avctx->rc_override = av_realloc(avctx->rc_override,
|
||||||
realloc(*((RcOverride**)c->val),
|
|
||||||
sizeof(RcOverride) * (avctx->rc_override_count + 1));
|
sizeof(RcOverride) * (avctx->rc_override_count + 1));
|
||||||
o = *((RcOverride**)c->val) + avctx->rc_override_count++;
|
o = avctx->rc_override + avctx->rc_override_count++;
|
||||||
o->start_frame = sf;
|
o->start_frame = sf;
|
||||||
o->end_frame = ef;
|
o->end_frame = ef;
|
||||||
o->qscale = qs;
|
o->qscale = qs;
|
||||||
@ -98,14 +92,27 @@ static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
|
|||||||
printf("incorrect/unparsable Rc: \"%s\"\n", s);
|
printf("incorrect/unparsable Rc: \"%s\"\n", s);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
(char*)(c->val) = strdup(s);
|
*var = av_strdup(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
|
/**
|
||||||
|
*
|
||||||
|
* \param codec codec for option parsing
|
||||||
|
* \param opts string with options for parsing
|
||||||
|
* \param avctx where to store parsed results
|
||||||
|
*/
|
||||||
|
int avcodec_parse(const AVCodec *codec, const char *opts, AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
while (str && *str) {
|
int r = 0;
|
||||||
avc_config_t* c = config;
|
char* dopts = av_strdup(opts);
|
||||||
|
if (dopts) {
|
||||||
|
char *str = dopts;
|
||||||
|
|
||||||
|
while (str && *str && r == 0) {
|
||||||
|
const AVOption *stack[FF_OPT_MAX_DEPTH];
|
||||||
|
int depth = 0;
|
||||||
|
const AVOption *c = codec->options;
|
||||||
char* e = strchr(str, ':');
|
char* e = strchr(str, ':');
|
||||||
char* p;
|
char* p;
|
||||||
if (e)
|
if (e)
|
||||||
@ -115,164 +122,46 @@ static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
|
|||||||
if (p)
|
if (p)
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
|
|
||||||
while (c->name) {
|
// going through option structures
|
||||||
|
for (;;) {
|
||||||
|
if (!c->name) {
|
||||||
|
if (c->sub) {
|
||||||
|
stack[depth++] = c;
|
||||||
|
c = c->sub;
|
||||||
|
assert(depth > FF_OPT_MAX_DEPTH);
|
||||||
|
} else {
|
||||||
|
if (depth == 0)
|
||||||
|
break; // finished
|
||||||
|
c = stack[--depth];
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (!strcmp(c->name, str)) {
|
if (!strcmp(c->name, str)) {
|
||||||
switch (c->type & FF_CONF_TYPE_MASK) {
|
void* ptr = (char*)avctx + c->offset;
|
||||||
case FF_CONF_TYPE_BOOL:
|
|
||||||
parse_bool(c, p);
|
switch (c->type & FF_OPT_TYPE_MASK) {
|
||||||
|
case FF_OPT_TYPE_BOOL:
|
||||||
|
r = parse_bool(c, p, (int*)ptr);
|
||||||
break;
|
break;
|
||||||
case FF_CONF_TYPE_DOUBLE:
|
case FF_OPT_TYPE_DOUBLE:
|
||||||
parse_double(c, p);
|
r = parse_double(c, p, (double*)ptr);
|
||||||
break;
|
break;
|
||||||
case FF_CONF_TYPE_INT:
|
case FF_OPT_TYPE_INT:
|
||||||
parse_int(c, p);
|
r = parse_int(c, p, (int*)ptr);
|
||||||
break;
|
break;
|
||||||
case FF_CONF_TYPE_STRING:
|
case FF_OPT_TYPE_STRING:
|
||||||
parse_string(avctx, c, p);
|
r = parse_string(c, p, avctx, (char**)ptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
assert(0 == 1);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
str = e;
|
str = e;
|
||||||
}
|
}
|
||||||
return 0;
|
av_free(dopts);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* \param avctx where to store parsed results
|
|
||||||
* \param str string with options for parsing
|
|
||||||
* or selectional string (pick only options appliable
|
|
||||||
* for codec - use ,msmpeg4, (with commas to avoid mismatch)
|
|
||||||
* \param config allocated avc_config_t for external parsing
|
|
||||||
* i.e. external program might learn about all available
|
|
||||||
* options for given codec
|
|
||||||
**/
|
|
||||||
void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
|
|
||||||
{
|
|
||||||
AVCodecContext avctx_tmp;
|
|
||||||
AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp;
|
|
||||||
static const char* class_h263 = ",msmpeg4,";
|
|
||||||
//"huffyuv,wmv1,msmpeg4v2,msmpeg4,mpeg4,mpeg1,mpeg1video,mjpeg,rv10,h263,h263p"
|
|
||||||
|
|
||||||
avc_config_t cnf[] =
|
|
||||||
{
|
|
||||||
// FIXME: sorted by importance!!!
|
|
||||||
// expert option should follow more common ones
|
|
||||||
{
|
|
||||||
"bitrate", "desired video bitrate",
|
|
||||||
FF_CONF_TYPE_INT, &ctx->bit_rate, 4, 240000000, 800000, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"vhq", "very high quality",
|
|
||||||
FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_HQ, 0, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"ratetol", "number of bits the bitstream is allowed to diverge from the reference"
|
|
||||||
"the reference can be CBR (for CBR pass1) or VBR (for pass2)",
|
|
||||||
FF_CONF_TYPE_INT, &ctx->bit_rate_tolerance, 4, 240000000, 8000, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"qmin", "minimum quantizer", FF_CONF_TYPE_INT, &ctx->qmin, 1, 31, 2, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"qmax", "maximum qunatizer", FF_CONF_TYPE_INT, &ctx->qmax, 1, 31, 31, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"rc_eq", "rate control equation",
|
|
||||||
FF_CONF_TYPE_STRING, &ctx->rc_eq, 0, 0, 0, "tex^qComp" /* FILLME options */, class_h263
|
|
||||||
}, {
|
|
||||||
"rc_minrate", "rate control minimum bitrate",
|
|
||||||
FF_CONF_TYPE_INT, &ctx->rc_min_rate, 4, 24000000, 0, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"rc_maxrate", "rate control maximum bitrate",
|
|
||||||
FF_CONF_TYPE_INT, &ctx->rc_max_rate, 4, 24000000, 0, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"psnr", "calculate PSNR of compressed frames",
|
|
||||||
FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_PSNR, 0, NULL, class_h263
|
|
||||||
}, {
|
|
||||||
"rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)",
|
|
||||||
FF_CONF_TYPE_RCOVERIDE, &ctx->rc_override, 0, 0, 0, "0,0,0,0", class_h263
|
|
||||||
},
|
|
||||||
|
|
||||||
{ NULL, NULL, 0, NULL, 0, 0, 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config) {
|
|
||||||
*config = malloc(sizeof(cnf));
|
|
||||||
if (*config) {
|
|
||||||
avc_config_t* src = cnf;
|
|
||||||
avc_config_t* dst = *config;
|
|
||||||
while (src->name) {
|
|
||||||
if (!str || !src->supported || strstr(src->supported, str))
|
|
||||||
memcpy(dst++, src, sizeof(avc_config_t));
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
memset(dst, 0, sizeof(avc_config_t));
|
|
||||||
}
|
|
||||||
} else if (str) {
|
|
||||||
char* s = strdup(str);
|
|
||||||
if (s) {
|
|
||||||
parse(avctx, cnf, s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef OPTS_MAIN
|
|
||||||
/*
|
|
||||||
* API test -
|
|
||||||
* arg1: options
|
|
||||||
* arg2: codec type
|
|
||||||
*
|
|
||||||
* compile standalone: make CFLAGS="-DOPTS_MAIN" opts
|
|
||||||
*/
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
AVCodecContext avctx;
|
|
||||||
avc_config_t* config;
|
|
||||||
char* def = malloc(5000);
|
|
||||||
const char* col = "";
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
memset(&avctx, 0, sizeof(avctx));
|
|
||||||
*def = 0;
|
|
||||||
avcodec_getopt(&avctx, argv[1], NULL);
|
|
||||||
|
|
||||||
avcodec_getopt(NULL, (argc > 2) ? argv[2] : NULL, &config);
|
|
||||||
if (config)
|
|
||||||
while (config->name) {
|
|
||||||
int t = config->type & FF_CONF_TYPE_MASK;
|
|
||||||
printf("Config %s %s\n", config->name,
|
|
||||||
t == FF_CONF_TYPE_BOOL ? "bool" :
|
|
||||||
t == FF_CONF_TYPE_DOUBLE ? "double" :
|
|
||||||
t == FF_CONF_TYPE_INT ? "integer" :
|
|
||||||
t == FF_CONF_TYPE_STRING ? "string" :
|
|
||||||
"unknown??");
|
|
||||||
switch (t) {
|
|
||||||
case FF_CONF_TYPE_BOOL:
|
|
||||||
i += sprintf(def + i, "%s%s=%s",
|
|
||||||
col, config->name,
|
|
||||||
config->defval != 0. ? "on" : "off");
|
|
||||||
break;
|
|
||||||
case FF_CONF_TYPE_DOUBLE:
|
|
||||||
i += sprintf(def + i, "%s%s=%f",
|
|
||||||
col, config->name, config->defval);
|
|
||||||
break;
|
|
||||||
case FF_CONF_TYPE_INT:
|
|
||||||
i += sprintf(def + i, "%s%s=%d",
|
|
||||||
col, config->name, (int) config->defval);
|
|
||||||
break;
|
|
||||||
case FF_CONF_TYPE_STRING:
|
|
||||||
i += sprintf(def + i, "%s%s=%s",
|
|
||||||
col, config->name, config->defstr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
col = ":";
|
|
||||||
config++;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Default Options: %s\n", def);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user