aboutsummaryrefslogtreecommitdiffstats
path: root/libMpegTPEnc
diff options
context:
space:
mode:
Diffstat (limited to 'libMpegTPEnc')
-rw-r--r--libMpegTPEnc/src/tpenc_dab.cpp467
-rw-r--r--libMpegTPEnc/src/tpenc_dab.h217
-rw-r--r--libMpegTPEnc/src/tpenc_lib.cpp51
3 files changed, 734 insertions, 1 deletions
diff --git a/libMpegTPEnc/src/tpenc_dab.cpp b/libMpegTPEnc/src/tpenc_dab.cpp
new file mode 100644
index 0000000..202fecf
--- /dev/null
+++ b/libMpegTPEnc/src/tpenc_dab.cpp
@@ -0,0 +1,467 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/******************************** MPEG Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport Headers support
+
+******************************************************************************/
+#include <stdio.h>
+#include "FDK_audio.h"
+#include "tpenc_dab.h"
+
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+
+#include "common_fix.h"
+
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab, /*!< pointer to dab stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcStartReg(%p): bits in crc region=%d\n", hBs, mBits);
+ return ( FDKcrcStartReg(&pDab->crcInfo2, hBs, mBits) );
+}
+
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab, /*!< pointer to dab crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcEndReg(%p): crc region=%d\n", hBs, reg);
+ FDKcrcEndReg(&pDab->crcInfo2, hBs, reg);
+}
+
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab )
+{
+ int bits = 0;
+
+ if (hDab->currentBlock == 0) {
+ /* Static and variable header bits */
+ bits += 16; //header_firecode 16
+ bits += 8; //rfa=1, dac_rate=1, sbr_flag=1, aac_channel_mode=1, ps_flag=1, mpeg_surround_config=3
+ bits += 12 * hDab->num_raw_blocks; //au_start[1...num_aus] 12 bit AU start position markers
+
+ //4 byte alignment
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0)
+ bits+=4;
+ //16sbr => 16 + 5 + 3 + 12*(2-1) => 36 => 40 bits 5
+ //24sbr => 16 + 5 + 3 + 12*(3-1) => 48 ok 6
+ //32sbr => 16 + 5 + 3 + 12*(4-1) => 60 => 64 bits 8
+ //48sbr => 16 + 5 + 3 + 12*(6-1) => 84 => 88 bits 11
+ }
+
+ /* Add raw data block CRC bits. Not really part of the header, put they cause bit overhead to be accounted. */
+ bits += 16;
+
+
+ return bits;
+}
+
+
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength )
+{
+ //fprintf(stderr, "streamDataLength=%d (%d bytes)\n", streamDataLength, streamDataLength >> 3);
+ return dabWrite_GetHeaderBits(hDab);
+}
+
+
+INT dabWrite_Init(HANDLE_DAB hDab, CODER_CONFIG *config)
+{
+ /* Sanity checks */
+ if((int)config->aot > 4
+ || (int)config->aot < 1 ) {
+ return -1;
+ }
+
+ /* Sanity checks DAB-specific */
+ if ( !(config->nSubFrames == 2 && config->samplingRate == 16000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 3 && config->samplingRate == 24000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 4 && config->samplingRate == 32000) &&
+ !(config->nSubFrames == 6 && config->samplingRate == 48000)) {
+ return -1;
+ }
+
+ hDab->dac_rate = 0;
+ hDab->aac_channel_mode=0;
+ hDab->sbr_flag = 0;
+ hDab->ps_flag = 0;
+ hDab->mpeg_surround_config=0;
+ hDab->subchannels_num=config->bitRate/8000;
+
+
+ if(config->samplingRate == 24000 || config->samplingRate == 48000)
+ hDab->dac_rate = 1;
+
+ if (config->extAOT==AOT_SBR || config->extAOT == AOT_PS)
+ hDab->sbr_flag = 1;
+
+ if(config->extAOT == AOT_PS)
+ hDab->ps_flag = 1;
+
+
+ if(config->channelMode == MODE_2)
+ hDab->aac_channel_mode = 1;
+
+ //fprintf(stderr, "hDab->dac_rate=%d\n", hDab->dac_rate);
+ //fprintf(stderr, "hDab->sbr_flag=%d\n", hDab->sbr_flag);
+ //fprintf(stderr, "hDab->ps_flag=%d\n", hDab->ps_flag);
+ //fprintf(stderr, "hDab->aac_channel_mode=%d\n", hDab->aac_channel_mode);
+ //fprintf(stderr, "hDab->subchannels_num=%d\n", hDab->subchannels_num);
+ //fprintf(stderr, "cc->nSubFrames=%d\n", config->nSubFrames);
+
+ hDab->num_raw_blocks=config->nSubFrames-1; /* 0 means 1 raw data block */
+
+ FDKcrcInit(&hDab->crcInfo, 0x1021, 0xFFFF, 16);
+ FDKcrcInit(&hDab->crcFire, 0x782d, 0, 16);
+ FDKcrcInit(&hDab->crcInfo2, 0x8005, 0xFFFF, 16);
+
+ hDab->currentBlock = 0;
+ hDab->headerBits = dabWrite_GetHeaderBits(hDab);
+
+ return 0;
+}
+
+int dabWrite_EncodeHeader(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int buffer_fullness,
+ int frame_length)
+{
+ INT crcIndex = 0;
+
+
+ FDK_ASSERT(((frame_length+hDab->headerBits)/8)<0x2000); /*13 bit*/
+ FDK_ASSERT(buffer_fullness<0x800); /* 11 bit */
+
+ FDKcrcReset(&hDab->crcInfo);
+
+
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->currentBlock=%d, frame_length=%d, buffer_fullness=%d\n",
+// hDab->currentBlock, frame_length, buffer_fullness);
+
+// if (hDab->currentBlock == 0) {
+// //hDab->subFrameStartPrev=dabWrite_GetHeaderBits(hDab);
+// fprintf(stderr, "header bits[%d] [%d]\n", hDab->subFrameStartPrev, hDab->subFrameStartPrev >> 3);
+// FDKresetBitbuffer(hBitStream, BS_WRITER);
+// }
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->subFrameStartBit=%d [%d]\n", hDab->subFrameStartBit, hDab->subFrameStartBit >> 3);
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ /* Skip new header if this is raw data block 1..n */
+ if (hDab->currentBlock == 0)
+ {
+ FDKresetBitbuffer(hBitStream, BS_WRITER);
+// fprintf(stderr, "dabWrite_EncodeHeader() after FDKresetBitbuffer=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+
+ /* fixed header */
+ FDKwriteBits(hBitStream, 0, 16); //header_firecode
+ FDKwriteBits(hBitStream, 0, 1); //rfa
+ FDKwriteBits(hBitStream, hDab->dac_rate, 1);
+ FDKwriteBits(hBitStream, hDab->sbr_flag, 1);
+ FDKwriteBits(hBitStream, hDab->aac_channel_mode, 1);
+ FDKwriteBits(hBitStream, hDab->ps_flag, 1);
+ FDKwriteBits(hBitStream, hDab->mpeg_surround_config, 3);
+ /* variable header */
+ int i;
+ for(i=0; i<hDab->num_raw_blocks; i++)
+ FDKwriteBits(hBitStream, 0, 12);
+ /* padding */
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0) {
+ FDKwriteBits(hBitStream, 0, 4);
+ }
+ } /* End of DAB header */
+
+ hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ FDK_ASSERT(FDKgetValidBits(hBitStream) % 8 == 0); //only aligned header
+
+// fprintf(stderr, "dabWrite_EncodeHeader() FDKgetValidBits(hBitStream)=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+ return 0;
+}
+
+int dabWrite_writeExtensionFillPayload(HANDLE_FDK_BITSTREAM hBitStream, int extPayloadBits)
+{
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+ INT extBitsUsed = 0;
+ INT extPayloadType = EXT_FIL;
+ //fprintf(stderr, "FDKaacEnc_writeExtensionPayload() extPayloadType=%d\n", extPayloadType);
+ if (extPayloadBits >= EXT_TYPE_BITS)
+ {
+ UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
+
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
+ }
+ extBitsUsed += EXT_TYPE_BITS;
+
+ switch (extPayloadType) {
+ case EXT_FILL_DATA:
+ fillByte = 0xA5;
+ case EXT_FIL:
+ default:
+ if (hBitStream != NULL) {
+ int writeBits = extPayloadBits;
+ FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
+ writeBits -= 8; /* acount for the extension type and the fill nibble */
+ while (writeBits >= 8) {
+ FDKwriteBits(hBitStream, fillByte, 8);
+ writeBits -= 8;
+ }
+ }
+ extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
+ break;
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+void dabWrite_FillRawDataBlock(HANDLE_FDK_BITSTREAM hBitStream, int payloadBits)
+{
+ INT extBitsUsed = 0;
+#define EL_ID_BITS ( 3 )
+#define FILL_EL_COUNT_BITS ( 4 )
+#define FILL_EL_ESC_COUNT_BITS ( 8 )
+#define MAX_FILL_DATA_BYTES ( 269 )
+ while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
+ INT cnt, esc_count=-1, alignBits=7;
+
+ payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
+ if (payloadBits >= 15*8) {
+ payloadBits -= FILL_EL_ESC_COUNT_BITS;
+ esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
+ }
+ alignBits = 0;
+
+ cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3);
+
+ if (cnt >= 15) {
+ esc_count = cnt - 15 + 1;
+ }
+
+ if (hBitStream != NULL) {
+ /* write bitstream */
+ FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
+ }
+ }
+
+ extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0);
+
+ cnt = fixMin(cnt*8, payloadBits); /* convert back to bits */
+#if 0
+ extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
+ pExtension->type,
+ pExtension->pPayload,
+ cnt );
+#else
+ extBitsUsed += dabWrite_writeExtensionFillPayload(hBitStream, cnt);
+#endif
+ payloadBits -= cnt;
+ }
+}
+
+void dabWrite_EndRawDataBlock(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *pBits)
+{
+ FDK_BITSTREAM bsWriter;
+ INT crcIndex = 0;
+ USHORT crcData;
+ INT writeBits=0;
+ INT writeBitsNonLastBlock=0;
+ INT writeBitsLastBlock=0;
+#if 1
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ //calculate byte-alignment before writing ID_FIL
+ if((FDKgetValidBits(hBs)+3) % 8){
+ writeBits = 8 - ((FDKgetValidBits(hBs)+3) % 8);
+ }
+
+ INT offset_end = hDab->subchannels_num*110*8 - 2*8 - 3;
+ writeBitsLastBlock = offset_end - FDKgetValidBits(hBs);
+ dabWrite_FillRawDataBlock(hBs, writeBitsLastBlock);
+ FDKsyncCache(hBs);
+ //fprintf(stderr, "FIL-element written=%d\n", writeBitsLastBlock);
+ writeBitsLastBlock=writeBits;
+ }
+#endif
+ FDKwriteBits(hBs, 7, 3); //finalize AU: ID_END
+ FDKsyncCache(hBs);
+ //byte-align (if ID_FIL doesn't align it).
+ if(FDKgetValidBits(hBs) % 8){
+ writeBits = 8 - (FDKgetValidBits(hBs) % 8);
+ FDKwriteBits(hBs, 0x00, writeBits);
+ FDKsyncCache(hBs);
+ }
+
+ //fake-written bits alignment for last AU
+ if (hDab->currentBlock == hDab->num_raw_blocks)
+ writeBits=writeBitsLastBlock;
+
+ INT frameLen = (FDKgetValidBits(hBs) - hDab->subFrameStartBit) >> 3;
+ //fprintf(stderr, "frame=%d, offset writeBits=%d\n", frameLen, writeBits);
+
+ FDK_ASSERT(FDKgetValidBits(hBs) % 8 == 0); //only aligned au's
+ FDK_ASSERT(hDab->subchannels_num*110*8 >= FDKgetValidBits(hBs)+2*8); //don't overlap superframe
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, hDab->subFrameStartBit);
+ FDKcrcReset(&hDab->crcInfo);
+ hDab->crcIndex = FDKcrcStartReg(&hDab->crcInfo, &bsWriter, 0);
+#if 0
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ INT offset_size = hDab->subchannels_num*110*8 - 2*8 - FDKgetValidBits(hBs);
+ //fprintf(stderr, "offset_size=%d\n", offset_size >> 3);
+ FDKpushFor(hBs, offset_size);
+ }
+#endif
+
+ FDKpushFor(&bsWriter, FDKgetValidBits(hBs) - hDab->subFrameStartBit);
+ FDKcrcEndReg(&hDab->crcInfo, &bsWriter, hDab->crcIndex);
+ crcData = FDKcrcGetCRC(&hDab->crcInfo);
+ //fprintf(stderr, "crcData = %04x\n", crcData);
+ /* Write inverted CRC of current raw data block */
+ FDKwriteBits(hBs, crcData ^ 0xffff, 16);
+ FDKsyncCache(hBs);
+
+
+ /* Write distance to current data block */
+ if(hDab->currentBlock) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 24 + (hDab->currentBlock-1)*12);
+ //fprintf(stderr, "FDKwriteBits() = %d\n", hDab->subFrameStartBit>>3);
+ FDKwriteBits(&bsWriter, (hDab->subFrameStartBit>>3), 12);
+ FDKsyncCache(&bsWriter);
+ }
+
+ /* Write FireCode */
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 16);
+
+ FDKcrcReset(&hDab->crcFire);
+ crcIndex = FDKcrcStartReg(&hDab->crcFire, &bsWriter, 72);
+ FDKpushFor(&bsWriter, 9*8); //9bytes
+ FDKcrcEndReg(&hDab->crcFire, &bsWriter, crcIndex);
+
+ crcData = FDKcrcGetCRC(&hDab->crcFire);
+ //fprintf(stderr, "Firecode: %04x\n", crcData);
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKwriteBits(&bsWriter, crcData, 16);
+ FDKsyncCache(&bsWriter);
+ }
+
+ if (hDab->currentBlock == 0)
+ *pBits += hDab->headerBits;
+ else
+ *pBits += 16;
+
+ *pBits += writeBits + 3; //size: ID_END + alignment
+
+ /* Correct *pBits to reflect the amount of bits of the current subframe */
+ *pBits -= hDab->subFrameStartBit;
+ /* Fixup CRC bits, since they come after each raw data block */
+
+ hDab->currentBlock++;
+ //fprintf(stderr, "dabWrite_EndRawDataBlock() *pBits=%d (%d)\n", *pBits, *pBits >> 3);
+}
+
diff --git a/libMpegTPEnc/src/tpenc_dab.h b/libMpegTPEnc/src/tpenc_dab.h
new file mode 100644
index 0000000..17b83c6
--- /dev/null
+++ b/libMpegTPEnc/src/tpenc_dab.h
@@ -0,0 +1,217 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/******************************** MPEG Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport writer
+
+******************************************************************************/
+
+#ifndef TPENC_DAB_H
+#define TPENC_DAB_H
+
+
+
+#include "tp_data.h"
+
+#include "FDK_crc.h"
+
+typedef struct {
+ USHORT frame_length;
+ UCHAR dac_rate;
+ UCHAR aac_channel_mode;
+ UCHAR sbr_flag;
+ UCHAR ps_flag;
+ UCHAR mpeg_surround_config;
+ UCHAR num_raw_blocks;
+ UCHAR BufferFullnesStartFlag;
+ int subchannels_num;
+ int headerBits; /*!< Header bit demand for the current raw data block */
+ int currentBlock; /*!< Index of current raw data block */
+ int subFrameStartBit; /*!< Bit position where the current raw data block begins */
+ //int subFrameStartPrev; /*!< Bit position where the previous raw data block begins */
+ int crcIndex;
+ FDK_CRCINFO crcInfo;
+ FDK_CRCINFO crcFire;
+ FDK_CRCINFO crcInfo2;
+ USHORT tab[256];
+} STRUCT_DAB;
+
+typedef STRUCT_DAB *HANDLE_DAB;
+
+/**
+ * \brief Initialize DAB data structure
+ *
+ * \param hDab DAB data handle
+ * \param config a valid CODER_CONFIG struct from where the required
+ * information for the DAB header is extrated from
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_Init(
+ HANDLE_DAB hDab,
+ CODER_CONFIG *config
+ );
+
+/**
+ * \brief Get the total bit overhead caused by DAB
+ *
+ * \hDab handle to DAB data
+ *
+ * \return Amount of additional bits required for the current raw data block
+ */
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab );
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength );
+
+/**
+ * \brief Write an DAB header into the given bitstream. May not write a header
+ * in case of multiple raw data blocks.
+ *
+ * \param hDab DAB data handle
+ * \param hBitStream bitstream handle into which the DAB may be written into
+ * \param buffer_fullness the buffer fullness value for the DAB header
+ * \param the current raw data block length
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_EncodeHeader(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int bufferFullness,
+ int frame_length
+ );
+/**
+ * \brief Finish a DAB raw data block
+ *
+ * \param hDab DAB data handle
+ * \param hBs bitstream handle into which the DAB may be written into
+ * \param pBits a pointer to a integer holding the current bitstream buffer bit count,
+ * which is corrected to the current raw data block boundary.
+ *
+ */
+void dabWrite_EndRawDataBlock(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *bits
+ );
+
+
+/**
+ * \brief Start CRC region with a maximum number of bits
+ * If mBits is positive zero padding will be used for CRC calculation, if there
+ * are less than mBits bits available.
+ * If mBits is negative no zero padding is done.
+ * If mBits is zero the memory for the buffer is allocated dynamically, the
+ * number of bits is not limited.
+ *
+ * \param pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param mBits limit of number of bits to be considered for the requested CRC region
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int mBits
+ );
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param reg a CRC region ID returned previously by dabWrite_CrcStartReg()
+ */
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int reg
+ );
+
+
+
+
+#endif /* TPENC_DAB_H */
+
diff --git a/libMpegTPEnc/src/tpenc_lib.cpp b/libMpegTPEnc/src/tpenc_lib.cpp
index 77c19b5..d241979 100644
--- a/libMpegTPEnc/src/tpenc_lib.cpp
+++ b/libMpegTPEnc/src/tpenc_lib.cpp
@@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de
#include "tpenc_adif.h"
+#include "tpenc_dab.h"
+
#include "tpenc_latm.h"
typedef struct {
@@ -137,6 +139,8 @@ struct TRANSPORTENC {
ADIF_INFO adif;
+ STRUCT_DAB dab;
+
LATM_STREAM latm;
RAWPACKETS_INFO raw;
@@ -215,6 +219,7 @@ static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
FDK_FALLTHROUGH;
case TT_MP4_LOAS: /* PCE in ASC if chChonfig==0 */
case TT_MP4_LATM_MCP1: /* PCE in ASC if chChonfig==0 */
+ case TT_DABPLUS:
default:
pceFrameCounter = -1; /* no PCE in raw_data_block */
}
@@ -233,6 +238,7 @@ static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
case TT_MP4_RAW:
pceFrameCounter = headerPeriod;
break;
+ case TT_DABPLUS:
default:
pceFrameCounter = -1; /* no PCE in raw_data_block */
} /* switch transportFmt */
@@ -295,6 +301,18 @@ TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
}
break;
+ case TT_DABPLUS:
+ /* Sanity checks */
+ if ( ( hTpEnc->config.aot != AOT_AAC_LC)
+ ||(hTpEnc->config.samplesPerFrame != 960) )
+ {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ if ( dabWrite_Init(&hTpEnc->writer.dab, &hTpEnc->config) != 0) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ break;
+
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1: {
@@ -410,6 +428,17 @@ TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
adtsWrite_EncodeHeader(&hTp->writer.adts, &hTp->bitStream, bufferFullness,
frameUsedBits);
break;
+ case TT_DABPLUS:
+ bufferFullness /= ncc; /* Number of Considered Channels */
+ bufferFullness /= 32;
+ bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
+ dabWrite_EncodeHeader(
+ &hTp->writer.dab,
+ &hTp->bitStream,
+ bufferFullness,
+ frameUsedBits
+ );
+ break;
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -478,6 +507,9 @@ TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
case TT_MP4_ADTS:
adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
break;
+ case TT_DABPLUS:
+ dabWrite_EndRawDataBlock(&hTp->writer.dab, &hTp->bitStream, bits);
+ break;
case TT_MP4_ADIF:
/* Substract ADIF header from AU bits, not to be considered. */
*bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
@@ -514,6 +546,14 @@ TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
*nbytes = 0;
}
break;
+ case TT_DABPLUS:
+ if (hTpEnc->writer.dab.currentBlock >= hTpEnc->writer.dab.num_raw_blocks+1) {
+ *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
+ hTpEnc->writer.dab.currentBlock = 0;
+ } else {
+ *nbytes = 0;
+ }
+ break;
case TT_MP4_ADIF:
FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
*nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
@@ -551,6 +591,9 @@ INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits) {
case TT_MP4_ADTS:
nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
break;
+ case TT_DABPLUS:
+ nbits = dabWrite_CountTotalBitDemandHeader(&hTp->writer.dab, auBits);
+ break;
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -585,6 +628,9 @@ int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits) {
crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream,
mBits);
break;
+ case TT_DABPLUS:
+ crcReg = dabWrite_CrcStartReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, mBits);
+ break;
default:
break;
}
@@ -597,6 +643,9 @@ void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg) {
case TT_MP4_ADTS:
adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
break;
+ case TT_DABPLUS:
+ dabWrite_CrcEndReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, reg);
+ break;
default:
break;
}
@@ -658,7 +707,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
/* Set flags */
info->flags =
- 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS;
+ 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS | CAPF_DAB_AAC;
return TRANSPORTENC_OK;
}