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

📄 ac3_decoder.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 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-2005 Intel Corporation. All Rights Reserved.//*/#include <stdlib.h>#include <string.h>#include <ipps.h>#include "umc_ac3_decoder.h"#include "ac3dec_tables.h"#include "vm_debug.h"UMC::AC3Decoder::AC3Decoder(){  data_vectors.stream_coeffs.ShortBuff[0] = NULL;  data_vectors.stream_coeffs.ShortBuff[1] = NULL;  allocation_imdct.pMDCTSpecLong = NULL;  allocation_imdct.pMDCTSpecShort = NULL;  allocation_imdct.pBufferLong = NULL;  allocation_imdct.pBufferShort = NULL;  for(int i = 0; i < 6; i++)    audblk[i] = NULL;}UMC::Status UMC::AC3Decoder::Init(BaseCodecParams* init){  UMC::Status res;  int n, size, size_short;  AudioCodecParams* a_init = DynamicCast<AudioCodecParams,BaseCodecParams>(init);  if (NULL == a_init)    return UMC_NULL_PTR;  m_params = *a_init;  if (a_init) {    syncinfo.bit_rate = (Ipp16u)a_init->m_info_in.bitrate;    syncinfo.SampleRate = (float)a_init->m_info_out.sample_frequency;  }  syncinfo.frame_size = 1920 * 2;  audblk[0] = new _AudBlk;  if (!audblk[0])    return UMC_FAILED_TO_ALLOCATE_BUFFER;  for (int i = 1; i < 6; i++) {    audblk[i] = audblk[0];  }  data_vectors.stream_coeffs.ShortBuff[0] = ippsMalloc_32f(128);  data_vectors.stream_coeffs.ShortBuff[1] = ippsMalloc_32f(128);  ippsZero_32f( data_vectors.stream_samples.delay[0], 256*6);  ippsZero_32f( &(data_vectors.stream_coeffs.channel[5][0]), 256); /* LFE */  ippsMDCTInvInitAlloc_32f( &allocation_imdct.pMDCTSpecLong, 512 );  ippsMDCTInvGetBufSize_32f( allocation_imdct.pMDCTSpecLong, &size );  ippsMDCTInvInitAlloc_32f( &allocation_imdct.pMDCTSpecShort, 256 );  ippsMDCTInvGetBufSize_32f( allocation_imdct.pMDCTSpecShort, &size_short );  if (size_short > size) size = size_short;  allocation_imdct.pBufferLong = ( Ipp8u* )ippsMalloc_8u( size );  if (!allocation_imdct.pBufferLong)    return UMC_FAILED_TO_INITIALIZE;//code error  allocation_imdct.pBufferShort = allocation_imdct.pBufferLong;  dataBuffer.pBuffer = NULL;  dataBuffer.iDWDoneNum = 0;  dataBuffer.iReceivedBytes = 0;  dataBuffer.iBitOffset = 32;  mants_tabls.dithtemp = 1;  // Make Fast Mantissa Lookups  for( n=0; n < 32; n++){    mants_tabls.fastM_9[n][0] = (Ipp16u)( n / 9 );    mants_tabls.fastM_9[n][1] = (Ipp16u)( (n % 9) / 3 );    mants_tabls.fastM_9[n][2] = (Ipp16u)( (n % 9) % 3 );  }  for( n=0; n < 128; n++){    mants_tabls.fastM_25[n][0] = (Ipp16u)( n / 25 );    mants_tabls.fastM_25[n][1] = (Ipp16u)( (n % 25) / 5 );    mants_tabls.fastM_25[n][2] = (Ipp16u)( (n % 25) % 5 );  }  for( n=0; n < 128; n++){    mants_tabls.fastM_11[n][0] = (Ipp16u)( n / 11 );    mants_tabls.fastM_11[n][1] = (Ipp16u)( n % 11 );  }  for( n=0; n < 7; n++) {    mants_tabls.m_pointers[n] = 0;  }  m_frame_num = 0;  m_pts_prev  = 0.;  nChannelOut = NFCHANS[decoder_settings.out_acmod] +                        decoder_settings.outlfeon;  return UMC_OK;}UMC::Status UMC::AC3Decoder::GetFrame(MediaData* in, MediaData* out){  UMC::Status res;  int cbErrors = 0;  int unused_bits_sync, unused_bits, shift;  ReceiveBuffer(in);  res = GetSynch();  if (res != UMC_OK) {    return UMC_NOT_FIND_SYNCWORD;  }  unused_bits_sync = get_unused_bits();  if (unused_bits_sync < 24) {    in->MoveDataPointer(in->GetDataSize() - ((unused_bits_sync + 16 + 7) >> 3));    return UMC_NOT_ENOUGH_DATA;  }  crcInit();  cbErrors = ParseSyncInfo();  if (cbErrors != 0) {    return UMC_BAD_STREAM;  }  unused_bits = get_unused_bits();  if (unused_bits < syncinfo.frame_size * 16 - 16 - 24) {    in->MoveDataPointer(in->GetDataSize() - ((unused_bits_sync + 16 + 7) >> 3));    return UMC_NOT_ENOUGH_DATA;  }  res = DecodeFrame(out);  if (first_frame) {    first_frame = false;  }  shift = dataBuffer.iDWDoneNum*4 + (32-dataBuffer.iBitOffset+7)/8 -    (((int)in->GetDataPointer()) & 3);  if (shift && (UMC_OK == res || UMC_BAD_STREAM == res)) {    double pts_start = in->GetTime();    double pts_end;    if (pts_start == -1.0)      pts_start = m_pts_prev;    m_pts_prev = pts_end = pts_start + (256.0*6.0)/syncinfo.SampleRate;    in->MoveDataPointer(shift);    in->SetTime(pts_end);    out->SetDataSize(nChannelOut*256*6*2);    out->SetTime(pts_start, pts_end);  }  return res;}UMC::Status UMC::AC3Decoder::GetSynch(){  Ipp16u syncw;  if (get_unused_bits() < 16)    return UMC_NOT_FIND_SYNCWORD;  syncw = (Ipp16u)(getbits(16));  for (;;) {    if(syncw == 0x0b77 )      break;    if (get_unused_bits() < 8)      return UMC_NOT_FIND_SYNCWORD;    syncw  = (Ipp16u)( syncw << 8 );    syncw |= (Ipp16u)getbits(8);  }  dataBuffer.total_bits_read = 16;  syncinfo.syncword = syncw;  m_frame_num++;  return UMC_OK;}UMC::Status UMC::AC3Decoder::SetParams(BaseCodecParams * params) {  AC3DecoderParams *info = DynamicCast < AC3DecoderParams > (params);  if (info) {    if ((info->out_acmod < 0) || (info->out_acmod > 7))      return UMC_FLAGS_ERROR;    decoder_settings.out_acmod = info->out_acmod;    if ((info->outlfeon < 0) || (info->outlfeon > 1))      return UMC_FLAGS_ERROR;    decoder_settings.outlfeon = info->outlfeon;    if ((info->dualmonomode < 0) || (info->dualmonomode > 3))      return UMC_FLAGS_ERROR;    decoder_settings.dualmonomode = info->dualmonomode;    if ((info->drc_scaleLow < 0.0) || (info->drc_scaleLow > 1.0))      return UMC_FLAGS_ERROR;    decoder_settings.drc_scaleLow = info->drc_scaleLow;    if ((info->drc_scaleHigh < 0.0) || (info->drc_scaleHigh > 1.0))      return UMC_FLAGS_ERROR;    decoder_settings.drc_scaleHigh = info->drc_scaleHigh;    if ((info->out_compmod < 0) || (info->out_compmod > 3))      return UMC_FLAGS_ERROR;    decoder_settings.out_compmod = info->out_compmod;    if ((info->karaokeCapable < -1) || (info->karaokeCapable > 3))      return UMC_FLAGS_ERROR;    decoder_settings.karaokeCapable = info->karaokeCapable;    if ((info->crc_mute < 0) || (info->crc_mute > 1))      return UMC_FLAGS_ERROR;    decoder_settings.crc_mute = info->crc_mute;    nChannelOut = NFCHANS[decoder_settings.out_acmod] +                  decoder_settings.outlfeon;  } else {    return UMC_NOT_INITIALIZED;  }  return UMC_OK;}UMC::Status UMC::AC3Decoder::DecodeFrame(MediaData* out){  short* pOut = (short*)out->GetDataPointer();  int  nblk;  int  cbErrors = 0;  int  cbMantErrors = 0, cbExpErrors = 0;  int  sizeCrc1, firstBadBlock;  unsigned short crc1, crc2;  if (out->GetBufferSize() < (size_t)(nChannelOut*256*6))    return UMC_NOT_ENOUGH_BUFFER;  sizeCrc1 = (syncinfo.frame_size >> 1) + (syncinfo.frame_size >> 3);  crcCheck(sizeCrc1 - 1);  crc1 = dataBuffer.state;  crcCheck(syncinfo.frame_size - sizeCrc1);  crc2 = dataBuffer.state;  if (crc1 == 0) {    ippsZero_8u((Ipp8u*)&bsi, sizeof(_BSI));    cbErrors = ParseBsi();    if (cbErrors != 0) {      return UMC_BAD_STREAM;    }    ippsZero_8u((Ipp8u*)audblk[0],sizeof(_AudBlk));  }  firstBadBlock = 1;  for (nblk = 0; nblk < 6; nblk++) {    if (((nblk <= 1) && (crc1 == 0)) ||        ((nblk > 1) && (crc2 == 0))) {      ParseAudblk(nblk);      cbExpErrors += DecodeExponents(nblk);      BitAllocation(nblk);      cbMantErrors += UnpackMantissas(nblk);      DeCoupling(nblk);      if (bsi.acmod == 0x2)        Rematrix(nblk);      InverseTransform(nblk);      Downmix(audblk[nblk]->dynrng, audblk[nblk]->dynrng2);      WindowingOverlap(pOut);    } else {      if (decoder_settings.crc_mute) {        if (firstBadBlock) {          int i;          firstBadBlock = 0;          for (i = 0; i < nChannelOut; i++) {            ippsZero_32f(data_vectors.temp[i], 512);          }          WindowingOverlap(pOut);        }   else {          ippsZero_8u((Ipp8u*)pOut, nChannelOut*256*2);        }      } else {        int i;        Ipp32f dataTemp[6][256];        Ipp32f *pDataTemp[6];        for (i = 0; i < nChannelOut; i++) {          ippsAdd_32f(data_vectors.temp[i],                      data_vectors.stream_samples.delay[i],                      dataTemp[i], 256);          ippsMulC_32f_I(GAINSCALE, dataTemp[i], 256);          ippsCopy_32f(&(data_vectors.temp[i][256]),                         data_vectors.stream_samples.delay[i], 256);          pDataTemp[i] = dataTemp[i];        }        ippsJoin_32f16s_D2L((const Ipp32f **)pDataTemp,                             nChannelOut, 256, (Ipp16s*)pOut);      }    }    pOut += nChannelOut*256;  }  if ((crc1 == 0) && (crc2 == 0))  {    ParseAuxdata();  } else {    dataBuffer.total_bits_read = (dataBuffer.ptrCrc -                                (unsigned char *)dataBuffer.pBuffer) * 8;    dataBuffer.iDWDoneNum = dataBuffer.total_bits_read >> 5;    dataBuffer.iBitOffset = 32 - (dataBuffer.total_bits_read -                                  dataBuffer.iDWDoneNum * 32);  }  {    AudioData* pAudio = DynamicCast<AudioData,MediaData>(out);    if (pAudio) {      pAudio->m_info.bitPerSample = 16;      pAudio->m_info.bitrate = 0;      pAudio->m_info.channels = nChannelOut;      pAudio->m_info.sample_frequency = (int)syncinfo.SampleRate;      pAudio->m_info.stream_type = PCM_AUDIO;    }  }  return UMC_OK;}UMC::AC3Decoder::~AC3Decoder(){  Close();}UMC::Status UMC::AC3Decoder::Close(){  if (data_vectors.stream_coeffs.ShortBuff[0]) {    ippsFree(data_vectors.stream_coeffs.ShortBuff[0]);    data_vectors.stream_coeffs.ShortBuff[0] = NULL;  }  if (data_vectors.stream_coeffs.ShortBuff[1]) {    ippsFree(data_vectors.stream_coeffs.ShortBuff[1]);    data_vectors.stream_coeffs.ShortBuff[1] = NULL;  }  if (allocation_imdct.pMDCTSpecLong) {    ippsMDCTInvFree_32f(allocation_imdct.pMDCTSpecLong);    allocation_imdct.pMDCTSpecLong = NULL;  }  if (allocation_imdct.pMDCTSpecShort) {    ippsMDCTInvFree_32f(allocation_imdct.pMDCTSpecShort);    allocation_imdct.pMDCTSpecShort = NULL;  }  if (allocation_imdct.pBufferLong) {    ippsFree(allocation_imdct.pBufferLong);    allocation_imdct.pBufferLong = NULL;  }  delete audblk[0];  for(int j = 0; j < 6; j++) {    audblk[j] = NULL;  }  return UMC_OK;}UMC::Status UMC::AC3Decoder::Reset(){  Close();  Init(&m_params);  first_frame = true;  return UMC_OK;}UMC::Status UMC::AC3Decoder::GetInfo(BaseCodecParams* info){  if (!info)    return UMC_NULL_PTR;  AudioCodecParams* a_info = DynamicCast<AudioCodecParams,BaseCodecParams>(info);  info->m_SuggestedInputSize = syncinfo.frame_size;  if (a_info) {    a_info->m_info_in.bitPerSample = 0;    a_info->m_info_out.bitPerSample = 16;    a_info->m_info_in.bitrate      = syncinfo.bit_rate * 1000;    a_info->m_info_out.bitrate     = 0;    a_info->m_info_in.channels = nChannelOut;    a_info->m_info_out.channels = nChannelOut;    a_info->m_info_in.stream_type  = AC3_AUDIO;    a_info->m_info_out.stream_type  = PCM_AUDIO;    a_info->m_info_in.sample_frequency = (int)syncinfo.SampleRate;    a_info->m_info_out.sample_frequency = (int)syncinfo.SampleRate;    a_info->m_info_in.channels = nChannelOut;    a_info->m_info_out.channels = nChannelOut;        a_info->m_frame_num = m_frame_num;  }    return UMC_OK;}UMC::StatusUMC::AC3Decoder::GetDuration(float* p_duration){  float duration;  duration  = (float)m_frame_num;  duration *= 6*256;  duration /= syncinfo.SampleRate;  p_duration[0] = duration;  return UMC_OK;}int UMC::AC3Decoder::get_unused_bits(){  return (dataBuffer.iReceivedBytes * 8 - (dataBuffer.iDWDoneNum + 1) * 32 +          dataBuffer.iBitOffset);}

⌨️ 快捷键说明

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