/* returns error code */ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, const UINT layer ) { TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; HANDLE_FDK_BITSTREAM hBs; if (!hTp) { return TRANSPORTDEC_INVALID_PARAMETER; } hBs = &hTp->bitStream[layer]; switch (hTp->transportFmt) { case TT_MP4_ADIF: /* Read header if not already done */ if (!(hTp->flags & TPDEC_CONFIG_FOUND)) { CProgramConfig *pce; AudioSpecificConfig_Init(&hTp->asc[0]); pce = &hTp->asc[0].m_progrConfigElement; err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs); if (err) goto bail; /* Map adif header to ASC */ hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1); hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex; hTp->asc[0].m_samplingFrequency = SamplingRateTable[pce->SamplingFrequencyIndex]; hTp->asc[0].m_channelConfiguration = 0; hTp->asc[0].m_samplesPerFrame = 1024; hTp->avgBitRate = hTp->parser.adif.BitRate; /* Call callback to decoder. */ { int errC; errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]); if (errC == 0) { hTp->flags |= TPDEC_CONFIG_FOUND; } else { err = TRANSPORTDEC_PARSE_ERROR; goto bail; } } } hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */ break; case TT_MP4_RAW: if ((INT)FDKgetValidBits(hBs) <= 0 && layer == 0) { err = TRANSPORTDEC_NOT_ENOUGH_BITS; } /* One Access Unit was filled into buffer. So get the length out of the buffer. */ hTp->auLength[layer] = FDKgetValidBits(hBs); hTp->flags |= TPDEC_SYNCOK; break; case TT_RSVD50: case TT_MP4_ADTS: case TT_MP4_LOAS: case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP1: err = transportDec_readStream(hTp, layer); break; default: err = TRANSPORTDEC_UNSUPPORTED_FORMAT; break; } if (err == TRANSPORTDEC_OK) { hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs); } else { hTp->accessUnitAnchor[layer] = 0; } bail: return err; }
TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, int fExplicitBackwardCompatible, CSTpCallBacks *cb ) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; UINT ascStartAnchor = FDKgetValidBits(bs); int frameLengthFlag = -1; AudioSpecificConfig_Init(self); self->m_aot = getAOT(bs); self->m_samplingFrequency = getSampleRate(bs, &self->m_samplingFrequencyIndex, 4); if (self->m_samplingFrequency <= 0) { return TRANSPORTDEC_PARSE_ERROR; } self->m_channelConfiguration = FDKreadBits(bs,4); /* SBR extension ( explicit non-backwards compatible mode ) */ self->m_sbrPresentFlag = 0; self->m_psPresentFlag = 0; if ( self->m_aot == AOT_SBR || self->m_aot == AOT_PS ) { self->m_extensionAudioObjectType = AOT_SBR; self->m_sbrPresentFlag = 1; if ( self->m_aot == AOT_PS ) { self->m_psPresentFlag = 1; } self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4); self->m_aot = getAOT(bs); } else { self->m_extensionAudioObjectType = AOT_NULL_OBJECT; } /* Parse whatever specific configs */ switch (self->m_aot) { #ifdef TP_GA_ENABLE case AOT_AAC_LC: case AOT_ER_AAC_LC: case AOT_ER_AAC_LD: case AOT_ER_AAC_SCAL: case AOT_ER_BSAC: if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, self, bs, ascStartAnchor)) != TRANSPORTDEC_OK ) { return (ErrorStatus); } frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag; break; #endif /* TP_GA_ENABLE */ case AOT_MPEGS: if (cb->cbSsc != NULL) { cb->cbSsc( cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, 1, 0 /* don't know the length */ ); } else { return TRANSPORTDEC_UNSUPPORTED_FORMAT; } break; #ifdef TP_ELD_ENABLE case AOT_ER_AAC_ELD: if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK ) { return (ErrorStatus); } frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag; self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag; self->m_extensionSamplingFrequency = (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate+1) * self->m_samplingFrequency; break; #endif /* TP_ELD_ENABLE */ default: return TRANSPORTDEC_UNSUPPORTED_FORMAT; break; } /* Frame length */ switch (self->m_aot) { #if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE) case AOT_AAC_LC: case AOT_ER_AAC_LC: case AOT_ER_AAC_SCAL: case AOT_ER_BSAC: /*case AOT_USAC:*/ if (!frameLengthFlag) self->m_samplesPerFrame = 1024; else self->m_samplesPerFrame = 960; break; #endif /* TP_GA_ENABLE */ #if defined(TP_GA_ENABLE) case AOT_ER_AAC_LD: if (!frameLengthFlag) self->m_samplesPerFrame = 512; else self->m_samplesPerFrame = 480; break; #endif /* defined(TP_GA_ENABLE) */ default: break; } switch (self->m_aot) { case AOT_ER_AAC_LC: case AOT_ER_AAC_LD: case AOT_ER_AAC_ELD: case AOT_ER_AAC_SCAL: case AOT_ER_CELP: case AOT_ER_HVXC: case AOT_ER_BSAC: self->m_epConfig = FDKreadBits(bs,2); if (self->m_epConfig > 1) { return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG; } break; default: break; } if (fExplicitBackwardCompatible) { ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb); } return (ErrorStatus); }
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs ) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; AudioSpecificConfig_Init(self); if ((INT)FDKgetValidBits(bs) < 20) { ErrorStatus = TRANSPORTDEC_PARSE_ERROR; goto bail; } else { /* DRM - Audio information data entity - type 9 - Short Id 2 bits - Stream Id 2 bits - audio coding 2 bits - SBR flag 1 bit - audio mode 2 bits - audio sampling rate 3 bits - text flag 1 bit - enhancement flag 1 bit - coder field 5 bits - rfa 1 bit */ int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag; /* Read the SDC field */ FDKreadBits(bs,4); /* Short and Stream Id */ audioCoding = FDKreadBits(bs, 2); sbrFlag = FDKreadBits(bs, 1); audioMode = FDKreadBits(bs, 2); cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */ FDKreadBits(bs, 2); /* Text and enhancement flag */ coderField = FDKreadBits(bs, 5); FDKreadBits(bs, 1); /* rfa */ /* Evaluate configuration and fill the ASC */ switch (cSamplingFreq) { case 0: /* 8 kHz */ sfIdx = 11; break; case 1: /* 12 kHz */ sfIdx = 9; break; case 2: /* 16 kHz */ sfIdx = 8; break; case 3: /* 24 kHz */ sfIdx = 6; break; case 5: /* 48 kHz */ sfIdx = 3; break; case 4: /* reserved */ case 6: /* reserved */ case 7: /* reserved */ default: ErrorStatus = TRANSPORTDEC_PARSE_ERROR; goto bail; } self->m_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); }
TRANSPORTDEC_ERROR adtsRead_DecodeHeader( HANDLE_ADTS pAdts, CSAudioSpecificConfig *pAsc, HANDLE_FDK_BITSTREAM hBs, const INT ignoreBufferFullness ) { INT crcReg; INT valBits; INT cmp_buffer_fullness; int i, adtsHeaderLength; STRUCT_ADTS_BS bs; #ifdef TP_PCE_ENABLE CProgramConfig oldPce; /* Store the old PCE temporarily. Maybe we'll need it later if we have channelConfig=0 and no PCE in this frame. */ FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig)); #endif valBits = FDKgetValidBits(hBs); #ifndef ANDROID_DEFAULT_CODE if (valBits <= ADTS_HEADERLENGTH) return TRANSPORTDEC_NOT_ENOUGH_BITS; #endif /* adts_fixed_header */ bs.mpeg_id = FDKreadBits(hBs, Adts_Length_Id); bs.layer = FDKreadBits(hBs, Adts_Length_Layer); bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent); bs.profile = FDKreadBits(hBs, Adts_Length_Profile); bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex); bs.private_bit = FDKreadBits(hBs, Adts_Length_PrivateBit); bs.channel_config = FDKreadBits(hBs, Adts_Length_ChannelConfiguration); bs.original = FDKreadBits(hBs, Adts_Length_OriginalCopy); bs.home = FDKreadBits(hBs, Adts_Length_Home); /* adts_variable_header */ bs.copyright_id = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit); bs.copyright_start = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart); bs.frame_length = FDKreadBits(hBs, Adts_Length_FrameLength); bs.adts_fullness = FDKreadBits(hBs, Adts_Length_BufferFullness); bs.num_raw_blocks = FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame); bs.num_pce_bits = 0; adtsHeaderLength = ADTS_HEADERLENGTH; if (!bs.protection_absent) { FDKcrcReset(&pAdts->crcInfo); FDKpushBack(hBs, 56); /* complete fixed and variable header! */ crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0); FDKpushFor(hBs, 56); } if (! bs.protection_absent && bs.num_raw_blocks>0) { for (i=0; i<bs.num_raw_blocks; i++) { pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16); adtsHeaderLength += 16; } /* Change raw data blocks to delta values */ pAdts->rawDataBlockDist[bs.num_raw_blocks] = bs.frame_length - 7 - bs.num_raw_blocks*2 - 2 ; for (i=bs.num_raw_blocks; i>0; i--) { pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i-1]; } } /* adts_error_check */ if (!bs.protection_absent) { USHORT crc_check; FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg); crc_check = FDKreadBits(hBs, Adts_Length_CrcCheck); adtsHeaderLength += Adts_Length_CrcCheck; pAdts->crcReadValue = crc_check; /* Check header CRC in case of multiple raw data blocks */ if (bs.num_raw_blocks > 0) { if (pAdts->crcReadValue != FDKcrcGetCRC(&pAdts->crcInfo)) { return TRANSPORTDEC_CRC_ERROR; } /* Reset CRC for the upcoming raw_data_block() */ FDKcrcReset(&pAdts->crcInfo); } } /* check if valid header */ if ( (bs.layer != 0) || // we only support MPEG ADTS (bs.sample_freq_index >= 13) // we only support 96kHz - 7350kHz ) { FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later return TRANSPORTDEC_UNSUPPORTED_FORMAT; } /* special treatment of id-bit */ if ( (bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0) ) { /* MPEG-2 decoder cannot play MPEG-4 bitstreams */ FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later return TRANSPORTDEC_UNSUPPORTED_FORMAT; } if (!ignoreBufferFullness) { cmp_buffer_fullness = bs.frame_length*8 + bs.adts_fullness*32*getNumberOfEffectiveChannels(bs.channel_config); /* Evaluate buffer fullness */ if (bs.adts_fullness != 0x7FF) { if (pAdts->BufferFullnesStartFlag) { if ( valBits < cmp_buffer_fullness ) { /* Condition for start of decoding is not fulfilled */ /* The current frame will not be decoded */ FDKpushBack(hBs, adtsHeaderLength); if ( (cmp_buffer_fullness+adtsHeaderLength) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) { return TRANSPORTDEC_SYNC_ERROR; } else { return TRANSPORTDEC_NOT_ENOUGH_BITS; } } else { pAdts->BufferFullnesStartFlag = 0; } } } } /* Get info from ADTS header */ AudioSpecificConfig_Init(pAsc); pAsc->m_aot = (AUDIO_OBJECT_TYPE)(bs.profile + 1); pAsc->m_samplingFrequencyIndex = bs.sample_freq_index; pAsc->m_samplingFrequency = SamplingRateTable[bs.sample_freq_index]; pAsc->m_channelConfiguration = bs.channel_config; pAsc->m_samplesPerFrame = 1024; #ifdef TP_PCE_ENABLE if (bs.channel_config == 0) { int pceBits = 0; UINT alignAnchor = FDKgetValidBits(hBs); if (FDKreadBits(hBs,3) == ID_PCE) { /* Got luck! Parse the PCE */ int crcReg; crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0); CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor); adtsRead_CrcEndReg(pAdts, hBs, crcReg); pceBits = alignAnchor - FDKgetValidBits(hBs); /* store the number of PCE bits */ bs.num_pce_bits = pceBits; } else { /* No PCE in this frame! Push back the ID tag bits. */ FDKpushBack(hBs,3); /* Encoders do not have to write a PCE in each frame. So if we already have a valid PCE we have to use it. */ if ( oldPce.isValid && (bs.sample_freq_index == pAdts->bs.sample_freq_index) /* we could compare the complete fixed header (bytes) here! */ && (bs.channel_config == pAdts->bs.channel_config) /* == 0 */ && (bs.mpeg_id == pAdts->bs.mpeg_id) ) { /* Restore previous PCE which is still valid */ FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig)); } else if (bs.mpeg_id == 0) { /* If not it seems that we have a implicit channel configuration. This mode is not allowed in the context of ISO/IEC 14496-3. Skip this frame and try the next one. */ FDKpushFor(hBs, (bs.frame_length<<3) - adtsHeaderLength - 3); return TRANSPORTDEC_UNSUPPORTED_FORMAT; } /* else { ISO/IEC 13818-7 implicit channel mapping is allowed. So just open the box of chocolates to see what we got. } */ } } #endif /* TP_PCE_ENABLE */ /* Copy bit stream data struct to persistent memory now, once we passed all sanity checks above. */ FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS)); return TRANSPORTDEC_OK; }