📄 ac3_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-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 + -