diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index d388576..458fda1 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index a0c0854..7ab60f1 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -378,6 +378,7 @@ typedef enum { not exist. */ AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be performed. */ + AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */ aac_dec_init_error_end = 0x2FFF, /* Decode errors. Output buffer is valid but concealed. */ diff --git a/libAACdec/src/aac_rom.cpp b/libAACdec/src/aac_rom.cpp index 607cb3b..f3c9b5a 100644 --- a/libAACdec/src/aac_rom.cpp +++ b/libAACdec/src/aac_rom.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -167,6 +167,36 @@ const SCHAR ExponentTable [4][14] = } ; +/* 41 scfbands */ +static const SHORT sfb_96_1024[42] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, + 48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, + 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640, + 704, 768, 832, 896, 960, 1024 +}; +/* 12 scfbands */ +static const SHORT sfb_96_128[13] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, + 128 +}; + +/* 47 scfbands*/ +static const SHORT sfb_64_1024[48] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240, + 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, + 824, 864, 904, 944, 984,1024 +}; + +/* 12 scfbands */ +static const SHORT sfb_64_128[13] = +{ + 0, 4, 8, 12, 16, 20, 24, + 32, 40, 48, 64, 92, 128 +}; /* 49 scfbands */ static const SHORT sfb_48_1024[50] = { @@ -239,6 +269,35 @@ static const SHORT sfb_8_128[16] = }; +static const SHORT sfb_96_960[42] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 156, 172, 188, 212, 240, 276, + 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, + 960 +}; /* 40 scfbands */ + +static const SHORT sfb_96_120[13] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, + 64, 92, 120 +}; /* 12 scfbands */ + +static const SHORT sfb_64_960[47] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 100, + 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, + 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, + 744, 784, 824, 864, 904, 944, 960 +}; /* 46 scfbands */ + +static const SHORT sfb_64_120[13] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, + 64, 92, 120 +}; /* 12 scfbands */ static const SHORT sfb_48_960[50] = { @@ -358,9 +417,9 @@ static const SHORT sfb_24_480[31] = const SFB_INFO sfbOffsetTables[5][16] = { { - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, + { sfb_96_1024, sfb_96_128, 41, 12 }, + { sfb_96_1024, sfb_96_128, 41, 12 }, + { sfb_64_1024, sfb_64_128, 47, 12 }, { sfb_48_1024, sfb_48_128, 49, 14 }, { sfb_48_1024, sfb_48_128, 49, 14 }, { sfb_32_1024, sfb_48_128, 51, 14 }, @@ -372,9 +431,9 @@ const SFB_INFO sfbOffsetTables[5][16] = { sfb_8_1024, sfb_8_128, 40, 15 }, { sfb_8_1024, sfb_8_128, 40, 15 }, }, { - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, + { sfb_96_960, sfb_96_120, 40, 12 }, + { sfb_96_960, sfb_96_120, 40, 12 }, + { sfb_64_960, sfb_64_120, 46, 12 }, { sfb_48_960, sfb_48_120, 49, 14 }, { sfb_48_960, sfb_48_120, 49, 14 }, { sfb_32_960, sfb_48_120, 49, 14 }, @@ -388,9 +447,9 @@ const SFB_INFO sfbOffsetTables[5][16] = }, { { NULL, NULL, 0, 0 }, }, { - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, + { sfb_48_512, NULL, 36, 0 }, + { sfb_48_512, NULL, 36, 0 }, + { sfb_48_512, NULL, 36, 0 }, { sfb_48_512, NULL, 36, 0 }, { sfb_48_512, NULL, 36, 0}, { sfb_32_512, NULL, 37, 0 }, @@ -402,9 +461,9 @@ const SFB_INFO sfbOffsetTables[5][16] = { sfb_24_512, NULL, 31, 0 }, { sfb_24_512, NULL, 31, 0 }, }, { - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, + { sfb_48_480, NULL, 35, 0 }, + { sfb_48_480, NULL, 35, 0 }, + { sfb_48_480, NULL, 35, 0 }, { sfb_48_480, NULL, 35, 0 }, { sfb_48_480, NULL, 35, 0 }, { sfb_32_480, NULL, 37, 0 }, diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 8270f69..579e470 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -157,6 +157,7 @@ amm-info@iis.fraunhofer.de #include "conceal.h" + #include "FDK_crc.h" void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) @@ -537,8 +538,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, previous_element, elIndex, self->flags & AC_INDEP ); - /* Enable SBR for implicit SBR signalling. */ - if (sbrError == SBRDEC_OK) { + /* Enable SBR for implicit SBR signalling but only if no severe error happend. */ + if ( (sbrError == SBRDEC_OK) + || (sbrError == SBRDEC_PARSE_ERROR) ) { self->sbrEnabled = 1; } } else { @@ -553,7 +555,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, FDKpushBiDirectional(hBs, *count); *count = 0; } else { - /* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */ + /* If this is not a fill element with a known length, we are screwed and further parsing makes no sense. */ if (sbrError != SBRDEC_OK) { self->frameOK = 0; } @@ -832,12 +834,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS switch (asc->m_aot) { case AOT_AAC_LC: self->streamInfo.profile = 1; - break; + + case AOT_ER_AAC_SCAL: + if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) { + /* aac_scalable_extension_element() currently not supported. */ + return AAC_DEC_UNSUPPORTED_FORMAT; + } case AOT_SBR: case AOT_PS: case AOT_ER_AAC_LD: case AOT_ER_AAC_ELD: + case AOT_DRM_AAC: break; default: @@ -957,11 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS if (asc->m_aot == AOT_ER_AAC_ELD) { self->flags |= AC_ELD; + self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; /* Need to set the SBR flag for backward-compatibility + reasons. Even if SBR is not supported. */ self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0; } self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0; + if ( asc->m_aot == AOT_DRM_AAC ) { + self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE; + } + if ( (asc->m_aot == AOT_AAC_SCAL) + || (asc->m_aot == AOT_ER_AAC_SCAL) ) { + self->flags |= AC_SCALABLE; + } if (asc->m_sbrPresentFlag) { @@ -1147,6 +1164,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* Check sampling frequency */ switch ( self->streamInfo.aacSampleRate ) { + case 96000: + case 88200: + case 64000: case 16000: case 12000: case 11025: @@ -1475,7 +1495,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* get the remaining bits of this frame */ bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0); - if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) ) + if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) ) { SBR_ERROR err = SBRDEC_OK; int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE]; @@ -1513,6 +1533,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( } + if (self->flags & AC_DRM) + { + if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) { + FDKpushBiDirectional(bs, bitCnt); + } + } + if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) ) { while ( bitCnt > 7 ) { diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index 3541773..25bc35d 100644 --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -226,6 +226,8 @@ struct AAC_DECODER_INSTANCE { FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */ + INT_PCM pcmOutputBuffer[(8)*(2048)]; + }; diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index b501eb9..8863da5 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL1 5 -#define AACDECODER_LIB_VL2 11 +#define AACDECODER_LIB_VL2 17 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" @@ -181,8 +181,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw ( break; } /* if baselayer is OK we continue decoding */ - if(layer >= 1){ + if(layer >= 1){ self->nrOfLayers = layer; + err = AAC_DEC_OK; } break; } @@ -785,8 +786,8 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( HANDLE_AACDECODER self, - INT_PCM *pTimeData, - const INT timeDataSize, + INT_PCM *pTimeData_extern, + const INT timeDataSize_extern, const UINT flags) { AAC_DECODER_ERROR ErrorStatus; @@ -796,12 +797,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( HANDLE_FDK_BITSTREAM hBs; int fTpInterruption = 0; /* Transport originated interruption detection. */ int fTpConceal = 0; /* Transport originated concealment. */ + INT_PCM *pTimeData = NULL; + INT timeDataSize = 0; if (self == NULL) { return AAC_DEC_INVALID_HANDLE; } + pTimeData = self->pcmOutputBuffer; + timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer); + if (flags & AACDEC_INTR) { self->streamInfo.numLostAccessUnits = 0; } @@ -918,7 +924,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( if (self->sbrEnabled) { SBR_ERROR sbrError = SBRDEC_OK; - int chOutMapIdx = ((self->chMapIndex==0) && (self->streamInfo.numChannels<7)) ? self->streamInfo.numChannels : self->chMapIndex; + int chIdx, numCoreChannel = self->streamInfo.numChannels; + int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex; /* set params */ sbrDecoder_SetParam ( self->hSbrDecoder, @@ -978,10 +985,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( if (self->psPossible) { self->flags |= AC_PS_PRESENT; - self->channelType[0] = ACT_FRONT; - self->channelType[1] = ACT_FRONT; - self->channelIndices[0] = 0; - self->channelIndices[1] = 1; + } + for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) { + self->channelType[chIdx] = ACT_FRONT; + self->channelIndices[chIdx] = chIdx; } } } @@ -1006,7 +1013,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->channelOutputMapping, (self->limiterEnableCurr) ? &pcmLimiterScale : NULL ); - if (dmxErr == PCMDMX_INVALID_MODE) { + if ( (ErrorStatus == AAC_DEC_OK) + && (dmxErr == PCMDMX_INVALID_MODE) ) { /* Announce the framework that the current combination of channel configuration and downmix * settings are not know to produce a predictable behavior and thus maybe produce strange output. */ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; @@ -1051,6 +1059,19 @@ bail: /* Update Statistics */ aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus); + /* Check whether external output buffer is large enough. */ + if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) { + ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; + } + + /* Update external output buffer. */ + if ( IS_OUTPUT_VALID(ErrorStatus) ) { + FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData)); + } + else { + FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern)); + } + return ErrorStatus; } @@ -1120,6 +1141,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info ) /* Set flags */ info->flags = 0 | CAPF_AAC_LC + | CAPF_ER_AAC_SCAL | CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC @@ -1130,6 +1152,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info ) | CAPF_AAC_MPEG4 + | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 | CAPF_AAC_960 diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp index 9d703cc..2965fa6 100644 --- a/libAACdec/src/block.cpp +++ b/libAACdec/src/block.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -324,11 +324,11 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs, if (flags & AC_ER_HCR) { /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */ - pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band]; - numLinesInSecIdx++; if (numLinesInSecIdx >= MAX_SFB_HCR) { return AAC_DEC_PARSE_ERROR; } + pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band]; + numLinesInSecIdx++; if ( (sect_cb == BOOKSCL) ) { diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index f4b510d..1d8ac7b 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de /* FDK tools library info */ #define FDK_TOOLS_LIB_VL0 2 #define FDK_TOOLS_LIB_VL1 3 -#define FDK_TOOLS_LIB_VL2 5 +#define FDK_TOOLS_LIB_VL2 6 #define FDK_TOOLS_LIB_TITLE "FDK Tools" #ifdef __ANDROID__ #define FDK_TOOLS_LIB_BUILD_DATE "" diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp index 49f0ee1..29e37f2 100644 --- a/libFDK/src/FDK_tools_rom.cpp +++ b/libFDK/src/FDK_tools_rom.cpp @@ -2236,7 +2236,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = { ics_info, ms, ltp_data_present, - ltp_data, + /* ltp_data, */ global_gain, section_data, scale_factor_data, @@ -2247,7 +2247,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = { next_channel, ltp_data_present, - ltp_data, + /* ltp_data, */ global_gain, section_data, scale_factor_data, @@ -2290,7 +2290,178 @@ static const element_list_t node_aac_cpe_epc1 = { { &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 } }; +/* + * AOT = 20 + * epConfig = 0 + */ +static const rbd_id_t el_scal_sce_epc0[] = { + ics_info, /* ESC 1 */ + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 */ + tns_data, /* ESC 3 */ + spectral_data, /* ESC 4 */ + end_of_sequence +}; +static const struct element_list node_scal_sce_epc0 = { + el_scal_sce_epc0, + { NULL, NULL } +}; + +static const rbd_id_t el_scal_cpe_epc0[] = { + ics_info, /* ESC 0 */ + ms, + tns_data_present, /* ESC 1 (ch 0) */ + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 (ch 0) */ + tns_data, /* ESC 3 (ch 0) */ + spectral_data, /* ESC 4 (ch 0) */ + next_channel, + tns_data_present, /* ESC 1 (ch 1) */ + ltp_data_present, + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 (ch 1) */ + tns_data, /* ESC 3 (ch 1) */ + spectral_data, /* ESC 4 (ch 1) */ + end_of_sequence +}; + +static const struct element_list node_scal_cpe_epc0 = { + el_scal_cpe_epc0, + { NULL, NULL } +}; + +/* + * AOT = 20 + * epConfig = 1 + */ +static const rbd_id_t el_scal_sce_epc1[] = { + ics_info, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + tns_data, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_scal_sce_epc1 = { + el_scal_sce_epc1, + { NULL, NULL } +}; + +static const rbd_id_t el_scal_cpe_epc1[] = { + ics_info, + ms, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data, + next_channel, + tns_data, + next_channel, + spectral_data, + next_channel, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_scal_cpe_epc1 = { + el_scal_cpe_epc1, + { NULL, NULL } +}; + +/* + * Pseudo AOT for DRM/DRM+ (similar to AOT 20) + * Derived from epConfig = 1 + */ +static const rbd_id_t el_drm_sce[] = { + drmcrc_start_reg, + ics_info, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + tns_data, + drmcrc_end_reg, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_drm_sce = { + el_drm_sce, + { NULL, NULL } +}; + +static const rbd_id_t el_drm_cpe[] = { + drmcrc_start_reg, + ics_info, + ms, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data, + next_channel, + tns_data, + drmcrc_end_reg, + next_channel, + spectral_data, + next_channel, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_drm_cpe = { + el_drm_cpe, + { NULL, NULL } +}; /* * AOT = 39 @@ -2405,6 +2576,19 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo return &node_aac_cpe_epc1; } break; + case AOT_ER_AAC_SCAL: + if (nChannels == 1) { + if (epConfig <= 0) + return &node_scal_sce_epc0; + else + return &node_scal_sce_epc1; + } else { + if (epConfig <= 0) + return &node_scal_cpe_epc0; + else + return &node_scal_cpe_epc1; + } + break; case AOT_ER_AAC_ELD: if (nChannels == 1) { if (epConfig <= 0) @@ -2417,6 +2601,16 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo else return &node_eld_cpe_epc1; } + case AOT_DRM_AAC: + case AOT_DRM_SBR: + case AOT_DRM_MPEG_PS: + FDK_ASSERT(epConfig == 1); + if (nChannels == 1) { + return &node_drm_sce; + } else { + return &node_drm_cpe; + } + break; default: break; } diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index bae271e..96a1b35 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1126,6 +1126,8 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse( if ( 0 != ld_sbr_header(asc, hBs, cb) ) { return TRANSPORTDEC_PARSE_ERROR; } + } else { + return TRANSPORTDEC_UNSUPPORTED_FORMAT; } } esc->m_useLdQmfTimeAlign = 0; @@ -1146,7 +1148,7 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse( switch (eldExtType) { default: - for(cnt=0; cntm_samplingFrequencyIndex = sfIdx; + self->m_samplingFrequency = SamplingRateTable[sfIdx]; + + if ( sbrFlag ) { + UINT i; + int tmp = -1; + self->m_sbrPresentFlag = 1; + self->m_extensionAudioObjectType = AOT_SBR; + self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1; + for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){ + if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){ + tmp = i; + break; + } + } + self->m_extensionSamplingFrequencyIndex = tmp; + } + + switch (audioCoding) { + case 0: /* AAC */ + self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */ + + switch (audioMode) { + case 1: /* parametric stereo */ + self->m_psPresentFlag = 1; + case 0: /* mono */ + self->m_channelConfiguration = 1; + break; + case 2: /* stereo */ + self->m_channelConfiguration = 2; + break; + default: + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + self->m_vcb11Flag = 1; + self->m_hcrFlag = 1; + self->m_samplesPerFrame = 960; + self->m_epConfig = 1; + break; + case 1: /* CELP */ + self->m_aot = AOT_ER_CELP; + self->m_channelConfiguration = 1; + break; + case 2: /* HVXC */ + self->m_aot = AOT_ER_HVXC; + self->m_channelConfiguration = 1; + break; + case 3: /* reserved */ + default: + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + self->m_aot = AOT_NONE; + break; + } + + if (self->m_psPresentFlag && !self->m_sbrPresentFlag) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + } + +bail: + return (ErrorStatus); +} diff --git a/libMpegTPDec/src/tpdec_drm.cpp b/libMpegTPDec/src/tpdec_drm.cpp new file mode 100644 index 0000000..df319e5 --- /dev/null +++ b/libMpegTPDec/src/tpdec_drm.cpp @@ -0,0 +1,146 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 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-4 AAC Decoder ************************** + + Author(s): Christian Griebel + Description: DRM transport stuff + +******************************************************************************/ + +#include "tpdec_drm.h" + + +#include "FDK_bitstream.h" + + + +void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */ +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcInit(&pDrm->crcInfo, 0x001d, 0xFFFF, 8); +} + +int drmRead_CrcStartReg( + HANDLE_DRM pDrm, /*!< pointer to drm stucture */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ + int mBits /*!< number of bits in crc region */ + ) +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcReset(&pDrm->crcInfo); + + pDrm->crcReadValue = FDKreadBits(hBs, 8); + + return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) ); + +} + +void drmRead_CrcEndReg( + HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ + int reg /*!< crc region */ + ) +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcEndReg(&pDrm->crcInfo, hBs, reg); +} + +TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm ) +{ + TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; + USHORT crc; + + crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF; + if (crc != pDrm->crcReadValue) + { + return (TRANSPORTDEC_CRC_ERROR); + } + + return (ErrorStatus); +} + + diff --git a/libMpegTPDec/src/tpdec_drm.h b/libMpegTPDec/src/tpdec_drm.h new file mode 100644 index 0000000..2161b4c --- /dev/null +++ b/libMpegTPDec/src/tpdec_drm.h @@ -0,0 +1,194 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 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-4 AAC Decoder ************************** + + Author(s): Josef Hoepfl + Description: DRM interface + +******************************************************************************/ + +#ifndef TPDEC_DRM_H +#define TPDEC_DRM_H + +#include "tpdec_lib.h" + + +#include "FDK_crc.h" + +typedef struct { + + FDK_CRCINFO crcInfo; /* CRC state info */ + USHORT crcReadValue; /* CRC value read from bitstream data */ + +} STRUCT_DRM; + +typedef STRUCT_DRM *HANDLE_DRM; + +/*! + \brief Initialize DRM CRC + + The function initialzes the crc buffer and the crc lookup table. + + \return none +*/ +void drmRead_CrcInit( HANDLE_DRM pDrm ); + +/** + * \brief Starts 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 pDrm DRM data handle + * \param hBs bitstream handle, on which the CRC region referes to + * \param mBits max number of bits in crc region to be considered + * + * \return ID for the created region, -1 in case of an error + */ +int drmRead_CrcStartReg( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM hBs, + int mBits + ); + +/** + * \brief Ends CRC region identified by reg + * + * \param pDrm DRM data handle + * \param hBs bitstream handle, on which the CRC region referes to + * \param reg CRC regions ID returned by drmRead_CrcStartReg() + * + * \return none + */ +void drmRead_CrcEndReg( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM hBs, + int reg + ); + +/** + * \brief Check CRC + * + * Checks if the currently calculated CRC matches the CRC field read from the bitstream + * Deletes all CRC regions. + * + * \param pDrm DRM data handle + * + * \return Returns 0 if they are identical otherwise 1 + */ +TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm ); + +/** + * \brief Check if we have a valid DRM frame at the current bitbuffer position + * + * This function assumes enough bits in buffer for the current frame. + * It reads out the header bits to prepare the bitbuffer for the decode loop. + * In case the header bits show an invalid bitstream/frame, the whole frame is skipped. + * + * \param pDrm DRM data handle which is filled with parsed DRM header data + * \param bs handle of bitstream from whom the DRM header is read + * + * \return error status + */ +TRANSPORTDEC_ERROR drmRead_DecodeHeader( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM bs + ); + +/** + * \brief Parse a Drm specific SDC audio config from a given bitstream handle. + * + * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct. + * \param hBs Bitstream handle. + * + * \return Total element count including all SCE, CPE and LFE. + */ +TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc, + HANDLE_FDK_BITSTREAM hBs ); + + + +#endif /* TPDEC_DRM_H */ diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 950af64..24f755b 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -102,6 +102,7 @@ amm-info@iis.fraunhofer.de #include "tpdec_latm.h" +#include "tpdec_drm.h" #define MODULE_NAME "transportDec" @@ -113,6 +114,7 @@ typedef union { CLatmDemux latm; + STRUCT_DRM drm; } transportdec_parser_t; @@ -182,6 +184,9 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const hInput->numberOfRawDataBlocks = 0; break; + case TT_DRM: + drmRead_CrcInit(&hInput->parser.drm); + break; case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP1: @@ -253,6 +258,18 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * } } break; + case TT_DRM: + fConfigFound = 1; + err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs); + if (err == TRANSPORTDEC_OK) { + int errC; + + errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + break; } if (err == TRANSPORTDEC_OK && fConfigFound) { @@ -1083,6 +1100,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c break; case TT_MP4_RAW: + case TT_DRM: /* One Access Unit was filled into buffer. So get the length out of the buffer. */ hTp->auLength[layer] = FDKgetValidBits(hBs); @@ -1283,6 +1301,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ) | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS + | CAPF_DRM ; return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */ @@ -1294,6 +1313,8 @@ int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) switch (pTp->transportFmt) { case TT_MP4_ADTS: return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits); + case TT_DRM: + return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits); default: return 0; } @@ -1305,6 +1326,9 @@ void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) case TT_MP4_ADTS: adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg); break; + case TT_DRM: + drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg); + break; default: break; } @@ -1321,6 +1345,9 @@ TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) transportDec_AdjustEndOfAccessUnit(pTp); } return adtsRead_CrcCheck(&pTp->parser.adts); + case TT_DRM: + return drmRead_CrcCheck(&pTp->parser.drm); + break; default: return TRANSPORTDEC_OK; } diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version index 18fc9ba..75e22c9 100644 --- a/libMpegTPDec/src/version +++ b/libMpegTPDec/src/version @@ -2,7 +2,7 @@ /* library info */ #define TP_LIB_VL0 2 #define TP_LIB_VL1 3 -#define TP_LIB_VL2 5 +#define TP_LIB_VL2 7 #define TP_LIB_TITLE "MPEG Transport" #ifdef __ANDROID__ #define TP_LIB_BUILD_DATE "" diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index 174fb5c..3bb9ba3 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -262,6 +262,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self, * into *count if a payload length is given (byPayLen > 0). If no SBR payload length is * given (bsPayLen < 0) then the bit stream position on return will be random after this * function call in case of errors, and any further decoding will be completely pointless. + * This function accepts either normal ordered SBR data or reverse ordered DRM SBR data. * * \param self SBR decoder handle. * \param hBs Bit stream handle as data source. diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index ade57fc..fa5330a 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -151,13 +151,13 @@ typedef struct } ENV_CALC_NRGS; -/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, +static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e, FIXP_DBL *NrgGain, SCHAR *NrgGain_e, int subbands); -/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, +static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, FIXP_DBL **analysBufferImag, int lowSubband, int highSubband, int start_pos, int next_pos, @@ -165,7 +165,7 @@ ENV_CALC_NRGS; FIXP_DBL *nrgEst, SCHAR *nrgEst_e ); -/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, +static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, FIXP_DBL **analysBufferImag, int nSfb, UCHAR *freqBandTable, @@ -174,13 +174,13 @@ ENV_CALC_NRGS; FIXP_DBL *nrg_est, SCHAR *nrg_est_e ); -/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, +static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, FIXP_DBL tmpNoise, SCHAR tmpNoise_e, UCHAR sinePresentFlag, UCHAR sineMapped, int noNoiseFlag); -/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, +static void calcAvgGain(ENV_CALC_NRGS* nrgs, int lowSubband, int highSubband, FIXP_DBL *sumRef_m, @@ -188,7 +188,7 @@ ENV_CALC_NRGS; FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e); -/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, +static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS* nrgs, UCHAR *ptrHarmIndex, int lowSubbands, @@ -196,8 +196,17 @@ ENV_CALC_NRGS; int scale_change, int noNoiseFlag, int *ptrPhaseIndex, - int fCldfb); -/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal, + int scale_diff_low); + +static void adjustTimeSlotLC(FIXP_DBL *ptrReal, + ENV_CALC_NRGS* nrgs, + UCHAR *ptrHarmIndex, + int lowSubbands, + int noSubbands, + int scale_change, + int noNoiseFlag, + int *ptrPhaseIndex); +static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag, HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS* nrgs, @@ -224,7 +233,7 @@ ENV_CALC_NRGS; Additionally, the flags in harmFlagsPrev are being updated by this function for the next frame. */ -/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ +static void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ int nSfb, /*!< Number of bands in the table */ UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */ int *harmFlagsPrev, /*!< Packed 'addHarmonics' */ @@ -990,7 +999,6 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling /* Prevent the smoothing filter from running on constant levels */ if (j-start_pos < smooth_length) smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos]; - else smooth_ratio = FL2FXCONST_SGL(0.0f); @@ -1007,7 +1015,8 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling } else { - adjustTimeSlotLC(&analysBufferReal[j][lowSubband], + if (flags & SBRDEC_ELD_GRID) { + adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs, &h_sbr_cal_env->harmIndex, lowSubband, @@ -1015,7 +1024,18 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling scale_change, noNoiseFlag, &h_sbr_cal_env->phaseIndex, - (flags & SBRDEC_ELD_GRID)); + EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); + } else + { + adjustTimeSlotLC(&analysBufferReal[j][lowSubband], + pNrgs, + &h_sbr_cal_env->harmIndex, + lowSubband, + noSubbands, + scale_change, + noNoiseFlag, + &h_sbr_cal_env->phaseIndex); + } } } // for @@ -1176,7 +1196,7 @@ resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to env can be performed. This function is called once for each envelope before adjusting. */ -/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ +static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ FIXP_DBL *nrgGain, /*!< gains for current envelope */ SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ @@ -1331,7 +1351,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output This function is used when interpolFreq is true. */ -/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ +static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ int lowSubband, /*!< Begin of the SBR frequency range */ int highSubband, /*!< High end of the SBR frequency range */ @@ -1452,7 +1472,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output This function is used when interpolFreq is false. */ -/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ +static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ int nSfb, /*!< Number of scale factor bands */ UCHAR *freqBandTable, /*!< First Subband for each Sfb */ @@ -1585,7 +1605,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output The resulting energy gain is given by mantissa and exponent. */ -/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ +static void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ ENV_CALC_NRGS* nrgs, int i, @@ -1689,7 +1709,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output The result is used as a relative limit for all gains within the current "limiter band" (a certain frequency range). */ -/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, +static void calcAvgGain(ENV_CALC_NRGS* nrgs, int lowSubband, /*!< Begin of the limiter band */ int highSubband, /*!< High end of the limiter band */ FIXP_DBL *ptrSumRef, @@ -1728,21 +1748,101 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output *ptrSumRef_e = sumRef_e; } +static void adjustTimeSlot_EldGrid( + FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ + ENV_CALC_NRGS* nrgs, + UCHAR *ptrHarmIndex, /*!< Harmonic index */ + int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ + int noSubbands, /*!< Number of QMF subbands */ + int scale_change, /*!< Number of bits to shift adjusted samples */ + int noNoiseFlag, /*!< Flag to suppress noise addition */ + int *ptrPhaseIndex, /*!< Start index to random number array */ + int scale_diff_low) /*!< */ +{ + int k; + FIXP_DBL signalReal, sbNoise; + int tone_count = 0; + + FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ + FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ + FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ + + int phaseIndex = *ptrPhaseIndex; + UCHAR harmIndex = *ptrHarmIndex; + + static const INT harmonicPhase [2][4] = { + { 1, 0, -1, 0}, + { 0, 1, 0, -1} + }; + + static const FIXP_DBL harmonicPhaseX [2][4] = { + { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) }, + { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) } + }; + + for (k=0; k < noSubbands; k++) { + + phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); + + if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){ + sbNoise = FL2FXCONST_DBL(0.0f); + } else { + sbNoise = pNoiseLevel[0]; + } + + signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change); + + signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4); + + signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex]; + + *ptrReal = signalReal; + + if (k == 0) { + *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ; + if (k < noSubbands - 1) { + *(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]); + } + } + if (k > 0 && k < noSubbands - 1 && tone_count < 16) { + *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]); + *(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]); + } + if (k == noSubbands - 1 && tone_count < 16) { + if (k > 0) { + *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]); + } + if (k + lowSubband + 1< 63) { + *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]); + } + } + + if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){ + tone_count++; + } + ptrReal++; + pNoiseLevel++; + pGain++; + pSineLevel++; + } + + *ptrHarmIndex = (harmIndex + 1) & 3; + *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1); +} /*! \brief Amplify one timeslot of the signal with the calculated gains and add the noisefloor. */ -/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ +static void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ ENV_CALC_NRGS* nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ int noSubbands, /*!< Number of QMF subbands */ int scale_change, /*!< Number of bits to shift adjusted samples */ int noNoiseFlag, /*!< Flag to suppress noise addition */ - int *ptrPhaseIndex, /*!< Start index to random number array */ - int fCldfb) /*!< CLDFB 80 flag */ + int *ptrPhaseIndex) /*!< Start index to random number array */ { FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ @@ -1775,41 +1875,10 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++; - else if (!noNoiseFlag) /* Add noisefloor to the amplified signal */ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); - if (fCldfb) { - - if (!(harmIndex&0x1)) { - /* harmIndex 0,2 */ - signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel; - *ptrReal++ = signalReal; - } - else { - /* harmIndex 1,3 in combination with freqInvFlag */ - int shift = (int) (scale_change+1); - shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift); - - FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift ); - - FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext); - - - /* save switch and compare operations and reduce to XOR statement */ - if ( ((harmIndex>>1)&0x1)^freqInvFlag) { - *(ptrReal-1) += tmp1; - signalReal -= tmp2; - } else { - *(ptrReal-1) -= tmp1; - signalReal += tmp2; - } - *ptrReal++ = signalReal; - freqInvFlag = !freqInvFlag; - } - - } else { if (!(harmIndex&0x1)) { /* harmIndex 0,2 */ @@ -1933,8 +2002,9 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output *ptrHarmIndex = (harmIndex + 1) & 3; *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); } -void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ - FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ +static void adjustTimeSlotHQ( + FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ + FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS* nrgs, int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ @@ -2137,7 +2207,6 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; int patchBorders[MAX_NUM_PATCHES + 1]; int kx, k2; - FIXP_DBL temp; int lowSubband = freqBandTable[0]; int highSubband = freqBandTable[noFreqBands]; @@ -2169,13 +2238,32 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM while (hiLimIndex <= tempNoLim) { + FIXP_DBL div_m, oct_m, temp; + INT div_e = 0, oct_e = 0, temp_e = 0; + k2 = workLimiterBandTable[hiLimIndex] + lowSubband; kx = workLimiterBandTable[loLimIndex] + lowSubband; - temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */ - temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]); + div_m = fDivNorm(k2, kx, &div_e); + + /* calculate number of octaves */ + oct_m = fLog2(div_m, div_e, &oct_e); + + /* multiply with limiterbands per octave */ + /* values 1, 1.2, 2, 3 -> scale factor of 2 */ + temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e); + + /* overall scale factor of temp ist addition of scalefactors from log2 calculation, + limiter bands scalefactor (2) and limiter bands multiplication */ + temp_e += oct_e + 2; + + /* div can be a maximum of 64 (k2 = 64 and kx = 1) + -> oct can be a maximum of 6 + -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3) + -> we need a scale factor of 5 for comparisson + */ + if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) { - if (temp < FL2FXCONST_DBL (0.49f)>>5) { if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) { workLimiterBandTable[hiLimIndex] = highSubband; nBands--; diff --git a/libSBRdec/src/env_dec.cpp b/libSBRdec/src/env_dec.cpp index 24b2d3b..c65c169 100644 --- a/libSBRdec/src/env_dec.cpp +++ b/libSBRdec/src/env_dec.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -369,7 +369,7 @@ leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d FIXP_SGL step; /* speed of fade */ int i; - int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots; + int currentStartPos = FDKmax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); int currentStopPos = hHeaderData->numberTimeSlots; diff --git a/libSBRdec/src/env_extr.cpp b/libSBRdec/src/env_extr.cpp index 6cb0b99..dacd951 100644 --- a/libSBRdec/src/env_extr.cpp +++ b/libSBRdec/src/env_extr.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -327,7 +327,7 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData, } /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */ - if(hHeaderData->syncState != SBR_ACTIVE || + if(hHeaderData->syncState < SBR_HEADER || lastHeader.startFreq != pBsData->startFreq || lastHeader.stopFreq != pBsData->stopFreq || lastHeader.freqScale != pBsData->freqScale || diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h index ab6b704..0518ea9 100644 --- a/libSBRdec/src/env_extr.h +++ b/libSBRdec/src/env_extr.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -125,6 +125,7 @@ amm-info@iis.fraunhofer.de typedef enum { HEADER_NOT_PRESENT, + HEADER_ERROR, HEADER_OK, HEADER_RESET } @@ -132,10 +133,10 @@ SBR_HEADER_STATUS; typedef enum { - SBR_NOT_INITIALIZED, - UPSAMPLING, - SBR_HEADER, - SBR_ACTIVE + SBR_NOT_INITIALIZED = 0, + UPSAMPLING = 1, + SBR_HEADER = 2, + SBR_ACTIVE = 3 } SBR_SYNC_STATE; @@ -179,6 +180,7 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA; #define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */ #define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */ #define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */ +#define SBRDEC_SYNTAX_DRM 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being used. */ #define SBRDEC_DOWNSAMPLE 8192 /* Flag indicating that the downsampling mode is used. */ #define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */ #define SBRDEC_FORCE_RESET 32768 /* Flag is used to force a reset of all elements in use. */ diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index 1282338..0864348 100644 --- a/libSBRdec/src/sbr_dec.cpp +++ b/libSBRdec/src/sbr_dec.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand } if (resetAnaQmf) { - int qmfErr = qmfInitAnalysisFilterBank ( + QMF_FILTER_BANK prvAnaQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset analysis QMF */ + qmfErr = qmfInitAnalysisFilterBank ( &hSbrDec->AnalysiscQMF, hSbrDec->anaQmfStates, hSbrDec->AnalysiscQMF.no_col, @@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand hSbrDec->AnalysiscQMF.no_channels, anaQmfFlags | QMF_FLAG_KEEP_STATES ); + if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of analysis QMF */ + FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK)); } } if (resetSynQmf) { - int qmfErr = qmfInitSynthesisFilterBank ( + QMF_FILTER_BANK prvSynQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset synthesis QMF */ + qmfErr = qmfInitSynthesisFilterBank ( &hSbrDec->SynthesisQMF, hSbrDec->pSynQmfStates, hSbrDec->SynthesisQMF.no_col, @@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand ); if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of synthesis QMF */ + FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK)); } } } @@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, - const UINT flags + const UINT flags, + const int codecFrameSize ) { int i, slot, reserve; @@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ if (flags & SBRDEC_ELD_GRID) { /* Choose the right low delay filter bank */ changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 ); + + /* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate) + * samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */ + if ( (flags & SBRDEC_LD_MPS_QMF) + && (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) ) + { + INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */ + int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0); + /* Create TMPBUF */ + C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96)); + /* Copy delay samples from INBUF to TMPBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn]; + } + /* Move input signal remainder to the very end of INBUF */ + for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) { + timeIn[smpl+delay] = timeIn[smpl]; + } + /* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + timeIn[smpl*strideIn] = pDlyBuf[smpl]; + } + /* Copy TMPBUF to DLYBUF */ + FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM)); + /* Destory TMPBUF */ + C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96)); + } } /* @@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, { int qmfErr; /* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */ - const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0; + const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0; qmfErr = qmfInitAnalysisFilterBank ( &hs->AnalysiscQMF, @@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, } } + /* Clear input delay line */ + FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM)); + /* assign qmf time slots */ assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP); diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h index 175e7b2..edde637 100644 --- a/libSBRdec/src/sbr_dec.h +++ b/libSBRdec/src/sbr_dec.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -118,6 +118,9 @@ typedef struct FIXP_DBL * WorkBuffer1; FIXP_DBL * WorkBuffer2; + /* Delayed time input signal needed to align CLDFD with LD-MPS QMF. */ + INT_PCM coreDelayBuf[(96)]; + /* QMF filter states */ FIXP_QAS anaQmfStates[(320)]; FIXP_QSS * pSynQmfStates; @@ -182,7 +185,8 @@ sbr_dec (HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, - const UINT flags + const UINT flags, + const int codecFrameSize ); diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h index f12631d..7ab5044 100644 --- a/libSBRdec/src/sbr_ram.h +++ b/libSBRdec/src/sbr_ram.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -135,6 +135,7 @@ struct SBR_DECODER_INSTANCE USHORT codecFrameSize; UCHAR synDownsampleFac; UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */ + UCHAR numFlushedFrames; /* The variable counts the number of frames which are flushed consecutively. */ UINT flags; diff --git a/libSBRdec/src/sbr_rom.cpp b/libSBRdec/src/sbr_rom.cpp index e84c3cd..c48ce35 100644 --- a/libSBRdec/src/sbr_rom.cpp +++ b/libSBRdec/src/sbr_rom.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -189,6 +189,15 @@ const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] = FL2FXCONST_SGL(3.0f / 4.0f) }; +/*! Constants for calculating the number of limiter bands */ +const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] = +{ + FL2FXCONST_DBL(1.0f / 4.0f), + FL2FXCONST_DBL(1.2f / 4.0f), + FL2FXCONST_DBL(2.0f / 4.0f), + FL2FXCONST_DBL(3.0f / 4.0f) +}; + /*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */ const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = { FL2FXCONST_SGL(0.66666666666666f), diff --git a/libSBRdec/src/sbr_rom.h b/libSBRdec/src/sbr_rom.h index c318870..1f800bc 100644 --- a/libSBRdec/src/sbr_rom.h +++ b/libSBRdec/src/sbr_rom.h @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -124,6 +124,7 @@ extern const FIXP_DBL FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRI extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4]; extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4]; +extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2]; extern const FIXP_SGL harmonicPhaseX [2][4]; diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index e15145a..f9ded54 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -128,6 +128,7 @@ amm-info@iis.fraunhofer.de #include "lpp_tran.h" #include "transcendent.h" +#include "FDK_crc.h" #include "sbrdec_drc.h" @@ -137,7 +138,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL1 2 -#define SBRDECODER_LIB_VL2 7 +#define SBRDECODER_LIB_VL2 12 #define SBRDECODER_LIB_TITLE "SBR Decoder" #ifdef __ANDROID__ #define SBRDECODER_LIB_BUILD_DATE "" @@ -194,6 +195,33 @@ static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_ hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi; } +static int compareSbrHeader( const HANDLE_SBR_HEADER_DATA hHdr1, const HANDLE_SBR_HEADER_DATA hHdr2 ) +{ + int result = 0; + + /* compare basic data */ + result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0; + result |= (hHdr1->status != hHdr2->status) ? 1 : 0; + result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0; + result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0; + result |= (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0; + result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0; + result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0; + + /* compare bitstream data */ + result |= FDKmemcmp( &hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS) ); + result |= FDKmemcmp( &hHdr1->bs_info, &hHdr2->bs_info, sizeof(SBR_HEADER_DATA_BS_INFO) ); + + /* compare frequency band data */ + result |= FDKmemcmp( &hHdr1->freqBandData, &hHdr2->freqBandData, (8+MAX_NUM_LIMITERS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableLo, hHdr2->freqBandData.freqBandTableLo, (MAX_FREQ_COEFFS/2+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableHi, hHdr2->freqBandData.freqBandTableHi, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableNoise, hHdr2->freqBandData.freqBandTableNoise, (MAX_NOISE_COEFFS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) ); + + return result; +} + /*! \brief Reset SBR decoder. @@ -391,6 +419,7 @@ int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) case AOT_PS: case AOT_ER_AAC_SCAL: case AOT_ER_AAC_ELD: + case AOT_DRM_AAC: return 1; default: return 0; @@ -463,6 +492,8 @@ SBR_ERROR sbrDecoder_InitElement ( self->flags = 0; self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0; + self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0; + self->flags |= (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL|SBRDEC_SYNTAX_DRM : 0; /* Init SBR elements */ { @@ -928,24 +959,73 @@ SBR_ERROR sbrDecoder_Parse( ) { SBR_DECODER_ELEMENT *hSbrElement; - HANDLE_SBR_HEADER_DATA hSbrHeader; + HANDLE_SBR_HEADER_DATA hSbrHeader = NULL; HANDLE_SBR_CHANNEL *pSbrChannel; SBR_FRAME_DATA *hFrameDataLeft; SBR_FRAME_DATA *hFrameDataRight; SBR_ERROR errorStatus = SBRDEC_OK; - SBR_SYNC_STATE initialSyncState; SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; INT startPos; INT CRCLen = 0; + HANDLE_FDK_BITSTREAM hBsOriginal = hBs; + FDK_CRCINFO crcInfo; /* shall be used for all other CRCs in the future (TBD) */ + INT crcReg = 0; + USHORT drmSbrCrc = 0; int stereo; int fDoDecodeSbrData = 1; int lastSlot, lastHdrSlot = 0, thisHdrSlot; + /* Reverse bits of DRM SBR payload */ + if ( (self->flags & SBRDEC_SYNTAX_DRM) && *count > 0 ) + { + UCHAR *bsBufferDrm = (UCHAR*)self->workBuffer1; + HANDLE_FDK_BITSTREAM hBsBwd = (HANDLE_FDK_BITSTREAM) (bsBufferDrm + (512)); + int dataBytes, dataBits; + + dataBits = *count; + + if (dataBits > ((512)*8)) { + /* do not flip more data than needed */ + dataBits = (512)*8; + } + + dataBytes = (dataBits+7)>>3; + + int j; + + if ((j = (int)FDKgetValidBits(hBs)) != 8) { + FDKpushBiDirectional(hBs, (j-8)); + } + + j = 0; + for ( ; dataBytes > 0; dataBytes--) + { + int i; + UCHAR tmpByte; + UCHAR buffer = 0x00; + + tmpByte = (UCHAR) FDKreadBits(hBs, 8); + for (i = 0; i < 4; i++) { + int shift = 2 * i + 1; + buffer |= (tmpByte & (0x08>>i)) << shift; + buffer |= (tmpByte & (0x10<> shift; + } + bsBufferDrm[j++] = buffer; + FDKpushBack(hBs, 16); + } + + FDKinitBitStream(hBsBwd, bsBufferDrm, (512), dataBits, BS_READER); + + /* Use reversed data */ + hBs = hBsBwd; + bsPayLen = *count; + } + /* Remember start position of SBR element */ startPos = FDKgetValidBits(hBs); @@ -970,7 +1050,6 @@ SBR_ERROR sbrDecoder_Parse( hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; - initialSyncState = hSbrHeader->syncState; /* reset PS flag; will be set after PS was found */ self->flags &= ~SBRDEC_PS_DECODED; @@ -1006,12 +1085,19 @@ SBR_ERROR sbrDecoder_Parse( */ if (fDoDecodeSbrData) { - if (crcFlag == 1) { + if (crcFlag) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: FDKpushFor (hBs, 10); /* check sbrcrc later: we don't know the payload length now */ break; + case AOT_DRM_AAC: + drmSbrCrc = (USHORT)FDKreadBits(hBs, 8); + /* Setup CRC decoder */ + FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8); + /* Start CRC region */ + crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); + break; default: CRCLen = bsPayLen - 10; /* change: 0 => i */ if (CRCLen < 0) { @@ -1056,6 +1142,7 @@ SBR_ERROR sbrDecoder_Parse( hSbrHeader->syncState = SBR_HEADER; } else { hSbrHeader->syncState = SBR_NOT_INITIALIZED; + headerStatus = HEADER_ERROR; } } @@ -1105,7 +1192,7 @@ SBR_ERROR sbrDecoder_Parse( valBits = (INT)FDKgetValidBits(hBs); } - if ( crcFlag == 1 ) { + if ( crcFlag ) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: { @@ -1117,6 +1204,14 @@ SBR_ERROR sbrDecoder_Parse( FDKpushFor(hBs, crcLen); } break; + case AOT_DRM_AAC: + /* End CRC region */ + FDKcrcEndReg(&crcInfo, hBs, crcReg); + /* Check CRC */ + if ((FDKcrcGetCRC(&crcInfo)^0xFF) != drmSbrCrc) { + fDoDecodeSbrData = 0; + } + break; default: break; } @@ -1167,8 +1262,25 @@ SBR_ERROR sbrDecoder_Parse( } bail: - if (errorStatus == SBRDEC_OK) { - if (headerStatus == HEADER_NOT_PRESENT) { + + if ( self->flags & SBRDEC_SYNTAX_DRM ) + { + hBs = hBsOriginal; + } + + if ( (errorStatus == SBRDEC_OK) + || ( (errorStatus == SBRDEC_PARSE_ERROR) + && (headerStatus != HEADER_ERROR) ) ) + { + int useOldHdr = ( (headerStatus == HEADER_NOT_PRESENT) + || (headerStatus == HEADER_ERROR) ) ? 1 : 0; + + if (!useOldHdr && (thisHdrSlot != lastHdrSlot)) { + useOldHdr |= ( compareSbrHeader( hSbrHeader, + &self->sbrHeader[elementIndex][lastHdrSlot] ) == 0 ) ? 1 : 0; + } + + if (useOldHdr != 0) { /* Use the old header for this frame */ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; } else { @@ -1229,12 +1341,21 @@ sbrDecoder_DecodeElement ( int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */ if (self->flags & SBRDEC_FLUSH) { - /* Move frame pointer to the next slot which is up to be decoded/applied next */ - hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1); - /* Update header and frame data pointer because they have already been set */ - hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; - hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; - hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; + if ( self->numFlushedFrames > self->numDelayFrames ) { + int hdrIdx; + /* No valid SBR payload available, hence switch to upsampling (in all headers) */ + for (hdrIdx = 0; hdrIdx < ((1)+1); hdrIdx += 1) { + self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; + } + } + else { + /* Move frame pointer to the next slot which is up to be decoded/applied next */ + hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1); + /* Update header and frame data pointer because they have already been set */ + hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; + hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; + hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; + } } /* Update the header error flag */ @@ -1354,7 +1475,8 @@ sbrDecoder_DecodeElement ( &pSbrChannel[0]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, - self->flags + self->flags, + codecFrameSize ); if (stereo) { @@ -1371,7 +1493,8 @@ sbrDecoder_DecodeElement ( &pSbrChannel[1]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), NULL, - self->flags + self->flags, + codecFrameSize ); } @@ -1387,20 +1510,21 @@ sbrDecoder_DecodeElement ( if ( !(self->flags & SBRDEC_PS_DECODED) ) { /* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */ /* So copy left channel to right channel. */ + int copyFrameSize = codecFrameSize * 2 / self->synDownsampleFac; if (interleaved) { INT_PCM *ptr; INT i; FDK_ASSERT(strideOut == 2); ptr = timeData; - for (i = codecFrameSize; i--; ) + for (i = copyFrameSize>>1; i--; ) { INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */ tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; *ptr++ = tmp; } } else { - FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) ); + FDKmemcpy( timeData+copyFrameSize, timeData, copyFrameSize*sizeof(INT_PCM) ); } } *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */ @@ -1464,14 +1588,23 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, self->flags &= ~SBRDEC_PS_DECODED; } + if ( self->flags & SBRDEC_FLUSH ) { + /* flushing is signalized, hence increment the flush frame counter */ + self->numFlushedFrames++; + } + else { + /* no flushing is signalized, hence reset the flush frame counter */ + self->numFlushedFrames = 0; + } + /* Loop over SBR elements */ for (sbrElementNum = 0; sbrElementNumnumSbrElements; sbrElementNum++) { int numElementChan; if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) { - errorStatus = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; + /* Disable PS and try decoding SBR mono. */ + psPossible = 0; } numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1; @@ -1579,6 +1712,7 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info ) | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG + | CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC ; @@ -1607,6 +1741,9 @@ UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self ) /* Low delay SBR: */ { outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */ + if (flags & SBRDEC_LD_MPS_QMF) { + outputDelay += 32; + } } } else if (!IS_USAC(self->coreCodec)) { diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp index 53abe06..89c422c 100644 --- a/libSYS/src/genericStds.cpp +++ b/libSYS/src/genericStds.cpp @@ -92,14 +92,14 @@ amm-info@iis.fraunhofer.de #define _CRT_SECURE_NO_WARNINGS -#include "genericStds.h" - #include +#include "genericStds.h" + /* library info */ #define SYS_LIB_VL0 1 #define SYS_LIB_VL1 3 -#define SYS_LIB_VL2 7 +#define SYS_LIB_VL2 8 #define SYS_LIB_TITLE "System Integration Library" #ifdef __ANDROID__ #define SYS_LIB_BUILD_DATE ""