ref: 10655c15c4d96dc52679a4f0f66ccb2d94c9a277
dir: /libfaac/bitstream.c/
/********************************************************************** This software module was originally developed by and edited by Texas Instruments in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products. The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1997. **********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "coder.h" #include "channels.h" #include "huff2.h" #include "bitstream.h" #include "util.h" static int CountBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannels); static int WriteADTSHeader(faacEncStruct* hEncoder, BitStream *bitStream, int writeFlag); static int WriteCPE(CoderInfo *coderInfoL, CoderInfo *coderInfoR, ChannelInfo *channelInfo, BitStream* bitStream, int objectType, int writeFlag); static int WriteSCE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag); static int WriteLFE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag); static int WriteICSInfo(CoderInfo *coderInfo, BitStream *bitStream, int objectType, int common_window, int writeFlag); static int WriteICS(CoderInfo *coderInfo, BitStream *bitStream, int commonWindow, int objectType, int writeFlag); static int WritePulseData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteTNSData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteGainControlData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteSpectralData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteAACFillBits(BitStream* bitStream, int numBits, int writeFlag); static int FindGroupingBits(CoderInfo *coderInfo); static long BufferNumBit(BitStream *bitStream); static int WriteByte(BitStream *bitStream, unsigned long data, int numBit); static int ByteAlign(BitStream* bitStream, int writeFlag, int bitsSoFar); #ifdef DRM static int PutBitHcr(BitStream *bitStream, unsigned long curpos, unsigned long data, int numBit); static int rewind_word(int W, int len); static int WriteReorderedSpectralData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static void calc_CRC(BitStream *bitStream, int len); #endif static int WriteFAACStr(BitStream *bitStream, char *version, int write) { int i; char str[200]; int len, padbits, count; int bitcnt; sprintf(str, "libfaac %s", version); len = strlen(str) + 1; padbits = (8 - ((bitStream->numBit + 7) % 8)) % 8; count = len + 3; bitcnt = LEN_SE_ID + 4 + ((count < 15) ? 0 : 8) + count * 8; if (!write) return bitcnt; PutBit(bitStream, ID_FIL, LEN_SE_ID); if (count < 15) { PutBit(bitStream, count, 4); } else { PutBit(bitStream, 15, 4); PutBit(bitStream, count - 14, 8); } PutBit(bitStream, 0, padbits); PutBit(bitStream, 0, 8); PutBit(bitStream, 0, 8); // just in case for (i = 0; i < len; i++) PutBit(bitStream, str[i], 8); PutBit(bitStream, 0, 8 - padbits); return bitcnt; } int WriteBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel) { int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; if (CountBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannel) < 0) return -1; if(hEncoder->config.outputFormat == 1){ bits += WriteADTSHeader(hEncoder, bitStream, 1); }else{ bits = 0; // compilier will remove it, byt anyone will see that current size of bitstream is 0 } /* sur: faad2 complains about scalefactor error if we are writing FAAC String */ #ifndef DRM if (hEncoder->frameNum == 4) WriteFAACStr(bitStream, hEncoder->config.name, 1); #endif for (channel = 0; channel < numChannel; channel++) { if (channelInfo[channel].present) { /* Write out a single_channel_element */ if (!channelInfo[channel].cpe) { if (channelInfo[channel].lfe) { /* Write out lfe */ bits += WriteLFE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } else { /* Write out sce */ bits += WriteSCE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } else { if (channelInfo[channel].ch_is_left) { /* Write out cpe */ bits += WriteCPE(&coderInfo[channel], &coderInfo[channelInfo[channel].paired_ch], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } } } /* Compute how many fill bits are needed to avoid overflowing bit reservoir */ /* Save room for ID_END terminator */ if (bits < (8 - LEN_SE_ID) ) { numFillBits = 8 - LEN_SE_ID - bits; } else { numFillBits = 0; } /* Write AAC fill_elements, smallest fill element is 7 bits. */ /* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */ numFillBits += 6; bitsLeftAfterFill = WriteAACFillBits(bitStream, numFillBits, 1); bits += (numFillBits - bitsLeftAfterFill); /* Write ID_END terminator */ bits += LEN_SE_ID; PutBit(bitStream, ID_END, LEN_SE_ID); /* Now byte align the bitstream */ /* * This byte_alignment() is correct for both MPEG2 and MPEG4, although * in MPEG4 the byte_alignment() is officially done before the new frame * instead of at the end. But this is basically the same. */ bits += ByteAlign(bitStream, 1, bits); return bits; } static int CountBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel) { int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; if(hEncoder->config.outputFormat == 1){ bits += WriteADTSHeader(hEncoder, bitStream, 0); }else{ bits = 0; // compilier will remove it, byt anyone will see that current size of bitstream is 0 } /* sur: faad2 complains about scalefactor error if we are writing FAAC String */ #ifndef DRM if (hEncoder->frameNum == 4) bits += WriteFAACStr(bitStream, hEncoder->config.name, 0); #endif for (channel = 0; channel < numChannel; channel++) { if (channelInfo[channel].present) { /* Write out a single_channel_element */ if (!channelInfo[channel].cpe) { if (channelInfo[channel].lfe) { /* Write out lfe */ bits += WriteLFE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } else { /* Write out sce */ bits += WriteSCE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } } else { if (channelInfo[channel].ch_is_left) { /* Write out cpe */ bits += WriteCPE(&coderInfo[channel], &coderInfo[channelInfo[channel].paired_ch], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } } } } /* Compute how many fill bits are needed to avoid overflowing bit reservoir */ /* Save room for ID_END terminator */ if (bits < (8 - LEN_SE_ID) ) { numFillBits = 8 - LEN_SE_ID - bits; } else { numFillBits = 0; } /* Write AAC fill_elements, smallest fill element is 7 bits. */ /* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */ numFillBits += 6; bitsLeftAfterFill = WriteAACFillBits(bitStream, numFillBits, 0); bits += (numFillBits - bitsLeftAfterFill); /* Write ID_END terminator */ bits += LEN_SE_ID; /* Now byte align the bitstream */ bits += ByteAlign(bitStream, 0, bits); hEncoder->usedBytes = bit2byte(bits); if (hEncoder->usedBytes > bitStream->size) { fprintf(stderr, "frame buffer overrun\n"); return -1; } if (hEncoder->usedBytes >= ADTS_FRAMESIZE) { fprintf(stderr, "frame size limit exceeded\n"); return -1; } return bits; } static int WriteADTSHeader(faacEncStruct* hEncoder, BitStream *bitStream, int writeFlag) { int bits = 56; if (writeFlag) { /* Fixed ADTS header */ PutBit(bitStream, 0xFFFF, 12); /* 12 bit Syncword */ PutBit(bitStream, hEncoder->config.mpegVersion, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */ PutBit(bitStream, 0, 2); /* layer == 0 */ PutBit(bitStream, 1, 1); /* protection absent */ PutBit(bitStream, hEncoder->config.aacObjectType - 1, 2); /* profile */ PutBit(bitStream, hEncoder->sampleRateIdx, 4); /* sampling rate */ PutBit(bitStream, 0, 1); /* private bit */ PutBit(bitStream, hEncoder->numChannels, 3); /* ch. config (must be > 0) */ /* simply using numChannels only works for 6 channels or less, else a channel configuration should be written */ PutBit(bitStream, 0, 1); /* original/copy */ PutBit(bitStream, 0, 1); /* home */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) PutBit(bitStream, 0, 2); /* emphasis */ #endif /* Variable ADTS header */ PutBit(bitStream, 0, 1); /* copyr. id. bit */ PutBit(bitStream, 0, 1); /* copyr. id. start */ PutBit(bitStream, hEncoder->usedBytes, 13); PutBit(bitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */ PutBit(bitStream, 0, 2); /* raw data blocks (0+1=1) */ } /* * MPEG2 says byte_aligment() here, but ADTS always is multiple of 8 bits * MPEG4 has no byte_alignment() here */ /* if (hEncoder->config.mpegVersion == 1) bits += ByteAlign(bitStream, writeFlag); */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) bits += 2; /* emphasis */ #endif return bits; } static int WriteCPE(CoderInfo *coderInfoL, CoderInfo *coderInfoR, ChannelInfo *channelInfo, BitStream* bitStream, int objectType, int writeFlag) { int bits = 0; #ifndef DRM if (writeFlag) { /* write ID_CPE, single_element_channel() identifier */ PutBit(bitStream, ID_CPE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); /* common_window? */ PutBit(bitStream, channelInfo->common_window, LEN_COM_WIN); } bits += LEN_SE_ID; bits += LEN_TAG; bits += LEN_COM_WIN; #endif /* if common_window, write ics_info */ if (channelInfo->common_window) { int numWindows, maxSfb; bits += WriteICSInfo(coderInfoL, bitStream, objectType, channelInfo->common_window, writeFlag); numWindows = coderInfoL->groups.n; maxSfb = coderInfoL->sfbn; if (writeFlag) { PutBit(bitStream, channelInfo->msInfo.is_present, LEN_MASK_PRES); if (channelInfo->msInfo.is_present == 1) { int g; int b; for (g=0;g<numWindows;g++) { for (b=0;b<maxSfb;b++) { PutBit(bitStream, channelInfo->msInfo.ms_used[g*maxSfb+b], LEN_MASK); } } } } bits += LEN_MASK_PRES; if (channelInfo->msInfo.is_present == 1) bits += (numWindows*maxSfb*LEN_MASK); } /* Write individual_channel_stream elements */ bits += WriteICS(coderInfoL, bitStream, channelInfo->common_window, objectType, writeFlag); bits += WriteICS(coderInfoR, bitStream, channelInfo->common_window, objectType, writeFlag); return bits; } static int WriteSCE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; #ifndef DRM if (writeFlag) { /* write Single Element Channel (SCE) identifier */ PutBit(bitStream, ID_SCE, LEN_SE_ID); /* write the element identifier tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; #endif /* Write an Individual Channel Stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; } static int WriteLFE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; if (writeFlag) { /* write ID_LFE, lfe_element_channel() identifier */ PutBit(bitStream, ID_LFE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; /* Write an individual_channel_stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; } static int WriteICSInfo(CoderInfo *coderInfo, BitStream *bitStream, int objectType, int common_window, int writeFlag) { int grouping_bits; int bits = 0; if (writeFlag) { /* write out ics_info() information */ PutBit(bitStream, 0, LEN_ICS_RESERV); /* reserved Bit*/ /* Write out window sequence */ PutBit(bitStream, coderInfo->block_type, LEN_WIN_SEQ); /* block type */ /* Write out window shape */ PutBit(bitStream, coderInfo->window_shape, LEN_WIN_SH); /* window shape */ } bits += LEN_ICS_RESERV; bits += LEN_WIN_SEQ; bits += LEN_WIN_SH; /* For short windows, write out max_sfb and scale_factor_grouping */ if (coderInfo->block_type == ONLY_SHORT_WINDOW){ if (writeFlag) { PutBit(bitStream, coderInfo->sfbn, LEN_MAX_SFBS); grouping_bits = FindGroupingBits(coderInfo); PutBit(bitStream, grouping_bits, MAX_SHORT_WINDOWS - 1); /* the grouping bits */ } bits += LEN_MAX_SFBS; bits += MAX_SHORT_WINDOWS - 1; } else { /* Otherwise, write out max_sfb and predictor data */ if (writeFlag) { PutBit(bitStream, coderInfo->sfbn, LEN_MAX_SFBL); } bits += LEN_MAX_SFBL; #ifdef DRM } if (writeFlag) { PutBit(bitStream,coderInfo->tnsInfo.tnsDataPresent,LEN_TNS_PRES); } bits += LEN_TNS_PRES; #endif bits++; if (writeFlag) PutBit(bitStream, 0, LEN_PRED_PRES); /* predictor_data_present */ #ifndef DRM } #endif return bits; } static int WriteICS(CoderInfo *coderInfo, BitStream *bitStream, int commonWindow, int objectType, int writeFlag) { /* this function writes out an individual_channel_stream to the bitstream and */ /* returns the number of bits written to the bitstream */ int bits = 0; #ifndef DRM /* Write the 8-bit global_gain */ if (writeFlag) PutBit(bitStream, coderInfo->global_gain, LEN_GLOB_GAIN); bits += LEN_GLOB_GAIN; #endif /* Write ics information */ if (!commonWindow) { bits += WriteICSInfo(coderInfo, bitStream, objectType, commonWindow, writeFlag); } #ifdef DRM /* Write the 8-bit global_gain */ if (writeFlag) PutBit(bitStream, coderInfo->global_gain, LEN_GLOB_GAIN); bits += LEN_GLOB_GAIN; #endif bits += writebooks(coderInfo, bitStream, writeFlag); bits += writesf(coderInfo, bitStream, writeFlag); #ifdef DRM if (writeFlag) { /* length_of_reordered_spectral_data */ PutBit(bitStream, coderInfo->iLenReordSpData, LEN_HCR_REORDSD); /* length_of_longest_codeword */ PutBit(bitStream, coderInfo->iLenLongestCW, LEN_HCR_LONGCW); } bits += LEN_HCR_REORDSD + LEN_HCR_LONGCW; #else bits += WritePulseData(coderInfo, bitStream, writeFlag); #endif bits += WriteTNSData(coderInfo, bitStream, writeFlag); #ifndef DRM bits += WriteGainControlData(coderInfo, bitStream, writeFlag); #endif #ifdef DRM /* DRM CRC calculation */ if (writeFlag) calc_CRC(bitStream, bits); bits += WriteReorderedSpectralData(coderInfo, bitStream, writeFlag); #else bits += WriteSpectralData(coderInfo, bitStream, writeFlag); #endif /* Return number of bits */ 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; #ifndef DRM if (writeFlag) { PutBit(bitStream,tnsInfoPtr->tnsDataPresent,LEN_TNS_PRES); } bits += LEN_TNS_PRES; #endif /* 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; if (writeFlag) { for(i = 0; i < coderInfo->datacnt; i++) { int data = coderInfo->s[i].data; int len = coderInfo->s[i].len; if (len > 0) { PutBit(bitStream, data, len); bits += len; } } } else { for(i = 0; i < coderInfo->datacnt; i++) { bits += coderInfo->s[i].len; } } 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->groups.n; i++){ for (j = 0; j < coderInfo->groups.len[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; #ifdef DRM /* skip first byte for CRC */ bitStream->numBit = 8; bitStream->currentBit = 8; #else bitStream->numBit = 0; bitStream->currentBit = 0; #endif 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; #ifndef DRM if (numUsed == 0) bitStream->data[idx] = 0; #endif 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 bitsSoFar) { int len, i,j; if (writeFlag) { len = BufferNumBit(bitStream); } else { len = bitsSoFar; } j = (8 - (len%8))%8; if ((len % 8) == 0) j = 0; if (writeFlag) { for( i=0; i<j; i++ ) { PutBit(bitStream, 0, 1); } } return j; } #ifdef DRM /* **************************************************************************** The following code was written by Volker Fischer (c) 2004 The GNU Lesser General Public License as published by the Free Software Foundation applies to this code. **************************************************************************** */ #define LEN_PRESORT_CODEBOOK 22 static const unsigned short PresortedCodebook_VCB11[] = {11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1}; static const int maxCwLen[32] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41}; /* 8.5.3.3.3.1 */ typedef struct { /* segment parameters */ unsigned int left; /* left start of free space in segment */ unsigned int right; /* right position of free space in segment */ unsigned int len; /* length of free space in segment */ } segment_t; typedef struct { /* codeword parameters */ unsigned int cw_offset; /* offset in actual codeword data vector */ unsigned short window; /* which window belongs to this codeword */ unsigned short cb; /* codebook */ unsigned short num_sl_cw; /* number of spectral lines per codeword */ unsigned int cw_nr; /* codeword number in the window */ unsigned short cw_len; /* codeword lenght */ unsigned short num_data; /* number of data cells for codeword */ } cw_info_t; static int PutBitHcr(BitStream *bitStream, unsigned long curpos, unsigned long data, int numBit) { /* data can be written at an arbitrary position in the bitstream */ bitStream->currentBit = curpos; return PutBit(bitStream, data, numBit); } static int rewind_word(int W, int len) { /* rewind len (max. 32) bits so that the MSB becomes LSB */ short i; int tmp_W = 0; for (i = 0; i < len; i++) { tmp_W <<= 1; if (W & (1<<i)) tmp_W |= 1; } return tmp_W; } static int WriteReorderedSpectralData(CoderInfo *coder, BitStream *bitStream, int writeFlag) { int i, j; int cursegmsize, accsegmsize = 0; int segmcnt = 0; long startbitpos; segment_t segment[FRAME_LEN]; int* groups = coder->groups.len; int* sfb_offset = coder->sfb_offset; cw_info_t cw_info[FRAME_LEN]; cw_info_t cw_info_preso[FRAME_LEN]; int num_cw = coder->cur_cw; int window_cw_cnt[MAX_SHORT_WINDOWS] = {0,0,0,0,0,0,0,0}; int presort, set, num_sets; unsigned short cur_cb, cw_cnt; short is_backwards; int diff, tmp_data, cw_part_cnt, cur_cw_part; int cur_cw_len, cur_data; int sfb_cnt, win_cnt, acc_win_cnt, win_grp_cnt; int coeff_cnt, last_sfb, cur_sfb_len; /* set up local pointers to data and len */ /* data array contains data to be written */ /* len array contains lengths of data words */ int* num_data = coder->num_data_cw; if (writeFlag) { /* build offset table */ cur_data = 0; cw_info[0].cw_offset = 0; for (i = 0; i < num_cw; i++) { cur_cw_len = 0; for (j = 0; j < num_data[i]; j++) { cur_cw_len += coder->s[cur_data++].len; } cw_info[i].num_data = num_data[i]; cw_info[i].cw_len = cur_cw_len; if (i > 0) /* calculate offset (codeword info parameter) */ cw_info[i].cw_offset = cw_info[i - 1].cw_offset + num_data[i - 1]; } /* presort codewords ------------------------------------------------ */ /* classify codewords first */ sfb_cnt = win_cnt = win_grp_cnt = coeff_cnt = last_sfb = acc_win_cnt = 0; cur_sfb_len = sfb_offset[1] / groups[0]; cur_cb = coder->book[0]; for (i = 0; i < num_cw; i++) { /* Set codeword info parameters */ cw_info[i].cb = cur_cb; cw_info[i].num_sl_cw = (cur_cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN; cw_info[i].window = acc_win_cnt + win_cnt; cw_info[i].cw_nr = window_cw_cnt[cw_info[i].window]; window_cw_cnt[cw_info[i].window]++; coeff_cnt += cw_info[i].num_sl_cw; if (coeff_cnt - last_sfb >= cur_sfb_len) { last_sfb += cur_sfb_len; win_cnt++; /* next window */ if (win_cnt == groups[win_grp_cnt]) { win_cnt = 0; sfb_cnt++; /* next sfb */ if (sfb_cnt == coder->all_sfb) { sfb_cnt = 0; acc_win_cnt += groups[win_grp_cnt]; win_grp_cnt++; /* next window group */ } /* new codebook and sfb length */ cur_cb = coder->book[sfb_cnt]; if (last_sfb < FRAME_LEN) { cur_sfb_len = (sfb_offset[sfb_cnt + 1] - sfb_offset[sfb_cnt]) / groups[win_grp_cnt]; } } } } /* presorting (first presorting step) */ /* only needed for short windows */ /* Somehow the second presorting step does not give expected results. Disabling the following code surprisingly gives good results. TODO: find the bug */ if (0) {//coder->block_type == ONLY_SHORT_WINDOW) { for (i = 0; i < MAX_SHORT_WINDOWS; i++) window_cw_cnt[i] = 0; /* reset all counters */ win_cnt = 0; cw_cnt = 0; for (i = 0; i < num_cw; i++) { for (j = 0; j < num_cw; j++) { if (cw_info[j].window == win_cnt) { if (cw_info[j].cw_nr == window_cw_cnt[win_cnt]) { cw_info_preso[cw_cnt++] = cw_info[j]; window_cw_cnt[win_cnt]++; /* check if two one-dimensional codewords */ if (cw_info[j].num_sl_cw == PAIR_LEN) { cw_info_preso[cw_cnt++] = cw_info[j + 1]; window_cw_cnt[win_cnt]++; } win_cnt++; /* next window */ if (win_cnt == MAX_SHORT_WINDOWS) win_cnt = 0; } } } } } else { for (i = 0; i < num_cw; i++) { cw_info_preso[i] = cw_info[i]; /* just copy */ } } /* presorting (second presorting step) */ cw_cnt = 0; for (presort = 0; presort < LEN_PRESORT_CODEBOOK; presort++) { /* next codebook that has to be processed according to presorting */ unsigned short nextCB = PresortedCodebook_VCB11[presort]; for (i = 0; i < num_cw; i++) { /* process only codewords that are due now */ if ((cw_info_preso[i].cb == nextCB) || ((nextCB < HCB_ESC) && (cw_info_preso[i].cb == nextCB + 1))) { cw_info[cw_cnt++] = cw_info_preso[i]; } } } /* init segments */ accsegmsize = 0; for (i = 0; i < num_cw; i++) { /* 8.5.3.3.3.2 Derivation of segment width */ cursegmsize = min(maxCwLen[cw_info[i].cb], coder->iLenLongestCW); if (accsegmsize + cursegmsize > coder->iLenReordSpData) { /* the last segment is extended until iLenReordSpData */ segment[segmcnt - 1].right = coder->iLenReordSpData - 1; segment[segmcnt - 1].len = coder->iLenReordSpData - segment[segmcnt - 1].left; break; } segment[segmcnt].left = accsegmsize; segment[segmcnt].right = accsegmsize + cursegmsize - 1; segment[segmcnt++].len = cursegmsize; accsegmsize += cursegmsize; } /* store current bit position */ startbitpos = bitStream->currentBit; /* write write priority codewords (PCWs) and nonPCWs ---------------- */ num_sets = num_cw / segmcnt; /* number of sets */ for (set = 0; set <= num_sets; set++) { int trial; /* ever second set the bit order is reversed */ is_backwards = set % 2; for (trial = 0; trial < segmcnt; trial++) { int codewordBase; int set_encoded = segmcnt; if (set == num_sets) set_encoded = num_cw - set * segmcnt; /* last set is shorter than the rest */ for (codewordBase = 0; codewordBase < segmcnt; codewordBase++) { int segment_index = (trial + codewordBase) % segmcnt; int codeword_index = codewordBase + set * segmcnt; if (codeword_index >= num_cw) break; if ((cw_info[codeword_index].cw_len > 0) && (segment[segment_index].len > 0)) { /* codeword is not yet written (completely) */ /* space left in this segment */ short tmplen; /* how many bits can be written? */ if (segment[segment_index].len >= cw_info[codeword_index].cw_len) { tmplen = cw_info[codeword_index].cw_len; set_encoded--; /* CW fits into segment */ } else { tmplen = segment[segment_index].len; } /* Adjust lengths */ cw_info[codeword_index].cw_len -= tmplen; segment[segment_index].len -= tmplen; /* write codewords to bitstream */ for (cw_part_cnt = 0; cw_part_cnt < cw_info[codeword_index].num_data; cw_part_cnt++) { cur_cw_part = cw_info[codeword_index].cw_offset + cw_part_cnt; if (coder->s[cur_cw_part].len <= tmplen) { /* write complete data, no partitioning */ if (is_backwards) { /* write data in reversed bit-order */ PutBitHcr(bitStream, startbitpos + segment[segment_index].right - coder->s[cur_cw_part].len + 1, rewind_word(coder->s[cur_cw_part].data, coder->s[cur_cw_part].len), coder->s[cur_cw_part].len); segment[segment_index].right -= coder->s[cur_cw_part].len; } else { PutBitHcr(bitStream, startbitpos + segment[segment_index].left, coder->s[cur_cw_part].data, coder->s[cur_cw_part].len); segment[segment_index].left += coder->s[cur_cw_part].len; } tmplen -= coder->s[cur_cw_part].len; coder->s[cur_cw_part].len = 0; } else { /* codeword part must be partitioned */ /* data must be taken from the left side */ tmp_data = coder->s[cur_cw_part].data; diff = coder->s[cur_cw_part].len - tmplen; tmp_data >>= diff; /* remove bits which are already used */ coder->s[cur_cw_part].data &= (1 << diff) - 1 /* diff number of ones */; coder->s[cur_cw_part].len = diff; if (is_backwards) { /* write data in reversed bit-order */ PutBitHcr(bitStream, startbitpos + segment[segment_index].right - tmplen + 1, rewind_word(tmp_data, tmplen), tmplen); segment[segment_index].right -= tmplen; } else { PutBitHcr(bitStream, startbitpos + segment[segment_index].left, tmp_data, tmplen); segment[segment_index].left += tmplen; } tmplen = 0; } if (tmplen == 0) break; /* all data written for this segment trial */ } } } /* of codewordBase */ if (set_encoded == 0) break; /* no unencoded codewords left in this set */ } /* of trial */ } /* set parameter for bit stream to current correct position */ bitStream->currentBit = startbitpos + coder->iLenReordSpData; bitStream->numBit = bitStream->currentBit; } return coder->iLenReordSpData; } /* CRC8 x^8 + x^4 + x^3 + x^2 + 1 */ static const unsigned char _crctable[256] = { 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4 }; static void calc_CRC(BitStream *bitStream, int len) { //int i; //unsigned char r = ~0; /* Initialize to all ones */ unsigned char crc = ~0; /* Initialize to all ones */ /* CRC polynome used x^8 + x^4 + x^3 + x^2 +1 */ unsigned int cb = len / 8; unsigned int taillen = len & 0x7; unsigned char* pb = &bitStream->data[1]; //compatible, but slower unsigned char b = ( bitStream->data[cb + 1] ) >> ( 8 - taillen ); unsigned char b = bitStream->data[cb + 1]; //#define GPOLY 0435 // // for (i = 8; i < len + 8; i++) { // r = ( (r << 1) ^ (( ( // ( bitStream->data[i / 8] >> (7 - (i % 8)) ) // & 1) ^ ((r >> 7) & 1)) * GPOLY )) & 0xFF; // } #define GP 0x1d //fprintf( stderr, "\nfaac:" ); while ( cb-- ) { //fprintf( stderr, " %02X", *pb ); crc = _crctable[ crc ^ *pb++ ]; } //compatible, but slower switch ( taillen ) //{ //case 7: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 6 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 6: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 5 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 5: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 4 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 4: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 3 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 3: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 2 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 2: // crc = ( ( crc << 1 ) ^ ( ( ( ( b >> 1 ) & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // // goto next case //case 1: // crc = ( ( crc << 1 ) ^ ( ( ( b & 1 ) ^ ( ( crc >> 7 ) & 1 ) ) * GP ) ) & 0xFF; // break; //} //fprintf( stderr, " %02X", ( b >> ( 8 - taillen ) ) << 7 ); switch ( taillen ) { case 7: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 6: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 5: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 4: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 3: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 2: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; b <<= 1; // goto next case case 1: crc = ( ( crc << 1 ) ^ ( ( (signed char)( b ^ crc ) >> 7 ) & GP ) ) & 0xFF; break; } //if ( crc != r ) //{ // fprintf( stderr, "%08X != %08X\n", crc, r ); //} //fprintf( stderr, " (%5d bits), CRC is %02X\n", len, ~crc & 0xFF ); /* CRC is stored inverted, per definition at first byte in stream */ bitStream->data[0] = ~crc; } #endif