videoeditorengine/audioeditorengine/codecs/AAC/src/ProcAACFrameHandler.cpp
changeset 0 951a5db380a0
--- /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;
+}