diff -r 951a5db380a0 -r d87d32eab1a9 videoeditorengine/audioeditorengine/src/ProcEncoder.cpp --- a/videoeditorengine/audioeditorengine/src/ProcEncoder.cpp Fri Jan 29 14:08:33 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,702 +0,0 @@ -/* -* 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 "ProcEncoder.h" -#include "audconstants.h" -#include -#include -#include -#include -#include - - - -// MACROS - -// Debug print macro -#if defined _DEBUG -#include -#define PRINT(x) RDebug::Print x; -#else -#define PRINT(x) -#endif - -// ----------------------------------------------------------------------------- -// TCMRAMREncParams -// Encoding parameters structure for SW AMR codec -// ----------------------------------------------------------------------------- -// -class TVedACAMREncParams - { -public: - // encoding mode (for AMR-NB: 0=MR475,1=MR515,...,7=MR122, default 7) - TInt iMode; - // DTX flag (TRUE or default FALSE) - TInt iDTX; - }; - -CProcEncoder* CProcEncoder::NewL() - - { - CProcEncoder* self = NewLC(); - CleanupStack::Pop(self); - return self; - - } - - -CProcEncoder* CProcEncoder::NewLC() - - { - - CProcEncoder* self = new (ELeave) CProcEncoder(); - CleanupStack::PushL(self); - self->ConstructL(); - return self; - - } - -CProcEncoder::~CProcEncoder() - { - - - delete iSourceInputBuffer; - - delete iDestInputBuffer; - - delete iDestCodec; - - - } - - - - -TBool CProcEncoder::InitL(TAudType aAudioType, TInt aTargetSamplingRate, TChannelMode aChannelMode, - TInt aBitrate) - { - PRINT((_L("CProcEncoder::InitL() in"))); - - if (aAudioType == EAudAMR) - { - iOutputFrameDurationMilli = 20; - } - else if (aAudioType == EAudAAC_MPEG4) - { - iOutputFrameDurationMilli = (1024*1000)/(aTargetSamplingRate); - } - else - { - // only AMR & AAC encoding supported - PRINT((_L("CProcEncoder::InitL() out, unsupported audio type"))); - User::Leave(KErrNotSupported); - } - - iToBitRate = aBitrate; - - iAudioType = aAudioType; - - iNumberOfFramesInOutputBuffer = 0; - - iToSampleRate = aTargetSamplingRate; - - iToChannels = 1; - - if (aChannelMode == EAudStereo) - { - iToChannels = 2; - } - - - TInt destInputBufferSize = 0; - TInt sourceInputBufferSize = 0; - - // input buffer size: - // we never get longer than 64 milliseconds input - // as it is limited by the input formats - // for 16kHz AAC the frame duration is 64 ms - // - const TInt KMaxInputDurationMilli = 64; - - // multiplied by 2 as we have a bitdepth of 16 - sourceInputBufferSize = (2*aTargetSamplingRate*KMaxInputDurationMilli)/1000; - - if (aChannelMode == EAudStereo) - { - sourceInputBufferSize *= 2; - } - - if ( aAudioType == EAudAMR ) - { - - // from 64 ms input we can have maximum 4 AMR frames - destInputBufferSize = KAedMaxAMRFrameLength*4; - - - } - else if (aAudioType == EAudAAC_MPEG4) - { - - if ( aChannelMode == EAudSingleChannel ) - { - destInputBufferSize = KAedMaxAACFrameLengthPerChannel; - } - else - { - destInputBufferSize = 2 * KAedMaxAACFrameLengthPerChannel; - - } - } - - if ( iSourceInputBuffer ) - { - delete iSourceInputBuffer; - iSourceInputBuffer = NULL; - } - - iSourceInputBuffer = CMMFDataBuffer::NewL(sourceInputBufferSize*5); - - - if ( iDestInputBuffer ) - { - delete iDestInputBuffer; - iDestInputBuffer = NULL; - } - - TInt errC = KErrNone; - - if (aAudioType == EAudAMR) - { - - // shouldn't get more than 6 AMR frames at a time -> 120 ms - iDestInputBuffer = CMMFDataBuffer::NewL( destInputBufferSize); - - } - else - { - - iDestInputBuffer = CMMFDataBuffer::NewL( destInputBufferSize); - - } - - TRAP (errC,SetDestCodecL()); - - if (errC != KErrNone) - { - // initialization failed for some reason - User::Leave(KErrNotSupported); - - } - - TInt err = KErrNone; - - if ( iAudioType == EAudAAC_MPEG4 ) - { - TRAP( err, ConfigureAACEncoderL()); - - } - else if (iAudioType == EAudAMR) - { - TRAP( err, ConfigureAMREncoderL()); - } - - - if (err != KErrNone || errC != KErrNone) - { - - // initialization failed for some reason - User::Leave(KErrNotSupported); - } - - iReady = ETrue; - PRINT((_L("CProcEncoder::InitL() out"))); - - return ETrue; - } - -TBool CProcEncoder::FillEncBufferL(const TDesC8& aRawFrame, HBufC8* aEncBuffer, TInt& aOutputDurationMilli) - { - PRINT((_L("CProcEncoder::FillEncBufferL() in"))); - - aOutputDurationMilli = 0; - - - if (!iReady) - { - User::Leave(KErrNotReady); - } - - iEncBuffer = aEncBuffer; - - if (iEncBuffer->Length() == 0) - { - iNumberOfFramesInOutputBuffer = 0; - } - - if ( !aRawFrame.Length() ) - { - return EFalse; - } - - if ( (TInt)(aRawFrame.Length() + iSourceInputBuffer->Position() ) > iSourceInputBuffer->Data().MaxLength() ) - { - ReAllocBufferL( iSourceInputBuffer, aRawFrame.Length() + iSourceInputBuffer->Position() ); - - } - - - // copy the input data to MMF buffer - iSourceInputBuffer->Data().SetLength( 0 ); - iSourceInputBuffer->SetPosition( 0 ); - - iSourceInputBuffer->Data().Append( aRawFrame ); - iSourceInputBuffer->Data().SetLength( iSourceInputBuffer->Data().Length() ); - iSourceInputBuffer->SetStatus(EFull); - - iDestInputBuffer->Data().SetLength(0); - iDestInputBuffer->SetPosition(0); - - FeedCodecL( iDestCodec, iSourceInputBuffer, iDestInputBuffer); - - - - iDestInputBuffer->Data().SetLength(0); - iDestInputBuffer->SetPosition(0); - - if (iEncBuffer->Size() > 0) - { - - aOutputDurationMilli = iOutputFrameDurationMilli * iNumberOfFramesInOutputBuffer; - PRINT((_L("CProcEncoder::FillEncBufferL() out with ETrue (complete)"))); - return ETrue; - } - - PRINT((_L("CProcEncoder::FillEncBufferL() out with EFalse (incomplete)"))); - return EFalse; - } - -TAudType CProcEncoder::DestAudType() - { - return iAudioType; - } - -void CProcEncoder::ConstructL() - { - - } - -CProcEncoder::CProcEncoder() - { - - } - - -void CProcEncoder::ConfigureAMREncoderL() - { - PRINT((_L("CProcEncoder::ConfigureAMREncoderL() in"))); - - if ( (iToBitRate < KAedMinAMRBitRate) || (iToBitRate > KAedMaxAMRBitRate) ) - { - User::Leave( KErrArgument ); - } - - TVedACAMREncParams* configData = new (ELeave) TVedACAMREncParams; - CleanupStack::PushL( configData ); - - // the bitrates in the switch & if below are not magic numbers but AMR bitrates in bits per seconds and mode indices from TAmrEncParams - - switch ( iToBitRate ) - { - case 4750: - configData->iMode = 0; - configData->iDTX = EFalse; - break; - case 5150: - configData->iMode = 1; - configData->iDTX = EFalse; - break; - case 5900: - configData->iMode = 2; - configData->iDTX = EFalse; - break; - case 6700: - configData->iMode = 3; - configData->iDTX = EFalse; - break; - case 7400: - configData->iMode = 4; - configData->iDTX = EFalse; - break; - case 7950: - configData->iMode = 5; - configData->iDTX = EFalse; - break; - case 10200: - configData->iMode = 6; - configData->iDTX = EFalse; - break; - case 12200: - configData->iMode = 7; - configData->iDTX = EFalse; - break; - default : - // Interprets now the bitrate proprietarily: bitrates that are not exactly AMR bitrates - // mean that voice activity detection is used and the AMR bitrates is the given bitrate rounded upwards to the next AMR bitrate - if ( iToBitRate < 4750 ) - { - configData->iMode = 0; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 5150 ) - { - configData->iMode = 1; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 5900 ) - { - configData->iMode = 2; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 6700 ) - { - configData->iMode = 3; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 7400 ) - { - configData->iMode = 4; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 7950 ) - { - configData->iMode = 5; - configData->iDTX = ETrue; - } - else if ( iToBitRate < 10200 ) - { - configData->iMode = 6; - configData->iDTX = ETrue; - } - else // must be: ( iToBitRate < 12200 ) since checked earlier - { - configData->iMode = 7; - configData->iDTX = ETrue; - } - } - - TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations - iDestCodec->ConfigureL( uid, reinterpret_cast(*configData)); - CleanupStack::PopAndDestroy( configData ); - PRINT((_L("CProcEncoder::ConfigureAMREncoderL() out"))); - } - -// ----------------------------------------------------------------------------- -// CProcEncoder::ConfigureAACEncoderL -// -// (other items were commented in a header). -// ----------------------------------------------------------------------------- -// -void CProcEncoder::ConfigureAACEncoderL() - { - PRINT((_L("CProcEncoder::ConfigureAACEncoderL() in"))); - - TInt i = 0; - TBool iSet = EFalse; - for ( i = 0; i < KAedNumSupportedAACSampleRates; i++ ) - { - if ( iToSampleRate == KAedSupportedAACSampleRates[i] ) - { - iSet = ETrue; - } - } - if ( !iSet ) - { - // given samplerate is not supported - User::Leave( KErrNotSupported ); - } - - // AAC codec interprets the input as array of TInts, not as a class - RArray config; - config.Append (iToBitRate); //BitRate - config.Append (iToSampleRate); //SamplingRate - config.Append (0); //iToolFlags - config.Append (iToChannels); //iNumChan - - // NOTE Ali: for 48kHz stereo we might need to use ADTS as output format - // as we can get more than one frame in synchronous call! - config.Append (0); //iuseFormat 0=RAW; 1=ADTS; 2=ADIF - config.Append (0); // 0 = 1 Frame only; 1 = Full Buffer - - TUid uid ={KUidMmfCodecAudioSettings}; // Use Uid reserved for codec configurations - iDestCodec->ConfigureL( uid, reinterpret_cast(config)); - config.Close(); - PRINT((_L("CProcEncoder::ConfigureAACEncoderL() out"))); - } - - -void CProcEncoder::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 CProcEncoder::FeedCodecL( CMMFCodec* aCodec, CMMFDataBuffer* aSourceBuffer, CMMFDataBuffer* aDestBuffer ) - { - PRINT((_L("CProcEncoder::FeedCodecL() in"))); - TBool completed = EFalse; - TCodecProcessResult result; - TInt aSrcUsed = 0; - - while ( !completed ) - { - - // encode and check the result - result = EncodeL(aCodec, aSourceBuffer, aDestBuffer); - - switch ( result.iStatus ) - { - case TCodecProcessResult::EProcessIncomplete: - // Not all data from input was consumed (EncodeL updated buffer members), but output was generated - - iEncBuffer->Des().Append(aDestBuffer->Data()); - iNumberOfFramesInOutputBuffer++; - - aDestBuffer->Data().SetLength( 0 ); - aDestBuffer->SetPosition( 0 ); - - break; - - case TCodecProcessResult::EProcessComplete: - // all data from input was used and output was generated - - iEncBuffer->Des().Append(aDestBuffer->Data()); - - iNumberOfFramesInOutputBuffer++; - - aDestBuffer->Data().SetLength( 0 ); - aDestBuffer->SetPosition( 0 ); - - //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 ); - } - - aSrcUsed += result.iSrcBytesProcessed; - if (aSrcUsed >= (STATIC_CAST(CMMFDataBuffer*, aSourceBuffer)->Data().Length())) - { - PRINT((_L("CProcEncoder::FeedCodecL() ProcessL is completed aSrcUsed[%d]"), aSrcUsed)); - completed = ETrue; - } - - - } - - PRINT((_L("CProcEncoder::FeedCodecL() out"))); - } - - -TBool CProcEncoder::GetIsSupportedDestCodec() - { - TFourCC fourCC; - TUid euid; - - if (iAudioType == EAudAMR) - { - fourCC = TFourCC(KMMFFourCCCodeAMR); - euid = KAedAMRNBEncSWCodecUid; - } - else if (iAudioType == EAudAAC_MPEG4 ) - { - fourCC = TFourCC(KMMFFourCCCodeAAC); - euid = KAedAACEncSWCodecUid; - } - - _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'); - srcFourCC.FourCC(&fourCCPtr1); - fourCC.FourCC(&fourCCPtr2); - - TBool found = EFalse; - TRAPD( err, found = CheckIfCodecAvailableL( fourCCPtr, euid )); - - if (err == KErrNone) - { - return found; - } - else - { - return EFalse; - } - - } - - -void CProcEncoder::SetDestCodecL() - { - PRINT((_L("CProcEncoder::SetDestCodecL() in"))); - - if ( !GetIsSupportedDestCodec() ) - { - PRINT((_L("CProcEncoder::SetDestCodecL() error, unsupported codec"))); - User::Leave( KErrNotSupported ); - } - - if ( iDestCodec ) - { - delete iDestCodec; - iDestCodec = NULL; - } - - TUid euid = TUid::Null(); - - if (iAudioType == EAudAMR) - { - euid = KAedAMRNBEncSWCodecUid; - } - else if (iAudioType == EAudAAC_MPEG4 ) - { - euid = KAedAACEncSWCodecUid; - } - - - iDestCodec = CMMFCodec::NewL (euid); - iReady = EFalse; - - PRINT((_L("CProcEncoder::SetDestCodecL() out"))); - } - - -TBool CProcEncoder::CheckIfCodecAvailableL( - const TDesC8& aCodecFourCCString, const TUid& aCodecUId ) - { - PRINT((_L("CProcEncoder::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("CProcEncoder::CheckIfCodecAvailable() plugin found with Uid 0x%x"), plugInArray[i]->ImplementationUid().iUid )); - if ( plugInArray[i]->ImplementationUid() == aCodecUId ) - { - //match accepted - PRINT((_L("CProcEncoder::CheckIfCodecAvailable() plugin accepted"))); - found = ETrue; - } - } - } - else - { - PRINT((_L("CProcEncoder::CheckIfCodecAvailable() Error in ListImp.: %d"), err)); - //no match - found = EFalse; - } - - - CleanupStack::PopAndDestroy(); //plugInArray - PRINT((_L("CProcEncoder::CheckIfCodecAvailableL() out"))); - return found; - } - -TCodecProcessResult CProcEncoder::EncodeL( CMMFCodec* aCodec, CMMFDataBuffer* aInBuffer, CMMFDataBuffer* aOutBuffer) - { - PRINT((_L("CProcEncoder::EncodeL() 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("CProcEncoder::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("CProcEncoder::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("CProcEncoder::FeedCodecL() EProcessIncomplete"))); - aOutBuffer->SetPosition( 0 ); - aInBuffer->SetPosition( aInBuffer->Position() + result.iSrcBytesProcessed ); - break; - - default: - break; - } - - - - PRINT((_L("CProcEncoder::EncodeL() out, %d -> %d"),result.iSrcBytesProcessed, result.iDstBytesAdded)); - PRINT((_L("CProcEncoder::EncodeL() out, input pos: %d, length: %d"), aInBuffer->Position(), aInBuffer->Data().Length() )); - return result; - } -