www.pudn.com > bladeenc-0.90.0-src.zip > reservoir.c


/* 
			(c) Copyright 1998, 1999 - Tord Jansson 
			======================================= 
 
		This file is part of the BladeEnc MP3 Encoder, based on 
		ISO's reference code for MPEG Layer 3 compression, and might 
		contain smaller or larger sections that are directly taken 
		from ISO's reference code. 
 
		All changes to the ISO reference code herein are either 
		copyrighted by Tord Jansson (tord.jansson@swipnet.se) 
		or sublicensed to Tord Jansson by a third party. 
 
	BladeEnc is free software; you can redistribute this file 
	and/or modify it under the terms of the GNU Lesser General Public 
	License as published by the Free Software Foundation; either 
	version 2.1 of the License, or (at your option) any later version. 
 
*/ 
 
#include  
#include  
#include  
#include  
#include "l3side.h" 
#include "loop.h" 
#include "huffman.h" 
#include "l3bitstream.h" 
#include "reservoir.h" 
 
/* 
  Layer3 bit reservoir: 
  Described in C.1.5.4.2.2 of the IS 
*/ 
 
static int ResvSize = 0; /* in bits */ 
static int ResvMax  = 0; /* in bits */ 
 
void fixStatic_reservoir( void ) 
{ 
	ResvSize = 0; 
	ResvMax = 0; 
} 
 
 
/* 
  ResvFrameBegin: 
  Called at the beginning of a frame. Updates the maximum 
  size of the reservoir, and checks to make sure main_data_begin 
  was set properly by the formatter 
*/ 
void 
ResvFrameBegin( frame_params *fr_ps, III_side_info_t *l3_side, int mean_bits, int frameLength ) 
{ 
  layer *info; 
  int fullFrameBits, mode_gr; 
  int expectedResvSize, resvLimit; 
 
  info = fr_ps->header; 
	mode_gr = 2; 
	resvLimit = 4088; /* main_data_begin has 9 bits in MPEG 1 */ 
 
  /* 
    main_data_begin was set by the formatter to the 
    expected value for the next call -- this should 
    agree with our reservoir size 
  */ 
  expectedResvSize = l3_side->main_data_begin * 8; 
/*  assert( expectedResvSize == ResvSize ); */ 
 
  fullFrameBits = mean_bits * mode_gr; 
 
  /* 
    determine maximum size of reservoir: 
    ResvMax + frameLength <= 7680; 
  */ 
  if ( frameLength > 7680 ) 
		ResvMax = 0; 
  else 
		ResvMax = 7680 - frameLength; 
 
    /* 
      limit max size to resvLimit bits because 
      main_data_begin cannot indicate a 
      larger value 
      */ 
  if ( ResvMax > resvLimit ) 
		ResvMax = resvLimit; 
} 
 
/* 
  ResvMaxBits: 
  Called at the beginning of each granule to get the max bit 
  allowance for the current granule based on reservoir size 
  and perceptual entropy. 
*/ 
int 
ResvMaxBits( frame_params *fr_ps, III_side_info_t *l3_side, double *pe, int mean_bits ) 
{ 
    int more_bits, max_bits, add_bits, over_bits; 
 
    mean_bits /= fr_ps->stereo; 
    max_bits = mean_bits; 
 
    if ( max_bits > 4095 ) 
	max_bits = 4095; 
 
    if ( ResvMax == 0 ) 
	return max_bits; 
 
    more_bits = (int) (*pe * 3.1 - mean_bits); 
    add_bits = 0; 
    if ( more_bits > 100 ) 
    { 
	int frac = (ResvSize * 6) / 10; 
 
	if ( frac < more_bits ) 
	    add_bits = frac; 
	else 
	    add_bits = more_bits; 
    } 
    over_bits = ResvSize - ((ResvMax * 8) / 10) - add_bits; 
    if ( over_bits > 0 ) 
	add_bits += over_bits; 
 
    max_bits += add_bits; 
    if ( max_bits > 4095 ) 
	max_bits = 4095; 
    return max_bits; 
} 
 
/* 
  ResvAdjust: 
  Called after a granule's bit allocation. Readjusts the size of 
  the reservoir to reflect the granule's usage. 
*/ 
void 
ResvAdjust( frame_params *fr_ps, gr_info *gi, III_side_info_t *l3_side, int mean_bits ) 
{ 
    ResvSize += (mean_bits / fr_ps->stereo) - gi->part2_3_length; 
} 
 
/* 
  ResvFrameEnd: 
  Called after all granules in a frame have been allocated. Makes sure 
  that the reservoir size is within limits, possibly by adding stuffing 
  bits. Note that stuffing bits are added by increasing a granule's 
  part2_3_length. The bitstream formatter will detect this and write the 
  appropriate stuffing bits to the bitstream. 
*/ 
void 
ResvFrameEnd( frame_params *fr_ps, III_side_info_t *l3_side, int mean_bits ) 
{ 
    layer *info; 
    gr_info *gi; 
    int mode_gr, gr, ch, stereo, ancillary_pad, stuffingBits; 
    int over_bits; 
 
    info   = fr_ps->header; 
    stereo = fr_ps->stereo; 
    mode_gr = 2; 
    ancillary_pad = 0; 
 
    /* just in case mean_bits is odd, this is necessary... */ 
    if ( (stereo == 2) && (mean_bits & 1) ) 
			ResvSize += 1; 
 
    over_bits = ResvSize - ResvMax; 
    if ( over_bits < 0 ) 
			over_bits = 0; 
     
    ResvSize -= over_bits; 
    stuffingBits = over_bits + ancillary_pad; 
 
    /* we must be byte aligned */ 
    if ( (over_bits = ResvSize % 8) ) 
    { 
	stuffingBits += over_bits; 
	ResvSize -= over_bits; 
    } 
 
    if ( stuffingBits ) 
    { 
	/* 
	  plan a: put all into the first granule 
	  This was preferred by someone designing a 
	  real-time decoder... 
	*/ 
	gi = (gr_info *) &(l3_side->gr[0].ch[0]);	 
	 
	if ( gi->part2_3_length + stuffingBits < 4095 ) 
	    gi->part2_3_length += stuffingBits; 
	else 
	{ 
	    /* plan b: distribute throughout the granules */ 
	    for (gr = 0; gr < mode_gr; gr++ ) 
		for (ch = 0; ch < stereo; ch++ ) 
		{ 
		    int extraBits, bitsThisGr; 
		    gr_info *gi = (gr_info *) &(l3_side->gr[gr].ch[ch]); 
		    if ( stuffingBits == 0 ) 
			break; 
		    extraBits = 4095 - gi->part2_3_length; 
		    bitsThisGr = extraBits < stuffingBits ? extraBits : stuffingBits; 
		    gi->part2_3_length += bitsThisGr; 
		    stuffingBits -= bitsThisGr; 
		} 
	    /* 
	      If any stuffing bits remain, we elect to spill them 
	      into ancillary data. The bitstream formatter will do this if 
	      l3side->resvDrain is set 
	    */ 
	    l3_side->resvDrain = stuffingBits; 
	} 
    } 
}