Sigrid Solveig HaflínudóttirPlan 9 portf19cd855 years agoHistory
1396 lines · 46.2 KB · C
RawDownload
/********************************************************************** 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.**********************************************************************/ #include "util.h"#include "coder.h"#include "channels.h"#include "huff2.h"#include "bitstream.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 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);#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;

Lines 1–500 of 1396.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t