changeset 7088:9a0017ee11aa

support for the new ratecontrol code
author michael
date Sun, 25 Aug 2002 21:43:22 +0000
parents cf14ac26980d
children b7a1223fcef1
files DOCS/tech/libavc-options.txt libmpcodecs/ve_lavc.c
diffstat 2 files changed, 211 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/tech/libavc-options.txt	Sun Aug 25 15:37:37 2002 +0000
+++ b/DOCS/tech/libavc-options.txt	Sun Aug 25 21:43:22 2002 +0000
@@ -12,8 +12,8 @@
            weird things: msmpeg4, h263 will be very low quality
                          ratecontrol will be confused -> lower quality
                          some decoders will not be able to decode it
-	2 is recommended for normal mpeg4/mpeg1video encoding
-	3 is recommended for h263(p)/msmpeg4 (default)
+	2 is recommended for normal mpeg4/mpeg1video encoding (default)
+	3 is recommended for h263(p)/msmpeg4
 	   the reason for 3 instead of 2 is that 2 could lead to overflows
            (this will be fixed for h263(p) by changing the quanizer per MB in	    
            the future, but msmpeg4 doesnt support that so it cant be fixed for
@@ -26,7 +26,7 @@
 	see vqmin
 
 vqmax 1-31 (maximum quantizer) for pass1/2
-	15 default
+	31 default
 	10-31 should be a sane range
 
 vqdiff  1-31 (maximum quantizer difference between I or P frames) for pass1/2
@@ -34,6 +34,7 @@
 
 vmax_b_frames 0-4 (maximum number of B frames between non B frames)
 	0 no b frames (default)
+	0-2 is a sane range for mpeg4
 
 vme 0-5 (motion estimation)
 	0 none  (not recommanded, very lq)
@@ -60,6 +61,7 @@
 	0 no keyframes 
 	>300 is not recommended as the quality might be bad (depends upon
         decoder, encoder and luck)
+        for strict mpeg1/2/4 compliance this would have to be <=132
 
 vb_strategy 0-1 for pass 2
 	0 allways use the max number of B frames (default)
@@ -81,28 +83,89 @@
 	1000-100000 is a sane range
 	8000 is default
 
-vb_qfactor (1.0-31.0) for pass1/2
-        (B-Frame quantizer = IP-Frame quantizer * vb_qfactor)
-	2.0 is default
+vrc_maxrate (maximum bitrate in kbit/sec) for pass1/2
+vrc_minrate (minimum bitrate in kbit/sec) for pass1/2
+vrc_buf_size (buffer size    in kbit) for pass1/2
+	this is for stuff like VCD
+	VCD:  FIXME
+	SVCD: ...
+	DVD:  ...
+	Note: vratetol should not be too large during the 2.pass or there might 
+              be problems if vrc_(min|max)rate is used
+
+vb_qfactor (-31.0-31.0) for pass1/2
+	1.25 is default
+vi_qfactor (-31.0-31.0) for pass1/2
+	0.8 is default
+vb_qoffset (-31.0-31.0) for pass1/2
+	1.25 is default
+vi_qoffset (-31.0-31.0) for pass1/2
+	0.0 is default
+        if v{b|i}_qfactor > 0  
+            I/B-Frame quantizer = P-Frame quantizer * v{b|i}_qfactor + v{b|i}_qoffset
+        else    
+            do normal ratecontrol (dont lock to next P frame quantizer) and
+            set q= -q * v{b|i}_qfactor + v{b|i}_qoffset
 	tip: to do constant quantizer encoding with different quantizers for
              I/P and B frames you can use:
              vqmin=<ip_quant>:vqmax=<ip_quant>:vb_qfactor=<b_quant/ip_quant>
 
-vqblur (0.0-1.0) quantizer blur (only for pass1)
+vqblur (0.0-1.0) quantizer blur (pass1)
 	0.0 qblur disabled
 	0.5 is the default
 	1.0 average the quantizer over all previous frames
 	larger values will average the quantizer more over time so that it will
         be changed slower
+vqblur (0.0-99.0) quantizer blur (pass2)
+	gaussian blur (gaussian blur cant be done during pass 1 as the future quantizers arent known)
+	0.5 is the default
+	larger values will average the quantizer more over time so that it will
+        be changed slower
 
-vqcomp (0.0-1.0) quantizer compression (for pass1/2)
-	0.0 constant bitrate encoding, so fast motion frames will get as many
-            bits as low motion (high motion scenes look bad)
-	0.5 (default)
-	1.0 constant quantizer encoding (low motion scenes look bad)
+vqcomp  quantizer compression (for pass1/2) 
+	depends upon vrc_eq
+
+vrc_eq	the main ratecontrol equation (for pass1/2)
+	1			constant bitrate
+	tex			constant quality
+	1+(tex/avgTex-1)*qComp	approximately the equation of the old ratecontrol code
+	tex^qComp		with qcomp 0.5 or something like that (default)
 
-vrc_strategy (0,1,2)
-	FIXME (different rate control strategies)
+        infix operators: +,-,*,/,^
+        variables:
+		tex		texture complexity
+		iTex,pTex	intra, non intra texture complexity
+		avgTex		average texture complexity
+		avgIITex	average intra texture complexity in I frames
+		avgPITex	average intra texture complexity in P frames
+		avgPPTex	average non intra texture complexity in P frames
+		avgBPTex	average non intra texture complexity in B frames
+		mv		bits used for MVs
+		fCode		maximum length of MV in log2 scale
+		iCount		number of intra MBs / number of MBs
+		var		spatial complexity
+		mcVar		temporal complexity
+		qComp		qcomp from the command line
+		isI, isP, isB	is 1 if picture type is I/P/B else 0
+		Pi,E		see ur favorite math book
+
+        functions: 
+		max(a,b),min(a,b)	maximum / minimum
+		gt(a,b)			is 1 if a>b, 0 otherwise
+		lt(a,b)			is 1 if a<b, 0 otherwise
+		eq(a,b)			is 1 if a==b,0 otherwise
+		sin,cos,tan,sinh,cosh,tanh,exp,log,abs
+
+vrc_override	user specified quality for specific parts (ending credits ...) (for pass1/2)
+	<start-frame>,<end-frame>,<quality>[/<start-frame>,<end-frame>,<quality>[/...]]
+	quality 2..31 -> quantizer
+	quality -500..0 -> quality correcture in %
+        
+vrc_init_cplx	(0-1000) initial complexity for pass1
+
+vqsquish (0 or 1) for pass1/2 how to keep the quantizer between qmin & qmax
+	0 use cliping
+	1 use a nice differentiable function (default)
 
 vlelim (-1000-1000) single coefficient elimination threshold for luminance
 	0 disabled (default)
@@ -163,7 +226,7 @@
            with the libavcodec encode.
            If you want to fix it read DOCS/tech/patches.txt and send a patch.
 	Q: What provides better error recovery while keeping the filesize low?
-           Should I increase data partitioning or the number of video packets?
+           Should I use data partitioning or increase the number of video packets?
 	A: Data partitioning is better in this case.
 
 Glossary:
@@ -171,6 +234,9 @@
 MV	Motion vector
 ME	Motion estimation
 MC	Motion compensation
+RC	Rate control
+DCT	Discrete Cosine Transform
+IDCT	Inverse Discrete Cosine Transform
 JVT	Joint Video Team Standard -- http://www.itu.int/ITU-T/news/jvtpro.html
 
 Examples:
--- a/libmpcodecs/ve_lavc.c	Sun Aug 25 15:37:37 2002 +0000
+++ b/libmpcodecs/ve_lavc.c	Sun Aug 25 21:43:22 2002 +0000
@@ -39,23 +39,29 @@
 #error your version of libavcodec is too old, get a newer one, and dont send a bugreport, THIS IS NO BUG
 #endif
 
+#if LIBAVCODEC_BUILD < 4620
+#warning your version of libavcodec is old, u might want to get a newer one
+#endif
+
 extern int avcodec_inited;
 
 /* video options */
 static char *lavc_param_vcodec = NULL;
 static int lavc_param_vbitrate = -1;
-static int lavc_param_vrate_tolerance = 1024*8;
+static int lavc_param_vrate_tolerance = 1000*8;
 static int lavc_param_vhq = 0; /* default is realtime encoding */
 static int lavc_param_v4mv = 0;
 static int lavc_param_vme = 4;
 static int lavc_param_vqscale = 0;
-static int lavc_param_vqmin = 3;
-static int lavc_param_vqmax = 15;
+static int lavc_param_vqmin = 2;
+static int lavc_param_vqmax = 31;
 static int lavc_param_vqdiff = 3;
 static float lavc_param_vqcompress = 0.5;
 static float lavc_param_vqblur = 0.5;
-static float lavc_param_vb_qfactor = 2.0;
-static float lavc_param_vb_qoffset = 0.0;
+static float lavc_param_vb_qfactor = 1.25;
+static float lavc_param_vb_qoffset = 1.25;
+static float lavc_param_vi_qfactor = 0.8;
+static float lavc_param_vi_qoffset = 0.0;
 static int lavc_param_vmax_b_frames = 0;
 static int lavc_param_keyint = -1;
 static int lavc_param_vpass = 0;
@@ -67,6 +73,16 @@
 static int lavc_param_strict= 0;
 static int lavc_param_data_partitioning= 0;
 static int lavc_param_gray=0;
+static float lavc_param_rc_qsquish=1.0;
+static float lavc_param_rc_qmod_amp=0;
+static int lavc_param_rc_qmod_freq=0;
+static char *lavc_param_rc_override_string=NULL;
+static char *lavc_param_rc_eq="tex^qComp";
+static int lavc_param_rc_buffer_size=0;
+static float lavc_param_rc_buffer_aggressivity=1.0;
+static int lavc_param_rc_max_rate=0;
+static int lavc_param_rc_min_rate=0;
+static float lavc_param_rc_initial_cplx=0;
 static int lavc_param_mpeg_quant=0;
 
 #include "cfgparser.h"
@@ -85,10 +101,12 @@
 	{"vqdiff", &lavc_param_vqdiff, CONF_TYPE_INT, CONF_RANGE, 1, 31, NULL},
 	{"vqcomp", &lavc_param_vqcompress, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 1.0, NULL},
 	{"vqblur", &lavc_param_vqblur, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 1.0, NULL},
-	{"vb_qfactor", &lavc_param_vb_qfactor, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 31.0, NULL},
+	{"vb_qfactor", &lavc_param_vb_qfactor, CONF_TYPE_FLOAT, CONF_RANGE, -31.0, 31.0, NULL},
 	{"vmax_b_frames", &lavc_param_vmax_b_frames, CONF_TYPE_INT, CONF_RANGE, 0, FF_MAX_B_FRAMES, NULL},
 	{"vpass", &lavc_param_vpass, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
+#if LIBAVCODEC_BUILD < 4620
 	{"vrc_strategy", &lavc_param_vrc_strategy, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
+#endif
 	{"vb_strategy", &lavc_param_vb_strategy, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL},
 #ifdef CODEC_FLAG_PART
 	{"vb_qoffset", &lavc_param_vb_qoffset, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 31.0, NULL},
@@ -105,6 +123,20 @@
 #if LIBAVCODEC_BUILD >= 4619
 	{"mpeg_quant", &lavc_param_mpeg_quant, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 #endif
+#if LIBAVCODEC_BUILD >= 4620
+	{"vi_qfactor", &lavc_param_vi_qfactor, CONF_TYPE_FLOAT, CONF_RANGE, -31.0, 31.0, NULL},
+	{"vi_qoffset", &lavc_param_vi_qoffset, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 31.0, NULL},
+	{"vqsquish", &lavc_param_rc_qsquish, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 99.0, NULL},
+	{"vqmod_amp", &lavc_param_rc_qmod_amp, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 99.0, NULL},
+	{"vqmod_freq", &lavc_param_rc_qmod_freq, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"vrc_eq", &lavc_param_rc_eq, CONF_TYPE_STRING, 0, 0, 0, NULL},
+	{"vrc_override", &lavc_param_rc_override_string, CONF_TYPE_STRING, 0, 0, 0, NULL},
+	{"vrc_maxrate", &lavc_param_rc_max_rate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
+	{"vrc_minrate", &lavc_param_rc_min_rate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
+	{"vrc_buf_size", &lavc_param_rc_min_rate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
+	{"vrc_buf_aggressivity", &lavc_param_rc_buffer_aggressivity, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 99.0, NULL},
+	{"vrc_init_cplx", &lavc_param_rc_initial_cplx, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 9999999.0, NULL},
+#endif
 	{NULL, NULL, 0, 0, 0, 0, NULL}
 };
 #endif
@@ -113,15 +145,19 @@
     aviwrite_stream_t* mux;
     AVCodecContext context;
     AVCodec *codec;
+    FILE *stats_file;
 };
 
+#define stats_file (vf->priv->stats_file)
 #define mux_v (vf->priv->mux)
 #define lavc_venc_context (vf->priv->context)
 
 static int config(struct vf_instance_s* vf,
         int width, int height, int d_width, int d_height,
 	unsigned int flags, unsigned int outfmt){
-
+    int size, i;
+    void *p;
+        
     mux_v->bih->biWidth=width;
     mux_v->bih->biHeight=height;
     mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8);
@@ -160,6 +196,44 @@
     if(lavc_param_packet_size )lavc_venc_context.rtp_mode=1;
     lavc_venc_context.strict_std_compliance= lavc_param_strict;
 #endif
+#if LIBAVCODEC_BUILD >= 4620
+    lavc_venc_context.i_quant_factor= lavc_param_vi_qfactor;
+    lavc_venc_context.i_quant_offset= lavc_param_vi_qoffset;
+    lavc_venc_context.rc_qsquish= lavc_param_rc_qsquish;
+    lavc_venc_context.rc_qmod_amp= lavc_param_rc_qmod_amp;
+    lavc_venc_context.rc_qmod_freq= lavc_param_rc_qmod_freq;
+    lavc_venc_context.rc_eq= lavc_param_rc_eq;
+    lavc_venc_context.rc_max_rate= lavc_param_rc_max_rate*1000;
+    lavc_venc_context.rc_min_rate= lavc_param_rc_min_rate*1000;
+    lavc_venc_context.rc_buffer_size= lavc_param_rc_buffer_size*1000;
+    lavc_venc_context.rc_buffer_aggressivity= lavc_param_rc_buffer_aggressivity;
+    lavc_venc_context.rc_initial_cplx= lavc_param_rc_initial_cplx;
+    p= lavc_param_rc_override_string;
+    for(i=0; p; i++){
+        int start, end, q;
+        int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
+        if(e!=3){
+	    mp_msg(MSGT_MENCODER,MSGL_ERR,"error parsing vrc_q\n");
+            return 0;
+        }
+        lavc_venc_context.rc_override= 
+            realloc(lavc_venc_context.rc_override, sizeof(RcOverride)*(i+1));
+        lavc_venc_context.rc_override[i].start_frame= start;
+        lavc_venc_context.rc_override[i].end_frame  = end;
+        if(q>0){
+            lavc_venc_context.rc_override[i].qscale= q;
+            lavc_venc_context.rc_override[i].quality_factor= 1.0;
+        }
+        else{
+            lavc_venc_context.rc_override[i].qscale= 0;
+            lavc_venc_context.rc_override[i].quality_factor= -q/100.0;
+        }
+        p= strchr(p, '/');
+        if(p) p++;
+    }
+    lavc_venc_context.rc_override_count=i;
+#endif
+
 #if LIBAVCODEC_BUILD >= 4619
     lavc_venc_context.mpeg_quant=lavc_param_mpeg_quant;
 #endif
@@ -199,8 +273,34 @@
 #else
     switch(lavc_param_vpass?lavc_param_vpass:pass){
 #endif
-    case 1: lavc_venc_context.flags|= CODEC_FLAG_PASS1; break;
-    case 2: lavc_venc_context.flags|= CODEC_FLAG_PASS2; break;
+    case 1: 
+	lavc_venc_context.flags|= CODEC_FLAG_PASS1; 
+	stats_file= fopen(passtmpfile, "w");
+	if(stats_file==NULL){
+	    mp_msg(MSGT_MENCODER,MSGL_ERR,"2pass failed: filename=%s\n", passtmpfile);
+            return 0;
+	}
+	break;
+    case 2:
+	lavc_venc_context.flags|= CODEC_FLAG_PASS2; 
+	stats_file= fopen(passtmpfile, "r");
+	if(stats_file==NULL){
+	    mp_msg(MSGT_MENCODER,MSGL_ERR,"2pass failed: filename=%s\n", passtmpfile);
+            return 0;
+	}
+	fseek(stats_file, 0, SEEK_END);
+	size= ftell(stats_file);
+	fseek(stats_file, 0, SEEK_SET);
+	
+	lavc_venc_context.stats_in= malloc(size + 1);
+	lavc_venc_context.stats_in[size]=0;
+
+	if(fread(lavc_venc_context.stats_in, size, 1, stats_file)<1){
+	    mp_msg(MSGT_MENCODER,MSGL_ERR,"2pass failed: reading from filename=%s\n", passtmpfile);
+            return 0;
+	}
+        
+	break;
     }
 
 #ifdef ME_ZERO
@@ -249,7 +349,13 @@
 	mp_msg(MSGT_MENCODER,MSGL_ERR,"avcodec init failed (ctx->codec->encode == NULL)!\n");
 	return 0;
     }
-
+    
+#if LIBAVCODEC_BUILD >= 4620
+    /* free second pass buffer, its not needed anymore */
+    if(lavc_venc_context.stats_in) free(lavc_venc_context.stats_in);
+    lavc_venc_context.stats_in= NULL;
+#endif
+    
     return 1;
 }
 
@@ -306,10 +412,24 @@
     }
 
     mencoder_write_chunk(mux_v,out_size,lavc_venc_context.key_frame?0x10:0);
+    
+#if LIBAVCODEC_BUILD >= 4620
+    /* store stats if there are any */
+    if(lavc_venc_context.stats_out && stats_file) 
+        fprintf(stats_file, "%s", lavc_venc_context.stats_out);
+#endif
 }
 
 static void uninit(struct vf_instance_s* vf){
     avcodec_close(&lavc_venc_context);
+
+    if(stats_file) fclose(stats_file);
+
+#if LIBAVCODEC_BUILD >= 4620
+    /* free rc_override */
+    if(lavc_venc_context.rc_override) free(lavc_venc_context.rc_override);
+    lavc_venc_context.rc_override= NULL;
+#endif
 }
 
 //===========================================================================//