From a06da3587f26a6c068ed87a0d63d59d839399858 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 19 Dec 2001 07:33:52 +0000 Subject: [PATCH] bitrate management is active svn path=/trunk/vorbis/; revision=2856 --- lib/bitrate.c | 23 ++++-- lib/bitrate.h | 4 +- lib/modes/residue_44.h | 6 +- lib/vorbisenc.c | 197 ++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 183 insertions(+), 47 deletions(-) diff --git a/lib/bitrate.c b/lib/bitrate.c index 6f19bf0..0bfc1e4 100644 --- a/lib/bitrate.c +++ b/lib/bitrate.c @@ -11,7 +11,7 @@ ******************************************************************** function: bitrate tracking and management - last mod: $Id: bitrate.c,v 1.4 2001/12/19 01:08:13 xiphmont Exp $ + last mod: $Id: bitrate.c,v 1.5 2001/12/19 07:33:51 xiphmont Exp $ ********************************************************************/ @@ -283,7 +283,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ bm->avg_tail++; if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0; } - + /* update the avg center */ if(bm->avg_centeracc>desired_center){ /* choose the new average floater */ @@ -310,7 +310,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ /* apply the average floater to new blocks */ bin=bm->avgfloat*BITTRACK_DIVISOR; /* truncate on purpose */ - fprintf(stderr,"float:%d ",bin); + fprintf(stderr,"u:%f l:%f float:%d ",upper,lower,bin); while(bm->avg_centeracc>desired_center){ int samples= samples=ci->blocksizes[bm->queue_actual[bm->avg_center]& @@ -328,14 +328,20 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ /* track noise bias triggers and noise bias */ if(bm->avgfloatavgfloat_noise_lowtrigger) bm->noisetrigger_request+=1.f; - + else + if(bm->noisetrigger_request>0. && bm->avgnoise>0.) + bm->noisetrigger_request-=.2f; + if(bm->avgfloat>bi->avgfloat_noise_hightrigger) bm->noisetrigger_request-=1.f; - + else + if(bm->noisetrigger_request<0 && bm->avgnoise<0.) + bm->noisetrigger_request+=.2f; + if(bm->noisetrigger_postpone<=0){ if(bm->noisetrigger_request<0.){ bm->avgnoise-=1.f; - if(bm->noisetrigger_request<(signed long)(bm->avg_sampleacc)/2) + if(-bm->noisetrigger_request>(signed long)(bm->avg_sampleacc)/2) bm->avgnoise-=1.f; bm->noisetrigger_postpone=bm->avg_sampleacc/2; } @@ -358,7 +364,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ if(bm->avgnoise>bi->avgfloat_noise_maxval) bm->avgnoise=bi->avgfloat_noise_maxval; } - fprintf(stderr,"noise:%f req:%ld trigger:%ld\n",bm->avgnoise, + fprintf(stderr,"noise:%f req:%f trigger:%ld\n",bm->avgnoise, bm->noisetrigger_request,bm->noisetrigger_postpone); } @@ -435,7 +441,8 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ int limit=0; fprintf(stderr,"prelimit:%dkbps ",(int)bitrate/1000); - if(bitrate>bi->queue_hardmax || bitratequeue_hardmin){ + if((bi->queue_hardmax>0 && bitrate>bi->queue_hardmax) || + (bi->queue_hardmin>0 && bitratequeue_hardmin)){ int newstack; int stackctr; long bitsum=limit_sum(bm,0); diff --git a/lib/bitrate.h b/lib/bitrate.h index 96675f0..87ef704 100644 --- a/lib/bitrate.h +++ b/lib/bitrate.h @@ -11,7 +11,7 @@ ******************************************************************** function: bitrate tracking and management - last mod: $Id: bitrate.h,v 1.2 2001/12/12 09:45:24 xiphmont Exp $ + last mod: $Id: bitrate.h,v 1.3 2001/12/19 07:33:51 xiphmont Exp $ ********************************************************************/ @@ -56,7 +56,7 @@ typedef struct bitrate_manager_state { double avgfloat; double avgnoise; long noisetrigger_postpone; - long noisetrigger_request; + double noisetrigger_request; /* unfortunately, we need to hold queued packet data somewhere */ oggpack_buffer *queue_packet_buffers; diff --git a/lib/modes/residue_44.h b/lib/modes/residue_44.h index 7d91d1b..2babf67 100644 --- a/lib/modes/residue_44.h +++ b/lib/modes/residue_44.h @@ -11,7 +11,7 @@ v ******************************************************************** function: toplevel residue templates for 32/44.1/48kHz - last mod: $Id: residue_44.h,v 1.5 2001/12/19 01:10:27 xiphmont Exp $ + last mod: $Id: residue_44.h,v 1.6 2001/12/19 07:33:52 xiphmont Exp $ ********************************************************************/ @@ -26,8 +26,8 @@ static bitrate_manager_info _bm_44_default={ 4.0, 0., -1., .05, -.05, .05, - 3.5,5.0, - -10.f,+2.f + 3.2,5.0, + -6.f,+2.f }; /***** residue backends *********************************************/ diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c index 260433e..39ebcf0 100644 --- a/lib/vorbisenc.c +++ b/lib/vorbisenc.c @@ -11,7 +11,7 @@ ******************************************************************** function: simple programmatic interface for encoder mode setup - last mod: $Id: vorbisenc.c,v 1.25 2001/12/19 01:18:40 xiphmont Exp $ + last mod: $Id: vorbisenc.c,v 1.26 2001/12/19 07:33:51 xiphmont Exp $ ********************************************************************/ @@ -609,7 +609,7 @@ static int vorbis_encode_lowpass_setup(vorbis_info *vi,double q,int block){ /* the final setup call */ int vorbis_encode_setup_init(vorbis_info *vi){ int ret=0; - long rate=vi->rate; + /*long rate=vi->rate;*/ long channels=vi->channels; codec_setup_info *ci=vi->codec_setup; highlevel_encode_setup *hi=&ci->hi; @@ -667,9 +667,16 @@ int vorbis_encode_setup_init(vorbis_info *vi){ 3,_psy_tone_masterguard,_psy_tone_suppress, _vp_peakguard); - ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[0].noise_bias_quality, - 0,_psy_noise_suppress,_psy_noisebias_impulse, - _psy_noiseguards_short); + if(hi->impulse_block_p){ + ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[0].noise_bias_quality, + 0,_psy_noise_suppress,_psy_noisebias_impulse, + _psy_noiseguards_short); + }else{ + ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[0].noise_bias_quality, + 0,_psy_noise_suppress,_psy_noisebias_other, + _psy_noiseguards_short); + } + ret|=vorbis_encode_noisebias_setup(vi,hi->blocktype[1].noise_bias_quality, 1,_psy_noise_suppress,_psy_noisebias_other, _psy_noiseguards_short); @@ -745,6 +752,68 @@ int vorbis_encode_setup_init(vorbis_info *vi){ } +/* this is only tuned for 44.1kHz right now. S'ok, for other rates it + just doesn't guess */ +static double ratepch_un44[11]= + {40000.,50000.,60000.,70000.,75000.,85000.,105000., + 115000.,135000.,160000.,250000.}; +static double ratepch_st44[11]= + {32000.,40000.,48000.,56000.,64000., + 80000.,96000.,112000.,128000.,160000.,250000.}; + +static double vbr_to_approx_bitrate(int ch,int coupled, + double q,long srate){ + int iq=q*10.; + double dq; + double *r=NULL; + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + if(srate>42000 && srate<46000){ + if(coupled) + r=ratepch_st44; + else + r=ratepch_un44; + } + + if(r==NULL) + return(-1); + + return((r[iq]*(1.-dq)+r[iq+1]*dq)*ch); +} + +static double approx_bitrate_to_vbr(int ch,int coupled, + double bitrate,long srate){ + double *r=NULL,del; + int i; + + if(srate>42000 && srate<46000){ + if(coupled) + r=ratepch_st44; + else + r=ratepch_un44; + } + + if(r==NULL) + return(-1.); + + bitrate/=ch; + + if(bitrate=bitrate)break; + if(i==10)return(10.); + + del=(bitrate-r[i])/(r[i+1]-r[i]); + + return((i+del)*.1); +} + /* only populates the high-level settings so that we can tweak with ctl before final setup */ int vorbis_encode_setup_vbr(vorbis_info *vi, long channels, @@ -808,7 +877,11 @@ int vorbis_encode_setup_vbr(vorbis_info *vi, _psy_lowpass_44[iq]*(1.-dq)+_psy_lowpass_44[iq+1]*dq; /* set bitrate approximation */ - + vi->bitrate_nominal=vbr_to_approx_bitrate(vi->channels,hi->stereo_couple_p, + base_quality,vi->rate); + vi->bitrate_lower=-1; + vi->bitrate_upper=-1; + vi->bitrate_window=-1; return(ret); } @@ -833,6 +906,81 @@ int vorbis_encode_init_vbr(vorbis_info *vi, return(ret); } +int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate){ + + double approx_vbr=approx_bitrate_to_vbr(channels,(channels==2), + nominal_bitrate,rate); + int ret=0; + if(approx_vbr<0)return(OV_EIMPL); + + if(nominal_bitrate<=0.){ + if(max_bitrate>0.){ + nominal_bitrate=max_bitrate*.875; + }else{ + if(min_bitrate>0.){ + nominal_bitrate=min_bitrate; + }else{ + return(OV_EINVAL); + } + } + } + + ret=vorbis_encode_setup_vbr(vi,channels,rate,approx_vbr); + if(ret){ + vorbis_info_clear(vi); + return ret; + } + + /* adjust to make management's life easier. Use the ctl() interface + once it's implemented */ + { + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + + /* backfills */ + hi->stereo_backfill_p=1; + hi->residue_backfill_p=1; + + /* no impulse blocks */ + hi->impulse_block_p=0; + /* de-rate stereo */ + if(hi->stereo_point_dB && hi->stereo_couple_p && channels==2){ + hi->stereo_point_dB++; + if(hi->stereo_point_dB>3)hi->stereo_point_dB=3; + }else{ + /* else, slug the vbr noise setting */ + int i; + for(i=0;i<4;i++){ + hi->blocktype[i].noise_bias_quality-=.1; + if(hi->blocktype[i].noise_bias_quality<0.) + hi->blocktype[i].noise_bias_quality=0.; + } + } + + /* initialize management. Currently hardcoded for 44, but so is above. */ + memcpy(&ci->bi,&_bm_44_default,sizeof(ci->bi)); + ci->bi.queue_hardmin=min_bitrate; + ci->bi.queue_hardmax=max_bitrate; + + ci->bi.queue_avgmin=nominal_bitrate; + ci->bi.queue_avgmax=nominal_bitrate; + + /* adjust management */ + if(max_bitrate<=0. && min_bitrate<=0.){ + /* just an average tracker; no reason for the window to be as small as 2s. */ + ci->bi.queue_avg_time=4.; + } + + } + return(ret); +} + int vorbis_encode_init(vorbis_info *vi, long channels, long rate, @@ -841,34 +989,15 @@ int vorbis_encode_init(vorbis_info *vi, long nominal_bitrate, long min_bitrate){ - /* it's temporary while I do the merge; relax */ - if(rate>40000){ - if(nominal_bitrate>360000){ - return(vorbis_encode_init_vbr(vi,channels,rate, 1.)); - }else if(nominal_bitrate>270000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .9)); - }else if(nominal_bitrate>230000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .8)); - }else if(nominal_bitrate>200000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .7)); - }else if(nominal_bitrate>180000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .6)); - }else if(nominal_bitrate>140000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .5)); - }else if(nominal_bitrate>120000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .4)); - }else if(nominal_bitrate>100000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .3)); - }else if(nominal_bitrate>90000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .2)); - }else if(nominal_bitrate>75000){ - return(vorbis_encode_init_vbr(vi,channels,rate, .1)); - }else{ - return(vorbis_encode_init_vbr(vi,channels,rate, .0)); - } - } - - return(OV_EIMPL); + int ret=vorbis_encode_setup_managed(vi,channels,rate, + max_bitrate, + nominal_bitrate, + min_bitrate); + + ret=vorbis_encode_setup_init(vi); + if(ret) + vorbis_info_clear(vi); + return(ret); } int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ -- 2.7.4