mirror of https://github.com/mpv-player/mpv
support for the new ratecontrol code
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7089 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
e52cb91a66
commit
a2eebbfa2d
|
@ -12,8 +12,8 @@ vqmin 2-31 (minimum quantizer) for pass1/2
|
|||
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 @@ vqscale 1-31 quantizer for constant quantizer / constant quality encoding
|
|||
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 @@ vqdiff 1-31 (maximum quantizer difference between I or P frames) for pass1/2
|
|||
|
||||
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 @@ keyint 0-300 (maximum interval between keyframes)
|
|||
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 @@ vratetol (filesize tolerance in kbit) for pass1/2
|
|||
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_strategy (0,1,2)
|
||||
FIXME (different rate control strategies)
|
||||
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)
|
||||
|
||||
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 @@ FAQ: Q: Why is the filesize much too small?
|
|||
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 @@ MB Macroblock (16x16 luminance and 8x8 chrominance samples)
|
|||
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:
|
||||
|
|
|
@ -39,23 +39,29 @@ extern int pass;
|
|||
#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_packet_size= 0;
|
|||
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 @@ struct config lavcopts_conf[]={
|
|||
{"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},
|
||||
|
@ -104,6 +122,20 @@ struct config lavcopts_conf[]={
|
|||
#endif
|
||||
#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}
|
||||
};
|
||||
|
@ -113,15 +145,19 @@ struct vf_priv_s {
|
|||
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 @@ static int config(struct vf_instance_s* vf,
|
|||
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 @@ static int config(struct vf_instance_s* vf,
|
|||
#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 @@ static int config(struct vf_instance_s* vf,
|
|||
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 @@ static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
|
|
Loading…
Reference in New Issue