changeset 2873:55809f38eb63 libavcodec

AVOption API improvments support AVOptions for encoding in ffmpeg.c
author michael
date Sun, 11 Sep 2005 11:10:25 +0000
parents 062b2d5d1eba
children b6def74f5811
files avcodec.h opt.c utils.c
diffstat 3 files changed, 220 insertions(+), 135 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Sat Sep 10 23:00:13 2005 +0000
+++ b/avcodec.h	Sun Sep 11 11:10:25 2005 +0000
@@ -21,8 +21,8 @@
 #define AV_STRINGIFY(s)	AV_TOSTRING(s)
 #define AV_TOSTRING(s) #s
 
-#define LIBAVCODEC_VERSION_INT ((49<<16)+(2<<8)+0)
-#define LIBAVCODEC_VERSION     49.2.0
+#define LIBAVCODEC_VERSION_INT ((50<<16)+(0<<8)+0)
+#define LIBAVCODEC_VERSION     50.0.0
 #define LIBAVCODEC_BUILD       LIBAVCODEC_VERSION_INT
 
 #define LIBAVCODEC_IDENT       "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
@@ -703,6 +703,10 @@
 #define AV_OPT_FLAG_ENCODING_PARAM  1   ///< a generic parameter which can be set by the user for muxing or encoding
 #define AV_OPT_FLAG_DECODING_PARAM  2   ///< a generic parameter which can be set by the user for demuxing or decoding
 #define AV_OPT_FLAG_METADATA        4   ///< some data extracted or inserted into the file like title, comment, ...
+#define AV_OPT_FLAG_AUDIO_PARAM     8
+#define AV_OPT_FLAG_VIDEO_PARAM     16
+#define AV_OPT_FLAG_SUBTITLE_PARAM  32
+//FIXME think about enc-audio, ... style flags
 } AVOption;
 
 /**
@@ -1883,14 +1887,16 @@
     enum AVDiscard skip_frame;
 } AVCodecContext;
 
-int av_set_string(void *obj, const char *name, const char *val);
-int av_set_double(void *obj, const char *name, double n);
-int av_set_q(void *obj, const char *name, AVRational n);
-int av_set_int(void *obj, const char *name, int64_t n);
-const char *av_get_string(void *obj, const char *name);
-double av_get_double(void *obj, const char *name);
+AVOption *av_set_string(void *obj, const char *name, const char *val);
+AVOption *av_set_double(void *obj, const char *name, double n);
+AVOption *av_set_q(void *obj, const char *name, AVRational n);
+AVOption *av_set_int(void *obj, const char *name, int64_t n);
+double av_get_double(void *obj, const char *name, AVOption **o_out);
+AVRational av_get_q(void *obj, const char *name, AVOption **o_out);
+int64_t av_get_int(void *obj, const char *name, AVOption **o_out);
+const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len);
 AVOption *av_next_option(void *obj, AVOption *last);
-
+int av_opt_show(void *obj, FILE *f);
 
 /**
  * AVCodec.
--- a/opt.c	Sat Sep 10 23:00:13 2005 +0000
+++ b/opt.c	Sun Sep 11 11:10:25 2005 +0000
@@ -52,46 +52,36 @@
     else                     return (*(AVClass**)obj)->option;
 }
 
-static int av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
+static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
     AVOption *o= find_opt(obj, name);
     void *dst;
     if(!o || o->offset<=0) 
-        return -1;
+        return NULL;
     
     if(o->max*den < num*intnum || o->min*den > num*intnum)
-        return -1;
+        return NULL;
         
     dst= ((uint8_t*)obj) + o->offset;
 
     switch(o->type){
-    case FF_OPT_TYPE_INT:
-        *(int*)dst= lrintf(num/den)*intnum;
-        break;
-    case FF_OPT_TYPE_INT64:
-        *(int64_t*)dst= lrintf(num/den)*intnum;
-        break;
-    case FF_OPT_TYPE_FLOAT:
-        *(float*)dst= num*intnum/den;
-        break;
-    case FF_OPT_TYPE_DOUBLE:
-        *(double*)dst= num*intnum/den;
-        break;
+    case FF_OPT_TYPE_INT:   *(int       *)dst= lrintf(num/den)*intnum; break;
+    case FF_OPT_TYPE_INT64: *(int64_t   *)dst= lrintf(num/den)*intnum; break;
+    case FF_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
+    case FF_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
     case FF_OPT_TYPE_RATIONAL:
-        if((int)num == num)
-            *(AVRational*)dst= (AVRational){num*intnum, den};
-        else
-            *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
+        if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
+        else                *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
     default:
-        return -1;
+        return NULL;
     }
-    return 0;
+    return o;
 }
 
 //FIXME use eval.c maybe?
-int av_set_string(void *obj, const char *name, const char *val){
+AVOption *av_set_string(void *obj, const char *name, const char *val){
     AVOption *o= find_opt(obj, name);
     if(!o || !val || o->offset<=0) 
-        return -1;
+        return NULL;
     if(o->type != FF_OPT_TYPE_STRING){
         double d=0, tmp_d;
         for(;;){
@@ -113,56 +103,136 @@
                 else if(!strcmp(buf, "default")) d+= o->default_val;
                 else if(!strcmp(buf, "max"    )) d+= o->max;
                 else if(!strcmp(buf, "min"    )) d+= o->min;
-                else return -1;
+                else return NULL;
             }
 
             if(*val == '+') val++;
             if(!*val)
                 return av_set_number(obj, name, d, 1, 1);
         }
-        return -1;
+        return NULL;
     }
     
     memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val));
-    return 0;
+    return o;
 }
 
-int av_set_double(void *obj, const char *name, double n){
+AVOption *av_set_double(void *obj, const char *name, double n){
     return av_set_number(obj, name, n, 1, 1);
 }
 
-int av_set_q(void *obj, const char *name, AVRational n){
+AVOption *av_set_q(void *obj, const char *name, AVRational n){
     return av_set_number(obj, name, n.num, n.den, 1);
 }
 
-int av_set_int(void *obj, const char *name, int64_t n){
+AVOption *av_set_int(void *obj, const char *name, int64_t n){
     return av_set_number(obj, name, 1, 1, n);
 }
 
-const char *av_get_string(void *obj, const char *name){
+/**
+ * 
+ * @param buf a buffer which is used for returning non string values as strings, can be NULL
+ * @param buf_len allocated length in bytes of buf
+ */
+const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){
     AVOption *o= find_opt(obj, name);
+    void *dst;
     if(!o || o->offset<=0)
         return NULL;
-    if(o->type != FF_OPT_TYPE_STRING) //FIXME convert to string? but what about free()?
+    if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
         return NULL;
 
-    return (const char*)(((uint8_t*)obj) + o->offset);
+    dst= ((uint8_t*)obj) + o->offset;
+    if(o_out) *o_out= o;
+    
+    if(o->type == FF_OPT_TYPE_STRING)
+        return dst;
+    
+    switch(o->type){
+    case FF_OPT_TYPE_INT:       snprintf(buf, buf_len, "%d" , *(int    *)dst);break;
+    case FF_OPT_TYPE_INT64:     snprintf(buf, buf_len, "%Ld", *(int64_t*)dst);break;
+    case FF_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
+    case FF_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
+    case FF_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+    default: return NULL;
+    }
+    return buf;
 }
 
-double av_get_double(void *obj, const char *name){
+static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){
     AVOption *o= find_opt(obj, name);
     void *dst;
     if(!o || o->offset<=0)
-        return NAN;
+        goto error;
 
     dst= ((uint8_t*)obj) + o->offset;
 
+    if(o_out) *o_out= o;
+
     switch(o->type){
-    case FF_OPT_TYPE_INT:       return *(int*)dst;
-    case FF_OPT_TYPE_INT64:     return *(int64_t*)dst; //FIXME maybe write a av_get_int64() ?
-    case FF_OPT_TYPE_FLOAT:     return *(float*)dst;
-    case FF_OPT_TYPE_DOUBLE:    return *(double*)dst;
-    case FF_OPT_TYPE_RATIONAL:  return av_q2d(*(AVRational*)dst); //FIXME maybe write a av_get_q() ?
-    default:                    return NAN;
+    case FF_OPT_TYPE_INT:       *intnum= *(int    *)dst;return 0;
+    case FF_OPT_TYPE_INT64:     *intnum= *(int64_t*)dst;return 0;
+    case FF_OPT_TYPE_FLOAT:     *num=    *(float  *)dst;return 0;
+    case FF_OPT_TYPE_DOUBLE:    *num=    *(double *)dst;return 0;
+    case FF_OPT_TYPE_RATIONAL:  *intnum= ((AVRational*)dst)->num; 
+                                *den   = ((AVRational*)dst)->den;
+                                                        return 0;
     }
+error:
+    *den=*intnum=0;
+    return -1;
 }
+
+double av_get_double(void *obj, const char *name, AVOption **o_out){
+    int64_t intnum=1;
+    double num=1;
+    int den=1;
+
+    av_get_number(obj, name, o_out, &num, &den, &intnum);
+    return num*intnum/den;
+}
+
+AVRational av_get_q(void *obj, const char *name, AVOption **o_out){
+    int64_t intnum=1;
+    double num=1;
+    int den=1;
+
+    av_get_number(obj, name, o_out, &num, &den, &intnum);
+    if(num == 1.0 && (int)intnum == intnum)
+        return (AVRational){intnum, den};
+    else
+        return av_d2q(num*intnum/den, 1<<24);
+}
+
+int64_t av_get_int(void *obj, const char *name, AVOption **o_out){
+    int64_t intnum=1;
+    double num=1;
+    int den=1;
+
+    av_get_number(obj, name, o_out, &num, &den, &intnum);
+    return num*intnum/den;
+}
+
+int av_opt_show(void *obj, FILE *f){
+    AVOption *opt=NULL;
+    
+    if(!obj)
+        return -1;
+#undef fprintf
+    fprintf(f, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
+
+    while((opt= av_next_option(obj, opt))){
+        if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM)))
+            continue;
+            
+        fprintf(f, "-%-17s ", opt->name);
+        fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
+        fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
+        fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
+        fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
+        fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
+        
+        fprintf(f, " %s\n", opt->help);
+    }
+    return 0;
+}
--- a/utils.c	Sat Sep 10 23:00:13 2005 +0000
+++ b/utils.c	Sun Sep 11 11:10:25 2005 +0000
@@ -437,16 +437,22 @@
 
 #define OFFSET(x) (int)&((AVCodecContext*)0)->x
 #define DEFAULT 0 //should be NAN but it doesnt work as its not a constant in glibc as required by ANSI/ISO C
+//these names are too long to be readable
+#define V AV_OPT_FLAG_VIDEO_PARAM
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define S AV_OPT_FLAG_SUBTITLE_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM 
+#define D AV_OPT_FLAG_DECODING_PARAM
 
 static AVOption options[]={
-{"bit_rate", NULL, OFFSET(bit_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"bit_rate_tolerance", NULL, OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"bit_rate", NULL, OFFSET(bit_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E},
+{"bit_rate_tolerance", NULL, OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, //FIXME
 {"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_method", NULL, OFFSET(me_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"me_method", NULL, OFFSET(me_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX},
-{"gop_size", NULL, OFFSET(gop_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"gop_size", NULL, OFFSET(gop_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"rate_emu", NULL, OFFSET(rate_emu), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"sample_rate", NULL, OFFSET(sample_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"channels", NULL, OFFSET(channels), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
@@ -454,16 +460,16 @@
 {"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"real_pict_num", NULL, OFFSET(real_pict_num), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"qcompress", NULL, OFFSET(qcompress), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"qblur", NULL, OFFSET(qblur), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"qmin", NULL, OFFSET(qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"qmax", NULL, OFFSET(qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"max_qdiff", NULL, OFFSET(max_qdiff), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"max_b_frames", NULL, OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"b_quant_factor", NULL, OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"rc_strategy", NULL, OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"b_frame_strategy", NULL, OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"qcompress", NULL, OFFSET(qcompress), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"qblur", NULL, OFFSET(qblur), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"qmin", NULL, OFFSET(qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"qmax", NULL, OFFSET(qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"max_qdiff", NULL, OFFSET(max_qdiff), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"max_b_frames", NULL, OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"b_quant_factor", NULL, OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"rc_strategy", NULL, OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"b_frame_strategy", NULL, OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
 {"rtp_mode", NULL, OFFSET(rtp_mode), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"rtp_payload_size", NULL, OFFSET(rtp_payload_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"mv_bits", NULL, OFFSET(mv_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
@@ -476,101 +482,104 @@
 {"misc_bits", NULL, OFFSET(misc_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"frame_bits", NULL, OFFSET(frame_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"codec_tag", NULL, OFFSET(codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"workaround_bugs", NULL, OFFSET(workaround_bugs), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"luma_elim_threshold", NULL, OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"chroma_elim_threshold", NULL, OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"strict_std_compliance", NULL, OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"b_quant_offset", NULL, OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"error_resilience", NULL, OFFSET(error_resilience), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"workaround_bugs", NULL, OFFSET(workaround_bugs), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
+{"lelim", "single coefficient elimination threshold for luminance (negative values also consider DC coefficient)", OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"celim", "single coefficient elimination threshold for chrominance (negative values also consider DC coefficient)", OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"strict_std_compliance", NULL, OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"b_quant_offset", NULL, OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"error_resilience", NULL, OFFSET(error_resilience), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
 {"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mpeg_quant", NULL, OFFSET(mpeg_quant), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"mpeg_quant", NULL, OFFSET(mpeg_quant), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"stats_out", NULL, OFFSET(stats_out), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX},
 {"stats_in", NULL, OFFSET(stats_in), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX},
-{"rc_qsquish", NULL, OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"rc_qmod_amp", NULL, OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"rc_qmod_freq", NULL, OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"rc_qsquish", NULL, OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"rc_qmod_amp", NULL, OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"rc_qmod_freq", NULL, OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"rc_override_count", NULL, OFFSET(rc_override_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"rc_eq", NULL, OFFSET(rc_eq), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX},
-{"rc_max_rate", NULL, OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"rc_min_rate", NULL, OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"rc_buffer_size", NULL, OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"rc_buffer_aggressivity", NULL, OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"i_quant_factor", NULL, OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"i_quant_offset", NULL, OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"rc_initial_cplx", NULL, OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"dct_algo", NULL, OFFSET(dct_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"lumi_masking", NULL, OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"temporal_cplx_masking", NULL, OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"spatial_cplx_masking", NULL, OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"p_masking", NULL, OFFSET(p_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"dark_masking", NULL, OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
+{"rc_eq", NULL, OFFSET(rc_eq), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX, V|E},
+{"rc_max_rate", NULL, OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"rc_min_rate", NULL, OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"rc_buffer_size", NULL, OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"rc_buf_aggressivity", NULL, OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"i_quant_factor", NULL, OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"i_quant_offset", NULL, OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"rc_initial_cplx", NULL, OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"dct_algo", NULL, OFFSET(dct_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"lumi_mask", NULL, OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"tcplx_mask", NULL, OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"scplx_mask", NULL, OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"p_mask", NULL, OFFSET(p_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"dark_mask", NULL, OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
 {"unused", NULL, OFFSET(unused), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"idct_algo", NULL, OFFSET(idct_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"idct_algo", NULL, OFFSET(idct_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E|D},
 {"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"error_concealment", NULL, OFFSET(error_concealment), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"error_concealment", NULL, OFFSET(error_concealment), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
 {"bits_per_sample", NULL, OFFSET(bits_per_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"prediction_method", NULL, OFFSET(prediction_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"sample_aspect_ratio", NULL, OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX},
-{"debug", NULL, OFFSET(debug), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"debug_mv", NULL, OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mb_qmin", NULL, OFFSET(mb_qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mb_qmax", NULL, OFFSET(mb_qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_cmp", NULL, OFFSET(me_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_sub_cmp", NULL, OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mb_cmp", NULL, OFFSET(mb_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"ildct_cmp", NULL, OFFSET(ildct_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"dia_size", NULL, OFFSET(dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"last_predictor_count", NULL, OFFSET(last_predictor_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"pre_me", NULL, OFFSET(pre_me), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_pre_cmp", NULL, OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"pre_dia_size", NULL, OFFSET(pre_dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_subpel_quality", NULL, OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"prediction_method", NULL, OFFSET(prediction_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"aspect", NULL, OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"debug", NULL, OFFSET(debug), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|S|E|D},
+{"debug_mv", NULL, OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
+{"mb_qmin", NULL, OFFSET(mb_qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"mb_qmax", NULL, OFFSET(mb_qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"me_cmp", NULL, OFFSET(me_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"me_sub_cmp", NULL, OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"mb_cmp", NULL, OFFSET(mb_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"ildct_cmp", NULL, OFFSET(ildct_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"dia_size", NULL, OFFSET(dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"last_pred", NULL, OFFSET(last_predictor_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"pre_me", NULL, OFFSET(pre_me), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"me_pre_cmp", NULL, OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"pre_dia_size", NULL, OFFSET(pre_dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"me_subpel_quality", NULL, OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"dtg_active_format", NULL, OFFSET(dtg_active_format), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_range", NULL, OFFSET(me_range), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"intra_quant_bias", NULL, OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"inter_quant_bias", NULL, OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"me_range", NULL, OFFSET(me_range), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"ibias", NULL, OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"pbias", NULL, OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"color_table_id", NULL, OFFSET(color_table_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"internal_buffer_count", NULL, OFFSET(internal_buffer_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"global_quality", NULL, OFFSET(global_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"coder_type", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"context_model", NULL, OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"coder_type", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"context_model", NULL, OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mb_decision", NULL, OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"mb_decision", NULL, OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"stream_codec_tag", NULL, OFFSET(stream_codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"scenechange_threshold", NULL, OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"lmin", NULL, OFFSET(lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"lmax", NULL, OFFSET(lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"noise_reduction", NULL, OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"rc_initial_buffer_occupancy", NULL, OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"sc_threshold", NULL, OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"lmin", NULL, OFFSET(lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"lmax", NULL, OFFSET(lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"noise_reduction", NULL, OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"rc_init_occupancy", NULL, OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"error_rate", NULL, OFFSET(error_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"antialias_algo", NULL, OFFSET(antialias_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"quantizer_noise_shaping", NULL, OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"thread_count", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"quantizer_noise_shaping", NULL, OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"thread_count", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E|D},
 {"me_threshold", NULL, OFFSET(me_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
 {"mb_threshold", NULL, OFFSET(mb_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"intra_dc_precision", NULL, OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"nsse_weight", NULL, OFFSET(nsse_weight), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"skip_top", NULL, OFFSET(skip_top), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"skip_bottom", NULL, OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"lowres", NULL, OFFSET(lowres), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"frame_skip_threshold", NULL, OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"frame_skip_factor", NULL, OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"frame_skip_exp", NULL, OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"frame_skip_cmp", NULL, OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"border_masking", NULL, OFFSET(border_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX},
-{"mb_lmin", NULL, OFFSET(mb_lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"mb_lmax", NULL, OFFSET(mb_lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
-{"me_penalty_compensation", NULL, OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"dc", NULL, OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"nsse_weight", NULL, OFFSET(nsse_weight), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"skip_top", NULL, OFFSET(skip_top), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
+{"skip_bottom", NULL, OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
+{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E},
+{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E},
+{"lowres", NULL, OFFSET(lowres), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D},
+{"frame_skip_threshold", NULL, OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"frame_skip_factor", NULL, OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"frame_skip_exp", NULL, OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"frame_skip_cmp", NULL, OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"border_mask", NULL, OFFSET(border_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E},
+{"mb_lmin", NULL, OFFSET(mb_lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"mb_lmax", NULL, OFFSET(mb_lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
+{"me_penalty_compensation", NULL, OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
 {NULL},
 };
 
+#undef A
+#undef V
+
 static AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options };
 
 void avcodec_get_context_defaults(AVCodecContext *s){