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

📄 umc_aac_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:

      if (m_adts_fixed_header.protection_absent == 0) {
        Ipp32s tmp_crc;
        CRC = (Ipp32s)Getbits(&BS, 16);
        aacdecInitCRC(1, state);
        aacdecGetCRC(&tmp_crc, state);
        bs_CRC_update(crc_ptr, crc_offset, decodedBits2 - decodedBits0, (Ipp32u*)&tmp_crc);
        aacdecSetCRC(tmp_crc, state);
        crc_enable = 1;
      }

      if (aacdecSetAdtsChannelConfiguration(
          m_adts_fixed_header.channel_configuration, state) != AAC_OK ) {
        in->MoveDataPointer(3);
        MemUnlock();
        return UMC_ERR_INVALID_STREAM;
      }

      Byte_alignment(&BS);
      GET_BITS_COUNT(&BS, tmp_decodedBytes)

      num_channel = m_adts_fixed_header.channel_configuration;
      if (num_channel == 7) num_channel = 8;

      if (m_adts_variable_header.aac_frame_length >
          num_channel * 768 + tmp_decodedBytes) {
        in->MoveDataPointer(3);
        MemUnlock();
        return UMC_ERR_INVALID_STREAM;
      }

      if (m_adts_variable_header.aac_frame_length > DataSize) {
        MemUnlock();
        return UMC_ERR_NOT_ENOUGH_DATA;
      }
    }

    Byte_alignment(&BS);
    GET_BITS_COUNT(&BS, tmp_decodedBytes)
    tmp_decodedBytes >>= 3;
    nDecodedBytes = 0;

    result = aacdecGetFrame(inPointer + tmp_decodedBytes, &nDecodedBytes,
                            (Ipp16s *)out->GetDataPointer(),
                            (Ipp32s)out->GetBufferSize() -
                            (Ipp32s)((Ipp8u *)out->GetDataPointer() - (Ipp8u *)out->GetBufferPointer()),
                            state);

    if (crc_enable) {
      if (AAC_OK == result) {
        Ipp32s streamCRC;
        aacdecGetCRC(&streamCRC, state);
        if (streamCRC != CRC) {
          result = AAC_BAD_STREAM;
        }
      }
    }

    if (AAC_NOT_ENOUGH_BUFFER == result) {
      MemUnlock();
      return UMC_ERR_NOT_ENOUGH_BUFFER;
    }

    nDecodedBytes += tmp_decodedBytes;

    aacdecGetSbrFlagPresent(&SbrFlagPresent, state);
    aacdecGetFrameSize(&frameSize, state);
    aacdecGetSampleFrequency(&freq, state);
    aacdecGetChannels(&ch, state);

    if (AAC_BAD_STREAM == result) {
      Ipp32s size = frameSize * sizeof(Ipp16s) * ch;

      if (size > ((Ipp32s)out->GetBufferSize() - (Ipp32s)((Ipp8u *)out->GetDataPointer() -
        (Ipp8u *)out->GetBufferPointer()))) {
        MemUnlock();
        return UMC_ERR_NOT_ENOUGH_BUFFER;
      }
    }

    if ((0 == initSubtype) && (1 == SbrFlagPresent)) {
      initSubtype = 1;
      if (m_info.m_stream_subtype == AAC_MAIN_PROFILE) {
        m_info.m_stream_subtype =
          (UMC::AudioStreamSubType) (AAC_MAIN_PROFILE | AAC_HE_PROFILE);
      } else if (m_info.m_stream_subtype == AAC_LC_PROFILE) {
        m_info.m_stream_subtype =
          (UMC::AudioStreamSubType) (AAC_LC_PROFILE | AAC_HE_PROFILE);
      } else if (m_info.m_stream_subtype == AAC_SSR_PROFILE) {
        m_info.m_stream_subtype =
          (UMC::AudioStreamSubType) (AAC_SSR_PROFILE | AAC_HE_PROFILE);
      } else if (m_info.m_stream_subtype == AAC_LTP_PROFILE) {
        m_info.m_stream_subtype =
          (UMC::AudioStreamSubType) (AAC_LTP_PROFILE | AAC_HE_PROFILE);
      }
    }

    if (AAC_MPEG4_STREAM == m_info.m_init_stream_type) {
      in->MoveDataPointer(in->GetDataSize());
    } else {
      in->MoveDataPointer(nDecodedBytes);
    }

    if (AAC_BAD_STREAM == result) {
      Ipp32s size = frameSize * sizeof(Ipp16s) * ch;

      memset(out->GetDataPointer(),0,size);
    }

    {
      AudioData* pAudio = DynamicCast<AudioData,MediaData>(out);

      out->SetDataSize(frameSize * sizeof(Ipp16s) * ch);

      if (pts_start < 0)
        pts_start = m_pts_prev;

      m_pts_prev = pts_end = pts_start +
        ((Ipp64f)frameSize / (Ipp64f)freq);

      in->SetTime(pts_end);
      out->SetTime(pts_start, pts_end);

      m_info.m_frame_number++;

      if (pAudio) {
        pAudio->m_info.bitPerSample = 16;
        pAudio->m_info.bitrate = 0;

        pAudio->m_info.channels = ch;
        pAudio->m_info.sample_frequency = freq;
        pAudio->m_info.stream_type = PCM_AUDIO;

        switch (pAudio->m_info.channels) {
        case 1:
          pAudio->m_info.channel_mask = CHANNEL_FRONT_CENTER;
          break;
        case 2:
          pAudio->m_info.channel_mask  = CHANNEL_FRONT_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_RIGHT;
          break;
        case 3:
          pAudio->m_info.channel_mask  = CHANNEL_FRONT_CENTER;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_RIGHT;
          break;
        case 4:
          pAudio->m_info.channel_mask  = CHANNEL_FRONT_CENTER;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_RIGHT;
          pAudio->m_info.channel_mask |= CHANNEL_LOW_FREQUENCY;
          break;
        case 5:
          pAudio->m_info.channel_mask  = CHANNEL_FRONT_CENTER;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_RIGHT;
          pAudio->m_info.channel_mask |= CHANNEL_BACK_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_BACK_RIGHT;
          break;
        case 6:
          pAudio->m_info.channel_mask  = CHANNEL_FRONT_CENTER;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_FRONT_RIGHT;
          pAudio->m_info.channel_mask |= CHANNEL_BACK_LEFT;
          pAudio->m_info.channel_mask |= CHANNEL_BACK_RIGHT;
          pAudio->m_info.channel_mask |= CHANNEL_LOW_FREQUENCY;
          break;
        default:
          break;
        }
      }
    }

    MemUnlock();
    return StatusAAC_2_UMC(result);
  }

/********************************************************************/

  AACDecoder::~AACDecoder()
  {
    Close();
  }

/********************************************************************/

  Status AACDecoder::Close()
  {
    Status status;

    if ((state == NULL) && (pObjMem == NULL))
      return AAC_OK;

    /* AYA: 24 nov 06 failed if this check delete */
    if( m_pMemoryAllocator == NULL ) {
      return AAC_OK;
    }

    status = MemLock();
    if (status != UMC_OK) {
      vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
      return status;
    }

    aacdecClose(state);

    MemUnlock();

    if (pObjMem) {
      m_pMemoryAllocator->Free(objMemId);
      objMemId = NULL;
    }

    if (state) {
      m_pMemoryAllocator->Free(stateMemId);
      state = NULL;
    }

    BaseCodec::Close();
    return UMC_OK;
  }

/********************************************************************/

  Status  AACDecoder::Reset()
  {
    Status status;

    status = MemLock();
    if (status != UMC_OK) {
      vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
      return status;
    }
    m_pts_prev = 0;
    aacdecReset(state);
    MemUnlock();
    return UMC_OK;
  }

/********************************************************************/

  Status  AACDecoder::GetInfo(BaseCodecParams * info)
  {
    Ipp32s SbrFlagPresent;
    Status status;

    if (!info)
      return UMC_ERR_NULL_PTR;

    AudioCodecParams *p_info =
      DynamicCast < AudioCodecParams, BaseCodecParams > (info);

    status = MemLock();
    if (status != UMC_OK) {
      vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
      return status;
    }

    aacdecGetInfo(&params, state);

    info->m_SuggestedInputSize = params.m_SuggestedInputSize;
    info->m_SuggestedOutputSize = params.m_SuggestedOutputSize;
    info->level = AAC_LEVEL_MAIN;

    if (!p_info)
      return UMC_OK;

    if (params.is_valid) {
      info->profile = m_info.m_audio_object_type;
      aacdecGetSbrFlagPresent(&SbrFlagPresent, state);

      if (SbrFlagPresent) {
        info->profile |= AAC_PROFILE_SBR;
      }

      p_info->m_info_in.bitPerSample = params.m_info_in.bitPerSample;
      p_info->m_info_out.bitPerSample = params.m_info_out.bitPerSample;

      p_info->m_info_in.channels = params.m_info_in.channels;
      p_info->m_info_out.channels = params.m_info_out.channels;

      p_info->m_info_in.stream_type = AAC_AUDIO;
      p_info->m_info_out.stream_type = PCM_AUDIO;

      p_info->m_info_in.sample_frequency = params.m_info_in.sample_frequency;
      p_info->m_info_out.sample_frequency = params.m_info_out.sample_frequency;

      p_info->m_frame_num = m_info.m_frame_number;

      p_info->m_info_in.bitrate = params.m_info_in.bitrate;
      p_info->m_info_out.bitrate = params.m_info_out.bitrate;

      p_info->m_info_in.stream_subtype = m_info.m_stream_subtype;

      p_info->m_info_in.channel_mask = 0;
      switch (p_info->m_info_in.channels) {
      case 1:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_CENTER;
        break;
      case 2:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
        break;
      case 3:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_CENTER;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
        break;
      case 4:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_CENTER;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
        p_info->m_info_in.channel_mask |= CHANNEL_LOW_FREQUENCY;
        break;
      case 5:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_CENTER;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
        p_info->m_info_in.channel_mask |= CHANNEL_BACK_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_BACK_RIGHT;
        break;
      case 6:
        p_info->m_info_in.channel_mask  = CHANNEL_FRONT_CENTER;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
        p_info->m_info_in.channel_mask |= CHANNEL_BACK_LEFT;
        p_info->m_info_in.channel_mask |= CHANNEL_BACK_RIGHT;
        p_info->m_info_in.channel_mask |= CHANNEL_LOW_FREQUENCY;
        break;
      default:
        break;
      }

      p_info->m_info_out.channel_mask = p_info->m_info_in.channel_mask;
    }
    else
    {
        MemUnlock();
        return UMC_WRN_INFO_NOT_READY;
    }

    MemUnlock();
    return UMC_OK;
  }

/********************************************************************/

  Status AACDecoder::GetDuration(Ipp32f *p_duration)
  {
    Status status;
    status = MemLock();
    if (status != UMC_OK) {
      vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
      return status;
    }
    aacdecGetDuration(p_duration, state);
    MemUnlock();
    return UMC_OK;
  }

/********************************************************************/

  Status AACDecoder::StatusAAC_2_UMC(AACStatus st)
  {
    Status res;
    if (st == AAC_OK)
      res = UMC_OK;
    else if (st == AAC_NOT_ENOUGH_DATA)
      res = UMC_ERR_NOT_ENOUGH_DATA;
    else if (st == AAC_BAD_FORMAT)
      res = UMC_ERR_INVALID_STREAM;
    else if (st == AAC_ALLOC)
      res = UMC_ERR_ALLOC;
    else if (st == AAC_BAD_STREAM)
      res = UMC_ERR_INVALID_STREAM;
    else if (st == AAC_NULL_PTR)
      res = UMC_ERR_NULL_PTR;
    else if (st == AAC_NOT_FIND_SYNCWORD)
      res = UMC_ERR_SYNC;
    else if (st == AAC_UNSUPPORTED)
      res = UMC_ERR_UNSUPPORTED;
    else if (st == AAC_BAD_PARAMETER)
      res = UMC_ERR_UNSUPPORTED;
    else
      res = UMC_ERR_UNSUPPORTED;

    return res;
  }

  /****************************************************************************/

  Status AACDecoder::MemLock() {
    AACDec *pOldState = state;
    state = (AACDec *)m_pMemoryAllocator->Lock(stateMemId);
    if (!state) {
      vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
      return UMC_ERR_ALLOC;
    }
    if (state != pOldState) {
      aacdecUpdateStateMemMap(state, (Ipp8u *)state-(Ipp8u *)pOldState);
    }

    if (pObjMem) {  // skip for first GetFrame
      Ipp8u *pOldObjMem = pObjMem;
      pObjMem = (Ipp8u *)m_pMemoryAllocator->Lock(objMemId);
      if (!state) {
        vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
        return UMC_ERR_ALLOC;
      }
      if (pObjMem != pOldObjMem) {
        aacdecUpdateObjMemMap(state, (Ipp8u *)pObjMem-(Ipp8u *)pOldObjMem);
      }
    }

    return UMC_OK;
  }

  /****************************************************************************/

  Status AACDecoder::MemUnlock() {
    if (stateMemId) {
      if (m_pMemoryAllocator->Unlock(stateMemId) != UMC_OK) {
        vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Unlock failed\n"));
        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;
  }

  /****************************************************************************/
};      // namespace UMC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -