--- /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;
+ }
+