| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| /* |
| |
| Pathname: ./src/get_audio_specific_config.c |
| |
| ------------------------------------------------------------------------------ |
| REVISION HISTORY |
| |
| Description: Modified per review comments |
| |
| Description: Modified per second review comments |
| (1) change audioObjectType to Int |
| (2) do not set pVars->prog_config.profile |
| (3) clean up status flag, default to SUCCESS |
| (4) fix multiple lines comments |
| |
| Description: Change getbits.h to ibstream.h |
| |
| Description: Modified per review comments |
| (1) updated revision history |
| (2) declare audioObjectType as enum type |
| |
| Description: Replace some instances of getbits to get9_n_lessbits |
| when the number of bits read is 9 or less. |
| |
| Description: Added support for backward and non-backward (explicit) |
| mode for Parametric Stereo (PS) used in enhanced AAC+ |
| |
| Who: Date: |
| Description: |
| |
| ------------------------------------------------------------------------------ |
| INPUT AND OUTPUT DEFINITIONS |
| |
| Inputs: |
| pVars = pointer to the structure that holds all information for |
| this instance of the library. pVars->prog_config is directly |
| used, and pVars->mc_info, pVars->prog_config, |
| pVars->pWinSeqInfo, pVars->SFBWidth128 are needed indirectly |
| for calling set_mc_info. Data type pointer to tDec_Int_File |
| |
| Local Stores/Buffers/Pointers Needed: |
| None |
| |
| Global Stores/Buffers/Pointers Needed: |
| None |
| |
| Outputs: |
| status = 0 if successfully decoded AudioSpecificConfig |
| 1 if un-supported config is used for this release |
| |
| Pointers and Buffers Modified: |
| pVars->prog_config contents are updated with the information read in. |
| pVars->mc_info contents are updated with channel information. |
| pVars->pWinSeqInfo contents are updated with window information. |
| pVars->SFBWidth128 contents are updated with scale factor band width data. |
| |
| Local Stores Modified: |
| None |
| |
| Global Stores Modified: |
| None |
| |
| ------------------------------------------------------------------------------ |
| FUNCTION DESCRIPTION |
| |
| This function reads the bitstream for the structure "AudioSpecificConfig", |
| and sets the decoder configuration that is needed by the decoder to be able |
| to decode the media properly. |
| |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| This function shall not use global variables |
| |
| ------------------------------------------------------------------------------ |
| REFERENCES |
| |
| (1) ISO/IEC 14496-3: 1999(E) |
| Part 3 |
| Subpart 1 p18 1.6 Interface to MPEG-4 Systems |
| Subpart 4 p13 4.4.1 GA Specific Configuration |
| Amendment p10 6.2.1 AudioSpecificInfo |
| Amendment p78 8.2 Decoder configuration (GASpecificConfig) |
| |
| (2) AAC DecoderSpecificInfo Information |
| PacketVideo descriptions - San Diego |
| |
| ------------------------------------------------------------------------------ |
| PSEUDO-CODE |
| |
| status = SUCCESS; |
| |
| pInputStream = &(pVars->inputStream); |
| |
| temp = CALL getbits( |
| neededBits = LEN_OBJ_TYPE + LEN_SAMP_RATE_IDX, |
| pInputStream = pInputStream) |
| MODIFYING (pInputStream) |
| RETURNING (temp) |
| |
| audioObjectType = (temp & 0x1f0) >> 4; |
| |
| pVars->prog_config.profile = audioObjectType; |
| |
| pVars->prog_config.sampling_rate_idx = temp & 0xf; |
| |
| IF (pVars->prog_config.sampling_rate_idx == 0xf) |
| THEN |
| sampling_rate = CALL getbits( |
| neededBits = LEN_SAMP_RATE, |
| pInputStream = pInputStream); |
| MODIFYING (pInputStream) |
| RETURNING (sampling_rate) |
| ENDIF |
| |
| channel_config = CALL getbits( |
| neededBits = LEN_CHAN_CONFIG, |
| pInputStream = pInputStream); |
| MODIFYING (pInputStream) |
| RETURNING (channel_config) |
| |
| IF (channel_config > 2) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (((audioObjectType == MP4AUDIO_AAC_MAIN) OR |
| (audioObjectType == MP4AUDIO_AAC_LC) OR |
| (audioObjectType == MP4AUDIO_AAC_SSR) OR |
| (audioObjectType == MP4AUDIO_LTP) OR |
| (audioObjectType == MP4AUDIO_AAC_SCALABLE) OR |
| (audioObjectType == MP4AUDIO_TWINVQ)) AND (status == -1)) |
| THEN |
| status = CALL get_GA_specific_config( |
| pVars = pVars, |
| channel_config = channel_config, |
| audioObjectType = audioObjectType, |
| pInputStream = pInputStream); |
| MODIFYING (pVars->mc_info,channel_config,pInputStream) |
| RETURNING (status) |
| |
| ENDIF |
| |
| IF (audioObjectType == MP4AUDIO_CELP) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (audioObjectType == MP4AUDIO_HVXC) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (audioObjectType == MP4AUDIO_TTSI) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF ((audioObjectType == 13) OR (audioObjectType == 14) OR |
| (audioObjectType == 15) OR (audioObjectType == 16)) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (((audioObjectType == MP4AUDIO_ER_AAC_LC) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_LTP) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_SCALABLE) OR |
| (audioObjectType == MP4AUDIO_ER_TWINVQ) OR |
| (audioObjectType == MP4AUDIO_ER_BSAC) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_LD)) AND (status == -1)) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (audioObjectType == MP4AUDIO_ER_CELP) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF (audioObjectType == MP4AUDIO_ER_HVXC) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF ((audioObjectType == MP4AUDIO_ER_HILN) OR |
| (audioObjectType == MP4AUDIO_PARAMETRIC)) |
| THEN |
| status = 1; |
| ENDIF |
| |
| IF ((audioObjectType == MP4AUDIO_ER_AAC_LC) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_LTP) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_SCALABLE) OR |
| (audioObjectType == MP4AUDIO_ER_TWINVQ) OR |
| (audioObjectType == MP4AUDIO_ER_BSAC) OR |
| (audioObjectType == MP4AUDIO_ER_AAC_LD) OR |
| (audioObjectType == MP4AUDIO_ER_CELP) OR |
| (audioObjectType == MP4AUDIO_ER_HVXC) OR |
| (audioObjectType == MP4AUDIO_ER_HILN) OR |
| (audioObjectType == MP4AUDIO_PARAMETRIC)) |
| THEN |
| epConfig = CALL getbits( |
| neededBits = LEN_EP_CONFIG, |
| pInputStream = pInputStream); |
| MODIFYING (pInputStream) |
| RETURNING (epConfig) |
| |
| IF (epConfig == 2) |
| THEN |
| status = 1; |
| ENDIF |
| |
| ENDIF |
| |
| RETURN status; |
| |
| ------------------------------------------------------------------------------ |
| RESOURCES USED |
| When the code is written for a specific target processor the |
| the resources used should be documented below. |
| |
| STACK USAGE: [stack count for this module] + [variable to represent |
| stack usage for each subroutine called] |
| |
| where: [stack usage variable] = stack usage for [subroutine |
| name] (see [filename].ext) |
| |
| DATA MEMORY USED: x words |
| |
| PROGRAM MEMORY USED: x words |
| |
| CLOCK CYCLES: [cycle count equation for this module] + [variable |
| used to represent cycle count for each subroutine |
| called] |
| |
| where: [cycle count variable] = cycle count for [subroutine |
| name] (see [filename].ext) |
| |
| ------------------------------------------------------------------------------ |
| */ |
| |
| |
| /*---------------------------------------------------------------------------- |
| ; INCLUDES |
| ----------------------------------------------------------------------------*/ |
| #include "pv_audio_type_defs.h" |
| #include "e_mp4ff_const.h" |
| #include "e_tmp4audioobjecttype.h" |
| #include "get_audio_specific_config.h" |
| #include "get_ga_specific_config.h" |
| #include "ibstream.h" |
| #include "sfb.h" /* Where samp_rate_info[] is declared */ |
| |
| /*---------------------------------------------------------------------------- |
| ; MACROS |
| ; Define module specific macros here |
| ----------------------------------------------------------------------------*/ |
| |
| |
| /*---------------------------------------------------------------------------- |
| ; DEFINES |
| ; Include all pre-processor statements here. Include conditional |
| ; compile variables also. |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; LOCAL FUNCTION DEFINITIONS |
| ; Function Prototype declaration |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; LOCAL STORE/BUFFER/POINTER DEFINITIONS |
| ; Variable declaration - defined here and used outside this module |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; EXTERNAL FUNCTION REFERENCES |
| ; Declare functions defined elsewhere and referenced in this module |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES |
| ; Declare variables used in this module but defined elsewhere |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; FUNCTION CODE |
| ----------------------------------------------------------------------------*/ |
| Int get_audio_specific_config(tDec_Int_File * const pVars) |
| { |
| |
| UInt temp; |
| tMP4AudioObjectType audioObjectType; |
| //UInt32 sampling_rate; |
| UInt channel_config; |
| UInt syncExtensionType; |
| UInt extensionAudioObjectType = 0; |
| UInt extensionSamplingFrequencyIndex = 0; |
| BITS *pInputStream; |
| Int status; |
| |
| status = SUCCESS; |
| |
| pInputStream = &(pVars->inputStream); |
| |
| pVars->mc_info.upsamplingFactor = 1; /* default to regular AAC */ |
| |
| temp = get9_n_lessbits(LEN_OBJ_TYPE + LEN_SAMP_RATE_IDX, |
| pInputStream); |
| |
| /* |
| * The following code can directly set the values of elements in |
| * MC_Info, rather than first setting the values in pVars->prog_config |
| * and then copy these values to MC_Info by calling set_mc_info. |
| * In order to keep consistent with get_prog_config (ADIF) and |
| * get_adts_header (ADTS), the code here is still copying |
| * the info, and set the pVars->current_program = 0 |
| */ |
| |
| /* AudioObjectType */ |
| audioObjectType = (tMP4AudioObjectType)((temp & 0x1f0) >> 4); |
| |
| pVars->mc_info.ExtendedAudioObjectType = audioObjectType; /* default */ |
| /* saving an audioObjectType into a profile field */ |
| /* pVars->prog_config.profile = audioObjectType; */ |
| |
| /* sampling rate index */ |
| pVars->prog_config.sampling_rate_idx = temp & 0xf; |
| |
| if (pVars->prog_config.sampling_rate_idx == 0xf) |
| { |
| /* |
| * sampling rate not listed in Table 1.6.2, |
| * this release does not support this |
| */ |
| /*sampling_rate = getbits( LEN_SAMP_RATE, |
| pInputStream);*/ |
| getbits(LEN_SAMP_RATE, pInputStream); |
| |
| status = 1; |
| } |
| |
| channel_config = get9_n_lessbits(LEN_CHAN_CONFIG, |
| pInputStream); |
| |
| if ((channel_config > 2) && (!pVars->aacConfigUtilityEnabled)) |
| { |
| /* |
| * AAC lib does not support more than two channels |
| * signal error when in decoder mode |
| * do not test when in utility mode |
| */ |
| status = 1; |
| |
| } |
| |
| if (audioObjectType == MP4AUDIO_SBR || audioObjectType == MP4AUDIO_PS) |
| { |
| /* to disable explicit backward compatiblity check */ |
| pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_SBR; |
| pVars->mc_info.sbrPresentFlag = 1; |
| |
| if (audioObjectType == MP4AUDIO_PS) |
| { |
| pVars->mc_info.psPresentFlag = 1; |
| pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_PS; |
| } |
| |
| extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */ |
| get9_n_lessbits(LEN_SAMP_RATE_IDX, |
| pInputStream); |
| if (extensionSamplingFrequencyIndex == 0x0f) |
| { |
| /* |
| * sampling rate not listed in Table 1.6.2, |
| * this release does not support this |
| */ |
| /*sampling_rate = getbits( LEN_SAMP_RATE, |
| pInputStream);*/ |
| getbits(LEN_SAMP_RATE, pInputStream); |
| } |
| |
| audioObjectType = (tMP4AudioObjectType) get9_n_lessbits(LEN_OBJ_TYPE , |
| pInputStream); |
| } |
| |
| |
| if ((/*(audioObjectType == MP4AUDIO_AAC_MAIN) ||*/ |
| (audioObjectType == MP4AUDIO_AAC_LC) || |
| /*(audioObjectType == MP4AUDIO_AAC_SSR) ||*/ |
| (audioObjectType == MP4AUDIO_LTP) /*||*/ |
| /*(audioObjectType == MP4AUDIO_AAC_SCALABLE) ||*/ |
| /*(audioObjectType == MP4AUDIO_TWINVQ)*/) && (status == SUCCESS)) |
| { |
| status = get_GA_specific_config(pVars, |
| pInputStream, |
| channel_config, |
| audioObjectType); |
| |
| /* |
| * verify that Program config returned a supported audio object type |
| */ |
| |
| if ((pVars->mc_info.audioObjectType != MP4AUDIO_AAC_LC) && |
| (pVars->mc_info.audioObjectType != MP4AUDIO_LTP)) |
| { |
| status = 1; |
| } |
| } |
| else |
| { |
| status = 1; |
| } |
| |
| /* |
| * SBR tool explicit signaling ( backward compatible ) |
| */ |
| if (extensionAudioObjectType != MP4AUDIO_SBR) |
| { |
| syncExtensionType = (UInt)get17_n_lessbits(LEN_SYNC_EXTENSION_TYPE, |
| pInputStream); |
| |
| if (syncExtensionType == 0x2b7) |
| { |
| extensionAudioObjectType = get9_n_lessbits( /* extensionAudioObjectType */ |
| LEN_OBJ_TYPE, |
| pInputStream); |
| |
| if (extensionAudioObjectType == MP4AUDIO_SBR) |
| { |
| pVars->mc_info.sbrPresentFlag = get1bits(pInputStream); /* sbrPresentFlag */ |
| if (pVars->mc_info.sbrPresentFlag == 1) |
| { |
| extensionSamplingFrequencyIndex = |
| get9_n_lessbits( /* extensionSamplingFrequencyIndex */ |
| LEN_SAMP_RATE_IDX, |
| pInputStream); |
| if (pVars->aacPlusEnabled == true) |
| { |
| #ifdef AAC_PLUS |
| pVars->mc_info.upsamplingFactor = (samp_rate_info[extensionSamplingFrequencyIndex].samp_rate >> 1) == |
| samp_rate_info[pVars->prog_config.sampling_rate_idx].samp_rate ? 2 : 1; |
| |
| if ((Int)extensionSamplingFrequencyIndex == pVars->prog_config.sampling_rate_idx) |
| { |
| /* |
| * Disable SBR decoding for any sbr-downsampled file whose SF is >= 24 KHz |
| */ |
| if (pVars->prog_config.sampling_rate_idx < 6) |
| { |
| pVars->aacPlusEnabled = false; |
| } |
| |
| pVars->mc_info.bDownSampledSbr = true; |
| } |
| pVars->prog_config.sampling_rate_idx = extensionSamplingFrequencyIndex; |
| |
| #endif |
| } |
| |
| if (extensionSamplingFrequencyIndex == 0x0f) |
| { |
| /* |
| * sampling rate not listed in Table 1.6.2, |
| * this release does not support this |
| */ |
| /*sampling_rate = getbits( LEN_SAMP_RATE, |
| pInputStream);*/ |
| getbits(LEN_SAMP_RATE, pInputStream); |
| } |
| /* syncExtensionType */ |
| syncExtensionType = (UInt)get17_n_lessbits(LEN_SYNC_EXTENSION_TYPE, |
| pInputStream); |
| if (syncExtensionType == 0x548) |
| { |
| pVars->mc_info.psPresentFlag = get1bits(pInputStream); /* psPresentFlag */ |
| if (pVars->mc_info.psPresentFlag) |
| { |
| extensionAudioObjectType = MP4AUDIO_PS; |
| } |
| } |
| else |
| { |
| /* |
| * Rewind bitstream pointer so that the syncExtensionType reading has no |
| * effect when decoding raw bitstream |
| */ |
| pVars->inputStream.usedBits -= LEN_SYNC_EXTENSION_TYPE; |
| } |
| |
| pVars->mc_info.ExtendedAudioObjectType = (eMP4AudioObjectType)extensionAudioObjectType; |
| } |
| } |
| } |
| else if (!status) |
| { |
| /* |
| * Rewind bitstream pointer so that the syncExtensionType reading has no |
| * effect when decoding raw bitstream |
| */ |
| pVars->inputStream.usedBits -= LEN_SYNC_EXTENSION_TYPE; |
| |
| #ifdef AAC_PLUS |
| |
| /* |
| * For implicit signalling, no hint that sbr or ps is used, so we need to |
| * check the sampling frequency of the aac content, if lesser or equal to |
| * 24 KHz, by defualt upsample, otherwise, do nothing |
| */ |
| if ((pVars->prog_config.sampling_rate_idx >= 6) && (pVars->aacPlusEnabled == true) && |
| audioObjectType == MP4AUDIO_AAC_LC) |
| { |
| pVars->mc_info.upsamplingFactor = 2; |
| pVars->prog_config.sampling_rate_idx -= 3; |
| pVars->mc_info.sbrPresentFlag = 1; |
| pVars->sbrDecoderData.SbrChannel[0].syncState = SBR_NOT_INITIALIZED; |
| pVars->sbrDecoderData.SbrChannel[1].syncState = SBR_NOT_INITIALIZED; |
| |
| } |
| #endif |
| |
| } |
| } |
| else /* MP4AUDIO_SBR was detected */ |
| { |
| /* |
| * Set the real output frequency use by the SBR tool, define tentative upsample ratio |
| */ |
| if (pVars->aacPlusEnabled == true) |
| { |
| #ifdef AAC_PLUS |
| pVars->mc_info.upsamplingFactor = (samp_rate_info[extensionSamplingFrequencyIndex].samp_rate >> 1) == |
| samp_rate_info[pVars->prog_config.sampling_rate_idx].samp_rate ? 2 : 1; |
| |
| if ((Int)extensionSamplingFrequencyIndex == pVars->prog_config.sampling_rate_idx) |
| { |
| /* |
| * Disable SBR decoding for any sbr-downsampled file whose SF is >= 24 KHz |
| */ |
| if (pVars->prog_config.sampling_rate_idx < 6) |
| { |
| pVars->aacPlusEnabled = false; |
| } |
| pVars->mc_info.bDownSampledSbr = true; |
| } |
| pVars->prog_config.sampling_rate_idx = extensionSamplingFrequencyIndex; |
| |
| |
| |
| #endif |
| |
| |
| |
| |
| } |
| |
| } /* if ( extensionAudioObjectType != MP4AUDIO_SBR ) */ |
| |
| /* |
| * The following object types are not supported in this release, |
| * however, keep these interfaces for future implementation |
| */ |
| |
| /* |
| *if (audioObjectType == MP4AUDIO_CELP) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if (audioObjectType == MP4AUDIO_HVXC) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if (audioObjectType == MP4AUDIO_TTSI) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if ((audioObjectType == 13) || (audioObjectType == 14) || |
| * (audioObjectType == 15) || (audioObjectType == 16)) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* The following objects are Amendment 1 objects */ |
| /* |
| *if (((audioObjectType == MP4AUDIO_ER_AAC_LC) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_LTP) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_SCALABLE) || |
| * (audioObjectType == MP4AUDIO_ER_TWINVQ) || |
| * (audioObjectType == MP4AUDIO_ER_BSAC) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_LD)) && (status == -1)) |
| *{ |
| */ |
| /* |
| * should call get_GA_specific_config |
| * for this release, do not support Error Resilience |
| * temporary solution is set status flag and exit decoding |
| */ |
| /* status = 1; |
| *} |
| */ |
| |
| /* |
| *if (audioObjectType == MP4AUDIO_ER_CELP) |
| * { |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if (audioObjectType == MP4AUDIO_ER_HVXC) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if ((audioObjectType == MP4AUDIO_ER_HILN) || |
| * (audioObjectType == MP4AUDIO_PARAMETRIC)) |
| *{ |
| * status = 1; |
| *} |
| */ |
| |
| /* |
| *if ((audioObjectType == MP4AUDIO_ER_AAC_LC) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_LTP) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_SCALABLE) || |
| * (audioObjectType == MP4AUDIO_ER_TWINVQ) || |
| * (audioObjectType == MP4AUDIO_ER_BSAC) || |
| * (audioObjectType == MP4AUDIO_ER_AAC_LD) || |
| * (audioObjectType == MP4AUDIO_ER_CELP) || |
| * (audioObjectType == MP4AUDIO_ER_HVXC) || |
| * (audioObjectType == MP4AUDIO_ER_HILN) || |
| * (audioObjectType == MP4AUDIO_PARAMETRIC)) |
| *{ |
| */ |
| /* error protection config */ |
| /* |
| * epConfig = |
| * getbits( |
| * LEN_EP_CONFIG, |
| * pInputStream); |
| * |
| * if (epConfig == 2) |
| * { |
| */ |
| /* should call ErrorProtectionSpecificConfig() */ |
| /* |
| * status = 1; |
| * } |
| * |
| *} |
| */ |
| |
| return status; |
| |
| } |