📄 umc_aac_decoder_int.cpp
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2002-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_aac_decoder_int.h"
#include "mp4cmn_config.h"
#include "aaccmn_adif.h"
#include "aaccmn_adts.h"
#include "aac_dec_own_int.h"
#include "aac_dec_int.h"
#include "umc_aac_decoder_params.h"
#include "vm_debug.h"
namespace UMC {
/********************************************************************/
AudioCodec *newAACDecoderInt() { return (new AACDecoderInt); }
AACDecoderInt::AACDecoderInt()
{
state = NULL;
stateMemId = 0;
}
/********************************************************************/
Status AACDecoderInt::Init(BaseCodecParams * init)
{
AACStatus result;
AudioCodecParams *pAudioCodecInit = DynamicCast < AACDecoderParams > (init);
Ipp32s mStateSize;
// checks or create memory allocator;
if (BaseCodec::Init(init) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("Failed to create allocator!\n"));
return UMC_ERR_ALLOC;
}
result = aacidecGetSize(&mStateSize);
if (result != AAC_OK)
return StatusAAC_2_UMC(result);
if (m_pMemoryAllocator->Alloc(&stateMemId, mStateSize,
UMC_ALLOC_PERSISTENT) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External allocation failed\n"));
return UMC_ERR_ALLOC;
}
state = (AACDec *)m_pMemoryAllocator->Lock(stateMemId);
if(!state) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
return UMC_ERR_ALLOC;
}
result = aacidecInit(state);
if (result != AAC_OK)
return StatusAAC_2_UMC(result);
initSubtype = 0;
m_info.m_audio_object_type = AOT_UNDEF;
m_info.m_decode_mode = DM_UNDEF_STREAM;
m_info.m_init_stream_type = UNDEF_AUDIO;
m_info.m_init_config_data_size = 0;
m_info.m_sampling_frequency_index = 0;
m_info.m_frame_number = 0;
m_pts_prev = 0;
params.is_valid = 0;
if (!pAudioCodecInit)
return UMC_OK;
/* ***************************** *
* usr settings for HEAAC
* status = SetParams(init) - incorrect here
* because default settings apply by constructor()
* ***************************** */
SetParams(init) ;
if (stateMemId) {
if (UMC_OK != m_pMemoryAllocator->Unlock(stateMemId)) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Unlock failed\n"));
return UMC_ERR_ALLOC;
}
}
m_info.m_init_stream_type = pAudioCodecInit->m_info_in.stream_type;
if (NULL != pAudioCodecInit->m_pData) {
m_info.m_init_config_data_size = pAudioCodecInit->m_pData->GetDataSize();
}
return UMC_OK;
}
/********************************************************************/
Status AACDecoderInt::SetParams(BaseCodecParams * params) {
AACDecoderParams *info = DynamicCast < AACDecoderParams > (params);
if (info) {
if ((info->ModeDecodeHEAACprofile == HEAAC_HQ_MODE ||
info->ModeDecodeHEAACprofile == HEAAC_LP_MODE) &&
(info->ModeDwnsmplHEAACprofile == HEAAC_DWNSMPL_ON ||
info->ModeDwnsmplHEAACprofile == HEAAC_DWNSMPL_OFF)) {
Status status;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
aacidecSetSBRModeDecode(info->ModeDecodeHEAACprofile, state);
aacidecSetSBRModeDwnmx(info->ModeDwnsmplHEAACprofile, state);
aacidecSetSBRSupport(info->flag_SBR_support_lev, state);
MemUnlock();
}
} else {
return UMC_ERR_NULL_PTR;
}
return UMC_OK;
}
/********************************************************************/
Status AACDecoderInt::GetFrame(MediaData * in,
MediaData * out)
{
AACStatus result;
sBitsreamBuffer BS;
Ipp32s res;
Ipp32s nDecodedBytes, tmp_decodedBytes;
Ipp32s firstTime;
sAudio_specific_config audio_config_data;
sAdif_header m_adif_header;
sAdts_fixed_header m_adts_fixed_header;
sAdts_variable_header m_adts_variable_header;
Ipp8u *inPointer;
Ipp32s inDataSize;
Ipp64f pts_start;
Ipp64f pts_end;
Ipp32s SbrFlagPresent, frameSize, freq, ch, decodedBytes;
Ipp32s CRC = 0;
Ipp32s crc_enable = 0;
Status status;
if (!in || !out)
return UMC_ERR_NULL_PTR;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
pts_start = in->GetTime();
aacidecInitCRC(1, state);
if (AAC_MPEG4_STREAM != m_info.m_init_stream_type) {
inPointer = (Ipp8u *)in->GetDataPointer();
inDataSize = in->GetDataSize();
if (inDataSize == 0) {
MemUnlock();
return UMC_ERR_NOT_ENOUGH_DATA;
}
result = aacidec_GetID3Len(inPointer, inDataSize, state);
if (result != AAC_OK) {
MemUnlock();
return StatusAAC_2_UMC(result);
}
result = aacidec_SkipID3(inDataSize, &decodedBytes, state);
in->MoveDataPointer(decodedBytes);
if (result != AAC_OK) {
MemUnlock();
return StatusAAC_2_UMC(result);
}
}
inPointer = (Ipp8u *)in->GetDataPointer();
GET_INIT_BITSTREAM(&BS, inPointer)
firstTime = 0;
while ((DM_UNDEF_STREAM == m_info.m_decode_mode) && (0 == firstTime)) {
firstTime = 1;
m_info.m_audio_object_type = AOT_UNDEF;
if (AAC_MPEG4_STREAM == m_info.m_init_stream_type) {
BS.nDataLen = m_info.m_init_config_data_size;
dec_audio_specific_config(&audio_config_data, &BS);
/* **************************************************** *
* if MP4 contains explicit HEAAC signalization
* then usrParam <ModeDwnsmplHEAACprofile> is ignored
* **************************************************** */
if( 5 == audio_config_data.extensionAudioObjectType ){ //AOT_SBR = 5
if( audio_config_data.extensionSamplingFrequencyIndex == audio_config_data.samplingFrequencyIndex ){
aacidecSetSBRModeDwnmx(HEAAC_DWNSMPL_ON, state);
} else {
aacidecSetSBRModeDwnmx(HEAAC_DWNSMPL_OFF, state);
}
}
/* END SET_PARAM OF HEAAC FROM MP4 HEADER */
m_info.m_sampling_frequency_index =
get_sampling_frequency_index(&audio_config_data);
if (audio_config_data.channelConfiguration == 0) {
aacidecSetPCE(&audio_config_data.GASpecificConfig.pce, state);
}
m_info.m_decode_mode = DM_RAW_STREAM;
m_info.m_audio_object_type =
(AudioObjectType) audio_config_data.audioObjectType;
aacidecSetAudioObjectType(m_info.m_audio_object_type, state);
/* Init tables */
aacidecSetSamplingFrequency(m_info.m_sampling_frequency_index, state);
in->MoveDataPointer((Ipp32s)m_info.m_init_config_data_size);
out->SetDataSize(0);
/* IMPORTANT!!! */
MemUnlock();
return UMC_ERR_SYNC;
}
bs_save(&BS);
res = dec_adif_header(&m_adif_header, &BS);
if (res == 0) {
sProgram_config_element *m_p_pce = &m_adif_header.pce[0];
aacidecSetPCE(m_p_pce, state);
m_info.m_sampling_frequency_index = m_p_pce->sampling_frequency_index;
m_info.m_decode_mode = DM_RAW_STREAM;
/* Init tables */
aacidecSetSamplingFrequency(m_info.m_sampling_frequency_index, state);
switch (m_p_pce->object_type) {
case 0:
m_info.m_audio_object_type = AOT_AAC_MAIN;
break;
case 1:
m_info.m_audio_object_type = AOT_AAC_LC;
break;
case 2:
m_info.m_audio_object_type = AOT_AAC_SSR;
break;
case 3:
m_info.m_audio_object_type = AOT_AAC_LTP;
break;
}
aacidecSetAudioObjectType(m_info.m_audio_object_type, state);
break;
}
bs_restore(&BS);
if ((0 == dec_adts_fixed_header(&m_adts_fixed_header, &BS)) &&
(0 == dec_adts_variable_header(&m_adts_variable_header, &BS))) {
m_info.m_sampling_frequency_index =
m_adts_fixed_header.sampling_frequency_index;
m_info.m_audio_object_type = (AudioObjectType)
get_audio_object_type_by_adts_header(&m_adts_fixed_header);
m_info.m_decode_mode = DM_ADTS_STREAM;
aacidecSetAudioObjectType(m_info.m_audio_object_type, state);
/* Init tables */
aacidecSetSamplingFrequency(m_info.m_sampling_frequency_index, state);
adts_sw = (0xFFF << 12) + ((m_adts_fixed_header.ID & 1) << 11) +
((m_adts_fixed_header.Layer & 3) << 8) +
((m_adts_fixed_header.Profile & 3) << 6) +
((m_adts_fixed_header.sampling_frequency_index & 15) << 2);
bs_restore(&BS);
break;
}
bs_restore(&BS);
m_info.m_stream_subtype = UNDEF_AUDIO_SUBTYPE;
if (m_info.m_audio_object_type == AOT_AAC_MAIN) {
m_info.m_stream_subtype = AAC_MAIN_PROFILE;
} else if (m_info.m_audio_object_type == AOT_AAC_LC) {
m_info.m_stream_subtype = AAC_LC_PROFILE;
} else if (m_info.m_audio_object_type == AOT_AAC_SSR) {
m_info.m_stream_subtype = AAC_SSR_PROFILE;
} else if (m_info.m_audio_object_type == AOT_AAC_LTP) {
m_info.m_stream_subtype = AAC_LTP_PROFILE;
}
}
if (AOT_UNDEF == m_info.m_audio_object_type) {
MemUnlock();
return UMC_ERR_UNSUPPORTED;
}
if (DM_ADTS_STREAM == m_info.m_decode_mode) {
Ipp32s DataSize = in->GetDataSize();
Ipp8u *tmp_ptr = (Ipp8u *)in->GetDataPointer();
Ipp32u val;
Ipp32u *crc_ptr;
Ipp32s crc_offset;
Ipp32s decodedBits0, decodedBits2;
Ipp32s num_channel;
if (DataSize < 9) {
MemUnlock();
return UMC_ERR_NOT_ENOUGH_DATA;
}
val = (tmp_ptr[0] << 16) + (tmp_ptr[1] << 8) + tmp_ptr[2];
DataSize -= 3;
tmp_ptr += 3;
while (((val & 0xFFFEFC) != adts_sw) && (DataSize > 0)) {
val = (val << 8) + tmp_ptr[0];
DataSize--;
tmp_ptr++;
}
if ((val & 0xFFFEFC) != adts_sw) {
in->MoveDataPointer(in->GetDataSize()-2);
MemUnlock();
return UMC_ERR_NOT_ENOUGH_DATA;
}
DataSize += 3;
in->MoveDataPointer(in->GetDataSize()-DataSize);
if (DataSize < 9) {
MemUnlock();
return UMC_ERR_NOT_ENOUGH_DATA;
}
inPointer = (Ipp8u *)in->GetDataPointer();
GET_INIT_BITSTREAM(&BS, inPointer)
crc_ptr = BS.pCurrent_dword;
crc_offset = BS.nBit_offset;
GET_BITS_COUNT(&BS, decodedBits0)
dec_adts_fixed_header(&m_adts_fixed_header, &BS);
dec_adts_variable_header(&m_adts_variable_header, &BS);
GET_BITS_COUNT(&BS, decodedBits2)
if (m_adts_fixed_header.protection_absent == 0) {
Ipp32s tmp_crc;
CRC = (Ipp32s)Getbits(&BS, 16);
aacidecInitCRC(1, state);
aacidecGetCRC(&tmp_crc, state);
bs_CRC_update(crc_ptr, crc_offset, decodedBits2 - decodedBits0, (Ipp32u*)&tmp_crc);
aacidecSetCRC(tmp_crc, state);
crc_enable = 1;
}
if (aacidecSetAdtsChannelConfiguration(
m_adts_fixed_header.channel_configuration, state) != AAC_OK ) {
in->MoveDataPointer(3);
MemUnlock();
return UMC_ERR_INVALID_STREAM;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -