videoeditorengine/audioeditorengine/src/ProcDecoder.cpp
changeset 0 951a5db380a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/audioeditorengine/src/ProcDecoder.cpp	Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,950 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:  
+*
+*/
+
+
+
+#include "ProcDecoder.h"
+#include "audconstants.h"
+#include    <MmfDatabuffer.h>
+#include    <mmfcontrollerpluginresolver.h>
+#include    <mmf/plugin/mmfCodecImplementationUIDs.hrh>
+#include    <MMFCodec.h>
+
+
+// CONSTANTS
+
+
+
+
+
+// MACROS
+
+// Debug print macro
+#if defined _DEBUG 
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x;
+#else
+#define PRINT(x)
+#endif
+
+
+CProcDecoder* CProcDecoder::NewL()
+                            
+    {
+    CProcDecoder* self = NewLC();
+    CleanupStack::Pop(self);
+    return self;
+    
+    }
+
+
+CProcDecoder* CProcDecoder::NewLC()
+                                
+    {
+
+    CProcDecoder* self = new (ELeave) CProcDecoder();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    
+    }
+
+CProcDecoder::~CProcDecoder()
+    {
+    
+    delete iSourceInputBuffer;
+    
+    // Input buffer for encoder (alternative output buffer for decoder).
+    delete  iDestInputBuffer;
+        
+    // Codec used in decoding input audio to PCM16
+    delete iSourceCodec;
+    
+    delete iSampleRateChannelBuffer;
+    
+    delete iRateConverter;
+        
+    }
+ 
+TBool CProcDecoder::InitL(TAudFileProperties aProperties, TInt aTargetSamplingRate, TChannelMode aChannelMode)
+    {
+    PRINT((_L("CProcDecoder::InitL() in")));
+    
+    if (aTargetSamplingRate == 0)
+        {
+        
+        // we are just adding a clip now, check if the source codec is available
+        iProperties = aProperties;    
+        SetSourceCodecL();
+        
+        return ETrue;
+        }
+    
+    
+    iDecimFactor = 0; // by default
+    
+    iDoDecoding = ETrue;
+    
+    if (aProperties.iAudioType == EAudWAV)
+        {
+        // if input is PCM, no decoding is required, but possibly sample rate conversion
+        iDoDecoding = EFalse;
+        }
+    
+    
+    
+    // set output params
+    iToSampleRate = aTargetSamplingRate;
+    iToChannels = 1;
+    
+    if (aChannelMode == EAudStereo)
+        {
+        iToChannels = 2;    
+        }
+    
+    
+    //set input params
+    iProperties = aProperties;
+    
+    iFromSampleRate = iProperties.iSamplingRate;
+    
+    iFromChannels = 1;
+    
+    if (aProperties.iChannelMode == EAudStereo)
+        {
+        iFromChannels = 2;    
+        }
+    
+    
+    iDoSampleRateChannelConversion = EFalse;
+    if (iFromSampleRate != iToSampleRate || iProperties.iChannelMode != aChannelMode)
+        {
+        // sample rate or channel conversion is needed
+        iDoSampleRateChannelConversion = ETrue;
+        }
+    
+ 
+    PRINT((_L("CProcDecoder::PrepareConverterL() in")));
+    
+    TInt destInputBufferSize = 0;
+    TInt sourceInputBufferSize = 0;
+    
+    // buffer sizes for input and output
+    if ( iProperties.iAudioType == EAudAMR )
+        {
+        destInputBufferSize = KAedSizeAMRBuffer;
+        sourceInputBufferSize = KAedMaxAMRFrameLength;
+       
+        }
+    else if ( iProperties.iAudioType == EAudAMRWB )
+        {
+        destInputBufferSize = KAedSizeAWBBuffer;
+        sourceInputBufferSize = KAedMaxAWBFrameLength;
+       
+        }
+    else if (iProperties.iAudioType == EAudAAC_MPEG4 &&
+             iProperties.iAudioTypeExtension == EAudExtensionTypeNoExtension)
+        {
+        if ( aProperties.iChannelMode == EAudSingleChannel )
+            {
+            destInputBufferSize = KAedSizeAACBuffer;
+            sourceInputBufferSize = KAedMaxAACFrameLengthPerChannel;
+            }
+        else
+            {
+            destInputBufferSize = KAedSizeAACStereoBuffer;
+            sourceInputBufferSize = 2* KAedMaxAACFrameLengthPerChannel;
+            }
+                 
+        }
+    else if (iProperties.iAudioType == EAudAAC_MPEG4 &&
+             iProperties.iAudioTypeExtension != EAudExtensionTypeNoExtension)
+        {
+        if ( iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo )
+            {
+            // output is parametric stereo (mono channel, but decoded to stereo)
+            destInputBufferSize = KAedSizeAACStereoBuffer*2; // 2 for eAAC+
+            sourceInputBufferSize = KAedMaxAACFrameLengthPerChannel;
+            }
+        else
+            {
+            // output is normal stereo
+            destInputBufferSize = KAedSizeAACBuffer*2; // 2 for eAAC+
+            sourceInputBufferSize = 2* KAedMaxAACFrameLengthPerChannel;
+            }
+            
+                 
+        }
+    
+    else if ( iProperties.iAudioType == EAudMP3 )
+        {
+        // mp3 can be directly decoded to mono if necessary
+        if (iToChannels == 1)
+            {
+            iFromChannels = 1;
+            }
+        
+        // check if decimation would be useful    
+        if (iFromSampleRate == iToSampleRate * 4)
+            {
+            iFromSampleRate /= 4;
+            iDecimFactor = 4;
+            }
+            
+        if (iFromSampleRate == iToSampleRate * 2)
+            {
+            iFromSampleRate /= 2;
+            iDecimFactor = 2;
+            }
+            
+        if ((iToSampleRate == 8000) && ((iFromSampleRate == 48000) || (iFromSampleRate == 44100)))
+            {
+            iFromSampleRate /= 2;
+            iDecimFactor = 2;
+            }        
+        
+        const TReal KMP3FrameDurationSec = 0.026;
+        
+        destInputBufferSize =  (iFromSampleRate * KMP3FrameDurationSec + 1);
+        destInputBufferSize *= 2; //16 bit samples
+        if (iFromChannels == 2)
+            {
+            destInputBufferSize *= 2; // stereo
+            }
+        
+        sourceInputBufferSize = KAedMaxMP3FrameLength;
+        }
+        
+    else if (iProperties.iAudioType == EAudWAV)
+        {
+        // frame duration in WAV case is always 20 ms, that is 50 frames per sec
+        const TInt KNumberOfFramesInSecond = 50;
+            
+        destInputBufferSize = iFromSampleRate / KNumberOfFramesInSecond;    // Number of samples
+        destInputBufferSize *= iFromChannels;
+        if ((destInputBufferSize % 2) != 0) destInputBufferSize++;          // Must be even
+        destInputBufferSize *= 2;                                           // 16-bit samples
+        
+        sourceInputBufferSize = iProperties.iFrameLen;
+        
+        TInt sourceBufferSizeAfterExpansion = sourceInputBufferSize;
+        if (iProperties.iNumberOfBitsPerSample == 8)
+            {
+            // 8-bit samples are expanded to 16-bit so twice as big buffer is needed
+            sourceBufferSizeAfterExpansion *= 2;
+            }
+        
+        if (sourceBufferSizeAfterExpansion > destInputBufferSize)
+            {
+            // Make sure there's no overflow
+            destInputBufferSize = sourceBufferSizeAfterExpansion;
+            }
+        }
+        
+    PRINT((_L("CProcDecoder::InitL() source size: %d, dest size %d"), sourceInputBufferSize, destInputBufferSize));
+    
+
+    if ( iSourceInputBuffer )
+        {
+        delete iSourceInputBuffer;
+        iSourceInputBuffer = NULL;
+        }
+    // create buffer for input data
+    iSourceInputBuffer = CMMFDataBuffer::NewL(sourceInputBufferSize);
+    
+    
+    if ( iDestInputBuffer )
+        {
+        delete iDestInputBuffer;
+        iDestInputBuffer = NULL;
+        }
+
+    
+    TInt errC = KErrNone;
+    if (iDoDecoding)
+        {
+        SetSourceCodecL();
+        
+        // create buffer for output data if necessary
+        iDestInputBuffer = CMMFDataBuffer::NewL( destInputBufferSize);
+        }
+    
+
+
+    TInt err = KErrNone;
+
+    if (iProperties.iAudioType == EAudAAC_MPEG4)
+        {
+        // configure AAC plus decoder, used also for AAC
+        TRAP( err, ConfigureAACPlusDecoderL());
+        
+        }
+    
+    else if ( iProperties.iAudioType == EAudMP3 )
+        {
+        // configure mp3 decoder
+        TRAP( err, ConfigureMP3DecoderL());
+        
+        }
+    if (err != KErrNone || errC != KErrNone)
+        {
+        User::Leave(KErrNotSupported);
+        }
+
+    if ( iDoSampleRateChannelConversion )
+        {
+        if (iRateConverter)
+            {
+            delete iRateConverter;
+            iRateConverter = NULL;
+            }
+
+        iRateConverter = CRateConverter::NewL(iFromSampleRate, iToSampleRate, iFromChannels, iToChannels);
+        
+        if( !iRateConverter->InitL(destInputBufferSize / (2 * iFromChannels)) ) // 16-bit samples
+            {
+            User::Leave(KErrNotSupported);
+            }
+            
+        TInt sampleRateBufferSize = iRateConverter->GetOutputBufferSize() * 2 * iToChannels;    // 16-bit samples
+        
+        PRINT((_L("CProcDecoder::InitL() sample rate buffer size %d"), sampleRateBufferSize));
+               
+        if ( iSampleRateChannelBuffer )
+            {
+            delete iSampleRateChannelBuffer;
+            iSampleRateChannelBuffer = NULL;
+            }
+
+        // Buffer for sample rate conversion output
+        iSampleRateChannelBuffer = CMMFDataBuffer::NewL(sampleRateBufferSize);
+        }
+
+
+    iReady = ETrue;
+    PRINT((_L("CProcDecoder::InitL() out")));
+
+    
+    return ETrue;
+    }
+
+TBool CProcDecoder::FillDecBufferL(const HBufC8* aEncFrame, HBufC8*& aDecBuffer)
+    {
+    PRINT((_L("CProcDecoder::FillDecBufferL() in")));
+    
+    iDecBuffer = 0;
+    if (iProperties.iAudioType == EAudWAV && !iDoSampleRateChannelConversion)
+        {
+        
+        // if we don't have to do anything for input data ->
+        aDecBuffer = HBufC8::NewL(aEncFrame->Size());
+        aDecBuffer->Des().Append(*aEncFrame);
+        PRINT((_L("CProcDecoder::FillDecBufferL() out from Wav branch with ETrue")));
+        return ETrue;
+
+        }
+        
+        
+    if (!iReady)
+        {
+        User::Leave(KErrNotReady);
+        }
+      
+    if ( aEncFrame == 0 || !aEncFrame->Length() )
+        {
+        // no data in input buffer
+        PRINT((_L("CProcDecoder::FillDecBufferL() no input data, out with EFalse")));
+        return EFalse;
+        }
+    
+    if ( (TInt)(aEncFrame->Length() + iSourceInputBuffer->Position() ) > iSourceInputBuffer->Data().MaxLength() )
+        {
+        
+        ReAllocBufferL( iSourceInputBuffer, aEncFrame->Length() + iSourceInputBuffer->Position() );
+        }
+    
+    iSourceInputBuffer->Data().SetLength( 0 );
+    iSourceInputBuffer->SetPosition( 0 );
+    
+    iSourceInputBuffer->Data().Append( *aEncFrame );
+    iSourceInputBuffer->Data().SetLength( aEncFrame->Length() );
+    
+    PRINT((_L("CProcDecoder::FillDecBufferL(), iSourceInputBuffer length = %d"),aEncFrame->Length()));
+    if (iDoDecoding)
+        {
+        iDestInputBuffer->Data().SetLength(0);
+        iDestInputBuffer->SetPosition(0); 
+        
+        }
+            
+    if ( iDoSampleRateChannelConversion )
+        {
+        iSampleRateChannelBuffer->Data().SetLength(0);
+        iSampleRateChannelBuffer->SetPosition(0);
+        }
+        
+    
+    FeedCodecL( iSourceCodec, iSourceInputBuffer, iDestInputBuffer);
+ 
+    if ( aDecBuffer )
+        {
+        // in case of EDstNotFilled from decoder, you may end up looping and to avoid memory leaks, you need to 
+        // delete the previous allocated buffer. Alternative might be to not allocate a new one in this case.
+        delete aDecBuffer;
+        aDecBuffer = NULL;
+        }
+    aDecBuffer = iDecBuffer;    
+            
+    if (iDoDecoding)
+        {
+        iDestInputBuffer->Data().SetLength(0);
+        iDestInputBuffer->SetPosition(0); 
+        
+        }
+    
+    if (iDecBuffer != 0 && iDecBuffer->Size() > 0)
+        {
+        PRINT((_L("CProcDecoder::FillDecBufferL() out with ETrue")));
+        return ETrue;
+          
+        }
+               
+    PRINT((_L("CProcDecoder::FillDecBufferL() out with EFalse")));
+    return EFalse;
+        
+    }
+
+
+void CProcDecoder::ConstructL()
+    {
+    
+    
+    
+    }
+
+CProcDecoder::CProcDecoder()
+    {
+    
+    }
+    
+    
+    
+void CProcDecoder::ConfigureAACPlusDecoderL()
+    {
+
+    
+    RArray<TInt> config;
+    
+    if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo)
+        {
+        
+        // for sample rate and channel converter, the output from parametric stereo
+        // is stereo, only the AAC part is incoded as mono
+        iFromChannels = 2;
+        }
+    
+    
+    config.Append( iFromSampleRate);
+    config.Append( iFromChannels );
+   
+    
+    if (iProperties.iAACObjectType ==  EAudAACObjectTypeLC)
+        {
+        config.Append( 1 );     // {1 - LC, 3 - LTP}    
+        }
+    else if (iProperties.iAACObjectType ==  EAudAACObjectTypeLTP)
+        {
+        config.Append( 3 );     // {1 - LC, 3 - LTP}    
+        }
+    else
+        {
+        User::Leave(KErrNotSupported);
+        }
+    
+    config.Append( 8192 );  //Size of PCM Samples generated by decoder
+    
+    config.Append( 1024 );  //Number of PCM Samples generated by decoder per frame
+    
+    config.Append( iFromSampleRate);        //Sampling freq of AAC Code decoder
+    
+    config.Append( 0 );     // not used ??
+    
+  
+    config.Append( 0 );     // down sampled mode
+    
+    config.Append( 16 );    // Sample resolution: 16-bit resolution
+    
+    
+        
+    // NOTE!: for some reason, the sample rate of the output from AACPlus decoder used
+    // to be a half of the proper output sampling rate. 
+    // eAAC+ data consists of AAC band + enhancement band. The enhancement band is not included
+    // in the rate indicated in the header (iFromSampleRate)
+    // There was a workaround for the 
+    // earlier problem not to increase the sampling rate.
+    // Now, with 2006 releases it seems to work, and the sampling rate need to be doubled
+    // for the sampling rate converter.
+    
+    if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlus)
+        {
+        iFromSampleRate *= 2; // for sample rate converter ->
+        config.Append(iFromSampleRate);// Output sampling frequency
+        config.Append( 5 ); //Type of extended object (5=SBR/HE AAC profile; 6=PS is present)
+        
+        }
+    else if (iProperties.iAudioTypeExtension == EAudExtensionTypeEnhancedAACPlusParametricStereo)
+        {
+        iFromSampleRate *= 2; // for sample rate converter ->
+        config.Append(iFromSampleRate);// Output sampling frequency
+        config.Append( 6 ); //Type of extended object (5=SBR/HE AAC profile; 6=PS is present)
+        }
+    else
+        {
+        // AAC, in&out samplerates are equal, and extended object type is 0
+        config.Append(iFromSampleRate);// Output sampling frequency
+        config.Append( 0 );
+        
+        }
+        
+
+    TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations
+    TRAPD( err, iSourceCodec->ConfigureL( uid, reinterpret_cast<TDesC8&>(config)));
+            
+    if ( err != KErrNone )
+        {
+        PRINT((_L("CProcDecoder::PrepareConverterL() error, Source codec config failed")));
+        config.Close();
+        User::Leave( err );
+        }
+    config.Close();
+    
+    }
+    
+    
+void CProcDecoder::ConfigureMP3DecoderL()
+    {
+
+    
+    RArray<TInt> config;
+    
+    TInt stereoToMono = 0;
+    if (iToChannels == 1 || iFromChannels == 1)
+        {
+        stereoToMono = 1;
+        }
+    
+    config.Append( stereoToMono); // stereo to mono
+    config.Append( 0 ); //iLeftRight??
+    config.Append( iDecimFactor ); //iDecimFactor
+    config.Append( 0 ); //iConcealment
+    config.Append( 0 ); //iSampleLength??
+    config.Append( 0 ); //iSamplingFrequency
+    
+    TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations
+    TRAPD( err, iSourceCodec->ConfigureL( uid, reinterpret_cast<TDesC8&>(config)));
+            
+    if ( err != KErrNone )
+        {
+        PRINT((_L("CProcDecoder::PrepareConverterL() error, Source codec config failed")));
+        config.Close();
+        User::Leave( err );
+        }
+    config.Close();
+    }
+    
+    
+void CProcDecoder::ReAllocBufferL( CMMFDataBuffer* aBuffer, TInt aNewMaxSize )
+    {
+    if ( aBuffer->Data().Length() )
+        {
+        TInt position = aBuffer->Position();
+        TInt length = aBuffer->Data().Length();
+        HBufC8* oldData = aBuffer->Data().AllocL();
+        CleanupStack::PushL( oldData );
+        ((CMMFDescriptorBuffer*)aBuffer)->ReAllocBufferL( aNewMaxSize );
+        aBuffer->Data().Copy( *oldData );
+        CleanupStack::PopAndDestroy( oldData );
+        aBuffer->Data().SetLength( length );
+        aBuffer->SetPosition( position );
+        }
+    else
+        {
+        ((CMMFDescriptorBuffer*)aBuffer)->ReAllocBufferL( aNewMaxSize );
+        }
+    }
+    
+void CProcDecoder::FeedCodecL( CMMFCodec* aCodec, CMMFDataBuffer* aSourceBuffer, CMMFDataBuffer* aDestBuffer )
+    {
+    PRINT((_L("CProcDecoder::FeedCodecL() in")));
+    TBool completed = EFalse;
+    TCodecProcessResult result;
+
+    while ( !completed )
+        {
+
+        if (iDoDecoding)
+            {
+            // decode and check the result
+            result = DecodeL(aCodec, aSourceBuffer, aDestBuffer);
+            }
+        else
+            {
+            
+            // no need for decoding, just perform sample rate and channel conversion
+            result.iStatus = TCodecProcessResult::EProcessComplete;
+            }
+       
+        
+        switch ( result.iStatus )
+            {
+            case TCodecProcessResult::EProcessIncomplete:
+                // Not all data from input was consumed (DecodeL updated buffer members), but output was generated
+                    
+                if ( iDoSampleRateChannelConversion )
+                    {
+                    if ( !iRateConverter )
+                        {
+                        PRINT((_L("CProcDecoder::FeedCodecL() error, no rate converter")));
+                        User::Leave( KErrNotFound );
+                        }
+                    
+                    // Convert buffer size in bytes    
+                    TUint convertBufferSize = aDestBuffer->Data().Length();
+                    
+                    // Number of samples in the buffer
+                    TUint inputSamples = convertBufferSize / (2 * iFromChannels);    // 16-bit samples
+                    
+                    PRINT((_L("CProcDecoder::FeedCodecL() converting %d samples"), inputSamples));
+                    
+                    if ( convertBufferSize > ( iDestInputBuffer->Data().MaxLength() - iDestInputBuffer->Position() ) )
+                        {
+                        ReAllocBufferL( iDestInputBuffer, convertBufferSize + iDestInputBuffer->Position() );
+                        }
+
+                    TInt outputSamples = iRateConverter->ConvertBufferL( (TInt16*) aDestBuffer->Data().Ptr(),
+                        (TInt16*) iSampleRateChannelBuffer->Data().Ptr(), inputSamples );
+                        
+                    iSampleRateChannelBuffer->Data().SetLength( outputSamples * 2 * iToChannels );
+
+                    UpdateOutputBufferL(iSampleRateChannelBuffer);
+                    
+                    }  
+                else
+                    {
+                    if (iDoDecoding)
+                        {
+
+                        UpdateOutputBufferL(aDestBuffer);
+                        }
+                    }
+                    
+                break;
+
+            case TCodecProcessResult::EProcessComplete:
+                // all data from input was used and output was generated
+                if ( iDoSampleRateChannelConversion )
+                    {
+                    if ( !iRateConverter )
+                        {
+                        PRINT((_L("CProcDecoder::FeedCodecL() error, no rate converter")));
+                        User::Leave( KErrNotFound );
+                        }
+                        
+                        
+                    CMMFDataBuffer* src = 0;
+                        
+                    if (!iDoDecoding)
+                        {
+                        
+                        // if decoding was not needed, 
+                        // the input data for SR converter is in aSourceBuffer
+                        src = aSourceBuffer;
+                        }
+                    else
+                        {
+                        // if decoding was needed, 
+                        // the input data for SR converter is in iDestBuffer
+                      
+                        src = iDestInputBuffer;
+                        }
+                        
+                    // Convert buffer size in bytes 
+                    TUint convertBufferSize = src->Data().Length();
+                    
+                    // Number of samples in the buffer
+                    TUint inputSamples = convertBufferSize / (2 * iFromChannels);    // 16-bit samples
+                    
+                    PRINT((_L("CProcDecoder::FeedCodecL() converting %d samples"), inputSamples));
+   
+                    if ( convertBufferSize > ( src->Data().MaxLength() - src->Position() ) )
+                        {
+                        ReAllocBufferL( src, convertBufferSize + src->Position() );
+                        }
+                        
+                    TInt outputSamples = iRateConverter->ConvertBufferL( (TInt16*) src->Data().Ptr(),
+                        (TInt16*) iSampleRateChannelBuffer->Data().Ptr(), inputSamples );
+                        
+                    iSampleRateChannelBuffer->Data().SetLength( outputSamples * 2 * iToChannels );
+
+                    UpdateOutputBufferL(iSampleRateChannelBuffer);
+ 
+                    }
+                else
+                    {
+                    if (iDoDecoding)
+                        {
+                        UpdateOutputBufferL(aDestBuffer);
+                        }
+                    
+                    }
+        
+                completed = ETrue;
+                break;
+
+            case TCodecProcessResult::EDstNotFilled:
+                // need more input data, can't fill the output yet; put it back to the empty queue
+                completed = ETrue;
+             
+                break;
+
+            default:
+                // EEndOfData, EProcessError, EProcessIncompleteRepositionRequest, EProcessCompleteRepositionRequest
+                User::Leave( KErrUnknown );
+            }
+
+        }
+    
+
+    PRINT((_L("CProcDecoder::FeedCodecL() out")));
+    }
+    
+TCodecProcessResult CProcDecoder::DecodeL( CMMFCodec* aCodec, CMMFDataBuffer* aInBuffer, CMMFDataBuffer* aOutBuffer)
+    {
+    PRINT((_L("CProcDecoder::DecodeL() in, input pos: %d, length: %d"), aInBuffer->Position(), aInBuffer->Data().Length() ));
+    TCodecProcessResult result;
+
+    result = aCodec->ProcessL (*aInBuffer, *aOutBuffer);
+
+    switch (result.iStatus)
+        {
+        case TCodecProcessResult::EProcessComplete:
+            // finished processing source data, all data in sink buffer
+            PRINT((_L("CProcDecoder::FeedCodecL() EProcessComplete")));
+            aInBuffer->SetPosition( 0 );
+            aInBuffer->Data().SetLength(0);
+            break;
+
+        case TCodecProcessResult::EDstNotFilled:
+            // the destination is not full, we need more data. Handled in caller
+            PRINT((_L("CProcDecoder::FeedCodecL() EDstNotFilled")));
+            aInBuffer->SetPosition( 0 );
+            aInBuffer->Data().SetLength(0);
+            break;
+
+        case TCodecProcessResult::EProcessIncomplete:
+            // the sink was filled before all the source was processed
+            PRINT((_L("CProcDecoder::FeedCodecL() EProcessIncomplete")));
+            aOutBuffer->SetPosition( 0 );
+            aInBuffer->SetPosition( aInBuffer->Position() + result.iSrcBytesProcessed );
+            break;
+
+        default:
+            break;
+        }
+
+    PRINT((_L("CProcDecoder::DecodeL() out, %d -> %d"),result.iSrcBytesProcessed, result.iDstBytesAdded));
+    PRINT((_L("CProcDecoder::DecodeL() out, input pos: %d, length: %d"), aInBuffer->Position(), aInBuffer->Data().Length() ));
+    return result;
+    }
+    
+TBool CProcDecoder::GetIsSupportedSourceCodec()
+    {
+ 
+     TFourCC fourCC;
+     TUid uID;
+ 
+    if (iProperties.iAudioType == EAudAMR)
+        {
+        fourCC = TFourCC(KMMFFourCCCodeAMR);
+        uID = TUid(KMmfAMRNBDecSWCodecUid);
+        }
+    else if (iProperties.iAudioType == EAudAAC_MPEG4)
+        {
+        // use eAAC+ also for AAC
+        fourCC = TFourCC(KMMFFourCCCodeAACPlus);
+        uID = TUid(KMmfUidCodecEnhAACPlusToPCM16);
+        }
+    else if (iProperties.iAudioType == EAudMP3)
+        {
+        fourCC = TFourCC(KMMFFourCCCodeMP3);
+        uID = TUid(KMmfAdvancedUidCodecMP3ToPCM16);
+        }
+    else if (iProperties.iAudioType == EAudAMRWB)
+        {
+        fourCC = TFourCC(KMMFFourCCCodeAWB);
+        uID = TUid(KMmfAMRWBDecSWCodecUid);
+        }
+    else
+        {
+        //Wav, no codec
+        return ETrue;
+        }
+    
+    
+    
+    _LIT8(emptyFourCCString, "    ,    ");
+    TBufC8<9> fourCCString(emptyFourCCString);
+    TPtr8 fourCCPtr = fourCCString.Des();
+    TPtr8 fourCCPtr1(&fourCCPtr[0], 4);
+    TPtr8 fourCCPtr2(&fourCCPtr[5], 4 );
+
+    TFourCC srcFourCC(' ','P','1','6');
+    fourCC.FourCC(&fourCCPtr1);
+    srcFourCC.FourCC(&fourCCPtr2);
+
+    TBool found = EFalse;
+    TRAPD( err, found = CheckIfCodecAvailableL( fourCCPtr , uID));
+    
+    if (err == KErrNone)
+        {
+        return found;    
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+
+void CProcDecoder::SetSourceCodecL()
+    {
+    PRINT((_L("CProcDecoder::SetSourceCodecL() in")));
+
+    if ( !GetIsSupportedSourceCodec() )
+        {
+        PRINT((_L("CProcDecoder::SetSourceCodecL() error, unsupported codec")));
+        User::Leave( KErrNotSupported );
+        }
+
+    if ( iSourceCodec )
+        {
+        delete iSourceCodec;
+        iSourceCodec = NULL;
+        }
+    
+    TFourCC destFourCC = KMMFFourCCCodePCM16;
+    
+    if (iProperties.iAudioType == EAudAMR)
+        {
+        iSourceCodec = CMMFCodec::NewL( KMmfAMRNBDecSWCodecUid );
+    
+        }
+    else if (iProperties.iAudioType == EAudAAC_MPEG4)
+        {
+        // use eAAC+ also for AAC
+        iSourceCodec = CMMFCodec::NewL( KMmfUidCodecEnhAACPlusToPCM16 );
+    
+        }
+    else if (iProperties.iAudioType == EAudMP3)
+        {
+        iSourceCodec = CMMFCodec::NewL( KMmfAdvancedUidCodecMP3ToPCM16 );
+    
+        }
+    else if (iProperties.iAudioType == EAudAMRWB)
+        {
+        iSourceCodec = CMMFCodec::NewL( KMmfAMRWBDecSWCodecUid );
+    
+        }
+    else
+        {
+        // Wav, but no codec needed then
+        }
+    
+    iReady = EFalse;
+
+    PRINT((_L("CProcDecoder::SetSourceCodecL() out")));
+    }
+    
+    
+    
+TBool CProcDecoder::CheckIfCodecAvailableL(const TDesC8& aCodecFourCCString, 
+                                            const TUid& aCodecUId )
+    {
+    PRINT((_L("CProcDecoder::CheckIfCodecAvailableL() in")));
+    TBool found = EFalse;
+
+    // Create a TEcomResolverParams structure.
+    TEComResolverParams resolverParams ;
+    resolverParams.SetDataType( aCodecFourCCString ) ;
+    resolverParams.SetWildcardMatch( EFalse ) ;
+
+    RImplInfoPtrArray plugInArray ; // Array to return matching decoders in (place on cleanupstack _after_ ListImplementationsL() )
+
+    TUid UidMmfPluginInterfaceCodec = {KMmfUidPluginInterfaceCodec};
+
+    // ListImplementationsL leaves if it cannot find anything so trap the error and ignore it.
+    TRAPD( err, REComSession::ListImplementationsL(UidMmfPluginInterfaceCodec, resolverParams, plugInArray ) ) ;
+    CleanupResetAndDestroyPushL(plugInArray);
+
+
+    if (err == KErrNone)
+        {
+        found = EFalse;
+        for ( TInt i = 0; i < plugInArray.Count(); i++)
+            {
+            // 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
+            PRINT((_L("CProcDecoder::CheckIfCodecAvailable() plugin found with Uid 0x%x"), plugInArray[i]->ImplementationUid().iUid ));
+            if ( plugInArray[i]->ImplementationUid() == aCodecUId )
+                {
+			    //match accepted
+                PRINT((_L("CProcDecoder::CheckIfCodecAvailable() plugin accepted")));
+			    found = ETrue;
+                }
+            }
+        }
+    else
+        {
+        PRINT((_L("CProcDecoder::CheckIfCodecAvailable() Error in ListImp.: %d"), err));
+        //no match
+        found = EFalse;
+        }
+
+    CleanupStack::PopAndDestroy();  //plugInArray
+    PRINT((_L("CProcDecoder::CheckIfCodecAvailableL() out")));
+    return found;
+    }
+    
+TBool CProcDecoder::UpdateOutputBufferL(CMMFDataBuffer* aInBuffer)
+    {
+    if (iDecBuffer == 0)
+        {
+        iDecBuffer = HBufC8::NewL(aInBuffer->BufferSize());
+        iDecBuffer->Des().Append(aInBuffer->Data());
+        }
+    else
+        {
+        iDecBuffer = iDecBuffer->ReAlloc(iDecBuffer->Size()+aInBuffer->BufferSize());
+        iDecBuffer->Des().Append(aInBuffer->Data());
+        }
+    
+    aInBuffer->Data().SetLength( 0 );
+    aInBuffer->SetPosition( 0 );    
+    
+    return ETrue;
+    }
+