diff -r 000000000000 -r 951a5db380a0 videoeditorengine/audioeditorengine/src/ProcDecoder.cpp --- /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 +#include +#include +#include + + +// CONSTANTS + + + + + +// MACROS + +// Debug print macro +#if defined _DEBUG +#include +#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 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(config))); + + if ( err != KErrNone ) + { + PRINT((_L("CProcDecoder::PrepareConverterL() error, Source codec config failed"))); + config.Close(); + User::Leave( err ); + } + config.Close(); + + } + + +void CProcDecoder::ConfigureMP3DecoderL() + { + + + RArray 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(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; + } +