diff options
author | michael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-08-25 21:43:22 +0000 |
---|---|---|
committer | michael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-08-25 21:43:22 +0000 |
commit | a2eebbfa2da50dc3ef62335a785351c6222628e4 (patch) | |
tree | b3121aebb1335e3f93bd94a17cb2ff36eb8c8d7a /libmpcodecs/ve_lavc.c | |
parent | e52cb91a669b1a8371017a0563526943d4ec05e4 (diff) | |
download | mpv-a2eebbfa2da50dc3ef62335a785351c6222628e4.tar.bz2 mpv-a2eebbfa2da50dc3ef62335a785351c6222628e4.tar.xz |
support for the new ratecontrol code
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7089 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs/ve_lavc.c')
-rw-r--r-- | libmpcodecs/ve_lavc.c | 140 |
1 files changed, 130 insertions, 10 deletions
diff --git a/libmpcodecs/ve_lavc.c b/libmpcodecs/ve_lavc.c index d3ee8b9e9b..e1bfb3ef6c 100644 --- a/libmpcodecs/ve_lavc.c +++ b/libmpcodecs/ve_lavc.c @@ -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}, @@ -105,6 +123,20 @@ struct config lavcopts_conf[]={ #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 @@ 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 } //===========================================================================// |