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

📄 mp3dec_int.cpp

📁 audio-video-codecs.rar语音编解码器
💻 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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "ipps.h"

#include "umc_mp3_dec.h"
#include "umc_mp3_decoder_params.h"
#include "mp3dec.h"

namespace UMC {

    AudioCodec *newMP3DecoderInt() { return (new MP3DecoderInt); }

    MP3DecoderInt::MP3DecoderInt()
    {
        state = NULL;
        stateMemId = 0;
    }

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

    Status MP3DecoderInt::Init(BaseCodecParams *init)
    {
        Ipp32s size;
        MP3Status status;
        MP3DecoderParams* pMP3DecoderParams;

        // 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;
        }

        pMP3DecoderParams = DynamicCast<MP3DecoderParams, BaseCodecParams>(init);
        if (pMP3DecoderParams) {
          m_syncro_mode = pMP3DecoderParams->synchro_mode;
        } else {
          m_syncro_mode = 0;
        }

        status = mp3idecInit(NULL, m_syncro_mode, &size);
        if (status != MP3_OK)
          return StatusMP3_2_UMC(status);

        if (m_pMemoryAllocator->Alloc(&stateMemId, size,
          UMC_ALLOC_PERSISTENT) != UMC_OK) {
            vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External allocation failed\n"));
            return UMC_ERR_ALLOC;
          }

        state = (MP3Dec *)m_pMemoryAllocator->Lock(stateMemId);
        if(!state) {
          vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
          return UMC_ERR_ALLOC;
        }

        status = mp3idecInit(state, m_syncro_mode, &size);
        if (status != MP3_OK)
          return StatusMP3_2_UMC(status);

        params.is_valid = 0;
        m_frame_num = 0;
        m_pts_prev = 0;

        MemUnlock();

        return StatusMP3_2_UMC(status);
    }

    Status MP3DecoderInt::GetFrame(MediaData* in, MediaData* out)
    {
        MP3Status resMP3;
        Ipp32s shift = 0;
        Ipp32s frameSize, freq, ch, ch_mask;
        Ipp8u  *in_ptr;
        Ipp16s *out_ptr;
        Ipp32s in_size, out_size;

        if (!in || !in->GetDataPointer() || !out || !out->GetDataPointer())
            return UMC_ERR_NULL_PTR;

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

        in_ptr = (Ipp8u *)in->GetDataPointer();
        in_size = in->GetDataSize();
        out_ptr = (Ipp16s *)out->GetDataPointer();
        out_size = (out->GetBufferSize() - ((Ipp8u*)out_ptr -
          (Ipp8u*)out->GetBufferPointer())) / sizeof(Ipp16s);
        resMP3 = mp3idecGetFrame(in_ptr, in_size, &shift, out_ptr, out_size, state);

        if (shift) {
            if ((MP3_OK == resMP3 || MP3_BAD_STREAM == resMP3)) {
                Ipp64f  pts_start = in->GetTime();
                Ipp64f  pts_end;

                mp3idecGetFrameSize(&frameSize, state);
                mp3idecGetSampleFrequency(&freq, state);
                mp3idecGetChannels(&ch, &ch_mask, state);

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

                in->MoveDataPointer(shift);
                in->SetTime(pts_end);

                if (out_size >= frameSize * ch) {
                  if(MP3_BAD_STREAM == resMP3) {
                    resMP3 = MP3_OK;
                    ippsZero_16s(out_ptr, frameSize * ch);
                  }
                  out->SetDataSize(frameSize * sizeof(Ipp16s) * ch);
                  out->SetTime(pts_start, pts_end);
                } else {
                  resMP3 = MP3_NOT_ENOUGH_BUFFER;
                }

                AudioData* pAudio    = DynamicCast<AudioData,MediaData>(out);
                if ((MP3_OK == resMP3 && 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;

                }
                m_frame_num++;
            }
            else {
                in->MoveDataPointer(shift);
            }
        }

        MemUnlock();

        return StatusMP3_2_UMC(resMP3);
    }

    Status MP3DecoderInt::Close()
    {
        Status status = MemLock();
        if (status != UMC_OK) {
          vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
          return UMC_OK;
        }
        mp3idecClose(state);
        MemUnlock();

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

        BaseCodec::Close();

        return UMC_OK;
    }

    Status MP3DecoderInt::Reset()
    {
//        params.is_valid = 0;
        m_pts_prev  = 0;
        m_frame_num = 0;

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

        return UMC_OK;
    }

    Status MP3DecoderInt::GetInfo(BaseCodecParams * info)
    {
        if (!info)
            return UMC_ERR_NULL_PTR;

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

        Status status = MemLock();
        if (status != UMC_OK) {
          vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
          return status;
        }
        mp3idecGetInfo(&params, state);
        MemUnlock();

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

        if (!a_info)
          return UMC_OK;

        if (params.is_valid) {
            a_info->m_info_in.bitPerSample = params.m_info_in.bitPerSample;
            a_info->m_info_out.bitPerSample = params.m_info_out.bitPerSample;

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

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

            a_info->m_info_in.channel_mask = 0;

            if (params.m_info_in.channel_mask & MP3_CHANNEL_STEREO)
              a_info->m_info_in.channel_mask  |= (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT);

            if (params.m_info_in.channel_mask & MP3_CHANNEL_CENTER)
              a_info->m_info_in.channel_mask  |= CHANNEL_FRONT_CENTER;

            a_info->m_info_out.channel_mask = a_info->m_info_in.channel_mask;

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

            switch (params.m_info_in.stream_type) {
          case MP1L1_AUD:
              a_info->m_info_in.stream_type = MP1L1_AUDIO;
              info->profile = MP3_PROFILE_MPEG1;
              info->level = MP3_LEVEL_LAYER1;
              break;
          case MP1L2_AUD:
              a_info->m_info_in.stream_type = MP1L2_AUDIO;
              info->profile = MP3_PROFILE_MPEG1;
              info->level = MP3_LEVEL_LAYER2;
              break;
          case MP1L3_AUD:
              a_info->m_info_in.stream_type = MP1L3_AUDIO;
              info->profile = MP3_PROFILE_MPEG1;
              info->level = MP3_LEVEL_LAYER3;
              break;
          case MP2L1_AUD:
              a_info->m_info_in.stream_type = MP2L1_AUDIO;
              info->profile = MP3_PROFILE_MPEG2;
              info->level = MP3_LEVEL_LAYER1;
              break;
          case MP2L2_AUD:
              a_info->m_info_in.stream_type = MP2L2_AUDIO;
              info->profile = MP3_PROFILE_MPEG2;
              info->level = MP3_LEVEL_LAYER2;
              break;
          case MP2L3_AUD:
              a_info->m_info_in.stream_type = MP2L3_AUDIO;
              info->profile = MP3_PROFILE_MPEG2;
              info->level = MP3_LEVEL_LAYER3;
              break;
          default:
              break;
            };

            a_info->m_info_out.stream_type = PCM_AUDIO;

            a_info->m_frame_num = params.m_frame_num;

            return UMC_OK;
        }

        return UMC_WRN_INFO_NOT_READY;
    }

    Status MP3DecoderInt::GetDuration(Ipp32f *p_duration)
    {
        if(!p_duration)
          return UMC_ERR_NULL_PTR;

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

    Status MP3DecoderInt::StatusMP3_2_UMC(MP3Status st)
    {
        Status res;
        if (st == MP3_OK)
            res = UMC_OK;
        else if (st == MP3_NOT_ENOUGH_DATA)
            res = UMC_ERR_NOT_ENOUGH_DATA;
        else if (st == MP3_BAD_FORMAT)
            res = UMC_ERR_INVALID_STREAM;
        else if (st == MP3_ALLOC)
            res = UMC_ERR_ALLOC;
        else if (st == MP3_BAD_STREAM)
            res = UMC_ERR_INVALID_STREAM;
        else if (st == MP3_NULL_PTR)
            res = UMC_ERR_NULL_PTR;
        else if (st == MP3_NOT_FIND_SYNCWORD)
            res = UMC_ERR_SYNC;
        else if (st == MP3_NOT_ENOUGH_BUFFER)
            res = UMC_ERR_NOT_ENOUGH_BUFFER;
        else if (st == MP3_FAILED_TO_INITIALIZE)
            res = UMC_ERR_INIT;
        else if (st == MP3_UNSUPPORTED)
            res = UMC_ERR_UNSUPPORTED;
        else
            res = UMC_ERR_UNSUPPORTED;

        return res;
    }

    Status MP3DecoderInt::MemLock() {
      MP3Dec *pOldState = state;

      if (!m_pMemoryAllocator) {
        vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed: m_pMemoryAllocator is NULL\n"));
        return UMC_ERR_ALLOC;
      }

      state = (MP3Dec *)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) {
        mp3idecUpdateMemMap(state, (Ipp8u *)state-(Ipp8u *)pOldState);
      }
      return UMC_OK;
    }

    Status MP3DecoderInt::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;
        }
      }
      return UMC_OK;
    }
}

⌨️ 快捷键说明

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