diff -r 000000000000 -r 951a5db380a0 videoeditorengine/audioeditorengine/codecs/AAC/src/ProcAACFrameHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/audioeditorengine/codecs/AAC/src/ProcAACFrameHandler.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,620 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* +*/ + + + + +#include "ProcAACFrameHandler.h" +#include "ProcFrameHandler.h" +#include "ProcTools.h" +#include "nok_bits.h" +#include "AACAPI.h" + +#include +#include + + +TBool CProcAACFrameHandler::ManipulateGainL(const HBufC8* aFrameIn, HBufC8*& aFrameOut, TInt8 aGain) + { + + if (aFrameIn == 0) + return EFalse; + + + TInt numBlocks = 1; + TInt headerBytes = CalculateNumberOfHeaderBytes(aFrameIn, numBlocks); + + // Unfortunately const casting is needed to avoid unecessary temporary arrays + // and we don't have a separate bitstream class for const objects + // Just have to make very sure not to modify const descriptors!! + TUint8* buf = const_cast(aFrameIn->Right(aFrameIn->Size()-headerBytes).Ptr()); + + uint8* gains = new (ELeave) uint8[16]; + uint32* gainPos = new (ELeave) uint32[16]; + + TInt bufLen = aFrameIn->Size()-headerBytes; + + TBitStream bs; + TBitStream bs2; + + BsInit(&bs, buf, bufLen); + BsInit(&bs2, buf, bufLen); + + for (TInt b = 0 ; b < numBlocks ; b++) + { + + TInt b_i = bs.buf_index; + iFrameStarts.Append(b_i+headerBytes); + + BsSaveBufState(&bs, &bs2); + + uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos); + + if (numberOfGains > 2) + { + // illegal frame?? + delete[] gainPos; + delete[] gains; + return KErrGeneral; + + } + + if (bs.buf_index > 0) + iFrameLengths.Append(bs.buf_index - b_i); + else + iFrameLengths.Append(bs.buf_len - b_i); + + if (headerBytes > 7) + { + bs.buf_index += 2; // crc + bs.slots_read += 2; + bs.bits_read += 16; + + } + + TInt tmpGain = aGain*500; + int16 newGain = static_cast(tmpGain/1500); + + + for (TInt a = 0 ; a < numberOfGains ; a++) + { + if (gains[a] + newGain > 255) + { + gains[a] = 255; + } + else if (gains[a] + newGain < 0) + { + gains[a] = 0; + } + else + { + gains[a] = static_cast(gains[a]+newGain); + } + } + + + if (iAACInfo.isSBR || iAACInfo.iIsParametricStereo) + { + + uint8 *data = new (ELeave) uint8[1024]; + CleanupStack::PushL(data); + TBitStream bsOut; + + BsInit(&bsOut, data, 1024); + + SetAACPlusGlobalGains(&bs2, &bsOut, iDecHandle, static_cast(-newGain), numberOfGains, gains, gainPos); + + TInt incBytes = (bsOut.bits_read >> 3) - bs2.buf_len; + iFrameLengths[iFrameLengths.Count()-1] +=incBytes; + + TInt newSize = aFrameIn->Size()+incBytes; + aFrameOut = HBufC8::NewL(newSize); + aFrameOut->Des().Append(aFrameIn->Left(headerBytes)); + aFrameOut->Des().Append(bsOut.bit_buffer, bsOut.bits_read >> 3); + + if (headerBytes != 0) UpdateHeaderL(aFrameOut); + + CleanupStack::Pop(data); + delete[] data; + data = 0; + + + } + else + { + SetAACGlobalGains(&bs2, numberOfGains, gains, gainPos); + aFrameOut = HBufC8::NewL(aFrameIn->Size()); + aFrameOut->Des().Copy(aFrameIn->Ptr(), aFrameIn->Size()); + + } + + + + // } + + } + delete[] gains; + delete[] gainPos; + + + return ETrue; + } + +TBool CProcAACFrameHandler::GetGainL(const HBufC8* aFrame, RArray& aGains, TInt& aMaxGain) const + { + + + TInt numBlocks = 1; + TInt headerBytes = CalculateNumberOfHeaderBytes(aFrame, numBlocks); + + //TBitStream bs; + TUint8* buf = const_cast(aFrame->Right(aFrame->Size()-headerBytes).Ptr()); + //BsInit(&bs, buf, aFrame->Size()-headerBytes); + + uint8* gains = new (ELeave) uint8[16]; + CleanupStack::PushL(gains); + uint32* gainPos = new (ELeave) uint32[16]; + CleanupStack::PushL(gainPos); + + //TPtr8 frameWithoutHeader = aFrame->Right(aFrame->Size()-headerBytes)); + TInt bufLen = aFrame->Size()-headerBytes; + + TBitStream bs; + + + BsInit(&bs, buf, bufLen); + + + for (TInt b = 0 ; b < numBlocks ; b++) + { + + uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos); + + for (TInt a = 0 ; a < numberOfGains ; a++) + { + aGains.Append(gains[a]); + } + + if (headerBytes > 7) + { + bs.buf_index += 2; // crc + bs.slots_read += 2; + bs.bits_read += 16; + + } + + } + CleanupStack::Pop(); //(gainPos) + CleanupStack::Pop(); //(gains) + delete[] gains; + delete[] gainPos; + + aMaxGain = 255; + return EFalse; + + + + } + + +TBool CProcAACFrameHandler::GetNormalizingMargin(const HBufC8* aFrame, TInt8& aMargin) const + + { + + TUint8* buf = const_cast(aFrame->Ptr()); + TInt bufLen = aFrame->Size(); + + uint8* gains = new uint8[16]; + + uint32* gainPos = new uint32[16]; + + + TBitStream bs; + + BsInit(&bs, buf, bufLen); + + uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos); + + TUint8 maxGain = 0; + + for (TInt a = 0 ; a < numberOfGains ; a++) + { + if (gains[a] > maxGain) + { + maxGain = gains[a]; + } + } + delete[] gains; + delete[] gainPos; + + TInt marginInt = (255-maxGain)*6; + + if (marginInt > 127) + { + aMargin = 127; + } + else if (marginInt < 0) + { + aMargin = 0; + } + else + { + aMargin = static_cast(marginInt); + } + + return ETrue; + + + } + +CProcAACFrameHandler::~CProcAACFrameHandler() + { + + iFrameStarts.Reset(); + iFrameLengths.Reset(); + if (iDecHandle != 0) + { + + DeleteAACAudDec(iDecHandle); + } + + + } + +CProcAACFrameHandler* CProcAACFrameHandler::NewL(TAACFrameHandlerInfo aAACInfo) + { + + + CProcAACFrameHandler* self = NewLC(aAACInfo); + CleanupStack::Pop(self); + return self; + + } +CProcAACFrameHandler* CProcAACFrameHandler::NewLC(TAACFrameHandlerInfo aAACInfo) + { + + CProcAACFrameHandler* self = new (ELeave) CProcAACFrameHandler(); + CleanupStack::PushL(self); + self->ConstructL(aAACInfo); + return self; + + } + +void CProcAACFrameHandler::ConstructL(TAACFrameHandlerInfo aAACInfo) + { + + CreateAACAudDecL(iDecHandle, static_cast(aAACInfo.iNumChannels), + static_cast(aAACInfo.iNumCouplingChannels)); + + InitAACAudDec(iDecHandle, static_cast(aAACInfo.iProfileID), + static_cast(aAACInfo.iSampleRateID), + static_cast(aAACInfo.iIs960)); + + if(aAACInfo.isSBR) + { + uint8 isStereo; + + isStereo = (aAACInfo.iNumChannels > 1) ? 1 : 0; + + CreateAACPlusAudDecL(iDecHandle, static_cast(aAACInfo.iSampleRateID), isStereo, (uint8) 0); + } + iAACInfo = aAACInfo; + +} + +CProcAACFrameHandler::CProcAACFrameHandler() : iDecHandle(0) +{ + +} + +TInt CProcAACFrameHandler::CalculateNumberOfHeaderBytes(const HBufC8* aFrame, TInt& aNumBlocksInFrame) const + { + + if (aFrame->Size() < 7) return 0; + TBuf8<7> possibleHeader(aFrame->Left(7)); + + TUint8 byte2 = possibleHeader[1]; + TBuf8<8> byte2b; + ProcTools::Dec2Bin(byte2, byte2b); + TUint8 byte7 = possibleHeader[6]; + + // lets confirm that we have found a legal AAC header + if (possibleHeader[0] == 0xFF && + byte2b[0] == '1' && + byte2b[1] == '1' && + byte2b[2] == '1' && + byte2b[3] == '1' && + // byte2b[4] == '1' && + byte2b[5] == '0' && + byte2b[6] == '0') + { + + aNumBlocksInFrame = (byte7 & 0x3)+1; + + + // protection_absent -> the last bit of the second byte + if (byte2b[7] == '0') + { + return 9 + 2*(aNumBlocksInFrame-1); + } + else + { + return 7; + } + + + + + + } + else + { + // it seems like a raw data block + return 0; + + + + } + } + + + +TBool CProcAACFrameHandler::ParseFramesL(HBufC8* aFrame, RArray& aFrameStarts, RArray& aFrameLengths) +{ + if (iFrameStarts.Count() > 0) + { + for (TInt a = 0 ; a < iFrameStarts.Count() ; a++) + { + aFrameStarts.Append(iFrameStarts[a]); + aFrameLengths.Append(iFrameLengths[a]); + } + iFrameStarts.Reset(); + iFrameLengths.Reset(); + return ETrue; + } + else + { + + TInt numBlocks = 1; + TInt headerBytes = CalculateNumberOfHeaderBytes(aFrame, numBlocks); + if (headerBytes > 0) + { + //TBuf8 hB(aFrame->Left(headerBytes)); + + + } + + //TBitStream bs; + TUint8* buf = const_cast(aFrame->Right(aFrame->Size()-headerBytes).Ptr()); + //BsInit(&bs, buf, aFrame->Size()-headerBytes); + + uint8* gains = new (ELeave) uint8[16]; + CleanupStack::PushL(gains); + uint32* gainPos = new (ELeave) uint32[16]; + CleanupStack::PushL(gainPos); + + //TPtr8 frameWithoutHeader = aFrame->Right(aFrame->Size()-headerBytes)); + TInt bufLen = aFrame->Size()-headerBytes; + + TBitStream bs; + + BsInit(&bs, buf, bufLen); + + for (TInt b = 0 ; b < numBlocks ; b++) + { + + TInt b_i = bs.buf_index; + iFrameStarts.Append(b_i+headerBytes); + + uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos); + if (numberOfGains > 2) + { + CleanupStack::Pop(); // gainPos + CleanupStack::Pop(); // gains + delete[] gains; + delete[] gainPos; + return EFalse; + + } + + if (bs.buf_index > 0) + iFrameLengths.Append(bs.buf_index - b_i); + else + iFrameLengths.Append(bs.buf_len - b_i); + + if (headerBytes > 7) + { + bs.buf_index += 2; // crc + bs.slots_read += 2; + bs.bits_read += 16; + + } + + } + CleanupStack::Pop(); // gainPos + CleanupStack::Pop(); // gains + delete[] gains; + delete[] gainPos; + + + + for (TInt c = 0 ; c < iFrameStarts.Count() ; c++) + { + aFrameStarts.Append(iFrameStarts[c]); + aFrameLengths.Append(iFrameLengths[c]); + } + iFrameStarts.Reset(); + iFrameLengths.Reset(); + return ETrue; + + } + + + + +} + + + +TBool CProcAACFrameHandler::UpdateHeaderL(HBufC8* aFrame) + { + + _LIT8(KZero, "0"); + + TInt frameLength = aFrame->Size(); + + HBufC8* lenBin; + ProcTools::Dec2BinL(frameLength, lenBin); + + HBufC8* len13Bin = HBufC8::NewL(13); + TInt zerosNeeded = 13-lenBin->Size(); + + TPtr8 framePtr(aFrame->Des()); + for (TInt w = 0 ; w < zerosNeeded ; w++) + { + len13Bin->Des().Append(_L8("0")); + } + len13Bin->Des().Append(lenBin->Des()); + + if (len13Bin->Mid(0,1).Compare(KZero) == 0) + { + framePtr[3] &= 0xFD; // 1111 1101 + } + else + { + framePtr[3] |= 2; + } + + if (len13Bin->Mid(1,1).Compare(KZero) == 0) + { + framePtr[3] &= 0xFE; // 1111 1110 + + } + else + { + framePtr[3] |= 1; + } + + + TUint byte5 = 0; + ProcTools::Bin2Dec(len13Bin->Mid(2,8),byte5); + framePtr[4] = static_cast(byte5); + + if (len13Bin->Mid(10,1).Compare(KZero) == 0) + { + framePtr[5] &= 0x7F; + + } + else + { + framePtr[5] |= 0x80; + } + + if (len13Bin->Mid(11,1).Compare(KZero) == 0) + { + framePtr[5] &= 0xBF; + + } + else + { + framePtr[5] |= 0x40; + } + + if (len13Bin->Mid(12,1).Compare(KZero) == 0) + { + framePtr[5] &= 0xDF; + + } + else + { + framePtr[5] |= 0x20; + } + delete lenBin; + delete len13Bin; + return ETrue; + } + + + +void CProcAACFrameHandler:: +GetEnhancedAACPlusParametersL(TUint8* buf, TInt bufLen, + TAudFileProperties* aProperties, + TAACFrameHandlerInfo *aAACInfo) +{ + TBitStream bs; + uint8 sbrStatus; + int16 bytesInFrame; + CAACAudDec* decHandle = 0; + + //-- No SBR by default. --// + aAACInfo->isSBR = 0; + aAACInfo->iIsParametricStereo = 0; + aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension; + aProperties->iChannelModeExtension = EAudChannelModeNotRecognized; + + //-- Create AAC handle. --// + CreateAACAudDecL(decHandle, + static_cast(aAACInfo->iNumChannels), + static_cast(aAACInfo->iNumCouplingChannels)); + CleanupStack::PushL(decHandle); + + //-- Initialize AAC handle. --/ + InitAACAudDec(decHandle, + static_cast(aAACInfo->iProfileID), + static_cast(aAACInfo->iSampleRateID), + static_cast(aAACInfo->iIs960)); + + //-- Create SBR handle on top of the AAC handle. -- + sbrStatus = CreateAACPlusAudDecL(decHandle, static_cast(aAACInfo->iSampleRateID), + (uint8) ((aAACInfo->iNumChannels > 1) ? 1 : 0), + (uint8) 0); + + if(sbrStatus) + { + //-- Initialize bitstream. -- + BsInit(&bs, buf, bufLen); + + //-- Parse the AAC frame. --/ + CountAACChunkLength(&bs, decHandle, &bytesInFrame); + + //-- Were any SBR elements found? -- + if(IsAACSBREnabled(decHandle)) + { + aAACInfo->isSBR = 1; + aProperties->iAudioTypeExtension = EAudExtensionTypeEnhancedAACPlus; + + aAACInfo->iIsParametricStereo = IsAACParametricStereoEnabled(decHandle); + + if(aAACInfo->iIsParametricStereo) + { + aProperties->iChannelModeExtension = EAudParametricStereoChannel; + aProperties->iAudioTypeExtension = EAudExtensionTypeEnhancedAACPlusParametricStereo; + } + } + } + + + //-- Delete resources. --/ + CleanupStack::Pop(decHandle); + if(decHandle != 0) + { + DeleteAACAudDec(decHandle); + } + + decHandle = 0; +}