videoeditorengine/audioeditorengine/codecs/AAC/src/ProcAACFrameHandler.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description: 
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "ProcAACFrameHandler.h"
       
    23 #include "ProcFrameHandler.h"
       
    24 #include "ProcTools.h"
       
    25 #include "nok_bits.h"
       
    26 #include "AACAPI.h"
       
    27 
       
    28 #include <f32file.h>
       
    29 #include <e32math.h>
       
    30 
       
    31 
       
    32 TBool CProcAACFrameHandler::ManipulateGainL(const HBufC8* aFrameIn, HBufC8*& aFrameOut, TInt8 aGain) 
       
    33     {
       
    34 
       
    35     if (aFrameIn == 0)
       
    36         return EFalse;
       
    37 
       
    38     
       
    39     TInt numBlocks = 1;
       
    40     TInt headerBytes = CalculateNumberOfHeaderBytes(aFrameIn, numBlocks);
       
    41     
       
    42     // Unfortunately const casting is needed to avoid unecessary temporary arrays
       
    43     // and we don't have a separate bitstream class for const objects
       
    44     // Just have to make very sure not to modify const descriptors!!
       
    45     TUint8* buf = const_cast<TUint8*>(aFrameIn->Right(aFrameIn->Size()-headerBytes).Ptr());
       
    46     
       
    47     uint8* gains = new (ELeave) uint8[16];
       
    48     uint32* gainPos = new (ELeave) uint32[16];
       
    49 
       
    50     TInt bufLen = aFrameIn->Size()-headerBytes;
       
    51 
       
    52     TBitStream bs;
       
    53     TBitStream bs2;
       
    54     
       
    55     BsInit(&bs, buf, bufLen);
       
    56     BsInit(&bs2, buf, bufLen);
       
    57     
       
    58     for (TInt b = 0 ; b < numBlocks ; b++)
       
    59         {
       
    60         
       
    61         TInt b_i = bs.buf_index;
       
    62         iFrameStarts.Append(b_i+headerBytes);
       
    63 
       
    64         BsSaveBufState(&bs, &bs2);
       
    65 
       
    66         uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos);
       
    67         
       
    68         if (numberOfGains > 2)
       
    69             {
       
    70             // illegal frame??
       
    71             delete[] gainPos;
       
    72             delete[] gains;
       
    73             return KErrGeneral;
       
    74 
       
    75             }
       
    76 
       
    77         if (bs.buf_index > 0)
       
    78             iFrameLengths.Append(bs.buf_index - b_i);
       
    79         else
       
    80             iFrameLengths.Append(bs.buf_len - b_i);
       
    81         
       
    82         if (headerBytes > 7)
       
    83             {
       
    84             bs.buf_index += 2; // crc
       
    85             bs.slots_read += 2;
       
    86             bs.bits_read += 16;
       
    87 
       
    88             }
       
    89                 
       
    90         TInt tmpGain = aGain*500;
       
    91         int16 newGain = static_cast<int16>(tmpGain/1500);
       
    92         
       
    93         
       
    94         for (TInt a = 0 ; a < numberOfGains ; a++)
       
    95         {
       
    96             if (gains[a] + newGain > 255)
       
    97             {
       
    98                 gains[a] = 255;
       
    99             }
       
   100             else if (gains[a] + newGain < 0)
       
   101             {
       
   102                 gains[a] = 0;
       
   103             }
       
   104             else
       
   105             {
       
   106                 gains[a] = static_cast<TUint8>(gains[a]+newGain);
       
   107             }
       
   108         }
       
   109         
       
   110     
       
   111         if (iAACInfo.isSBR || iAACInfo.iIsParametricStereo)
       
   112             {
       
   113 
       
   114             uint8 *data = new (ELeave) uint8[1024];
       
   115             CleanupStack::PushL(data);
       
   116             TBitStream bsOut;
       
   117 
       
   118             BsInit(&bsOut, data, 1024);
       
   119 
       
   120             SetAACPlusGlobalGains(&bs2, &bsOut, iDecHandle, static_cast<int16>(-newGain), numberOfGains, gains, gainPos);
       
   121             
       
   122             TInt incBytes = (bsOut.bits_read >> 3) - bs2.buf_len;
       
   123             iFrameLengths[iFrameLengths.Count()-1] +=incBytes; 
       
   124             
       
   125             TInt newSize = aFrameIn->Size()+incBytes;
       
   126             aFrameOut = HBufC8::NewL(newSize);
       
   127             aFrameOut->Des().Append(aFrameIn->Left(headerBytes));
       
   128             aFrameOut->Des().Append(bsOut.bit_buffer, bsOut.bits_read >> 3);
       
   129             
       
   130             if (headerBytes != 0) UpdateHeaderL(aFrameOut);
       
   131                 
       
   132             CleanupStack::Pop(data);
       
   133             delete[] data;
       
   134             data = 0;
       
   135             
       
   136                 
       
   137             }
       
   138         else
       
   139             {
       
   140             SetAACGlobalGains(&bs2, numberOfGains, gains, gainPos);
       
   141             aFrameOut = HBufC8::NewL(aFrameIn->Size());
       
   142             aFrameOut->Des().Copy(aFrameIn->Ptr(), aFrameIn->Size());
       
   143         
       
   144             }
       
   145             
       
   146 
       
   147             
       
   148         //    }
       
   149 
       
   150         }
       
   151     delete[] gains;
       
   152     delete[] gainPos;
       
   153     
       
   154     
       
   155     return ETrue;
       
   156     }
       
   157 
       
   158 TBool CProcAACFrameHandler::GetGainL(const HBufC8* aFrame, RArray<TInt>& aGains, TInt& aMaxGain) const
       
   159     {
       
   160 
       
   161     
       
   162     TInt numBlocks = 1;
       
   163     TInt headerBytes = CalculateNumberOfHeaderBytes(aFrame, numBlocks);
       
   164     
       
   165     //TBitStream bs;
       
   166     TUint8* buf = const_cast<TUint8*>(aFrame->Right(aFrame->Size()-headerBytes).Ptr());
       
   167     //BsInit(&bs, buf, aFrame->Size()-headerBytes);
       
   168 
       
   169     uint8* gains = new (ELeave) uint8[16];
       
   170     CleanupStack::PushL(gains);
       
   171     uint32* gainPos = new (ELeave) uint32[16];
       
   172     CleanupStack::PushL(gainPos);
       
   173 
       
   174     //TPtr8 frameWithoutHeader = aFrame->Right(aFrame->Size()-headerBytes));
       
   175     TInt bufLen = aFrame->Size()-headerBytes;
       
   176 
       
   177     TBitStream bs;
       
   178 
       
   179     
       
   180     BsInit(&bs, buf, bufLen);
       
   181     
       
   182     
       
   183     for (TInt b = 0 ; b < numBlocks ; b++)
       
   184     {
       
   185                 
       
   186         uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos);
       
   187 
       
   188         for (TInt a = 0 ; a < numberOfGains ; a++)
       
   189         {
       
   190             aGains.Append(gains[a]);
       
   191         }
       
   192 
       
   193         if (headerBytes > 7)
       
   194             {
       
   195             bs.buf_index += 2; // crc
       
   196             bs.slots_read += 2;
       
   197             bs.bits_read += 16;
       
   198 
       
   199             }
       
   200                 
       
   201     }
       
   202     CleanupStack::Pop(); //(gainPos)
       
   203     CleanupStack::Pop(); //(gains)
       
   204     delete[] gains;
       
   205     delete[] gainPos;
       
   206 
       
   207     aMaxGain = 255;
       
   208     return EFalse;
       
   209 
       
   210 
       
   211 
       
   212     }
       
   213 
       
   214 
       
   215 TBool CProcAACFrameHandler::GetNormalizingMargin(const HBufC8* aFrame, TInt8& aMargin) const
       
   216 
       
   217     {
       
   218         
       
   219     TUint8* buf = const_cast<TUint8*>(aFrame->Ptr());
       
   220     TInt bufLen = aFrame->Size();
       
   221 
       
   222     uint8* gains = new uint8[16];
       
   223 
       
   224     uint32* gainPos = new uint32[16];
       
   225     
       
   226     
       
   227     TBitStream bs;
       
   228     
       
   229     BsInit(&bs, buf, bufLen);
       
   230 
       
   231     uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos);
       
   232 
       
   233     TUint8 maxGain = 0;
       
   234 
       
   235     for (TInt a = 0 ; a < numberOfGains ; a++)
       
   236         {
       
   237         if (gains[a] > maxGain)
       
   238             {
       
   239             maxGain = gains[a];
       
   240             }
       
   241         }
       
   242     delete[] gains;
       
   243     delete[] gainPos;
       
   244 
       
   245     TInt marginInt = (255-maxGain)*6;
       
   246 
       
   247     if (marginInt > 127)
       
   248         {
       
   249         aMargin = 127;
       
   250         }
       
   251     else if (marginInt < 0)
       
   252         {
       
   253         aMargin = 0;
       
   254         }
       
   255     else
       
   256         {
       
   257         aMargin = static_cast<TInt8>(marginInt);
       
   258         }
       
   259 
       
   260     return ETrue;
       
   261 
       
   262 
       
   263     }
       
   264 
       
   265 CProcAACFrameHandler::~CProcAACFrameHandler()
       
   266     {
       
   267 
       
   268     iFrameStarts.Reset();
       
   269     iFrameLengths.Reset();
       
   270     if (iDecHandle != 0)
       
   271         {
       
   272         
       
   273         DeleteAACAudDec(iDecHandle);
       
   274         }
       
   275 
       
   276 
       
   277     }
       
   278 
       
   279 CProcAACFrameHandler* CProcAACFrameHandler::NewL(TAACFrameHandlerInfo aAACInfo) 
       
   280     {
       
   281 
       
   282     
       
   283     CProcAACFrameHandler* self = NewLC(aAACInfo);
       
   284     CleanupStack::Pop(self);
       
   285     return self;
       
   286 
       
   287     }
       
   288 CProcAACFrameHandler* CProcAACFrameHandler::NewLC(TAACFrameHandlerInfo aAACInfo) 
       
   289     {
       
   290 
       
   291     CProcAACFrameHandler* self = new (ELeave) CProcAACFrameHandler();
       
   292     CleanupStack::PushL(self);
       
   293     self->ConstructL(aAACInfo);
       
   294     return self;
       
   295 
       
   296     }
       
   297 
       
   298 void CProcAACFrameHandler::ConstructL(TAACFrameHandlerInfo aAACInfo) 
       
   299     {
       
   300     
       
   301     CreateAACAudDecL(iDecHandle, static_cast<TInt16>(aAACInfo.iNumChannels), 
       
   302                                 static_cast<TInt16>(aAACInfo.iNumCouplingChannels));
       
   303     
       
   304     InitAACAudDec(iDecHandle, static_cast<TInt16>(aAACInfo.iProfileID), 
       
   305                                 static_cast<TInt16>(aAACInfo.iSampleRateID), 
       
   306                                 static_cast<TUint8>(aAACInfo.iIs960));
       
   307     
       
   308     if(aAACInfo.isSBR)
       
   309         {
       
   310         uint8 isStereo;
       
   311         
       
   312         isStereo = (aAACInfo.iNumChannels > 1) ? 1 : 0;
       
   313         
       
   314         CreateAACPlusAudDecL(iDecHandle, static_cast<TInt16>(aAACInfo.iSampleRateID), isStereo, (uint8) 0);
       
   315         }
       
   316     iAACInfo = aAACInfo;
       
   317     
       
   318 }
       
   319 
       
   320 CProcAACFrameHandler::CProcAACFrameHandler() : iDecHandle(0)
       
   321 {
       
   322     
       
   323 }
       
   324 
       
   325 TInt CProcAACFrameHandler::CalculateNumberOfHeaderBytes(const HBufC8* aFrame, TInt& aNumBlocksInFrame) const
       
   326     {
       
   327 
       
   328     if (aFrame->Size() < 7) return 0;
       
   329     TBuf8<7> possibleHeader(aFrame->Left(7));
       
   330 
       
   331     TUint8 byte2 = possibleHeader[1];
       
   332     TBuf8<8> byte2b;
       
   333     ProcTools::Dec2Bin(byte2, byte2b);
       
   334     TUint8 byte7 = possibleHeader[6];
       
   335 
       
   336     // lets confirm that we have found a legal AAC header
       
   337     if (possibleHeader[0] == 0xFF &&
       
   338         byte2b[0] == '1' &&
       
   339         byte2b[1] == '1' &&
       
   340         byte2b[2] == '1' &&
       
   341         byte2b[3] == '1' &&
       
   342         //    byte2b[4] == '1' &&
       
   343         byte2b[5] == '0' &&
       
   344         byte2b[6] == '0')
       
   345         {
       
   346         
       
   347         aNumBlocksInFrame = (byte7 & 0x3)+1;
       
   348         
       
   349         
       
   350         // protection_absent -> the last bit of the second byte
       
   351         if (byte2b[7] == '0')
       
   352             {
       
   353             return 9 + 2*(aNumBlocksInFrame-1);
       
   354             }
       
   355         else
       
   356             {
       
   357             return 7;
       
   358             }
       
   359         
       
   360         
       
   361         
       
   362 
       
   363 
       
   364         }
       
   365     else
       
   366         {
       
   367         // it seems like a raw data block
       
   368         return 0;
       
   369 
       
   370 
       
   371 
       
   372         }
       
   373     }
       
   374 
       
   375 
       
   376 
       
   377 TBool CProcAACFrameHandler::ParseFramesL(HBufC8* aFrame, RArray<TInt>& aFrameStarts, RArray<TInt>& aFrameLengths)
       
   378 {
       
   379     if (iFrameStarts.Count() > 0)
       
   380     {
       
   381         for (TInt a = 0 ; a < iFrameStarts.Count() ; a++)
       
   382         {
       
   383             aFrameStarts.Append(iFrameStarts[a]);
       
   384             aFrameLengths.Append(iFrameLengths[a]);
       
   385         }    
       
   386         iFrameStarts.Reset();
       
   387         iFrameLengths.Reset();
       
   388         return ETrue;
       
   389     }
       
   390     else
       
   391     {
       
   392         
       
   393         TInt numBlocks = 1;
       
   394         TInt headerBytes = CalculateNumberOfHeaderBytes(aFrame, numBlocks);
       
   395         if (headerBytes > 0)
       
   396         {
       
   397             //TBuf8<headerBytes> hB(aFrame->Left(headerBytes));
       
   398             
       
   399             
       
   400         }
       
   401         
       
   402         //TBitStream bs;
       
   403         TUint8* buf = const_cast<TUint8*>(aFrame->Right(aFrame->Size()-headerBytes).Ptr());
       
   404         //BsInit(&bs, buf, aFrame->Size()-headerBytes);
       
   405         
       
   406         uint8* gains = new (ELeave) uint8[16];
       
   407         CleanupStack::PushL(gains);
       
   408         uint32* gainPos = new (ELeave) uint32[16];
       
   409         CleanupStack::PushL(gainPos);
       
   410         
       
   411         //TPtr8 frameWithoutHeader = aFrame->Right(aFrame->Size()-headerBytes));
       
   412         TInt bufLen = aFrame->Size()-headerBytes;
       
   413         
       
   414         TBitStream bs;
       
   415     
       
   416         BsInit(&bs, buf, bufLen);
       
   417     
       
   418         for (TInt b = 0 ; b < numBlocks ; b++)
       
   419         {
       
   420             
       
   421             TInt b_i = bs.buf_index;
       
   422             iFrameStarts.Append(b_i+headerBytes);
       
   423             
       
   424             uint8 numberOfGains = GetAACGlobalGains(&bs, iDecHandle, 16, gains, gainPos);
       
   425             if (numberOfGains > 2) 
       
   426                 {
       
   427                 CleanupStack::Pop(); // gainPos
       
   428                 CleanupStack::Pop(); // gains
       
   429                 delete[] gains;
       
   430                 delete[] gainPos;
       
   431                 return EFalse;
       
   432 
       
   433                 }
       
   434             
       
   435             if (bs.buf_index > 0)
       
   436                 iFrameLengths.Append(bs.buf_index - b_i);
       
   437             else
       
   438                 iFrameLengths.Append(bs.buf_len - b_i);
       
   439             
       
   440             if (headerBytes > 7)
       
   441             {
       
   442                 bs.buf_index += 2; // crc
       
   443                 bs.slots_read += 2;
       
   444                 bs.bits_read += 16;
       
   445                 
       
   446             }
       
   447                         
       
   448         }
       
   449         CleanupStack::Pop(); // gainPos
       
   450         CleanupStack::Pop(); // gains
       
   451         delete[] gains;
       
   452         delete[] gainPos;
       
   453 
       
   454         
       
   455         
       
   456         for (TInt c = 0 ; c < iFrameStarts.Count() ; c++)
       
   457             {
       
   458             aFrameStarts.Append(iFrameStarts[c]);
       
   459             aFrameLengths.Append(iFrameLengths[c]);
       
   460             }    
       
   461         iFrameStarts.Reset();
       
   462         iFrameLengths.Reset();
       
   463         return ETrue;    
       
   464         
       
   465     }
       
   466     
       
   467     
       
   468     
       
   469     
       
   470 }
       
   471 
       
   472 
       
   473 
       
   474 TBool CProcAACFrameHandler::UpdateHeaderL(HBufC8* aFrame)
       
   475     {
       
   476 
       
   477     _LIT8(KZero, "0");
       
   478 
       
   479     TInt frameLength = aFrame->Size();
       
   480 
       
   481     HBufC8* lenBin;
       
   482     ProcTools::Dec2BinL(frameLength, lenBin);
       
   483     
       
   484     HBufC8* len13Bin = HBufC8::NewL(13);
       
   485     TInt zerosNeeded = 13-lenBin->Size();
       
   486     
       
   487     TPtr8 framePtr(aFrame->Des());
       
   488     for (TInt w = 0 ; w < zerosNeeded ; w++)
       
   489         {
       
   490         len13Bin->Des().Append(_L8("0"));
       
   491         }
       
   492     len13Bin->Des().Append(lenBin->Des());
       
   493 
       
   494     if (len13Bin->Mid(0,1).Compare(KZero) == 0)
       
   495         {
       
   496         framePtr[3] &= 0xFD; // 1111 1101
       
   497         }
       
   498     else
       
   499         {
       
   500         framePtr[3] |= 2;
       
   501         }
       
   502 
       
   503     if (len13Bin->Mid(1,1).Compare(KZero) == 0)
       
   504         {
       
   505         framePtr[3] &= 0xFE; // 1111 1110
       
   506 
       
   507         }
       
   508     else
       
   509         {
       
   510         framePtr[3] |= 1;
       
   511         }
       
   512 
       
   513 
       
   514     TUint byte5 = 0;
       
   515     ProcTools::Bin2Dec(len13Bin->Mid(2,8),byte5);
       
   516     framePtr[4] = static_cast<TUint8>(byte5);
       
   517 
       
   518     if (len13Bin->Mid(10,1).Compare(KZero) == 0)
       
   519         {
       
   520         framePtr[5] &= 0x7F;
       
   521 
       
   522         }
       
   523     else
       
   524         {
       
   525         framePtr[5] |= 0x80;
       
   526         }
       
   527 
       
   528     if (len13Bin->Mid(11,1).Compare(KZero) == 0)
       
   529         {
       
   530         framePtr[5] &= 0xBF;
       
   531 
       
   532         }
       
   533     else
       
   534         {
       
   535         framePtr[5] |= 0x40;
       
   536         }
       
   537 
       
   538     if (len13Bin->Mid(12,1).Compare(KZero) == 0)
       
   539         {
       
   540         framePtr[5] &= 0xDF;
       
   541 
       
   542         }
       
   543     else
       
   544         {
       
   545         framePtr[5] |= 0x20;
       
   546         }
       
   547     delete lenBin;
       
   548     delete len13Bin;
       
   549     return ETrue;
       
   550     }
       
   551 
       
   552 
       
   553 
       
   554 void CProcAACFrameHandler::
       
   555 GetEnhancedAACPlusParametersL(TUint8* buf, TInt bufLen, 
       
   556                               TAudFileProperties* aProperties, 
       
   557                               TAACFrameHandlerInfo *aAACInfo)
       
   558 {
       
   559   TBitStream bs;
       
   560   uint8 sbrStatus;
       
   561   int16 bytesInFrame;
       
   562   CAACAudDec* decHandle = 0;
       
   563 
       
   564   //-- No SBR by default. --//
       
   565   aAACInfo->isSBR = 0;
       
   566   aAACInfo->iIsParametricStereo = 0;
       
   567   aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension;
       
   568   aProperties->iChannelModeExtension = EAudChannelModeNotRecognized;
       
   569 
       
   570   //-- Create AAC handle. --//
       
   571   CreateAACAudDecL(decHandle, 
       
   572                    static_cast<TInt16>(aAACInfo->iNumChannels), 
       
   573                    static_cast<TInt16>(aAACInfo->iNumCouplingChannels));
       
   574   CleanupStack::PushL(decHandle);
       
   575 
       
   576   //-- Initialize AAC handle. --/
       
   577   InitAACAudDec(decHandle, 
       
   578                 static_cast<TInt16>(aAACInfo->iProfileID), 
       
   579                                 static_cast<TInt16>(aAACInfo->iSampleRateID), 
       
   580                                 static_cast<TUint8>(aAACInfo->iIs960));
       
   581 
       
   582   //-- Create SBR handle on top of the AAC handle. --
       
   583   sbrStatus = CreateAACPlusAudDecL(decHandle, static_cast<TInt16>(aAACInfo->iSampleRateID), 
       
   584                                    (uint8) ((aAACInfo->iNumChannels > 1) ? 1 : 0), 
       
   585                                    (uint8) 0);
       
   586 
       
   587   if(sbrStatus)
       
   588   {
       
   589     //-- Initialize bitstream. --
       
   590     BsInit(&bs, buf, bufLen);
       
   591 
       
   592     //-- Parse the AAC frame. --/
       
   593     CountAACChunkLength(&bs, decHandle, &bytesInFrame);
       
   594 
       
   595     //-- Were any SBR elements found? --
       
   596     if(IsAACSBREnabled(decHandle))
       
   597     {
       
   598       aAACInfo->isSBR = 1;
       
   599       aProperties->iAudioTypeExtension = EAudExtensionTypeEnhancedAACPlus;
       
   600       
       
   601       aAACInfo->iIsParametricStereo = IsAACParametricStereoEnabled(decHandle);
       
   602 
       
   603       if(aAACInfo->iIsParametricStereo)
       
   604       {
       
   605         aProperties->iChannelModeExtension = EAudParametricStereoChannel;
       
   606         aProperties->iAudioTypeExtension = EAudExtensionTypeEnhancedAACPlusParametricStereo;
       
   607       }
       
   608     }
       
   609   }
       
   610 
       
   611 
       
   612   //-- Delete resources. --/
       
   613   CleanupStack::Pop(decHandle);
       
   614   if(decHandle != 0)
       
   615       {
       
   616       DeleteAACAudDec(decHandle);    
       
   617       }
       
   618     
       
   619   decHandle = 0;
       
   620 }