--- /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 <f32file.h>
+#include <e32math.h>
+
+
+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<TUint8*>(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<int16>(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<TUint8>(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<int16>(-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<TInt>& aGains, TInt& aMaxGain) const
+ {
+
+
+ TInt numBlocks = 1;
+ TInt headerBytes = CalculateNumberOfHeaderBytes(aFrame, numBlocks);
+
+ //TBitStream bs;
+ TUint8* buf = const_cast<TUint8*>(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<TUint8*>(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<TInt8>(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<TInt16>(aAACInfo.iNumChannels),
+ static_cast<TInt16>(aAACInfo.iNumCouplingChannels));
+
+ InitAACAudDec(iDecHandle, static_cast<TInt16>(aAACInfo.iProfileID),
+ static_cast<TInt16>(aAACInfo.iSampleRateID),
+ static_cast<TUint8>(aAACInfo.iIs960));
+
+ if(aAACInfo.isSBR)
+ {
+ uint8 isStereo;
+
+ isStereo = (aAACInfo.iNumChannels > 1) ? 1 : 0;
+
+ CreateAACPlusAudDecL(iDecHandle, static_cast<TInt16>(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<TInt>& aFrameStarts, RArray<TInt>& 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<headerBytes> hB(aFrame->Left(headerBytes));
+
+
+ }
+
+ //TBitStream bs;
+ TUint8* buf = const_cast<TUint8*>(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<TUint8>(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<TInt16>(aAACInfo->iNumChannels),
+ static_cast<TInt16>(aAACInfo->iNumCouplingChannels));
+ CleanupStack::PushL(decHandle);
+
+ //-- Initialize AAC handle. --/
+ InitAACAudDec(decHandle,
+ static_cast<TInt16>(aAACInfo->iProfileID),
+ static_cast<TInt16>(aAACInfo->iSampleRateID),
+ static_cast<TUint8>(aAACInfo->iIs960));
+
+ //-- Create SBR handle on top of the AAC handle. --
+ sbrStatus = CreateAACPlusAudDecL(decHandle, static_cast<TInt16>(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;
+}