diff options
author | Dave Burke <daveburke@google.com> | 2012-05-12 13:17:25 -0700 |
---|---|---|
committer | Dave Burke <daveburke@google.com> | 2012-05-12 13:47:46 -0700 |
commit | 698b536f3b34a7cfc41a80e1034cc359456bdd66 (patch) | |
tree | fa3dfa75d535b188725f1b84316cb4b06db79771 /libMpegTPDec/src | |
parent | 9bf37cc9712506b2483650c82d3c41152337ef7e (diff) | |
download | fdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.tar.gz fdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.tar.bz2 fdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.zip |
Update to 2012_05_11 version.
Fixes:
- Don't throw error for invalid bitrate but limit to functional value
- More robust ASC parsing
- More robust handling of corrupt bitstreams
- Handle multiple raw access units
Change-Id: Ib49fe2545ff4185fe924126da702fe84ac5c2d87
Diffstat (limited to 'libMpegTPDec/src')
-rw-r--r-- | libMpegTPDec/src/tpdec_asc.cpp | 101 | ||||
-rw-r--r-- | libMpegTPDec/src/tpdec_latm.cpp | 3 | ||||
-rw-r--r-- | libMpegTPDec/src/tpdec_lib.cpp | 28 |
3 files changed, 30 insertions, 102 deletions
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index ee7c7cf..3553398 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -382,11 +382,19 @@ int CProgramConfig_LookupElement( #ifdef TP_PCE_ENABLE int CProgramConfig_GetElementTable( const CProgramConfig *pPce, - MP4_ELEMENT_ID elList[] + MP4_ELEMENT_ID elList[], + const INT elListSize ) { int i, el = 0; + if ( elListSize + < pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements + ) + { + return 0; + } + for (i=0; i < pPce->NumFrontChannelElements; i++) { elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE; @@ -619,94 +627,6 @@ bail: #endif /* TP_ELD_ENABLE */ -static -TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) -{ - TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN; - INT bitsAvailable = (INT)FDKgetValidBits(bs); - - while (bitsAvailable >= 11) - { - lastAscExt = ascExtId; - ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11); - bitsAvailable -= 11; - - switch (ascExtId) { - case ASCEXT_SBR: /* 0x2b7 */ - if ( (self->m_extensionAudioObjectType != AOT_SBR) && (bitsAvailable >= 5) ) { - self->m_extensionAudioObjectType = getAOT(bs); - - if ( (self->m_extensionAudioObjectType == AOT_SBR) - || (self->m_extensionAudioObjectType == AOT_ER_BSAC) ) - { /* Get SBR extension configuration */ - self->m_sbrPresentFlag = FDKreadBits(bs, 1); - bitsAvailable -= 1; - - if ( self->m_sbrPresentFlag == 1 ) { - self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4); - - if ((INT)self->m_extensionSamplingFrequency <= 0) { - return TRANSPORTDEC_PARSE_ERROR; - } - } - if ( self->m_extensionAudioObjectType == AOT_ER_BSAC ) { - self->m_extensionChannelConfiguration = FDKreadBits(bs, 4); - bitsAvailable -= 4; - } - } - /* Update counter because of variable length fields (AOT and sampling rate) */ - bitsAvailable = (INT)FDKgetValidBits(bs); - } - break; - case ASCEXT_PS: /* 0x548 */ - if ( (lastAscExt == ASCEXT_SBR) - && (self->m_extensionAudioObjectType == AOT_SBR) - && (bitsAvailable > 0) ) - { /* Get PS extension configuration */ - self->m_psPresentFlag = FDKreadBits(bs, 1); - bitsAvailable -= 1; - } - break; - case ASCEXT_MPS: /* 0x76a */ - if ( self->m_extensionAudioObjectType == AOT_MPEGS ) - break; - case ASCEXT_LDMPS: /* 0x7cc */ - if ( (ascExtId == ASCEXT_LDMPS) - && (self->m_extensionAudioObjectType == AOT_LD_MPEGS) ) - break; - if (bitsAvailable >= 1) - { - bitsAvailable -= 1; - if ( FDKreadBits(bs, 1) ) { /* self->m_mpsPresentFlag */ - int sscLen = FDKreadBits(bs, 8); - bitsAvailable -= 8; - if (sscLen == 0xFF) { - sscLen += FDKreadBits(bs, 16); - bitsAvailable -= 16; - } - if (cb->cbSsc != NULL) { - cb->cbSsc( - cb->cbSscData, - bs, - self->m_aot, - self->m_samplingFrequency, - 1, - sscLen - ); - } else - FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next extension if there is one. */ - - bitsAvailable -= sscLen*8; - } - } - break; - default: - return TRANSPORTDEC_UNSUPPORTED_FORMAT; - } - } - - return TRANSPORTDEC_OK; -} /* * API Functions @@ -857,9 +777,6 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( break; } - if (fExplicitBackwardCompatible) { - ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb); - } return (ErrorStatus); } diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index 28daebc..71e35a7 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -315,9 +315,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLa else { ErrorStatus = TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_TIMEFRAMING; } - if ((INT)FDKgetValidBits(bs) < totalPayloadBits) { - return TRANSPORTDEC_NOT_ENOUGH_BITS; - } if (pLatmDemux->m_audioMuxLengthBytes > 0 && totalPayloadBits > pLatmDemux->m_audioMuxLengthBytes*8) { return TRANSPORTDEC_PARSE_ERROR; } diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 4387847..e179678 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -85,6 +85,7 @@ struct TRANSPORTDEC #define TPDEC_IGNORE_BUFFERFULLNESS 4 #define TPDEC_EARLY_CONFIG 8 #define TPDEC_LOST_FRAMES_PENDING 16 +#define TPDEC_CONFIG_FOUND 32 C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1) C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE) @@ -177,11 +178,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * } } break; + default: case TT_MP4_RAW: err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks); break; - default: - return TRANSPORTDEC_UNSUPPORTED_FORMAT; } if (err == TRANSPORTDEC_OK) { int errC; @@ -192,6 +192,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * } } + if (err == TRANSPORTDEC_OK) { + hTp->flags |= TPDEC_CONFIG_FOUND; + } + return err; } @@ -439,6 +443,14 @@ TRANSPORTDEC_ERROR synchronization( totalBits = (INT)FDKgetValidBits(hBs); + if (totalBits <= 0) { + /* Return sync error, because this happens only in case of severly damaged bit streams. + Returning TRANSPORTDEC_NOT_ENOUGH_BITS here is very dangerous. */ + /* numberOfRawDataBlocks must be always reset in case of sync errors. */ + hTp->numberOfRawDataBlocks = 0; + goto bail; + } + fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK); /* Set transport specific sync parameters */ @@ -625,13 +637,15 @@ TRANSPORTDEC_ERROR synchronization( if (err == TRANSPORTDEC_SYNC_ERROR) { int bits; - FDK_ASSERT(hTp->numberOfRawDataBlocks == 0); + /* Enforce re-sync of transport headers. */ + hTp->numberOfRawDataBlocks = 0; + /* Ensure that the bit amount lands and a multiple of TPDEC_SYNCSKIP */ bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP; /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */ FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits); bitsAvail += headerBits - TPDEC_SYNCSKIP - bits; - headerBits = 0; + headerBits = 0; } /* Frame traversal */ @@ -710,6 +724,7 @@ TRANSPORTDEC_ERROR synchronization( err = TRANSPORTDEC_OK; } +bail: hTp->auLength[0] = rawDataBlockLength; if (err == TRANSPORTDEC_OK) { @@ -852,7 +867,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c case TT_MP4_ADIF: /* Read header if not already done */ - if (!(hTp->flags & TPDEC_SYNCOK)) + if (!(hTp->flags & TPDEC_CONFIG_FOUND)) { CProgramConfig *pce; @@ -876,8 +891,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]); if (errC == 0) { - /* Misuse sync flag to parse header only once. */ - hTp->flags |= TPDEC_SYNCOK; + hTp->flags |= TPDEC_CONFIG_FOUND; } else { err = TRANSPORTDEC_PARSE_ERROR; goto bail; |