📄 bitstream.c
字号:
/* Write ics information */
if (!commonWindow) {
bits += WriteICSInfo(coderInfo, bitStream, objectType, writeFlag);
}
bits += SortBookNumbers(coderInfo, bitStream, writeFlag);
bits += WriteScalefactors(coderInfo, bitStream, writeFlag);
bits += WritePulseData(coderInfo, bitStream, writeFlag);
bits += WriteTNSData(coderInfo, bitStream, writeFlag);
bits += WriteGainControlData(coderInfo, bitStream, writeFlag);
bits += WriteSpectralData(coderInfo, bitStream, writeFlag);
/* Return number of bits */
return bits;
}
static int WriteLTPPredictorData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag)
{
int i, last_band;
int bits;
LtpInfo *ltpInfo = &coderInfo->ltpInfo;
bits = 1;
if (ltpInfo->global_pred_flag)
{
if(writeFlag)
PutBit(bitStream, 1, 1); /* LTP used */
switch(coderInfo->block_type)
{
case ONLY_LONG_WINDOW:
case LONG_SHORT_WINDOW:
case SHORT_LONG_WINDOW:
bits += LEN_LTP_LAG;
bits += LEN_LTP_COEF;
if(writeFlag)
{
PutBit(bitStream, ltpInfo->delay[0], LEN_LTP_LAG);
PutBit(bitStream, ltpInfo->weight_idx, LEN_LTP_COEF);
}
last_band = (coderInfo->nr_of_sfb < MAX_LT_PRED_LONG_SFB) ?
coderInfo->nr_of_sfb : MAX_LT_PRED_LONG_SFB;
bits += last_band;
if(writeFlag)
for (i = 0; i < last_band; i++)
PutBit(bitStream, ltpInfo->sfb_prediction_used[i], LEN_LTP_LONG_USED);
break;
default:
break;
}
} else {
if(writeFlag)
PutBit(bitStream, 0, 1); /* LTP not used */
}
return (bits);
}
static int WritePredictorData(CoderInfo *coderInfo,
BitStream *bitStream,
int writeFlag)
{
int bits = 0;
/* Write global predictor data present */
short predictorDataPresent = coderInfo->pred_global_flag;
int numBands = min(coderInfo->max_pred_sfb, coderInfo->nr_of_sfb);
if (writeFlag) {
PutBit(bitStream, predictorDataPresent, LEN_PRED_PRES); /* predictor_data_present */
if (predictorDataPresent) {
int b;
if (coderInfo->reset_group_number == -1) {
PutBit(bitStream, 0, LEN_PRED_RST); /* No prediction reset */
} else {
PutBit(bitStream, 1, LEN_PRED_RST);
PutBit(bitStream, (unsigned long)coderInfo->reset_group_number,
LEN_PRED_RSTGRP);
}
for (b=0;b<numBands;b++) {
PutBit(bitStream, coderInfo->pred_sfb_flag[b], LEN_PRED_ENAB);
}
}
}
bits = LEN_PRED_PRES;
bits += (predictorDataPresent) ?
(LEN_PRED_RST +
((coderInfo->reset_group_number)!=-1)*LEN_PRED_RSTGRP +
numBands*LEN_PRED_ENAB) : 0;
return bits;
}
static int WritePulseData(CoderInfo *coderInfo,
BitStream *bitStream,
int writeFlag)
{
int bits = 0;
if (writeFlag) {
PutBit(bitStream, 0, LEN_PULSE_PRES); /* no pulse_data_present */
}
bits += LEN_PULSE_PRES;
return bits;
}
static int WriteTNSData(CoderInfo *coderInfo,
BitStream *bitStream,
int writeFlag)
{
int bits = 0;
int numWindows;
int len_tns_nfilt;
int len_tns_length;
int len_tns_order;
int filtNumber;
int resInBits;
int bitsToTransmit;
unsigned long unsignedIndex;
int w;
TnsInfo* tnsInfoPtr = &coderInfo->tnsInfo;
if (writeFlag) {
PutBit(bitStream,tnsInfoPtr->tnsDataPresent,LEN_TNS_PRES);
}
bits += LEN_TNS_PRES;
/* If TNS is not present, bail */
if (!tnsInfoPtr->tnsDataPresent) {
return bits;
}
/* Set window-dependent TNS parameters */
if (coderInfo->block_type == ONLY_SHORT_WINDOW) {
numWindows = MAX_SHORT_WINDOWS;
len_tns_nfilt = LEN_TNS_NFILTS;
len_tns_length = LEN_TNS_LENGTHS;
len_tns_order = LEN_TNS_ORDERS;
}
else {
numWindows = 1;
len_tns_nfilt = LEN_TNS_NFILTL;
len_tns_length = LEN_TNS_LENGTHL;
len_tns_order = LEN_TNS_ORDERL;
}
/* Write TNS data */
bits += (numWindows * len_tns_nfilt);
for (w=0;w<numWindows;w++) {
TnsWindowData* windowDataPtr = &tnsInfoPtr->windowData[w];
int numFilters = windowDataPtr->numFilters;
if (writeFlag) {
PutBit(bitStream,numFilters,len_tns_nfilt); /* n_filt[] = 0 */
}
if (numFilters) {
bits += LEN_TNS_COEFF_RES;
resInBits = windowDataPtr->coefResolution;
if (writeFlag) {
PutBit(bitStream,resInBits-DEF_TNS_RES_OFFSET,LEN_TNS_COEFF_RES);
}
bits += numFilters * (len_tns_length+len_tns_order);
for (filtNumber=0;filtNumber<numFilters;filtNumber++) {
TnsFilterData* tnsFilterPtr=&windowDataPtr->tnsFilter[filtNumber];
int order = tnsFilterPtr->order;
if (writeFlag) {
PutBit(bitStream,tnsFilterPtr->length,len_tns_length);
PutBit(bitStream,order,len_tns_order);
}
if (order) {
bits += (LEN_TNS_DIRECTION + LEN_TNS_COMPRESS);
if (writeFlag) {
PutBit(bitStream,tnsFilterPtr->direction,LEN_TNS_DIRECTION);
PutBit(bitStream,tnsFilterPtr->coefCompress,LEN_TNS_COMPRESS);
}
bitsToTransmit = resInBits - tnsFilterPtr->coefCompress;
bits += order * bitsToTransmit;
if (writeFlag) {
int i;
for (i=1;i<=order;i++) {
unsignedIndex = (unsigned long) (tnsFilterPtr->index[i])&(~(~0<<bitsToTransmit));
PutBit(bitStream,unsignedIndex,bitsToTransmit);
}
}
}
}
}
}
return bits;
}
static int WriteGainControlData(CoderInfo *coderInfo,
BitStream *bitStream,
int writeFlag)
{
int bits = 0;
if (writeFlag) {
PutBit(bitStream, 0, LEN_GAIN_PRES);
}
bits += LEN_GAIN_PRES;
return bits;
}
static int WriteSpectralData(CoderInfo *coderInfo,
BitStream *bitStream,
int writeFlag)
{
int i, bits = 0;
/* set up local pointers to data and len */
/* data array contains data to be written */
/* len array contains lengths of data words */
int* data = coderInfo->data;
int* len = coderInfo->len;
if (writeFlag) {
for(i = 0; i < coderInfo->spectral_count; i++) {
if (len[i] > 0) { /* only send out non-zero codebook data */
PutBit(bitStream, data[i], len[i]); /* write data */
bits += len[i];
}
}
} else {
for(i = 0; i < coderInfo->spectral_count; i++) {
bits += len[i];
}
}
return bits;
}
static int WriteAACFillBits(BitStream* bitStream,
int numBits,
int writeFlag)
{
int numberOfBitsLeft = numBits;
/* Need at least (LEN_SE_ID + LEN_F_CNT) bits for a fill_element */
int minNumberOfBits = LEN_SE_ID + LEN_F_CNT;
while (numberOfBitsLeft >= minNumberOfBits)
{
int numberOfBytes;
int maxCount;
if (writeFlag) {
PutBit(bitStream, ID_FIL, LEN_SE_ID); /* Write fill_element ID */
}
numberOfBitsLeft -= minNumberOfBits; /* Subtract for ID,count */
numberOfBytes = (int)(numberOfBitsLeft/LEN_BYTE);
maxCount = (1<<LEN_F_CNT) - 1; /* Max count without escaping */
/* if we have less than maxCount bytes, write them now */
if (numberOfBytes < maxCount) {
int i;
if (writeFlag) {
PutBit(bitStream, numberOfBytes, LEN_F_CNT);
for (i = 0; i < numberOfBytes; i++) {
PutBit(bitStream, 0, LEN_BYTE);
}
}
/* otherwise, we need to write an escape count */
}
else {
int maxEscapeCount, maxNumberOfBytes, escCount;
int i;
if (writeFlag) {
PutBit(bitStream, maxCount, LEN_F_CNT);
}
maxEscapeCount = (1<<LEN_BYTE) - 1; /* Max escape count */
maxNumberOfBytes = maxCount + maxEscapeCount;
numberOfBytes = (numberOfBytes > maxNumberOfBytes ) ? (maxNumberOfBytes) : (numberOfBytes);
escCount = numberOfBytes - maxCount;
if (writeFlag) {
PutBit(bitStream, escCount, LEN_BYTE);
for (i = 0; i < numberOfBytes-1; i++) {
PutBit(bitStream, 0, LEN_BYTE);
}
}
}
numberOfBitsLeft -= LEN_BYTE*numberOfBytes;
}
return numberOfBitsLeft;
}
static int FindGroupingBits(CoderInfo *coderInfo)
{
/* This function inputs the grouping information and outputs the seven bit
'grouping_bits' field that the AAC decoder expects. */
int grouping_bits = 0;
int tmp[8];
int i, j;
int index = 0;
for(i = 0; i < coderInfo->num_window_groups; i++){
for (j = 0; j < coderInfo->window_group_length[i]; j++){
tmp[index++] = i;
}
}
for(i = 1; i < 8; i++){
grouping_bits = grouping_bits << 1;
if(tmp[i] == tmp[i-1]) {
grouping_bits++;
}
}
return grouping_bits;
}
/* size in bytes! */
BitStream *OpenBitStream(int size, unsigned char *buffer)
{
BitStream *bitStream;
bitStream = AllocMemory(sizeof(BitStream));
bitStream->size = size;
bitStream->numBit = 0;
bitStream->currentBit = 0;
bitStream->data = buffer;
SetMemory(bitStream->data, 0, size);
return bitStream;
}
int CloseBitStream(BitStream *bitStream)
{
int bytes = bit2byte(bitStream->numBit);
FreeMemory(bitStream);
return bytes;
}
static long BufferNumBit(BitStream *bitStream)
{
return bitStream->numBit;
}
static int WriteByte(BitStream *bitStream,
unsigned long data,
int numBit)
{
long numUsed,idx;
idx = (bitStream->currentBit / BYTE_NUMBIT) % bitStream->size;
numUsed = bitStream->currentBit % BYTE_NUMBIT;
if (numUsed == 0)
bitStream->data[idx] = 0;
bitStream->data[idx] |= (data & ((1<<numBit)-1)) <<
(BYTE_NUMBIT-numUsed-numBit);
bitStream->currentBit += numBit;
bitStream->numBit = bitStream->currentBit;
return 0;
}
int PutBit(BitStream *bitStream,
unsigned long data,
int numBit)
{
int num,maxNum,curNum;
unsigned long bits;
if (numBit == 0)
return 0;
/* write bits in packets according to buffer byte boundaries */
num = 0;
maxNum = BYTE_NUMBIT - bitStream->currentBit % BYTE_NUMBIT;
while (num < numBit) {
curNum = min(numBit-num,maxNum);
bits = data>>(numBit-num-curNum);
if (WriteByte(bitStream, bits, curNum)) {
return 1;
}
num += curNum;
maxNum = BYTE_NUMBIT;
}
return 0;
}
static int ByteAlign(BitStream *bitStream, int writeFlag, int offset)
{
int len, i,j;
assert(offset<8);
assert(offset>=0);
len = BufferNumBit(bitStream);
j = (16+offset - (len%8))%8;
if ((len % 8) == offset)
j = 0;
if (writeFlag) {
for( i=0; i<j; i++ ) {
PutBit(bitStream, 0, 1);
}
}
else
bitStream->numBit+=j;
return j;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -