18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/********************************************************************
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: bitrate tracking and management
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: bitrate.c 16227 2009-07-08 06:58:46Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h"
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "bitrate.h"
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* compute bitrate tracking setup  */
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bitrate_manager_info *bi=&ci->bi;
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(bm,0,sizeof(*bm));
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bi && (bi->reservoir_bits>0)){
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long ratesamples=vi->rate;
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int  halfsamples=ci->blocksizes[0]>>1;
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->managed=1;
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->avgfloat=PACKETBLOBS/2;
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* not a necessary fix, but one that leads to a more balanced
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       typical initialization */
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    {
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      bm->minmax_reservoir=desired_fill;
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      bm->avg_reservoir=desired_fill;
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid vorbis_bitrate_clear(bitrate_manager_state *bm){
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(bm,0,sizeof(*bm));
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_bitrate_managed(vorbis_block *vb){
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_dsp_state      *vd=vb->vd;
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state         *b=vd->backend_state;
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bitrate_manager_state *bm=&b->bms;
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm && bm->managed)return(1);
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* finish taking in the block we just processed */
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_bitrate_addblock(vorbis_block *vb){
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_block_internal *vbi=vb->internal;
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_dsp_state      *vd=vb->vd;
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state         *b=vd->backend_state;
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bitrate_manager_state *bm=&b->bms;
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info           *vi=vd->vi;
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info      *ci=vi->codec_setup;
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bitrate_manager_info  *bi=&ci->bi;
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int  choice=rint(bm->avgfloat);
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int  samples=ci->blocksizes[vb->W]>>1;
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!bm->managed){
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* not a bitrate managed stream, but for API simplicity, we'll
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       buffer the packet to keep the code path clean */
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(bm->vb)return(-1); /* one has been submitted without
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             being claimed */
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->vb=vb;
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bm->vb=vb;
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* look ahead for avg floater */
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm->avg_bitsper>0){
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double slew=0.;
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double slewlimit= 15./bi->slew_damp;
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* choosing a new floater:
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       if we're over target, we slew down
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       if we're under target, we slew up
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       choose slew as follows: look through packetblobs of this frame
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       and set slew as the first in the appropriate direction that
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       gives us the slew we want.  This may mean no slew if delta is
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       already favorable.
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       Then limit slew to slew max */
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      while(choice>0 && this_bits>avg_target_bits &&
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        choice--;
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        choice++;
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    slew=rint(choice-bm->avgfloat)/samples*vi->rate;
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(slew<-slewlimit)slew=-slewlimit;
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(slew>slewlimit)slew=slewlimit;
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    choice=rint(bm->avgfloat+= slew/vi->rate*samples);
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* enforce min(if used) on the current floater (if used) */
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm->min_bitsper>0){
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* do we need to force the bitrate up? */
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(this_bits<min_target_bits){
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        choice++;
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(choice>=PACKETBLOBS)break;
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* enforce max (if used) on the current floater (if used) */
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm->max_bitsper>0){
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* do we need to force the bitrate down? */
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(this_bits>max_target_bits){
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        choice--;
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(choice<0)break;
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Choice of packetblobs now made based on floater, and min/max
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     requirements. Now boundary check extreme choices */
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(choice<0){
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* choosing a smaller packetblob is insufficient to trim bitrate.
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       frame will need to be truncated */
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->choice=choice=0;
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(choice>=PACKETBLOBS)
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      choice=PACKETBLOBS-1;
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->choice=choice;
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* prop up bitrate according to demand. pad this frame out with zeroes */
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    minsize-=oggpack_bytes(vbi->packetblob[choice]);
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* now we have the final packet and the final packet size.  Update statistics */
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* min and max reservoir */
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm->min_bitsper>0 || bm->max_bitsper>0){
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(max_target_bits>0 && this_bits>max_target_bits){
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      bm->minmax_reservoir+=(this_bits-max_target_bits);
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else if(min_target_bits>0 && this_bits<min_target_bits){
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      bm->minmax_reservoir+=(this_bits-min_target_bits);
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* inbetween; we want to take reservoir toward but not past desired_fill */
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(bm->minmax_reservoir>desired_fill){
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(max_target_bits>0){ /* logical bulletproofing against initialization state */
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          bm->minmax_reservoir+=(this_bits-max_target_bits);
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          bm->minmax_reservoir=desired_fill;
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(min_target_bits>0){ /* logical bulletproofing against initialization state */
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          bm->minmax_reservoir+=(this_bits-min_target_bits);
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          bm->minmax_reservoir=desired_fill;
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* avg reservoir */
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bm->avg_bitsper>0){
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bm->avg_reservoir+=this_bits-avg_target_bits;
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state         *b=vd->backend_state;
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bitrate_manager_state *bm=&b->bms;
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_block          *vb=bm->vb;
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int                    choice=PACKETBLOBS/2;
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!vb)return 0;
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(op){
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_block_internal *vbi=vb->internal;
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vorbis_bitrate_managed(vb))
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      choice=bm->choice;
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->bytes=oggpack_bytes(vbi->packetblob[choice]);
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->b_o_s=0;
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->e_o_s=vb->eofflag;
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->granulepos=vb->granulepos;
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    op->packetno=vb->sequence; /* for sake of completeness */
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bm->vb=0;
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(1);
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
254