00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <math.h>
00021 #include "ogg/ogg.h"
00022 #include "vorbis/codec.h"
00023 #include "codec_internal.h"
00024 #include "os.h"
00025 #include "misc.h"
00026 #include "bitrate.h"
00027
00028
00029 void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
00030 codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00031 bitrate_manager_info *bi=&ci->bi;
00032
00033 memset(bm,0,sizeof(*bm));
00034
00035 if(bi && (bi->reservoir_bits>0)){
00036 long ratesamples=vi->rate;
00037 int halfsamples=ci->blocksizes[0]>>1;
00038
00039 bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
00040 bm->managed=1;
00041
00042 bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
00043 bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
00044 bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
00045
00046 bm->avgfloat=PACKETBLOBS/2;
00047
00048
00049
00050 {
00051 long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
00052 bm->minmax_reservoir=desired_fill;
00053 bm->avg_reservoir=desired_fill;
00054 }
00055
00056 }
00057 }
00058
00059 void vorbis_bitrate_clear(bitrate_manager_state *bm){
00060 memset(bm,0,sizeof(*bm));
00061 return;
00062 }
00063
00064 int vorbis_bitrate_managed(vorbis_block *vb){
00065 vorbis_dsp_state *vd=vb->vd;
00066 private_state *b=(private_state*)vd->backend_state;
00067 bitrate_manager_state *bm=&b->bms;
00068
00069 if(bm && bm->managed)return(1);
00070 return(0);
00071 }
00072
00073
00074 int vorbis_bitrate_addblock(vorbis_block *vb){
00075 vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
00076 vorbis_dsp_state *vd=vb->vd;
00077 private_state *b=(private_state*)vd->backend_state;
00078 bitrate_manager_state *bm=&b->bms;
00079 vorbis_info *vi=vd->vi;
00080 codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00081 bitrate_manager_info *bi=&ci->bi;
00082
00083 int choice=rint(bm->avgfloat);
00084 long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00085 long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
00086 long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
00087 int samples=ci->blocksizes[vb->W]>>1;
00088 long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
00089 if(!bm->managed){
00090
00091
00092
00093 if(bm->vb)return(-1);
00094
00095 bm->vb=vb;
00096 return(0);
00097 }
00098
00099 bm->vb=vb;
00100
00101
00102 if(bm->avg_bitsper>0){
00103 double slew=0.;
00104 long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
00105 double slewlimit= 15./bi->slew_damp;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
00119 while(choice>0 && this_bits>avg_target_bits &&
00120 bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
00121 choice--;
00122 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00123 }
00124 }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
00125 while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
00126 bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
00127 choice++;
00128 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00129 }
00130 }
00131
00132 slew=rint(choice-bm->avgfloat)/samples*vi->rate;
00133 if(slew<-slewlimit)slew=-slewlimit;
00134 if(slew>slewlimit)slew=slewlimit;
00135 choice=rint(bm->avgfloat+= slew/vi->rate*samples);
00136 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00137 }
00138
00139
00140
00141
00142 if(bm->min_bitsper>0){
00143
00144 if(this_bits<min_target_bits){
00145 while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
00146 choice++;
00147 if(choice>=PACKETBLOBS)break;
00148 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00149 }
00150 }
00151 }
00152
00153
00154 if(bm->max_bitsper>0){
00155
00156 if(this_bits>max_target_bits){
00157 while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
00158 choice--;
00159 if(choice<0)break;
00160 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00161 }
00162 }
00163 }
00164
00165
00166
00167
00168 if(choice<0){
00169
00170
00171 long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
00172 bm->choice=choice=0;
00173
00174 if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
00175
00176 oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
00177 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00178 }
00179 }else{
00180 long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
00181 if(choice>=PACKETBLOBS)
00182 choice=PACKETBLOBS-1;
00183
00184 bm->choice=choice;
00185
00186
00187 minsize-=oggpack_bytes(vbi->packetblob[choice]);
00188 while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
00189 this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
00190
00191 }
00192
00193
00194
00195 if(bm->min_bitsper>0 || bm->max_bitsper>0){
00196
00197 if(max_target_bits>0 && this_bits>max_target_bits){
00198 bm->minmax_reservoir+=(this_bits-max_target_bits);
00199 }else if(min_target_bits>0 && this_bits<min_target_bits){
00200 bm->minmax_reservoir+=(this_bits-min_target_bits);
00201 }else{
00202
00203 if(bm->minmax_reservoir>desired_fill){
00204 if(max_target_bits>0){
00205 bm->minmax_reservoir+=(this_bits-max_target_bits);
00206 if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
00207 }else{
00208 bm->minmax_reservoir=desired_fill;
00209 }
00210 }else{
00211 if(min_target_bits>0){
00212 bm->minmax_reservoir+=(this_bits-min_target_bits);
00213 if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
00214 }else{
00215 bm->minmax_reservoir=desired_fill;
00216 }
00217 }
00218 }
00219 }
00220
00221
00222 if(bm->avg_bitsper>0){
00223 long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
00224 bm->avg_reservoir+=this_bits-avg_target_bits;
00225 }
00226
00227 return(0);
00228 }
00229
00230 int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
00231 private_state *b=(private_state*)vd->backend_state;
00232 bitrate_manager_state *bm=&b->bms;
00233 vorbis_block *vb=bm->vb;
00234 int choice=PACKETBLOBS/2;
00235 if(!vb)return 0;
00236
00237 if(op){
00238 vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
00239
00240 if(vorbis_bitrate_managed(vb))
00241 choice=bm->choice;
00242
00243 op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
00244 op->bytes=oggpack_bytes(vbi->packetblob[choice]);
00245 op->b_o_s=0;
00246 op->e_o_s=vb->eofflag;
00247 op->granulepos=vb->granulepos;
00248 op->packetno=vb->sequence;
00249 }
00250
00251 bm->vb=0;
00252 return(1);
00253 }