📄 ac3_dec_api_fp.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// 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 "ac3_dec.h"
#include "ac3_dec_own_fp.h"
#include "ac3_dec_tables.h"
#define AC3_FRAME_SIZE 1920 * 2
#define AC3_UPDATE_PTR(type, ptr, inc) \
if (ptr) { \
ptr = (type*)((Ipp8u*)(ptr) + inc); \
}
/********************************************************************/
void ac3decUpdateMemMap(AC3Dec *state,
Ipp32s shift)
{
Ipp32s i;
for (i = 0; i < 2; i++) {
AC3_UPDATE_PTR(Ipp32f, state->ShortBuff[i], shift)
}
for (i = 0; i < 6; i++) {
AC3_UPDATE_PTR(Ipp32f, state->temp[i], shift)
}
//AC3_UPDATE_PTR(IppsMDCTInvSpec_32f, state->allocation_imdct.pMDCTSpecLong, shift)
//AC3_UPDATE_PTR(IppsMDCTInvSpec_32f, state->allocation_imdct.pMDCTSpecShort, shift)
//AC3_UPDATE_PTR(Ipp8u, state->state->allocation_imdct.pBufferShort, shift)
}
/********************************************************************/
AC3Status ac3decInit(AC3Dec *state,
Ipp32s *sizeAll)
{
Ipp8u *ptr, *ptrWork, *ptrInit;
Ipp32s i, size, sizeOfAC3Dec;
Ipp32s sizeInit = 0;
Ipp32s sizeWork = 0;
Ipp32s sizeSpecInvLong = 0;
Ipp32s sizeSpecInvShort = 0;
Ipp32s sizeInitTmp = 0;
Ipp32s sizeWorkTmp = 0;
sizeOfAC3Dec = (sizeof(AC3Dec) + 15) & (~15);
size = sizeOfAC3Dec + 256 * sizeof(Ipp32f);
if (ippsMDCTInvGetSize_32f(512, &sizeSpecInvLong, &sizeInitTmp, &sizeWorkTmp) != ippStsOk) {
return AC3_ALLOC;
}
if (sizeInit < sizeInitTmp) sizeInit = sizeInitTmp;
if (sizeWork < sizeWorkTmp) sizeWork = sizeWorkTmp;
if (ippsMDCTInvGetSize_32f(256, &sizeSpecInvLong, &sizeInitTmp, &sizeWorkTmp) != ippStsOk) {
return AC3_ALLOC;
}
if (sizeInit < sizeInitTmp) sizeInit = sizeInitTmp;
if (sizeWork < sizeWorkTmp) sizeWork = sizeWorkTmp;
size += sizeSpecInvLong + sizeSpecInvShort + sizeWork + sizeInit;
*sizeAll = size;
if (state) {
ippsZero_8u((Ipp8u*)state, size);
state->ShortBuff[0] = (Ipp32f*)((Ipp8u*)state + sizeOfAC3Dec);
state->ShortBuff[1] = state->ShortBuff[0] + 128;
ptr = (Ipp8u*)state->ShortBuff[1];
state->allocation_imdct.pMDCTSpecLong = NULL;
state->allocation_imdct.pMDCTSpecShort = NULL;
state->allocation_imdct.pBufferLong = NULL;
state->allocation_imdct.pBufferShort = NULL;
ptrWork = ptr + sizeSpecInvLong + sizeSpecInvShort;
ptrInit = ptrWork + sizeWork;
#if 0
if (ippsMDCTInvInit_32f(&(state->allocation_imdct.pMDCTSpecLong), 512,
ptr, ptrInit) != ippStsOk)
return AC3_ALLOC;
if (ippsMDCTInvInit_32f(&(state->allocation_imdct.pMDCTSpecShort), 256,
ptr + sizeSpecInvLong, ptrInit) != ippStsOk)
return AC3_ALLOC;
#else
if (ippsMDCTInvInitAlloc_32f(&(state->allocation_imdct.pMDCTSpecLong), 512) != ippStsOk)
return AC3_ALLOC;
if (ippsMDCTInvInitAlloc_32f(&(state->allocation_imdct.pMDCTSpecShort), 256) != ippStsOk)
return AC3_ALLOC;
ptrWork = (Ipp8u*)ippsMalloc_8u(size);
if (ptrWork == NULL)
return AC3_ALLOC;
#endif
state->allocation_imdct.pBufferLong =
state->allocation_imdct.pBufferShort = ptrWork;
state->out_acmod = 0;
state->outlfeon = 0;
state->dualmonomode = 0;
state->drc_scaleLow = 1;
state->drc_scaleHigh = 1;
state->out_compmod = 0;
state->karaokeCapable = 3;
state->crc_mute = 0;
state->as_input = 0;
state->nChannelOut = 2;
state->gainScale = 1;
for (i = 0; i < 7; i++) {
state->lfedeltba[i] = 0;
}
ac3decReset(state);
}
return AC3_OK;
}
/********************************************************************/
AC3Status ac3decReset(AC3Dec *state)
{
Ipp32s i;
if (!state)
return AC3_NULL_PTR;
state->m_frame_number = 0;
state->syncinfo.frame_size = AC3_FRAME_SIZE;
for (i = 0; i < 6; i++) {
ippsZero_32f(state->coeffs[i], 256);
ippsZero_32f(state->delay[i], 256);
state->temp[i] = state->coeffs[i];
}
state->mants_tabls.dithtemp = 1;
state->m_frame_number = 0;
state->nChannelOut = NFCHANS[state->out_acmod] +
state->outlfeon;
for (i = 0; i < 5; i++) {
state->audblk.chexpstr[i] = 0;
}
return AC3_OK;
}
/********************************************************************/
AC3Status ac3decClose(AC3Dec *state)
{
if (state == NULL)
return AC3_OK;
if (state->allocation_imdct.pMDCTSpecLong) {
ippsMDCTInvFree_32f(state->allocation_imdct.pMDCTSpecLong);
state->allocation_imdct.pMDCTSpecLong = NULL;
}
if (state->allocation_imdct.pMDCTSpecShort) {
ippsMDCTInvFree_32f(state->allocation_imdct.pMDCTSpecShort);
state->allocation_imdct.pMDCTSpecShort = NULL;
}
if (state->allocation_imdct.pBufferLong) {
ippsFree(state->allocation_imdct.pBufferLong);
state->allocation_imdct.pBufferLong = NULL;
state->allocation_imdct.pBufferShort = NULL;
}
return AC3_OK;
}
/********************************************************************/
AC3Status ac3decGetFrame(Ipp8u *inPointer,
Ipp32s inDataSize,
Ipp32s *decodedBytes,
Ipp16s *outPointer,
Ipp32s outBufferSize,
AC3Dec *state)
{
AC3Status result;
Ipp32s cbErrors = 0;
Ipp32s unused_bits_sync, unused_bits;
Ipp32s nChannelOut;
Ipp32s nblk;
Ipp32s cbMantErrors = 0, cbExpErrors = 0;
Ipp32s sizeCrc1, firstBadBlock;
Ipp32s start_bits;
Ipp32s crc1, crc2;
Ipp32s goodFrame;
sBitsreamBuffer BS;
sBitsreamBuffer *pBS = &BS;
Ipp8u *ptrCrc;
if (!inPointer || !outPointer || !state)
return AC3_NULL_PTR;
GET_INIT_BITSTREAM(pBS, inPointer)
result = GetSynch(pBS, inDataSize);
GET_BITS_COUNT(pBS, unused_bits_sync)
start_bits = unused_bits_sync - 16;
unused_bits_sync = inDataSize * 8 - unused_bits_sync;
if (result != AC3_OK) {
*decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
if (*decodedBytes < 0) *decodedBytes = 0;
return AC3_NOT_FIND_SYNCWORD;
}
if (unused_bits_sync < 24) {
*decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
if (*decodedBytes < 0) *decodedBytes = 0;
return AC3_NOT_ENOUGH_DATA;
}
ptrCrc = (Ipp8u*)(pBS->pCurrent_dword) - (pBS->nBit_offset >> 3) + 4;
cbErrors = ParseSyncInfo(state, pBS);
GET_BITS_COUNT(pBS, unused_bits)
unused_bits = inDataSize * 8 - unused_bits;
if (cbErrors != 0) {
*decodedBytes = inDataSize - ((unused_bits + 7) >> 3);
if (*decodedBytes < 0) *decodedBytes = 0;
return AC3_BAD_STREAM;
}
if (unused_bits < state->syncinfo.frame_size * 16 - 16 - 24) {
*decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
if (*decodedBytes < 0) *decodedBytes = 0;
return AC3_NOT_ENOUGH_DATA;
}
sizeCrc1 = (state->syncinfo.frame_size >> 1) + (state->syncinfo.frame_size >> 3);
crc1 = crcCheck(2 * (sizeCrc1 - 1), ptrCrc);
ptrCrc += 2 * (sizeCrc1 - 1);
crc2 = crcCheck(2 * (state->syncinfo.frame_size - sizeCrc1), ptrCrc);
crc2 += crc1;
if (crc1 == 0) {
ippsZero_8u((Ipp8u*)&(state->bsi), sizeof(_BSI));
cbErrors = ParseBsi(state, pBS);
GET_BITS_COUNT(pBS, unused_bits)
unused_bits = inDataSize * 8 - unused_bits;
if (cbErrors != 0) {
*decodedBytes = inDataSize - ((unused_bits + 7) >> 3);
if (*decodedBytes < 0) *decodedBytes = 0;
return AC3_BAD_STREAM;
}
}
nChannelOut = state->nChannelOut;
if (outBufferSize < nChannelOut*256*6*sizeof(Ipp16s)) {
*decodedBytes = 0;
return AC3_NOT_ENOUGH_BUFFER;
}
firstBadBlock = 1;
goodFrame = 1;
for (nblk = 0; nblk < 6; nblk++) {
if (((nblk <= 1) && (crc1 != 0)) ||
((nblk > 1) && (crc2 != 0))) {
goodFrame = 0;
}
if (goodFrame) {
if (ParseAudblk(nblk, state, pBS) < 1) {
goodFrame = 0;
}
}
if (goodFrame) {
cbExpErrors += DecodeExponents(state);
BitAllocation(state);
cbMantErrors += UnpackMantissas(state, pBS);
if (state->bsi.acmod == 0x2)
Rematrix(state);
if (((state->audblk.blksw == 0) ||
(state->audblk.blksw == ((1 << state->bsi.nfchans) - 1))) &&
((state->nChannelOut - state->bsi.lfeon) < state->bsi.nfchans)) {
Downmix(state->audblk.dynrng, state->audblk.dynrng2,
1, state);
InverseTransform(0, state);
} else {
InverseTransform(1, state);
Downmix(state->audblk.dynrng, state->audblk.dynrng2,
0, state);
}
WindowingOverlap(outPointer, state);
} else {
if (state->crc_mute) {
if (firstBadBlock) {
Ipp32s i;
firstBadBlock = 0;
for (i = 0; i < nChannelOut; i++) {
ippsZero_32f(state->temp[i], 512);
}
WindowingOverlap(outPointer, state);
} else {
ippsZero_8u((Ipp8u*)outPointer, nChannelOut*256*2);
}
} else {
Ipp32s i;
Ipp32f *pDataTemp[6];
for (i = 0; i < state->nChannelOut; i++) {
ippsAddProduct_32f(WindowTable, state->temp[i], state->delay[i], 256);
pDataTemp[i] = state->delay[i];
}
if (state->gainScale != 1) {
for (i = 0; i < state->nChannelOut; i++) {
ippsMulC_32f_I(state->gainScale, state->delay[i], 256);
}
}
ippsJoin_32f16s_D2L((const Ipp32f **)pDataTemp, nChannelOut,
256, (Ipp16s*)outPointer);
for (i = 0; i < state->nChannelOut; i++) {
ippsMul_32f(WindowTable + 256, state->temp[i] + 256,
state->delay[i], 256);
}
}
}
outPointer += nChannelOut*256;
}
if (goodFrame) {
ParseAuxdata(state, pBS, start_bits);
GET_BITS_COUNT(pBS, (*decodedBytes))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -