heaac_dec/ariheaacdecmmfcodec/src/ariheaacdecmmfcodec.cpp
changeset 0 bb31fbe78861
equal deleted inserted replaced
-1:000000000000 0:bb31fbe78861
       
     1 /*
       
     2 * Copyright (c) 2009 Aricent and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "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 * Aricent - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * Implementation of member functions of Plugin class
       
    16 * (CAriHeAacDecMmfCodec).
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <ecom.h>
       
    22 #include <implementationproxy.h>
       
    23 
       
    24 #include "ariheaacdecwrapper.h"
       
    25 #include "ariheaacdecmmfcodec.h"
       
    26 #include "ariheaacdecmmfcodec_uid.hrh"
       
    27 #include "ariprint.h"
       
    28 
       
    29 //Maximum size of a single input frame in an AAC stream
       
    30 const TInt KMinBytesInput = 1536;
       
    31 //Maximum size of a single output frame in an AAC stream
       
    32 const TInt KMaxOutputBufSize = 8192;
       
    33 
       
    34 const TInt KMinParamSize = 11;
       
    35 const TInt KRenderStatusIndex = 13;
       
    36 const TInt KMarkPlayStatusIndex = 14;
       
    37 const TInt KEnableStatusIndex = 15;
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 //  Two-phased constructor.
       
    41 //  Creates an instance of CAriHeAacDecMmfCodec.
       
    42 //  Instance is not left on cleanup stack.
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 CMMFCodec* CAriHeAacDecMmfCodec::NewL()
       
    46     {
       
    47     PRINT_ENTRY;
       
    48     CAriHeAacDecMmfCodec* self = new ( ELeave ) CAriHeAacDecMmfCodec();
       
    49     CleanupStack::PushL( self );
       
    50     self->ConstructL();
       
    51     CleanupStack::Pop( self );
       
    52     PRINT_EXIT;
       
    53     return ( CMMFCodec* )self;
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 //  Destructor;Destroys the decoder instance and any internal buffers
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CAriHeAacDecMmfCodec::~CAriHeAacDecMmfCodec()
       
    61     {
       
    62     PRINT_ENTRY;
       
    63     if ( iInternalInputBuffer )
       
    64         {
       
    65         delete iInternalInputBuffer;
       
    66         iInternalInputBuffer = NULL;
       
    67         }
       
    68     if ( iInternalOutputBuffer )
       
    69         {
       
    70         delete iInternalOutputBuffer;
       
    71         iInternalOutputBuffer = NULL;
       
    72         }
       
    73     if ( iCodec )
       
    74         {
       
    75         delete iCodec;
       
    76         iCodec = NULL;
       
    77         }
       
    78 
       
    79     iConfigured = EFalse;
       
    80     PRINT_EXIT;
       
    81     }
       
    82 
       
    83 
       
    84 // ---------------------------------------------------------------------------
       
    85 //  From class CMMFCodec.
       
    86 //  The function Sets codec configuration.
       
    87 //  The value used for aConfigType must be KUidMmfCodecAudioSettings
       
    88 //  (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh)
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 void CAriHeAacDecMmfCodec::ConfigureL( TUid /* aConfigType */,
       
    92                                     const TDesC8& aParam )
       
    93     {
       
    94     PRINT_ENTRY;
       
    95     TInt paramLen = aParam.Length();
       
    96     PRINT_MSG( LEVEL_HIGH, ( "param Len: %d",
       
    97                                         paramLen ) );
       
    98     if ( paramLen < KMinParamSize )
       
    99         {
       
   100         PRINT_MSG( LEVEL_HIGH, ( "param Len: %d",
       
   101                                     paramLen ) );
       
   102         PRINT_ERR( "Incorrect parameter descriptor " );
       
   103         User::Leave( KErrArgument );
       
   104         }
       
   105     if ( !iConfigured )
       
   106         {
       
   107         RArray<TInt>  configParam = ( RArray<TInt>& )( aParam );
       
   108         TInt index = 0;
       
   109 
       
   110         index++;
       
   111         //configParam[1] holds NoOfChannels
       
   112         iFrameInfo.iNoOfChannels = configParam[index++];
       
   113         //configParam[2] holds Profile
       
   114         iFrameInfo.iProfile = configParam[index++];
       
   115         //configParam[3] holds OutFrameSize
       
   116         iFrameInfo.iOutFrameSize = configParam[index++];
       
   117         //configParam[4] holds NoOfSamples
       
   118         iFrameInfo.iNoOfSamples = configParam[index++];
       
   119         //configParam[5] holds SamplingFrequency
       
   120         iFrameInfo.iSamplingFrequency = configParam[index++];
       
   121         //Ignore fields 6,7 & 8
       
   122         index++;
       
   123         index++;
       
   124         index++;
       
   125         //configParam[9] holds OutSamplingFrequency
       
   126         iFrameInfo.iOutSamplingFrequency = configParam[index++];
       
   127         //configParam[10] holds ExtObjectType
       
   128         iFrameInfo.iExtObjectType = configParam[index];
       
   129         iFrameInfo.iDownSampledMode = 0;
       
   130 
       
   131         if ( paramLen > KMinParamSize)
       
   132             {
       
   133             /**
       
   134              * Call Reset only if fields 13,14 and 15 of the
       
   135              * Param array are set to zero
       
   136              */
       
   137             if ( ( configParam[KRenderStatusIndex] == 0 &&
       
   138                                     configParam[KMarkPlayStatusIndex] == 0 &&
       
   139                                     configParam[KEnableStatusIndex] == 0 ) )
       
   140                 {
       
   141                 PRINT_MSG( LEVEL_HIGH, ( "frameInfo->OutFrameSize: %d",
       
   142                                             iFrameInfo.iOutFrameSize ) );
       
   143                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfSamples: %d",
       
   144                                             iFrameInfo.iNoOfSamples ) );
       
   145                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->SamplingFrequency: %d",
       
   146                                             iFrameInfo.iSamplingFrequency ) );
       
   147                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfChannels: %d",
       
   148                                             iFrameInfo.iNoOfChannels ) );
       
   149                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->Profile: %d",
       
   150                                             iFrameInfo.iProfile ) );
       
   151                 PRINT_MSG( LEVEL_HIGH,
       
   152                                     ( "iFrameInfo->OutSamplingFrequency: %d",
       
   153                                         iFrameInfo.iOutSamplingFrequency ) );
       
   154                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->ExtObjectType: %d",
       
   155                                             iFrameInfo.iExtObjectType ) );
       
   156                 PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->DownSampledMode: %d",
       
   157                                             iFrameInfo.iDownSampledMode ) );
       
   158 
       
   159                 User::LeaveIfError( iCodec->Reset( &iFrameInfo ) );
       
   160 
       
   161                 iConfigured = ETrue;
       
   162                 iOutFrameSize = iFrameInfo.iOutFrameSize;
       
   163                 }
       
   164             }
       
   165         else
       
   166             {
       
   167             PRINT_MSG( LEVEL_HIGH, ( "frameInfo->OutFrameSize: %d",
       
   168                                                iFrameInfo.iOutFrameSize ) );
       
   169             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfSamples: %d",
       
   170                                        iFrameInfo.iNoOfSamples ) );
       
   171             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->SamplingFrequency: %d",
       
   172                                        iFrameInfo.iSamplingFrequency ) );
       
   173             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfChannels: %d",
       
   174                                        iFrameInfo.iNoOfChannels ) );
       
   175             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->Profile: %d",
       
   176                                        iFrameInfo.iProfile ) );
       
   177             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->OutSamplingFrequency: %d",
       
   178                                        iFrameInfo.iOutSamplingFrequency ) );
       
   179             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->ExtObjectType: %d",
       
   180                                        iFrameInfo.iExtObjectType ) );
       
   181             PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->DownSampledMode: %d",
       
   182                                        iFrameInfo.iDownSampledMode ) );
       
   183 
       
   184             User::LeaveIfError( iCodec->Reset( &iFrameInfo ) );
       
   185 
       
   186             iConfigured = ETrue;
       
   187 
       
   188             iOutFrameSize = iFrameInfo.iOutFrameSize;
       
   189             }
       
   190         }
       
   191     PRINT_EXIT;
       
   192     }
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 //  From class CMMFCodec.
       
   196 //  This function is used to flush out status information when a
       
   197 //  reposition occurs.
       
   198 //  This is used if the codec requires resetting prior to use.
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 void CAriHeAacDecMmfCodec::ResetL()
       
   202     {
       
   203     PRINT_ENTRY;
       
   204     iInternalInputBufferResidueLen = 0;
       
   205     iInternalOutputBufferResidueLen = 0;
       
   206     iInternalOutputBufferPos = 0;
       
   207     PRINT_EXIT;
       
   208     }
       
   209 
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 //  From class CMMFCodec.
       
   213 //  This function is used to decode the given source and fill the destination
       
   214 //  buffer with the decode data.
       
   215 //  The buffers can be of any size.  Since the buffers can be of any size
       
   216 //  there is no guarantee that all the source buffer can be processed to fill
       
   217 //  the destination buffer or that the all the source buffer may be processed
       
   218 //  before the destination is full.  Therefore the ProcessL needs to return a
       
   219 //  TCodecProcessResult returing the number of source bytes processed and the
       
   220 //  number of destination bytes processed along with a process result code
       
   221 //  defined thus:
       
   222 //  - EProcessComplete: the codec processed all the source data into the sink
       
   223 //    buffer
       
   224 //  - EProcessIncomplete: the codec filled sink buffer before all the source
       
   225 //    buffer was processed
       
   226 //  - EDstNotFilled: the codec processed the source buffer but the sink buffer
       
   227 //    was not filled
       
   228 //  - EEndOfData: the codec detected the end data - all source data in
       
   229 //    processed but sink may not be full
       
   230 //  - EProcessError: the codec process error condition
       
   231 //
       
   232 //  The ProcessL should start processing the source buffer from the iPosition
       
   233 //  data member of the source data and start filling the destination buffer
       
   234 //  from its iPosition.
       
   235 //  --------------------------------------------------------------------------
       
   236 //
       
   237 TCodecProcessResult CAriHeAacDecMmfCodec::ProcessL( const CMMFBuffer& aSrc,
       
   238                                                 CMMFBuffer& aDst )
       
   239     {
       
   240     PRINT_ENTRY;
       
   241 
       
   242     if ( !iConfigured )
       
   243         {
       
   244         PRINT_ERR( "Decoder not yet configured" );
       
   245         User::Leave( KErrNotReady );
       
   246         }
       
   247     // total decoded bytes added to the dst buffer
       
   248     TInt totalDstBytesAdded = 0;
       
   249     // total src bytes added to the internal src buffer
       
   250     TInt totalSrcBytesCopied = 0;
       
   251     // temporary variable to use for copying the sorce or destination data
       
   252     TInt numberOfBytesCopied = 0;
       
   253     TInt dstBufferRemainingBytes = 0;
       
   254 
       
   255     /**
       
   256      * Process the dst buffer, update the dstBufferPos and check
       
   257      * whether dst buffer is NULL or not.
       
   258      */
       
   259     CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>( &aDst );
       
   260     const TInt dstMaxLen = dst->Data().MaxLength();
       
   261     TUint8* dstPtr = const_cast<TUint8*>( dst->Data().Ptr() );
       
   262     TInt dstBufferPos = dst->Position();
       
   263 
       
   264     /**
       
   265      * Process the src buffer, update srcbuffer length, position and
       
   266      * flag for last frame. check whether src buffer is NULL or not
       
   267      * and check src buffer contains any data
       
   268      */
       
   269     const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>( &aSrc );
       
   270     TUint8* srcPtr = const_cast<TUint8*>( src->Data().Ptr() );
       
   271     TInt srcBufferLen = src->Data().Length();
       
   272     TInt srcBufferPos = src->Position();
       
   273     TBool lastFrame = src->LastBuffer();
       
   274 
       
   275     PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d", srcBufferPos ) );
       
   276     PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d", dstBufferPos ) );
       
   277     PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d",
       
   278            iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) );
       
   279     PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d",
       
   280                                       iInternalInputBufferResidueLen ) );
       
   281     /**
       
   282      * if any destination bytes from internal destination buffer is not
       
   283      * given to the dst buffer from the previous call, give it to the
       
   284      * dst buffer. After this block, it ensures that no bytes are remaining
       
   285      * in the internal destination buffer.
       
   286      */
       
   287     if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
       
   288         {
       
   289         numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
       
   290 
       
   291         if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
       
   292             {
       
   293             PRINT_EXIT;
       
   294             return Result( TCodecProcessResult::EProcessIncomplete,
       
   295                             totalSrcBytesCopied, totalDstBytesAdded );
       
   296             }
       
   297         else
       
   298             {
       
   299             //Decode NULL frame to handle error concealment
       
   300             if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&&
       
   301             ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) )
       
   302                 {
       
   303                 dstBufferRemainingBytes = dstMaxLen - dstBufferPos -
       
   304                                                     totalDstBytesAdded;
       
   305                 if ( dstBufferRemainingBytes == 0 )
       
   306                     {
       
   307                     iInternalOutputBufferPos = 0;
       
   308                     iInternalOutputBufferResidueLen = 0;
       
   309                     totalSrcBytesCopied = 0;
       
   310                     PRINT_EXIT;
       
   311                     return Result( TCodecProcessResult::EProcessIncomplete,
       
   312                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   313                      }
       
   314 
       
   315                 TInt dstLen  = iOutFrameSize;
       
   316                 DecodeLastFrame(dstLen);
       
   317                 iInternalOutputBufferResidueLen = dstLen;
       
   318 
       
   319                 numberOfBytesCopied =
       
   320                                 CopyToDstBuffer( dst, totalDstBytesAdded );
       
   321                 totalDstBytesAdded += numberOfBytesCopied;
       
   322                 dstBufferRemainingBytes -= numberOfBytesCopied;
       
   323 
       
   324                 if ( ( iInternalOutputBufferResidueLen -
       
   325                     iInternalOutputBufferPos == 0 ) && iLastFrameDecoded )
       
   326                     {
       
   327                     totalSrcBytesCopied = 0;
       
   328                     iInternalOutputBufferResidueLen = 0;
       
   329                     iInternalInputBufferResidueLen = 0;
       
   330                     iInternalOutputBufferPos = 0;
       
   331                     PRINT_EXIT;
       
   332                     return Result( TCodecProcessResult::EEndOfData,
       
   333                                 totalSrcBytesCopied, totalDstBytesAdded );
       
   334                     }
       
   335                 else
       
   336                     {
       
   337                     totalSrcBytesCopied = 0;
       
   338                     PRINT_EXIT;
       
   339                     return Result( TCodecProcessResult::EProcessIncomplete,
       
   340                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   341                     }
       
   342                 }
       
   343             iInternalOutputBufferPos = 0;
       
   344             iInternalOutputBufferResidueLen = 0;
       
   345             }
       
   346         }
       
   347     else
       
   348         {
       
   349         if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&&
       
   350             ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) )
       
   351             {
       
   352             TInt dstLen  = iOutFrameSize;
       
   353             DecodeLastFrame(dstLen);
       
   354             iInternalOutputBufferResidueLen = dstLen;
       
   355 
       
   356             numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
       
   357             totalDstBytesAdded += numberOfBytesCopied;
       
   358             dstBufferRemainingBytes -= numberOfBytesCopied;
       
   359 
       
   360             if ( ( iInternalOutputBufferResidueLen -
       
   361                     iInternalOutputBufferPos == 0 ) && iLastFrameDecoded )
       
   362                 {
       
   363                 totalSrcBytesCopied = 0;
       
   364                 iInternalOutputBufferResidueLen = 0;
       
   365                 iInternalInputBufferResidueLen = 0;
       
   366                 iInternalOutputBufferPos = 0;
       
   367                 PRINT_EXIT;
       
   368                 return Result( TCodecProcessResult::EEndOfData,
       
   369                             totalSrcBytesCopied, totalDstBytesAdded );
       
   370                 }
       
   371             else
       
   372                 {
       
   373                 totalSrcBytesCopied = 0;
       
   374                 PRINT_EXIT;
       
   375                 return Result( TCodecProcessResult::EProcessIncomplete,
       
   376                                 totalSrcBytesCopied, totalDstBytesAdded );
       
   377                 }
       
   378             }
       
   379         }
       
   380 
       
   381     /**
       
   382      * copy the src buffer data into the internal buffer till internal buffer
       
   383      * holds minimum bytes to process i.e KMinBytesInput. After this block,
       
   384      * it ensures that internal source buffer holds KMinBytesInput.
       
   385      * if it is a last frame, treat remaining residual buffer as internal
       
   386      * buffer.
       
   387      */
       
   388     if ( ( KMinBytesInput - iInternalInputBufferResidueLen > 0 ) &&
       
   389                                 ( srcBufferLen - srcBufferPos > 0 ) )
       
   390         {
       
   391         numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
       
   392         }
       
   393 
       
   394     /**
       
   395      * update the internal buffer length.
       
   396      */
       
   397     if ( ( KMinBytesInput > iInternalInputBufferResidueLen ) &&
       
   398                                                         ( !lastFrame ) )
       
   399         {
       
   400         PRINT_EXIT;
       
   401         return Result( TCodecProcessResult::EDstNotFilled,
       
   402                 srcBufferLen - srcBufferPos, totalDstBytesAdded );
       
   403         }
       
   404 
       
   405     if ( iLastFrameDecoded && iInternalInputBufferResidueLen == 0 &&
       
   406                                     iInternalOutputBufferResidueLen == 0 )
       
   407         {
       
   408         totalSrcBytesCopied = 0;
       
   409         iInternalOutputBufferResidueLen = 0;
       
   410         iInternalInputBufferResidueLen = 0;
       
   411         iInternalOutputBufferPos = 0;
       
   412         PRINT_EXIT;
       
   413         return Result( TCodecProcessResult::EEndOfData,
       
   414                     totalSrcBytesCopied, totalDstBytesAdded );
       
   415         }
       
   416 
       
   417     /**
       
   418      * process the src buffer till destination buffer or source buffer or
       
   419      * both buffers are exhausted.
       
   420      */
       
   421     do
       
   422         {
       
   423         TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos -
       
   424                                                         totalSrcBytesCopied;
       
   425         dstBufferRemainingBytes = dstMaxLen - dstBufferPos -
       
   426                                                         totalDstBytesAdded;
       
   427         TInt internalInputBufferPos = 0;
       
   428 
       
   429         /**
       
   430          * initialize the variables like iSrcUsed and dstLen accordingly.
       
   431          * call Decode.
       
   432          */
       
   433         iSrcUsed = iInternalInputBufferResidueLen - internalInputBufferPos;
       
   434         TInt dstLen  = iOutFrameSize;
       
   435 
       
   436         TInt error = iCodec->Decode(
       
   437                             &iInternalInputBuffer[internalInputBufferPos],
       
   438                                 iSrcUsed, iInternalOutputBuffer, dstLen );
       
   439         if ( error != 0 )
       
   440             {
       
   441             iInternalInputBufferResidueLen = 0;
       
   442             totalSrcBytesCopied = srcBufferLen;
       
   443             PRINT_ERR( error );
       
   444             return Result(
       
   445                     TCodecProcessResult::EProcessError,
       
   446                     totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos);
       
   447             }
       
   448         iFrameNum++;
       
   449         PRINT_MSG( LEVEL_HIGH, ( "Frame: %d", iFrameNum ) );
       
   450         PRINT_MSG( LEVEL_HIGH, ( "iSrcUsed: %d", iSrcUsed ) );
       
   451         PRINT_MSG( LEVEL_HIGH, ( "dstLen: %d", dstLen ) );
       
   452 
       
   453         /**
       
   454          * Fill Destination Buffer
       
   455          */
       
   456         iInternalOutputBufferResidueLen = dstLen;
       
   457         numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
       
   458         dstBufferRemainingBytes -= numberOfBytesCopied;
       
   459 
       
   460         /**
       
   461          * Fill Source Buffer
       
   462          */
       
   463         internalInputBufferPos += iSrcUsed ;
       
   464         ShiftData( internalInputBufferPos, 0 );
       
   465         numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
       
   466         srcBufferRemainingBytes -= numberOfBytesCopied;
       
   467 
       
   468         /**
       
   469          * check four conditions if else for src and if else for dst
       
   470          */
       
   471         /**
       
   472          * src has available bytes
       
   473          */
       
   474         if ( srcBufferRemainingBytes > 0  ||
       
   475                 iInternalInputBufferResidueLen >= KMinBytesInput )
       
   476             {
       
   477             if ( dstBufferRemainingBytes == 0 )
       
   478                 {
       
   479                 PRINT_EXIT;
       
   480                 return Result(
       
   481                         TCodecProcessResult::EProcessIncomplete,
       
   482                         totalSrcBytesCopied, totalDstBytesAdded );
       
   483                 }
       
   484             }
       
   485         else
       
   486             {
       
   487             // dst buffer has availabe space for decoded bytes
       
   488             if ( dstBufferRemainingBytes > 0 )
       
   489                 {
       
   490                 if ( lastFrame )
       
   491                     {
       
   492                     if ( iInternalInputBufferResidueLen == 0 )
       
   493                         {
       
   494                         TInt dstLen  = iOutFrameSize;
       
   495                         DecodeLastFrame(dstLen);
       
   496                         iInternalOutputBufferResidueLen = dstLen;
       
   497 
       
   498                         numberOfBytesCopied =
       
   499                                 CopyToDstBuffer( dst, totalDstBytesAdded );
       
   500                         totalDstBytesAdded += numberOfBytesCopied;
       
   501                         dstBufferRemainingBytes -= numberOfBytesCopied;
       
   502 
       
   503                         if ( ( iInternalOutputBufferResidueLen -
       
   504                                 iInternalOutputBufferPos == 0 ) &&
       
   505                                 iLastFrameDecoded )
       
   506                             {
       
   507                             totalSrcBytesCopied = 0;
       
   508                             iInternalOutputBufferResidueLen = 0;
       
   509                             iInternalInputBufferResidueLen = 0;
       
   510                             iInternalOutputBufferPos = 0;
       
   511                             PRINT_EXIT;
       
   512                             return Result( TCodecProcessResult::EEndOfData,
       
   513                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   514                             }
       
   515                         else
       
   516                             {
       
   517                             totalSrcBytesCopied = 0;
       
   518                             PRINT_EXIT;
       
   519                             return Result(
       
   520                                     TCodecProcessResult::EProcessIncomplete,
       
   521                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   522                             }
       
   523                         }
       
   524                     }
       
   525                 else
       
   526                     {
       
   527                     PRINT_EXIT;
       
   528                     return Result( TCodecProcessResult::EDstNotFilled,
       
   529                             totalSrcBytesCopied, totalDstBytesAdded );
       
   530                     }
       
   531                 }
       
   532             else
       
   533                 {
       
   534                 if ( iInternalOutputBufferResidueLen -
       
   535                                             iInternalOutputBufferPos > 0 )
       
   536                     {
       
   537                     PRINT_EXIT;
       
   538                     return Result( TCodecProcessResult::EProcessIncomplete,
       
   539                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   540                     }
       
   541                 else
       
   542                     {
       
   543                     if ( lastFrame )
       
   544                         {
       
   545                         PRINT_EXIT;
       
   546                         return Result(
       
   547                                     TCodecProcessResult::EProcessIncomplete,
       
   548                                     totalSrcBytesCopied, totalDstBytesAdded );
       
   549                         }
       
   550                     else
       
   551                         {
       
   552                         PRINT_EXIT;
       
   553                         return Result(
       
   554                                 TCodecProcessResult::EProcessComplete,
       
   555                                 totalSrcBytesCopied, totalDstBytesAdded );
       
   556                         }
       
   557                     }
       
   558                 }
       
   559             }
       
   560         }while ( 1 );
       
   561     }
       
   562 
       
   563 
       
   564 // --------------------------------------------------------------------------
       
   565 //  Default constructor for performing 1st stage construction.
       
   566 //  Should not contain any code that could leave.
       
   567 // --------------------------------------------------------------------------
       
   568 //
       
   569 CAriHeAacDecMmfCodec::CAriHeAacDecMmfCodec()
       
   570     {
       
   571     PRINT_ENTRY;
       
   572     iCodec = NULL;
       
   573     iConfigured = EFalse;
       
   574     iOutFrameSize = 0;
       
   575     iLastFrameDecoded = EFalse;
       
   576 
       
   577     iFrameNum = 0;
       
   578     PRINT_EXIT;
       
   579     }
       
   580 
       
   581 
       
   582 // ---------------------------------------------------------------------------
       
   583 //  Second phase of the two-phased constructor.
       
   584 //  Creates an instance of decoder
       
   585 // ---------------------------------------------------------------------------
       
   586 //
       
   587 void CAriHeAacDecMmfCodec::ConstructL()
       
   588     {
       
   589     PRINT_ENTRY;
       
   590     iCodec = CAriHeAacDecWrapper::NewL();
       
   591 
       
   592     iInternalInputBuffer = ( TUint8* ) User::AllocZL( KMinBytesInput );
       
   593     iInternalOutputBuffer = ( TUint8* ) User::AllocZL( KMaxOutputBufSize );
       
   594     PRINT_EXIT;
       
   595     }
       
   596 
       
   597 //----------------------------------------------------------------------------
       
   598 //  Updates the result of the processing
       
   599 //----------------------------------------------------------------------------
       
   600 //
       
   601 TCodecProcessResult CAriHeAacDecMmfCodec::Result(
       
   602                     TCodecProcessResult::TCodecProcessResultStatus aStatus,
       
   603                     TInt aSrcBytesConsumed, TInt aDstBytesAdded )
       
   604      {
       
   605      PRINT_ENTRY;
       
   606      TCodecProcessResult result;
       
   607 
       
   608      result.iDstBytesAdded = aDstBytesAdded;
       
   609      result.iSrcBytesProcessed = aSrcBytesConsumed;
       
   610 
       
   611      switch ( aStatus )
       
   612          {
       
   613          case TCodecProcessResult::EProcessComplete:
       
   614             result.iStatus = TCodecProcessResult::EProcessComplete;
       
   615             break;
       
   616          case TCodecProcessResult::EProcessIncomplete:
       
   617             result.iStatus = TCodecProcessResult::EProcessIncomplete;
       
   618             break;
       
   619          case TCodecProcessResult::EEndOfData:
       
   620             result.iStatus = TCodecProcessResult::EEndOfData;
       
   621             break;
       
   622          case TCodecProcessResult::EDstNotFilled:
       
   623             result.iStatus = TCodecProcessResult::EDstNotFilled;
       
   624             break;
       
   625          case TCodecProcessResult::EProcessError:
       
   626             result.iStatus = TCodecProcessResult::EProcessError;
       
   627             break;
       
   628          default:
       
   629             result.iStatus = TCodecProcessResult::EProcessError;
       
   630             break;
       
   631          }
       
   632      PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d",
       
   633                                 result.iSrcBytesProcessed ) );
       
   634      PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d",
       
   635                                 result.iDstBytesAdded ) );
       
   636      PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d",
       
   637                                 result.iStatus ) );
       
   638      PRINT_EXIT;
       
   639      return result;
       
   640      }
       
   641 
       
   642 //----------------------------------------------------------------------------
       
   643 // Copy the bytes to destination buffer from the internal buffer
       
   644 // first checks whether the number of bytes to be copied is lesser of the
       
   645 // destination buffer reamining bytes and internal input internal remaining
       
   646 // remaining bytes and then copies that many bytes.
       
   647 //----------------------------------------------------------------------------
       
   648 //
       
   649  TInt CAriHeAacDecMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst,
       
   650                                      TInt &aDstBytesConsumed )
       
   651     {
       
   652     PRINT_ENTRY;
       
   653     TInt numberOfBytesToBeCopied;
       
   654     const TInt dstMaxLen = aDst->Data().MaxLength();
       
   655     TUint8* dstPtr = const_cast<TUint8*>(aDst->Data().Ptr() );
       
   656     TInt dstBufferPos = aDst->Position();
       
   657 
       
   658     TInt dstBufferRemainingBytes = dstMaxLen
       
   659                                    - dstBufferPos
       
   660                                    - aDstBytesConsumed;
       
   661     TInt internalOutputBufferRemainingBytes =
       
   662                                          iInternalOutputBufferResidueLen
       
   663                                          - iInternalOutputBufferPos;
       
   664 
       
   665     if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes )
       
   666         {
       
   667         numberOfBytesToBeCopied = dstBufferRemainingBytes;
       
   668         }
       
   669     else
       
   670         {
       
   671         numberOfBytesToBeCopied = internalOutputBufferRemainingBytes;
       
   672         iInternalOutputBufferResidueLen = 0;
       
   673         }
       
   674 
       
   675     Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed,
       
   676         iInternalOutputBuffer + iInternalOutputBufferPos,
       
   677         numberOfBytesToBeCopied );
       
   678 
       
   679     if( iInternalOutputBufferResidueLen )
       
   680         {
       
   681         iInternalOutputBufferPos += dstBufferRemainingBytes;
       
   682         }
       
   683     else
       
   684         {
       
   685         iInternalOutputBufferPos = 0;
       
   686         }
       
   687 
       
   688     aDstBytesConsumed += numberOfBytesToBeCopied;
       
   689     aDst->Data().SetLength( dstBufferPos +  aDstBytesConsumed );
       
   690     PRINT_EXIT;
       
   691     return numberOfBytesToBeCopied;
       
   692     }
       
   693 
       
   694 //---------------------------------------------------------------------------
       
   695 // Copy the bytes from the source buffer to the internal input buffer.
       
   696 // first it checks number of bytes to be copied is lesser of the source buffer
       
   697 // remaining bytes or internal input buffer remaining bytes and then copies
       
   698 // that many bytes.
       
   699 //---------------------------------------------------------------------------
       
   700 //
       
   701  TInt CAriHeAacDecMmfCodec::CopyFromSrcBuffer(const CMMFDataBuffer* aSrc,
       
   702                                          TInt &aSrcBytesConsumed )
       
   703     {
       
   704     PRINT_ENTRY;
       
   705     TInt numberOfBytesToBeCopied;
       
   706     TUint8* srcPtr = const_cast <TUint8*>( aSrc->Data().Ptr() );
       
   707     TInt srcBufferLen = aSrc->Data().Length();
       
   708     TInt srcBufferPos = aSrc->Position();
       
   709 
       
   710     TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos
       
   711                                    - aSrcBytesConsumed;
       
   712 
       
   713     TInt internalInputBufferRemaingBytes = KMinBytesInput
       
   714                                            - iInternalInputBufferResidueLen;
       
   715 
       
   716     if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes )
       
   717         {
       
   718         numberOfBytesToBeCopied = srcBufferRemainingBytes;
       
   719         }
       
   720     else
       
   721         {
       
   722         numberOfBytesToBeCopied = internalInputBufferRemaingBytes;
       
   723         }
       
   724 
       
   725     Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen,
       
   726     srcPtr + srcBufferPos + aSrcBytesConsumed,
       
   727     numberOfBytesToBeCopied );
       
   728 
       
   729     iInternalInputBufferResidueLen += numberOfBytesToBeCopied;
       
   730     aSrcBytesConsumed += numberOfBytesToBeCopied;
       
   731     PRINT_EXIT;
       
   732     return numberOfBytesToBeCopied;
       
   733     }
       
   734 
       
   735 //---------------------------------------------------------------------------
       
   736 // Moves the data of the internal input buffer to the start position
       
   737 //---------------------------------------------------------------------------
       
   738 //
       
   739 void CAriHeAacDecMmfCodec::ShiftData( TInt aFromPos, TInt aToPos )
       
   740     {
       
   741     PRINT_ENTRY;
       
   742     for ( TInt i = 0; i < ( iInternalInputBufferResidueLen -
       
   743             aFromPos ); i++ )
       
   744         {
       
   745         iInternalInputBuffer[i] =
       
   746             iInternalInputBuffer[i + aFromPos];
       
   747         }
       
   748     iInternalInputBufferResidueLen -= aFromPos;
       
   749     PRINT_EXIT;
       
   750     }
       
   751 
       
   752 //---------------------------------------------------------------------------
       
   753 // Calls Decode with NULL as source after all source data is exhausted
       
   754 //---------------------------------------------------------------------------
       
   755 //
       
   756 void CAriHeAacDecMmfCodec::DecodeLastFrame( TInt& aDstLen )
       
   757     {
       
   758     TInt error = iCodec->Decode( NULL, iSrcUsed,
       
   759                                             iInternalOutputBuffer, aDstLen );
       
   760     if ( KErrNone != error )
       
   761         {
       
   762         aDstLen = 0;
       
   763         }
       
   764 
       
   765     iLastFrameDecoded = ETrue;
       
   766     }
       
   767 
       
   768 // ---------------------------------------------------------------------------
       
   769 //  Exported proxy for instantiation method resolution
       
   770 //  Define the interface UIDs
       
   771 // ---------------------------------------------------------------------------
       
   772 //
       
   773 const TImplementationProxy ImplementationTable[] =
       
   774     {
       
   775     IMPLEMENTATION_PROXY_ENTRY( KUidHeAacDecMmfImplUid,
       
   776                                             CAriHeAacDecMmfCodec::NewL )
       
   777     };
       
   778 
       
   779 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(
       
   780                                                     TInt& aTableCount )
       
   781     {
       
   782     PRINT_ENTRY;
       
   783     aTableCount = sizeof( ImplementationTable ) /
       
   784                                     sizeof( TImplementationProxy );
       
   785     PRINT_EXIT;
       
   786     return ImplementationTable;
       
   787     }