📄 umc_aac_decoder.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.h"
#include "mp4cmn_config.h"
#include "aaccmn_adif.h"
#include "aaccmn_adts.h"
#include "aac_dec_own_fp.h"
#include "aac_dec_fp.h"
#include "umc_aac_decoder_params.h"
#include "vm_debug.h"
namespace UMC {
/********************************************************************/
AudioCodec *CreateAACDecoder() { return (new AACDecoder); }
AACDecoder::AACDecoder()
{
state = NULL;
pObjMem = NULL;
stateMemId = 0;
objMemId = 0;
}
/********************************************************************/
Status AACDecoder::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 = aacdecGetSize(&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;
}
/* AYA: clear memory */
ippsZero_8u( (Ipp8u*)state, mStateSize);
result = aacdecInit(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) ;
/* need for post-parser process */
state->psState.comState.modePS = state->com.m_flag_PS_support_lev;
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 AACDecoder::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;
}
/* SBR */
aacdecSetSBRModeDecode(info->ModeDecodeHEAACprofile, state);
aacdecSetSBRModeDwnsmpl(info->ModeDwnsmplHEAACprofile, state);
aacdecSetSBRSupport(info->flag_SBR_support_lev, state);
#if 1
/* PS */
if( info->flag_PS_support_lev == PS_ENABLE_BL ||
info->flag_PS_support_lev == PS_ENABLE_UR){
aacdecSetSBRModeDecode(HEAAC_HQ_MODE, state);
aacdecSetSBRModeDwnsmpl(HEAAC_DWNSMPL_OFF, state);
}
if( info->flag_PS_support_lev == PS_ENABLE_BL ||
info->flag_PS_support_lev == PS_ENABLE_UR ||
info->flag_PS_support_lev == PS_PARSER ||
info->flag_PS_support_lev == PS_DISABLE){
aacdecSetPSSupport(info->flag_PS_support_lev, state);
} else {
aacdecSetPSSupport(PS_DISABLE, state);
}
#endif
MemUnlock();
}
} else {
return UMC_ERR_NULL_PTR;
}
return UMC_OK;
}
/********************************************************************/
Status AACDecoder::SetObjectType(AudioObjectType mType,
AACDec *pState)
{
Ipp32s mSize;
AACStatus result;
result = aacdecSetAudioObjectType(mType, pState, NULL, &mSize);
if (result != AAC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("Failed on aacdecSetAudioObjectType\n"));
return UMC_ERR_ALLOC;
}
if (m_pMemoryAllocator->Alloc(&objMemId, mSize, UMC_ALLOC_PERSISTENT) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External allocation failed\n"));
return UMC_ERR_ALLOC;
}
pObjMem = (Ipp8u *)m_pMemoryAllocator->Lock(objMemId);
if(!pObjMem) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
return UMC_ERR_ALLOC;
}
result = aacdecSetAudioObjectType(mType, pState, pObjMem, &mSize);
if (result != AAC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("Failed on aacdecSetAudioObjectType\n"));
m_pMemoryAllocator->Free(objMemId);
return UMC_ERR_ALLOC;
}
if (objMemId) {
if (m_pMemoryAllocator->Unlock(objMemId) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Unlock failed\n"));
return UMC_ERR_ALLOC;
}
}
return UMC_OK;
}
/********************************************************************/
Status AACDecoder::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();
aacdecInitCRC(0, 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 = aacdec_GetID3Len(inPointer, inDataSize, state);
if (result != AAC_OK) {
MemUnlock();
return StatusAAC_2_UMC(result);
}
result = aacdec_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;
m_info.m_stream_subtype = UNDEF_AUDIO_SUBTYPE;
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 ){
aacdecSetSBRModeDwnsmpl(HEAAC_DWNSMPL_ON, state);
} else {
aacdecSetSBRModeDwnsmpl(HEAAC_DWNSMPL_OFF, state);
}
}
/* WE SUPPORT "PS-TOOL" only for (MPEG4 + MONO + SBR/PS) */
if( !audio_config_data.sbrPresentFlag ){
state->com.m_flag_PS_support_lev = PS_DISABLE;
}
/* 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) {
aacdecSetPCE(&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;
SetObjectType(m_info.m_audio_object_type, state);
/* Init tables */
aacdecSetSamplingFrequency(m_info.m_sampling_frequency_index, state);
in->MoveDataPointer((Ipp32s)m_info.m_init_config_data_size);
out->SetDataSize(0);
MemUnlock();
return UMC_ERR_NOT_ENOUGH_DATA;
} else { // WE DON'T SUPPORT PS TOOL FOR RAW AAC
state->com.m_flag_PS_support_lev = PS_DISABLE;
}
/* need for post-parser process */
state->psState.comState.modePS = state->com.m_flag_PS_support_lev;
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];
aacdecSetPCE(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 */
aacdecSetSamplingFrequency(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;
}
SetObjectType(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;
SetObjectType(m_info.m_audio_object_type, state);
/* Init tables */
aacdecSetSamplingFrequency(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);
}
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -