summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authormichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-08-25 21:43:22 +0000
committermichael <michael@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-08-25 21:43:22 +0000
commita2eebbfa2da50dc3ef62335a785351c6222628e4 (patch)
treeb3121aebb1335e3f93bd94a17cb2ff36eb8c8d7a /libmpcodecs
parente52cb91a669b1a8371017a0563526943d4ec05e4 (diff)
downloadmpv-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')
-rw-r--r--libmpcodecs/ve_lavc.c140
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
}
//===========================================================================//