⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_aac_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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 + -