📄 bitstream.c
字号:
/**********************************************************************This software module was originally developed byand edited by Texas Instruments in the course ofdevelopment of the MPEG-2 NBC/MPEG-4 Audio standardISO/IEC 13818-7, 14496-1,2 and 3. This software module is animplementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio toolsas specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC givesusers of the MPEG-2 NBC/MPEG-4 Audio standards free license to thissoftware module or modifications thereof for use in hardware orsoftware products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audiostandards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existingpatents. The original developer of this software module and his/hercompany, the subsequent editors and their companies, and ISO/IEC haveno liability for use of this software module or modifications thereofin an implementation. Copyright is not released for non MPEG-2NBC/MPEG-4 Audio conforming products. The original developer retainsfull right to use the code for his/her own purpose, assign or donatethe code to a third party and to inhibit third party from using thecode for non MPEG-2 NBC/MPEG-4 Audio conforming products. Thiscopyright notice must be included in all copies or derivative works.Copyright (c) 1997.**********************************************************************//* * $Id: bitstream.c,v 1.1 2006/02/23 14:30:26 kevin-fu Exp $ */#include <stdio.h>#include <stdlib.h>#include "coder.h"#include "channels.h"#include "huffman.h"#include "bitstream.h"#include "ltp.h"#include "util.h"static int CountBitstream(faacEncHandle hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannels);static int WriteADTSHeader(faacEncHandle 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 WriteLTPPredictorData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag);static int WritePredictorData(CoderInfo *coderInfo, BitStream *bitStream, 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);#ifdef DRMstatic 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);#endifstatic 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(faacEncHandle hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel){ int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; CountBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannel); 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 } if (hEncoder->frameNum == 4) WriteFAACStr(bitStream, hEncoder->config.name, 1); 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); return bits;}static int CountBitstream(faacEncHandle 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 } if (hEncoder->frameNum == 4) bits += WriteFAACStr(bitStream, hEncoder->config.name, 0); 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); hEncoder->usedBytes = bit2byte(bits); return bits;}static int WriteADTSHeader(faacEncHandle 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; 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; /* if common_window, write ics_info */ if (channelInfo->common_window) { int numWindows, maxSfb; bits += WriteICSInfo(coderInfoL, bitStream, objectType, channelInfo->common_window, writeFlag); numWindows = coderInfoL->num_window_groups; maxSfb = coderInfoL->max_sfb; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -