videoeditorengine/audioeditorengine/src/ProcDecoder.cpp
changeset 9 d87d32eab1a9
parent 0 951a5db380a0
equal deleted inserted replaced
0:951a5db380a0 9:d87d32eab1a9
     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 #include "ProcDecoder.h"
       
    22 #include "audconstants.h"
       
    23 #include    <MmfDatabuffer.h>
       
    24 #include    <mmfcontrollerpluginresolver.h>
       
    25 #include    <mmf/plugin/mmfCodecImplementationUIDs.hrh>
       
    26 #include    <MMFCodec.h>
       
    27 
       
    28 
       
    29 // CONSTANTS
       
    30 
       
    31 
       
    32 
       
    33 
       
    34 
       
    35 // MACROS
       
    36 
       
    37 // Debug print macro
       
    38 #if defined _DEBUG 
       
    39 #include <e32svr.h>
       
    40 #define PRINT(x) RDebug::Print x;
       
    41 #else
       
    42 #define PRINT(x)
       
    43 #endif
       
    44 
       
    45 
       
    46 CProcDecoder* CProcDecoder::NewL()
       
    47                             
       
    48     {
       
    49     CProcDecoder* self = NewLC();
       
    50     CleanupStack::Pop(self);
       
    51     return self;
       
    52     
       
    53     }
       
    54 
       
    55 
       
    56 CProcDecoder* CProcDecoder::NewLC()
       
    57                                 
       
    58     {
       
    59 
       
    60     CProcDecoder* self = new (ELeave) CProcDecoder();
       
    61     CleanupStack::PushL(self);
       
    62     self->ConstructL();
       
    63     return self;
       
    64     
       
    65     }
       
    66 
       
    67 CProcDecoder::~CProcDecoder()
       
    68     {
       
    69     
       
    70     delete iSourceInputBuffer;
       
    71     
       
    72     // Input buffer for encoder (alternative output buffer for decoder).
       
    73     delete  iDestInputBuffer;
       
    74         
       
    75     // Codec used in decoding input audio to PCM16
       
    76     delete iSourceCodec;
       
    77     
       
    78     delete iSampleRateChannelBuffer;
       
    79     
       
    80     delete iRateConverter;
       
    81         
       
    82     }
       
    83  
       
    84 TBool CProcDecoder::InitL(TAudFileProperties aProperties, TInt aTargetSamplingRate, TChannelMode aChannelMode)
       
    85     {
       
    86     PRINT((_L("CProcDecoder::InitL() in")));
       
    87     
       
    88     if (aTargetSamplingRate == 0)
       
    89         {
       
    90         
       
    91         // we are just adding a clip now, check if the source codec is available
       
    92         iProperties = aProperties;    
       
    93         SetSourceCodecL();
       
    94         
       
    95         return ETrue;
       
    96         }
       
    97     
       
    98     
       
    99     iDecimFactor = 0; // by default
       
   100     
       
   101     iDoDecoding = ETrue;
       
   102     
       
   103     if (aProperties.iAudioType == EAudWAV)
       
   104         {
       
   105         // if input is PCM, no decoding is required, but possibly sample rate conversion
       
   106         iDoDecoding = EFalse;
       
   107         }
       
   108     
       
   109     
       
   110     
       
   111     // set output params
       
   112     iToSampleRate = aTargetSamplingRate;
       
   113     iToChannels = 1;
       
   114     
       
   115     if (aChannelMode == EAudStereo)
       
   116         {
       
   117         iToChannels = 2;    
       
   118         }
       
   119     
       
   120     
       
   121     //set input params
       
   122     iProperties = aProperties;
       
   123     
       
   124     iFromSampleRate = iProperties.iSamplingRate;
       
   125     
       
   126     iFromChannels = 1;
       
   127     
       
   128     if (aProperties.iChannelMode == EAudStereo)
       
   129         {
       
   130         iFromChannels = 2;    
       
   131         }
       
   132     
       
   133     
       
   134     iDoSampleRateChannelConversion = EFalse;
       
   135     if (iFromSampleRate != iToSampleRate || iProperties.iChannelMode != aChannelMode)
       
   136         {
       
   137         // sample rate or channel conversion is needed
       
   138         iDoSampleRateChannelConversion = ETrue;
       
   139         }
       
   140     
       
   141  
       
   142     PRINT((_L("CProcDecoder::PrepareConverterL() in")));
       
   143     
       
   144     TInt destInputBufferSize = 0;
       
   145     TInt sourceInputBufferSize = 0;
       
   146     
       
   147     // buffer sizes for input and output
       
   148     if ( iProperties.iAudioType == EAudAMR )
       
   149         {
       
   150         destInputBufferSize = KAedSizeAMRBuffer;
       
   151         sourceInputBufferSize = KAedMaxAMRFrameLength;
       
   152        
       
   153         }
       
   154     else if ( iProperties.iAudioType == EAudAMRWB )
       
   155         {
       
   156         destInputBufferSize = KAedSizeAWBBuffer;
       
   157         sourceInputBufferSize = KAedMaxAWBFrameLength;
       
   158        
       
   159         }
       
   160     else if (iProperties.iAudioType == EAudAAC_MPEG4 &&
       
   161              iProperties.iAudioTypeExtension == EAudExtensionTypeNoExtension)
       
   162         {
       
   163         if ( aProperties.iChannelMode == EAudSingleChannel )
       
   164             {
       
   165             destInputBufferSize = KAedSizeAACBuffer;
       
   166             sourceInputBufferSize = KAedMaxAACFrameLengthPerChannel;
       
   167             }
       
   168         else
       
   169             {
       
   170             destInputBufferSize = KAedSizeAACStereoBuffer;
       
   171             sourceInputBufferSize = 2* KAedMaxAACFrameLengthPerChannel;
       
   172             }
       
   173                  
       
   174         }
       
   175     else if (iProperties.iAudioType == EAudAAC_MPEG4 &&
       
   176              iProperties.iAudioTypeExtension != EAudExtensionTypeNoExtension)
       
   177         {
       
   178         if ( iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo )
       
   179             {
       
   180             // output is parametric stereo (mono channel, but decoded to stereo)
       
   181             destInputBufferSize = KAedSizeAACStereoBuffer*2; // 2 for eAAC+
       
   182             sourceInputBufferSize = KAedMaxAACFrameLengthPerChannel;
       
   183             }
       
   184         else
       
   185             {
       
   186             // output is normal stereo
       
   187             destInputBufferSize = KAedSizeAACBuffer*2; // 2 for eAAC+
       
   188             sourceInputBufferSize = 2* KAedMaxAACFrameLengthPerChannel;
       
   189             }
       
   190             
       
   191                  
       
   192         }
       
   193     
       
   194     else if ( iProperties.iAudioType == EAudMP3 )
       
   195         {
       
   196         // mp3 can be directly decoded to mono if necessary
       
   197         if (iToChannels == 1)
       
   198             {
       
   199             iFromChannels = 1;
       
   200             }
       
   201         
       
   202         // check if decimation would be useful    
       
   203         if (iFromSampleRate == iToSampleRate * 4)
       
   204             {
       
   205             iFromSampleRate /= 4;
       
   206             iDecimFactor = 4;
       
   207             }
       
   208             
       
   209         if (iFromSampleRate == iToSampleRate * 2)
       
   210             {
       
   211             iFromSampleRate /= 2;
       
   212             iDecimFactor = 2;
       
   213             }
       
   214             
       
   215         if ((iToSampleRate == 8000) && ((iFromSampleRate == 48000) || (iFromSampleRate == 44100)))
       
   216             {
       
   217             iFromSampleRate /= 2;
       
   218             iDecimFactor = 2;
       
   219             }        
       
   220         
       
   221         const TReal KMP3FrameDurationSec = 0.026;
       
   222         
       
   223         destInputBufferSize =  (iFromSampleRate * KMP3FrameDurationSec + 1);
       
   224         destInputBufferSize *= 2; //16 bit samples
       
   225         if (iFromChannels == 2)
       
   226             {
       
   227             destInputBufferSize *= 2; // stereo
       
   228             }
       
   229         
       
   230         sourceInputBufferSize = KAedMaxMP3FrameLength;
       
   231         }
       
   232         
       
   233     else if (iProperties.iAudioType == EAudWAV)
       
   234         {
       
   235         // frame duration in WAV case is always 20 ms, that is 50 frames per sec
       
   236         const TInt KNumberOfFramesInSecond = 50;
       
   237             
       
   238         destInputBufferSize = iFromSampleRate / KNumberOfFramesInSecond;    // Number of samples
       
   239         destInputBufferSize *= iFromChannels;
       
   240         if ((destInputBufferSize % 2) != 0) destInputBufferSize++;          // Must be even
       
   241         destInputBufferSize *= 2;                                           // 16-bit samples
       
   242         
       
   243         sourceInputBufferSize = iProperties.iFrameLen;
       
   244         
       
   245         TInt sourceBufferSizeAfterExpansion = sourceInputBufferSize;
       
   246         if (iProperties.iNumberOfBitsPerSample == 8)
       
   247             {
       
   248             // 8-bit samples are expanded to 16-bit so twice as big buffer is needed
       
   249             sourceBufferSizeAfterExpansion *= 2;
       
   250             }
       
   251         
       
   252         if (sourceBufferSizeAfterExpansion > destInputBufferSize)
       
   253             {
       
   254             // Make sure there's no overflow
       
   255             destInputBufferSize = sourceBufferSizeAfterExpansion;
       
   256             }
       
   257         }
       
   258         
       
   259     PRINT((_L("CProcDecoder::InitL() source size: %d, dest size %d"), sourceInputBufferSize, destInputBufferSize));
       
   260     
       
   261 
       
   262     if ( iSourceInputBuffer )
       
   263         {
       
   264         delete iSourceInputBuffer;
       
   265         iSourceInputBuffer = NULL;
       
   266         }
       
   267     // create buffer for input data
       
   268     iSourceInputBuffer = CMMFDataBuffer::NewL(sourceInputBufferSize);
       
   269     
       
   270     
       
   271     if ( iDestInputBuffer )
       
   272         {
       
   273         delete iDestInputBuffer;
       
   274         iDestInputBuffer = NULL;
       
   275         }
       
   276 
       
   277     
       
   278     TInt errC = KErrNone;
       
   279     if (iDoDecoding)
       
   280         {
       
   281         SetSourceCodecL();
       
   282         
       
   283         // create buffer for output data if necessary
       
   284         iDestInputBuffer = CMMFDataBuffer::NewL( destInputBufferSize);
       
   285         }
       
   286     
       
   287 
       
   288 
       
   289     TInt err = KErrNone;
       
   290 
       
   291     if (iProperties.iAudioType == EAudAAC_MPEG4)
       
   292         {
       
   293         // configure AAC plus decoder, used also for AAC
       
   294         TRAP( err, ConfigureAACPlusDecoderL());
       
   295         
       
   296         }
       
   297     
       
   298     else if ( iProperties.iAudioType == EAudMP3 )
       
   299         {
       
   300         // configure mp3 decoder
       
   301         TRAP( err, ConfigureMP3DecoderL());
       
   302         
       
   303         }
       
   304     if (err != KErrNone || errC != KErrNone)
       
   305         {
       
   306         User::Leave(KErrNotSupported);
       
   307         }
       
   308 
       
   309     if ( iDoSampleRateChannelConversion )
       
   310         {
       
   311         if (iRateConverter)
       
   312             {
       
   313             delete iRateConverter;
       
   314             iRateConverter = NULL;
       
   315             }
       
   316 
       
   317         iRateConverter = CRateConverter::NewL(iFromSampleRate, iToSampleRate, iFromChannels, iToChannels);
       
   318         
       
   319         if( !iRateConverter->InitL(destInputBufferSize / (2 * iFromChannels)) ) // 16-bit samples
       
   320             {
       
   321             User::Leave(KErrNotSupported);
       
   322             }
       
   323             
       
   324         TInt sampleRateBufferSize = iRateConverter->GetOutputBufferSize() * 2 * iToChannels;    // 16-bit samples
       
   325         
       
   326         PRINT((_L("CProcDecoder::InitL() sample rate buffer size %d"), sampleRateBufferSize));
       
   327                
       
   328         if ( iSampleRateChannelBuffer )
       
   329             {
       
   330             delete iSampleRateChannelBuffer;
       
   331             iSampleRateChannelBuffer = NULL;
       
   332             }
       
   333 
       
   334         // Buffer for sample rate conversion output
       
   335         iSampleRateChannelBuffer = CMMFDataBuffer::NewL(sampleRateBufferSize);
       
   336         }
       
   337 
       
   338 
       
   339     iReady = ETrue;
       
   340     PRINT((_L("CProcDecoder::InitL() out")));
       
   341 
       
   342     
       
   343     return ETrue;
       
   344     }
       
   345 
       
   346 TBool CProcDecoder::FillDecBufferL(const HBufC8* aEncFrame, HBufC8*& aDecBuffer)
       
   347     {
       
   348     PRINT((_L("CProcDecoder::FillDecBufferL() in")));
       
   349     
       
   350     iDecBuffer = 0;
       
   351     if (iProperties.iAudioType == EAudWAV && !iDoSampleRateChannelConversion)
       
   352         {
       
   353         
       
   354         // if we don't have to do anything for input data ->
       
   355         aDecBuffer = HBufC8::NewL(aEncFrame->Size());
       
   356         aDecBuffer->Des().Append(*aEncFrame);
       
   357         PRINT((_L("CProcDecoder::FillDecBufferL() out from Wav branch with ETrue")));
       
   358         return ETrue;
       
   359 
       
   360         }
       
   361         
       
   362         
       
   363     if (!iReady)
       
   364         {
       
   365         User::Leave(KErrNotReady);
       
   366         }
       
   367       
       
   368     if ( aEncFrame == 0 || !aEncFrame->Length() )
       
   369         {
       
   370         // no data in input buffer
       
   371         PRINT((_L("CProcDecoder::FillDecBufferL() no input data, out with EFalse")));
       
   372         return EFalse;
       
   373         }
       
   374     
       
   375     if ( (TInt)(aEncFrame->Length() + iSourceInputBuffer->Position() ) > iSourceInputBuffer->Data().MaxLength() )
       
   376         {
       
   377         
       
   378         ReAllocBufferL( iSourceInputBuffer, aEncFrame->Length() + iSourceInputBuffer->Position() );
       
   379         }
       
   380     
       
   381     iSourceInputBuffer->Data().SetLength( 0 );
       
   382     iSourceInputBuffer->SetPosition( 0 );
       
   383     
       
   384     iSourceInputBuffer->Data().Append( *aEncFrame );
       
   385     iSourceInputBuffer->Data().SetLength( aEncFrame->Length() );
       
   386     
       
   387     PRINT((_L("CProcDecoder::FillDecBufferL(), iSourceInputBuffer length = %d"),aEncFrame->Length()));
       
   388     if (iDoDecoding)
       
   389         {
       
   390         iDestInputBuffer->Data().SetLength(0);
       
   391         iDestInputBuffer->SetPosition(0); 
       
   392         
       
   393         }
       
   394             
       
   395     if ( iDoSampleRateChannelConversion )
       
   396         {
       
   397         iSampleRateChannelBuffer->Data().SetLength(0);
       
   398         iSampleRateChannelBuffer->SetPosition(0);
       
   399         }
       
   400         
       
   401     
       
   402     FeedCodecL( iSourceCodec, iSourceInputBuffer, iDestInputBuffer);
       
   403  
       
   404     if ( aDecBuffer )
       
   405         {
       
   406         // in case of EDstNotFilled from decoder, you may end up looping and to avoid memory leaks, you need to 
       
   407         // delete the previous allocated buffer. Alternative might be to not allocate a new one in this case.
       
   408         delete aDecBuffer;
       
   409         aDecBuffer = NULL;
       
   410         }
       
   411     aDecBuffer = iDecBuffer;    
       
   412             
       
   413     if (iDoDecoding)
       
   414         {
       
   415         iDestInputBuffer->Data().SetLength(0);
       
   416         iDestInputBuffer->SetPosition(0); 
       
   417         
       
   418         }
       
   419     
       
   420     if (iDecBuffer != 0 && iDecBuffer->Size() > 0)
       
   421         {
       
   422         PRINT((_L("CProcDecoder::FillDecBufferL() out with ETrue")));
       
   423         return ETrue;
       
   424           
       
   425         }
       
   426                
       
   427     PRINT((_L("CProcDecoder::FillDecBufferL() out with EFalse")));
       
   428     return EFalse;
       
   429         
       
   430     }
       
   431 
       
   432 
       
   433 void CProcDecoder::ConstructL()
       
   434     {
       
   435     
       
   436     
       
   437     
       
   438     }
       
   439 
       
   440 CProcDecoder::CProcDecoder()
       
   441     {
       
   442     
       
   443     }
       
   444     
       
   445     
       
   446     
       
   447 void CProcDecoder::ConfigureAACPlusDecoderL()
       
   448     {
       
   449 
       
   450     
       
   451     RArray<TInt> config;
       
   452     
       
   453     if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo)
       
   454         {
       
   455         
       
   456         // for sample rate and channel converter, the output from parametric stereo
       
   457         // is stereo, only the AAC part is incoded as mono
       
   458         iFromChannels = 2;
       
   459         }
       
   460     
       
   461     
       
   462     config.Append( iFromSampleRate);
       
   463     config.Append( iFromChannels );
       
   464    
       
   465     
       
   466     if (iProperties.iAACObjectType ==  EAudAACObjectTypeLC)
       
   467         {
       
   468         config.Append( 1 );     // {1 - LC, 3 - LTP}    
       
   469         }
       
   470     else if (iProperties.iAACObjectType ==  EAudAACObjectTypeLTP)
       
   471         {
       
   472         config.Append( 3 );     // {1 - LC, 3 - LTP}    
       
   473         }
       
   474     else
       
   475         {
       
   476         User::Leave(KErrNotSupported);
       
   477         }
       
   478     
       
   479     config.Append( 8192 );  //Size of PCM Samples generated by decoder
       
   480     
       
   481     config.Append( 1024 );  //Number of PCM Samples generated by decoder per frame
       
   482     
       
   483     config.Append( iFromSampleRate);        //Sampling freq of AAC Code decoder
       
   484     
       
   485     config.Append( 0 );     // not used ??
       
   486     
       
   487   
       
   488     config.Append( 0 );     // down sampled mode
       
   489     
       
   490     config.Append( 16 );    // Sample resolution: 16-bit resolution
       
   491     
       
   492     
       
   493         
       
   494     // NOTE!: for some reason, the sample rate of the output from AACPlus decoder used
       
   495     // to be a half of the proper output sampling rate. 
       
   496     // eAAC+ data consists of AAC band + enhancement band. The enhancement band is not included
       
   497     // in the rate indicated in the header (iFromSampleRate)
       
   498     // There was a workaround for the 
       
   499     // earlier problem not to increase the sampling rate.
       
   500     // Now, with 2006 releases it seems to work, and the sampling rate need to be doubled
       
   501     // for the sampling rate converter.
       
   502     
       
   503     if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlus)
       
   504         {
       
   505         iFromSampleRate *= 2; // for sample rate converter ->
       
   506         config.Append(iFromSampleRate);// Output sampling frequency
       
   507         config.Append( 5 ); //Type of extended object (5=SBR/HE AAC profile; 6=PS is present)
       
   508         
       
   509         }
       
   510     else if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo)
       
   511         {
       
   512         iFromSampleRate *= 2; // for sample rate converter ->
       
   513         config.Append(iFromSampleRate);// Output sampling frequency
       
   514         config.Append( 6 ); //Type of extended object (5=SBR/HE AAC profile; 6=PS is present)
       
   515         }
       
   516     else
       
   517         {
       
   518         // AAC, in&out samplerates are equal, and extended object type is 0
       
   519         config.Append(iFromSampleRate);// Output sampling frequency
       
   520         config.Append( 0 );
       
   521         
       
   522         }
       
   523         
       
   524 
       
   525     TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations
       
   526     TRAPD( err, iSourceCodec->ConfigureL( uid, reinterpret_cast<TDesC8&>(config)));
       
   527             
       
   528     if ( err != KErrNone )
       
   529         {
       
   530         PRINT((_L("CProcDecoder::PrepareConverterL() error, Source codec config failed")));
       
   531         config.Close();
       
   532         User::Leave( err );
       
   533         }
       
   534     config.Close();
       
   535     
       
   536     }
       
   537     
       
   538     
       
   539 void CProcDecoder::ConfigureMP3DecoderL()
       
   540     {
       
   541 
       
   542     
       
   543     RArray<TInt> config;
       
   544     
       
   545     TInt stereoToMono = 0;
       
   546     if (iToChannels == 1 || iFromChannels == 1)
       
   547         {
       
   548         stereoToMono = 1;
       
   549         }
       
   550     
       
   551     config.Append( stereoToMono); // stereo to mono
       
   552     config.Append( 0 ); //iLeftRight??
       
   553     config.Append( iDecimFactor ); //iDecimFactor
       
   554     config.Append( 0 ); //iConcealment
       
   555     config.Append( 0 ); //iSampleLength??
       
   556     config.Append( 0 ); //iSamplingFrequency
       
   557     
       
   558     TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations
       
   559     TRAPD( err, iSourceCodec->ConfigureL( uid, reinterpret_cast<TDesC8&>(config)));
       
   560             
       
   561     if ( err != KErrNone )
       
   562         {
       
   563         PRINT((_L("CProcDecoder::PrepareConverterL() error, Source codec config failed")));
       
   564         config.Close();
       
   565         User::Leave( err );
       
   566         }
       
   567     config.Close();
       
   568     }
       
   569     
       
   570     
       
   571 void CProcDecoder::ReAllocBufferL( CMMFDataBuffer* aBuffer, TInt aNewMaxSize )
       
   572     {
       
   573     if ( aBuffer->Data().Length() )
       
   574         {
       
   575         TInt position = aBuffer->Position();
       
   576         TInt length = aBuffer->Data().Length();
       
   577         HBufC8* oldData = aBuffer->Data().AllocL();
       
   578         CleanupStack::PushL( oldData );
       
   579         ((CMMFDescriptorBuffer*)aBuffer)->ReAllocBufferL( aNewMaxSize );
       
   580         aBuffer->Data().Copy( *oldData );
       
   581         CleanupStack::PopAndDestroy( oldData );
       
   582         aBuffer->Data().SetLength( length );
       
   583         aBuffer->SetPosition( position );
       
   584         }
       
   585     else
       
   586         {
       
   587         ((CMMFDescriptorBuffer*)aBuffer)->ReAllocBufferL( aNewMaxSize );
       
   588         }
       
   589     }
       
   590     
       
   591 void CProcDecoder::FeedCodecL( CMMFCodec* aCodec, CMMFDataBuffer* aSourceBuffer, CMMFDataBuffer* aDestBuffer )
       
   592     {
       
   593     PRINT((_L("CProcDecoder::FeedCodecL() in")));
       
   594     TBool completed = EFalse;
       
   595     TCodecProcessResult result;
       
   596 
       
   597     while ( !completed )
       
   598         {
       
   599 
       
   600         if (iDoDecoding)
       
   601             {
       
   602             // decode and check the result
       
   603             result = DecodeL(aCodec, aSourceBuffer, aDestBuffer);
       
   604             }
       
   605         else
       
   606             {
       
   607             
       
   608             // no need for decoding, just perform sample rate and channel conversion
       
   609             result.iStatus = TCodecProcessResult::EProcessComplete;
       
   610             }
       
   611        
       
   612         
       
   613         switch ( result.iStatus )
       
   614             {
       
   615             case TCodecProcessResult::EProcessIncomplete:
       
   616                 // Not all data from input was consumed (DecodeL updated buffer members), but output was generated
       
   617                     
       
   618                 if ( iDoSampleRateChannelConversion )
       
   619                     {
       
   620                     if ( !iRateConverter )
       
   621                         {
       
   622                         PRINT((_L("CProcDecoder::FeedCodecL() error, no rate converter")));
       
   623                         User::Leave( KErrNotFound );
       
   624                         }
       
   625                     
       
   626                     // Convert buffer size in bytes    
       
   627                     TUint convertBufferSize = aDestBuffer->Data().Length();
       
   628                     
       
   629                     // Number of samples in the buffer
       
   630                     TUint inputSamples = convertBufferSize / (2 * iFromChannels);    // 16-bit samples
       
   631                     
       
   632                     PRINT((_L("CProcDecoder::FeedCodecL() converting %d samples"), inputSamples));
       
   633                     
       
   634                     if ( convertBufferSize > ( iDestInputBuffer->Data().MaxLength() - iDestInputBuffer->Position() ) )
       
   635                         {
       
   636                         ReAllocBufferL( iDestInputBuffer, convertBufferSize + iDestInputBuffer->Position() );
       
   637                         }
       
   638 
       
   639                     TInt outputSamples = iRateConverter->ConvertBufferL( (TInt16*) aDestBuffer->Data().Ptr(),
       
   640                         (TInt16*) iSampleRateChannelBuffer->Data().Ptr(), inputSamples );
       
   641                         
       
   642                     iSampleRateChannelBuffer->Data().SetLength( outputSamples * 2 * iToChannels );
       
   643 
       
   644                     UpdateOutputBufferL(iSampleRateChannelBuffer);
       
   645                     
       
   646                     }  
       
   647                 else
       
   648                     {
       
   649                     if (iDoDecoding)
       
   650                         {
       
   651 
       
   652                         UpdateOutputBufferL(aDestBuffer);
       
   653                         }
       
   654                     }
       
   655                     
       
   656                 break;
       
   657 
       
   658             case TCodecProcessResult::EProcessComplete:
       
   659                 // all data from input was used and output was generated
       
   660                 if ( iDoSampleRateChannelConversion )
       
   661                     {
       
   662                     if ( !iRateConverter )
       
   663                         {
       
   664                         PRINT((_L("CProcDecoder::FeedCodecL() error, no rate converter")));
       
   665                         User::Leave( KErrNotFound );
       
   666                         }
       
   667                         
       
   668                         
       
   669                     CMMFDataBuffer* src = 0;
       
   670                         
       
   671                     if (!iDoDecoding)
       
   672                         {
       
   673                         
       
   674                         // if decoding was not needed, 
       
   675                         // the input data for SR converter is in aSourceBuffer
       
   676                         src = aSourceBuffer;
       
   677                         }
       
   678                     else
       
   679                         {
       
   680                         // if decoding was needed, 
       
   681                         // the input data for SR converter is in iDestBuffer
       
   682                       
       
   683                         src = iDestInputBuffer;
       
   684                         }
       
   685                         
       
   686                     // Convert buffer size in bytes 
       
   687                     TUint convertBufferSize = src->Data().Length();
       
   688                     
       
   689                     // Number of samples in the buffer
       
   690                     TUint inputSamples = convertBufferSize / (2 * iFromChannels);    // 16-bit samples
       
   691                     
       
   692                     PRINT((_L("CProcDecoder::FeedCodecL() converting %d samples"), inputSamples));
       
   693    
       
   694                     if ( convertBufferSize > ( src->Data().MaxLength() - src->Position() ) )
       
   695                         {
       
   696                         ReAllocBufferL( src, convertBufferSize + src->Position() );
       
   697                         }
       
   698                         
       
   699                     TInt outputSamples = iRateConverter->ConvertBufferL( (TInt16*) src->Data().Ptr(),
       
   700                         (TInt16*) iSampleRateChannelBuffer->Data().Ptr(), inputSamples );
       
   701                         
       
   702                     iSampleRateChannelBuffer->Data().SetLength( outputSamples * 2 * iToChannels );
       
   703 
       
   704                     UpdateOutputBufferL(iSampleRateChannelBuffer);
       
   705  
       
   706                     }
       
   707                 else
       
   708                     {
       
   709                     if (iDoDecoding)
       
   710                         {
       
   711                         UpdateOutputBufferL(aDestBuffer);
       
   712                         }
       
   713                     
       
   714                     }
       
   715         
       
   716                 completed = ETrue;
       
   717                 break;
       
   718 
       
   719             case TCodecProcessResult::EDstNotFilled:
       
   720                 // need more input data, can't fill the output yet; put it back to the empty queue
       
   721                 completed = ETrue;
       
   722              
       
   723                 break;
       
   724 
       
   725             default:
       
   726                 // EEndOfData, EProcessError, EProcessIncompleteRepositionRequest, EProcessCompleteRepositionRequest
       
   727                 User::Leave( KErrUnknown );
       
   728             }
       
   729 
       
   730         }
       
   731     
       
   732 
       
   733     PRINT((_L("CProcDecoder::FeedCodecL() out")));
       
   734     }
       
   735     
       
   736 TCodecProcessResult CProcDecoder::DecodeL( CMMFCodec* aCodec, CMMFDataBuffer* aInBuffer, CMMFDataBuffer* aOutBuffer)
       
   737     {
       
   738     PRINT((_L("CProcDecoder::DecodeL() in, input pos: %d, length: %d"), aInBuffer->Position(), aInBuffer->Data().Length() ));
       
   739     TCodecProcessResult result;
       
   740 
       
   741     result = aCodec->ProcessL (*aInBuffer, *aOutBuffer);
       
   742 
       
   743     switch (result.iStatus)
       
   744         {
       
   745         case TCodecProcessResult::EProcessComplete:
       
   746             // finished processing source data, all data in sink buffer
       
   747             PRINT((_L("CProcDecoder::FeedCodecL() EProcessComplete")));
       
   748             aInBuffer->SetPosition( 0 );
       
   749             aInBuffer->Data().SetLength(0);
       
   750             break;
       
   751 
       
   752         case TCodecProcessResult::EDstNotFilled:
       
   753             // the destination is not full, we need more data. Handled in caller
       
   754             PRINT((_L("CProcDecoder::FeedCodecL() EDstNotFilled")));
       
   755             aInBuffer->SetPosition( 0 );
       
   756             aInBuffer->Data().SetLength(0);
       
   757             break;
       
   758 
       
   759         case TCodecProcessResult::EProcessIncomplete:
       
   760             // the sink was filled before all the source was processed
       
   761             PRINT((_L("CProcDecoder::FeedCodecL() EProcessIncomplete")));
       
   762             aOutBuffer->SetPosition( 0 );
       
   763             aInBuffer->SetPosition( aInBuffer->Position() + result.iSrcBytesProcessed );
       
   764             break;
       
   765 
       
   766         default:
       
   767             break;
       
   768         }
       
   769 
       
   770     PRINT((_L("CProcDecoder::DecodeL() out, %d -> %d"),result.iSrcBytesProcessed, result.iDstBytesAdded));
       
   771     PRINT((_L("CProcDecoder::DecodeL() out, input pos: %d, length: %d"), aInBuffer->Position(), aInBuffer->Data().Length() ));
       
   772     return result;
       
   773     }
       
   774     
       
   775 TBool CProcDecoder::GetIsSupportedSourceCodec()
       
   776     {
       
   777  
       
   778      TFourCC fourCC;
       
   779      TUid uID;
       
   780  
       
   781     if (iProperties.iAudioType == EAudAMR)
       
   782         {
       
   783         fourCC = TFourCC(KMMFFourCCCodeAMR);
       
   784         uID = TUid(KMmfAMRNBDecSWCodecUid);
       
   785         }
       
   786     else if (iProperties.iAudioType == EAudAAC_MPEG4)
       
   787         {
       
   788         // use eAAC+ also for AAC
       
   789         fourCC = TFourCC(KMMFFourCCCodeAACPlus);
       
   790         uID = TUid(KMmfUidCodecEnhAACPlusToPCM16);
       
   791         }
       
   792     else if (iProperties.iAudioType == EAudMP3)
       
   793         {
       
   794         fourCC = TFourCC(KMMFFourCCCodeMP3);
       
   795         uID = TUid(KMmfAdvancedUidCodecMP3ToPCM16);
       
   796         }
       
   797     else if (iProperties.iAudioType == EAudAMRWB)
       
   798         {
       
   799         fourCC = TFourCC(KMMFFourCCCodeAWB);
       
   800         uID = TUid(KMmfAMRWBDecSWCodecUid);
       
   801         }
       
   802     else
       
   803         {
       
   804         //Wav, no codec
       
   805         return ETrue;
       
   806         }
       
   807     
       
   808     
       
   809     
       
   810     _LIT8(emptyFourCCString, "    ,    ");
       
   811     TBufC8<9> fourCCString(emptyFourCCString);
       
   812     TPtr8 fourCCPtr = fourCCString.Des();
       
   813     TPtr8 fourCCPtr1(&fourCCPtr[0], 4);
       
   814     TPtr8 fourCCPtr2(&fourCCPtr[5], 4 );
       
   815 
       
   816     TFourCC srcFourCC(' ','P','1','6');
       
   817     fourCC.FourCC(&fourCCPtr1);
       
   818     srcFourCC.FourCC(&fourCCPtr2);
       
   819 
       
   820     TBool found = EFalse;
       
   821     TRAPD( err, found = CheckIfCodecAvailableL( fourCCPtr , uID));
       
   822     
       
   823     if (err == KErrNone)
       
   824         {
       
   825         return found;    
       
   826         }
       
   827     else
       
   828         {
       
   829         return EFalse;
       
   830         }
       
   831     }
       
   832 
       
   833 
       
   834 void CProcDecoder::SetSourceCodecL()
       
   835     {
       
   836     PRINT((_L("CProcDecoder::SetSourceCodecL() in")));
       
   837 
       
   838     if ( !GetIsSupportedSourceCodec() )
       
   839         {
       
   840         PRINT((_L("CProcDecoder::SetSourceCodecL() error, unsupported codec")));
       
   841         User::Leave( KErrNotSupported );
       
   842         }
       
   843 
       
   844     if ( iSourceCodec )
       
   845         {
       
   846         delete iSourceCodec;
       
   847         iSourceCodec = NULL;
       
   848         }
       
   849     
       
   850     TFourCC destFourCC = KMMFFourCCCodePCM16;
       
   851     
       
   852     if (iProperties.iAudioType == EAudAMR)
       
   853         {
       
   854         iSourceCodec = CMMFCodec::NewL( KMmfAMRNBDecSWCodecUid );
       
   855     
       
   856         }
       
   857     else if (iProperties.iAudioType == EAudAAC_MPEG4)
       
   858         {
       
   859         // use eAAC+ also for AAC
       
   860         iSourceCodec = CMMFCodec::NewL( KMmfUidCodecEnhAACPlusToPCM16 );
       
   861     
       
   862         }
       
   863     else if (iProperties.iAudioType == EAudMP3)
       
   864         {
       
   865         iSourceCodec = CMMFCodec::NewL( KMmfAdvancedUidCodecMP3ToPCM16 );
       
   866     
       
   867         }
       
   868     else if (iProperties.iAudioType == EAudAMRWB)
       
   869         {
       
   870         iSourceCodec = CMMFCodec::NewL( KMmfAMRWBDecSWCodecUid );
       
   871     
       
   872         }
       
   873     else
       
   874         {
       
   875         // Wav, but no codec needed then
       
   876         }
       
   877     
       
   878     iReady = EFalse;
       
   879 
       
   880     PRINT((_L("CProcDecoder::SetSourceCodecL() out")));
       
   881     }
       
   882     
       
   883     
       
   884     
       
   885 TBool CProcDecoder::CheckIfCodecAvailableL(const TDesC8& aCodecFourCCString, 
       
   886                                             const TUid& aCodecUId )
       
   887     {
       
   888     PRINT((_L("CProcDecoder::CheckIfCodecAvailableL() in")));
       
   889     TBool found = EFalse;
       
   890 
       
   891     // Create a TEcomResolverParams structure.
       
   892     TEComResolverParams resolverParams ;
       
   893     resolverParams.SetDataType( aCodecFourCCString ) ;
       
   894     resolverParams.SetWildcardMatch( EFalse ) ;
       
   895 
       
   896     RImplInfoPtrArray plugInArray ; // Array to return matching decoders in (place on cleanupstack _after_ ListImplementationsL() )
       
   897 
       
   898     TUid UidMmfPluginInterfaceCodec = {KMmfUidPluginInterfaceCodec};
       
   899 
       
   900     // ListImplementationsL leaves if it cannot find anything so trap the error and ignore it.
       
   901     TRAPD( err, REComSession::ListImplementationsL(UidMmfPluginInterfaceCodec, resolverParams, plugInArray ) ) ;
       
   902     CleanupResetAndDestroyPushL(plugInArray);
       
   903 
       
   904 
       
   905     if (err == KErrNone)
       
   906         {
       
   907         found = EFalse;
       
   908         for ( TInt i = 0; i < plugInArray.Count(); i++)
       
   909             {
       
   910             // there is a match, but 1st we need to ensure it is the one we have tested with, and that have compatible implementation of ConfigureL
       
   911             PRINT((_L("CProcDecoder::CheckIfCodecAvailable() plugin found with Uid 0x%x"), plugInArray[i]->ImplementationUid().iUid ));
       
   912             if ( plugInArray[i]->ImplementationUid() == aCodecUId )
       
   913                 {
       
   914 			    //match accepted
       
   915                 PRINT((_L("CProcDecoder::CheckIfCodecAvailable() plugin accepted")));
       
   916 			    found = ETrue;
       
   917                 }
       
   918             }
       
   919         }
       
   920     else
       
   921         {
       
   922         PRINT((_L("CProcDecoder::CheckIfCodecAvailable() Error in ListImp.: %d"), err));
       
   923         //no match
       
   924         found = EFalse;
       
   925         }
       
   926 
       
   927     CleanupStack::PopAndDestroy();  //plugInArray
       
   928     PRINT((_L("CProcDecoder::CheckIfCodecAvailableL() out")));
       
   929     return found;
       
   930     }
       
   931     
       
   932 TBool CProcDecoder::UpdateOutputBufferL(CMMFDataBuffer* aInBuffer)
       
   933     {
       
   934     if (iDecBuffer == 0)
       
   935         {
       
   936         iDecBuffer = HBufC8::NewL(aInBuffer->BufferSize());
       
   937         iDecBuffer->Des().Append(aInBuffer->Data());
       
   938         }
       
   939     else
       
   940         {
       
   941         iDecBuffer = iDecBuffer->ReAlloc(iDecBuffer->Size()+aInBuffer->BufferSize());
       
   942         iDecBuffer->Des().Append(aInBuffer->Data());
       
   943         }
       
   944     
       
   945     aInBuffer->Data().SetLength( 0 );
       
   946     aInBuffer->SetPosition( 0 );    
       
   947     
       
   948     return ETrue;
       
   949     }
       
   950