# HG changeset patch # User Pat Downey # Date 1279900724 -3600 # Node ID bb31fbe7886136e6fe699b9b4de53b92d18df7e1 Initial commit of Aricent codec contribution. diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/group/ariaaclcencmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/group/ariaaclcencmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for AacLC Encoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* AacLC Encoder plugin binaries. +* +*/ + +#include +#include "..\inc\ariaaclcencmmfcodec_uid.hrh" + +TARGET ariaaclcencmmfcodec.dll +TARGETTYPE PLUGIN + +CAPABILITY ALL -TCB + +UID 0x10009D8D KUidAacLCEncMmfDllUid + +MACRO LOGLEVEL_CRITICAL + +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server +SYSTEMINCLUDE \epoc32\include\mmf\plugin + +USERINCLUDE ..\inc +USERINCLUDE ..\..\ariaaclcencwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +SOURCEPATH ..\src +SOURCE ariaaclcencmmfcodec.cpp + +SOURCEPATH ..\src +START RESOURCE 20029901.rss + TARGET ariaaclcencmmfcodec.rsc +END + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY ECOM.lib +LIBRARY ariaaclcencwrapper.lib + + + + + + + + + + diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for AacLC encoder plugin. This file specifies the +* mmp to be used to build the AacLC encoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +DEFAULT + +PRJ_MMPFILES +AriAacLCEncMmfCodec.mmp + diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/inc/ariaaclcencmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/inc/ariaaclcencmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for AacLC encoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + + +#ifndef ARIAACLCENCMMFCODEC_H +#define ARIAACLCENCMMFCODEC_H + +#include + +//Enum representing the output file format +enum TOutputFormat + { + EFormatRaw = 0, + EFormatADIF = 1, + EFormatADTS = 2 + }; + +//Class to hold encoder parameters +class TAacEncParam + { +public: + TUint iNumberOfChannels; + TUint iSamplingFrequency; + TUint iTurnOnPns; + TUint iTurnOnTns; + TUint iVersionInfo; + TOutputFormat iOutputFormat; + TUint iOutputBitRate; + }; + +//Forward Declaration +class CAriAacLCEncWrapper; + +//Class Declaration +class CAriAacLCEncMmfCodec:public CMMFCodec + { +public: //constructors and destructors + /** + * Two-phased constructor. + * @return pointer to an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriAacLCEncMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + virtual void ConfigureL( TUid aConfigType, const TDesC8& aParam ); + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any size, + * therefore there is no guarantee that all the source buffer can be + * processed to fill the destination buffer or that all the source buffer + * may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes processed + * along with a process result code indicating completion status.This + * function is synchronous, when the function returns the data has been + * processed. The source buffer is converted to the appropriate coding type + * in the destination buffer. The buffers can be of any size, therefore + * there is no guarantee that all the source buffer can be processed to + * fill the destination buffer or that all the source buffer may be + * processed before the destination is full. This function therefore + * returns the number of source, and destination, bytes processed along + * with a process result code indicating completion status.The aSource and + * aSink buffers passed in are derived from CMMFBuffer. The buffer type + * (e.g. a CMMFDataBuffer) passed in should be supported by the codec + * otherwise this function should leave with KErrNotSupported. The + * position of the source buffer should be checked by calling the source + * buffer's Position() member which indicates the current source read + * position in bytes. The codec should start processing from the current + * source buffer read position. The position of the destination buffer + * should be checked by calling the destination buffer's Position() method + * which indicates the current destination write position in bytes. + * The codec should start writing to the destination buffer at the current + * destination buffer write position.This is a virtual function that each + * derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + virtual TCodecProcessResult ProcessL( const CMMFBuffer& aSource, + CMMFBuffer& aDestination ); + +private: + + /** + * Default Constructor + */ + CAriAacLCEncMmfCodec(); + + /** + * Symbian 2nd phase constructor + */ + void ConstructL(); + + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed ); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed ); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); + +private: //Data + + // Handle TO wrapper class + CAriAacLCEncWrapper* iCodec; + + TBool iConfigured; + TBool iHeaderGenerated; + TAacEncParam iParam; + //No of bytes of source to be provided to encoder to encode one frame + TInt iSrclenToProcess; + + /** + * Setting this flag indicates whether only one frame has to encoded at a + * time or encode till destination buffer is full + */ + TBool iFillBuffer; + TInt iInternalInputBufferResidueLen; + TInt iInternalOutputBufferResidueLen; + TUint8* iInternalInputBuffer; + TUint8* iInternalOutputBuffer; + TInt iInternalOutputBufferPos; + + }; + +#endif /* ARIAACLCENCMMFCODEC_H */ diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/inc/ariaaclcencmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/inc/ariaaclcencmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll +* and Implementation Uids. +* +*/ + + +#ifndef ARIAACLCENCMMFCODEC_UID_HRH +#define ARIAACLCENCMMFCODEC_UID_HRH + +#define KUidAacLCEncMmfImplUid 0x200298FF +#define KUidAacLCEncMmfDllUid 0x20029901 + +#endif /* ARIAACLCENCMMFCODEC_UID_HRH */ diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/src/20029901.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/src/20029901.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for AacLC Encoder Plugin. +* +*/ + +#include "RegistryInfo.rh" +#include "mmfPluginInterfaceUIDs.hrh" +#include "ariaaclcencmmfcodec_uid.hrh" + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidAacLCEncMmfDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidAacLCEncMmfImplUid; + version_no = 1; + display_name = "Aac-LC Encoder plugin||copyright Aricent"; + //four CC codes + default_data = " P16, AAC"; + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencmmfcodec/src/ariaaclcencmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencmmfcodec/src/ariaaclcencmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,816 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class +* (CAriAacLCEncMmfCodec). +* +*/ + +#include +#include + +#include "ariaaclcencwrapper.h" +#include "ariaaclcencmmfcodec.h" +#include "ariaaclcencmmfcodec_uid.hrh" +#include "ariprint.h" + +const TUint KMinDstLen = 6144; +const TUint KMinBytesInput = 4096; + +const TUint KFlagSet = 1; +const TUint KFlagNotSet = 0; +const TUint KNoOfSamples = 1024; +const TUint KDefaultChannels = 1; +const TUint KDefaultOutputBitrate = 16000; +const TUint KDefaultSamplingFrequency = 8000; +const TUint KDefaultFormat = 0; + + +// -------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriAacLCEncMmfCodec. +// Instance is not left on cleanup stack. +// -------------------------------------------------------------------------- +// +CMMFCodec* CAriAacLCEncMmfCodec::NewL() + { + PRINT_ENTRY; + + CAriAacLCEncMmfCodec* self = new ( ELeave ) CAriAacLCEncMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + PRINT_EXIT; + return ( CMMFCodec* )self; + } + + +// -------------------------------------------------------------------------- +// Destructor;Destroys the encoder instance and any internal buffers +// -------------------------------------------------------------------------- +// +CAriAacLCEncMmfCodec::~CAriAacLCEncMmfCodec() + { + PRINT_ENTRY; + + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + iConfigured = EFalse; + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// From class CMMFCodec. +// The function sets codec configuration. +// value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +// +// -------------------------------------------------------------------------- +// +void CAriAacLCEncMmfCodec::ConfigureL( TUid /* aConfigType */, + const TDesC8& aParam ) + { + PRINT_ENTRY; + + if ( !iConfigured ) + { + TInt numberOfChannels = 0; + TInt samplingFrequency = 0; + TInt outputFormat = 0; + TInt outputBitRate = 0; + TInt flags = 0; + TInt fillBuffer = 0; + TInt offset = 0; + + Mem::Copy( &outputBitRate, aParam.Ptr() + offset, sizeof( TUint ) ); + offset += sizeof( TUint ); + + Mem::Copy( &samplingFrequency, aParam.Ptr() + offset, + sizeof( TUint ) ); + offset += sizeof( TUint ); + + Mem::Copy( &flags, aParam.Ptr() + offset, sizeof( TUint ) ); + offset += sizeof( TUint ); + + Mem::Copy( &numberOfChannels, aParam.Ptr() + offset, + sizeof( TUint ) ); + offset += sizeof( TUint ); + + Mem::Copy( &outputFormat, aParam.Ptr() + offset, sizeof( TUint ) ); + offset += sizeof( TUint ); + + Mem::Copy( &fillBuffer, aParam.Ptr() + offset, sizeof( TUint ) ); + offset += sizeof( TUint ); + + if ( ( flags != 0 && flags != 1 ) || + ( fillBuffer != 0 && fillBuffer != 1 ) ) + { + User::Leave( KErrArgument ); + } + + iParam.iNumberOfChannels = ( TUint )numberOfChannels; + iParam.iOutputBitRate = ( TUint )outputBitRate; + iParam.iOutputFormat = ( TOutputFormat )outputFormat; + iParam.iSamplingFrequency = ( TUint )samplingFrequency; + + PRINT_MSG( LEVEL_HIGH, + ( "NumberOfChannels: %d", iParam.iNumberOfChannels ) ); + PRINT_MSG( LEVEL_HIGH, + ( "OutputBitRate: %d", iParam.iOutputBitRate ) ); + PRINT_MSG( LEVEL_HIGH, + ( "OutputFormat: %d", iParam.iOutputFormat ) ); + PRINT_MSG( LEVEL_HIGH, + ( "SamplingFrequenc: %d", iParam.iSamplingFrequency ) ); + PRINT_MSG( LEVEL_HIGH, + ( "FillBuffer: %d", iFillBuffer ) ); + + User::LeaveIfError( iCodec->Reset( &iParam ) ); + + iSrclenToProcess = sizeof( TInt16 ) * KNoOfSamples * + iParam.iNumberOfChannels; + if ( fillBuffer == KFlagSet ) + { + iFillBuffer = ETrue; + } + else + { + iFillBuffer = EFalse; + } + iConfigured = ETrue; + + } + + PRINT_EXIT; + } + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to flush out status information when a +// reposition occurs. +// This is used if the codec requires resetting prior to use. +// --------------------------------------------------------------------------- +// +void CAriAacLCEncMmfCodec::ResetL() + { + PRINT_ENTRY; + User::LeaveIfError( iCodec->Reset( &iParam ) ); + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to encode the given source and fill the destination +// buffer with the encode data. +// The buffers can be of any size. Since the buffers can be of any size +// there is no guarantee that all the source buffer can be processed to fill +// the destination buffer or that the all the source buffer may be processed +// before the destination is full. Therefore the ProcessL needs to return a +// TCodecProcessResult returing the number of source bytes processed and the +// number of destination bytes processed along with a process result code +// defined thus: +// - EProcessComplete: the codec processed all the source data into the +// sink buffer +// - EProcessIncomplete: the codec filled sink buffer before all the source +// buffer +// was processed +// - EDstNotFilled: the codec processed the source buffer but the sink +// buffer was not filled +// - EEndOfData: the codec detected the end data - all source data is +// processed but sink may not be full +// - EProcessError: the codec process error condition +// +// The ProcessL should start processing the source buffer from the iPosition +// data member of the source data and start filling the destination buffer +// from its iPosition. +// ------------------------------------------------------------------------- +// +TCodecProcessResult CAriAacLCEncMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + + // total decoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + TInt internalInputBufferLen = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied; + + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + TUint8* srcPtr = const_cast ( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d",srcBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d",dstBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d", + iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d", + iInternalInputBufferResidueLen ) ); + + TInt srcBufferRemainingBytes = 0; + srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + TInt totRemainingSrc = srcBufferRemainingBytes + + iInternalInputBufferResidueLen; + if ( ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos == 0 ) + && ( totRemainingSrc < iSrclenToProcess ) && ( lastFrame ) ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 ) && + ( iInternalInputBufferResidueLen == 0 ) ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + TInt dstBufferRemainingBytes = 0; + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - totalDstBytesAdded; + if ( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + + + + //generate header for ADIF and Raw encoded formats + if ( !iHeaderGenerated ) + { + if ( ( iParam.iOutputFormat == EFormatADIF ) || + ( iParam.iOutputFormat == EFormatRaw ) ) + { + TInt retval = KErrNone; + TInt headerLen = KMinDstLen; + retval = iCodec->GetHeader( iInternalOutputBuffer,headerLen ); + + /** + * Fill Destination Buffer + */ + + iInternalOutputBufferResidueLen = headerLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + iHeaderGenerated = ETrue; + if ( ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos > 0 ) || + dstBufferRemainingBytes == 0 ) + { + totalSrcBytesCopied = 0; + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + iHeaderGenerated = ETrue; + } + } + + TInt newSrcCopied = 0; + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, it + * ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( iSrclenToProcess - iInternalInputBufferResidueLen > 0 ) && + ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + newSrcCopied = numberOfBytesCopied; + } + + if ( iSrclenToProcess > iInternalInputBufferResidueLen ) + { + if ( !lastFrame ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + else + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + + srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + + if ( lastFrame && ( ( iSrclenToProcess > iInternalInputBufferResidueLen ) + && ( iSrclenToProcess > srcBufferRemainingBytes ) ) + && ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos == 0 ) ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos == 0 ) + { + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + } + /** + * process the src buffer till destination buffer or source buffer or + * both buffers are exhausted. + */ + do + { + + srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - + totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + /** + * initialize the variables like srcUsed and dstLen accordingly. + * call Encode. + */ + TInt srcUsed = iSrclenToProcess; + TInt dstLen = KMinDstLen; + TInt16* tempIn = NULL; + tempIn = ( TInt16* ) ( ( iInternalInputBuffer + + internalInputBufferPos ) ); + TInt error = iCodec->Encode( tempIn, srcUsed, iInternalOutputBuffer, + dstLen ); + if ( error != KErrNone ) + { + iInternalInputBufferResidueLen = 0; + totalSrcBytesCopied = srcBufferLen; + PRINT_ERR( error ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos ); + } + + /** + * Fill Destination Buffer + */ + PRINT_MSG( LEVEL_HIGH, ( "dstLen: %d",dstLen ) ); + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * Fill Source Buffer if FillBuffer flag is true + */ + internalInputBufferPos += srcUsed ; + ShiftData( internalInputBufferPos, 0 ); + + if ( iFillBuffer ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, + totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + } + + /*** + * check four conditions if else for src and if else for dst + */ + // src has available bytes + TInt totSrcUsed = 0; + if ( ( iSrclenToProcess > srcBufferRemainingBytes ) && + ( iSrclenToProcess > iInternalInputBufferResidueLen ) && + ( lastFrame ) ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + if ( srcBufferRemainingBytes > 0 || iInternalInputBufferResidueLen >= + iSrclenToProcess ) + { + if ( dstBufferRemainingBytes > 0 ) + { + if ( !iFillBuffer ) + { + totSrcUsed = srcBufferPos + srcUsed; + totalSrcBytesCopied = newSrcCopied; + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + } + else + { + if ( dstBufferRemainingBytes > 0 ) + { + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen >= iSrclenToProcess ) + { + if ( !iFillBuffer ) + { + totSrcUsed = srcBufferPos + srcUsed; + totalSrcBytesCopied = newSrcCopied; + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + if ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if( lastFrame && (iInternalInputBufferResidueLen == 0 ) ) + + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + } + }while ( 1 ); + } + + +// -------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +// -------------------------------------------------------------------------- +// +CAriAacLCEncMmfCodec::CAriAacLCEncMmfCodec() + { + PRINT_ENTRY; + iCodec = NULL; + iConfigured = EFalse; + iHeaderGenerated = EFalse; + iSrclenToProcess = 0; + iFillBuffer = EFalse; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + iInternalInputBuffer = NULL; + iInternalOutputBuffer = NULL; + //default parameters + iParam.iNumberOfChannels = KDefaultChannels; + iParam.iOutputBitRate = KDefaultOutputBitrate; + iParam.iOutputFormat = EFormatRaw; + iParam.iSamplingFrequency = KDefaultSamplingFrequency; + iParam.iTurnOnPns = KFlagSet; + iParam.iTurnOnTns = KFlagSet; + iParam.iVersionInfo = KFlagNotSet; + PRINT_EXIT; +} + + +// -------------------------------------------------------------------------- +// Second phase of the two-phased constructor. +// Creates an instance of encoder +// -------------------------------------------------------------------------- +// +void CAriAacLCEncMmfCodec::ConstructL() + { + PRINT_ENTRY; + iCodec = CAriAacLCEncWrapper::NewL(); + + iInternalInputBuffer = ( TUint8* ) User::AllocZL( KMinBytesInput ); + iInternalOutputBuffer = ( TUint8* ) User::AllocZL( KMinDstLen ); + + PRINT_MSG( LEVEL_HIGH, ( "Default NumberOfChannels: %d", + iParam.iNumberOfChannels ) ); + PRINT_MSG( LEVEL_HIGH, ( "Default OutputBitRate: %d", + iParam.iOutputBitRate ) ); + PRINT_MSG( LEVEL_HIGH, ( "Default OutputFormat: %d", + iParam.iOutputFormat ) ); + + PRINT_MSG( LEVEL_HIGH, ( "Default SamplingFrequency: %d", + iParam.iSamplingFrequency ) ); + + //Reset encoder with default parameters + User::LeaveIfError( iCodec->Reset( &iParam ) ); + + iSrclenToProcess = sizeof( TInt16 ) * KNoOfSamples * + iParam.iNumberOfChannels; + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriAacLCEncMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + { + PRINT_ENTRY; + TCodecProcessResult result; + + result.iDstBytesAdded = aDstBytesAdded; + result.iSrcBytesProcessed = aSrcBytesConsumed; + + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriAacLCEncMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast( aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriAacLCEncMmfCodec::CopyFromSrcBuffer( const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + TInt internalInputBufferRemaingBytes = KMinBytesInput + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriAacLCEncMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = aFromPos; i < ( iInternalInputBufferResidueLen - + aFromPos ); i++ ) + { + iInternalInputBuffer[i] = + iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } + +// -------------------------------------------------------------------------- +// Exported proxy for instantiation method resolution +// Define the interface UIDs +// -------------------------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = +{ + IMPLEMENTATION_PROXY_ENTRY( KUidAacLCEncMmfImplUid, + CAriAacLCEncMmfCodec::NewL ) +}; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) +{ +PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + + PRINT_EXIT; + return ImplementationTable; +} diff -r 000000000000 -r bb31fbe78861 aaclc_enc/ariaaclcencwrapper/export_hdr/ariaaclcencwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aaclc_enc/ariaaclcencwrapper/export_hdr/ariaaclcencwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* AacLC encoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIAACLCENCWRAPPER_H +#define ARIAACLCENCWRAPPER_H + +#include + +// Class declaration +class CAriAacLCEncWrapper:public CBase + { + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriAacLCEncWrapper + */ + IMPORT_C static CAriAacLCEncWrapper* NewL(); + + /**> Destructor */ + ~CAriAacLCEncWrapper(); + + /** + * The function resets the encoder. + * @param aParam + * pointer to encoding parameter structure + * @return return status + */ + virtual TInt Reset( TAny* aParam ) = 0; + + /** + * The function creates the header for the AAC stream with the + * parameters specified. + * @param aDstBuf + * The destination buffer to hold the header information + * @param aDstLen + * Length of the header in bytes + * @return return status + */ + virtual TInt GetHeader( TUint8* aDstBuf, TInt &aDstLen ) = 0; + + /** + * The function encodes the input stream. + * @param aSrcBuf + * The source buffer containing data to encode. + * @param aSrcLen + * Size of source buffer in bytes + * @param aDstBuf + * The destination buffer to hold the data after encoding. + * @param aDstLen + * Size of destination buffer in bytes + * @return return status + */ + virtual TInt Encode( TInt16* aSrcBuf, TInt &aSrcLen, + TUint8* aDstBuf, TInt &aDstLen ) = 0; + + }; + + +#endif /* ARIAACLCENCWRAPPER_H */ diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/group/ariamrnbdecmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/group/ariamrnbdecmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for AmrNb Decoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* AmrNb Decoder plugin binaries. +* +*/ + +TARGET ariamrnbdecmmfcodec.dll +TARGETTYPE plugin +UID 0x10009D8D 0x200297D6 +MACRO LOGLEVEL_CRITICAL + +CAPABILITY ALL -TCB + +SOURCEPATH ..\src +SOURCE ariamrnbdecmmfcodec.cpp + +USERINCLUDE ..\inc +USERINCLUDE ..\..\ariamrnbdecwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server +SYSTEMINCLUDE \epoc32\include\mmf\plugin +SYSTEMINCLUDE \epoc32\include\platform + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY ECOM.lib +LIBRARY efsrv.lib +LIBRARY ariamrnbdecwrapper.lib // Wrapper Library + +START RESOURCE 200297D6.rss +TARGET ariamrnbdecmmfcodec.rsc +END +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- + diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for AmrNb decoder plugin. This file specifies the mmp +* to be used to build the AmrNb decoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +WINSCW ARMv5 ARM9E + +PRJ_MMPFILES +ariamrnbdecmmfcodec.mmp diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/inc/ariamrnbdecmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/inc/ariamrnbdecmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for AmrNb decoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + +#ifndef ARIAMRNBDECMMFCODEC_H +#define ARIAMRNBDECMMFCODEC_H + +// System includes +#include + +// Forward declaration +class CAriAmrNbDecWrapper; + +// Class declaration +class CAriAmrNbDecMmfCodec:public CMMFCodec + { +public: //constructors and destructors + /** + * Two-phased constructor. + * @return an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriAmrNbDecMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + virtual void ConfigureL( TUid aConfigType, const TDesC8& aParam ); + + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any + * size, therefore there is no guarantee that all the source buffer can + * be processed to fill the destination buffer or that all the source + * buffer may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status.This function is synchronous, when the function returns the + * data has been processed. The source buffer is converted to the + * appropriate coding type in the destination buffer. The buffers can be + * of any size, therefore there is no guarantee that all the source + * buffer can be processed to fill the destination buffer or that all + * the source buffer may be processed before the destination is full. + * This function therefore returns the number of source,and destination, + * bytes processed along with a process result code indicating completion + * status.The aSource and aSink buffers passed in are derived from + * CMMFBuffer. The buffer type (e.g. a CMMFDataBuffer) passed in should + * be supported by the codec otherwise this function should leave with + * KErrNotSupported. The position of the source buffer should be checked + * by calling the source buffer's Position() member which indicates the + * current source read position in bytes. The codec should start + * processing from the current source buffer read position. The position + * of the destination buffer should be checked by calling the destination + * buffer's Position() method which indicates the current destination + * write position in bytes. The codec should start writing to the + * destination buffer at the current destination buffer write position. + * This is a virtual function that each derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + virtual TCodecProcessResult ProcessL( const CMMFBuffer& aSource, + CMMFBuffer& aDestination ); + +private: + /** + * Default Constructor + */ + CAriAmrNbDecMmfCodec(); + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed ); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed ); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); + +private: + + // Amr Nb Decoder wrapper handle + CAriAmrNbDecWrapper* iCodec; + // Residue buffer length for input internal buffer + TInt iInternalInputBufferResidueLen; + // Residue buffer length for output internal buffer + TInt iInternalOutputBufferResidueLen; + // Input internal buffer + TUint8 *iInternalInputBuffer; + // Output internal buffer + TUint8 *iInternalOutputBuffer; + // internal input buffer position + TInt iInternalOutputBufferPos; + + }; + + +#endif /* ARIAMRNBDECMMFCODEC_H */ diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/inc/ariamrnbdecmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/inc/ariamrnbdecmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll and Implementation Uids. +* +*/ + +#ifndef ARIAMRDECMMFCODEC_UID_HRH +#define ARIAMRDECMMFCODEC_UID_HRH + +// Implementation UID +#define KUidAMRNBDecImplUid 0x200297D5 +// Dll UID +#define KUidAMRNBDecDllUid 0x200297D6 + +#endif /* ARIAMRDECMMFCODEC_UID_HRH */ diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/src/200297D6.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/src/200297D6.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for AmrNb Decoder Plugin. +* +*/ + +#include "RegistryInfo.rh" +#include "mmfplugininterfaceuids.hrh" +#include "ariamrnbdecmmfcodec_uid.hrh" + + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidAMRNBDecDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidAMRNBDecImplUid; + version_no = 1; + display_name = "AMR Decoder codec||copyright Aricent"; + default_data = " AMR, P16"; //four CC codes + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecmmfcodec/src/ariamrnbdecmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecmmfcodec/src/ariamrnbdecmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,604 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class (CAriAmrNbDecMmfCodec). +* +*/ + +// System includes +#include +#include +// User includes +#include "ariamrnbdecwrapper.h" +#include "ariamrnbdecmmfcodec.h" +#include "ariamrnbdecmmfcodec_uid.hrh" +#include "ariprint.h" + +// Maximum input and output buffer length +const TUint KAMRNBMinOutBufLength = 320; + + +//--------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriHeAacDecMmfCodec. +// Instance is not left on cleanup stack. +//--------------------------------------------------------------------------- +// +CMMFCodec* CAriAmrNbDecMmfCodec::NewL() + { + PRINT_ENTRY; + CAriAmrNbDecMmfCodec* self = new (ELeave) CAriAmrNbDecMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return ( CMMFCodec* )self; + } + +//--------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +//--------------------------------------------------------------------------- +// +CAriAmrNbDecMmfCodec::~CAriAmrNbDecMmfCodec() + { + PRINT_ENTRY; + + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// The function Sets codec configuration. +// The value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +//--------------------------------------------------------------------------- +// +void CAriAmrNbDecMmfCodec::ConfigureL( TUid /* aConfigType */, + const TDesC8& /*aParam*/ ) + { + PRINT_ENTRY; + + TInt configParam = 0; // Hardcoded to RTP + TDecParam lParam; + lParam.iMediatype = configParam; + + User::LeaveIfError( iCodec->Reset( lParam ) ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to flush out status information when a +// reposition occurs. +// This is used if the codec requires resetting prior to use. +//--------------------------------------------------------------------------- +// +void CAriAmrNbDecMmfCodec::ResetL() + { + PRINT_ENTRY; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to decode the given source and fill the destination +// buffer with the decode data. +// The buffers can be of any size. Since the buffers can be of any size there +// is no guarantee that all the source buffer can be processed to fill the +// destination buffer or that the all the source buffer may be processed +// before the destination is full. Therefore the ProcessL needs to return a +// TCodecProcessResult returing the number of source bytes processed and the +// number of destination bytes processed along with a process result code +// defined thus: +// - EProcessComplete: the codec processed all the source data into the sink +// buffer +// - EProcessIncomplete: the codec filled sink buffer before all the source +// buffer was processed +// - EDstNotFilled: the codec processed the source buffer but the sink buffer +// was not filled +// - EEndOfData: the codec detected the end data - all source data in +// processed but sink may not be full +// - EProcessError: the codec process error condition +// +// The ProcessL should start processing the source buffer from the iPosition +// data member of the source data and start filling the destination buffer +// from its iPosition. +//--------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrNbDecMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + // total decoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied; + // Flag for finding valid sync + TBool syncFound = EFalse; + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + + TUint8* srcPtr = const_cast ( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + if ( srcBufferLen == 0 && iInternalInputBufferResidueLen == 0 ) + { + PRINT_ERR( "source buffer length is zero" ); + User::Leave( KErrArgument ); + } + + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( ( lastFrame ) && ( srcBufferLen - srcBufferPos == 0 )&& + ( iInternalInputBufferResidueLen == 0 ) ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, it + * ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( KAMRNBMinOutBufLength - iInternalInputBufferResidueLen > 0 ) + && ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + } + + if ( ( KAMRNBMinOutBufLength > iInternalInputBufferResidueLen ) + && ( !lastFrame ) ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + + /** + * process the src buffer till destination buffer or source buffer + * or both buffers are exhausted. + */ + do + { + TInt srcBufferRemainingBytes = srcBufferLen + - srcBufferPos + - totalSrcBytesCopied; + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + + /** + * initialize the variables like srcUsed and dstLen accordingly. + * call Decode. + */ + + TInt srcUsed = iInternalInputBufferResidueLen + - internalInputBufferPos; + TInt dstLen = KAMRNBMinOutBufLength; + + TInt error = + iCodec->Decode( &iInternalInputBuffer[internalInputBufferPos], + srcUsed, ( TInt* )iInternalOutputBuffer, dstLen ); + + if ( KErrNone != error ) + { + iInternalInputBufferResidueLen = 0; + PRINT_ERR( "Amr Nb Decoder decodes fails" ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + /** + * Fill Destination Buffer + */ + + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * Fill Sorce Buffer + */ + + internalInputBufferPos += srcUsed ; + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + internalInputBufferPos = 0; + + /*** + * check four conditions if else for src and if else for dst + */ + + // src buffer has available bytes to decode + if ( srcBufferRemainingBytes > 0 ) + { + if ( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + + else + { + // dst buffer has availabe space for decoded bytes + if ( dstBufferRemainingBytes > 0 ) + { + // last frame of the input stream + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + /** + *internal output buffer has decoded bytes which is not + *given to dst buffer. + */ + if ( iInternalOutputBufferResidueLen + - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + // last frame of the input stream + else if ( lastFrame ) + { + // if internal buffer has available bytes to decode + if ( iInternalInputBufferResidueLen > 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + iInternalInputBufferResidueLen = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + }while ( 1 ); + } + +//--------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +//--------------------------------------------------------------------------- +// +CAriAmrNbDecMmfCodec::CAriAmrNbDecMmfCodec(): +iCodec( NULL ), iInternalInputBufferResidueLen( 0 ), +iInternalOutputBufferResidueLen( 0 ), iInternalInputBuffer( NULL ), +iInternalOutputBuffer( NULL ), iInternalOutputBufferPos( 0 ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +//--------------------------------------------------------------------------- +// +void CAriAmrNbDecMmfCodec::ConstructL() + { + PRINT_ENTRY; + + iCodec = CAriAmrNbDecWrapper::NewL(); + + if ( !iCodec ) + { + PRINT_ERR( "Amr Nb Decoder creation is failed" ); + User::Leave( KErrGeneral ); + } + + TInt configParam = 0; // Hardcoded to RTP + TDecParam lParam; + lParam.iMediatype = configParam; + User::LeaveIfError( iCodec->Reset( lParam ) ); + + iInternalInputBuffer = new( ELeave ) TUint8[KAMRNBMinOutBufLength]; + if ( !iInternalInputBuffer ) + { + PRINT_ERR( "internal input buffer creation is failed" ); + User::Leave( KErrNoMemory ); + } + + iInternalOutputBuffer = new( ELeave ) TUint8[KAMRNBMinOutBufLength]; + if ( !iInternalOutputBuffer ) + { + PRINT_ERR( "internal output buffer creation is failed" ); + User::Leave( KErrNoMemory ); + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrNbDecMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + + { + PRINT_ENTRY; + TCodecProcessResult result; + // update destination bytes + result.iDstBytesAdded = aDstBytesAdded; + // update source bytes + result.iSrcBytesProcessed = aSrcBytesConsumed; + + // update status + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriAmrNbDecMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast(aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + // destination buffer remaining bytes + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + // internal output buffer remaining bytes + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + // copy data to destination buffer from internal ouput buffer + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + // update internal output buffer position + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriAmrNbDecMmfCodec::CopyFromSrcBuffer( const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + // calculate the source buffer remaining bytes + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + // calculate internal input buffer remaining bytes + TInt internalInputBufferRemaingBytes = KAMRNBMinOutBufLength + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + // copy data from source buffer to internal input buffer + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + // update internal input buffer residue length + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriAmrNbDecMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = aToPos; i < ( iInternalInputBufferResidueLen - aFromPos ); + i++ ) + { + iInternalInputBuffer[i] = iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } + +// __________________________________________________________________________ +// ********************* ECOM Instantiation ********************* +// __________________________________________________________________________ + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( KUidAMRNBDecImplUid, + CAriAmrNbDecMmfCodec::NewL ) + }; + +EXPORT_C const TImplementationProxy* + ImplementationGroupProxy( TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } diff -r 000000000000 -r bb31fbe78861 amrnb_dec/ariamrnbdecwrapper/export_hdr/ariamrnbdecwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_dec/ariamrnbdecwrapper/export_hdr/ariamrnbdecwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* AmrNb Decoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIAMRNBDECWRAPPER_H +#define ARIAMRNBDECWRAPPER_H + +// system include files +#include +#include +#include +#include + +// Class declaration +class TDecParam + { +public: + //mediatype takes 0 for RTP and 1 for 3GPP + TInt iMediatype; + }; + +// Class declaration +class CAriAmrNbDecWrapper:public CBase + { +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriAmrNbDecWrapper + */ + IMPORT_C static CAriAmrNbDecWrapper* NewL(); + + /**> Destructor */ + ~CAriAmrNbDecWrapper(); + + /** + * The function resets the codec. + * @param aParam + * TDecParam in which it takes 0 for RTP and 1 for RTP + * @return return status + */ + virtual TInt Reset( TDecParam aParam ) = 0; + + /** + * The function decodes the input stream. + * @param aSrcBuf + * The source buffer containing data to decode. + * @param aSrcLen + * Size of source buffer in bytes + * @param aDstBuf + * The destination buffer to hold the data after decoding. + * @param aDstLen + * Size of destination buffer in bytes + * @return return status + */ + virtual TInt Decode( TUint8* aSrcBuf, TInt &aSrcLen, TInt* aDstBuf, + TInt &aDstLen ) = 0; + }; + + +#endif /* ARIAMRNBDECWRAPPER_H */ diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/group/ariamrnbencmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/group/ariamrnbencmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for AmrNb Encoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* AmrNb Encoder plugin binaries. +* +*/ + +#include +#include "..\inc\ariamrnbencmmfcodec_uid.hrh" + +TARGET ariamrnbencmmfcodec.dll +TARGETTYPE PLUGIN + +CAPABILITY ALL -TCB + +UID 0x10009D8D KUidAmrNbEncMmfDllUid + +MACRO LOGLEVEL_CRITICAL + +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server +SYSTEMINCLUDE \epoc32\include\mmf\plugin + +USERINCLUDE ..\inc +USERINCLUDE ..\..\ariamrnbencwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +SOURCEPATH ..\src +SOURCE ariamrnbencmmfcodec.cpp + +SOURCEPATH ..\src +START RESOURCE 200297D2.rss + TARGET ariamrnbencmmfcodec.rsc +END + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY ECOM.lib +LIBRARY ariamrnbencwrapper.lib \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for AmrNb encoder plugin. This file specifies the +* mmp to be used to build the AmrNb encoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +DEFAULT + +PRJ_MMPFILES +ariamrnbencmmfcodec.mmp + diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/inc/ariamrnbencmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/inc/ariamrnbencmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for AmrNb encoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + +#ifndef ARIAMRNBENCMMFCODEC_H +#define ARIAMRNBENCMMFCODEC_H + +#include + +//Class to hold encoding parameters +class TAmrNbEncParam + { +public: + //encoding mode to specify bitrate(takes values 0 to 7) + TInt16 iMode; + //discontinuous transmission flag(1-true/0-false) + TInt16 iDtx; + //type of file(0-RTP/1-3GPP);need not be set(By default-RTP) + TInt16 iFileFormat; + }; + +//Forward Declaration +class CAriAmrNbEncWrapper; + +// Class declaration +class CAriAmrNbEncMmfCodec:public CMMFCodec + { +public: //constructors and destructors + /** + * Two-phased constructor. + * @return pointer to an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriAmrNbEncMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + virtual void ConfigureL( TUid aConfigType, const TDesC8& aParam ); + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any size, + * therefore there is no guarantee that all the source buffer can be + * processed to fill the destination buffer or that all the source buffer + * may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status. This function is synchronous, when the function returns the + * data has been processed. The source buffer is converted to the + * appropriate coding type in the destination buffer. The buffers can be + * of any size, therefore there is no guarantee that all the source buffer + * can be processed to fill the destination buffer or that all the source + * buffer may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status. The aSource and aSink buffers passed in are derived from + * CMMFBuffer. The buffer type (e.g. a CMMFDataBuffer) passed in should be + * supported by the codec otherwise this function should leave with + * KErrNotSupported. The position of the source buffer should be checked + * by calling the source buffer's Position() member which indicates the + * current source read position in bytes. The codec should start + * processing from the current source buffer read position. The position + * of the destination buffer should be checked by + * calling the destination buffer's Position() method which indicates the + * current destination write position in bytes. The codec should start + * writing to the destination buffer at the current destination buffer + * write position. + * This is a virtual function that each derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + virtual TCodecProcessResult ProcessL( const CMMFBuffer& aSource, + CMMFBuffer& aDestination ); + +private: + + /** + * Default Constructor + */ + CAriAmrNbEncMmfCodec(); + + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed,TInt aDstBytesAdded ); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed ); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed ); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); + +private: //Data + + // Handle to wrapper class + CAriAmrNbEncWrapper* iCodec; + + TBool iConfigured; + TAmrNbEncParam iParam; + TInt iSrclenToProcess; + TInt iInternalInputBufferResidueLen; + TInt iInternalOutputBufferResidueLen; + TUint8* iInternalInputBuffer; + TUint8* iInternalOutputBuffer; + TInt iInternalOutputBufferPos; + + }; + +#endif /* ARIAMRNBENCMMFCODEC_H */ diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/inc/ariamrnbencmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/inc/ariamrnbencmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll +* and Implementation Uids. +* +*/ + +#ifndef ARIAMRNBENCMMFCODEC_UID_HRH +#define ARIAMRNBENCMMFCODEC_UID_HRH + +#define KUidAmrNbEncMmfImplUid 0x200297D1 +#define KUidAmrNbEncMmfDllUid 0x200297D2 + +#endif /* ARIAMRNBENCMMFCODEC_UID_HRH */ diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/src/200297D2.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/src/200297D2.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for AmrNb Encoder Plugin. +* +*/ + +#include "RegistryInfo.rh" +#include "mmfPluginInterfaceUIDs.hrh" +#include "ariamrnbencmmfcodec_uid.hrh" + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidAmrNbEncMmfDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidAmrNbEncMmfImplUid; + version_no = 1; + display_name = "AmrNb Encoder plugin||copyright Aricent"; + //four CC codes + default_data = " P16, AMR"; + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencmmfcodec/src/ariamrnbencmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencmmfcodec/src/ariamrnbencmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,622 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class +* (CAriAmrNbEncMmfCodec). +* +*/ + +#include +#include + +#include "ariamrnbencwrapper.h" +#include "ariamrnbencmmfcodec.h" +#include "ariamrnbencmmfcodec_uid.hrh" +#include "AriPrint.h" + +//Minimum bytes that contain 160 samples that has to be encoded at a time +const TUint KMinBytesInput = 320; +const TUint KMinDstLen = 32; + + +// -------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriAmrNbEncMmfCodec. +// Instance is not left on cleanup stack. +// -------------------------------------------------------------------------- +// +CMMFCodec* CAriAmrNbEncMmfCodec::NewL() + { + PRINT_ENTRY; + CAriAmrNbEncMmfCodec* self = new ( ELeave ) CAriAmrNbEncMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return ( CMMFCodec* )self; + } + +// -------------------------------------------------------------------------- +// Destructor;Destroys the encoder instance and any internal buffers +// -------------------------------------------------------------------------- +// +CAriAmrNbEncMmfCodec::~CAriAmrNbEncMmfCodec() + { + PRINT_ENTRY; + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + iConfigured = EFalse; + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// From class CMMFCodec. +// The function sets codec configuration. +// value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +// +// -------------------------------------------------------------------------- +// +void CAriAmrNbEncMmfCodec::ConfigureL( TUid /* aConfigType */, + const TDesC8& aParam ) + { + PRINT_ENTRY; + if ( !iConfigured ) + { + TInt encMode = 0; + TInt dtx = 0; + TInt offset = 0; + + Mem::Copy( &encMode, aParam.Ptr() + offset, sizeof( TInt ) ); + offset += sizeof(TInt); + + Mem::Copy( &dtx, aParam.Ptr() + offset, sizeof( TInt ) ); + offset += sizeof(TInt); + + iParam.iMode = ( TInt16 )encMode; + iParam.iDtx = ( TInt16 )dtx; + + PRINT_MSG( LEVEL_HIGH, ( "Mode: %d", iParam.iMode ) ); + PRINT_MSG( LEVEL_HIGH, ( "DTX: %d", iParam.iDtx ) ); + + User::LeaveIfError( iCodec->Reset( &iParam ) ); + + iConfigured = ETrue; + } + PRINT_EXIT; + } + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to flush out status information when a +// reposition occurs. +// This is used if the codec requires resetting prior to use. +// --------------------------------------------------------------------------- +// +void CAriAmrNbEncMmfCodec::ResetL() + { + PRINT_ENTRY; + User::LeaveIfError( iCodec->Reset( &iParam ) ); + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to encode the given source and fill the destination +// buffer with the encode data. +// The buffers can be of any size. Since the buffers can be of any size +// there is no guarantee that all the source buffer can be processed to fill +// the destination buffer or that the all the source buffer may be processed +// before the destination is full. Therefore the ProcessL needs to return a +// TCodecProcessResult returing the number of source bytes processed and the +// number of destination bytes processed along with a process result code +// defined thus: +// - EProcessComplete: the codec processed all the source data into the +// sink buffer +// - EProcessIncomplete: the codec filled sink buffer before all the source +// buffer +// was processed +// - EDstNotFilled: the codec processed the source buffer but the sink +// buffer was not filled +// - EEndOfData: the codec detected the end data - all source data is +// processed but sink may not be full +// - EProcessError: the codec process error condition +// +// The ProcessL should start processing the source buffer from the iPosition +// data member of the source data and start filling the destination buffer +// from its iPosition. +// ------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrNbEncMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + + // total encoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied = 0; + TInt dstBufferRemainingBytes = 0; + TInt srcBufferRemainingBytes = 0; + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + TUint8* srcPtr = const_cast ( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d", srcBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d", dstBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d", + iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d", + iInternalInputBufferResidueLen ) ); + + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 ) && + ( iInternalInputBufferResidueLen == 0 ) ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, it + * ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( iSrclenToProcess - iInternalInputBufferResidueLen > 0 ) && + ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + } + + if ( ( iSrclenToProcess > iInternalInputBufferResidueLen ) && + ( !lastFrame ) ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - totalDstBytesAdded; + + if ( lastFrame && ( ( iSrclenToProcess > iInternalInputBufferResidueLen ) + && ( iSrclenToProcess > srcBufferRemainingBytes ) ) + && ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos == 0 ) ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos == 0 ) + { + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + } + /** + * process the src buffer till destination buffer or source buffer or + * both buffers are exhausted. + */ + do + { + srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - + totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + /** + * initialize the variables like srcUsed and dstLen accordingly. + * call encode. + */ + TInt index; + TInt srcUsed = iSrclenToProcess; + TInt dstLen = KMinDstLen; + TInt* tempIn = NULL; + TInt len = KMinBytesInput / sizeof( TInt ); + tempIn = ( TInt* ) ( ( iInternalInputBuffer + + internalInputBufferPos ) ); + for ( index = 0; index < len; index++ ) + { + tempIn[index] &= 0xfff8fff8; + } + + TInt error = iCodec->Encode( tempIn, srcUsed, + iInternalOutputBuffer, dstLen ); + if ( error != 0 ) + { + iInternalInputBufferResidueLen = 0; + totalSrcBytesCopied = srcBufferLen; + PRINT_ERR( error ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos ); + } + + /** + * Fill Destination Buffer + */ + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * Fill Source Buffer + */ + internalInputBufferPos += srcUsed ; + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * check four conditions if else for src and if else for dst + */ + // src has available bytes + if ( srcBufferRemainingBytes > 0 || iInternalInputBufferResidueLen >= + iSrclenToProcess ) + { + if( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + // dst buffer has availabe space for encoded bytes + if ( dstBufferRemainingBytes > 0 ) + { + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen == 0 ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + if ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( lastFrame && + ( iInternalInputBufferResidueLen == 0 ) ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + } + }while ( 1 ); + } + + +// -------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +// -------------------------------------------------------------------------- +// +CAriAmrNbEncMmfCodec::CAriAmrNbEncMmfCodec() + { + PRINT_ENTRY; + iCodec = NULL; + iConfigured = EFalse; + iSrclenToProcess = KMinBytesInput; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + iInternalInputBuffer = NULL; + iInternalOutputBuffer = NULL; + //default Parameters + iParam.iMode = 0; + iParam.iDtx = 0; + iParam.iFileFormat = 0; + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// Second phase of the two-phased constructor. +// Creates an instance of encoder +// -------------------------------------------------------------------------- +// +void CAriAmrNbEncMmfCodec::ConstructL() + { + PRINT_ENTRY; + iCodec = CAriAmrNbEncWrapper::NewL(); + + iInternalInputBuffer = ( TUint8* ) User::AllocZL( KMinBytesInput ); + iInternalOutputBuffer = ( TUint8* ) User::AllocZL( KMinDstLen ); + + PRINT_MSG( LEVEL_HIGH, ( "Default mode: %d", iParam.iMode ) ); + PRINT_MSG( LEVEL_HIGH, ( "Default DTX: %d", iParam.iDtx ) ); + //Reset encoder with default parameters + User::LeaveIfError( iCodec->Reset( &iParam ) ); + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrNbEncMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + { + PRINT_ENTRY; + TCodecProcessResult result; + + result.iDstBytesAdded = aDstBytesAdded; + result.iSrcBytesProcessed = aSrcBytesConsumed; + + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriAmrNbEncMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast( aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriAmrNbEncMmfCodec::CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + TInt internalInputBufferRemaingBytes = KMinBytesInput + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriAmrNbEncMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = aFromPos; i < ( iInternalInputBufferResidueLen - + aFromPos ); i++ ) + { + iInternalInputBuffer[i] = + iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } + + +// -------------------------------------------------------------------------- +// Exported proxy for instantiation method resolution +// Define the interface UIDs +// -------------------------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( KUidAmrNbEncMmfImplUid, + CAriAmrNbEncMmfCodec::NewL ) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } diff -r 000000000000 -r bb31fbe78861 amrnb_enc/ariamrnbencwrapper/export_hdr/ariamrnbencwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrnb_enc/ariamrnbencwrapper/export_hdr/ariamrnbencwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* AmrNb Encoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIAMRNBENCWRAPPER_H +#define ARIAMRNBENCWRAPPER_H + +#include + +// Class declaration +class CAriAmrNbEncWrapper:public CBase + { +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriAmrNbEncWrapper + */ + IMPORT_C static CAriAmrNbEncWrapper* NewL(); + + /**> Destructor */ + virtual ~CAriAmrNbEncWrapper(); + + /** + * The function resets the encoder. + * @param aParam + * pointer to FrameInfo structure + * @return return status + */ + virtual TInt Reset( TAny* aParam ) = 0; + + /** + * The function encodes the input stream. + * @param aSrcBuf + * The source buffer containing data to encode. + * @param aSrcLen + * Size of source buffer in bytes + * @param aDstBuf + * The destination buffer to hold the data after encoding. + * @param aDstLen + * Size of destination buffer in bytes + * @return return status + */ + virtual TInt Encode( TInt* aSrcBuf, TInt &aSrcLen, TUint8* aDstBuf, + TInt &aDstLen ) = 0; + + }; + + +#endif /* ARIAMRNBENCWRAPPER_H */ diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/group/ariamrwbdecmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/group/ariamrwbdecmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for AmrWb Decoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* AmrWb Decoder plugin binaries. +* +*/ + + +#include + +TARGET ariamrwbdecmmfcodec.dll +TARGETTYPE plugin +UID 0x10009D8D 0x200298F7 + +CAPABILITY ALL -TCB +MACRO LOGLEVEL_LOW + + +SOURCEPATH ..\src +SOURCE ariamrwbdecmmfcodec.cpp + +USERINCLUDE ..\inc +USERINCLUDE ..\..\ariamrwbdecwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server +SYSTEMINCLUDE \epoc32\include\mmf\plugin + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY efsrv.lib +LIBRARY ECOM.lib +LIBRARY ariamrwbdecwrapper.lib // Wrapper Library + +START RESOURCE 200298F7.rss +TARGET ariamrwbdecmmfcodec.rsc +END + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- + diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for AmrWb decoder plugin. This file specifies the mmp +* to be used to build the AmrWb decoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +DEFAULT + +PRJ_MMPFILES +ariamrwbdecmmfcodec.mmp diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/inc/ariamrwbdecmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/inc/ariamrwbdecmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for AmrWb decoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + + +#ifndef ARIAMRWBDECMMFCODEC_H +#define ARIAMRWBDECMMFCODEC_H + +// User includes +#include +// Forward declaration +class CAriAmrWbDecWrapper; + +// Class declaration +class CAriAmrWbDecMmfCodec:public CMMFCodec +{ +public: //constructors and destructors + /** + * Two-phased constructor. + * @return an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriAmrWbDecMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + virtual void ConfigureL(TUid aConfigType, const TDesC8& aParam); + + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any + * size, therefore there is no guarantee that all the source buffer can + * be processed to fill the destination buffer or that all the source + * buffer may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status.This function is synchronous, when the function returns the + * data has been processed. The source buffer is converted to the + * appropriate coding type in the destination buffer. The buffers can be + * of any size, therefore there is no guarantee that all the source + * buffer can be processed to fill the destination buffer or that all + * the source buffer may be processed before the destination is full. + * This function therefore returns the number of source,and destination, + * bytes processed along with a process result code indicating completion + * status.The aSource and aSink buffers passed in are derived from + * CMMFBuffer. The buffer type (e.g. a CMMFDataBuffer) passed in should + * be supported by the codec otherwise this function should leave with + * KErrNotSupported. The position of the source buffer should be checked + * by calling the source buffer's Position() member which indicates the + * current source read position in bytes. The codec should start + * processing from the current source buffer read position. The position + * of the destination buffer should be checked by calling the destination + * buffer's Position() method which indicates the current destination + * write position in bytes. The codec should start writing to the + * destination buffer at the current destination buffer write position. + * This is a virtual function that each derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + + virtual TCodecProcessResult ProcessL(const CMMFBuffer& aSource, + CMMFBuffer& aDestination); + +private: + + /** + * Default Constructor + */ + CAriAmrWbDecMmfCodec(); + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed,TInt aDstBytesAdded); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); +private: + + // wrapper instance handle + CAriAmrWbDecWrapper* iCodec; + // internal input buffer + TUint8* iInternalInputBuffer; + // internal output buffer + TUint8* iInternalOutputBuffer; + // internal input residual length + TInt iInternalInputBufferResidueLen; + // internal output residual length + TInt iInternalOutputBufferResidueLen; + // internal output buffer position + TInt iInternalOutputBufferPos; + +}; + + +#endif /* ARIAMRWBDECMMFCODEC_H */ diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/inc/ariamrwbdecmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/inc/ariamrwbdecmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll and Implementation Uids. +* +*/ + + +#ifndef ARIAMRWBDECMMFCODECUID_H +#define ARIAMRWBDECMMFCODECUID_H + +// Implementation UID +#define KUidARIAMRWBDecImplUid 0x200298F6 +// Dll UID +#define KUidARIAMRWBDecDllUid 0x200298F7 + +#endif /* ARIAMRWBDECMMFCODECUID_H */ diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/src/200298F7.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/src/200298F7.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for AmrWb Decoder Plugin. +* +*/ + + +// system include files +#include "RegistryInfo.rh" +#include "mmfplugininterfaceuids.hrh" +// user include files +#include "ariamrwbdecmmfcodec_uid.hrh" + + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidARIAMRWBDecDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidARIAMRWBDecImplUid; + version_no = 1; + display_name = "AMR-WB Decoder codec||copyright Aricent"; + default_data = " AWB, P16"; //four CC codes + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecmmfcodec/src/ariamrwbdecmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecmmfcodec/src/ariamrwbdecmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,597 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class (CAriAmrWbDecMmfCodec). +* +*/ + + +// System includes +#include +#include +// User includes +#include "ariamrwbdecwrapper.h" +#include "ariamrwbdecmmfcodec.h" +#include "ariamrwbdecmmfcodec_uid.hrh" +#include "ariprint.h" + +// Maximum input and output buffer length +const TUint KAMRWBMINOutBufLength = 640; + + +//--------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriAmrWbDecMmfCodec. +// Instance is not left on cleanup stack. +//--------------------------------------------------------------------------- +// +CMMFCodec* CAriAmrWbDecMmfCodec::NewL() + { + PRINT_ENTRY; + CAriAmrWbDecMmfCodec* self = new ( ELeave ) CAriAmrWbDecMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return ( CMMFCodec* )self; + } + +//--------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +//--------------------------------------------------------------------------- +// +CAriAmrWbDecMmfCodec::~CAriAmrWbDecMmfCodec() + { + PRINT_ENTRY; + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// The function Sets codec configuration. +// The value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +//--------------------------------------------------------------------------- +// +void CAriAmrWbDecMmfCodec::ConfigureL( TUid /* aConfigType */, + const TDesC8& /*aParam*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to flush out status information when a +// reposition occurs. +// This is used if the codec requires resetting prior to use. +//--------------------------------------------------------------------------- +// +void CAriAmrWbDecMmfCodec::ResetL() + { + PRINT_ENTRY; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to decode the given source and fill the destination +// buffer with the decode data. +// The buffers can be of any size. Since the buffers can be of any size there +// is no guarantee that all the source buffer can be processed to fill the +// destination buffer or that the all the source buffer may be processed +// before the destination is full. Therefore the ProcessL needs to return a +// TCodecProcessResult returing the number of source bytes processed and the +// number of destination bytes processed along with a process result code +// defined thus: +// - EProcessComplete: the codec processed all the source data into the sink +// buffer +// - EProcessIncomplete: the codec filled sink buffer before all the source +// buffer was processed +// - EDstNotFilled: the codec processed the source buffer but the sink buffer +// was not filled +// - EEndOfData: the codec detected the end data - all source data in +// processed but sink may not be full +// - EProcessError: the codec process error condition +// +// The ProcessL should start processing the source buffer from the iPosition +// data member of the source data and start filling the destination buffer +// from its iPosition. +//--------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrWbDecMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + + // total decoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied; + // Flag for finding valid sync + TBool syncFound = EFalse; + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + + TUint8* srcPtr = const_cast ( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + if ( srcBufferLen == 0 && iInternalInputBufferResidueLen == 0 ) + { + PRINT_ERR( "source buffer length is zero" ); + User::Leave( KErrArgument ); + } + + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( ( lastFrame ) && ( srcBufferLen - srcBufferPos == 0 )&& + ( iInternalInputBufferResidueLen == 0 ) ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, it + * ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( KAMRWBMINOutBufLength - iInternalInputBufferResidueLen > 0 ) + && ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + } + + if ( ( KAMRWBMINOutBufLength > iInternalInputBufferResidueLen ) + && ( !lastFrame ) ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + + /** + * process the src buffer till destination buffer or source buffer + * or both buffers are exhausted. + */ + do + { + TInt srcBufferRemainingBytes = srcBufferLen + - srcBufferPos + - totalSrcBytesCopied; + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + + /** + * initialize the variables like srcUsed and dstLen accordingly. + * call Decode. + */ + + TInt32 srcUsed = iInternalInputBufferResidueLen + - internalInputBufferPos; + TInt32 dstLen = KAMRWBMINOutBufLength; + + TInt error = + iCodec->Decode( &iInternalInputBuffer[internalInputBufferPos], + srcUsed,( TInt32* )iInternalOutputBuffer, dstLen ); + + if ( KErrNone != error ) + { + iInternalInputBufferResidueLen = 0; + PRINT_ERR( "Amr Wb Decoder decoding is failed" ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + /** + * Fill Destination Buffer + */ + + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * Fill Sorce Buffer + */ + + internalInputBufferPos += srcUsed ; + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + internalInputBufferPos = 0; + + /*** + * check four conditions if else for src and if else for dst + */ + + // src buffer has available bytes to decode + if ( srcBufferRemainingBytes > 0 ) + { + if ( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + + else + { + // dst buffer has availabe space for decoded bytes + if ( dstBufferRemainingBytes > 0 ) + { + // last frame of the input stream + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + /** + *internal output buffer has decoded bytes which is not + *given to dst buffer. + */ + if ( iInternalOutputBufferResidueLen + - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + // last frame of the input stream + else if ( lastFrame ) + { + // if internal buffer has available bytes to decode + if ( iInternalInputBufferResidueLen > 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + iInternalInputBufferResidueLen = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + }while ( 1 ); + } + + + +//--------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +//--------------------------------------------------------------------------- +// +CAriAmrWbDecMmfCodec::CAriAmrWbDecMmfCodec(): +iCodec( NULL ), iInternalInputBuffer( NULL ), +iInternalOutputBuffer( NULL ), iInternalInputBufferResidueLen( 0 ), +iInternalOutputBufferResidueLen( 0 ), iInternalOutputBufferPos( 0 ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +//--------------------------------------------------------------------------- +// +void CAriAmrWbDecMmfCodec::ConstructL() + { + PRINT_ENTRY; + + iCodec = CAriAmrWbDecWrapper::NewL(); + + if ( !iCodec ) + { + PRINT_ERR( "Amr Nb Decoder creation is failed" ); + User::Leave( KErrGeneral ); + } + + User::LeaveIfError( iCodec->Reset() ) ; + + iInternalInputBuffer = new( ELeave ) TUint8[KAMRWBMINOutBufLength]; + if ( !iInternalInputBuffer ) + { + PRINT_ERR( "internal input buffer creation is failed" ); + User::Leave( KErrNoMemory ); + } + + iInternalOutputBuffer = new( ELeave ) TUint8[KAMRWBMINOutBufLength]; + if ( !iInternalOutputBuffer ) + { + PRINT_ERR( "internal output buffer creation is failed" ); + User::Leave( KErrNoMemory ); + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriAmrWbDecMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + + { + PRINT_ENTRY; + TCodecProcessResult result; + // update destination bytes + result.iDstBytesAdded = aDstBytesAdded; + // update source bytes + result.iSrcBytesProcessed = aSrcBytesConsumed; + + // update status + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriAmrWbDecMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast( aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + // destination buffer remaining bytes + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + // internal output buffer remaining bytes + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + // copy data to destination buffer from internal ouput buffer + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + // update internal output buffer position + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriAmrWbDecMmfCodec::CopyFromSrcBuffer( const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + // calculate the source buffer remaining bytes + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + // calculate internal input buffer remaining bytes + TInt internalInputBufferRemaingBytes = KAMRWBMINOutBufLength + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + // copy data from source buffer to internal input buffer + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + // update internal input buffer residue length + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriAmrWbDecMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = aToPos; i < ( iInternalInputBufferResidueLen - aFromPos ); + i++ ) + { + iInternalInputBuffer[i] = iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } + +// __________________________________________________________________________ +// ********************* ECOM Instantiation ********************* +// __________________________________________________________________________ + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KUidARIAMRWBDecImplUid, + CAriAmrWbDecMmfCodec::NewL) + }; + +EXPORT_C const TImplementationProxy* + ImplementationGroupProxy( TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable) / + sizeof(TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } diff -r 000000000000 -r bb31fbe78861 amrwb_dec/ariamrwbdecwrapper/export_hdr/ariamrwbdecwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrwb_dec/ariamrwbdecwrapper/export_hdr/ariamrwbdecwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* AmrWb Decoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIAMRWBDECWRAPPER_H +#define ARIAMRWBDECWRAPPER_H + +#include +#include +#include +#include + + +class CAriAmrWbDecWrapper:public CBase + { + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriAmrWbDecWrapper + */ + IMPORT_C static CAriAmrWbDecWrapper* NewL(); + /**> Destructor */ + ~CAriAmrWbDecWrapper(); + + /** + * The function resets the codec. + * @param + * @return return status + */ + virtual TInt Reset() = 0; + + /** + * The function decodes the input stream. + * @param aSrcBuf + * The source buffer containing data to decode. + * @param aSrcLen + * Size of source buffer in bytes + * @param aDstBuf + * The destination buffer to hold the data after decoding. + * @param aDstLen + * Size of destination buffer in bytes + * @return return status + */ + virtual TInt Decode(TUint8* aSrcBuf,TInt32 &aSrcLen,TInt32* aDstBuf, + TInt32 &aDstLen) = 0; + }; + + +#endif /* ARIAMRWBDECWRAPPER_H */ diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/group/arih264dechwdevice.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/group/arih264dechwdevice.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for H264 Video Decode HwDevice. +* +*/ + + +#include +#include "..\inc\arih264dechwdeviceuid.hrh" + +TARGET arih264dechwdevice.dll + +TARGETTYPE PLUGIN + +UID 0x10009D8D KUidH264DecoderHwDeviceDllUid + +CAPABILITY ALL -TCB + +SOURCEPATH ..\src +SOURCE arih264dechwdevice.cpp + +START RESOURCE 20029904.rss +#ifdef SYMBIAN_SECURE_ECOM +TARGET arih264dechwdevice.rsc +#endif +END + +MACRO LOGLEVEL_CRITICAL + +USERINCLUDE ..\inc +//wrapper includes +USERINCLUDE ..\..\arih264decwrapper\export_hdr +//utilities includes +USERINCLUDE ..\..\..\Utilities\Log +USERINCLUDE ..\..\..\Utilities\ariprocessengine\inc +USERINCLUDE ..\..\..\Utilities\aristatemachine\inc + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\libc +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\devvideo +SYSTEMINCLUDE \epoc32\include\oem + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib estlib.lib +LIBRARY efsrv.lib +LIBRARY aristatemachine.lib +LIBRARY devvideo.lib +LIBRARY arih264decwrapper.lib +LIBRARY ariprocessengine.lib + diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for Mpeg4/H263 Video Decode HwDevice. +* +*/ + +PRJ_PLATFORMS +winscw armv5 armv6 + + +PRJ_MMPFILES +arih264dechwdevice.mmp + +//----------------------------------------------------------------------------- +// End of BLD.INF +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/inc/arih264dechwdevice.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/inc/arih264dechwdevice.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,1177 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Interface of the arih264dechwdevice. +* +*/ + +#ifndef ARIH264DECHWDEVICE_H +#define ARIH264DECHWDEVICE_H + +//System includes +#include +#include +#include + +//User includes +#include "aribaseengine.h" +#include "arih264dechwdeviceuid.hrh" + +// CONSTANTS +const TInt KMaxAllowPicLoss = 75; +const TInt KMaxInputBufferSize = ( 248 * 2048 ); +const TInt KMaxOutputBuffers = 2; +const TInt KMaxInputBuffers = 2; +const TInt KMinInputBuffers = 2; +// Implementatin id for the hwdevice +const TUid KUidH264DecoderHwDevice = {KUidH264DecoderHwDeviceImplUid}; + +const TUint KMaxBitRate = 15*1024*1024; +const TInt KDecoderInfoCount = 14; + +//const TInt KMaxFrameWidth = 1280; +//const TInt KMaxFrameHeight = 720; +const TInt KPicRate = 30; + +// FORWARD DECLARTIONS +class CAriH264decWrapper; +class CStateMachine; +//CLASS DECLARATIONS + +/** + * This class is part of Aricent's H264 decoder HwDevice plugin used for + * decoding H264 content to yuv420. + * Provides implementation for standard MDF HwDevice plugin APIs as well as private functions + * used internal to this class for .This class also implements callback APIs from + * MMmfVideoBufferManagementObserver and MProcessEngineObserver which are called from CBaseEngine. + */ +class CAriH264decHwDevice: public CMMFVideoDecodeHwDevice, + public MProcessEngineObserver, + public MMmfVideoBufferManagementObserver +{ +public: //Constructors and destructor + + /** + * Two-phased constructor. + * @return pointer to an instance of CMMFVideoDecodeHwDevice + */ + static CMMFVideoDecodeHwDevice* NewL(); + + /** + * Function to destroy resources allocated by this object + */ + virtual ~CAriH264decHwDevice(); + +public: //CMMFVideoHwDevice Functions + + /** + * Retrieves a custom interface to the specified hardware device + + * @param aInteface Interface UID, defined with the custom interface + * @return Pointer to the interface implementation, or NULL if the + * device does not implement the interface requested. + * The return value must be cast to the correct type by the user. + */ + virtual TAny* CustomInterface( TUid aInterface ); + +public: //CMMFVideoDecodeHwDevice Functions + + /** + * Retrieves decoder information about this hardware device. + * The device creates a CVideoDecoderInfo structure, + * fills it with correct data, pushes it to cleanup stack and returns it. + * The client will delete the object when it is no longer needed + + * @return Decoder information as a CVideoDecoderInfo object. + * The object is pushed to the cleanup stack, and must be deallocated by + * the caller. + + * @leave The method will leave if an error occurs. + */ + virtual CVideoDecoderInfo* VideoDecoderInfoLC(); + + /** + * Reads header information from a coded data unit. + + * @param aDataUnitType The type of the coded data unit that is contained + * in aDataUnit. + * If the data is a simple piece of bitstream, use + * EDuArbitraryStreamSection. + * @param aEncapsulation The encapsulation type used for the coded data. + * If the data is a simple piece of bitstream, use + * EDuElementaryStream. + * @param aDataUnit The coded data unit, contained in a + * TVideoInputBuffer. + + * @return Header information for the data unit, or NULL if + * the coded data unit did not contain enough data + * to parse the header.The header data must be + * returned to device using ReturnHeader() before + * Initialize() is called or decoder is destroyed. + * The data remains valid until it is returned. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called before hwdevice + * has been initialized with Initialize() + */ + virtual TVideoPictureHeader* GetHeaderInformationL( + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TVideoInputBuffer* aDataUnit ); + + /** + * Returns a header from GetHeaderInformationL() back to the decoder so + * that the memory can be freed. + + * @param aHeader The header to return + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void ReturnHeader( TVideoPictureHeader* aHeader ); + + /** + * Sets the device input format to a compressed video format. + + * @param aFormat The input format to use + * @param aDataUnitType The encapsulation type used for the coded data + * @param aEncapsulation The encapsulation type used for the coded data + * @param aDataInOrder True if the input data is written in correct + * decoding order, false if will be written in + * arbitrary order. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called before hwdevice + * has been initialized with Initialize() + */ + virtual void SetInputFormatL( const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TBool aDataInOrder ); + + /** + * Sets whether decoding should be synchronzed to the current clock source, + * if any, or if pictures should instead be decoded as soon as possible. + * If decoding is synchronized, decoding timestamps are used if available, + * presentation timestamps are used if not. When decoding is not + * synchronized, pictures are decoded as soon as source data is available + * for them, and the decoder has a free output buffer. If a clock source is + * not available, decoding will not be synchronized. + + * @param aSynchronize True if decoding should be synchronized to a clock + * source. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SynchronizeDecoding( TBool aSynchronize ); + + /** + * Sets decoder buffering options + + * @param aOptions Buffering options + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual void SetBufferOptionsL( + const CMMFDevVideoPlay::TBufferOptions& aOptions ); + + /** + * Gets the video decoder buffer options actually in use. This can be used + * before calling SetBufferOptions() to determine the default options, or + * afterwards to check the values actually in use ( if some default values + * were used ). + + * @param aOptions Buffering options structure to fill. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual void GetBufferOptions( + CMMFDevVideoPlay::TBufferOptions& aOptions ); + + /** + * Indicates which HRD/VBV specification is fulfilled in the input stream + * and any related parameters. + + * @param aHrdVbvSpec The HRD/VBV specification fulfilled + * @param aHrdVbvParams HRD/VBV parameters. The data format depends on the + * parameters chosen. For 3GPP TS 26.234. parameters + * aHrdVbvSpec=EHrdVbv3GPP, data in the descriptor + * is a package of type TPckC + * If no HRD/VBV parameters are used, the descriptor + * is empty. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SetHrdVbvSpec( THrdVbvSpecification aHrdVbvSpec, + const TDesC8& aHrdVbvParams ); + + /** + * Sets the output post-procesor device to use. If an output device is set, + * all decoded pictures are delivered to that device, and not drawn on + * screen or returned to the client. Pictures are written using + * CMMDVideoPostProcDevice::WritePictureL() or a custom interface after + * they have been decoded. The post-processor must then synchronize + * rendering to the clock source if necessary. + * + * @param aDevice The output post-processor device to use. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SetOutputDevice( CMMFVideoPostProcHwDevice* aDevice ); + + /** + * Returns the current decoding position, i.e. the timestamp for the most + * recently decoded picture. + + * @return Current decoding position. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual TTimeIntervalMicroSeconds DecodingPosition(); + + /** + * Returns the current pre-decoder buffer size + + * @return The number of bytes of data in the pre-decoder buffer. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint PreDecoderBufferBytes(); + + /** + * Reads various counters related to the received input bitstream and coded + * data units. + + * @param aCounters The counter structure to fill. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetBitstreamCounters( + CMMFDevVideoPlay::TBitstreamCounters& aCounters ); + + /** + * Retrieves the number of free input buffers the decoder has available + + * @return Number of free input buffers the decoder has available. + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint NumFreeBuffers(); + + /** + * Retrieves an empty video input buffer from the decoder. After input data + * has been written to the buffer, it can be written to the decoder using + * WriteCodedDataL(). The number of buffers the decoder must be able + * to provide before expecting any back, and the maximum size for each + * buffer, are specified in the buffer options.The decoder maintains + * ownership of the buffers even while they have been retrieved by client, + * and will take care of deallocating them. + + * @param aBufferSize Required buffer size, in bytes. The resulting + * buffer can be larger than this, but not smaller + + * @return A new input data buffer. The buffer is at least + * as large as requested, but it may be larger. + * If no free buffers are available, the return value + * is NULL. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual TVideoInputBuffer* GetBufferL( TUint aBufferSize ); + + /** + * Writes a piece of coded video data to the decoder. The data buffer must + * be retrieved from the decoder with GetBufferL(). + + * @param aBuffer The coded data unit to write. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void WriteCodedDataL( TVideoInputBuffer* aBuffer ); + +#ifdef SYMBIAN_MDF_API_V2 + /** + * Configures the Decoder using header information known by the client. + * @param aVideoPictureHeader Header information to configure the + * decoder with + * @leave The method will leave if an error occurs. Running out of data + * is not considered an error, + * as described above. + * @pre This method can only be called before the hwdevice has been + * initialized with Initialize(). + */ + virtual void ConfigureDecoderL( + const TVideoPictureHeader& aVideoPictureHeader ); + +#endif + +public: //Inherited from CMMFVideoPlayHwDevice + + /** + * Retrieves post-processing information about this hardware device. The + * device creates a CPostProcessorInfo structure ( defined in [3] ), fills + * it with correct data, pushes it to the cleanup stack and returns it. The + * client will delete the object when it is no longer needed. + + * @return Post-processor information as a CPostProcessorInfo object. + * The object is pushed to the cleanup stack, and must be + * deallocated by the caller. + + * @leave This method may leave with one of the standard error codes + */ + virtual CPostProcessorInfo* PostProcessorInfoLC(); + + /** + * Retrieves the list of the output formats that the device supports. The + * list is ordered in plug-in preference order, with the preferred formats + * at the beginning of the list. The list can depend on the device source + * format, and therefore SetSourceFormatL() must be called before calling + * this method. + + * @param aFormats An array for the result format list. The array + * must be created and destroyed by the caller. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetOutputFormatListL( + RArray& aFormats ); + + /** + * Sets the device output format. + + * @param aDataUnit The format to use. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetOutputFormatL( const TUncompressedVideoFormat &aFormat ); + + /** + * Sets the clock source to use for video timing. See [3] for a discussion + * about audio/video synchronization. If no clock source is set. video + * playback will not be synchronized, but will proceed as fast as possible, + * depending on input data and output buffer availability. + + * @param aDataUnitType The clock source to use. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetClockSource( MMMFClockSource* aClock ); + + /** + * Sets the device video output destination. The destination can be the + * screen ( using direct screen access ) or memory buffers. By default + * memory buffers are used. If data is written to another device, this + * method is ignored, and suitable memory buffers are always used. + + * @param aScreen True if video output destination is the screen, false + * if memory buffers. + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void SetVideoDestScreenL( TBool aScreen ); + + /** + * Sets the post-processing types to be used. + + * @param aPostProcCombination The post-processing steps to perform, a + * bitwise or of values from TPostProcessType + * @leave This method may leave with one of the + * standard error codes. + + * @pre This method can be called either before + * or after the hwdevice has been initialized + * with Initialize(). If called after + * with initialization, the change will only + * with be committed once CommitL() is called + */ + virtual void SetPostProcessTypesL( TUint32 aPostProcCombination ); + + /** + * Sets post-processing options for input ( pan-scan ) cropping. + + * @param aRect The type of the coded data unit that is contained in + * aDataUnit. + + * @leave This method may leave with one of the standard error codes + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If called + * after initialization, the change will only be committed + * once CommitL() is called. + */ + virtual void SetInputCropOptionsL( const TRect& aRect ); + + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aOptions The conversion options to use + * @param aYuvFormat Conversion source YUV format, if specified. + * @param aRgbFormat Conversion target RGB format, if specified.. + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If + * called after initialization, the change will only be + * committed once CommitL() is called. + */ + virtual void SetYuvToRgbOptionsL( const TYuvToRgbOptions& aOptions, + const TYuvFormat& aYuvFormat, + TRgbFormat aRgbFormat ); + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aOptions The conversion options to use + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized + * with Initialize(). If called after initialization, + * the change will only be committed once CommitL() is + * called + */ + virtual void SetYuvToRgbOptionsL( const TYuvToRgbOptions& aOptions ); + + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aRotationType The rotation to perform. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can be called either before or after + * the hwdevice has been initialized with Initialize(). + * If called after initialization, the change will only + * be committed once CommitL() is called. + */ + virtual void SetRotateOptionsL( TRotationType aRotationType ); + + /** + * @param aRotationType The rotation to perform. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can be called either before or after + * the hwdevice has been initialized with Initialize(). + * If called after initialization, the change will + * only be committed once CommitL() is called. + */ + virtual void SetScaleOptionsL( const TSize& aTargetSize, + TBool aAntiAliasFiltering ); + + /** + * Sets post-processing options for output cropping. SetPostProcessTypesL() + * must be called before this method is used. + + * @param aRect Output cropping area + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If called + * after initialization, the change will only be committed + * once CommitL() is called. + */ + virtual void SetOutputCropOptionsL( const TRect& aRect ); + + /** + * Sets post-processing plug-in specific options. SetPostProcessTypesL() + * must be called before this method is used. + + * @param aOptions The format is plug-in specific + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If + * called after initialization, the change will only be + * committed once CommitL() is called. + */ + virtual void SetPostProcSpecificOptionsL( const TDesC8& aOptions ); + + /** + * Initializes the device. This method is asynchronous, the device will + * call MMFVideoPlayProxy::MdvppInitializeComplete() after initialization + * has completed. After this method has successfully completed, further + * configuration changes are not possible except where separately noted + + * @leave This method may leave with one of the standard error codes. + */ + virtual void Initialize(); + + /** + * Commit all configuration changes since the last CommitL(), Revert() or + * Initialize(). This only applies to methods that can be called both + * before AND after the hwdevice has been initialized. + + @leave This method may leave with one of the standard error codes. + */ + virtual void CommitL(); + + /** + * Revert any configuration changes that have not yet been committed using + * CommitL(). This only applies to methods that can be called both before + * AND after the hwdevice has been initialized. + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Revert(); + + /** + * Starts writing output directly to the display frame buffer using Direct + * Screen Access. + + * @param aVideoRect The video output rectangle on screen. + * @param aScreenDevice The screen device to use. The screen device object + * must be valid in the current thread. + * @param aClipRegion Initial clipping region to use. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void StartDirectScreenAccessL( const TRect& aVideoRect, + CFbsScreenDevice& aScreenDevice, + const TRegion& aClipRegion ); + + /** + * Sets a new clipping region for Direct Screen Access. After the method + * returns, no video will be drawn outside of the region. If clipping is + * not supported, or the clipping region is too complex, either playback + * will pause or will resume without video display, depending on the + * current setting of SetPauseOnClipFail(), and the result can be verified + * with IsPlaying(). Clipping can be disabled by setting a new clipping + * region that includes the whole video window. + + * @param aRegion The new clipping region. After the method returns, + * no video will be drawn outside the region. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetScreenClipRegion( const TRegion& aRegion ); + + + /** + * Sets whether the system should pause playback when it gets a clipping + * region it cannot handle, or Direct Screen Access is aborted completely. + * If not, processing will proceed normally, but no video will be drawn. + * By default, playback is paused. + + * @param aPause True if playback should be paused when clipping fails, + * false if not. + * If playback is not paused, it will be continued + * If without video display + * + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void SetPauseOnClipFail( TBool aPause ); + + /** + * Aborts Direct Screen Access completely, to be called from + * MAbortDirectScreenAccess::AbortNow() and similar methods. DSA can be + * resumed by calling StartDirectScreenAccessL(). + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void AbortDirectScreenAccess(); + + /** + * Indicates Whether playback is proceeding + * @return ETrue if video is still being played ( even if not + * necessarily displayed ) + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TBool IsPlaying(); + + /** + * Re-draws the latest video picture.Only available when DSA is being used. + * If DSA is aborted or a non-supported clipping region has been set, the + * request may be ignored. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Redraw(); + + /** + * Starts video playback, including decoding, post-processing, and + * rendering. Playback will proceed until it has been stopped or paused, or + * the end of the bitstream is reached. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Start(); + + /** + * Stops video playback. No new pictures will be decoded, post-processed, + * or rendered. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Stop(); + + /** + * Pauses video playback, including decoding, post-processing, and + * rendering. No pictures will be decoded, post-processed, or rendered + * until playback has been resumed. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Pause(); + + /** + * Resumes video playback after a pause. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Resume(); + + /** + * Changes to a new decoding and playback position, used for randomly + * accessing ( seeking ) the input stream. The position change flushes all + * input and output buffers, pre-decoder and post-decoder buffering are + * handled as if a new bitstream was. If the device still has buffered + * pictures that precede the new playback position, they will be discarded. + * If playback is synchronized to a clock source, the client is responsible + * for setting the clock source to the new position. + + * @param aPlaybackPositio The new playback position in the video stream. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetPosition( + const TTimeIntervalMicroSeconds& aPlaybackPosition ); + + /** + * Freezes a picture on the screen. After the picture has been frozen, no + * new pictures are displayed until the freeze is released with + * ReleaseFreeze(). If the device output is being written to memory buffers + * or to another plug-in, instead of the screen, no decoded pictures will + * be delivered while the freeze is active, and they are simply discarded. + + * @param aTimestamp The presentation timestamp of the picture to + * freeze. The frozen picture will be the first + * picture with a timestamp greater than or equal to + * this parameter + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void FreezePicture( const TTimeIntervalMicroSeconds& aTimestamp ); + + /** + * Releases a picture frozen with FreezePicture() + + * @param aTimestamp The presentation timestamp of the picture to + * release. The first picture displayed after the + * release will be the first picture with a timestamp + * greater than or equal to this parameter. To + * greater release the freeze immediately, set the + * greater timestamp to zero. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void ReleaseFreeze( const TTimeIntervalMicroSeconds& aTimestamp ); + + /** + * Returns the current playback position, i.e. the timestamp for the most + * recently displayed or virtually displayed picture. If the device output + * is written to another device, the most recent output picture is used. + + * @return Current playback position + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TTimeIntervalMicroSeconds PlaybackPosition(); + + /** + * Returns the total amount of memory allocated for uncompressed pictures. + * This figure only includes the pictures actually allocated by the plug-in + * itself, so that the total number of bytes allocated in the system can be + * calculated by taking the sum of the values from all plug-ins. + + * @return Total number of bytes of memory allocated for uncompressed + * pictures. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint PictureBufferBytes(); + + /** + * Reads various counters related to decoded pictures. See the definition + * of TPictureCounters for a description of the counters. The counters are + * reset when Initialize() or this method is called, and thus they only + * include pictures processed since the last call. + + * @param aCounters The counter structure to fill + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void GetPictureCounters( + CMMFDevVideoPlay::TPictureCounters& aCounters ); + + /** + * Sets the computational complexity level to use. If separate complexity + * levels are not available, the method call is ignored. If the level + * specified is not available, the results are undefined. Typically the + * device will either ignore the request or use the nearest suitable level. + + * @param aLevel The computational complexity level to use. Level zero (0) + * is the most complex one, with the highest quality. Higher + * level numbers require less processing and may have lower + * quality + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void SetComplexityLevel( TUint aLevel ); + + /** + * Gets the number of complexity levels available. + + * @return The number of complexity control levels available, or zero if + * the information is not available yet. The information may not + * be available if the number of levels depends on the input + * data, and enough input data has not been read yet. In that + * case, using level zero is safe. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint NumComplexityLevels(); + + /** + * Gets information about a computational complexity level. This method can + * be called after NumComplexityLevels() has returned a non-zero value - at + * that point the information is guaranteed to be available. Some hardware + * device implementations may not be able to provide all values, in that + * case the values will be approximated. + + * @param aLevel The computational complexity level to query. The level + * numbers range from zero ( the most complex ) to + * NumComplexityLevels()-1. + * @param aInfo The information structure to fill + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void GetComplexityLevelInfo( TUint aLevel, + CMMFDevVideoPlay::TComplexityLevelInfo& aInfo ); + + /** + * Returns a picture back to the device. This method is called by + * CDevVideoPlay to return pictures from the client ( after they have been + * written with NewPicture() ), or by the output device when it has + * finished using a picture. + + * @param aPicture The picture to return. The device can re-use the + * memory for the picture. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void ReturnPicture( TVideoPicture* aPicture ); + + /** + * Gets a copy of the latest picture sent to output + + * @param aPictureData Target picture. The memory for the picture + * must be allocated by the caller, and + * initialized properly. The data formats must + * match the snapshot format requested. + * @param aFormat The picture format to use for the snapshot. + + * @return ETrue if the snapshot was taken, EFalse if a + * picture is not available. The picture may not + * be available if decoding has not progressed + * far enough yet. + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the + * hwdevice has been initialized with Initialize(). + */ + virtual TBool GetSnapshotL( TPictureData& aPictureData, + const TUncompressedVideoFormat& aFormat ); + + /** + * Gets a copy of a specified picture.When the snapshot is available, it + * will be returned to the client using the TimedSnapshotComplete() + * callback. To cancel a timed snapshot request, use CancelTimedSnapshot(). + * Only one timed snapshot request can be active at a time. + + * @param aPictureData Target picture. The memory for the picture + * must be allocated by the caller, and + * initialized properly. The data formats + * must match the snapshot format requested. + * The picture must remain valid until + * the snapshot has been taken or until the + * the request has been cancelled with + * the CancelTimedSnapshot(). + * @param aFormat The picture format to use for the snapshot + * @param aPresentationTimestamp Presentation timestamp for the picture to + * copy. The timestamp + * must match the timestamp in the picture + * must exactly, so the same clock frequency + * must should be used. Used for the first + * must method variant + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the + * hwdevice has been initialized with + * Initialize(). + */ + virtual void GetTimedSnapshotL( TPictureData* aPictureData, + const TUncompressedVideoFormat& aFormat, + const TTimeIntervalMicroSeconds& aPresentationTimestamp ); + + /** + * Gets a copy of a specified picture.When the snapshot is available, it + * will be returned to the client using the TimedSnapshotComplete() + * callback. To cancel a timed snapshot request, use CancelTimedSnapshot(). + * Only one timed snapshot request can be active at a time. + + * @param aPictureData Target picture. The memory for the picture must be + * allocated by the caller, and initialized properly. + * The data formats must match the snapshot format + * requested. The picture must remain valid until + the snapshot has been taken or until the request + has been cancelled with CancelTimedSnapshot(). + * @param aFormat The picture format to use for the snapshot. + * @param aPictureId Picture identifier for the picture to copy. Used + * for the second method variant + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetTimedSnapshotL( TPictureData* aPictureData, + const TUncompressedVideoFormat& aFormat, + const TPictureId& aPictureId ); + /** + * Cancels a timed snapshot request + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void CancelTimedSnapshot(); + + /** + * Gets a list of the supported snapshot picture formats. + + * @param aFormats An array for the result format list. The array + * must be created and destroyed by the caller + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetSupportedSnapshotFormatsL( + RArray& aFormats ); + + /** + * Notifies the hardware device that the end of input data has been reached + * and no more input data will be written. The hardware device can use this + * signal to ensure that the remaining data gets processed, without waiting + * for new data. After the remaining data has been processed, the hardware + * device must notify call the proxy MdvppStreamEnd() callback.This method + * is mainly useful for file-to-file conversions and other non-realtime + * processing. For real-time playback all video pictures are processed or + * discarded according to their timestamps. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void InputEnd(); + +public: // MProcessEngineObserver Function + + /** + * Callback from Engine to represent buffer has been consumed + * @param : aInp and aError + * @return : TInt: KErrNone or KErrCancel + */ + virtual TInt InputBufferConsumed ( TAny* aInp, TInt aError ); + + /** + * Callback to reprsent that output buffer is ready + * @param : aInp and aError + * @return : TInt: KErrNone or KErrCancel + */ + virtual TInt OutputBufferReady ( TAny* aOup, TInt aError ); + + /** + * CallBack to handle error + * @return : None + */ + virtual void FatalErrorFromProcessEngine ( TInt aError ); + /** + * added as a dummy function, to make compatibility with the + * encoder for the utility-processengine + */ + // Callback to indicate the completion of callback + void CommandProcessed ( TInt aCmd, TAny* aCmdData, TInt aError ); + +public : // MMmfVideoBufferManagementObserver Functions + + /** + * Notifies the observer that one or more new input buffers are available. + * The client can then use MmvbmGetBufferL() to get a buffer. + */ + virtual void MmvbmoNewBuffers() ; + + /** + * Notifies the observer all outstanding input buffers must be + * released immediately + */ + virtual void MmvbmoReleaseBuffers(); + +protected: + + /** + * Set the proxy implementation to be used. Called just after the object is + * constructed. + + * @param aProxy The proxy to use. + */ + virtual void SetProxy( MMMFDevVideoPlayProxy& aProxy ); + +private: + /** + * C++ default constructor. + */ + CAriH264decHwDevice(); + + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + + /** + *Creates o/p buffers based on the o/p formats supported + *@param : None + */ + void CreateOutputBuffersL(); + + /** + * Gives call backs to clinet regarding slice and picture loss + * @param : None + */ + + void SliceAndPictureLoss(); + + /** + * Allcotion and reallocation of input buffers + * @param : None + */ + + void CreateInputBufferL( TUint aBufferSize, TBool aReallocate ); + + /** + * HandleInputEndInStopping + * @param : None + */ + void HandleInputEndInStopping(); + +private : //Data + + // Reference to Input Free Buffer Queue + RArray iInputFreeBufferQueue; + + // Free Input Buffers + TVideoInputBuffer* iInputFreeBuffers; + + // Reference to Output Device + CMMFVideoPostProcHwDevice* iOutputDevice; + + // Reference to Proxy Object + MMMFDevVideoPlayProxy* iMMFDevVideoPlayProxy; + + // Represents the state of the Decoder Hw Device + CStateMachine *iState; + + // Reference to Video Picture Header + TVideoPictureHeader* iVideoPictureHeader; + + // Current Decoding Position + TTimeIntervalMicroSeconds iDecodingPosition; + + // Handle to the Compressed video format + CCompressedVideoFormat* iInputFormat; + + // Uncompressed Output format + TUncompressedVideoFormat iOutputFormat; + + // Buffer Options Set by the Client + CMMFDevVideoPlay::TBufferOptions iBufferOptions; + + // Current Picture Counter value + CMMFDevVideoPlay::TPictureCounters iPictureCounters; + + // Current Bit Stream Counter value + CMMFDevVideoPlay::TBitstreamCounters iBitstreamCounters; + + // Codec Reference + CAriH264decWrapper* iCodec; + + // Base Process Engine Reference + CBaseEngine* iEngine; + + // To Check whether inputend is called or not + TBool iInputEndCalled; + + // OutPut Buffers + TVideoPicture* iOutputFreeBuffer; + + // Free OutPut Buffer Queue + RArray iOutputFreeBufferQueue; + + // counter to keep track of the no of buffers added to the engine + TInt iFilledBufferCounter; + + // data unit type set by the client + TVideoDataUnitType iDataUnitType; + + // Encapulation set by the client + TVideoDataUnitEncapsulation iEncapsulation; + + // represents the o/p buffer size + TInt iOutputBufferSize; + + // flag to whether o/p buffers created or not + TBool iOutputBuffersCreated; + + // Picture Number + TUint iPictureNumber; + + // represents the number of inputbuffers created so avoids reallocation + TUint iNumberOfInputBuffersAllocated; + + // Reference to the custom buffer interface + MMmfVideoBufferManagement* iCustomBufferHandle; + + // buffer options for the custom interface + MMmfVideoBufferManagement::TBufferOptions *iCustomBufferOptions; + + // represents whether the o/p buffers should be added to engine or not + TBool iBufferAdded; + + // flag to indciate that ConfigureDecoderL is called + TBool iConfigureDecoderCalled; + + // flag to indciate that decoder has been configured + TBool iDecoderConfigured; + + // the width of the source file + TInt iWidthSource; + + // the height of the source file + TInt iHeightSource; + + // type of the input stream + TInt iStreamType; + + // length of the NAL hdr + TUint iLenOfNalLenFld, iLenOfHdrLen; + + // array which holds the list of supported formats + RArray iSupportedFormats; + + // array which holds the max value of the picture rates + RArray iMaxPictureRates; + +}; + +#endif //ARIH264DECHWDEVICE_H diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/inc/arih264dechwdeviceuid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/inc/arih264dechwdeviceuid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Information file for the H264 Video Decode HwDevice. +* +*/ + +#ifndef ARIH264DECHWDEVICE_HRH +#define ARIH264DECHWDEVICE_HRH + +#define KUidH264DecoderHwDeviceImplUid 0x20029903 +#define KUidH264DecoderHwDeviceDllUid 0x20029904 + +#endif //ARIH264DECHWDEVICE_HRH diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/src/20029904.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/src/20029904.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for the H264 Video Decode HwDevice +* +*/ + +#include "RegistryInfo.rh" +#include +#include "arih264dechwdeviceuid.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidH264DecoderHwDeviceDllUid; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidDevVideoDecoderHwDeviceDefine; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid + = KUidH264DecoderHwDeviceImplUid; + version_no = 1; + display_name + = "Aricent H264 Video Dec HwDevice"; + default_data ="video/H264"; + opaque_data = "0"; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264dechwdevice/src/arih264dechwdevice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264dechwdevice/src/arih264dechwdevice.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,2230 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This is a source file, required for arih264dechwdevice +* +*/ + +//User includes +#include "arih264dechwdevice.h" +#include "arih264decwrapper.h" +#include "aristatemachine.h" +#include "ariprint.h" + +// +//CAriH264decHwDevice +// + +_LIT( KManufacturer, "Aricent" ); + +_LIT( KIdentifier, "H264 Video Decoder" ); + +//supported h264 mime types +_LIT8( KH264SupportedMimeType, "video/H264" ); + + +//--------------------------------------------------------------------------- +//1st phase constructor of CAriH264decHwDevice +//--------------------------------------------------------------------------- +// +CMMFVideoDecodeHwDevice* CAriH264decHwDevice::NewL() + { + PRINT_ENTRY; + CAriH264decHwDevice* self = new ( ELeave ) CAriH264decHwDevice; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + PRINT_EXIT; + return self; + } + +//--------------------------------------------------------------------------- +//Destructor +//--------------------------------------------------------------------------- +// +CAriH264decHwDevice::~CAriH264decHwDevice() + { + PRINT_ENTRY; + delete iInputFormat; + delete iEngine; + delete iCodec; + delete iState; + + delete iVideoPictureHeader; + + // This is required becoz user may say exit before start at that point + // OutputFreeBuffer is not created + if ( iOutputFreeBuffer ) + { + for( TInt i = 0 ; i < KMaxOutputBuffers; i++ ) + { + if ( ( iOutputFreeBuffer + i )->iHeader ) + { + delete ( iOutputFreeBuffer + i )->iHeader; + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete + ( TUint8* )( iOutputFreeBuffer + i )->iData.iRawData->Ptr(); + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete ( iOutputFreeBuffer + i )->iData.iRawData; + } + } + delete [] iOutputFreeBuffer; + } + + if ( iInputFreeBuffers ) + { + for ( TInt i = 0 ; i < iBufferOptions.iMinNumInputBuffers; i++ ) + { + delete [] ( TUint8* )iInputFreeBuffers[i].iData.Ptr(); + delete iInputFreeBuffers[i].iUser; + } + delete [] iInputFreeBuffers; + } + + if ( iCustomBufferOptions ) + { + delete iCustomBufferOptions; + } + + iOutputFreeBufferQueue.Close(); + iInputFreeBufferQueue.Close(); + + iMaxPictureRates.Reset(); + iMaxPictureRates.Close(); + iSupportedFormats.Reset(); + iSupportedFormats.Close(); + + iOutputDevice = NULL; + iMMFDevVideoPlayProxy = NULL; + iCustomBufferHandle = NULL; + + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//Retrieves a custom interface to the device. +//--------------------------------------------------------------------------- +// +TAny* CAriH264decHwDevice::CustomInterface( TUid /*aInterface*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +//Retrieves decoder information about this hardware device. The device +//creates a CVideoDecoderInfo structure, fills it with correct data, +//pushes it to the cleanup stack and returns it. The client will delete the +//object when it is no longer needed. +//--------------------------------------------------------------------------- +// +CVideoDecoderInfo* CAriH264decHwDevice::VideoDecoderInfoLC() + { + PRINT_ENTRY; + + // construct the video types for iVidTypes + CCompressedVideoFormat* format = NULL; + format = CCompressedVideoFormat::NewL( KH264SupportedMimeType ); + CleanupStack::PushL(format); + TInt status = iSupportedFormats.Append( format ); + if ( status != KErrNone ) + { + PRINT_MSG( LEVEL_LOW, ( " Format support is not done, retval of " + "append = %d \n", status ) ); + } + CleanupStack::Pop( format ); + + for ( TUint i = 0; i < KDecoderInfoCount; i++ ) + { + // max picture rates + TPictureRateAndSize pictureRateAndSize; + pictureRateAndSize.iPictureSize = TSize( KMaxFrameWidth, + KMaxFrameHeight ); + pictureRateAndSize.iPictureRate = KPicRate; + status = iMaxPictureRates.Append(pictureRateAndSize); + if ( status != KErrNone ) + { + PRINT_MSG( LEVEL_LOW, ( " error in appendng picturerates = %d \n", + status ) ); + } + } + TUint maxBitRate = KMaxBitRate; + CVideoDecoderInfo* videoDecoderInfo = CVideoDecoderInfo::NewL( + KUidH264DecoderHwDevice, + KManufacturer, + KIdentifier, + TVersion( 1, 0, 0 ), + iSupportedFormats.Array(), + // Non-Accelerated + EFalse, + // Doesnt support Direct Display + EFalse, + TSize( KMaxFrameWidth, KMaxFrameHeight ), + maxBitRate, + iMaxPictureRates.Array(), + //decoder supports picture loss indications + ETrue, + //decoder supports slice loss indications + ETrue ); + + CleanupStack::PushL( videoDecoderInfo ); + + PRINT_MSG( LEVEL_LOW, ( "Closing maxPictureRates&supportedFormats\n" ) ); + + PRINT_EXIT; + + return videoDecoderInfo; + } + +//--------------------------------------------------------------------------- +//Reads header information from a coded data unit. +//--------------------------------------------------------------------------- +// +TVideoPictureHeader* CAriH264decHwDevice::GetHeaderInformationL( + TVideoDataUnitType /*aDataUnitType*/, + TVideoDataUnitEncapsulation aEncapsulation, + TVideoInputBuffer* aDataUnit ) + { + PRINT_ENTRY; + if (!aDataUnit ) + { + PRINT_ERR( "Input argument is not proper, aDataUnit is null \n" ); + User::Leave( KErrArgument ); + } + + if ( aEncapsulation != EDuElementaryStream ) + { + PRINT_ERR( "aEncapsulation is not supported type \n" ); + User::Leave( KErrNotSupported ); + } + + iVideoPictureHeader = new ( ELeave ) TVideoPictureHeader; + + TRAPD( err, CAriH264decWrapper::GetHeaderInfoL( *aDataUnit, + *iVideoPictureHeader ) ); + + if ( err == KErrNone ) + { + PRINT_EXIT; + return ( iVideoPictureHeader ); + } + + // An error has occured + delete iVideoPictureHeader; + iVideoPictureHeader = NULL; + + switch ( err ) + { + case KErrCorrupt: + case KErrNoMemory: + case KErrArgument: + case KErrNotSupported: + { + PRINT_ERR( "GetHeaderInfoL is returned with error \n" ); + User::Leave( err ); + break; + } + case KErrUnderflow: + { + PRINT_ERR( "GetHeaderInfoL returnd with error KErrUnderflow\n" ); + break; + } + default: + { + PRINT_ERR( "GetHeaderInfoL is returned with error \n" ); + User::Leave( KErrGeneral ); + } + }; + + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +//Returns a header from GetHeaderInformationL() back to the decoder so that +//the memory can be freed. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::ReturnHeader( TVideoPictureHeader* aHeader ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( iVideoPictureHeader == aHeader ) + { + delete iVideoPictureHeader; + iVideoPictureHeader = NULL; + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Sets the device input format to a compressed video format. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetInputFormatL( + const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TBool aDataInOrder ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( ( !aDataInOrder ) || + ( aEncapsulation == EDuGenericPayload ) || + ( aEncapsulation == EDuRtpPayload ) ) + User::Leave( KErrNotSupported ); + + if ( ( aFormat.MimeType().FindF( KH264SupportedMimeType ) != + KErrNotFound ) ) + + { + iInputFormat = CCompressedVideoFormat::NewL( aFormat ); + iDataUnitType = aDataUnitType; + iEncapsulation = aEncapsulation; + } + else + { + PRINT_ERR( "aFormat is not supported \n" ); + User::Leave( KErrNotSupported ); + } + } + else + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Sets whether decoding should be synchronized to the current clock source, +//if any, or if pictures should instead be decoded as soon as possible. +//If decoding is synchronized, decoding timestamps are used if available, +//presentation timestamps are used if not. When decoding is not synchronized, +//pictures are decoded as soon as source data is available for them, and the +//decoder has a free output buffer. If a clock source is not available, +//decoding will not be synchronized. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SynchronizeDecoding( TBool /*aSynchronize*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + return; + } + + +//--------------------------------------------------------------------------- +//Sets the Buffer Options as specified by the client. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetBufferOptionsL( + const CMMFDevVideoPlay::TBufferOptions& aOptions ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + TTimeIntervalMicroSeconds zerotime( 0 ); + if ( ( aOptions.iMinNumInputBuffers < KMinInputBuffers ) || + ( aOptions.iPreDecodeBufferSize != 0 ) || + ( aOptions.iMaxPostDecodeBufferSize != 0 ) || + ( aOptions.iPreDecoderBufferPeriod != zerotime ) || + ( aOptions.iPostDecoderBufferPeriod != zerotime ) ) + { + User::Leave( KErrArgument ); + } + + if ( ( aOptions.iMinNumInputBuffers > KMaxInputBuffers ) || + ( aOptions.iMaxInputBufferSize > KMaxInputBufferSize ) ) + { + User::Leave( KErrNotSupported ); + } + + iBufferOptions = aOptions; + } + else + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Gets the video decoder buffer options actually in use. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetBufferOptions( + CMMFDevVideoPlay::TBufferOptions& aOptions ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + aOptions = iBufferOptions; + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Indicates which HRD/VBV specification is fulfilled in the input stream and +//any related parameters. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetHrdVbvSpec( + THrdVbvSpecification /*aHrdVbvSpec*/, + const TDesC8& /*aHrdVbvParams*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets the output post-processor device to use. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetOutputDevice( + CMMFVideoPostProcHwDevice* aDevice ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( !aDevice ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + else + { + iOutputDevice = aDevice; + + // checks whether customBuffer supported by o/p device + iCustomBufferHandle = ( MMmfVideoBufferManagement* ) + ( iOutputDevice->CustomInterface( KMmfVideoBuffermanagementUid ) ); + } + } + else + { + PRINT_ERR( "istate is not initialized yet, " + "calling MdvppFatalError on iMMFDevVideoPlayProxy\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Returns the current decoding position, i.e. +//the timestamp for the most recently decoded picture. +//--------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriH264decHwDevice::DecodingPosition() + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_EXIT; + return iDecodingPosition; + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + return ( TTimeIntervalMicroSeconds( 0 ) ); + } + } + +//--------------------------------------------------------------------------- +//Returns the current pre-decoder buffer size. +//--------------------------------------------------------------------------- +// +TUint CAriH264decHwDevice::PreDecoderBufferBytes() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + return ( 0 ); + } + + PRINT_EXIT; + return 0; + } + +//--------------------------------------------------------------------------- +//Reads various counters related to the received input bitstream +//and coded data units. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetBitstreamCounters( + CMMFDevVideoPlay::TBitstreamCounters& aCounters ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + aCounters = iBitstreamCounters; + //Reset the counters to Zero + iBitstreamCounters.iLostPackets = 0; + iBitstreamCounters.iTotalPackets = 0; + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Retrieves the number of free input buffers the decoder has available +//--------------------------------------------------------------------------- +// +TUint CAriH264decHwDevice::NumFreeBuffers() + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + if ( iNumberOfInputBuffersAllocated == 0 ) + { + PRINT_EXIT; + return ( iBufferOptions.iMinNumInputBuffers ); + } + else + { + PRINT_EXIT; + return ( iInputFreeBufferQueue.Count() ); + } + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + return( 0 ); + } + } + +//--------------------------------------------------------------------------- +//Returns an input buffer of size aBufferSize. If no buffer is available +//then NULL is returned. +//--------------------------------------------------------------------------- +// +TVideoInputBuffer* CAriH264decHwDevice::GetBufferL( TUint aBufferSize ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + return NULL; + } + + if ( iState->IsInputEndPending() ) + { + PRINT_ERR( "input is pending\n" ); + User::Leave( KErrNotReady ); + return NULL; + } + + if ( aBufferSize > iBufferOptions.iMaxInputBufferSize ) + { + PRINT_ERR( "aBufferSize is more than the allowed size\n" ); + User::Leave( KErrArgument ); + return NULL; + } + + + TVideoInputBuffer *inBuffer; + + if ( iNumberOfInputBuffersAllocated == + iBufferOptions.iMinNumInputBuffers ) + { + if ( iInputFreeBufferQueue.Count() ) + { + PRINT_ERR( "CreateInputBufferL returned ETRUE\n" ); + // Reallocate the input buffer if needed + CreateInputBufferL( aBufferSize, ETrue ); + inBuffer = iInputFreeBufferQueue[0]; + iInputFreeBufferQueue.Remove( 0 ); + + } + else + { + PRINT_ERR( "No input free buffers available \n" ); + return NULL; + } + } + else if ( iNumberOfInputBuffersAllocated < + iBufferOptions.iMinNumInputBuffers ) + { + PRINT_ERR( "CreateInputBufferL returned EFALSE\n" ); + // Allocate new buffer of the requested size + CreateInputBufferL( aBufferSize, EFalse ); + + // remove the last created buffer + inBuffer = iInputFreeBufferQueue[ iInputFreeBufferQueue.Count() - 1]; + + iInputFreeBufferQueue.Remove( iInputFreeBufferQueue.Count() - 1 ); + } + else + { + PRINT_ERR( "iNumberOfInputBuffersAllocated is less " + " iBufferOptions.iMinNumInputBuffers\n" ); + User::Leave( KErrGeneral ); // unwanted state; + return NULL; + } + + PRINT_EXIT; + return inBuffer; + } + + +//--------------------------------------------------------------------------- +//Called by DevVideoPlay to write the coded data. +//Writes a piece of coded video data to the decoder. The data buffer must +//be retrieved from the decoder with GetBufferL().. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::WriteCodedDataL( TVideoInputBuffer* aBuffer ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + PRINT_ERR( "istate is not initialized yet \n" ); + User::Leave( KErrNotReady ); + } + + if ( !aBuffer ) + { + PRINT_ERR( "aBuffer is null \n" ); + User::Leave( KErrArgument ); + } + + if ( aBuffer->iData.Length() == 0 ) + { + PRINT_ERR( "length of aBuffer is zero \n" ); + User::Leave( KErrArgument ); + } + + if ( iState->IsInputEndPending() ) + { + PRINT_ERR( "IsInputEndPending is true \n" ); + User::Leave( KErrEof ); + } + + if ( !iCodec ) + { + iCodec = CAriH264decWrapper::NewL( iDataUnitType, + iOutputFormat, + &aBuffer->iData, + iStreamType ); + + iDecoderConfigured = ETrue; + } + + if ( ( iDataUnitType == EDuSeveralSegments ) || + ( iDataUnitType == EDuVideoSegment ) ) + { + iBitstreamCounters.iTotalPackets++; + } + + // if custom interface is supported by o/p device get all the buffers + //and add it to Engine + if ( !iOutputBuffersCreated ) + { + // Set Stream information + if ( !iDecoderConfigured ) + { + User::Leave( KErrNotReady ); + } + + if ( !iCustomBufferHandle ) + { + // Get o/p buffer length for creation + iCodec->GetParam( CONTROL_CMD_GET_OUTPUTBUFFERLENGTH, + ( TAny* )&iOutputBufferSize ); + CreateOutputBuffersL(); + } + iOutputBuffersCreated = ETrue; + } + + // add all the o/p buffers to engine + if ( !iBufferAdded ) + { + if ( iCustomBufferHandle ) + { + TVideoPicture* videoPicture = NULL; + for ( TInt i = 0; + i < iCustomBufferOptions->iNumInputBuffers; + i++ ) + { + videoPicture = + iCustomBufferHandle->MmvbmGetBufferL( + iCustomBufferOptions->iBufferSize ); + if ( videoPicture ) + { + TRAPD( lErr, videoPicture->iHeader = + new ( ELeave ) TVideoPictureHeader ) ; + if ( lErr != KErrNone ) + { + iCustomBufferHandle->MmvbmReleaseBuffer( + videoPicture ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, + KErrArgument ); + } + else + { + iEngine->AddOutput( videoPicture ); + } + } + else + { + break; + } + } + } + else + { + for( TInt i = 0; i < iOutputFreeBufferQueue.Count(); i++ ) + { + iEngine->AddOutput( iOutputFreeBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + } + } + iBufferAdded = ETrue; + } + + iPictureCounters.iTotalPictures++; + iFilledBufferCounter++; + TInt err = iEngine->AddInput( aBuffer ); + PRINT_MSG( LEVEL_LOW, ( "WriteCodedDataL, addinput err=%d", err ) ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Configures the H264 decoder by passing the required header +//information for the stream that is getting decoded. The header +//structurespecific to the Decoder is passed as iOptional member. +//--------------------------------------------------------------------------- +// +#ifdef SYMBIAN_MDF_API_V2 +void CAriH264decHwDevice::ConfigureDecoderL( + const TVideoPictureHeader& aVideoPictureHeader ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is already initialised \n" ); + User::Leave( KErrNotReady ); + } + if ( !iCodec ) + { + iCodec = CAriH264decWrapper::NewL( iDataUnitType, + iOutputFormat, + aVideoPictureHeader.iOptional, + iStreamType ); + + if ( !iCodec ) + { + PRINT_ERR( "codec wrapper returned error \n" ); + User::Leave( KErrNotReady ); + } + iDecoderConfigured = ETrue; + iConfigureDecoderCalled = ETrue; + } + + iWidthSource = aVideoPictureHeader.iSizeInMemory.iWidth; + iHeightSource = aVideoPictureHeader.iSizeInMemory.iHeight; + PRINT_EXIT; + } +#endif + + + +//--------------------------------------------------------------------------- +//Retrieves post-processing information about this hardware device. +//The device creates a CPostProcessorInfo structure, fills it with correct +//data, pushes it to the cleanup stack and returns it. The client will +//delete the object when it is no longer needed. +//--------------------------------------------------------------------------- +// +CPostProcessorInfo* CAriH264decHwDevice::PostProcessorInfoLC() + { + PRINT_ENTRY; + //Aricent decoder does not support any post processing functionality + RArray supportedFormats; + CleanupClosePushL( supportedFormats ); + + RArray supportedCombinations; + CleanupClosePushL( supportedCombinations ); + + TYuvToRgbCapabilities yuvToRgbCapabilities; + RArray supportedScaleFactors; + CleanupClosePushL( supportedScaleFactors ); + + CPostProcessorInfo* info = CPostProcessorInfo::NewL( + KUidH264DecoderHwDevice, + KManufacturer, + KIdentifier, + TVersion( 1, 0, 0 ), + supportedFormats.Array(), + supportedCombinations.Array(), + EFalse, //Accelerated or not + EFalse, //supports DSA + yuvToRgbCapabilities, + ERotateNone, //supported rotations + EFalse, //supports Arbitrary scaling + supportedScaleFactors.Array(), + EFalse ) //supports antialiased scaling + ; + + CleanupStack::PushL( info ); + + CleanupStack::Pop( &supportedScaleFactors ); + supportedScaleFactors.Close(); + CleanupStack::Pop( &supportedCombinations ); + supportedCombinations.Close(); + CleanupStack::Pop( &supportedFormats ); + supportedFormats.Close(); + + PRINT_EXIT; + return info; + } + +//--------------------------------------------------------------------------- +//Retrieves the list of the output formats that the device supports. +//The list can depend on the device source format, and therefore +//SetSourceFormatL() must be called before calling this method. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetOutputFormatListL( + RArray& aFormats ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is already initialised \n" ); + User::Leave( KErrNotReady ); + } + + if ( !iInputFormat ) + { + //Input format should be set before calling this function, as output + // format is decided based on input format + PRINT_ERR( "iInputFormat is not set yet \n" ); + User::Leave( KErrNotReady ); + } + + TUncompressedVideoFormat format; + format.iDataFormat = EYuvRawData; + format.iYuvFormat.iYuv2RgbMatrix = NULL; + format.iYuvFormat.iRgb2YuvMatrix = NULL; + format.iYuvFormat.iAspectRatioNum = 1; + format.iYuvFormat.iAspectRatioDenom = 1; + + aFormats.Reset(); + + //The following formats are supported by both H.263 and Mpeg-4 + + //YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt601Range0; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //The following formats are only supported by Mpeg-4 + if ( iInputFormat->MimeType().FindF( KH264SupportedMimeType ) != + KErrNotFound ) + { + //BT 601.5 Full Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt601Range1; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //BT 709 Reduced Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt709Range0; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //BT 709 Full Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt709Range1; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the device output format. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetOutputFormatL( + const TUncompressedVideoFormat &aFormat ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "istate is already initialised \n" ); + User::Leave( KErrNotReady ); + } + + if ( !iInputFormat ) + { + //Input format should be set before calling this function, as output + // format is decided based on input format + PRINT_ERR( "iInputFormat is not set yet \n" ); + User::Leave( KErrNotReady ); + } + + // check whether the output format is supported or not. if not + //supported leave + RArray formats; + CleanupClosePushL( formats ); + + GetOutputFormatListL( formats ); + + TBool flag = EFalse; + + for ( TInt i = 0; i < formats.Count(); i++ ) + { + if ( aFormat == formats[i] ) + { + flag = ETrue; + break; + } + } + CleanupStack::Pop ( &formats ); + formats.Close(); + + if ( !flag ) + { + PRINT_ERR( "outputformat is not supported \n" ); + User::Leave( KErrNotSupported ); + } + + iOutputFormat = aFormat; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the clock source to use for video timing. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetClockSource( MMMFClockSource* /*aClock*/ ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is initialised,calling MdvppFatalError \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +// Sets the device video output destination. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetVideoDestScreenL( TBool aScreen ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( aScreen ) + { + PRINT_ERR( "KErrNotSupported \n" ); + User::Leave( KErrNotSupported ); + } + } + else + { + PRINT_ERR( "KErrNotSupported \n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the post-processing types to be used. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetPostProcessTypesL( + TUint32 /*aPostProcCombination*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for input (pan-scan ) cropping. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetInputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + + +//--------------------------------------------------------------------------- +// Sets post-processing options for YUV to RGB color space conversion +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetYuvToRgbOptionsL( + const TYuvToRgbOptions& /*aOptions*/, + const TYuvFormat& /*aYuvFormat*/, + TRgbFormat /*aRgbFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for YUV to RGB color space conversion. Uses +//the device input and output formats. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetYuvToRgbOptionsL( + const TYuvToRgbOptions& /*aOptions*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for rotation. SetPostProcessTypesL() must be +//called before this method is used. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetRotateOptionsL( TRotationType /*aRotationType*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets post-processing options for scaling. SetPostProcessTypesL() must be +//called before this method is used. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetScaleOptionsL( const TSize& /*aTargetSize*/, + TBool /*aAntiAliasFiltering*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets post-processing options for output cropping. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetOutputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + + +//--------------------------------------------------------------------------- +//Sets post-processing plug-in specific options. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetPostProcSpecificOptionsL( + const TDesC8& /*aOptions*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Initializes the device. This method is asynchronous, the device calls +//MdvppInitializeComplete() of MMFVideoPlayProxy after initialization has +//completed. After this method has successfully completed, further +//configuration changes are not possible except where separately noted. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Initialize() + { + PRINT_ENTRY; + if ( !iState->IsTransitionValid( CStateMachine::EInitializeCommand ) ) + { + PRINT_ERR( "state is not valid in statemachine \n" ); + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, KErrNotReady ); + return; + } + + TRAPD( err, iInputFreeBuffers = + new ( ELeave ) TVideoInputBuffer[iBufferOptions.iMinNumInputBuffers] ); + if ( err ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "creation of iInputFreeBuffers returned error\n" ); + return; + } + + iPictureCounters.iPicturesDisplayed = 0; + iPictureCounters.iPicturesSkipped = 0; + iPictureCounters.iTotalPictures = 0; + iPictureCounters.iPicturesDecoded = 0; + + iBitstreamCounters.iLostPackets = 0; + iBitstreamCounters.iTotalPackets = 0; + + // if custom interface is supported then enable the interface + if ( iCustomBufferHandle ) + { + + TRAP( err, iCustomBufferOptions = + new ( ELeave ) MMmfVideoBufferManagement::TBufferOptions ); + + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "creation of iCustomBuffeOptions returned error \n" ); + return; + } + + iCustomBufferOptions->iNumInputBuffers = KMaxOutputBuffers + 1; + iCustomBufferOptions->iBufferSize = TSize( KMaxFrameWidth, + KMaxFrameHeight ); + + PRINT_MSG( LEVEL_HIGH, ( "w = %d, h = %d \n", KMaxFrameWidth, + KMaxFrameHeight) ); + + iCustomBufferHandle->MmvbmSetObserver( + ( MMmfVideoBufferManagementObserver * )this ); + + iCustomBufferHandle->MmvbmEnable( ETrue ); + + TRAP ( err, iCustomBufferHandle->MmvbmSetBufferOptionsL( + *iCustomBufferOptions ) ); + + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "iCustomBufferHandle->MmvbmSetBufferOptionsL \n" ); + return; + } + } + // Engine Creation + TRAP( err, iEngine = CBaseEngine::NewL( this, + ( MBaseCodec* )iCodec, + EFalse ) ); + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "Baseengine::NewL returned error \n" ); + return; + } + + // set input & output formats to Codec + + err = iState->Transit( CStateMachine::EInitializeCommand ); + if ( err ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + return; + } + + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, KErrNone ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Commit all changes since the last CommitL(), Revert() or Initialize() +//to the hardware device. This only applies to methods which can be called +//both before AND after DevVideoPlay has been initialized. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::CommitL() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Revert all changes since the last CommitL(), Revert() or Initialize() back +//to their previous settings. This only applies to methods which can be +//called both before AND after DevVideoPlay has been initialized.. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Revert() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + } + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::StartDirectScreenAccessL( + const TRect& /*aVideoRect*/, + CFbsScreenDevice& /*aScreenDevice*/, + const TRegion& /*aClipRegion*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetScreenClipRegion( const TRegion& /*aRegion*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetPauseOnClipFail( TBool /*aPause*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::AbortDirectScreenAccess() + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Indicates whether playback is proceeding. This method can be used to check +//whether playback was paused or not in response to a new clipping region +//or DSA abort +//--------------------------------------------------------------------------- +// +TBool CAriH264decHwDevice::IsPlaying() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + return ( iState->IsStarted() ); + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Redraw() + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Starts video playback, including decoding, post-processing, and rendering. +//Playback will proceed until it has been stopped or paused, or the end of +//the bitstream is reached. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Start() + { + PRINT_ENTRY; + if ( iState->IsPlaying() ) + { + PRINT_EXIT; + PRINT_ERR( "already in playing state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EStartCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iDecodingPosition = TTimeIntervalMicroSeconds( 0 ); + iEngine->Start(); + + TInt error = iState->Transit( CStateMachine::EStartCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Stops video playback. No new pictures will be decoded, post-processed, +//or rendered. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Stop() + { + PRINT_ENTRY; + if ( iState->IsStopped() ) + { + PRINT_EXIT; + PRINT_ERR( "already in stopped state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EStopCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iPictureNumber = 0; + // Stop & Reset the Engine + iEngine->Stop(); + iEngine->Reset(); + iBufferAdded = EFalse; + iFilledBufferCounter = 0; + iInputEndCalled = EFalse; + TInt error = iState->Transit( CStateMachine::EStopCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Pauses video playback, including decoding, post-processing, and rendering. +//No pictures will be decoded, post-processed, or rendered until playback has +//been resumed. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Pause() + { + PRINT_ENTRY; + if ( iState->IsPaused() ) + { + PRINT_EXIT; + PRINT_ERR( "already in paused state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EPauseCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + //Stop the Engine + iEngine->Stop(); + + TInt error = iState->Transit( CStateMachine::EPauseCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Resumes video playback after a pause. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::Resume() + { + PRINT_ENTRY; + if ( iState->IsPlaying() ) + { + PRINT_EXIT; + PRINT_ERR( "already in playing state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EResumeCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + // Start The Engine + iEngine->Start(); + + TInt error = iState->Transit( CStateMachine::EResumeCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + + + +//--------------------------------------------------------------------------- +//Changes to a new decoding and playback position,used for randomly accessing +//(seeking)the input stream. The position change flushes all input and output +//buffers. Pre-decoder and post-decoder buffering are handled as if a new +//bitstream was being decoded. If the device still has buffered pictures that +//precede the new playback position, they will be discarded. If playback is +//synchronized to a clock source, the client is responsible for setting the +//clock source to the new position.. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetPosition( + const TTimeIntervalMicroSeconds& aPlaybackPosition ) + { + PRINT_ENTRY; + //Start Decoding from new position + if ( iState->IsInitialized() ) + { + iEngine->Stop(); + iEngine->Reset(); + iDecodingPosition = aPlaybackPosition; + iBufferAdded = EFalse; + iEngine->Start(); + } + else + { + PRINT_ERR( "istate is not initialised yet\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::FreezePicture( + const TTimeIntervalMicroSeconds& /*aTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::ReleaseFreeze( + const TTimeIntervalMicroSeconds& /*aTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Returns the current playback position, i.e. the timestamp for the most +//recently displayed or virtually displayed picture. If the device output +//is written to another device, the most recent output picture is used +//--------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriH264decHwDevice::PlaybackPosition() + { + PRINT_ENTRY; + // In Decoder case decoding position is same as playback position + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + return iDecodingPosition; + } + +//--------------------------------------------------------------------------- +//Returns the total amount of memory allocated for uncompressed pictures. +//--------------------------------------------------------------------------- +// +TUint CAriH264decHwDevice::PictureBufferBytes() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + return( KMaxOutputBuffers * iOutputBufferSize ); + } + +//--------------------------------------------------------------------------- +//Reads various counters related to decoded pictures. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetPictureCounters( + CMMFDevVideoPlay::TPictureCounters& aCounters ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + aCounters = iPictureCounters; + + //Reset the counters to Zero + iPictureCounters.iPicturesDisplayed = 0; + iPictureCounters.iPicturesSkipped = 0; + iPictureCounters.iTotalPictures = 0; + iPictureCounters.iPicturesDecoded = 0; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetComplexityLevel( TUint /*aLevel*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +TUint CAriH264decHwDevice::NumComplexityLevels() + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return 0; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetComplexityLevelInfo( TUint /*aLevel*/, + CMMFDevVideoPlay::TComplexityLevelInfo& /*aInfo*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Called by the Post Proc hwdevice when a picture is displayed on the screen. +//Returns a picture back to the device. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::ReturnPicture( TVideoPicture* aPicture ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + if ( iCustomBufferHandle ) + { + delete aPicture->iHeader ; + aPicture->iHeader = NULL ; + } + else + { + // add to engine if state is not stopped + if ( iState->IsStopped() ) + { + iOutputFreeBufferQueue.Append( aPicture ); + } + else + { + iEngine->AddOutput( aPicture ); + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +TBool CAriH264decHwDevice::GetSnapshotL( TPictureData& /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + return( 0 ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetTimedSnapshotL( + TPictureData* /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/, + const TTimeIntervalMicroSeconds& /*aPresentationTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + //Should take it from Post Proc HwDevice + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetTimedSnapshotL( + TPictureData* /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/, + const TPictureId& /*aPictureId*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + //Should take it from Post Proc HwDevice + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::CancelTimedSnapshot() + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::GetSupportedSnapshotFormatsL( + RArray& /*aFormats*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//sets the Flag iInputEndCalled to ETrue +//Notifies the hardware device that the end of input data has been reached +//and no more input data will be written +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::InputEnd() + { + PRINT_ENTRY; + if ( !( iState->IsTransitionValid( CStateMachine::EInputEndCommand ) ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iInputEndCalled = ETrue; + + if ( iFilledBufferCounter == 0 ) + { + Stop(); + PRINT_EXIT; + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + return; + } + + TInt error = iState->Transit( CStateMachine::EInputEndCommand ); + + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Notifies the Hw Device that input buffer is free +//--------------------------------------------------------------------------- +// +TInt CAriH264decHwDevice::InputBufferConsumed ( TAny* aInp, TInt aError ) + { + PRINT_ENTRY; + if ( aInp ) + { + iInputFreeBufferQueue.Append( ( TVideoInputBuffer* )aInp ); + + //call back to clinet + if ( ( aError != KErrCancel ) && ( !iInputEndCalled ) ) + iMMFDevVideoPlayProxy->MdvppNewBuffers(); + } + PRINT_EXIT; + return ( KErrNone ); + } + + +//--------------------------------------------------------------------------- +//Notifies the Hw Device that out buffer has decoded data +//--------------------------------------------------------------------------- +// +TInt CAriH264decHwDevice::OutputBufferReady ( TAny* aOut, TInt aError ) + { + PRINT_ENTRY; + if ( aError == KErrNone ) + { + iPictureNumber++; + // call back information regarding slice and picture loss + + SliceAndPictureLoss(); + + //Decoded Buffer is available + TVideoPicture* videoPicture = ( TVideoPicture* )aOut; + videoPicture->iHeader->iPictureNumber = iPictureNumber; + + iFilledBufferCounter--; + + iPictureCounters.iPicturesDecoded++; + iPictureCounters.iPicturesDisplayed++; + + iDecodingPosition = videoPicture->iTimestamp; + if ( !iOutputDevice ) + { + iMMFDevVideoPlayProxy->MdvppNewPicture( videoPicture ); + + if ( iInputEndCalled && ( iFilledBufferCounter == 0 ) ) + { + Stop(); + PRINT_ERR( "calling streamend\n" ); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + } + + return( KErrNone ); + } + else + { + TRAPD( error, iOutputDevice->WritePictureL( videoPicture ) ); + + if ( error == KErrNone ) + { + if ( iInputEndCalled && ( iFilledBufferCounter == 0 ) ) + { + HandleInputEndInStopping(); + PRINT_ERR( "calling streamend\n" ); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + } + } + else if ( error ) // KErrArgument, KErrNotReady + { + iPictureCounters.iPicturesDisplayed--; + // Currently not handled + } + } + } + + else if ( aError == KErrCancel ) + { + + // Add buffers to output free buffer queue if cutombuffer is not set + if ( !iCustomBufferHandle ) + { + iOutputFreeBufferQueue.Append( ( TVideoPicture* )aOut ); + } + else + { + delete ( ( TVideoPicture* )aOut )->iHeader; + ( ( TVideoPicture* )aOut )->iHeader = NULL; + + // release the buffer + iCustomBufferHandle->MmvbmReleaseBuffer( ( TVideoPicture* )aOut ); + } + + } + + else // other errors + { + // currently not handled + } + + PRINT_EXIT; + return ( KErrNone ); + } + +//--------------------------------------------------------------------------- +//Notifies the hw devcie that Error has occured in PE +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::FatalErrorFromProcessEngine ( TInt aError ) + { + PRINT_ENTRY; + iMMFDevVideoPlayProxy->MdvppFatalError( this, aError ); + PRINT_EXIT; + } + +/* +****************************************************************************** +Name : CommandProcessed +Description : Callback to indicate the command has been processed +Parameter : +Return Value : +Assumptions : None +Known Issues : None +****************************************************************************** +*/ +void CAriH264decHwDevice::CommandProcessed ( TInt aCmd, TAny* aCmdData, + TInt aError ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + + + +//--------------------------------------------------------------------------- +//Call back from output device, indicates buffers availability +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::MmvbmoNewBuffers() + { + PRINT_ENTRY; + TVideoPicture* videoPicture = NULL; + + TRAPD( err, videoPicture = iCustomBufferHandle->MmvbmGetBufferL( + iCustomBufferOptions->iBufferSize ) ); + + if ( err != KErrNone ) + { + PRINT_ERR( "iCustomBufferHandle->MmvbmGetBufferL returned error\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + if ( videoPicture ) + { + if ( videoPicture->iHeader ) + { + delete videoPicture->iHeader; + videoPicture->iHeader = NULL; + } + + TRAPD( err1, videoPicture->iHeader = + new ( ELeave ) TVideoPictureHeader ) ; + + if ( err1 != KErrNone ) + { + iCustomBufferHandle->MmvbmReleaseBuffer( videoPicture ) ; + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + else + { + iEngine->AddOutput( videoPicture ); + } + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Callback from output device. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::MmvbmoReleaseBuffers() + { + PRINT_ENTRY; + iEngine->Stop(); + iEngine->Reset(); + PRINT_EXIT; + } + + + +//--------------------------------------------------------------------------- +//Set the proxy implementation to be used. Called just +//after the object is constructed +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SetProxy( MMMFDevVideoPlayProxy& aProxy ) + { + PRINT_ENTRY; + iMMFDevVideoPlayProxy = &aProxy; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Default constructor of CAriH264decHwDevice +//--------------------------------------------------------------------------- +// +CAriH264decHwDevice::CAriH264decHwDevice() + :iInputFreeBuffers( NULL ), + iOutputDevice( NULL ), + iMMFDevVideoPlayProxy( NULL ), + iState( NULL ), + iVideoPictureHeader( NULL ), + iDecodingPosition( TTimeIntervalMicroSeconds( 0 ) ), + iInputFormat( NULL ), + iCodec( NULL ), + iEngine( NULL ), + iInputEndCalled( EFalse ), + iOutputFreeBuffer( NULL ), + iFilledBufferCounter( 0 ), + iDataUnitType( EDuCodedPicture ), + iEncapsulation( EDuElementaryStream ), + iOutputBufferSize( 0 ), + iOutputBuffersCreated( EFalse ), + iPictureNumber( 0 ), + iNumberOfInputBuffersAllocated( 0 ), + iCustomBufferHandle( NULL ), + iCustomBufferOptions( NULL ), + iBufferAdded( EFalse ), + iConfigureDecoderCalled( EFalse ), + iDecoderConfigured( EFalse ) + { + PRINT_ENTRY; + iBufferOptions.iPreDecodeBufferSize = 0; + iBufferOptions.iMaxPostDecodeBufferSize = 0; + iBufferOptions.iPreDecoderBufferPeriod = 0; + iBufferOptions.iPostDecoderBufferPeriod = 0; + iBufferOptions.iMinNumInputBuffers = KMaxInputBuffers; + iBufferOptions.iMaxInputBufferSize = KMaxInputBufferSize; + + + // Initializing iOutputFormat with one of the combination supported by + iOutputFormat.iDataFormat = EYuvRawData; + iOutputFormat.iYuvFormat.iCoefficients = EYuvBt601Range0; + iOutputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + iOutputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + iOutputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + iOutputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + iOutputFormat.iYuvFormat.iAspectRatioNum = 1; + iOutputFormat.iYuvFormat.iAspectRatioDenom = 1; + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//This is the 2nd phase constructor +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::ConstructL() + { + PRINT_ENTRY; + iState = CStateMachine::NewL(); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Module to create output data +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::CreateOutputBuffersL() + { + PRINT_ENTRY; + if ( iOutputFreeBuffer ) + { + for ( TInt i = 0 ; i < KMaxOutputBuffers; i++ ) + { + if ( ( iOutputFreeBuffer + i )->iHeader ) + { + delete ( iOutputFreeBuffer + i )->iHeader; + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete + ( TUint8* )( iOutputFreeBuffer + i )->iData.iRawData->Ptr(); + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete ( iOutputFreeBuffer + i )->iData.iRawData; + } + } + delete [] iOutputFreeBuffer; + } + for ( TInt i = 0; i < iOutputFreeBufferQueue.Count(); i++ ) + { + iOutputFreeBufferQueue.Remove( 0 ); + } + + // Create the output Buffer( s ) and buffers to engine + iOutputFreeBuffer = new ( ELeave ) TVideoPicture[KMaxOutputBuffers]; + TInt i; + for ( i = 0 ; i < KMaxOutputBuffers; i++ ) + { + ( iOutputFreeBuffer + i )->iData.iRawData = NULL; + ( iOutputFreeBuffer + i )->iHeader = NULL; + } + + for ( i = 0 ; i < KMaxOutputBuffers; i++ ) + { + TUint8* ptr; + TPtr8* temp; + + ptr = new ( ELeave ) TUint8[iOutputBufferSize]; + CleanupStack::PushL( ptr ); + temp = new ( ELeave ) TPtr8( ptr, 0, iOutputBufferSize ); + CleanupStack::Pop( ptr ); + + ( iOutputFreeBuffer + i )->iData.iRawData = temp; + ( iOutputFreeBuffer + i )->iHeader = + new ( ELeave ) TVideoPictureHeader; + + // kunal + // set the frame widht and height + + ( iOutputFreeBuffer + i )->iData.iDataSize = + TSize( iWidthSource,iHeightSource ); + //Add o/p buffer( s ) to the Queue + iEngine->AddOutput( ( iOutputFreeBuffer + i ) ); + } + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//Gives callbacks to client regarding slice and picture loss +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::SliceAndPictureLoss() + { + PRINT_ENTRY; + TUint firstMacroblock = 0; + TUint numMacroblocks = 0; + TPictureId pictureId; + TUint picLoss = 0; + pictureId.iIdType = TPictureId::EPictureNumber; + + // call back to client regading picture loss + if ( ( iCodec->GetParam( CONTROL_CMD_GET_PICTURELOSSINFO, + ( TAny* )&picLoss ) ) >= KMaxAllowPicLoss ) + iMMFDevVideoPlayProxy->MdvppPictureLoss(); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264decHwDevice::SliceAndPictureLoss, " + " calling callback regarding slice loss" ) ); + + // call back to clinet regarding slice loss + firstMacroblock = iCodec->GetParam( CONTROL_CMD_GET_SLICELOSSINFO, + ( TAny* )&numMacroblocks ); + + if ( ( firstMacroblock != 0 ) || ( numMacroblocks != 0 ) ) + iMMFDevVideoPlayProxy->MdvppSliceLoss( firstMacroblock, + numMacroblocks, + pictureId ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Creates one input Buffer +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::CreateInputBufferL( TUint aBufferSize, + TBool aReallocate ) + { + PRINT_ENTRY; + if ( !aReallocate ) + { + // Create the Buffer and add it to Queue + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + TInt* lastBufferFlag = new ( ELeave ) TInt[sizeof( TInt )]; + iInputFreeBuffers[iNumberOfInputBuffersAllocated].iData.Set( + ptr, + 0, + aBufferSize ); + iInputFreeBuffers[iNumberOfInputBuffersAllocated].iUser = + ( TAny* )lastBufferFlag; + iInputFreeBufferQueue.Append( + iInputFreeBuffers + iNumberOfInputBuffersAllocated ); + iNumberOfInputBuffersAllocated++; + } + + else // input buffers are already created and do reallocation here + { + TVideoInputBuffer* inBuffer = iInputFreeBufferQueue[0]; + // check the size of the current with the size of the buffer + //present in i/p Q + if ( aBufferSize > inBuffer->iData.MaxLength() ) + { + // delete the previous buffer + delete [] ( TUint8* )inBuffer->iData.Ptr(); + delete inBuffer->iUser; + + // reallocate the buffer + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + TInt* lastBufferFlag = new ( ELeave ) TInt[sizeof( TInt )]; + inBuffer->iData.Set( ptr, 0, aBufferSize ); + inBuffer->iUser = ( TAny* )lastBufferFlag; + } + } + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//When InputEnd is called while the hw device in Stopping State. +//--------------------------------------------------------------------------- +// +void CAriH264decHwDevice::HandleInputEndInStopping() + { + PRINT_ENTRY; + if ( iState->IsInputEndPending() ) + { + iPictureNumber = 0; + // Stop & Reset the Engine + iEngine->Stop(); + iBufferAdded = EFalse; + iFilledBufferCounter = 0; + iInputEndCalled = EFalse; + TInt error = iState->Transit( CStateMachine::EStopCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + } + PRINT_EXIT; + } + + +const TImplementationProxy ImplementationTable[] = + { + //IMPLEMENTATION_PROXY_ENTRY( 0x20029903, CAriH264decHwDevice::NewL ) + IMPLEMENTATION_PROXY_ENTRY( KUidH264DecoderHwDeviceImplUid, + CAriH264decHwDevice::NewL ) + }; + + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = + sizeof( ImplementationTable ) / sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } + + +#ifndef EKA2 +GLDEF_C TInt E32Dll( TDllReason ) + { + return KErrNone; + } + +#endif + diff -r 000000000000 -r bb31fbe78861 h264_dec/arih264decwrapper/export_hdr/arih264decwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_dec/arih264decwrapper/export_hdr/arih264decwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Header file to the H264 Decoder wrapper Implementation. +* +*/ + +#ifndef ARIH264DECWRAPPER_H +#define ARIH264DECWRAPPER_H + +// INCLUDES +#include +#include +#include +#include "aribasecodec.h" +#include "ariprint.h" + +// FORWARD DECLARATIONS +class TUncompressedVideoFormat; +class TVideoInputBuffer; +class TVideoPictureHeader; + +enum TSetCommands +{ + CONTROL_CMD_SET_TIMESTAMP +}; + +enum TGetCommands +{ + CONTROL_CMD_GET_SLICELOSSINFO, + CONTROL_CMD_GET_PICTURELOSSINFO, + CONTROL_CMD_GET_OUTPUTBUFFERLENGTH +}; + +const TInt KMaxFrameWidth = 640;//should be 1280 for enabling 720P decoding; +const TInt KMaxFrameHeight = 480;//should be 720 for enabling 720P decoding; + +/** + * Class CAriH264decWrapper + * This class is part of Aricent's H264 decoder wrapper used by the H264 + * This HwDevice Plugin to decode H264 content to yuv420. + * + */ +class CAriH264decWrapper: public CBase, public MBaseCodec + { + + public:// Constructor and Destructor + + /** + * Two-phased constructor. + @param "aInputFormat" "type of input format, decides packetmode + or framemode". + @param "aOutputFormat" "supported output formats". + @param "aInpBuf" "configuration data required to create the + decoder". + + @leave "The method will leave if an error occurs". + + * @return pointer to an instance of CAriH264decWrapper + */ + IMPORT_C static CAriH264decWrapper* NewL( + TVideoDataUnitType &aInputFormat, + TUncompressedVideoFormat &aOutputFormat, + const TDesC8* aInpBuf, TInt aStreamType); + + /** + * Destructor + */ + virtual ~CAriH264decWrapper(); + + + public:// MBaseCodec functions + + /** + Retrieves a custom interface to the specified hardware device + + @param "aInpBuf" "Coded input data passed by Engine". + @param "aOutBuf" "Decoded output data". + + @leave "The method will leave if an error occurs". + + @return one of the TCodecState + */ + virtual TInt DoProcessL ( TAny *aInpBuf, TAny* aOutBuf = NULL ) = 0; + + /** + Resets the Decoder + @return None + */ + virtual void Reset () = 0; + + public: // New Functions + virtual TInt SetParam (TInt aCommand, TAny* aCmdData) = 0; + virtual TInt GetParam (TInt aCommand, TAny* aCmdData) = 0; + + /** + Gets the header info + @param "aDataUnit" "Input stream data". + @param "aHeaderPtr" "Output header information returned". + + @leave "The method will leave if an error occurs + KErrArgument - input data is null or zero length + KErrCorrupt - input stream is corrupt + KErrUnderflow - input stream is insufficient". + */ + IMPORT_C + static void GetHeaderInfoL(TVideoInputBuffer& aDataUnit, + TVideoPictureHeader& aHeaderPtr); + }; + +#endif //ARIH264DECWRAPPER_H diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/group/arih264enchwdevice.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/group/arih264enchwdevice.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,55 @@ + +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for H264 encoder. The file specifies the +* include paths, source files and libraries to be used to build the +* H264 encoder plugin binaries. +* +*/ + +#include +#include "../inc/arih264enchwdeviceuids.hrh" + +TARGET arih264enchwdevice.dll +TARGETTYPE PLUGIN + +UID 0x10009D8D KUidH264EncoderHwDeviceDllUid + +CAPABILITY All -TCB + +SOURCEPATH ../src +SOURCE arih264enchwdeviceimpl.cpp +START RESOURCE 20001C12.rss +TARGET arih264enchwdevice.rsc +END + +MACRO LOGLEVEL_CRITICAL + +USERINCLUDE ../inc +USERINCLUDE ../../../utilities/ariprocessengine/inc +USERINCLUDE ../../../utilities/aristatemachine/inc +USERINCLUDE ../../../utilities/log +USERINCLUDE ../../arih264encwrapper/export_hdr + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\devvideo +SYSTEMINCLUDE \epoc32\include + +LIBRARY euser.lib +LIBRARY devvideo.lib +LIBRARY aristatemachine.lib +LIBRARY ariprocessengine.lib +LIBRARY arih264encwrapper.lib diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,31 @@ + +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for H264 encoder HwDevice plugin. This file specifies the +* mmp to be used to build the H264 encoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +winscw armv5 armv6 + +PRJ_MMPFILES + +// H264 Encoder HwDevice Plugin +arih264enchwdevice.mmp + +//----------------------------------------------------------------------------- +// End of BLD.INF +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/inc/arih264encconfigdataci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/inc/arih264encconfigdataci.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* User defined encoder init data custom interface for H264 encoder plugin. +* +*/ + +/** +* Example of the CI usage: +* 1. Create CI. +* MH324AnnexKDefinedEncoderConfigDataCI* userConfigCI = NULL; +* userConfigCI = (MH324AnnexKDefinedEncoderConfigDataCI*) +* iDevvrInstance->CustomInterface( hwdevUid, +* KH324AnnexKDefinedEncoderConfigDataCIUid ); +* +* CDEVVRVideoRecord iDevvrInstance - The instance of the DeviceVideoRecord; +* TUid hwdevUid - Encoder HwDevice Uid; +* KH324AnnexKDefinedEncoderConfigDataCIUid - Custom Interface Uid; +* +* +* 2. TInt status = userConfigCI->H324AnnexKDefinedEncoderConfigDataOn(); +* +* if ( status != KErrNone ) +* { +* // handle error +* } +* +* 3. This CI API H324AnnexKDefinedEncoderConfigDataOn() can only be called +* before the initializing phase (Before Initialize() method is called by +* DevVideo). +* +*/ + +#ifndef ARIH264ENCCONFIGDATACI_H +#define ARIH264ENCCONFIGDATACI_H + + +// CONSTANTS +// Custom Interface UId +const TUid KH324AnnexKDefinedEncoderConfigDataCIUid = {0x10204C0B}; + +// CLASS DECLARATION +/** + * User defined encoder confguration data custom interface + */ +class MH324AnnexKDefinedEncoderConfigDataCI + { + public: + + /** + * Enables inserting H324 pre-defind config data (VOL / SPS PPS / etc.) + * @param none + * @return KErrNone - Success, otherwise KErrGeneral - Error, unable + * to process operation + */ + virtual TInt H324AnnexKDefinedEncoderConfigDataOn() = 0; + + }; + + +#endif // ARIH264ENCCONFIGDATACI_H diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/inc/arih264enchwdeviceimpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/inc/arih264enchwdeviceimpl.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,1128 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Declares plugin class for H264 encoder HwDevice. This class inherits from +* CMMFVideoEncodeHwDevice and implements the pure virtual functions.The class +* also contains implementation specific private methods. +* +*/ + +#ifndef ARIH264ENCHWDEVICEIMPL_H +#define ARIH264ENCHWDEVICEIMPL_H + +#include +#include +#include + +#include "arivideoenccommon.h" +#include "aristatemachine.h" +#include "aribaseengine.h" +#include "arih264enchwdeviceuids.hrh" +#include "ariprint.h" + +//Custom interface +#include "arih264encconfigdataci.h" + +// Forward declarations +class CBaseEngine; +class CAriH264encWrapper; + + +/** + * This class is part of Aricent's H264 encoder HwDevice plugin used + * for encoding yuv420 input to H264 content. + * Provides implementation for standard MDF HwDevice plugin APIs as well as + * private functions used internal to this class for .This class also + * implements callback APIs from MProcessEngineObserver which are called from + * CBaseEngine. + */ + +class CAriH264encHwDeviceImpl: public CMMFVideoEncodeHwDevice, + public MProcessEngineObserver, + public MH324AnnexKDefinedEncoderConfigDataCI +{ + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriH264encHwDeviceImpl + * @leave "The method will leave if an error occurs" + */ + static CAriH264encHwDeviceImpl* NewL(); + + /**> Destructor */ + ~CAriH264encHwDeviceImpl(); + +public: + /** + * From CMMFVideoHwDevice + * The function retrieves a custom interface to the HwDevice. + * @param aInterface + * UID of the interface to be retrieved. It is defined with the custom + * interface + * @return returns pointer to the interface + */ + TAny* CustomInterface( TUid aInterface ); + +public: + /** + * From CMMFVideoEncodeHwDevice + * The function retrieves information about the video encoder + * @return returns pointer to the object with encoder information + * @leave "The method will leave if an error occurs" + */ + CVideoEncoderInfo* VideoEncoderInfoLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder output format. + * @param aFormat + * UID of the interface to be retrieved. It is defined with the custom + * interface + * @param aDataUnitType + * The type of output coded data units + * @param aDataEncapsulation + * Data encapsulation type for output encoded data units + * @param aSegmentationAllowed + * Indicates if segmentation is allowed or not + * @leave "The method will leave if an error occurs" + */ + void SetOutputFormatL( const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aDataEncapsulation, + TBool aSegmentationAllowed=EFalse ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the pre-processor hwdevice that will write data to + * this encoder. + * @param aDevice + * Pre-processor device that will write to this encoder + */ + void SetInputDevice( CMMFVideoPreProcHwDevice* aDevice ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the number of bit-rate scalability layers to use. + * @param aNumLayers + * The number of bit-rate scalability layers to use + * @leave "The method will leave if an error occurs" + */ + void SetNumBitrateLayersL( TUint aNumLayers ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the scalability type for a bit-rate scalability layer + * @param aLayer + * The layer number + * @param aScalabilityType + * Layer scalability type + * @leave "The method will leave if an error occurs" + */ + void SetScalabilityLayerTypeL( TUint aLayer, + TScalabilityType aScalabilityType); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the reference picture options to be used for all + * scalability layers + * @param aMaxReferencePictures + * Maximum number of reference pictures to be used + * @param aMaxPictureOrderDelay + * The maximum picture order delay, in number of pictures. + */ + void SetGlobalReferenceOptions(TUint aMaxReferencePictures, + TUint aMaxPictureOrderDelay); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the reference picture options to be used for a + * particular scalability layer + * @param aLayer + * The layer number + * @param aMaxReferencePictures + * Maximum number of reference pictures to be used for this layer + * @param aMaxPictureOrderDelay + * The maximum picture order delay for this layer, in number of + * pictures. + */ + void SetLayerReferenceOptions( TUint aLayer,TUint aMaxReferencePictures, + TUint aMaxPictureOrderDelay ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder buffering options + * @param aOptions + * Buffering options to be used + * @leave "The method will leave if an error occurs" + */ + void SetBufferOptionsL( const TEncoderBufferOptions& aOptions ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder output rectangle + * @param aRect + * Output rectangle to be used + * @leave "The method will leave if an error occurs" + */ + void SetOutputRectL( const TRect& aRect ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder whether bit errors or packets losses + * can be expected in the video transmission + * @param aBitErrors + * Boolean to indicate if bit errors can be expected + * @param aPacketLosses + * Boolean to indicate if packet losses can be expected + */ + void SetErrorsExpected( TBool aBitErrors, TBool aPacketLosses ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the minimum random access rate to be used + * @param aRate + * The minimum random access rate + */ + void SetMinRandomAccessRate(TReal aRate); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the coding standard specific options to be used. + * @param aOptions + * Coding standard specific options to be used + * @leave "The method will leave if an error occurs" + */ + void SetCodingStandardSpecificOptionsL( const TDesC8& aOptions ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the implementation specific options to be used + * @param aOptions + * Implementation specific options to be used. + * @leave "The method will leave if an error occurs" + */ + void SetImplementationSpecificEncoderOptionsL( const TDesC8& aOptions ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function returns coding-standard specific initialization output + * from the encoder + * @return Returns the pointer to buffer holding coding-standard specific + * initialization output + * @leave "The method will leave if an error occurs" + */ + HBufC8* CodingStandardSpecificInitOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the implementation specific initialization output from + * the encoder + * @return Returns the pointer to buffer holding implementation specific + * initialization output + * @leave "The method will leave if an error occurs" + */ + HBufC8* ImplementationSpecificInitOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function the number of unequal error protection levels. + * @param aNumLevels + * The number of unequal error protection levels to be used + * @param aSeparateBuffers + * Boolean indicating whether each unequal error protection level of a + * coded data unit shall be encapsulated in its own output buffer + * @leave "The method will leave if an error occurs" + */ + void SetErrorProtectionLevelsL( TUint aNumLevels, + TBool aSeparateBuffers ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function the number of unequal error protection levels. + * @param aNumLevels + * The number of unequal error protection levels to be used + * @param aSeparateBuffers + * Boolean indicating whether each unequal error protection level of a + * coded data unit shall be encapsulated in its own output buffer + * @param aStrength + * Forward error control strength for this error protection level + * @leave "The method will leave if an error occurs" + */ + void SetErrorProtectionLevelL( TUint aLevel, TUint aBitrate, + TUint aStrength ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the expected or prevailing channel conditions for an + * unequal error protection level in terms of expected packet loss rate. + * @param aLevel + * Error protection level number + * @param aLossRate + * Packet loss rate, in number of packets lost per second. + * @param aLossBurstLength + * Expected average packet loss burst length + */ + void SetChannelPacketLossRate( TUint aLevel, TReal aLossRate, + TTimeIntervalMicroSeconds32 aLossBurstLength ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the expected or prevailing channel conditions for an + * unequal error protection level, in terms of expected bit error rate + * @param aLevel + * Error protection level number + * @param aErrorRate + * Expected bit error rate + * @param aStdDeviation + * Expected bit error rate standard deviation + */ + void SetChannelBitErrorRate( TUint aLevel, TReal aErrorRate, + TReal aStdDeviation ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the segment size. To be used only for packet mode + * @param aLayer + * Layer number + * @param aSizeBytes + * Segment size in bytes + * @param aSizeMacroblocks + * Size of the macro blocks + */ + void SetSegmentTargetSize( TUint aLayer, TUint aSizeBytes, + TUint aSizeMacroblocks ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the bit-rate control options for a layer + * @param aLayer + * Bit-rate scalability layer number + * @param aOptions + * Bit-rate control options to be used + */ + void SetRateControlOptions(TUint aLayer, + const TRateControlOptions& aOptions); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the in-layer scalability options for a layer + * @param aLayer + * Bit-rate scalability layer number + * @param aNumSteps + * The number of in-layer scalability steps to use + * @param aScalabilityType + * Bit-rate share for each scalability step + * @param aBitrateShare + * Picture rate share for each scalability step + * @param aPictureShare + * The scalability type to use + * @leave "The method will leave if an error occurs" + */ + void SetInLayerScalabilityL( TUint aLayer,TUint aNumSteps, + TInLayerScalabilityType aScalabilityType, + const TArray& aBitrateShare, + const TArray& aPictureShare ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the segment size. To be used only for packet mode + * @param aLayer + * Layer number + * @param aPeriod + * The number of in-layer scalability steps to use + */ + void SetLayerPromotionPointPeriod( TUint aLayer, TUint aPeriod ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the coding-standard specific settings output from the + * encoder + * @return Returns the pointer to buffer holding coding-standard specific + * settings output + * @leave "The method will leave if an error occurs" + */ + HBufC8* CodingStandardSpecificSettingsOutputLC(); + + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the Implementation specific settings output from the + * encoder + * @return Returns the pointer to buffer holding Implementation specific + * settings output + * @leave "The method will leave if an error occurs" + */ + HBufC8* ImplementationSpecificSettingsOutputLC(); + + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to send supplemental information in + * the bit stream + * @param aData + * Supplemental information data to send + * @leave "The method will leave if an error occurs" + */ + void SendSupplementalInfoL( const TDesC8& aData ); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to send supplemental information in + * the bit stream + * @param aData + * Supplemental information data to send + * @param aTimestamp + * Timestamp for the picture in which the supplemental information + * should be included + * @leave "The method will leave if an error occurs" + */ + void SendSupplementalInfoL( const TDesC8& aData, + const TTimeIntervalMicroSeconds& aTimestamp ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to cancel the current supplemental + * information send request + */ + void CancelSupplementalInfo(); + + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the current output buffer status + * @param aNumFreeBuffers + * Target for the number of free output buffers + * @param aTotalFreeBytes + * Target for the total free buffer size in bytes + */ + void GetOutputBufferStatus( TUint& aNumFreeBuffers, + TUint& aTotalFreeBytes ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function returns a used output buffer back to the encoder + * @param aBuffer + * The buffer to be returned + */ + void ReturnBuffer( TVideoOutputBuffer* aBuffer ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder that a picture loss has occurred + * without specifying the lost picture. + */ + void PictureLoss(); + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder that a picture loss has occurred + * @param aPictures + * Picture identifiers of lost pictures + */ + void PictureLoss(const TArray& aPictures); + + + /** + * From CMMFVideoEncodeHwDevice + * The function notify the encoder that slice loss has occurred, giving + * the details of the macroblocks and the picture to which they belong + * @param aFirstMacroblock + * The first lost macroblock. + * @param aNumMacroblocks + * The number of macroblocks in the lost slice + * @param aPicture + * The picture identified for the picture where the slice was lost + */ + void SliceLoss( TUint aFirstMacroblock, TUint aNumMacroblocks, + const TPictureId& aPicture ); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to use reference picture selection + * @param aSelectionData + * The reference picture selection request message + */ + void ReferencePictureSelection(const TDesC8& aSelectionData); + + +public: + + /** + * From CMMFVideoRecordHwDevice + * The function initializes the encoder HwDevice with the configuration + * settings and reserve + * the hardware resources required + */ + void Initialize(); + + + /** + * From CMMFVideoRecordHwDevice + * The function commits all changes since the last CommitL(), Revert() or + * Initialize() to the hardware device + * @leave "The method will leave if an error occurs" + */ + void CommitL(); + + + /** + * From CMMFVideoRecordHwDevice + * The function reverts all changes since the last CommitL(), Revert() or + * Initialize() + * back to their previous settings. + */ + void Revert(); + + + /** + * From CMMFVideoRecordHwDevice + * The function writes an uncompressed input picture + * @param aPicture + * The picture to write + * @leave "The method will leave if an error occurs" + */ + void WritePictureL( TVideoPicture* aPicture ); + + + /** + * From CMMFVideoRecordHwDevice + * The function notifies the hardware device that the end of input data + * has been reached. + */ + void InputEnd(); + + /** + * From CMMFVideoRecordHwDevice + * The function starts recording video. + */ + void Start(); + + static TInt TimerCallBack( TAny* aPtr ); + + /** + * From CMMFVideoRecordHwDevice + * The function stops recording video + */ + void Stop(); + + /** + * From CMMFVideoRecordHwDevice + * The function pauses video recording. + */ + void Pause(); + + + /** + * From CMMFVideoRecordHwDevice + * The function resumes video recording after a pause. + */ + void Resume(); + + + /** + * From CMMFVideoRecordHwDevice + * The function freezes the input picture + */ + void Freeze(); + + + /** + * From CMMFVideoRecordHwDevice + * The function releases a frozen input picture. + */ + void ReleaseFreeze(); + + + /** + * From CMMFVideoRecordHwDevice + * The function returns the current recording position + * @return Returns the current recording position + */ + TTimeIntervalMicroSeconds RecordingPosition(); + + + /** + * From CMMFVideoRecordHwDevice + * The function reads various counters related to processed video pictures + * @param aCounters + * The counter structure to fill + */ + void GetPictureCounters( CMMFDevVideoRecord:: + TPictureCounters& aCounters ); + + /** + * From CMMFVideoRecordHwDevice + * The function reads the frame stabilisation output picture position + * @param aRect + * Output rect which holds frame stabilisation output + */ + void GetFrameStabilisationOutput( TRect& aRect ); + + + + /** + * From CMMFVideoRecordHwDevice + * The function retrieves the number of complexity control levels + * available for this hardware device + * @return Returns the number of complexity level + */ + TUint NumComplexityLevels(); + + + /** + * From CMMFVideoRecordHwDevice + * The function sets the complexity level to use for video processing in a + * hardware device + * @param aLevel + * The computational complexity level to use. + */ + void SetComplexityLevel( TUint aLevel ); + + /** + * From CMMFVideoRecordHwDevice + * The function gets the information about the pre-processing capabilities + * of the encoder hwdevice + * @return Returns the pointer to object holding preprocessor info + * @leave "The method will leave if an error occurs" + */ + CPreProcessorInfo* PreProcessorInfoLC(); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the hardware device input format + * @param aFormat + * The input format to use + * @param aPictureSize + * The input picture size in pixels + * @leave "The method will leave if an error occurs" + */ + void SetInputFormatL( const TUncompressedVideoFormat& aFormat, + const TSize& aPictureSize ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the data source to be a camera + * @param aCameraHandle + * Camera handle to be used + * @param aPictureRate + * Video capture frame rate + * @leave "The method will leave if an error occurs" + */ + void SetSourceCameraL( TInt aCameraHandle, TReal aPictureRate ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the data source to be memory buffers + * @param aMaxPictureRate + * The maximum picture rate for input pictures. + * @param aConstantPictureRate + * Flag indicating if picture rate is constant or not + * @param aProcessRealtime + * Flag indicating real time processing should be done or not + * @leave "The method will leave if an error occurs" + */ + void SetSourceMemoryL( TReal aMaxPictureRate, TBool aConstantPictureRate, + TBool aProcessRealtime ); + + /** + * From CMMFVideoRecordHwDevice + * The function enables synchronized encoding and set the clock source to + * use for synchronization. + * @param aClock + * Clock source to be used. + */ + void SetClockSource( MMMFClockSource* aClock ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for RGB to YUV color space + * conversion + * @param aRange + * Input RGB data range + * @param aOutputFormat + * Conversion output YUV format + * @leave "The method will leave if an error occurs" + */ + void SetRgbToYuvOptionsL( TRgbRange aRange, + const TYuvFormat& aOutputFormat); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for YUV to YUV data format + * conversion + * @param aRange + * Conversion input format + * @param aOutputFormat + * Conversion output YUV format + * @leave "The method will leave if an error occurs" + */ + void SetYuvToYuvOptionsL( const TYuvFormat& aInputFormat, + const TYuvFormat& aOutputFormat ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the pre-processing types to be used + * @param aPreProcessTypes + * The pre-processing steps to perform, a bitwise OR of values from + * TPrePostProcessType + * @leave "The method will leave if an error occurs" + */ + void SetPreProcessTypesL( TUint32 aPreProcessTypes ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for rotation + * @param aRotationType + * The rotation to perform + * @leave "The method will leave if an error occurs" + */ + void SetRotateOptionsL( TRotationType aRotationType ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for scaling. + * @param aTargetSize + * Target picture size. + * @param aAntiAliasFiltering + * True if anti-aliasing filtering should be used + * @leave "The method will leave if an error occurs" + */ + void SetScaleOptionsL( const TSize& aTargetSize, + TBool aAntiAliasFiltering ); + + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for input cropping. + * @param aRect + * The input cropping rectangle specifying the area of the picture to + * use + * @leave "The method will leave if an error occurs" + */ + void SetInputCropOptionsL( const TRect& aRect ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for output cropping. + * @param aRect + * The output cropping rectangle specifying the area of the picture to + * use + * @leave "The method will leave if an error occurs" + */ + void SetOutputCropOptionsL( const TRect& aRect ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for output padding + * @param aOutputSize + * The padded output picture size. + * @param aPicturePos + * The position for the original picture in the new padded picture. + * @leave "The method will leave if an error occurs" + */ + void SetOutputPadOptionsL( const TSize& aOutputSize, + const TPoint& aPicturePos ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets color enhancement pre-processing options. + * @param aOptions + * Color enchancement options + * @leave "The method will leave if an error occurs" + */ + void SetColorEnhancementOptionsL( + const TColorEnhancementOptions& aOptions); + + /** + * From CMMFVideoRecordHwDevice + * The function sets frame stabilisation options + * @param aOutputSize + * Output picture size. + * @param aFrameStabilisation + * True if frame stabilisation should be used + * @leave "The method will leave if an error occurs" + */ + void SetFrameStabilisationOptionsL( const TSize& aOutputSize, + TBool aFrameStabilisation ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets custom implementation-specific pre-processing options + * @param aOptions + * Post-processing options + * @leave "The method will leave if an error occurs" + */ + void SetCustomPreProcessOptionsL( const TDesC8& aOptions ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the proxy implementation to be used + * @param aProxy + * The proxy to use + */ + void SetProxy( MMMFDevVideoRecordProxy& aProxy ); + +public: + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the input buffer is consumed + * @param aInp + * Pointer to the input picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + TInt InputBufferConsumed( TAny* aInp, TInt aError); + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the output buffer is ready + * @param aOup + * Pointer to the output picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + TInt OutputBufferReady( TAny* aOup, TInt aError ); + + /** + * From MProcessEngineObserver + * The function indicates to hwdevice that process engine has finished + * with the processing of command requested by hwdevice + * @param aCmd + * Command that has been processed by process engine + * @param aCmdData + * Pointer to command data that has been processed by process engine + * @param aError + * Error code corresponding to the command + */ + void CommandProcessed( TInt aCmd, TAny* aCmdData, TInt aError ); + + /** + * From CMMFVideoEncodeHwDevice + * The function indicates to hwdevice that process engine has met with an + * unrecoverable error during its processing + * @param aError + * The fatal error code + */ + void FatalErrorFromProcessEngine( TInt aError ); + +public: // Inherited from MH324AnnexKDefinedEncoderConfigDataCI + + /** + * From CMMFVideoEncodeHwDevice + * The function enables inserting H324 AnnexK pre-defined config data + * (VOL / SPS PPS / etc. ) + * @param aError + * Symbian wide error code + */ + TInt H324AnnexKDefinedEncoderConfigDataOn(); + +private: + + /** + * The function is the default constructor for class + * CAriH264encHwDeviceImpl + */ + CAriH264encHwDeviceImpl(); + + /** + * Symbian 2 phase constructor + */ + void ConstructL(); + + /** + * Updates the time periodically i.e gets the clock source values from + * client + * @return returns system wide error code on error + */ + TInt UpdateTime(); + + /** + * Creates coded Output buffers for the hw device. + * @param aSize + * Size of buffers to be created + */ + void CreateCodedOutputBuffersL( TUint aSize ); + + /** + * Creates Internal buffers in segment mode, to hold the complete + * encoded frame returned from the codec + * @param aSize + * Size of buffers to be created + */ + void CreateInternalOutputBuffersL( TUint aBufferSize ); + + + /** + * Creates packet offset info buffers + * @param aSize + * Size of buffers to be created + */ + void CreatePacketOffsetLengthInfoBuffersL( TUint aSize ); + + + /** + * Decides whether this input picture can be encoded or not + * @param aPicture + * Pointer to the input picture + */ + TBool CanEncode( TVideoPicture *aPicture ); + + + /** + * Input picture is not processed, returned back to client + * @param aPicture + * Pointer to the input picture + */ + void SkipInputPicture( TVideoPicture *aPicture ); + + /** + * Checks whether this input picture is coded as i-frame or not + * @param aPicture + * Pointer to the input picture + */ + TBool IsForcedIFrameRequired( TVideoPicture* aPicture ); + + + /** + * Fills one segment data from the internal buffer to output buffer + * @param aOutBuf + * Destination buffer to hold the packet + * @param aSrcBuf + * Buffer which contains encoder output frame + */ + void FillVideoSegment( TVideoOutputBuffer* aOutBuf, + TVideoOutputBuffer* aSrcBuf ); + + + /** + * Initializes the members of the output coded buffers created + * @param aOutputBuffer + * Output buffer for which members are to be initialized + */ + void InitializeOuputCodedBuffer( TVideoOutputBuffer& aOutputBuffer ); + + + /** + * Sets level and bitrate based on picture size information + */ + void SetLevelAndBitRate(); + + + /** + * Checks if the specified input format is supported or not + * @param aFormat + * Input format to be checked + * @return Returns True if input format is supported else false + */ + TBool CheckInputFormat( const TUncompressedVideoFormat& aFormat ); + + /** + * Notifies the client that the hw device has encountered with error + * @param aError + * Error code indicating type of fatal error + */ + void ClientFatalError (TInt aError); + + /** + * Reallocates the segment buffers happens only when segment size is + * set more than exsisting size. + */ + void ReallocSegmentOutputBuffersL(TUint aSize); + + /** + * Reallocates the segment buffer, this buffer is returned by client + * and need reallocation(i.e segment size has been changed) + */ + void ReallocateSegmentBufferL(TVideoOutputBuffer* aBuffer); + + + /** + * Creates one internal buffer when hw device is changed from frame mode + * to packet mode + */ + void CreateCodedBufferForModeChangeL(); + + /** + * Creates segment buffers in packet mode + * + */ + void CreateSegmentOutputBuffersL(TUint aNumoOfBuffers, TUint aSize); + + // Calculates instant bitrate averaged per 1 second on-the-fly + void CalculateInstantBitRate(const TVideoOutputBuffer &aOutBuf); + TInt iCurrentIntTS; + TInt iStreamSize; + +private: + + // handle to proxy i.e observer + MMMFDevVideoRecordProxy* iMMFDevVideoRecordProxy; + + // handle to preprocessor hw device + CMMFVideoPreProcHwDevice* iInputDevice; + + // reference to clock source if client + MMMFClockSource* iClockSource; + + // flag to indicate whether the buffer is returned to inputdevice + TBool iInputBufReturnToPreProc; + + // Hold all the parameters before initailize. + TH264EncInitParams iH264EncInitParams; + + // hold the parameters that are required after initialize + TH264EncInitParams iCurSetH264EncParams; + + // state machine object + CStateMachine* iEncStateMac; + + // All levels information is stored + RArray iLevels; + + // Supported Input format information + RArray iSupportedInputFormats; + + // Supported output formats information + RArray iSupportedOutputFormats; + + // all supported data unit types + TUint32 iSupportedDataUnitTypes; + + // all supported data unit encapsulation + TUint32 iSupportedDataUnitEncapsulations; + + // Timer for updates + CPeriodic* iPeriodicTimer; + + // Stores tha value when clock is paused + TInt64 iClockTimeWhenPaused; + + // Polling interval to be used + TTimeIntervalMicroSeconds32 iPollingInterval; + + // Codec Reference + CAriH264encWrapper* iCodec; + + // Base Process Engine Reference + CBaseEngine* iEngine; + + // Output Free buffers can be segment or coded buffers + TVideoOutputBuffer* iOutputBuffers; + + // output buffer queue + RPointerArray iOutputFreeBufferQueue; + + // output buffer size of the coded picture + TInt iOutputBufferSize; + + + // pause offset i.e offset between pause and resume + TInt64 iPauseOffset; + + // total time deviation from client clock source + TInt64 iTotalTime; + + // last encoded picture time stamp + TInt64 iLastEncodedPictureTimestamp; + + // Incdicates picture loss + TBool iPictureLoss; + + // indicates input end called + TBool iInputEndCalled; + + //Picture Counters + CMMFDevVideoRecord::TPictureCounters iPictureCounters; + + // freeze machine object + TBool iFrozen; + + // current postion in the coded frame in packet mode + TUint iTotalLengthFilledSoFarInPacketMode; + + // Total Output buffer Length of the coded picture in packet mode + TUint iTotalOutputBufferLengthInPacketMode; + + // Current position in the offset buffer + TUint* iPacketOffSetCurrentPosition; + + // holds offsets and length information array + TUint** iPacketOffSetAndLengthInfoBuffers; + + // free buffer queue for packet offset information + RPointerArray iFreeBufferQueueForPacketOffsetInfo; + + // filled buffer queue for packet offset information + RPointerArray iFilledBufferQueueForPacketOffsetInfo; + + // Temporary output buffers + TVideoOutputBuffer* iInternalOutputBuffers; + + // holds temporary o/p buffers + RPointerArray iInternalOutputBufferQueue; + + // represents the num of buffers at client in segment mode + TUint iNumOfBuffersAtClientInPacketModeNeedReAllocation; + + TBool iPacketsPending; + + // represents the no of buffers curretly avaible with the hw device + TUint iNumOfOutBuffersAvailableInPacketModeChange; + + // Count to represent the num of buffers pending from client + TUint iNumofBuffersPendingFromClientInChangeToPacketMode; + + // Counn the num of o/p buffers in hw before change to pkt mode + TUint iNumOfOutBuffersBeforeChangeToPacketMode; + + // Extra buffer to hold coded pciture from codec created when no buffers + // are with hw device + TVideoOutputBuffer* iCodedBufferForPacketModeChange; + + // reference to segment buffers + TVideoOutputBuffer* iSegmentBuffers; + + // whether config data to be filled in first buffer or not + TBool iIsConfigDataFilledInFirstOutputBuffer; + //whether slice header is enabled in CodedPicture format + TBool iIsSliceEnabledInCodedPicture; + //No of frames encoded per second + TInt iNoOfOutputFramesPerSec; + + //Size of each frame that's been encoded + TInt iSizePerFrame; + + HBufC8* iConfigData; + TUint iMaxNumOfPackets; + TBool iFirstTime; +}; + +#endif //__H264ENCHWDEVICEIMPL_H__ diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/inc/arih264enchwdeviceuids.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/inc/arih264enchwdeviceuids.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the Uids used in H264 encoder plugin. +* +*/ + +#ifndef ARIH264ENCHWDEVICEUIDS_H +#define ARIH264ENCHWDEVICEUIDS_H + +#define KUidH264EncoderHwDeviceImplUid 0x2002AD85 +#define KUidH264EncoderHwDeviceDllUid 0x2002AD86 + + +#endif //ARIH264ENCHWDEVICEUIDS_H diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/inc/arih264hwdeviceconstants.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/inc/arih264hwdeviceconstants.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the constants used in H264 encoder plugin. +* +*/ + +#ifndef ARIH264HWDEVICECONSTANTS_H +#define ARIH264HWDEVICECONSTANTS_H + +// Compressed H264 Video Formats Supported +_LIT8(KH264MimeType, "video/H264"); +_LIT8(KH264MimeType2, "video/H264; profile-level-id=42800A"); +_LIT8(KH264MimeType3, "video/H264; profile-level-id=42800B"); +_LIT8(KH264MimeType4, "video/H264; profile-level-id=42800C"); +_LIT8(KH264MimeType5, "video/H264; profile-level-id=42800D"); +_LIT8(KH264MimeType6, "video/H264; profile-level-id=428014"); +_LIT8(KH264MimeType7, "video/H264; profile-level-id=428015"); +_LIT8(KH264MimeType8, "video/H264; profile-level-id=428016"); +_LIT8(KH264MimeType9, "video/H264; profile-level-id=42801E"); +_LIT8(KH264MimeType10, "video/H264; profile-level-id=42900B"); + + +_LIT(KH264EncManufacturer,"Aricent"); +_LIT(KH264EncIdentifier, "ARM H264 Video Encoder Hw Device"); + +// 1 SPS and 1 PPS +const TInt KNumOfConfigParams = 2; +// 1 SPS, 1 PPS and 1 SEI +const TInt KNumOfConfigParams_SEI = 3; +// 1 SPS, 1 PPS, 4SEI +const TInt KNumOfNAL_SEI = 6; +const TInt KWordLength = 4; +const TInt KDoubleWordLength = 8; + +const TInt KH264ENCIMPL_MAJOR_VERSION = 1; +const TInt KH264ENCIMPL_MINOR_VERSION = 0; +const TInt KH264ENCIMPL_BUILD_VERSION = 0; + +// Size - width,height related +const TInt KH264ENCIMPL_SQCIF_WIDTH = 128; +const TInt KH264ENCIMPL_SQCIF_HEIGHT = 96; +const TInt KH264ENCIMPL_QCIF_WIDTH = 176; +const TInt KH264ENCIMPL_QCIF_HEIGHT = 144; +const TInt KH264ENCIMPL_QVGA_WIDTH = 320; +const TInt KH264ENCIMPL_QVGA_HEIGHT = 240; +const TInt KH264ENCIMPL_CIF_WIDTH = 352; +const TInt KH264ENCIMPL_CIF_HEIGHT = 288; +const TInt KH264ENCIMPL_VGA_WIDTH = 640; +const TInt KH264ENCIMPL_VGA_HEIGHT = 480; +const TInt KH264ENCIMPL_SDTV_WIDTH = 720; +const TInt KH264ENCIMPL_SDTV_HEIGHT_PAL = 576; +const TInt KH264ENCIMPL_SDTV_HEIGHT_NTSC = 480; +const TInt KH264ENCIMPL_HALFSDTV_WIDTH = 360; +const TInt KH264ENCIMPL_HALFSDTV_HEIGHT_PAL = 288; +const TInt KH264ENCIMPL_HALFSDTV_HEIGHT_NTSC = 240; +const TInt KH264ENCIMPL_720P_HEIGHT = 720; +const TInt KH264ENCIMPL_720P_WIDTH = 1280; + +// Bitrate related (bits per second) +const TInt KH264ENCIMPL_DEFAULT_BITRATE = 64000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_1b = 128000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_1 = 64000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_11 = 192000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_12 = 384000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_13 = 768000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_2 = 2000000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_21 = 4000000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_22 = 4000000; +const TInt KH264ENCIMPL_BITRATE_LEVEL_3 = 10000000; + +// Level related mapping +const TInt KH264ENCIMPL_LEVEL_UNKNOWN = 0; +const TInt KH264ENCIMPL_LEVEL_1b = 9; +const TInt KH264ENCIMPL_LEVEL_1 = 10; +const TInt KH264ENCIMPL_LEVEL_11 = 11; +const TInt KH264ENCIMPL_LEVEL_12 = 12; +const TInt KH264ENCIMPL_LEVEL_13 = 13; +const TInt KH264ENCIMPL_LEVEL_2 = 20; +const TInt KH264ENCIMPL_LEVEL_21 = 21; +const TInt KH264ENCIMPL_LEVEL_22 = 22; +const TInt KH264ENCIMPL_LEVEL_3 = 30; + +// o/p buffer related +const TInt KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS = 2; +const TInt KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS = 2; +const TInt KH264ENCIMPL_MAXNUM_SEGMENTBUFFERS = 30; +const TInt KH264ENCIMPL_FACTOR_FOR_OUTPUTBUFFERSIZE_IN_PACKETMODE = 2; + +// o/p buffer size related +const TInt KH264ENCIMPL_DEFAULT_SEGMENTSIZE = 256; +const TInt KH264ENCIMPL_MIN_SEGMENTSIZE = 192; +const TInt KH264ENCIMPL_MAX_SEGMENTSIZE = 300; + +// Max coded picture size in case of Level 1b +const TInt KH264ENCIMPL_LEVEL1b_MAXCPBSIZE = 39375; +// Max coded picture size in case of Level 1.1 +const TInt KH264ENCIMPL_LEVEL11_MAXCPBSIZE = 56250; + +// picture rate related +const TReal KH264ENCIMPL_MAX_PICTURERATE = 30.0; +const TReal KH264ENCIMPL_DEFAULT_PICTURERATE = 15.0; +const TReal KH264ENCIMPL_PICTURERATE_12_5 = 12.5; +const TReal KH264ENCIMPL_PICTURERATE_25 = 25.0; + +const TInt KH264ENCIMPL_NUM_COMPLEXITYLEVELS = 3; +const TInt KH264ENCIMPL_ENCODEAHEAD = 0; +const TInt KH264ENCIMPL_MAXNUM_REFERENCEPICTURES = 16; + +// Default random access rate - 1 per 3seconds ie 1 after 45 frames at 15 fps +const TInt KH264ENCIMPL_DEFAULT_RANDOMACCESSRATE = 0.3333333; + +// Minimum size of slice in coded picture format. +const TInt KH264ENCIMPL_MIN_SLICESIZE = 200; + +const TInt KPOLLINGINTERVAL = 100000; +const TUint KMAXSUPPBITRATE = 10000000; + +#endif //ARIH264HWDEVICECONSTANTS_H diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/src/20001C12.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/src/20001C12.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for H264 encoder plugin. +* +*/ + +#include "registryinfo.rh" +#include "devvideoplugininterfaceuids.hrh" +#include "arih264enchwdeviceuids.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidH264EncoderHwDeviceDllUid; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidDevVideoEncoderHwDeviceDefine; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidH264EncoderHwDeviceImplUid; + version_no = 1; + display_name = "Aricent H264 Video Enc HwDevice"; + default_data = "video/H264||video/H264; profile-level-id=*"; + opaque_data = "0"; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264enchwdevice/src/arih264enchwdeviceimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264enchwdevice/src/arih264enchwdeviceimpl.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,4779 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of H264 encoder plugin class - +* CAriH264encHwDeviceImpl. +* +*/ + +// System Includes +#include +#include +#include + +// User Includes +#include "arih264enchwdeviceimpl.h" +#include "arih264hwdeviceconstants.h" +#include "arih264encwrapper.h" + + + +// MACRO DEFINITIONS - start + +// Uncomment this flag to enable instant rate calculations on-the-fly in urel +// builds. In UDEB it is enabled automatically +// By default it is commented +//#define CALCINSTANTBITRATE + +// Uncomment to print additional debug information retrieved from +// core encoder +//#define DEBUG_INFO + +// MACRO DEFINITIONS - end + +//---------------------------------------------------------------------------- +// Maps the num/denom from the MDF to the aspect_ratio_idc value supported +//---------------------------------------------------------------------------- +// +TInt32 MapAspectRatio( TUint32 aNumerator, TUint32 aDenominator ) + { + PRINT_ENTRY; + TInt32 aspectratio = -1; + switch ( aDenominator ) + { + case 1: + if ( aNumerator == 1 ) + { + aspectratio = 1; + } + break; + case 11: + switch ( aNumerator ) + { + case 12: + aspectratio = 2; + break; + case 10: + aspectratio = 3; + break; + case 16: + aspectratio = 4; + break; + case 24: + aspectratio = 6; + break; + case 20: + aspectratio = 7; + break; + case 32: + aspectratio = 8; + break; + case 18: + aspectratio = 10; + break; + case 15: + aspectratio = 11; + break; + default: + break; + } + break; + case 33: + switch ( aNumerator ) + { + case 40: + aspectratio = 5; + break; + case 80: + aspectratio = 9; + break; + case 64: + aspectratio = 12; + break; + default: + break; + } + break; + case 99: + if ( aNumerator == 160 ) + { + aspectratio = 13; + } + + break; + default: + break; + } + PRINT_EXIT; + return aspectratio; + } + +//---------------------------------------------------------------------------- +// Two phase constructor for an object of CAriH264encHwDeviceImpl +//---------------------------------------------------------------------------- +// +CAriH264encHwDeviceImpl* CAriH264encHwDeviceImpl::NewL() + { + PRINT_ENTRY; + CAriH264encHwDeviceImpl* self = new ( ELeave ) CAriH264encHwDeviceImpl(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return self; + } + +//---------------------------------------------------------------------------- +// Default constructor +//---------------------------------------------------------------------------- +// +CAriH264encHwDeviceImpl::CAriH264encHwDeviceImpl() + :iMMFDevVideoRecordProxy( NULL ), + iInputDevice ( NULL ), + iClockSource ( NULL ), + iInputBufReturnToPreProc( EFalse ), + iPeriodicTimer ( NULL ), + iClockTimeWhenPaused( 0 ), + //100 milli seconds + iPollingInterval(TTimeIntervalMicroSeconds32( KPOLLINGINTERVAL ) ), + iCodec( NULL ), + iEngine( NULL ), + iOutputBuffers( NULL ), + iOutputBufferSize( 0 ), + iPauseOffset( 0 ), + iTotalTime( 0 ), + iLastEncodedPictureTimestamp( 0 ), + iPictureLoss( EFalse ), + iInputEndCalled( EFalse ), + iFrozen( EFalse ), + iTotalLengthFilledSoFarInPacketMode( 0 ), + iTotalOutputBufferLengthInPacketMode( 0 ), + iPacketOffSetCurrentPosition( NULL ), + iPacketOffSetAndLengthInfoBuffers( NULL ), + iInternalOutputBuffers( NULL ), + iNumOfBuffersAtClientInPacketModeNeedReAllocation( 0 ), + iPacketsPending( EFalse ), + iNumOfOutBuffersAvailableInPacketModeChange( 0 ), + iNumofBuffersPendingFromClientInChangeToPacketMode( 0 ), + iNumOfOutBuffersBeforeChangeToPacketMode( 0 ), + iCodedBufferForPacketModeChange( NULL ), + iSegmentBuffers( NULL ), + iIsConfigDataFilledInFirstOutputBuffer( EFalse ), + iIsSliceEnabledInCodedPicture( EFalse ), + iNoOfOutputFramesPerSec( 0 ), + iSizePerFrame( 0 ), + iEncStateMac( NULL ) + { + PRINT_ENTRY; + + iSupportedDataUnitTypes = EDuCodedPicture | EDuVideoSegment; + + iSupportedDataUnitEncapsulations = EDuElementaryStream + | EDuGenericPayload; + + // Default values for Init params - full range + TUncompressedVideoFormat inputFormat; + inputFormat.iDataFormat = EYuvRawData; + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range1; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + inputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + inputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + inputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + inputFormat.iYuvFormat.iAspectRatioNum = 1; + inputFormat.iYuvFormat.iAspectRatioDenom = 1; + + iH264EncInitParams.iInputFormat = inputFormat; + + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_UNKNOWN; + + iH264EncInitParams.iAfterInitialize = 0; + + iH264EncInitParams.iOutputFormat = EH264; + + iH264EncInitParams.iMinNumOutputBuffers + = KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS; + + iH264EncInitParams.iMaxCodedSegmentSize + = KH264ENCIMPL_DEFAULT_SEGMENTSIZE; + + iH264EncInitParams.iMaxPictureRate = KH264ENCIMPL_DEFAULT_PICTURERATE; + + // initialize picture counters + iPictureCounters.iPicturesSkippedBufferOverflow = 0; + iPictureCounters.iPicturesSkippedProcPower = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + iPictureCounters.iInputPictures = 0; + + // default packet mode is off + iH264EncInitParams.iDataEncapsulation = EDuElementaryStream; + + iH264EncInitParams.iDataUnitType = EDuCodedPicture; + + iH264EncInitParams.iBitRate = KH264ENCIMPL_DEFAULT_BITRATE; + iH264EncInitParams.iTargetPictureRate = KH264ENCIMPL_DEFAULT_PICTURERATE; + iH264EncInitParams.iRandomAccessRate + = KH264ENCIMPL_DEFAULT_RANDOMACCESSRATE; + + PRINT_EXIT; + + } + +//---------------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------------- +// +CAriH264encHwDeviceImpl::~CAriH264encHwDeviceImpl() + { + PRINT_ENTRY; + PRINT_MSG( LEVEL_LOW, ( "this is %x", this ) ); + + iSupportedInputFormats.Close(); + + iLevels.Close(); + + //allocated formats should be deleted before closing + while ( iSupportedOutputFormats.Count() > 0 ) + { + CCompressedVideoFormat* lCompFormat = iSupportedOutputFormats[0]; + iSupportedOutputFormats.Remove( 0 ); + delete lCompFormat; + } + + iSupportedOutputFormats.Close(); + + // Stop processing + if( !iEncStateMac->IsStopped() && ( !iEncStateMac->IsInDeadState() ) ) + { + if( iEncStateMac->IsInitialized() ) + { + Stop(); + } + } + + if( iEngine ) + { + iEngine->Reset(); + delete iEngine; + iEngine = NULL; + } + + if( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + //delete output buffers + iOutputFreeBufferQueue.Reset(); + + if( iOutputBuffers ) + { + if( iNumOfOutBuffersBeforeChangeToPacketMode ) + { + for ( TInt i = 0; i < iNumOfOutBuffersBeforeChangeToPacketMode + ; i++ ) + { + if ( iOutputBuffers[i].iData.Ptr() ) + { + delete ( TUint8* )iOutputBuffers[i].iData.Ptr(); + } + } + } + else + { + for ( TInt i = 0; i < iH264EncInitParams.iMinNumOutputBuffers; + i++ ) + { + if ( iOutputBuffers[i].iData.Ptr() ) + { + delete ( TUint8* )iOutputBuffers[i].iData.Ptr(); + } + } + } + delete []iOutputBuffers; + } + + delete iPeriodicTimer; + iPeriodicTimer = NULL; + + if ( iPacketOffSetAndLengthInfoBuffers ) + { + for( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + delete [] ( TUint8* )iPacketOffSetAndLengthInfoBuffers[i]; + } + delete []( TUint* )iPacketOffSetAndLengthInfoBuffers; + } + + //delete temp output buffers + iInternalOutputBufferQueue.Reset(); + + if( iInternalOutputBuffers ) + { + for ( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + if ( iInternalOutputBuffers[i].iData.Ptr() ) + { + delete ( TUint8* )iInternalOutputBuffers[i].iData.Ptr(); + } + } + delete []iInternalOutputBuffers; + } + + if ( iCodedBufferForPacketModeChange ) + { + if ( iCodedBufferForPacketModeChange->iData.Ptr() ) + { + delete iCodedBufferForPacketModeChange->iData.Ptr(); + } + + delete iCodedBufferForPacketModeChange; + } + + iFreeBufferQueueForPacketOffsetInfo.Reset(); + iFilledBufferQueueForPacketOffsetInfo.Reset(); + + //delete the segment buffers + if( iSegmentBuffers ) + { + for ( TInt i = 0; i < iH264EncInitParams.iMinNumOutputBuffers; i++ ) + { + if ( iSegmentBuffers[i].iData.Ptr() ) + { + delete ( TUint8* )iSegmentBuffers[i].iData.Ptr(); + } + } + delete []iSegmentBuffers; + } + + if ( iConfigData ) + { + delete iConfigData; + iConfigData = NULL; + } + + if ( iEncStateMac ) + { + delete iEncStateMac; + iEncStateMac = NULL; + } + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Custom Interface supported by the HwDevice plugin +//---------------------------------------------------------------------------- +// +TAny* CAriH264encHwDeviceImpl::CustomInterface( TUid aInterface ) + { + PRINT_ENTRY; + if( aInterface == KH324AnnexKDefinedEncoderConfigDataCIUid ) + { + PRINT_EXIT; + return ( ( MH324AnnexKDefinedEncoderConfigDataCI* ) this ); + } + else + { + PRINT_EXIT; + return NULL; + } + } + +//---------------------------------------------------------------------------- +// Returns information about this Encoder HW Device +//---------------------------------------------------------------------------- +// +CVideoEncoderInfo* CAriH264encHwDeviceImpl::VideoEncoderInfoLC() + { + PRINT_ENTRY; + + TSize maxPictureSize = TSize( KH264ENCIMPL_SDTV_WIDTH, + KH264ENCIMPL_SDTV_HEIGHT_PAL ); + + TUint32 maxBitRate = KMAXSUPPBITRATE; + RArray maxPictureRatesAndSizes; + CleanupClosePushL( maxPictureRatesAndSizes ); + + TPictureRateAndSize pictureRateAndSize; + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_QCIF_WIDTH, + KH264ENCIMPL_QCIF_HEIGHT ); + + TInt error = KErrNone; + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_VGA_WIDTH, + KH264ENCIMPL_VGA_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_CIF_WIDTH, + KH264ENCIMPL_CIF_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_SQCIF_WIDTH, + KH264ENCIMPL_SQCIF_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_QVGA_WIDTH, + KH264ENCIMPL_QVGA_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_SDTV_WIDTH, + KH264ENCIMPL_HALFSDTV_HEIGHT_NTSC); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_SDTV_WIDTH, + KH264ENCIMPL_HALFSDTV_HEIGHT_PAL ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_SDTV_WIDTH, + KH264ENCIMPL_SDTV_HEIGHT_NTSC ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KH264ENCIMPL_PICTURERATE_25; + pictureRateAndSize.iPictureSize = TSize( KH264ENCIMPL_SDTV_WIDTH, + KH264ENCIMPL_SDTV_HEIGHT_PAL ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending maximum picture rate and size" ); + User::Leave( error ); + } + + TUint32 supportedPictureOptions = TVideoPicture::ETimestamp | + TVideoPicture::EReqInstantRefresh; + + TUint32 supportedDataUnitEncapsulations = EDuElementaryStream | + EDuGenericPayload; + + TUint32 supportedDataUnitTypes = EDuCodedPicture | + EDuVideoSegment; + + CVideoEncoderInfo* lVideoEncoderInfo = CVideoEncoderInfo::NewL( TUid:: + Uid( KUidH264EncoderHwDeviceImplUid ), + KH264EncManufacturer, + KH264EncIdentifier, + TVersion( KH264ENCIMPL_MAJOR_VERSION, + KH264ENCIMPL_MINOR_VERSION, + KH264ENCIMPL_BUILD_VERSION ), + // Accelerated + EFalse, + // Enc doesnt support direct capture + EFalse, + iSupportedInputFormats.Array(), + iSupportedOutputFormats.Array(), + maxPictureSize, + supportedDataUnitTypes, + supportedDataUnitEncapsulations, + // Max bitrate layers + 1, + //aSupportsSupplementalEnhancementInfo + EFalse, + //aMaxUnequalErrorProtectionLevels + 1, + maxBitRate, + maxPictureRatesAndSizes.Array(), + //aMaxInLayerScalabilitySteps + 1, + supportedPictureOptions, + //aSupportsPictureLoss + ETrue, + //aSupportsSliceLoss + ETrue, + //aCodingStandardSpecificInfo + KNullDesC8, + //aImplementationSpecificInfo + KNullDesC8 ); + + CleanupStack::PopAndDestroy(); + CleanupStack::PushL( lVideoEncoderInfo ); + + PRINT_EXIT; + return lVideoEncoderInfo; + } + + +//---------------------------------------------------------------------------- +// Sets the encoder output format +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetOutputFormatL( + const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aDataEncapsulation, + TBool aSegmentationAllowed ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetOutputFormatL () called before Initialize ()" ); + User::Leave( KErrPermissionDenied ); + } + + TInt error = KErrNotFound; + + TPtrC8 mimeType( aFormat.MimeType() ); + + // Check if format is supported else return KErrNotSupported + for ( TInt i = 0; i < iSupportedOutputFormats.Count(); i++ ) + { + CCompressedVideoFormat* lFormat = iSupportedOutputFormats[i]; + + if( mimeType.CompareF( lFormat->MimeType() ) == 0 ) + { + iH264EncInitParams.iLevel = iLevels[i]; + error = KErrNone; + break; + } + } + + if( error == KErrNotFound ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl::SetOutputFormatL() Leaving" + " because of unsupported output mimetype" ); + + User::Leave( KErrNotSupported ); + return; + } + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetOutputFormatL() " + "level is set to %d", (TInt)iH264EncInitParams.iLevel ) ); + + if ( ( ( aDataUnitType != EDuCodedPicture ) && + ( aDataUnitType != EDuVideoSegment ) ) || + ( ( aDataEncapsulation != EDuElementaryStream ) && + ( aDataEncapsulation != EDuGenericPayload ) ) || + ( ( aSegmentationAllowed ) ) ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl::SetOutputFormatL() Leaving" + " because of unsupported data unit type or data unit" + " encapsulation" ); + User::Leave( KErrNotSupported ); + } + + if( aDataUnitType == EDuCodedPicture ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetOutputFormatL() " + "Packet mode is OFF" ) ); + } + else + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetOutputFormatL() " + "Packet mode is ON" ) ); + // must be calculated from and levels set by the client + iH264EncInitParams.iMinNumOutputBuffers + = KH264ENCIMPL_MAXNUM_SEGMENTBUFFERS; + } + + iH264EncInitParams.iDataUnitType = aDataUnitType; + iH264EncInitParams.iDataEncapsulation = aDataEncapsulation; + iH264EncInitParams.iSegmentationAllowed = aSegmentationAllowed; + iH264EncInitParams.iBeforeInitialize |= EEncOutputFormat; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the pre-processor device that will write data to this encoder +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetInputDevice( + CMMFVideoPreProcHwDevice* aDevice ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + ClientFatalError ( KErrPermissionDenied ); + return; + } + + if( !aDevice ) + { + ClientFatalError ( KErrArgument ); + return; + } + + iInputDevice = aDevice; + iH264EncInitParams.iBeforeInitialize |= EEncInputDevice; + iInputBufReturnToPreProc = ETrue; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the number of bit-rate scalability layers to use +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetNumBitrateLayersL( TUint aNumLayers ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetNumBitrateLayersL () called before Initialize" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + if( aNumLayers != 1 ) + { + PRINT_ERR( "Wrong value passed for aNumLayers... Leaving" ); + User::Leave( KErrNotSupported ); + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the scalability type for a bit-rate scalability layer. Currently not +// supported. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetScalabilityLayerTypeL( + TUint /*aLayer*/, + TScalabilityType /*aScalabilityType*/ ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetScalabilityLayerTypeL() called before Initialize" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + PRINT_ERR( "SetScalabilityLayerTypeL() not supported...Leaving with " + "KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Sets the reference picture options to be used for all scalability layers +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetGlobalReferenceOptions( + TUint aMaxReferencePictures, + TUint aMaxPictureOrderDelay ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if( aMaxPictureOrderDelay != 0 || aMaxReferencePictures + > KH264ENCIMPL_MAXNUM_REFERENCEPICTURES ) + { + ClientFatalError( KErrNotSupported ); + return; + } + + iH264EncInitParams.iLayerReferenceOptions[0].iMaxReferencePictures + = aMaxReferencePictures; + + iH264EncInitParams.iLayerReferenceOptions[0].iMaxPictureOrderDelay + = aMaxPictureOrderDelay; + + iH264EncInitParams.iBeforeInitialize |= EEncGlobalRefOptions; + + PRINT_EXIT + } + +//---------------------------------------------------------------------------- +// Sets the reference picture options to be used for a single scalability +// layer +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetLayerReferenceOptions( TUint /*aLayer*/, + TUint /*aMaxReferencePictures*/, + TUint /*aMaxPictureOrderDelay*/ ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +///--------------------------------------------------------------------------- +// Sets encoder buffering options +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetBufferOptionsL( + const TEncoderBufferOptions& aOptions ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetBufferOptionsL () called before Initialize ()" ); + User::Leave( KErrPermissionDenied ); + } + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iMaxPreEncoderBufferPictures = %d" , + (TInt)aOptions.iMaxPreEncoderBufferPictures ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iMaxOutputBufferSize = %d", + ( TInt ) aOptions.iMaxOutputBufferSize ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iMaxCodedPictureSize = %d" , + ( TInt )aOptions.iMaxCodedPictureSize ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iHrdVbvSpec = %x", ( TInt ) aOptions.iHrdVbvSpec ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iMinNumOutputBuffers = %d" , + ( TInt ) aOptions.iMinNumOutputBuffers ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetBufferOptionsL() " + "iMaxCodedSegmentSize = %d" , + ( TInt ) aOptions.iMaxCodedSegmentSize ) ); + + if( ( aOptions.iMaxPreEncoderBufferPictures == 0 ) || + ( aOptions.iMaxOutputBufferSize == 0 ) || + ( aOptions.iMinNumOutputBuffers == 0 ) || + ( aOptions.iHrdVbvSpec == EHrdVbv3GPP ) ) + { + PRINT_ERR( "SetBufferOptionsL () - incorrect parameter passed ..." + "leaving with KErrNotSupported" ); + User::Leave ( KErrNotSupported ); + return; + } + + if ( aOptions.iHrdVbvParams != KNullDesC8 ) + { + if ( aOptions.iHrdVbvSpec == EHrdVbvNone ) + { + PRINT_ERR( "SetBufferOptionsL () - incorrect HrdVbvParams or" + "iHrdVbvSpec passed ...leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + return; + } + + TPckgBuf params; + params.Copy ( aOptions.iHrdVbvParams ); + TUint size = sizeof( TAvcPictureHeader ); + if ( size != aOptions.iHrdVbvParams.Length() ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl::SetBufferOptionsL() -" + "invalid structure passed for iHrdVbvParams" ); + User::Leave( KErrArgument ); + } + + // Perform the checks on the members of + if( ( params().iBaselineProfileConstraintSet == ( TBool )EFalse ) || + ( params().iMainProfileConstraintSet == ( TBool )ETrue ) || + ( params().iExtendedProfileConstraintSet == ( TBool )ETrue ) || + ( ( params().iPictureType ) & EAvcPictureTypeB ) || + ( ( params().iPictureType ) & EAvcPictureTypeSI ) || + ( ( params().iPictureType ) & EAvcPictureTypeSP ) || + ( params().iLongTermPicture == ( TBool )ETrue ) || + ( params().iFrame == ( TBool )EFalse ) || + ( params().iQPY < 10 ) || + ( params().iQPY > 51 ) ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl ::SetBufferOptionsL Invalid " + "data passed in TAVCHrdParams" ); + User::Leave( KErrNotSupported ); + return; + } + } + + iH264EncInitParams.iMaxPreEncoderBufferPictures + = aOptions.iMaxPreEncoderBufferPictures; + + iH264EncInitParams.iMaxOutputBufferSize = aOptions.iMaxOutputBufferSize; + iH264EncInitParams.iMaxCodedPictureSize = aOptions.iMaxCodedPictureSize; + iH264EncInitParams.iMaxCodedSegmentSize = aOptions.iMaxCodedSegmentSize; + iH264EncInitParams.iMinNumOutputBuffers = aOptions.iMinNumOutputBuffers; + iH264EncInitParams.iBeforeInitialize |= EEncBufferOptions; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the encoder output rectangle +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetOutputRectL( const TRect& aRect ) + { + PRINT_ENTRY; + + if( ( aRect.iTl.iX >= aRect.iBr.iX ) || + ( aRect.iTl.iY >= aRect.iBr.iY ) ) + { + PRINT_ERR( " Invalid parameteres passed..Leaving " ); + User::Leave ( KErrNotSupported ); + return; + } + + iH264EncInitParams.iOutputRect = aRect; + iH264EncInitParams.iBeforeInitialize |= EEncOutputRectSize; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets whether bit errors or packets losses can be expected in the video +// transmission +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetErrorsExpected( TBool aBitErrors, + TBool aPacketLosses ) + { + PRINT_ENTRY; + + // This can bel called before and after initialize + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetErrorsExpected()" + " BitErrors is set to [ %d ]", aBitErrors ) ); + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::SetErrorsExpected() " + "iPacketLosses is set to [ %d ]", aPacketLosses ) ); + + if( iEncStateMac->IsInitialized() ) + { + iCurSetH264EncParams.iBitErrors = aBitErrors; + iCurSetH264EncParams.iPacketLosses = aPacketLosses; + iCurSetH264EncParams.iAfterInitialize |= EEncErrorsExpected; + } + else + { + iH264EncInitParams.iBitErrors = aBitErrors; + iH264EncInitParams.iPacketLosses = aPacketLosses; + iH264EncInitParams.iBeforeInitialize |= EEncErrorsExpected; + } + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Sets the minimum frequency (in time) for instantaneous random access points +// in the bitstream +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetMinRandomAccessRate( TReal aRate ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + // simply return no further action is taken + if( aRate <= 0.0 ) + { + return; + } + iCurSetH264EncParams.iRandomAccessRate = aRate; + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl" + "::SetMinRandomAccessRate() iRandomAccessRate is %f" , + ( TReal )iH264EncInitParams.iRandomAccessRate ) ); + + iCurSetH264EncParams.iAfterInitialize |= EEncRandomAccessRate; + } + else + { + if( aRate <= 0.0 ) + { + ClientFatalError ( KErrNotSupported ); + return; + } + iH264EncInitParams.iRandomAccessRate = aRate; + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl" + "::SetMinRandomAccessRate() iRandomAccessRate is %f" , + ( TReal )iH264EncInitParams.iRandomAccessRate ) ); + + iH264EncInitParams.iBeforeInitialize |= EEncRandomAccessRate; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets coding-standard specific encoder options. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetCodingStandardSpecificOptionsL( + const TDesC8& aOptions ) + { + PRINT_ENTRY; + + if ( aOptions == KNullDesC8 ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl" + "::SetCodingStandardSpecificOptionsL() Leaving because Null " + "Descriptor Passed" ); + User::Leave( KErrArgument ); + } + + // validate the parameters + TPckgBuf avcVideoMode; + TUint size = sizeof( TAvcVideoMode ); + if ( size != aOptions.Length() ) + { + PRINT_MSG( LEVEL_HIGH, ( "CAriH264encHwDeviceImpl" + "::SetCodingStandardSpecificOptionsL() - invalid structure passed") ); + User::Leave( KErrArgument ); + } + + // before init + if( !iEncStateMac->IsInitialized() ) + { + iH264EncInitParams.iCodingStandardSpecificOptions = avcVideoMode(); + iH264EncInitParams.iBeforeInitialize + |= EEncCodingStandardSpecificOptions; + } + avcVideoMode.Copy( aOptions ); + + if ( ( avcVideoMode().iAllowedPictureTypes & EAvcPictureTypeB ) || + ( avcVideoMode().iAllowedPictureTypes & EAvcPictureTypeSI ) || + ( avcVideoMode().iAllowedPictureTypes & EAvcPictureTypeSP ) || + ( avcVideoMode().iFlexibleMacroblockOrder ) || + ( avcVideoMode().iRedundantPictures ) || + ( avcVideoMode().iDataPartitioning ) || + ( !avcVideoMode().iFrameMBsOnly ) || + ( avcVideoMode().iMBAFFCoding ) || + ( avcVideoMode().iEntropyCodingCABAC ) || + ( avcVideoMode().iWeightedPPrediction ) || + ( avcVideoMode().iWeightedBipredicitonMode ) ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl" + "::SetCodingStandardSpecificOptionsL() - leaving invalid data " + "passed for TAvcVideoMode" ); + User::Leave( KErrNotSupported ); + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets coding-standard specific encoder options. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetImplementationSpecificEncoderOptionsL( + const TDesC8& /*aOptions*/) + { + PRINT_ENTRY; + + //This API can be called at any point of time + PRINT_ERR( "SetImplementationSpecificEncoderOptionsL () called before " + "Initialize ()" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Returns coding-standard specific initialization output from the encoder +//---------------------------------------------------------------------------- +// +HBufC8* CAriH264encHwDeviceImpl::CodingStandardSpecificInitOutputLC() + { + PRINT_ENTRY; + + TUint configlength; + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CodingStandardSpecificInitOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + TUint err = iCodec->GetParam( CONTROL_CMD_GET_CONFIG_LENGTH, + &configlength ); + if ( err ) + { + PRINT_ERR("GetParam failure"); + User::Leave( err ); + } + + iConfigData = HBufC8::NewL( configlength ); + err = iCodec->GetParam( CONTROL_CMD_GET_CONFIG_HEADER, iConfigData ); + + if ( err ) + { + PRINT_ERR("GetParam failure"); + User::Leave( err ); + } + + PRINT_EXIT; + return iConfigData; + } + +//---------------------------------------------------------------------------- +// Returns coding-standard specific initialization output from the encoder +//---------------------------------------------------------------------------- +// +HBufC8* CAriH264encHwDeviceImpl::ImplementationSpecificInitOutputLC() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "ImplementationSpecificInitOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + return NULL; + } + + PRINT_ERR( "ImplementationSpecificInitOutputLC () not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//---------------------------------------------------------------------------- +// Sets the number of unequal error protection levels +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetErrorProtectionLevelsL(TUint /*aNumLevels*/, + TBool /*aSeparateBuffers*/) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetErrorProtectionLevelsL() not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the number of unequal error protection levels +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetErrorProtectionLevelL( TUint /*aLevel*/, + TUint /*aBitrate*/, + TUint /*aStrength*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetErrorProtectionLevelsL() not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the expected or prevailing channel conditions for an unequal +// error protection level, in terms of expected packet loss rate +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetChannelPacketLossRate( TUint /*aLevel*/, + TReal /*aLossRate*/, + TTimeIntervalMicroSeconds32 /*aLossBurstLength*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + //packet mode is already enabled + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl" + " ::SetChannelPacketLossRate()- already in packet mode returning" ) ); + return; + } + + // Flush the output buffers + iEngine->ReturnOutputBuffers(); + + // output buffers status + iNumOfOutBuffersAvailableInPacketModeChange + = iOutputFreeBufferQueue.Count(); + + iNumofBuffersPendingFromClientInChangeToPacketMode + = iH264EncInitParams.iMinNumOutputBuffers + - iOutputFreeBufferQueue.Count(); + + iNumOfOutBuffersBeforeChangeToPacketMode + = iH264EncInitParams.iMinNumOutputBuffers; + + TInt error = KErrNone; + // some buffers are available + if ( iNumOfOutBuffersAvailableInPacketModeChange ) + { + while( iOutputFreeBufferQueue.Count() ) + { + // add to engine + iEngine->AddOutput( iOutputFreeBufferQueue[0] ); + + // remove this buffer + iOutputFreeBufferQueue.Remove( 0 ); + } + } + else + { + // create one buffer which can hold one encoded picture + TRAP( error, CreateCodedBufferForModeChangeL() ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + + iH264EncInitParams.iMaxCodedSegmentSize + = KH264ENCIMPL_DEFAULT_SEGMENTSIZE; + + // Get the maximum output buffer size for the encoder + TUint maxOutputBufferSize =0; + error = iCodec->GetParam( CONTROL_CMD_GET_MAX_FRAME_SIZE, + &maxOutputBufferSize ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + iH264EncInitParams.iMinNumOutputBuffers = ( maxOutputBufferSize / + iH264EncInitParams.iMaxCodedSegmentSize ) * + KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS; + + TRAP( error, CreateSegmentOutputBuffersL ( + iH264EncInitParams.iMinNumOutputBuffers, + iH264EncInitParams.iMaxCodedSegmentSize ) ) + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + error = iCodec->GetParam( CONTROL_CMD_GET_MAX_NUM_PACKETS, + &iMaxNumOfPackets ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + TRAP( error, CreatePacketOffsetLengthInfoBuffersL( iMaxNumOfPackets ) ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + TBool yesorno = ETrue; + error = iCodec->SetParam( CONTROL_CMD_SET_PACKET_MODE, &yesorno ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + // change output mode to videosegment + iH264EncInitParams.iDataUnitType = EDuVideoSegment; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the expected or prevailing channel conditions for an unequal error +// protection level, in terms of expected bit error rate +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetChannelBitErrorRate( TUint /*aLevel*/, + TReal aErrorRate, TReal /*aStdDeviation*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // ignore the negative and 0 error rate values - #AANV-6QSC9N + if ( aErrorRate < 0.0 ) + { + return; + } + + TReal* bitErrorRate = NULL; + TRAPD( error , bitErrorRate = new( ELeave )TReal ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + *bitErrorRate = aErrorRate; + TRAP( error, iEngine->AddCommandL( CBaseEngine::EHighPriority, + CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE, bitErrorRate ) ); + if( error != KErrNone ) + { + delete bitErrorRate; + ClientFatalError( error ); + return; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the target size of each coded video segment +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetSegmentTargetSize( TUint aLayer, + TUint aSizeBytes, + TUint /*aSizeMacroblocks*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( iH264EncInitParams.iDataUnitType == EDuCodedPicture ) + { + if( aSizeBytes== 0 ) + { + if( iIsSliceEnabledInCodedPicture ) + { + iIsSliceEnabledInCodedPicture= EFalse; + TInt error = iCodec->SetParam( CONTROL_CMD_SET_FRAME_MODE, + NULL ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + return; + } + TUint calculatedSegmentSize = 0; + if( aSizeBytes <= KH264ENCIMPL_MIN_SLICESIZE ) + { + calculatedSegmentSize = KH264ENCIMPL_MIN_SLICESIZE; + } + else + { + if ( iH264EncInitParams.iMaxCodedSegmentSize + < iH264EncInitParams.iMaxCodedPictureSize ) + { + if ( aSizeBytes > iH264EncInitParams.iMaxCodedSegmentSize ) + { + calculatedSegmentSize + = iH264EncInitParams.iMaxCodedSegmentSize; + } + else + { + calculatedSegmentSize = aSizeBytes; + } + } + else + { + if ( aSizeBytes < iH264EncInitParams.iMaxCodedPictureSize ) + { + calculatedSegmentSize = aSizeBytes; + } + else + { + return; + } + } + } + + if( calculatedSegmentSize < KH264ENCIMPL_MIN_SLICESIZE ) + { + calculatedSegmentSize = KH264ENCIMPL_MIN_SLICESIZE; + } + + TBool yesorno = EFalse; + TInt error = iCodec->SetParam( CONTROL_CMD_SET_PACKET_MODE, + &yesorno ); + + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + // Set the target size on codec + error = iCodec->SetParam( CONTROL_CMD_SET_PACKET_SIZE, + &calculatedSegmentSize ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::calculatedSegmentSize() is %d" , + ( TInt )calculatedSegmentSize ) ); + + iH264EncInitParams.iMaxCodedSegmentSize = calculatedSegmentSize; + iIsSliceEnabledInCodedPicture = ETrue; + return; + + } + + if ( iH264EncInitParams.iDataUnitType != EDuVideoSegment ) + { + return; + } + + // aLayer should be zero since layered bit-rate scalability is not used. + if ( aLayer != 0 ) + { + return; + } + + TUint calculatedSegmentSize = 0; + // if value < 0 or > iMaxOutputBufferSize the adjust this value + if ( aSizeBytes < KH264ENCIMPL_MIN_SEGMENTSIZE ) + { + calculatedSegmentSize = KH264ENCIMPL_MIN_SEGMENTSIZE; + } + else + { + if ( iH264EncInitParams.iMaxOutputBufferSize + > KH264ENCIMPL_MAX_SEGMENTSIZE ) + { + if ( aSizeBytes < KH264ENCIMPL_MAX_SEGMENTSIZE ) + { + calculatedSegmentSize = aSizeBytes; + } + else + { + calculatedSegmentSize = KH264ENCIMPL_MAX_SEGMENTSIZE; + } + } + else + { + if ( aSizeBytes < iH264EncInitParams.iMaxOutputBufferSize ) + { + calculatedSegmentSize = aSizeBytes; + } + else + { + calculatedSegmentSize + = iH264EncInitParams.iMaxOutputBufferSize; + } + } + } + + // Set the target size on codec + TInt error = iCodec->SetParam( CONTROL_CMD_SET_PACKET_SIZE, + &calculatedSegmentSize ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + iH264EncInitParams.iMaxCodedSegmentSize = calculatedSegmentSize; + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Sets the bit-rate control options for a layer +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetRateControlOptions( TUint aLayer, + const TRateControlOptions& aOptions ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // Since layered bit-rate scalability is not used, options are set for the + // entire stream + if ( aLayer != 0 ) + { + return; + } + + if ( ( aOptions.iPictureRate <= 0 ) || + ( aOptions.iControl & EBrControlPicture ) ) + { + return; + } + + if ( aOptions.iControl & EBrControlStream ) + { + if ( ( aOptions.iQualityTemporalTradeoff < 0 ) || + ( aOptions.iQualityTemporalTradeoff > 1 ) || + ( aOptions.iLatencyQualityTradeoff < 0 ) || + ( aOptions.iLatencyQualityTradeoff > 1 ) || + ( aOptions.iBitrate == 0 ) ) + { + return; + } + } + + TRateControlOptions* rateControlOptions = NULL; + TRAPD( error, rateControlOptions = new ( ELeave )TRateControlOptions ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + rateControlOptions->iControl = aOptions.iControl; + // default bit rate used + if( aOptions.iControl & EBrControlNone ) + { + rateControlOptions->iBitrate = iH264EncInitParams.iBitRate; + } + else + { + rateControlOptions->iBitrate = ( aOptions.iBitrate + <= iH264EncInitParams.iBitRate ) ? ( aOptions.iBitrate ) + : ( iH264EncInitParams.iBitRate ); + } + + rateControlOptions->iPictureQuality = aOptions.iPictureQuality; + rateControlOptions->iPictureRate = aOptions.iPictureRate; + rateControlOptions->iQualityTemporalTradeoff + = aOptions.iQualityTemporalTradeoff; + rateControlOptions->iLatencyQualityTradeoff + = aOptions.iLatencyQualityTradeoff; + + TRAP( error, iEngine->AddCommandL( CBaseEngine::EHighPriority, + CONTROL_CMD_SET_RATE_CONTROL_OPTIONS, rateControlOptions ) ); + + if( error != KErrNone ) + { + delete rateControlOptions; + ClientFatalError ( error ); + return; + } + + if( !iEncStateMac->IsPlaying() ) + { + TInt ret = iCodec->SetParam( CONTROL_CMD_SET_RATE_CONTROL_OPTIONS, + rateControlOptions ); + if ( ret ) + { + ClientFatalError( ret ); + } + } + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + "iBitrate is %d", ( TInt )aOptions.iBitrate ) ); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + "iPictureQuality is %d" , ( TInt )aOptions.iPictureQuality ) ); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + " iPictureRate is %f", ( TReal )aOptions.iPictureRate ) ); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + "iQualityTemporalTradeoff is %f" , + ( TReal )aOptions.iQualityTemporalTradeoff ) ); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + " iLatencyQualityTradeoff is %f " , + ( TReal ) aOptions.iLatencyQualityTradeoff ) ); + + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetRateControlOptions()" + "iControl is %x" , ( TInt ) aOptions.iControl ) ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets in-layer scalability options for a layer +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetInLayerScalabilityL( TUint /*aLayer*/, + TUint /*aNumSteps*/, + TInLayerScalabilityType /*aScalabilityType*/, + const TArray& /*aBitrateShare*/, + const TArray& /*aPictureShare*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetInLayerScalabilityL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetInLayerScalabilityL () not supported..leaving with " + "KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the period for layer promotions points for a scalability layer +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetLayerPromotionPointPeriod( TUint /*aLayer*/, + TUint /*aPeriod*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Returns coding-standard specific settings output from the encoder +//---------------------------------------------------------------------------- +// +HBufC8* CAriH264encHwDeviceImpl::CodingStandardSpecificSettingsOutputLC() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CodingStandardSpecificSettingsOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "CodingStandardSpecificSettingsOutputLC () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//---------------------------------------------------------------------------- +// Returns implementation-specific settings output from the encoder +//---------------------------------------------------------------------------- +// +HBufC8* CAriH264encHwDeviceImpl::ImplementationSpecificSettingsOutputLC() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "ImplementationSpecificSettingsOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "ImplementationSpecificSettingsOutputLC () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//---------------------------------------------------------------------------- +// Requests the encoder to sends supplemental information in the bitstream +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SendSupplementalInfoL( const TDesC8& /*aData*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SendSupplementalInfoL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SendSupplementalInfoL () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Requests the encoder to sends supplemental information in the bitstream +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SendSupplementalInfoL( const TDesC8& /*aData*/, + const TTimeIntervalMicroSeconds& /*aTimestamp*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SendSupplementalInfoL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SendSupplementalInfoL () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Cancels the current supplemental information send request +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::CancelSupplementalInfo() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Gets the current output buffer status. The information includes +// the number of free output buffers and the total size of free buffers in +// bytes. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::GetOutputBufferStatus( TUint& aNumFreeBuffers, + TUint& aTotalFreeBytes ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + aNumFreeBuffers = iEngine->NumOutputBuffers() + + iOutputFreeBufferQueue.Count(); + + aTotalFreeBytes = aNumFreeBuffers * iOutputBufferSize; + + PRINT_EXIT; + } +//---------------------------------------------------------------------------- +// Returns a used output buffer back to the encoder +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ReturnBuffer( TVideoOutputBuffer* aBuffer ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + // coded picture buffers so add it to Interanal Q or process engine + if ( iNumofBuffersPendingFromClientInChangeToPacketMode ) + { + iEngine->AddOutput( aBuffer ); + --iNumofBuffersPendingFromClientInChangeToPacketMode; + return; + } + + // buffers returned by the client are + if ( iNumOfBuffersAtClientInPacketModeNeedReAllocation ) + { + TRAPD( error, ReallocateSegmentBufferL( aBuffer ) ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + iNumOfBuffersAtClientInPacketModeNeedReAllocation--; + } + + TInt error = KErrNone; + error = iOutputFreeBufferQueue.Append( aBuffer ); + + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + if ( !iPacketsPending ) + { + return; + } + + // still has packets in temporary buffer + if ( iTotalLengthFilledSoFarInPacketMode + < iTotalOutputBufferLengthInPacketMode ) + { + TVideoOutputBuffer *outBuf = iOutputFreeBufferQueue[0]; + FillVideoSegment( outBuf, iInternalOutputBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + + #ifdef CALCINSTANTBITRATE + CalculateInstantBitRate( *outBuf ); + #endif + + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + else + { + aBuffer->iData.Set( ( TUint8* )aBuffer->iData.Ptr(), + iOutputBufferSize ); + + // add the buffer back to queue or process engine + if ( ( !iEncStateMac->IsInputEndPending() ) + && ( !iEncStateMac->IsStopped() ) ) + { + iEngine->AddOutput( ( TAny* )aBuffer ); + } + else + { + TInt error = iOutputFreeBufferQueue.Append( aBuffer ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Indicates a picture loss to the encoder, without specifying the lost +// picture +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::PictureLoss() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + iPictureLoss = ETrue; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Indicates to the encoder the pictures that have been lost +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::PictureLoss( + const TArray& /*aPictures*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + iPictureLoss = ETrue; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Indicates a slice loss to the encoder. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SliceLoss( TUint aFirstMacroblock, + TUint aNumMacroblocks, + const TPictureId& /*aPicture*/ ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( ( aFirstMacroblock == 0 ) || ( aNumMacroblocks == 0 ) ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SliceLoss() " + "aNumMacroblocks or aFirstMacroblock = 0 return" ) ); + return; + } + + TH264EncSliceLoss* sliceLossParams = NULL; + TRAPD( error, sliceLossParams = new( ELeave ) TH264EncSliceLoss ); + if( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + sliceLossParams->iFirstMacroblock = aFirstMacroblock; + sliceLossParams->iNumMacroblocks = aNumMacroblocks; + + TRAP( error, iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_SLICELOSS, sliceLossParams ) ); + + if( error != KErrNone ) + { + delete sliceLossParams; + ClientFatalError ( error ); + return; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sends a reference picture selection request to the encoder +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ReferencePictureSelection( + const TDesC8& /*aSelectionData*/) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Initializes the device, and reserves hardware resources +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Initialize() + { + PRINT_ENTRY; + + //Device should be in unintialized state + if ( !iEncStateMac->IsTransitionValid( + CStateMachine::EInitializingCommand ) ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete(this + , KErrPermissionDenied ); + return; + } + + // check for input and output formats set by the client + if ( ! ( iH264EncInitParams.iBeforeInitialize & EEncInputFormat ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriH264encHwDeviceImpl::Initialize() " + "- SetInputFormat not called" ) ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + + // check for buffer sizes + if( iH264EncInitParams.iBeforeInitialize & EEncBufferOptions ) + { + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + // Buffer size related checks + if ( ( iH264EncInitParams.iMaxOutputBufferSize > + ( KH264ENCIMPL_FACTOR_FOR_OUTPUTBUFFERSIZE_IN_PACKETMODE * + KH264ENCIMPL_MAX_SEGMENTSIZE ) ) || + ( iH264EncInitParams.iMaxCodedSegmentSize > + KH264ENCIMPL_MAX_SEGMENTSIZE ) || + ( iH264EncInitParams.iMaxCodedSegmentSize > + iH264EncInitParams.iMaxOutputBufferSize ) || + ( iH264EncInitParams.iMaxCodedSegmentSize == 0 ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ( "CAriH264encHwDeviceImpl" + "::Initialize() - Wrong size for iMaxCodedSegmentSize" ) ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + } + + else if ( iH264EncInitParams.iDataUnitType == EDuCodedPicture ) + { + if ( ( iH264EncInitParams.iMaxCodedPictureSize > + iH264EncInitParams.iMaxOutputBufferSize ) + || ( iH264EncInitParams.iMaxCodedPictureSize == 0 ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ( "CAriH264encHwDeviceImpl" + "::Initialize() - Wrong size for iMaxCodedPictureSize" ) ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + } + } + else + { + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + iH264EncInitParams.iMinNumOutputBuffers + = KH264ENCIMPL_MAXNUM_SEGMENTBUFFERS; + iH264EncInitParams.iMaxCodedSegmentSize + = KH264ENCIMPL_DEFAULT_SEGMENTSIZE; + iH264EncInitParams.iMaxOutputBufferSize + = KH264ENCIMPL_MAX_SEGMENTSIZE; + } + else + { + iH264EncInitParams.iMinNumOutputBuffers + = KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS; + } + } + + // based on level set the max bit rate + switch ( iH264EncInitParams.iLevel ) + { + //Level 1b + case KH264ENCIMPL_LEVEL_1b: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_1b; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + break; + + case KH264ENCIMPL_LEVEL_1: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_1; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + break; + + case KH264ENCIMPL_LEVEL_11: + // Both Level 1b and 1.1 have this value + // need to decide if 1.1 or 1.b + // two options - client passes buffer options and client doesnt + // pass buffer options + { + TBool isLevel1b = EFalse; + if ( iH264EncInitParams.iBeforeInitialize & EEncBufferOptions ) + { + isLevel1b = ( ( KH264ENCIMPL_LEVEL1b_MAXCPBSIZE <= + iH264EncInitParams.iMaxCodedPictureSize ) && + ( iH264EncInitParams.iMaxCodedPictureSize < + KH264ENCIMPL_LEVEL11_MAXCPBSIZE ) ) + ? ( ETrue ) + : ( EFalse ); + } + //now we have input size information to decide 1b vs 1.1 + else + { + isLevel1b = ( ( iH264EncInitParams.iPictureSize.iWidth > + KH264ENCIMPL_QCIF_WIDTH ) + && ( iH264EncInitParams.iPictureSize.iHeight > + KH264ENCIMPL_QCIF_HEIGHT ) ) + ? ( EFalse ) + : ( ETrue ); + } + + if ( isLevel1b ) + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_1b; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_1b; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + } + else + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_11; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_11; + iH264EncInitParams.iTargetPictureRate + = ( ( iH264EncInitParams.iPictureSize.iWidth + <= KH264ENCIMPL_QCIF_WIDTH ) && + ( iH264EncInitParams.iPictureSize.iHeight + <= KH264ENCIMPL_QCIF_HEIGHT ) ) ? ( KPictureRate15 ) + : ( KPictureRate75 ); + } + } + break; + + case KH264ENCIMPL_LEVEL_12: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_12; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + break; + + case KH264ENCIMPL_LEVEL_13: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_13; + iH264EncInitParams.iTargetPictureRate = KPictureRate30; + break; + + case KH264ENCIMPL_LEVEL_2: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_2; + iH264EncInitParams.iTargetPictureRate = KPictureRate30; + break; + + case KH264ENCIMPL_LEVEL_21: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_21; + if ( iH264EncInitParams.iPictureSize.iHeight > + KH264ENCIMPL_HALFSDTV_HEIGHT_NTSC ) + { + // HALFSDTV-PAL + iH264EncInitParams.iTargetPictureRate = KPictureRate25; + } + else + { + // HALFSDTV-NTSC + iH264EncInitParams.iTargetPictureRate = KPictureRate30; + } + break; + + case KH264ENCIMPL_LEVEL_22: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_22; + if ( iH264EncInitParams.iPictureSize.iHeight > + KH264ENCIMPL_SDTV_HEIGHT_NTSC ) + { + // SDTV-PAL + iH264EncInitParams.iTargetPictureRate + = KH264ENCIMPL_PICTURERATE_12_5; + } + else + { + // SDTV-NTSC + iH264EncInitParams.iTargetPictureRate + = KPictureRate15; + } + break; + + case KH264ENCIMPL_LEVEL_3: + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_3; + if ( iH264EncInitParams.iPictureSize.iHeight + > KH264ENCIMPL_SDTV_HEIGHT_NTSC ) + { + iH264EncInitParams.iTargetPictureRate = KPictureRate25; + } + else + { + // SDTV-NTSC + iH264EncInitParams.iTargetPictureRate = KPictureRate30; + } + break; + + // level unknown based on size decide bitrate and level + case 0: + SetLevelAndBitRate(); + break; + + default: + break; + }; + + // create codec + TRAPD( error, iCodec = CAriH264encWrapper::NewL( iH264EncInitParams ) ); + if( error != KErrNone ) + { + // init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + // set the sync options to the codec + if( iClockSource ) + { + TInt error = iCodec->SetSyncOptions( iClockSource ); + + if( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + } + //Check whether picture is of QCIF format if VT fast call setup is set + + if ( iH264EncInitParams.iVTFastCallSetUp ) + { + if ( iH264EncInitParams.iPictureSize.iWidth + != KH264ENCIMPL_QCIF_WIDTH || + iH264EncInitParams.iPictureSize.iHeight + != KH264ENCIMPL_QCIF_HEIGHT ) + { + PRINT_MSG( LEVEL_LOW, ("Input resolution should be 176x144 for" + " VT Fast call setup" ) ); + ClientFatalError( KErrNotSupported ); + } + } + + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + //create engine + TRAP( error, iEngine = CBaseEngine::NewL( this, + ( MBaseCodec* ) iCodec, EFalse ) ); + + if( error != KErrNone ) + { + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + //get the max buffer length from the codec + TInt maxOutputBufferSize = 0; + error = iCodec->GetParam( CONTROL_CMD_GET_MAX_FRAME_SIZE, + &maxOutputBufferSize ); + + if( error != KErrNone ) + { + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + // if EduCodedPicture mode then check for buffer size passed + if( iH264EncInitParams.iDataUnitType == EDuCodedPicture ) + { + if ( iH264EncInitParams.iBeforeInitialize & EEncBufferOptions ) + { + if( maxOutputBufferSize + > iH264EncInitParams.iMaxCodedPictureSize ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::Initialize()" + "maxOutputBufferSize = %d", ( TInt ) maxOutputBufferSize ) ); + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete(this, + KErrNotSupported ); + return; + } + } + else + { + iH264EncInitParams.iMaxOutputBufferSize = maxOutputBufferSize; + iH264EncInitParams.iMaxCodedPictureSize = maxOutputBufferSize; + } + } + + // if packet mode is on then allocate memory for NAL information + TUint maxNumOfPackets = 0; + if( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + error = iCodec->GetParam( CONTROL_CMD_GET_MAX_NUM_PACKETS, + &iMaxNumOfPackets ); + if( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + } + + if ( iH264EncInitParams.iDataUnitType != EDuVideoSegment ) + { + TInt maxSlices = 0; + if( maxOutputBufferSize ) + { + maxSlices = maxOutputBufferSize / KH264ENCIMPL_MIN_SLICESIZE; + if( maxOutputBufferSize % KH264ENCIMPL_MIN_SLICESIZE ) + { + maxSlices++; + } + } + +#ifndef EMZ_AVC_ENC_CODEC_SEIINFO_ENABLE + PRINT_MSG( LEVEL_LOW, ( "CreateCodedOutputBuffersL SEI disble " ) ); + + // included KNumOfConfigParams*KDoubleWordLength bytes which are + // required for filling offset length information + + TRAP( error, CreateCodedOutputBuffersL( ( maxOutputBufferSize + + KWordLength + ( ( KNumOfConfigParams + maxSlices ) + * KDoubleWordLength ) ) ) ); +#else + PRINT_MSG( LEVEL_LOW, ("CreateCodedOutputBuffersL SEI enable " ) ); + TRAP( error, CreateCodedOutputBuffersL( ( maxOutputBufferSize + + KWordLength + ( ( KNumOfNAL_SEI + maxSlices ) * + KDoubleWordLength ) ) ) ); +#endif + } + else + { + // Allocate sufficient segment mode buffers Comment it for some time. + iH264EncInitParams.iMinNumOutputBuffers = ( maxOutputBufferSize / + iH264EncInitParams.iMaxCodedSegmentSize ) * + KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS; + + // holds output buffer 2. holds packet lenght and offset information + TRAP( error, CreateInternalOutputBuffersL( maxOutputBufferSize ) ); + if( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + TRAP( error, CreatePacketOffsetLengthInfoBuffersL( iMaxNumOfPackets * + KDoubleWordLength ) ); + if( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + //segement size will be the max segment size + TUint segmentSize = iH264EncInitParams.iMaxOutputBufferSize; + if ( ( iH264EncInitParams.iDataEncapsulation == EDuGenericPayload ) && + ( iH264EncInitParams.iMaxOutputBufferSize < + ( KH264ENCIMPL_MAX_SEGMENTSIZE + KDoubleWordLength + + KWordLength ) ) ) + { + segmentSize += KDoubleWordLength + KWordLength; + } + + TRAP( error, CreateCodedOutputBuffersL( segmentSize ) ); + if( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + } + + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + //reset the picture counters + iPictureCounters.iInputPictures = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + + // reset the options set by client + iH264EncInitParams.iBeforeInitialize = 0; + iCurSetH264EncParams = iH264EncInitParams; + iEncStateMac->Transit( CStateMachine::EInitializingCommand ); + iEncStateMac->Transit( CStateMachine::EInitializeCommand ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, KErrNone ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Commit all changes since the last CommitL(), Revert() or Initialize() +// to the Hw device +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::CommitL() + { + PRINT_ENTRY; + + // This method can only be called after Initialize + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CommitL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + // Methods that will be affected by CommitL in our case: + // SetOutputRectL + // SetCodingStandardSpecificOptionsL + // SetErrorsExpected + // SetMinRandomAccessRate + + TH264EncInitParams *currentParams = new( ELeave ) TH264EncInitParams; + CleanupStack::PushL( currentParams ); + *currentParams = iCurSetH264EncParams; + + // Add command apply commit settings to the codec + iEngine->AddCommandL ( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_COMMIT_OPTIONS, currentParams ); + + iCurSetH264EncParams.iAfterInitialize = 0; + CleanupStack::Pop(); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Revert all changes since the last CommitL(), Revert() or Initialize() +// back to their previous settings +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Revert() + { + PRINT_ENTRY; + + // This method can only be called after Initialize + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // Methods that will be affected by Revert in our case: + // SetOutputRectL + // SetCodingStandardSpecificOptionsL + // SetErrorsExpected + // SetMinRandomAccessRate + + iCurSetH264EncParams = iH264EncInitParams; + iCurSetH264EncParams.iAfterInitialize = 0; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// This method is called only in case of client memory buffers +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::WritePictureL( TVideoPicture* aPicture ) + { + PRINT_ENTRY; + + // This method should only be called only in following states + if( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "WritePictureL () called before Initialize ()" ); + User::Leave( KErrNotReady ); + } + + if( iEncStateMac->IsInputEndPending() ) + { + PRINT_ERR( "Input end is pending.. leaving with KErrEof" ); + User::Leave( KErrEof ); + } + + if( !aPicture || + ( aPicture->iData.iRawData->Length() == 0 ) || + ( aPicture->iData.iRawData->Length() != + ( ( iH264EncInitParams.iPictureSize.iWidth * + iH264EncInitParams.iPictureSize.iHeight * 3 ) / 2 ) ) || + ( aPicture->iData.iDataFormat != EYuvRawData ) ) + { + PRINT_ERR( "Incorrect parameter passed" ); + User::Leave( KErrArgument ); + return; + } + + // Added a check to return the input picture if application tries to add + // pictures after calling InputEnd() or Stop() and before calling + // Start() again. + + if ( iEncStateMac->IsStopped() ) + { + SkipInputPicture( aPicture ); + return; + } + + // counter to represent the num of input pictures received + iPictureCounters.iInputPictures++; + if( IsForcedIFrameRequired( aPicture ) ) + { + iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_FORCED_I_FRAME, NULL ); + iPictureLoss = EFalse; + } + + //Check if clock source is enabled skip logic + if ( iClockSource ) + { + if ( ( !CanEncode( aPicture ) ) || iFrozen ) + { + SkipInputPicture( aPicture ); + return; + } + } + + TInt error = iEngine->AddInput( aPicture ); + if( error != KErrNone ) + { + PRINT_ERR( "CAriH264encHwDeviceImpl::WritePictureL()" + " AddInput() failed" ); + User::Leave( error ); + return; + } + + if( this->iH264EncInitParams.iProcessRealtime ) + { + // Check the iDataUnitType + if( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + TInt perPictureSegmentBuffers + = iH264EncInitParams.iMinNumOutputBuffers + / KH264ENCIMPL_MAXNUM_OUTPUTBUFFERS; + TInt queueCount = iOutputFreeBufferQueue.Count(); + // Check for availability of segment buffers + if ( queueCount < perPictureSegmentBuffers ) + { + // Sufficient number of segment buffers are not present + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl" + "::WritePictureL() Input returned EDuVideoSegment " ) ); + // Return the earlier input picture added to the queue + iEngine->ReturnInput(); + return; + } + } + else + { + // Check for availability of buffers. + if ( iEngine->NumOutputBuffers() == 0 ) + { + // Return the earlier input picture added to the queue + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::WritePictureL() Input returned EDuCodedPicture " ) ); + iEngine->ReturnInput(); + return; + } + } + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Notifies the hardware device that the end of input data has been reached +// and no more input pictures will be written +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::InputEnd() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EInputEndCommand ) ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( iEngine->NumInputBuffers() == 0 ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriH264encHwDeviceImpl::InputEnds()" ) ); + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return; + } + else + { + iInputEndCalled = ETrue; + } + + iEncStateMac->Transit( CStateMachine::EInputEndCommand ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Starts recording video +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Start() + { + PRINT_ENTRY; + + if( iEncStateMac->IsPlaying() && !iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::Start()-already in" + "started state, So ignore" ) ); + return; + } + + if( !iEncStateMac->IsTransitionValid( CStateMachine::EStartCommand ) ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + // Enable flag which indicates that all picture params and sequence + // params are put into 1st buffer + iIsConfigDataFilledInFirstOutputBuffer = ETrue; + for( TInt i = 0; i <= iInternalOutputBufferQueue.Count(); i++ ) + { + TVideoOutputBuffer *outputBuffer = iInternalOutputBufferQueue[0]; + iEngine->AddOutput( ( TAny* )outputBuffer ); + iInternalOutputBufferQueue.Remove( 0 ); + } + } + else + { + // add all output buffers to engine + for( TInt i = 0; i <= iOutputFreeBufferQueue.Count(); i++ ) + { + TVideoOutputBuffer *outputBuffer = iOutputFreeBufferQueue[0]; + iEngine->AddOutput( ( TAny* )outputBuffer ); + iOutputFreeBufferQueue.Remove( 0 ); + } + } + + if ( iClockSource ) + { + TTime lSystemTime; + lSystemTime.UniversalTime(); + UpdateTime(); + iPeriodicTimer->Start( iPollingInterval, iPollingInterval, + TCallBack( CAriH264encHwDeviceImpl::TimerCallBack, ( TAny* )this ) ); + } + + iEngine->Start(); + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::Start() Change to " + " start state** ") ) ; + iEncStateMac->Transit( CStateMachine::EStartCommand ); + + PRINT_EXIT; + + } + +//---------------------------------------------------------------------------- +// Callback function to CPeriodicTimer object +//---------------------------------------------------------------------------- +// +TInt CAriH264encHwDeviceImpl::TimerCallBack( TAny* aPtr ) + { + PRINT_ENTRY; + if ( !aPtr ) + { + ( ( CAriH264encHwDeviceImpl* )aPtr )->ClientFatalError( + KErrArgument ); + return KErrNone; + } + PRINT_EXIT; + return ( ( CAriH264encHwDeviceImpl* )aPtr )->UpdateTime(); + } + +//---------------------------------------------------------------------------- +// Stops recording video. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Stop() + { + PRINT_ENTRY; + + if( iEncStateMac->IsStopped() ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::Stop() -> already " + "in stop state, so ignore" ) ); + return; + } + + if( !iEncStateMac->IsTransitionValid( CStateMachine::EStopCommand ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriH264encHwDeviceImpl::Stop() -> " + "fatalerror because Stop called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + iInputEndCalled = EFalse; + iIsSliceEnabledInCodedPicture = EFalse; + + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + // new clip started so config data has to be filled in first output + // buffer + iIsConfigDataFilledInFirstOutputBuffer = ETrue; + iTotalOutputBufferLengthInPacketMode = 0; + iTotalLengthFilledSoFarInPacketMode = 0; + iPacketsPending = EFalse; + } + + iEngine->Stop(); + iEngine->Reset(); + + iFrozen = EFalse; + if( iPeriodicTimer ) + { + iPeriodicTimer->Cancel(); + } + iEncStateMac->Transit( CStateMachine::EStopCommand ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Pauses video recording +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Pause() + { + PRINT_ENTRY; + + if( iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::Pause()-> already" + "in Paused state, so ignore" ) ); + return; + } + + if( !iEncStateMac->IsTransitionValid( CStateMachine::EPauseCommand ) ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::Pause() Pause " + "called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + // No arguments to be passed in Pause + if( iClockSource ) + { + iPeriodicTimer->Cancel(); + //Note down the clock when paued + iClockTimeWhenPaused = iClockSource->Time().Int64(); + } + + // Stop the engine + iEngine->Stop(); + + //Change the state of the encoder + iEncStateMac->Transit( CStateMachine::EPauseCommand ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Resumes video recording +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Resume() + { + PRINT_ENTRY; + + // doing it before transitionvalid check because initialize->resume is + // not added + if( iEncStateMac->IsInInitializedState() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::Resume()->Got resume" + " in initialized state. So go to start()" ) ); + Start(); + return; + } + + if( iEncStateMac->IsPlaying() && !iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::Resume()->already in" + " playing-not-paused state, so ignore" ) ); + return; + } + + if( !iEncStateMac->IsTransitionValid( CStateMachine::EResumeCommand ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("Resume called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + // No arguments to be passed in Resume + if ( iClockSource ) + { + //Clock may or may not be paused, when HWDevice is paused, so + //add the paused duration to clock + iPauseOffset = iClockSource->Time().Int64(); + iPauseOffset -= iClockTimeWhenPaused; + + //calculate the total time and deviation + iTotalTime += iPauseOffset; + TTime lSystemTime; + lSystemTime.UniversalTime(); + + // Send Update time before sending Resume command, so that clock + // source is set before + + UpdateTime (); + iPeriodicTimer->Start( iPollingInterval, iPollingInterval, + TCallBack( CAriH264encHwDeviceImpl::TimerCallBack, ( TAny* )this ) ); + } + + // Start the engine + iEngine->Start(); + + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + + // send the remaining pending packets to client + while ( iOutputFreeBufferQueue.Count() && iPacketsPending ) + { + TVideoOutputBuffer *outBuf = iOutputFreeBufferQueue[0]; + FillVideoSegment( outBuf, iInternalOutputBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + + #ifdef CALCINSTANTBITRATE + CalculateInstantBitRate( *outBuf ); + #endif + + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + //Change the state of the encoder + iEncStateMac->Transit( CStateMachine::EResumeCommand ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Freezes the input picture +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::Freeze() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriH264encHwDeviceImpl::Freeze() Freeze" + " called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return; + } + iFrozen = ETrue; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Releases a frozen input picture +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ReleaseFreeze() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::ReleaseFreeze() " + "called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return; + } + iFrozen = EFalse; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Returns the current recording position +//---------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriH264encHwDeviceImpl::RecordingPosition() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriH264encHwDeviceImpl::RecordingPosition()" + " called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return TTimeIntervalMicroSeconds( 0 ); + } + + PRINT_EXIT; + return TTimeIntervalMicroSeconds( iLastEncodedPictureTimestamp ); + } + +//---------------------------------------------------------------------------- +// Reads various counters related to processed video pictures +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::GetPictureCounters( + CMMFDevVideoRecord::TPictureCounters& aCounters ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + TUint numofpacktsskipped; + TUint err = iCodec->GetParam( CONTROL_CMD_GET_PICTURES_SKIPPED, + &numofpacktsskipped ); + if ( err ) + { + ClientFatalError( err ); + return; + } + + iPictureCounters.iPicturesSkippedRateControl + = iPictureCounters.iPicturesSkippedRateControl + numofpacktsskipped; + + iPictureCounters.iPicturesProcessed + = iPictureCounters.iInputPictures + - iPictureCounters.iPicturesSkippedRateControl; + + aCounters = iPictureCounters; + + //reset the counters + iPictureCounters.iInputPictures = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Reads the frame stabilisation output picture position. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::GetFrameStabilisationOutput( TRect&/* aRect*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + ClientFatalError( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Retrieves the number of complexity control levels available for this +// hardware device +//---------------------------------------------------------------------------- +// +TUint CAriH264encHwDeviceImpl::NumComplexityLevels() + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return 0; + } + + PRINT_EXIT; + return( KH264ENCIMPL_NUM_COMPLEXITYLEVELS ); + } + +//---------------------------------------------------------------------------- +// Sets the complexity level to use for video processing in a hardware device +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetComplexityLevel( TUint aLevel ) + { + PRINT_ENTRY; + + if( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if( aLevel >= KH264ENCIMPL_NUM_COMPLEXITYLEVELS ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriH264encHwDeviceImpl" + "::SetComplexityLevel() Unsupported level Passed" ) ); + ClientFatalError( KErrArgument ); + } + + iH264EncInitParams.iComplexityLevel = aLevel; + TH264EncInitParams *currentParams = NULL; + TRAPD( error, currentParams = new( ELeave ) TH264EncInitParams ); + *currentParams = iH264EncInitParams; + + // Add command apply commit settings to the codec + TRAP( error, iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_COMPLEXITY_LEVEL, currentParams ) ); + + if( error != KErrNone ) + { + delete currentParams; + ClientFatalError( error ); + return; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Retrieves information about the pre-processing capabilities of this +// hardware device. +//---------------------------------------------------------------------------- +// +CPreProcessorInfo* CAriH264encHwDeviceImpl::PreProcessorInfoLC() + { + PRINT_ENTRY; + + TInt cleanupstackpushcount = 0; + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called after Initialize()" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + _LIT( KManufacturer, "" ); + _LIT( KIdentifier, "" ); + + TPtrC8 implementationSpecificInfo( NULL,0 ); + RArray inputFormats; + CleanupClosePushL( inputFormats ); + cleanupstackpushcount++; + inputFormats.Reset(); + + RArray outputFormats; + CleanupClosePushL( outputFormats ); + cleanupstackpushcount++; + outputFormats.Reset(); + + RArray supportedCombinations; + CleanupClosePushL( supportedCombinations ); + cleanupstackpushcount++; + supportedCombinations.Reset(); + + RArray supportedScaleFactors; + CleanupClosePushL( supportedScaleFactors ); + cleanupstackpushcount++; + supportedScaleFactors.Reset(); + + TYuvToYuvCapabilities yuvToYuvCapabilities; + TUid uid; + + CPreProcessorInfo *preProcessorInfo = CPreProcessorInfo::NewL( uid.Null(), + KManufacturer, + KIdentifier, + TVersion( 0,0,0 ), + EFalse, + EFalse, + inputFormats.Array(), + outputFormats.Array(), + supportedCombinations.Array(), + EFalse, + EFalse, + supportedScaleFactors.Array(), + yuvToYuvCapabilities, + 0, + 0, + implementationSpecificInfo ); + + CleanupStack::PushL( preProcessorInfo ); + CleanupStack::Pop( cleanupstackpushcount ); + + PRINT_EXIT; + return preProcessorInfo ; + } + +//---------------------------------------------------------------------------- +// Sets the hardware device input format +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetInputFormatL( + const TUncompressedVideoFormat& aFormat, const TSize& aPictureSize ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetInputFormatL () called after Initialize()..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + if( !CheckInputFormat( aFormat ) ) + { + PRINT_ERR("CAriH264encHwDeviceImpl" + "::SetInputFormatL() Leaving because of not support input format" ); + User::Leave( KErrNotSupported ); + } + + // Check if passed size is supported by encoder + // Check if encoder supports the passed input format + // supports all sizes which are multiple of 16 pixels + + if ( ( !aPictureSize.iWidth ) || ( !aPictureSize.iHeight ) || + ( aPictureSize.iWidth % 16 ) || ( aPictureSize.iHeight % 16 ) || + ( aPictureSize.iWidth > KH264ENCIMPL_SDTV_WIDTH ) || + ( aPictureSize.iHeight > KH264ENCIMPL_SDTV_HEIGHT_PAL ) ) + { + PRINT_ERR( "Incorrect parameter passed.. leaving" ); + User::Leave( KErrNotSupported ); + } + + TInt32 aspectratio = ::MapAspectRatio( + aFormat.iYuvFormat.iAspectRatioNum, + aFormat.iYuvFormat.iAspectRatioDenom ); + + if ( aspectratio == -1 ) + { + PRINT_ERR( "Aspect ratio is -1.. leaving" ); + User::Leave( KErrNotSupported ); + } + + iH264EncInitParams.iAspectRatio = aspectratio; + iH264EncInitParams.iInputFormat = aFormat; + iH264EncInitParams.iPictureSize = aPictureSize; + iH264EncInitParams.iBeforeInitialize |= EEncInputFormat; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the data source to be a camera, and sets the device to use direct +// capture for input. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetSourceCameraL( TInt /*aCameraHandle*/, + TReal /*aPictureRate*/ ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetSourceCameraL() called after Initialize()..leaving" ); + User::Leave( KErrPermissionDenied ); + return; + } + + User::Leave( KErrNotSupported ); + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets the data source to be memory buffers. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetSourceMemoryL( TReal aMaxPictureRate, + TBool aConstantPictureRate, + TBool aProcessRealtime ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetSourceMemoryL() called after Initialize()..leaving" ); + User::Leave( KErrPermissionDenied ); + return; + } + + if( ( aMaxPictureRate <= 0 ) || + ( aMaxPictureRate > KH264ENCIMPL_MAX_PICTURERATE ) ) + { + PRINT_ERR( "Incorrect value of max picture rate..leaving" ); + User::Leave( KErrNotSupported ); + return; + } + + // Check for the picture rates supported + PRINT_MSG( LEVEL_LOW, ( "CAriH264encHwDeviceImpl::SetSourceMemoryL() " + "Memory Picture rate is set as %f", aMaxPictureRate ) ); + + iH264EncInitParams.iMaxPictureRate = aMaxPictureRate; + iH264EncInitParams.iConstantPictureRate = aConstantPictureRate; + iH264EncInitParams.iProcessRealtime = aProcessRealtime; + iH264EncInitParams.iBeforeInitialize |= EEncSourceMemory; + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Sets the clock source to use for video timing. If no clock +// source is set. video encoding will not be synchronized, but +// will proceed as fast as possible, depending on input data and +// output buffer availability. +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetClockSource( MMMFClockSource* aClock ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if( !aClock ) + { + ClientFatalError( KErrArgument ); + return; + } + + PRINT_MSG( LEVEL_LOW, ( " CAriH264encHwDeviceImpl::SetClockSource() " + "encoder clockSource is %x", ( TInt ) aClock ) ); + + iClockSource = aClock; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for RGB to YUV color space conversion +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetRgbToYuvOptionsL( TRgbRange /*aRange*/, + const TYuvFormat& /*aOutputFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetRgbToYuvOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for YUV to YUV data format conversion +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetYuvToYuvOptionsL( + const TYuvFormat& /*aInputFormat*/, + const TYuvFormat& /*aOutputFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetYuvToYuvOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets the pre-processing types to be used in a hardware device +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetPreProcessTypesL( + TUint32 /*aPreProcessTypes*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetPreProcessTypesL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for rotation +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetRotateOptionsL( + TRotationType /*aRotationType*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetRotateOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for scaling +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetScaleOptionsL( const TSize& /*aTargetSize*/, + TBool /*aAntiAliasFiltering*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetScaleOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for input cropping +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetInputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetInputCropOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for output cropping +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetOutputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetOutputCropOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for output padding +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetOutputPadOptionsL( + const TSize& /*aOutputSize*/, const TPoint& /*aPicturePos*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetOutputPadOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets color enhancement pre-processing options +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetColorEnhancementOptionsL( + const TColorEnhancementOptions& /*aOptions*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetColorEnhancementOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets frame stabilisation options +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetFrameStabilisationOptionsL( + const TSize& /*aOutputSize*/, TBool /*aFrameStabilisation*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetFrameStabilisationOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets custom implementation-specific pre-processing options. +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SetCustomPreProcessOptionsL( + const TDesC8& /*aOptions*/) + { + PRINT_ENTRY; + PRINT_ERR( "SetCustomPreProcessOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Proxy which recieves callbacks from Hw Device +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetProxy( MMMFDevVideoRecordProxy& aProxy ) + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return ; + } + iMMFDevVideoRecordProxy = &aProxy; + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Callback to indicate the input buffer is consumed +//---------------------------------------------------------------------------- +// + +TInt CAriH264encHwDeviceImpl::InputBufferConsumed ( TAny* aInp, TInt aError ) + { + PRINT_ENTRY; + + if( !aInp ) + { + return KErrArgument; + } + + TVideoPicture *picture = (TVideoPicture *) aInp; + if( ( picture->iOptions & TVideoPicture::ETimestamp ) + && aError != ( KErrCancel ) ) + { + iLastEncodedPictureTimestamp = picture->iTimestamp.Int64(); + } + + // if custom buffer emabled then add it to queue else return the picture + // to client + if ( !iInputBufReturnToPreProc ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::InputBufferConsumed()-return picture back to client" ) ); + + iMMFDevVideoRecordProxy->MdvrpReturnPicture( picture ); + } + else + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::InputBufferConsumed()-return picture back to Input Device" ) ); + iInputDevice->ReturnPicture( picture ); + } + + if ( iInputEndCalled && ( iEngine->NumInputBuffers() == 0 ) + && ( iCodec->IsCurrentPictureSkipped() ) ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriH264encHwDeviceImpl" + "::InputBufferConsumed()::Calling stream end " ) ); + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return( KErrNone ); + } + + PRINT_EXIT; + return KErrNone; + } + +//---------------------------------------------------------------------------- +// Callback to indicate the output buffer is ready +//---------------------------------------------------------------------------- +// + +TInt CAriH264encHwDeviceImpl::OutputBufferReady ( TAny* aOup, TInt aError ) + { + PRINT_ENTRY; + + TVideoOutputBuffer *outputBuf = ( TVideoOutputBuffer* ) aOup; + TInt error = KErrNone; + TInt length = outputBuf->iData.Length(); + + if (iFrozen) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::OutputBufferReady() " + "Frozen state, so drop output picture" ) ); + outputBuf->iData.Set( ( TUint8* )outputBuf->iData.Ptr() + ,iOutputBufferSize ); + iEngine->AddOutput( outputBuf ); + return KErrNone; + } + + if( aError == KErrNone ) + { + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + error = iInternalOutputBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError ( error ); + return KErrNone; + } + + // get the packet offset infor + error = iCodec->GetParam( CONTROL_CMD_GET_PACKET_OFFSET_DATA, + iFreeBufferQueueForPacketOffsetInfo[0] ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + //remove the first element and add it to filled Queue + TUint* filledOffsetLengthInfoBuffer + = iFreeBufferQueueForPacketOffsetInfo[0]; + iFreeBufferQueueForPacketOffsetInfo.Remove( 0 ); + error = iFilledBufferQueueForPacketOffsetInfo.Append( + filledOffsetLengthInfoBuffer ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + if ( !iTotalLengthFilledSoFarInPacketMode ) + { + iTotalOutputBufferLengthInPacketMode + = iInternalOutputBufferQueue[0]->iData.Length(); + iPacketOffSetCurrentPosition + = iFilledBufferQueueForPacketOffsetInfo[0]; + iPacketsPending = ETrue; + + while ( iOutputFreeBufferQueue.Count() && iPacketsPending ) + { + TVideoOutputBuffer *outBuf = iOutputFreeBufferQueue[0]; + FillVideoSegment( outBuf, iInternalOutputBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + + #ifdef CALCINSTANTBITRATE + CalculateInstantBitRate( *outBuf ); + #endif + + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + TInt ts + = ( TInt ) ( ( outputBuf->iCaptureTimestamp ).Int64() / 1000 ); + iSizePerFrame = 0; + } + else + { + #ifdef CALCINSTANTBITRATE + CalculateInstantBitRate( *outputBuf ); + #endif + + iSizePerFrame = outputBuf->iData.Length(); + iSizePerFrame = 0 ; + // inform devvideo record that the new encoded buffer is + // avaibable + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outputBuf ); + } + iNoOfOutputFramesPerSec++; + } + + else if ( aError == KErrCancel ) + { + // add the buffer back to outputQueue + outputBuf->iData.Set( ( TUint8* )outputBuf->iData.Ptr(), + iOutputBufferSize ); + + if ( iH264EncInitParams.iDataUnitType == EDuVideoSegment ) + { + error = iInternalOutputBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + else + { + error = iOutputFreeBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + else + { + ClientFatalError( aError ); + return KErrNone; + } + + if ( iInputEndCalled && ( iEngine->NumInputBuffers() == 0 ) ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriH264encHwDeviceImpl" + "::OutputBufferReady()::Calling stream end " ) ); + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return( KErrNone ); + } + + PRINT_EXIT; + return KErrNone; + } + +//---------------------------------------------------------------------------- +// Callback to indicate the command has been processed +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::CommandProcessed ( TInt aCmd, TAny* aCmdData, + TInt aError ) + { + PRINT_ENTRY; + + switch( aCmd ) + { + case CONTROL_CMD_SET_RATE_CONTROL_OPTIONS: + { + TRateControlOptions *options = ( TRateControlOptions* ) aCmdData; + delete options; + } + break; + + case CONTROL_CMD_SET_FORCED_I_FRAME: + { + } + break; + + case CONTROL_CMD_SET_COMMIT_OPTIONS: + { + TH264EncInitParams *currentParams + = ( TH264EncInitParams* ) aCmdData; + if( ( aError != KErrNone ) || ( aError != KErrCancel ) ) + { + delete currentParams; + return; + } + else{ + iH264EncInitParams.iBitErrors + = currentParams->iBitErrors; + iH264EncInitParams.iPacketLosses + = currentParams->iPacketLosses; + iH264EncInitParams.iRandomAccessRate + = currentParams->iRandomAccessRate; + + delete currentParams; + } + } + break; + + case CONTROL_CMD_SET_COMPLEXITY_LEVEL: + { + TH264EncInitParams *currentParams + = ( TH264EncInitParams* ) aCmdData; + delete currentParams; + } + break; + + case CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE: + { + TReal* currentParams = ( TReal* )aCmdData; + delete currentParams; + } + break; + + case CONTROL_CMD_SET_SLICELOSS: + { + TH264EncSliceLoss* currentParams + = ( TH264EncSliceLoss* )aCmdData; + delete currentParams; + } + break; + + default: + break; + } + PRINT_EXIT; + return; + } + +//---------------------------------------------------------------------------- +// Called when a fatal error occurs in process engine +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::FatalErrorFromProcessEngine( TInt aError ) + { + PRINT_ENTRY; + + ClientFatalError( aError ); + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Enables inserting H324 pre-defined config data (VOL / SPS / PPS / etc. ) +//---------------------------------------------------------------------------- +// + +TInt CAriH264encHwDeviceImpl::H324AnnexKDefinedEncoderConfigDataOn() + { + PRINT_ENTRY; + + if( iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_LOW, ("Not permitted as the encoder is already " + "initialised" ) ); + return KErrNotReady; + } + iH264EncInitParams.iVTFastCallSetUp = ETrue; + + PRINT_EXIT; + return KErrNone; + } + + +//---------------------------------------------------------------------------- +// 2 phase constructor +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ConstructL() + { + PRINT_ENTRY; + + TInt error = KErrNone; + + // Create Array of Supported Input Formats + TUncompressedVideoFormat inputFormat; + + inputFormat.iDataFormat = EYuvRawData; + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range0; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + inputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + inputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + inputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + inputFormat.iYuvFormat.iAspectRatioNum = 1; + inputFormat.iYuvFormat.iAspectRatioDenom = 1; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma2; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma3; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range1; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma2; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma3; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + + inputFormat.iYuvFormat.iCoefficients = EYuvBt601Range0; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma2; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma3; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt601Range1; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma2; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma3; + error = iSupportedInputFormats.Append( inputFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending input format...leaving \n" ); + User::Leave( error ); + } + + // Create Array of Supported Output Formats + CCompressedVideoFormat* compressedVideoFormat = + CCompressedVideoFormat::NewL( KH264MimeType ); + + CleanupStack::PushL( compressedVideoFormat ); + error = iSupportedOutputFormats.Append( compressedVideoFormat ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + // unknown level is set for short mime type - decide in initialize + error = iLevels.Append( KH264ENCIMPL_LEVEL_UNKNOWN ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 1 + CCompressedVideoFormat* compressedVideoFormat2 = + CCompressedVideoFormat::NewL( KH264MimeType2 ); + + CleanupStack::PushL( compressedVideoFormat2 ); + error = iSupportedOutputFormats.Append( compressedVideoFormat2 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_1 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 1.1 + // Bitrate and level will be decided in Initialize + CCompressedVideoFormat* compressedVideoFormat3 = + CCompressedVideoFormat::NewL( KH264MimeType3 ); + + CleanupStack::PushL( compressedVideoFormat3 ); + error = iSupportedOutputFormats.Append( compressedVideoFormat3 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_11 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 1.2 + CCompressedVideoFormat* compressedVideoFormat4 = + CCompressedVideoFormat::NewL( KH264MimeType4 ); + + CleanupStack::PushL( compressedVideoFormat4 ); + error = iSupportedOutputFormats.Append( compressedVideoFormat4 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_12 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 1.3 + CCompressedVideoFormat* compressedVideoFormat5 = + CCompressedVideoFormat::NewL( KH264MimeType5 ); + + CleanupStack::PushL( compressedVideoFormat5 ); + error = iSupportedOutputFormats.Append( compressedVideoFormat5 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_13 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 2 + CCompressedVideoFormat* compressedVideoFormat6 = + CCompressedVideoFormat::NewL( KH264MimeType6 ); + + CleanupStack::PushL( compressedVideoFormat6 ); + + error = iSupportedOutputFormats.Append( compressedVideoFormat6 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_2 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 2.1 + CCompressedVideoFormat* compressedVideoFormat7 = + CCompressedVideoFormat::NewL( KH264MimeType7 ); + + CleanupStack::PushL( compressedVideoFormat7 ); + + error = iSupportedOutputFormats.Append( compressedVideoFormat7 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_21 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 2.2 + CCompressedVideoFormat* compressedVideoFormat8 = + CCompressedVideoFormat::NewL( KH264MimeType8 ); + + CleanupStack::PushL( compressedVideoFormat8 ); + + error = iSupportedOutputFormats.Append( compressedVideoFormat8 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_22 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 3 + CCompressedVideoFormat* compressedVideoFormat9 = + CCompressedVideoFormat::NewL( KH264MimeType9 ); + + CleanupStack::PushL( compressedVideoFormat9 ); + + error = iSupportedOutputFormats.Append( compressedVideoFormat9 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_3 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + // Level 1b + CCompressedVideoFormat* compressedVideoFormat10 = + CCompressedVideoFormat::NewL( KH264MimeType10 ); + + CleanupStack::PushL( compressedVideoFormat10 ); + + error = iSupportedOutputFormats.Append( compressedVideoFormat10 ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending output format...leaving \n" ); + User::Leave( error ); + } + CleanupStack::Pop(); + + error = iLevels.Append( KH264ENCIMPL_LEVEL_1b ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending supported level...leaving \n" ); + User::Leave( error ); + } + + iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityIdle ); + iOutputFreeBufferQueue.Reset(); + iInternalOutputBufferQueue.Reset(); + iEncStateMac = CStateMachine::NewL(); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sends the updated time to the codec +//---------------------------------------------------------------------------- +// +TInt CAriH264encHwDeviceImpl::UpdateTime() + { + PRINT_ENTRY; + + if ( !iClockSource ) + { + ClientFatalError( KErrBadHandle ); + return -1; + } + + // send the time values to the codec + iCodec->SetUpdatedRefernceTime( iTotalTime ); + + PRINT_EXIT; + return 1; + } + +//---------------------------------------------------------------------------- +// Create the output buffers in Coded picture mode +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::CreateCodedOutputBuffersL( TUint aSize ) + { + PRINT_ENTRY; + + if( iH264EncInitParams.iDataUnitType != EDuVideoSegment ) + { + iOutputBufferSize = aSize; + } + + // Allocate memory for TVideoOutputBuffer + iOutputBuffers = new ( ELeave ) TVideoOutputBuffer[ + iH264EncInitParams.iMinNumOutputBuffers]; + + for ( TInt i = 0; i < iH264EncInitParams.iMinNumOutputBuffers; i++ ) + { + iOutputBuffers[i].iData.Set( NULL, 0); + } + + // Create the Buffer and add it to Queue + for ( TInt i = 0; i < iH264EncInitParams.iMinNumOutputBuffers; i++ ) + { + TUint8* ptr = new ( ELeave ) TUint8[aSize]; + CleanupStack::PushL( ptr ); + iOutputBuffers[i].iData.Set( ptr, aSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( iOutputBuffers[i] ); + TInt error = iOutputFreeBufferQueue.Append( iOutputBuffers + i ); + if ( error != KErrNone ) + { + PRINT_ERR( "Error while appending output buffer to the" + "output buffer queue \n" ); + User::Leave( error ); + return; + } + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Creates the temporary output buffers +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::CreateInternalOutputBuffersL( + TUint aBufferSize ) + { + PRINT_ENTRY; + + iOutputBufferSize = aBufferSize; + + // Allocate memory for TVideoOutputBuffer + iInternalOutputBuffers = new ( ELeave ) TVideoOutputBuffer[ + KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS]; + + for ( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iInternalOutputBuffers[i].iData.Set( NULL, 0 ); + } + + // Create the Buffer and add it to Queue + for ( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + CleanupStack::PushL( ptr ); + iInternalOutputBuffers[i].iData.Set( ptr, aBufferSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( iInternalOutputBuffers[i] ); + TInt error + = iInternalOutputBufferQueue.Append( iInternalOutputBuffers + i ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Creates the buffers required to store length and offset +// info of packets +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::CreatePacketOffsetLengthInfoBuffersL( + TUint aNumOfPackets ) + { + PRINT_ENTRY; + + iPacketOffSetAndLengthInfoBuffers = new ( ELeave ) + ( TUint*[KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS] ); + + for ( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iPacketOffSetAndLengthInfoBuffers[i] = NULL; + } + + for ( TInt i = 0; i < KH264ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iPacketOffSetAndLengthInfoBuffers[i] = ( TUint* ) ( new ( ELeave ) + TUint8[aNumOfPackets] ); + TInt error = iFreeBufferQueueForPacketOffsetInfo.Append( + iPacketOffSetAndLengthInfoBuffers[i] ); + if( error != KErrNone ) + { + PRINT_ERR( "Error while appending packet lengthoffset buffer to " + "queue \n" ); + User::Leave( error ); + } + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// decides whether picture can be encoded or not +//---------------------------------------------------------------------------- +// +TBool CAriH264encHwDeviceImpl::CanEncode( TVideoPicture *aPicture ) + { + PRINT_ENTRY; + + // check with the last encoded picture and decide whether it can be + // processed or skipped + if( aPicture->iTimestamp.Int64() < iLastEncodedPictureTimestamp ) + { + return EFalse; + } + + // check with current clock + if( ( aPicture->iTimestamp.Int64() ) < ( ( iClockSource->Time().Int64() - + iTotalTime ) + KH264ENCIMPL_ENCODEAHEAD ) ) + { + return EFalse; + } + + PRINT_EXIT; + return ETrue; + } +//---------------------------------------------------------------------------- +// Skips the Input Picture +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::SkipInputPicture( TVideoPicture *aPicture ) + { + + PRINT_ENTRY; + + // add the buffer back to queue + if ( !iInputBufReturnToPreProc ) + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::SkipInputPicture()" + "-return picture back to client" ) ); + iMMFDevVideoRecordProxy->MdvrpReturnPicture( aPicture ); + } + else + { + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::SkipInputPicture()-" + "return picture back to Input Device" ) ); + iInputDevice->ReturnPicture( aPicture ); + } + + if ( !iFrozen ) + { + iPictureCounters.iPicturesSkippedRateControl++; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Indicates whether the next frame is to be encoded as an I frame +//---------------------------------------------------------------------------- +// +TBool CAriH264encHwDeviceImpl::IsForcedIFrameRequired( + TVideoPicture* aPicture ) + { + PRINT_ENTRY; + + if( ( aPicture->iOptions & TVideoPicture::EReqInstantRefresh ) || + iPictureLoss ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriH264encHwDeviceImpl" + "::IsForcedIFrameRequired() ETrue 1--" ) ); + return ETrue; + } + + PRINT_EXIT; + return EFalse; + } + +//---------------------------------------------------------------------------- +// Extracts 1 packet from a frame and Fills output buffer with the same +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::FillVideoSegment( + TVideoOutputBuffer* aOutputBuf, TVideoOutputBuffer* aSrcOutputBuf ) + { + PRINT_ENTRY; + + // first time fill all config information in one o/p buffer + if ( iIsConfigDataFilledInFirstOutputBuffer ) + { + TUint configDataLength = 0; + TUint* startPtr = iPacketOffSetCurrentPosition; + TInt noOfConfigParamas = 0; + +#ifdef EMZ_AVC_ENC_CODEC_SEIINFO_ENABLE + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::FillVideoSegment() " + "SEI enabled" ) ); + noOfConfigParamas= KNumOfConfigParams_SEI; +#else + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::FillVideoSegment() " + "SEI disabled" ) ); + noOfConfigParamas= KNumOfConfigParams; +#endif + for( TInt i = 0; i < noOfConfigParamas; i++ ) + { + configDataLength += * ( ++startPtr ) ++; + } + + // copy data into output buffer + Mem::Copy( ( TUint8* )( ( TUint8* )aOutputBuf->iData.Ptr() ), + ( TUint8* )( aSrcOutputBuf->iData.Ptr() ), configDataLength ); + + iTotalLengthFilledSoFarInPacketMode += configDataLength; + + if( iH264EncInitParams.iDataEncapsulation == EDuGenericPayload ) + { + + // word boundary calculation + TUint32 offset = ( TUint32 )( ( TUint8* )aOutputBuf->iData.Ptr() + + configDataLength ); + + if ( offset % KWordLength ) + { + offset = KWordLength - ( offset % KWordLength ); + } + else + { + offset = 0; + } + + configDataLength += offset; + TUint8* ptr = ( ( TUint8* )aOutputBuf->iData.Ptr() + + configDataLength ); + + // copy offset and length information + Mem::Copy( ptr, ( TUint8* )iPacketOffSetCurrentPosition, + ( noOfConfigParamas*KDoubleWordLength ) ); + + ptr += ( noOfConfigParamas * KDoubleWordLength ); + + //put the num of nal units information + TUint* nalInfo = ( TUint* )ptr; + nalInfo[0] = noOfConfigParamas; + + configDataLength += ( ( noOfConfigParamas*KDoubleWordLength ) + + KWordLength ); + } + + // increment the packet offsetpointer + iPacketOffSetCurrentPosition += ( noOfConfigParamas * 2 ); + aOutputBuf->iData.Set( aOutputBuf->iData.Ptr(),configDataLength ); + iIsConfigDataFilledInFirstOutputBuffer = EFalse; + } + else + { + TUint currentPacketLength = *( ++iPacketOffSetCurrentPosition ); + + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl::FillVideoSegment()" + " currentPacketLength is %d", ( TInt )currentPacketLength ) ); + + if ( iTotalLengthFilledSoFarInPacketMode + < iTotalOutputBufferLengthInPacketMode ) + { + Mem::Copy( ( TUint8* )( aOutputBuf->iData.Ptr() ), + ( TUint8* )( aSrcOutputBuf->iData.Ptr() + + iTotalLengthFilledSoFarInPacketMode ), currentPacketLength ); + + aOutputBuf->iData.Set( aOutputBuf->iData.Ptr(), + currentPacketLength ); + + iTotalLengthFilledSoFarInPacketMode + = iTotalLengthFilledSoFarInPacketMode + currentPacketLength; + + if ( iH264EncInitParams.iDataEncapsulation == EDuGenericPayload ) + { + // fill the offset and length information + TUint32 offset = ( TUint32 )( aOutputBuf->iData.Ptr() + + currentPacketLength ); + + if ( offset % KWordLength ) + { + offset = ( KWordLength - ( offset % KWordLength ) ); + } + else + { + offset = 0; + } + + TUint* ptr = ( TUint* ) ( aOutputBuf->iData.Ptr() + + currentPacketLength + offset ); + + ptr[0] = 0; + ptr[1] = *( iPacketOffSetCurrentPosition ); + ptr[2] = 1; + + aOutputBuf->iData.Set( aOutputBuf->iData.Ptr(), + currentPacketLength + offset + KDoubleWordLength + + KWordLength ); + } + + if ( iTotalLengthFilledSoFarInPacketMode == + iTotalOutputBufferLengthInPacketMode ) + { + iTotalLengthFilledSoFarInPacketMode = 0; + iPacketsPending = EFalse; + + // remove packet offset info buffer from filled Q and + // add it to free Q + TUint* freeOffsetLengthInfoBuffer + = iFilledBufferQueueForPacketOffsetInfo[0]; + + iFilledBufferQueueForPacketOffsetInfo.Remove( 0 ); + TInt error = iFreeBufferQueueForPacketOffsetInfo.Append( + freeOffsetLengthInfoBuffer ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + // Remove the internal buffer and add it back to process + // engine + if ( iInternalOutputBufferQueue.Count() ) + { + TVideoOutputBuffer* outBuf + = iInternalOutputBufferQueue[0]; + iInternalOutputBufferQueue.Remove( 0 ); + outBuf->iData.Set( ( TUint8* )outBuf->iData.Ptr(), + iOutputBufferSize ); + + // Add the Buffer back to the Process Engine + if( ( !iEncStateMac->IsInputEndPending() ) && + ( !iEncStateMac->IsStopped() ) ) + { + iEngine->AddOutput( ( TAny* )outBuf ); + } + } + + // Still more encoded packets are available + if( iInternalOutputBufferQueue.Count() ) + { + iPacketsPending = ETrue; + iTotalOutputBufferLengthInPacketMode + = iInternalOutputBufferQueue[0]->iData.Length(); + + // Get the packet offset info buffer + if( iFilledBufferQueueForPacketOffsetInfo.Count() ) + { + iPacketOffSetCurrentPosition + = iFilledBufferQueueForPacketOffsetInfo[0]; + } + } + } + else + { + ++iPacketOffSetCurrentPosition; + } + } + } + + // Update the specific members of the output buffer + aOutputBuf->iRequiredSeveralPictures + = aSrcOutputBuf->iRequiredSeveralPictures; + aOutputBuf->iRandomAccessPoint = aSrcOutputBuf->iRandomAccessPoint; + aOutputBuf->iCaptureTimestamp = aSrcOutputBuf->iCaptureTimestamp; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Initializes the members of the output coded buffers created +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::InitializeOuputCodedBuffer( + TVideoOutputBuffer& aOutputBuffer ) + { + PRINT_ENTRY; + + aOutputBuffer.iOrderNumber = 0; + aOutputBuffer.iMinErrorProtectionLevel = 1; + aOutputBuffer.iMaxErrorProtectionLevel = 1; + aOutputBuffer.iRequiredThisPicture = EFalse; + aOutputBuffer.iLayer = 0; + aOutputBuffer.iInLayerScalabilityStep = 0; + aOutputBuffer.iDataPartitionNumber = 0; + aOutputBuffer.iHrdVbvParams.Set( NULL, 0 ); + aOutputBuffer.iCodingStandardSpecificData.Set( NULL, 0 ); + aOutputBuffer.iImplementationSpecificData.Set( NULL, 0 ); + + // The following members will be modified later during execution + aOutputBuffer.iRequiredSeveralPictures = EFalse; + aOutputBuffer.iRandomAccessPoint = EFalse; + aOutputBuffer.iCaptureTimestamp = 0; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Sets level and bitrate based on size information +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::SetLevelAndBitRate() + { + PRINT_ENTRY; + + if( (iH264EncInitParams.iPictureSize.iWidth <= KH264ENCIMPL_QCIF_WIDTH ) + && ( iH264EncInitParams.iPictureSize.iHeight + <= KH264ENCIMPL_QCIF_HEIGHT ) ) + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_1; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_1; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + } + //QVGA + else + if( ( iH264EncInitParams.iPictureSize.iWidth + <= KH264ENCIMPL_QVGA_WIDTH ) && + ( iH264EncInitParams.iPictureSize.iHeight + <= KH264ENCIMPL_QVGA_HEIGHT ) ) + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_12; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_12; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + } + //CIF + else + if( ( iH264EncInitParams.iPictureSize.iWidth + <= KH264ENCIMPL_CIF_WIDTH ) && + ( iH264EncInitParams.iPictureSize.iHeight + <= KH264ENCIMPL_CIF_HEIGHT ) ) + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_13; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_13; + iH264EncInitParams.iTargetPictureRate = KPictureRate30; + } + // VGA + else + if( ( iH264EncInitParams.iPictureSize.iWidth + <= KH264ENCIMPL_VGA_WIDTH ) && + ( iH264EncInitParams.iPictureSize.iHeight + <= KH264ENCIMPL_VGA_HEIGHT ) ) + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_22; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_22; + iH264EncInitParams.iTargetPictureRate = KPictureRate15; + } + else + { + iH264EncInitParams.iLevel = KH264ENCIMPL_LEVEL_3; + iH264EncInitParams.iBitRate = KH264ENCIMPL_BITRATE_LEVEL_3; + iH264EncInitParams.iTargetPictureRate = KPictureRate25; + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Checks if the specified input format is supported or not +//---------------------------------------------------------------------------- +// +TBool CAriH264encHwDeviceImpl::CheckInputFormat( + const TUncompressedVideoFormat& aFormat ) + { + PRINT_ENTRY; + + // Check if encoder supports the passed input format + if ( aFormat.iDataFormat != EYuvRawData ) + { + return EFalse; + } + + if ( aFormat.iYuvFormat.iDataLayout != EYuvDataPlanar ) + { + PRINT_EXIT; + return EFalse; + } + + if ( ( aFormat.iYuvFormat.iCoefficients != EYuvBt709Range0 ) && + ( aFormat.iYuvFormat.iCoefficients != EYuvBt709Range1 ) && + ( aFormat.iYuvFormat.iCoefficients != EYuvBt601Range0 ) && + ( aFormat.iYuvFormat.iCoefficients != EYuvBt601Range1 ) ) + { + return EFalse; + } + + if ( ( aFormat.iYuvFormat.iPattern != EYuv420Chroma1 ) && + ( aFormat.iYuvFormat.iPattern != EYuv420Chroma2 ) && + ( aFormat.iYuvFormat.iPattern != EYuv420Chroma3 ) ) + { + return EFalse; + } + + PRINT_EXIT; + return ETrue; + } + + +//---------------------------------------------------------------------------- +// Nofities the client that the fatal error happend in Hw device +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ClientFatalError( TInt aError ) + { + PRINT_ENTRY; + PRINT_MSG( LEVEL_CRITICAL, ("CAriH264encHwDeviceImpl::ClientFatalError()" + " Error is %d", aError ) ); + + if( iClockSource ) + { + iPeriodicTimer->Cancel(); + } + + // Stop processing + if( !iEncStateMac->IsStopped() ) + { + if( iEncStateMac->IsInitialized() ) + { + Stop(); + } + } + iEncStateMac->Transit( CStateMachine::EDeadStateCommand ); + iMMFDevVideoRecordProxy->MdvrpFatalError( this, aError ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Output buffers are created with the specified size +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::ReallocSegmentOutputBuffersL( TUint aSize ) + { + PRINT_ENTRY; + + TInt count = iOutputFreeBufferQueue.Count(); + for ( TInt i = 0; i < count; i++ ) + { + // dellallocate memory for this buffer + TVideoOutputBuffer* ouputBuf = iOutputFreeBufferQueue[i]; + if ( ouputBuf->iData.Ptr() ) + { + delete ( TUint8* )ouputBuf->iData.Ptr(); + } + + // and allocate memory and store it in temp Q + TUint8* ptr = new ( ELeave ) TUint8[aSize]; + CleanupStack::PushL( ptr ); + ouputBuf->iData.Set( ptr, aSize ); + CleanupStack::Pop(); + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Reallocates single buffer +//---------------------------------------------------------------------------- +// +void CAriH264encHwDeviceImpl::ReallocateSegmentBufferL( + TVideoOutputBuffer* aBuffer ) + { + PRINT_ENTRY; + + TInt size = iH264EncInitParams.iMaxCodedSegmentSize; + if( iH264EncInitParams.iDataEncapsulation == EDuGenericPayload ) + { + size += KDoubleWordLength + KWordLength; + } + + if ( aBuffer->iData.Ptr() ) + { + delete ( TUint8* )aBuffer->iData.Ptr(); + } + + // and allocate memory and store it in temp Q + TUint8* ptr = new ( ELeave ) TUint8[size]; + CleanupStack::PushL( ptr ); + aBuffer->iData.Set( ptr, ( size ) ); + CleanupStack::Pop(); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Creates single buffer for frame mode to packet mode change +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::CreateCodedBufferForModeChangeL() + { + PRINT_ENTRY; + + iCodedBufferForPacketModeChange = new ( ELeave ) TVideoOutputBuffer; + TUint8* ptr = new ( ELeave ) TUint8[iOutputBufferSize]; + CleanupStack::PushL( ptr ); + iCodedBufferForPacketModeChange->iData.Set( ptr, iOutputBufferSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( *iCodedBufferForPacketModeChange ); + + PRINT_EXIT; + } + + +//---------------------------------------------------------------------------- +// Creates buffers which are used as output buffers in packet mode. Function +// is called only when frame mode - packet mode change occurs while encoding +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::CreateSegmentOutputBuffersL( + TUint aNumOfBuffers, TUint aSize ) + { + PRINT_ENTRY; + + TInt segmentSize = aSize; + // 4+4 bytes for offset and length + if( iH264EncInitParams.iDataEncapsulation == EDuGenericPayload ) + { + segmentSize += KDoubleWordLength + KWordLength; + } + + // Allocate memory for TVideoOutputBuffer + iSegmentBuffers = new ( ELeave ) TVideoOutputBuffer[aNumOfBuffers]; + for ( TInt i = 0; i < aNumOfBuffers; i++ ) + { + iSegmentBuffers[i].iData.Set( NULL, 0 ); + } + + // Create the Buffer and add it to Queue + for ( TInt i = 0; i < aNumOfBuffers; i++ ) + { + TUint8* ptr = new ( ELeave ) TUint8[segmentSize]; + CleanupStack::PushL( ptr ); + iSegmentBuffers[i].iData.Set( ptr, segmentSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( iSegmentBuffers[i] ); + TInt error = iOutputFreeBufferQueue.Append( iSegmentBuffers + i ); + if ( error != KErrNone ) + { + PRINT_ERR( "Error while appending segment output buffer to the" + "segment output buffer queue" ); + User::Leave( error ); + return; + } + } + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Calculates the instant bit rate +//---------------------------------------------------------------------------- +// + +void CAriH264encHwDeviceImpl::CalculateInstantBitRate( + const TVideoOutputBuffer &aOutBuf ) + { + PRINT_ENTRY; + + TInt size = 0; + TReal ts = ( ( aOutBuf.iCaptureTimestamp ).Int64() ) / 1000000.0; + size = aOutBuf.iData.Length(); + TInt32 partInt = 0; + Math::Int( partInt, ts ); + + // Calculate stream size, averaged per 1 second + if ( partInt > iCurrentIntTS ) + { + #ifdef DEBUG_INFO + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::CalculateInstantBitRate(), Stream size per 1 second: %d", + iStreamSize * 8 ) ); + PRINT_MSG( LEVEL_LOW, ("CAriH264encHwDeviceImpl" + "::CalculateInstantBitRate(), Number of frames per 1 second: " + " %d", iNoOfOutputFramesPerSec ) ); + #endif + // Reset global stream size + iStreamSize = 0; + iNoOfOutputFramesPerSec = 0; + iCurrentIntTS = partInt; + } + iSizePerFrame = iSizePerFrame + size; + iStreamSize = iStreamSize + size; + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// The implementation table entry which indicates the 1st function +// to call when H264 encoder hwdevice plugin is selected +//---------------------------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = + { + { KUidH264EncoderHwDeviceImplUid, + ( TProxyNewLPtr )( CAriH264encHwDeviceImpl::NewL ) } + }; + +//---------------------------------------------------------------------------- +// Returns the implementation table +//---------------------------------------------------------------------------- +// + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) +{ + aTableCount = sizeof( ImplementationTable ) + / sizeof( TImplementationProxy ); + return ImplementationTable; +} + + + + + + + + + + + + + + + + diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264encwrapper/export_hdr/arih264encwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264encwrapper/export_hdr/arih264encwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for wrapper APIs.Interface class for +* H264 encoder wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + + +#ifndef ARIH264ENCWRAPPER_H +#define ARIH264ENCWRAPPER_H + +// INCLUDES +#include +#include +#include +#include "aribasecodec.h" + +//Uncomment to generate debug information useful for tracking bitrate problems +//#define STORETOLOG + +// FORWARD DECLARATIONS +class MBaseCodecObserver; +class TH264EncInitParams; + + +class CAriH264encWrapper: public CBase, public MBaseCodec + { + + public: + + /** + * Two-phased constructor. + * @param aEncoderParams + * Encoder params used to create the encoder. + * @return pointer to an instance of CAriH264encWrapper + */ + IMPORT_C static CAriH264encWrapper* NewL( + TH264EncInitParams &aEncoderParams ); + + /**> Destructor */ + virtual ~CAriH264encWrapper(); + + + public: + + + /** + * From MBaseCodec + * Encodes an input buffer + * @param aInpBuf + * Coded input data passed by Engine. + * @param aOutBuf + * Encoded output data + * @leave "The method will leave if an error occurs". + * @return one of the TCodecState + */ + + virtual TInt DoProcessL ( TAny *aInpBuf, TAny* aOutBuf ) = 0; + + /** + * From MBaseCodec + * Encodes an input buffer + * @param aCommand + * The command passed - indicates encoder parameter to be set. + * @param aOutBuf + * The value used to set the parameter. + * @leave "The method will leave if an error occurs". + * @return one of the TCodecState + */ + + virtual TInt SetParam (TInt aCommand, TAny* aCmdData) = 0; + + /** + * Used to get codec parameteres + * @param aCommand + * Indicates the encoder parameter to get + * @param aCmdData + * The value of the encoder parameter (OUT) + * @return symbian wide error code + */ + + virtual TInt GetParam(TInt aCommand, TAny* aCmdData) = 0; + + + /** + * Cancels all processing of the commands + * @return None + */ + virtual void Reset () = 0; + + /** + * Sets the clocksource. + * @param aClockSource + * The clocksource which will be used by wrapper. + * @param aProcessingTime + * Not used currently. + * @return TInt KErrArgument if clocksource is NULL + * else returns KErrNone + */ + + virtual TInt SetSyncOptions( TAny* aClockSource, + TInt aProcessingTime = 0 ) = 0; + + /** + * Sets the reference time to be used by wrapper. + * @param aReferenceTime + * The reference time passed by the plugin + * @return None + */ + + virtual void SetUpdatedRefernceTime( TInt64 &aReferenceTime ) = 0; + + /** + * Indicates whether current picture has been encoded or not. + * @return TBool ETrue if ppicture is skipped. + */ + + virtual TBool IsCurrentPictureSkipped() = 0; + +#ifdef STORETOLOG + public: + TInt iRemainingFramesInSecLog; + TInt iRemainingBitsInSecLog; + TInt iTargetLog; + TInt iRemainingBitsInSecBHLog; + TInt iFrameSkipHappenedLog; + TInt iTimeStampEncLog; + TInt iCheckingForDropLog; + TInt iAbsFrameCntLog; + TInt iFrameCntLog; + TInt iRCLevelLog; + TInt iScarceBitsLog; + TInt iExcessCountLog; +#endif + + }; + +#endif //ARIH264ENCWRAPPER_H diff -r 000000000000 -r bb31fbe78861 h264_enc/arih264encwrapper/export_hdr/arivideoenccommon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/h264_enc/arih264encwrapper/export_hdr/arivideoenccommon.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Defines the structures shared by HwDevice and wrapper +* +*/ + +#ifndef ARIVIDEOENCCOMMON_H +#define ARIVIDEOENCCOMMON_H + +#include +#include +#include + +#define MAX_SCALABILITY_LAYERS 1 + + +//Control SUB MEssages +enum TSetCommands + { + CONTROL_CMD_SET_BIT_RATE = 2051, + CONTROL_CMD_SET_FRAME_RATE = 2052, + CONTROL_CMD_SET_FORCED_I_FRAME = 2053, + CONTROL_CMD_SET_GOVLENGTH = 2054, + CONTROL_CMD_SET_CHANNEL_PACKET_LOSS_RATE = 2059, + CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE = 2060, + CONTROL_CMD_SET_SEGMENT_TARGET_SIZE = 2061, + CONTROL_CMD_SET_RATE_CONTROL_OPTIONS = 2062, + CONTROL_CMD_SET_COMMIT_OPTIONS = 2065, + CONTROL_CMD_SET_COMPLEXITY_LEVEL = 2068, + CONTROL_CMD_SET_SLICELOSS = 2069, + CONTROL_CMD_SET_PACKET_SIZE = 2070, + CONTROL_CMD_SET_PACKET_MODE = 2071, + CONTROL_CMD_SET_FRAME_MODE = 2072 + }; + +enum TGetCommands + { + CONTROL_CMD_GET_CONFIG_HEADER = 3051, + CONTROL_CMD_GET_PACKET_OFFSET_DATA, + CONTROL_CMD_GET_MAX_FRAME_SIZE, + CONTROL_CMD_GET_MAX_NUM_PACKETS, + CONTROL_CMD_GET_CONFIG_LENGTH, + CONTROL_CMD_GET_PICTURES_SKIPPED + + + }; + +/* + Enumeration covering SetInputFormatL, SetOutputFormatL, SetInputDevice, + SetNumBitrateLayersL, SetScalabilityLayerTypeL, SetGlobalReferenceOptions, + SetBufferOptionsL, SetMinRandomAccessRate,SetSourceMemoryL of Hw Device. + All these seven methods can be called only before + Initialize. +*/ + +enum TOutputFormat + { + EH264 = 0x00000001, + }; + + +enum TPanicCodes + { + EPanicArgument=1, + EPanicInitializationPreCondViolation, + EPanicNotSupported, + EPanicNotPaused, + EPanicNotFreezed, + EPanicInvalidState, + EPanicAlreadyStopped + }; + +enum TEncBeforeInitialize + { + EEncBeforeInitNone = 0x00000000, + EEncInputFormat = 0x00000001, + EEncOutputFormat = 0x00000002, + EEncInputDevice = 0x00000004, + EEncNumBitrateLayers = 0x00000008, + EEncScalabilityLayer = 0x00000010, + EEncGlobalRefOptions = 0x00000020, + EEncBufferOptions = 0x00000040, + EEncRandomAccessRate = 0x00000080, + EEncSourceMemory = 0x00000100, + EEncInpBufferOptions = 0x00000200, + EEncErrorProtectionLevelFEC = 0x00000400, + EEncSegmentTargetSize = 0x00000800, + EEncCodingStandardSpecificOptions = 0x00001000, + EEncOutputRectSize = 0x00002000, + EEncErrorsExpected = 0x00004000, + EEncSourceCamera = 0x00008000, + EEncComplexityLevel = 0x00010000, + EEncLayerRefOptions = 0x00020000, + }; + +class TH264EncLayerReferenceOptions +{ +public: + TUint iMaxReferencePictures; + TUint iMaxPictureOrderDelay; + + TH264EncLayerReferenceOptions () : + iMaxReferencePictures (1), + iMaxPictureOrderDelay (0) + { + } +}; + +/* + * slice loss structure +*/ +class TH264EncSliceLoss +{ +public: + TUint iFirstMacroblock; + TUint iNumMacroblocks; + + TH264EncSliceLoss() : + iFirstMacroblock (0), + iNumMacroblocks (0) + { + } +}; + +/* + * Parameters used by the HwDevice which are sent to codec +*/ + +class TH264EncInitParams + { +public: + // Specifies which parameters are being sent in the Initialize method + TUint32 iBeforeInitialize; + TUint32 iAfterInitialize; + + // For SetInputFormatL + TUncompressedVideoFormat iInputFormat; + TInt32 iAspectRatio; + TSize iPictureSize; + + // For SetOutputFormatL + TOutputFormat iOutputFormat; + TVideoDataUnitType iDataUnitType; + TVideoDataUnitEncapsulation iDataEncapsulation; + TBool iSegmentationAllowed; + + // For SetSourceMemoryL + TReal iMaxPictureRate; + TBool iConstantPictureRate; + TBool iProcessRealtime; + TUint iNumInputBuffers; + TSize iInputSize; + + // For SetNumBitrateLayersL + TUint iNumBitRateLayers; + + // For SetScalabilityLayerTypeL + TUint iLayer; + TScalabilityType iScalabilityType; + + // For SetGlobalReferenceOptions & SetLayerReferenceOptions + TH264EncLayerReferenceOptions iLayerReferenceOptions[ + MAX_SCALABILITY_LAYERS]; + + // For SetBufferOptionsL + TUint iMaxPreEncoderBufferPictures; + THrdVbvSpecification iHrdVbvSpec; + T3gppHrdVbvParams iHrdVbvParams; + TUint iMaxOutputBufferSize; + TUint iMaxCodedPictureSize; + TUint iMaxCodedSegmentSize; + TUint iMinNumOutputBuffers; + + // For SetErrorProtectionLevelL + TUint iFECStrength; + + // For SetRamdomAccessRate + TReal iRandomAccessRate; + + // For SetOutputRectL + TRect iOutputRect; + + // For SetCodingStandardSpecificOptionsL + TAvcVideoMode iCodingStandardSpecificOptions; + + + // For SetErrorsExpected + TBool iBitErrors; + TBool iPacketLosses; + + // For SetMinRandomAccessRate + TReal iRate; + TInt iLevel; + + TUint iBitRate; + TReal iTargetPictureRate; + // complexity level + TUint iComplexityLevel; + + //for H324AnnexK VTFastCallSetUp + TBool iVTFastCallSetUp; + }; + + +class TPictureCountersInfo + { +public: + TUint iPicturesSkippedBufferOverflow; + TUint iPicturesSkippedProcPower; + TUint iPicturesSkippedRateControl; + TUint iPicturesProcessed; + TUint iInputPictures; + }; + +#endif //ARIVIDEOENCCOMMON_H diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/group/ariheaacdecmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/group/ariheaacdecmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for HeAac Decoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* HeAac Decoder plugin binaries. +* +*/ + + +#include +#include "..\Inc\ariheaacdecmmfcodec_uid.hrh" + +TARGET ariheaacdecmmfcodec.dll +TARGETTYPE PLUGIN + +CAPABILITY ALL -TCB + +UID 0x10009D8D KUidHeAacDecMmfDllUid + +MACRO LOGLEVEL_LOW + +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server +SYSTEMINCLUDE \epoc32\include\mmf\plugin + +USERINCLUDE ..\inc +USERINCLUDE ..\..\ariheaacdecwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +SOURCEPATH ..\src +SOURCE ariheaacdecmmfcodec.cpp + +SOURCEPATH ..\src +START RESOURCE 200297C6.rss + TARGET ariheaacdecmmfcodec.rsc +END + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY ECOM.lib +LIBRARY ariheaacdecwrapper.lib + + + + + diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for HeAac decoder plugin. This file specifies the +* mmp to be used to build the HeAac decoder plugin binaries. +* +*/ + + +PRJ_PLATFORMS +DEFAULT + +PRJ_MMPFILES +ariheaacdecmmfcodec.mmp + diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/inc/ariheaacdecmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/inc/ariheaacdecmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,208 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for HeAac decoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + + +#ifndef ARIHEAACDECMMFCODEC_H +#define ARIHEAACDECMMFCODEC_H + +#include + +/** + * This is a T-Class that holds the configuration + * information of an AAC frame.The class has 8 data members. + * The data members of this should be set to value of respective parameters + * passed by the application. + */ +class TAacFrameInfo + { +public: + TInt iOutFrameSize; + TInt iNoOfSamples; + TInt iSamplingFrequency; + TInt iNoOfChannels; + TInt iProfile; + TInt iOutSamplingFrequency; + TInt iExtObjectType; + TInt iDownSampledMode; + }; + +//Forward Declaration +class CAriHeAacDecWrapper; + +// Class declaration +class CAriHeAacDecMmfCodec:public CMMFCodec + { +public: //constructors and destructors + /** + * Two-phased constructor. + * @return pointer to an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriHeAacDecMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + virtual void ConfigureL( TUid aConfigType, const TDesC8& aParam ); + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any + * size, therefore there is no guarantee that all the source buffer can + * be processed to fill the destination buffer or that all the source + * buffer may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status.This function is synchronous, when the function returns the + * data has been processed. The source buffer is converted to the + * appropriate coding type in the destination buffer. The buffers can be + * of any size, therefore there is no guarantee that all the source + * buffer can be processed to fill the destination buffer or that all + * the source buffer may be processed before the destination is full. + * This function therefore returns the number of source,and destination, + * bytes processed along with a process result code indicating completion + * status.The aSource and aSink buffers passed in are derived from + * CMMFBuffer. The buffer type (e.g. a CMMFDataBuffer) passed in should + * be supported by the codec otherwise this function should leave with + * KErrNotSupported. The position of the source buffer should be checked + * by calling the source buffer's Position() member which indicates the + * current source read position in bytes. The codec should start + * processing from the current source buffer read position. The position + * of the destination buffer should be checked by calling the destination + * buffer's Position() method which indicates the current destination + * write position in bytes. The codec should start writing to the + * destination buffer at the current destination buffer write position. + * This is a virtual function that each derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + virtual TCodecProcessResult ProcessL( const CMMFBuffer& aSource, + CMMFBuffer& aDestination ); + +private: + /** + * Default Constructor + */ + CAriHeAacDecMmfCodec(); + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed,TInt aDstBytesAdded); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); + + /** + * Calls Decode with NULL as source + * @param aDstLen + * destination size in bytes + */ + void DecodeLastFrame( TInt& aDstLen ); + +private: //Data + + // Handle to wrapper class + CAriHeAacDecWrapper* iCodec; + + TBool iConfigured; + TInt iOutFrameSize; + TUint8* iInternalBuffer; + TBool iLastFrameDecoded; + TInt iSrcUsed; + TInt iFrameNum; + TAacFrameInfo iFrameInfo; + TInt iInternalInputBufferResidueLen; + TInt iInternalOutputBufferResidueLen; + TUint8* iInternalInputBuffer; + TUint8* iInternalOutputBuffer; + TInt iInternalOutputBufferPos; + + }; + +#endif /* ARIHEAACDECMMFCODEC_H */ diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/inc/ariheaacdecmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/inc/ariheaacdecmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll +* and Implementation Uids. +* +*/ + + +#ifndef ARIHEAACDECMMFCODEC_UID_HRH +#define ARIHEAACDECMMFCODEC_UID_HRH + +//Implementaion UID +#define KUidHeAacDecMmfImplUid 0x200297C5 + +//DLL UID +#define KUidHeAacDecMmfDllUid 0x200297C6 + +#endif /* ARIHEAACDECMMFCODEC_UID_HRH */ diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/src/200297C6.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/src/200297C6.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for HeAac Decoder Plugin. +* +*/ + + +#include +#include "RegistryInfo.rh" +#include "ariheaacdecmmfcodec_UID.hrh" + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidHeAacDecMmfDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidHeAacDecMmfImplUid; + version_no = 1; + display_name = "eAAC Decoder codec||copyright Aricent"; + //four CC codes + default_data = " EAC, P16"; + opaque_data = ""; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecmmfcodec/src/ariheaacdecmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecmmfcodec/src/ariheaacdecmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,787 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class +* (CAriHeAacDecMmfCodec). +* +*/ + + +#include +#include + +#include "ariheaacdecwrapper.h" +#include "ariheaacdecmmfcodec.h" +#include "ariheaacdecmmfcodec_uid.hrh" +#include "ariprint.h" + +//Maximum size of a single input frame in an AAC stream +const TInt KMinBytesInput = 1536; +//Maximum size of a single output frame in an AAC stream +const TInt KMaxOutputBufSize = 8192; + +const TInt KMinParamSize = 11; +const TInt KRenderStatusIndex = 13; +const TInt KMarkPlayStatusIndex = 14; +const TInt KEnableStatusIndex = 15; + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriHeAacDecMmfCodec. +// Instance is not left on cleanup stack. +// --------------------------------------------------------------------------- +// +CMMFCodec* CAriHeAacDecMmfCodec::NewL() + { + PRINT_ENTRY; + CAriHeAacDecMmfCodec* self = new ( ELeave ) CAriHeAacDecMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return ( CMMFCodec* )self; + } + +// --------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +// --------------------------------------------------------------------------- +// +CAriHeAacDecMmfCodec::~CAriHeAacDecMmfCodec() + { + PRINT_ENTRY; + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + iConfigured = EFalse; + PRINT_EXIT; + } + + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// The function Sets codec configuration. +// The value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +// --------------------------------------------------------------------------- +// +void CAriHeAacDecMmfCodec::ConfigureL( TUid /* aConfigType */, + const TDesC8& aParam ) + { + PRINT_ENTRY; + TInt paramLen = aParam.Length(); + PRINT_MSG( LEVEL_HIGH, ( "param Len: %d", + paramLen ) ); + if ( paramLen < KMinParamSize ) + { + PRINT_MSG( LEVEL_HIGH, ( "param Len: %d", + paramLen ) ); + PRINT_ERR( "Incorrect parameter descriptor " ); + User::Leave( KErrArgument ); + } + if ( !iConfigured ) + { + RArray configParam = ( RArray& )( aParam ); + TInt index = 0; + + index++; + //configParam[1] holds NoOfChannels + iFrameInfo.iNoOfChannels = configParam[index++]; + //configParam[2] holds Profile + iFrameInfo.iProfile = configParam[index++]; + //configParam[3] holds OutFrameSize + iFrameInfo.iOutFrameSize = configParam[index++]; + //configParam[4] holds NoOfSamples + iFrameInfo.iNoOfSamples = configParam[index++]; + //configParam[5] holds SamplingFrequency + iFrameInfo.iSamplingFrequency = configParam[index++]; + //Ignore fields 6,7 & 8 + index++; + index++; + index++; + //configParam[9] holds OutSamplingFrequency + iFrameInfo.iOutSamplingFrequency = configParam[index++]; + //configParam[10] holds ExtObjectType + iFrameInfo.iExtObjectType = configParam[index]; + iFrameInfo.iDownSampledMode = 0; + + if ( paramLen > KMinParamSize) + { + /** + * Call Reset only if fields 13,14 and 15 of the + * Param array are set to zero + */ + if ( ( configParam[KRenderStatusIndex] == 0 && + configParam[KMarkPlayStatusIndex] == 0 && + configParam[KEnableStatusIndex] == 0 ) ) + { + PRINT_MSG( LEVEL_HIGH, ( "frameInfo->OutFrameSize: %d", + iFrameInfo.iOutFrameSize ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfSamples: %d", + iFrameInfo.iNoOfSamples ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->SamplingFrequency: %d", + iFrameInfo.iSamplingFrequency ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfChannels: %d", + iFrameInfo.iNoOfChannels ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->Profile: %d", + iFrameInfo.iProfile ) ); + PRINT_MSG( LEVEL_HIGH, + ( "iFrameInfo->OutSamplingFrequency: %d", + iFrameInfo.iOutSamplingFrequency ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->ExtObjectType: %d", + iFrameInfo.iExtObjectType ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->DownSampledMode: %d", + iFrameInfo.iDownSampledMode ) ); + + User::LeaveIfError( iCodec->Reset( &iFrameInfo ) ); + + iConfigured = ETrue; + iOutFrameSize = iFrameInfo.iOutFrameSize; + } + } + else + { + PRINT_MSG( LEVEL_HIGH, ( "frameInfo->OutFrameSize: %d", + iFrameInfo.iOutFrameSize ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfSamples: %d", + iFrameInfo.iNoOfSamples ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->SamplingFrequency: %d", + iFrameInfo.iSamplingFrequency ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->NoOfChannels: %d", + iFrameInfo.iNoOfChannels ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->Profile: %d", + iFrameInfo.iProfile ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->OutSamplingFrequency: %d", + iFrameInfo.iOutSamplingFrequency ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->ExtObjectType: %d", + iFrameInfo.iExtObjectType ) ); + PRINT_MSG( LEVEL_HIGH, ( "iFrameInfo->DownSampledMode: %d", + iFrameInfo.iDownSampledMode ) ); + + User::LeaveIfError( iCodec->Reset( &iFrameInfo ) ); + + iConfigured = ETrue; + + iOutFrameSize = iFrameInfo.iOutFrameSize; + } + } + PRINT_EXIT; + } + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to flush out status information when a +// reposition occurs. +// This is used if the codec requires resetting prior to use. +// --------------------------------------------------------------------------- +// +void CAriHeAacDecMmfCodec::ResetL() + { + PRINT_ENTRY; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + } + + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// This function is used to decode the given source and fill the destination +// buffer with the decode data. +// The buffers can be of any size. Since the buffers can be of any size +// there is no guarantee that all the source buffer can be processed to fill +// the destination buffer or that the all the source buffer may be processed +// before the destination is full. Therefore the ProcessL needs to return a +// TCodecProcessResult returing the number of source bytes processed and the +// number of destination bytes processed along with a process result code +// defined thus: +// - EProcessComplete: the codec processed all the source data into the sink +// buffer +// - EProcessIncomplete: the codec filled sink buffer before all the source +// buffer was processed +// - EDstNotFilled: the codec processed the source buffer but the sink buffer +// was not filled +// - EEndOfData: the codec detected the end data - all source data in +// processed but sink may not be full +// - EProcessError: the codec process error condition +// +// The ProcessL should start processing the source buffer from the iPosition +// data member of the source data and start filling the destination buffer +// from its iPosition. +// -------------------------------------------------------------------------- +// +TCodecProcessResult CAriHeAacDecMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + + if ( !iConfigured ) + { + PRINT_ERR( "Decoder not yet configured" ); + User::Leave( KErrNotReady ); + } + // total decoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied = 0; + TInt dstBufferRemainingBytes = 0; + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + TUint8* srcPtr = const_cast( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d", srcBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d", dstBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d", + iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) ); + PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d", + iInternalInputBufferResidueLen ) ); + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + //Decode NULL frame to handle error concealment + if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&& + ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) ) + { + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - + totalDstBytesAdded; + if ( dstBufferRemainingBytes == 0 ) + { + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + totalSrcBytesCopied = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + TInt dstLen = iOutFrameSize; + DecodeLastFrame(dstLen); + iInternalOutputBufferResidueLen = dstLen; + + numberOfBytesCopied = + CopyToDstBuffer( dst, totalDstBytesAdded ); + totalDstBytesAdded += numberOfBytesCopied; + dstBufferRemainingBytes -= numberOfBytesCopied; + + if ( ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos == 0 ) && iLastFrameDecoded ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + totalSrcBytesCopied = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + else + { + if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&& + ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) ) + { + TInt dstLen = iOutFrameSize; + DecodeLastFrame(dstLen); + iInternalOutputBufferResidueLen = dstLen; + + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + totalDstBytesAdded += numberOfBytesCopied; + dstBufferRemainingBytes -= numberOfBytesCopied; + + if ( ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos == 0 ) && iLastFrameDecoded ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + totalSrcBytesCopied = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, + * it ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( KMinBytesInput - iInternalInputBufferResidueLen > 0 ) && + ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + } + + /** + * update the internal buffer length. + */ + if ( ( KMinBytesInput > iInternalInputBufferResidueLen ) && + ( !lastFrame ) ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + + if ( iLastFrameDecoded && iInternalInputBufferResidueLen == 0 && + iInternalOutputBufferResidueLen == 0 ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + /** + * process the src buffer till destination buffer or source buffer or + * both buffers are exhausted. + */ + do + { + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos - + totalSrcBytesCopied; + dstBufferRemainingBytes = dstMaxLen - dstBufferPos - + totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + /** + * initialize the variables like iSrcUsed and dstLen accordingly. + * call Decode. + */ + iSrcUsed = iInternalInputBufferResidueLen - internalInputBufferPos; + TInt dstLen = iOutFrameSize; + + TInt error = iCodec->Decode( + &iInternalInputBuffer[internalInputBufferPos], + iSrcUsed, iInternalOutputBuffer, dstLen ); + if ( error != 0 ) + { + iInternalInputBufferResidueLen = 0; + totalSrcBytesCopied = srcBufferLen; + PRINT_ERR( error ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos); + } + iFrameNum++; + PRINT_MSG( LEVEL_HIGH, ( "Frame: %d", iFrameNum ) ); + PRINT_MSG( LEVEL_HIGH, ( "iSrcUsed: %d", iSrcUsed ) ); + PRINT_MSG( LEVEL_HIGH, ( "dstLen: %d", dstLen ) ); + + /** + * Fill Destination Buffer + */ + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /** + * Fill Source Buffer + */ + internalInputBufferPos += iSrcUsed ; + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + + /** + * check four conditions if else for src and if else for dst + */ + /** + * src has available bytes + */ + if ( srcBufferRemainingBytes > 0 || + iInternalInputBufferResidueLen >= KMinBytesInput ) + { + if ( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + // dst buffer has availabe space for decoded bytes + if ( dstBufferRemainingBytes > 0 ) + { + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen == 0 ) + { + TInt dstLen = iOutFrameSize; + DecodeLastFrame(dstLen); + iInternalOutputBufferResidueLen = dstLen; + + numberOfBytesCopied = + CopyToDstBuffer( dst, totalDstBytesAdded ); + totalDstBytesAdded += numberOfBytesCopied; + dstBufferRemainingBytes -= numberOfBytesCopied; + + if ( ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos == 0 ) && + iLastFrameDecoded ) + { + totalSrcBytesCopied = 0; + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + totalSrcBytesCopied = 0; + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + if ( iInternalOutputBufferResidueLen - + iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( lastFrame ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + } + }while ( 1 ); + } + + +// -------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +// -------------------------------------------------------------------------- +// +CAriHeAacDecMmfCodec::CAriHeAacDecMmfCodec() + { + PRINT_ENTRY; + iCodec = NULL; + iConfigured = EFalse; + iOutFrameSize = 0; + iLastFrameDecoded = EFalse; + + iFrameNum = 0; + PRINT_EXIT; + } + + +// --------------------------------------------------------------------------- +// Second phase of the two-phased constructor. +// Creates an instance of decoder +// --------------------------------------------------------------------------- +// +void CAriHeAacDecMmfCodec::ConstructL() + { + PRINT_ENTRY; + iCodec = CAriHeAacDecWrapper::NewL(); + + iInternalInputBuffer = ( TUint8* ) User::AllocZL( KMinBytesInput ); + iInternalOutputBuffer = ( TUint8* ) User::AllocZL( KMaxOutputBufSize ); + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriHeAacDecMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + { + PRINT_ENTRY; + TCodecProcessResult result; + + result.iDstBytesAdded = aDstBytesAdded; + result.iSrcBytesProcessed = aSrcBytesConsumed; + + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriHeAacDecMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast(aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriHeAacDecMmfCodec::CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + TInt internalInputBufferRemaingBytes = KMinBytesInput + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriHeAacDecMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = 0; i < ( iInternalInputBufferResidueLen - + aFromPos ); i++ ) + { + iInternalInputBuffer[i] = + iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Calls Decode with NULL as source after all source data is exhausted +//--------------------------------------------------------------------------- +// +void CAriHeAacDecMmfCodec::DecodeLastFrame( TInt& aDstLen ) + { + TInt error = iCodec->Decode( NULL, iSrcUsed, + iInternalOutputBuffer, aDstLen ); + if ( KErrNone != error ) + { + aDstLen = 0; + } + + iLastFrameDecoded = ETrue; + } + +// --------------------------------------------------------------------------- +// Exported proxy for instantiation method resolution +// Define the interface UIDs +// --------------------------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( KUidHeAacDecMmfImplUid, + CAriHeAacDecMmfCodec::NewL ) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } diff -r 000000000000 -r bb31fbe78861 heaac_dec/ariheaacdecwrapper/export_hdr/ariheaacdecwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heaac_dec/ariheaacdecwrapper/export_hdr/ariheaacdecwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* HeAac Decoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIHEAACDECWRAPPER_H +#define ARIHEAACDECWRAPPER_H + +#include +#include + + +// Class declaration +class CAriHeAacDecWrapper:public CBase + { + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriHeAacDecWrapper + */ + IMPORT_C static CAriHeAacDecWrapper* NewL(); + + /**> Destructor */ + virtual ~CAriHeAacDecWrapper(); + + /** + * The function returns the Format type of the input stream. + * @param aData + * Pointer to buffer containing the first chunk of input stream data + * @return Format type of input stream + */ + virtual TInt FormatType( TUint8* aData ) = 0; + + /** + * The function Gets frame information for the given source. + * @param aHeaderBuffer + * Pointer to buffer containing the header of input stream data + * @param aHeaderSize + * size of header in bytes + * @param aFrameInfo + * pointer to FrameInfo structure + * @param aFormat + * Format type of input stream + * @param aDataBuffer + * Pointer to buffer containing input stream data + * @param aDataSize + * size of input data in bytes + * @return return status + */ + virtual TInt GetFrameInfo( TUint8* aHeaderBuffer, TInt &aHeaderSize, + TAny* aFrameInfo, TInt aFormat, + TUint8* aDataBuffer, TInt aDataSize ) = 0; + + /** + * The function decodes the input stream. + * @param aSrcBuf + * The source buffer containing data to decode. + * @param aSrcUsed + * Size of source buffer in bytes + * @param aDstBuf + * The destination buffer to hold the data after decoding. + * @param aOutSize + * Size of destination buffer in bytes + * @return return status + */ + virtual TInt Decode( TUint8 *aSrcBuf, TInt &aSrcUsed, TUint8 *aDstBuf, + TInt &aOutSize ) = 0; + + /** + * The function resets the codec. + * @param aFrameInfo + * pointer to FrameInfo structure + * @return return status + */ + virtual TInt Reset( TAny* aFrameInfo ) = 0; + }; + + +#endif /* ARIHEAACDECWRAPPER_H */ + diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/group/arimp3decmmfcodec.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/group/arimp3decmmfcodec.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project File for Mp3 Decoder Plugin. The file specifies the +* include paths, source files and libraries to be used to build the +* Mp3 Decoder plugin binaries. +* +*/ + +#include +#include "../inc/arimp3decmmfcodec_uid.hrh" + +TARGET arimp3decmmfcodec.dll +TARGETTYPE plugin + +UID 0x10009D8D KUidMp3DecCodecDllUid + +CAPABILITY ALL -Tcb +MACRO LOGLEVEL_LOW + + +SOURCEPATH ..\src +SOURCE arimp3decmmfcodec.cpp + +USERINCLUDE ..\inc +USERINCLUDE ..\..\arimp3decwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\log + +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\common +SYSTEMINCLUDE \epoc32\include\mmf\server + +START RESOURCE 200297CE.rss +TARGET arimp3decmmfcodec.rsc +END + +LIBRARY euser.lib +LIBRARY mmfserverbaseclasses.lib +LIBRARY ECOM.lib +LIBRARY arimp3decwrapper.lib + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- + + diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for Mp3 decoder plugin. This file specifies the mmp +* to be used to build the Mp3 decoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +DEFAULT + +PRJ_MMPFILES +arimp3decmmfcodec.mmp + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/inc/arimp3decmmfcodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/inc/arimp3decmmfcodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,203 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Plugin class for Mp3 decoder. This class inherits CMMFCodec +* class and implements the pure virtual functions of CMMFCodec. +* The class also has a few private funtions. +* +*/ + +#ifndef ARIMP3DECMMFCODEC_H +#define ARIMP3DECMMFCODEC_H + +// system include files +#include +// user include files +#include "arimp3decmmfcodec_uid.hrh" + +// Forward Declaration +class CAriMp3DecWrapper; + +// Class declaration +class CAriMp3DecMmfCodec :public CMMFCodec + { + +public: //constructors and destructors + /** + * Two-phased constructor. + * @return Pointer to an instance of CMMFCodec + */ + static CMMFCodec* NewL(); + + /**> Destructor */ + ~CAriMp3DecMmfCodec(); + +public: // From CMMFCodec + + /** + * From CMMFCodec + * Sets codec configuration. + * The configuration data is passed in as a descriptor of type TDesC8. + * @param aConfigType + * The UID of the configuration data. + * @param aParam + * Descriptor with frame info parameters in the form of RArray + */ + + virtual void ConfigureL( TUid aConfigType, const TDesC8& aParam ); + + /** + * From CMMFCodec + * Codec reset function used to flush out status information when a + * reposition occurs. + * This is used if the codec requires resetting prior to use. + */ + virtual void ResetL(); + + /** + * From CMMFCodec + * Processes the data in the specified source buffer and writes the + * processed data to the specified destination buffer. + * This function is synchronous, when the function returns the data + * has been processed. The source buffer is converted to the appropriate + * coding type in the destination buffer. The buffers can be of any + * size, therefore there is no guarantee that all the source buffer can + * be processed to fill the destination buffer or that all the source + * buffer may be processed before the destination is full. This function + * therefore returns the number of source, and destination, bytes + * processed along with a process result code indicating completion + * status.This function is synchronous, when the function returns the + * data has been processed. The source buffer is converted to the + * appropriate coding type in the destination buffer. The buffers can be + * of any size, therefore there is no guarantee that all the source + * buffer can be processed to fill the destination buffer or that all + * the source buffer may be processed before the destination is full. + * This function therefore returns the number of source,and destination, + * bytes processed along with a process result code indicating completion + * status.The aSource and aSink buffers passed in are derived from + * CMMFBuffer. The buffer type (e.g. a CMMFDataBuffer) passed in should + * be supported by the codec otherwise this function should leave with + * KErrNotSupported. The position of the source buffer should be checked + * by calling the source buffer's Position() member which indicates the + * current source read position in bytes. The codec should start + * processing from the current source buffer read position. The position + * of the destination buffer should be checked by calling the destination + * buffer's Position() method which indicates the current destination + * write position in bytes. The codec should start writing to the + * destination buffer at the current destination buffer write position. + * This is a virtual function that each derived class must implement. + * @see enum TCodecProcessResult + * @param aSource + * The source buffer containing data to encode or decode. + * @param aDestination + * The destination buffer to hold the data after encoding or + * decoding. + * @return The result of the processing. + * @pre The function ConfigureL() should have been called. + */ + + virtual TCodecProcessResult ProcessL( const CMMFBuffer& aSource, + CMMFBuffer& aDestination ); + +private: + /** + * Default Constructor + */ + CAriMp3DecMmfCodec(); + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + + /** + * Update the result with result status, source bytes consumed + * and destination bytes added. + * @param aStatus + * status of the result like EProcessComplete + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @param aDstBytesAdded + * total bytes added to the destination buffer + * @return result of the processing + */ + TCodecProcessResult Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed,TInt aDstBytesAdded); + + /** + * Copy the bytes from internal output buffer to destination buffer + * @param aDst + * pointer to the destination buffer + * @param aDstBytesConsumed + * total bytes added to the destination buffer + * @return number of bytes copied to the destination buffer. + */ + TInt CopyToDstBuffer( CMMFDataBuffer* aDst, TInt& aDstBytesConsumed); + + /** + * Copy the bytes from the source buffer to the internal input burrer + * @param aSrc + * pointer to the source buffer + * @param aSrcBytesConsumed + * total bytes consumed from the source buffer + * @return number bytes copied from the source buffer + */ + TInt CopyFromSrcBuffer(const CMMFDataBuffer* aSrc, + TInt& aSrcBytesConsumed); + /** + * Shifts the data in the input internal buffer to start position + * @param aFromPos + * position from where data has to shift + * @param aToPos + * position to where data has to shift + */ + void ShiftData( TInt aFromPos, TInt aToPos ); + + /** + * Gets the new data from the source buffer + * @param aSrc + * pointer to the source buffer + * @param aDstBytesConsumed + * total number bytes added to the destination buffer + * @param aSrcBytesConsumed + * total number bytes consumed from the source buffer + * @return returns the processin result + */ + TCodecProcessResult GetNewData(const CMMFDataBuffer* aSrc, + TInt &aDstBytesConsumed, TInt &aSrcBytesConsumed); + +private: //Data + + // handle to the wrapper instance + CAriMp3DecWrapper* iCodec; + // Residue input buffer length + TInt iInternalInputBufferResidueLen; + // Residue output buffer length + TInt iInternalOutputBufferResidueLen; + // max output buffer size + TInt iOutFrameSize; + // Input internal buffer + TUint8 *iInternalInputBuffer; + // Output internal buffer + TUint8 *iInternalOutputBuffer; + // internal output buffer position + TInt iInternalOutputBufferPos; + + }; + +#endif \\ ARIMP3DECMMFCODEC_H \\ + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/inc/arimp3decmmfcodec_uid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/inc/arimp3decmmfcodec_uid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the macros for Plugin Dll and Implementation Uids. +* +*/ +#ifndef ARIMP3DECMMFCODEC_UID_HRH +#define ARIMP3DECMMFCODEC_UID_HRH + +// Implementation UID +#define KUidMp3DecCodecImplUid 0x200297CD +// Dll UID +#define KUidMp3DecCodecDllUid 0x200297CE + +#endif // ARIMP3DECMMFCODEC_UID_HRH // + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/src/200297CE.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/src/200297CE.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for Mp3 Decoder Plugin. +* +*/ + +#include "RegistryInfo.rh" +#include "mmfPluginInterfaceUIDs.hrh" +#include "arimp3decmmfcodec_uid.hrh" + +// Declares info for two implementations +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = KUidMp3DecCodecDllUid; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KMmfUidPluginInterfaceCodec; + implementations = + { + // Info for CImplementation1 + IMPLEMENTATION_INFO + { + implementation_uid = KUidMp3DecCodecImplUid; + version_no = 1; + display_name = + "Mp3 Decoder codec||copyright Aricent"; + //four CC codes + default_data = " MP3, P16"; + opaque_data = ""; + } + }; + } + }; + } + +//---------------------------------------------------------------------------- +// End of File +//---------------------------------------------------------------------------- diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decmmfcodec/src/arimp3decmmfcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decmmfcodec/src/arimp3decmmfcodec.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,751 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Plugin class (CAriMp3DecMmfCodec). +* +*/ + +// System includes +#include +#include +// User includes +#include "arimp3decwrapper.h" +#include "arimp3decmmfcodec.h" +#include "arimp3decmmfcodec_uid.hrh" +#include "ariprint.h" + +//Maximum size of a single input frame in an Mp3 stream +const TInt KMinBytesInput = 1440; + + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// Creates an instance of CAriMp3DecMmfCodec. +// Instance is not left on cleanup stack. +// --------------------------------------------------------------------------- +// + +CMMFCodec* CAriMp3DecMmfCodec::NewL() + { + PRINT_ENTRY; + CAriMp3DecMmfCodec* self = new ( ELeave ) CAriMp3DecMmfCodec(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return ( CMMFCodec* )self; + } + +// --------------------------------------------------------------------------- +// Destructor;Destroys the decoder instance and any internal buffers +// --------------------------------------------------------------------------- +// + +CAriMp3DecMmfCodec::~CAriMp3DecMmfCodec() + { + PRINT_ENTRY; + if ( iInternalInputBuffer ) + { + delete iInternalInputBuffer; + iInternalInputBuffer = NULL; + } + if ( iInternalOutputBuffer ) + { + delete iInternalOutputBuffer; + iInternalOutputBuffer = NULL; + } + + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + PRINT_EXIT; + } + +// --------------------------------------------------------------------------- +// From class CMMFCodec. +// The function Sets codec configuration. +// The value used for aConfigType must be KUidMmfCodecAudioSettings +// (defined in include\mmf\plugins\mmfCodecImplementationUIDs.hrh) +// --------------------------------------------------------------------------- +// + + void CAriMp3DecMmfCodec::ConfigureL( TUid /*aConfigType*/, + const TDesC8& /*aParam*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + + // -------------------------------------------------------------------------- + // From class CMMFCodec. + // This function is used to flush out status information when a + // reposition occurs. + // This is used if the codec requires resetting prior to use. + // -------------------------------------------------------------------------- + // + + void CAriMp3DecMmfCodec::ResetL() + { + PRINT_ENTRY; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + PRINT_EXIT; + } + + //--------------------------------------------------------------------------- + // From class CMMFCodec. + // This function is used to decode the given source and fill the + // destination buffer with the decode data. + // The buffers can be of any size. Since the buffers can be of any size + // there is no guarantee that all the source buffer can be processed to + // fill the destination buffer or that the all the source buffer may be + // processed before the destination is full. Therefore the ProcessL needs + // to return a TCodecProcessResult returing the number of source bytes + // processed and the number of destination bytes processed along with a + // process result code defined thus: + // - EProcessComplete: the codec processed all the source data into the + // sink buffer + // - EProcessIncomplete: the codec filled sink buffer before all the source + // buffer was processed + // - EDstNotFilled: the codec processed the source buffer but the sink + // buffer was not filled + // - EEndOfData: the codec detected the end data - all source data in + // processed but sink may not be full + // - EProcessError: the codec process error condition + // + // The ProcessL should start processing the source buffer from the iPosition + // data member of the source data and start filling the destination buffer + // from its iPosition. + //--------------------------------------------------------------------------- + // + +TCodecProcessResult CAriMp3DecMmfCodec::ProcessL( const CMMFBuffer& aSrc, + CMMFBuffer& aDst ) + { + PRINT_ENTRY; + // total decoded bytes added to the dst buffer + TInt totalDstBytesAdded = 0; + // total src bytes added to the internal src buffer + TInt totalSrcBytesCopied = 0; + // temporary variable to use for copying the sorce or destination data + TInt numberOfBytesCopied; + // Flag for finding valid sync + TBool syncFound = EFalse; + + /** + * Process the dst buffer, update the dstBufferPos and check + * whether dst buffer is NULL or not. + */ + CMMFDataBuffer* dst = static_cast( &aDst ); + + const TInt dstMaxLen = dst->Data().MaxLength(); + TUint8* dstPtr = const_cast( dst->Data().Ptr() ); + TInt dstBufferPos = dst->Position(); + + /** + * Process the src buffer, update srcbuffer length, position and + * flag for last frame. check whether src buffer is NULL or not + * and check src buffer contains any data + */ + const CMMFDataBuffer* src = static_cast( &aSrc ); + + TUint8* srcPtr = const_cast ( src->Data().Ptr() ); + TInt srcBufferLen = src->Data().Length(); + TInt srcBufferPos = src->Position(); + TBool lastFrame = src->LastBuffer(); + + if ( srcBufferLen == 0 && iInternalInputBufferResidueLen == 0 ) + { + PRINT_ERR( "source buffer length is zero" ); + User::Leave( KErrArgument ); + } + + /** + * if any destination bytes from internal destination buffer is not + * given to the dst buffer from the previous call, give it to the + * dst buffer. After this block, it ensures that no bytes are remaining + * in the internal destination buffer. + */ + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + + if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + if ( ( lastFrame ) && ( srcBufferLen - srcBufferPos == 0 )&& + ( iInternalInputBufferResidueLen == 0 ) ) + { + iInternalOutputBufferResidueLen = 0; + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + iInternalOutputBufferPos = 0; + iInternalOutputBufferResidueLen = 0; + } + } + + /** + * copy the src buffer data into the internal buffer till internal buffer + * holds minimum bytes to process i.e KMinBytesInput. After this block, it + * ensures that internal source buffer holds KMinBytesInput. + * if it is a last frame, treat remaining residual buffer as internal + * buffer. + */ + if ( ( KMinBytesInput - iInternalInputBufferResidueLen > 0 ) + && ( srcBufferLen - srcBufferPos > 0 ) ) + { + numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied ); + } + + if ( ( KMinBytesInput > iInternalInputBufferResidueLen ) + && ( !lastFrame ) ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + srcBufferLen - srcBufferPos, totalDstBytesAdded ); + } + + /** + * process the src buffer till destination buffer or source buffer + * or both buffers are exhausted. + */ + do + { + /** + * call seeksync to find the valid fram start offset i.e syncpos. + * update internal buffer position to that offset position if it is + * success.if it is failed then there is no valid frame start in + * the available buffer. Go for new src buffer. all bytes present + * in the internal buffer are discarded. + */ + TInt syncpos; + TInt srcBufferRemainingBytes = srcBufferLen + - srcBufferPos + - totalSrcBytesCopied; + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - totalDstBytesAdded; + TInt internalInputBufferPos = 0; + + if ( KErrNone != iCodec->SeekSync( + &iInternalInputBuffer[internalInputBufferPos], + ( iInternalInputBufferResidueLen - internalInputBufferPos ), + syncpos ) ) + { + TCodecProcessResult result = GetNewData( src, totalSrcBytesCopied, + totalDstBytesAdded ); + + if ( result.iStatus == TCodecProcessResult::EDstNotFilled || + result.iStatus == TCodecProcessResult::EEndOfData ) + { + return result; + } + } + else + { + syncFound = ETrue; + internalInputBufferPos += syncpos; + } + /** + * call GetFrameInfo to find whether valid frame is present in the + * availabel buffer.if it is success and framelength is 0 then + * there is no valid frame is present, discard the present buffer + * till sync position and add new buffer. + */ + if ( syncFound ) + { + TInt frameLen; + TMp3FrameInfo frameInfo; + if ( KErrNone != iCodec->GetFrameInfo( + &iInternalInputBuffer[internalInputBufferPos], + ( iInternalInputBufferResidueLen - internalInputBufferPos ), + frameLen, frameInfo ) ) + { + PRINT_ERR( "Decoder Getframeinfo failed" ); + User::Leave( KErrGeneral ); + } + if ( frameLen == 0 ) + { + TCodecProcessResult result = GetNewData( src, + totalSrcBytesCopied, totalDstBytesAdded ); + + if ( result.iStatus == TCodecProcessResult::EDstNotFilled || + result.iStatus == TCodecProcessResult::EEndOfData ) + { + return result; + } + } + + /** + * if the buffer has less than framelen then fill the internal + * sorce buffer with KMinBytesInput bytes. + */ + if ( frameLen > ( iInternalInputBufferResidueLen + - internalInputBufferPos ) ) + { + if( lastFrame ) + { + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( + TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, + totalSrcBytesCopied ); + internalInputBufferPos = 0; + + if ( iInternalInputBufferResidueLen < KMinBytesInput ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + + /** + * initialize the variables like srcUsed and dstLen accordingly. + * call Decode. + */ + + TInt srcUsed = iInternalInputBufferResidueLen + - internalInputBufferPos; + TInt dstLen = iOutFrameSize; + + TInt error = iCodec->Decode( + &iInternalInputBuffer[internalInputBufferPos], + srcUsed, iInternalOutputBuffer, dstLen ); + + if ( KErrNone != error ) + { + iInternalInputBufferResidueLen = 0; + PRINT_ERR( error ); + return Result( + TCodecProcessResult::EProcessError, + totalSrcBytesCopied, totalDstBytesAdded ); + } + + /** + * Fill Destination Buffer + */ + + iInternalOutputBufferResidueLen = dstLen; + numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded ); + dstBufferRemainingBytes -= numberOfBytesCopied; + + /*** + * Fill Sorce Buffer + */ + + internalInputBufferPos += srcUsed ; + ShiftData( internalInputBufferPos, 0 ); + numberOfBytesCopied = CopyFromSrcBuffer( src, + totalSrcBytesCopied ); + srcBufferRemainingBytes -= numberOfBytesCopied; + internalInputBufferPos = 0; + + /*** + * check four conditions if else for src and if else for dst + */ + + // src buffer has available bytes to decode + if ( srcBufferRemainingBytes > 0 ) + { + if ( dstBufferRemainingBytes == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + + else + { + // dst buffer has availabe space for decoded bytes + if ( dstBufferRemainingBytes > 0 ) + { + // last frame of the input stream + if ( lastFrame ) + { + if ( iInternalInputBufferResidueLen == 0 ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + /** + *internal output buffer has decoded bytes which is not + *given to dst buffer. + */ + if ( iInternalOutputBufferResidueLen + - iInternalOutputBufferPos > 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + // last frame of the input stream + else if ( lastFrame ) + { + // if internal buffer has available bytes to decode + if ( iInternalInputBufferResidueLen > 0 ) + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessIncomplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + else + { + iInternalInputBufferResidueLen = 0; + PRINT_EXIT; + return Result( + TCodecProcessResult::EEndOfData, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + else + { + PRINT_EXIT; + return Result( + TCodecProcessResult::EProcessComplete, + totalSrcBytesCopied, totalDstBytesAdded ); + } + } + } + } + }while ( 1 ); + } + +//---------------------------------------------------------------------------- +// Default constructor for performing 1st stage construction. +// Should not contain any code that could leave. +//---------------------------------------------------------------------------- +// + +CAriMp3DecMmfCodec::CAriMp3DecMmfCodec(): +iCodec( NULL ), iInternalInputBufferResidueLen( 0 ), +iInternalOutputBufferResidueLen( 0 ), iOutFrameSize( 0 ), +iInternalInputBuffer( NULL ), iInternalOutputBuffer( NULL ), +iInternalOutputBufferPos( 0 ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// Second phase of the two-phased constructor. +// Creates an instance of decoder +//---------------------------------------------------------------------------- +// + +void CAriMp3DecMmfCodec::ConstructL() + { + PRINT_ENTRY; + TMp3FrameInfo frameInfo; + + TRAPD( creatErr,iCodec = CAriMp3DecWrapper::NewL() ); + if( KErrNone != creatErr ) + { + PRINT_ERR( creatErr ); + User::Leave( creatErr ); + } + + User::LeaveIfError( iCodec->Reset() ); + + TInt frameLength; + + User::LeaveIfError( iCodec->GetMaxFrameInfo( frameLength, frameInfo ) ); + + iOutFrameSize = frameInfo.iBufferSize; + + iInternalInputBuffer = new( ELeave ) TUint8[KMinBytesInput]; + if ( !iInternalInputBuffer ) + { + PRINT_ERR( "iInternalInputBuffer is not created" ); + User::Leave( KErrNoMemory ); + } + + iInternalOutputBuffer = new( ELeave ) TUint8[iOutFrameSize]; + if ( !iInternalOutputBuffer ) + { + PRINT_ERR( "iInternalOutputBuffer is not created" ); + User::Leave( KErrNoMemory ); + } + } + +//---------------------------------------------------------------------------- +// Updates the result of the processing +//---------------------------------------------------------------------------- +// +TCodecProcessResult CAriMp3DecMmfCodec::Result( + TCodecProcessResult::TCodecProcessResultStatus aStatus, + TInt aSrcBytesConsumed, TInt aDstBytesAdded ) + + { + PRINT_ENTRY; + TCodecProcessResult result; + // update destination bytes + result.iDstBytesAdded = aDstBytesAdded; + // update source bytes + result.iSrcBytesProcessed = aSrcBytesConsumed; + + // update status + switch ( aStatus ) + { + case TCodecProcessResult::EProcessComplete: + result.iStatus = TCodecProcessResult::EProcessComplete; + break; + case TCodecProcessResult::EProcessIncomplete: + result.iStatus = TCodecProcessResult::EProcessIncomplete; + break; + case TCodecProcessResult::EEndOfData: + result.iStatus = TCodecProcessResult::EEndOfData; + break; + case TCodecProcessResult::EDstNotFilled: + result.iStatus = TCodecProcessResult::EDstNotFilled; + break; + case TCodecProcessResult::EProcessError: + result.iStatus = TCodecProcessResult::EProcessError; + break; + default: + result.iStatus = TCodecProcessResult::EProcessError; + break; + } + PRINT_MSG( LEVEL_HIGH, ( "result.iSrcBytesProcessed = %d", + result.iSrcBytesProcessed ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iDstBytesAdded = %d", + result.iDstBytesAdded ) ); + PRINT_MSG( LEVEL_HIGH, ( "result.iStatus = %d", + result.iStatus ) ); + PRINT_EXIT; + return result; + } + +//---------------------------------------------------------------------------- +// Copy the bytes to destination buffer from the internal buffer +// first checks whether the number of bytes to be copied is lesser of the +// destination buffer reamining bytes and internal input internal remaining +// remaining bytes and then copies that many bytes. +//---------------------------------------------------------------------------- +// + TInt CAriMp3DecMmfCodec::CopyToDstBuffer( CMMFDataBuffer* aDst, + TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + const TInt dstMaxLen = aDst->Data().MaxLength(); + TUint8* dstPtr = const_cast( aDst->Data().Ptr() ); + TInt dstBufferPos = aDst->Position(); + + // destination buffer remaining bytes + TInt dstBufferRemainingBytes = dstMaxLen + - dstBufferPos + - aDstBytesConsumed; + // internal output buffer remaining bytes + TInt internalOutputBufferRemainingBytes = + iInternalOutputBufferResidueLen + - iInternalOutputBufferPos; + + if ( internalOutputBufferRemainingBytes > dstBufferRemainingBytes ) + { + numberOfBytesToBeCopied = dstBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalOutputBufferRemainingBytes; + iInternalOutputBufferResidueLen = 0; + } + + // copy data to destination buffer from internal ouput buffer + Mem::Copy( dstPtr + dstBufferPos + aDstBytesConsumed, + iInternalOutputBuffer + iInternalOutputBufferPos, + numberOfBytesToBeCopied ); + + // update internal output buffer position + if( iInternalOutputBufferResidueLen ) + { + iInternalOutputBufferPos += dstBufferRemainingBytes; + } + else + { + iInternalOutputBufferPos = 0; + } + + aDstBytesConsumed += numberOfBytesToBeCopied; + aDst->Data().SetLength( dstBufferPos + aDstBytesConsumed ); + PRINT_EXIT; + return numberOfBytesToBeCopied; + } + +//--------------------------------------------------------------------------- +// Copy the bytes from the source buffer to the internal input buffer. +// first it checks number of bytes to be copied is lesser of the source buffer +// remaining bytes or internal input buffer remaining bytes and then copies +// that many bytes. +//--------------------------------------------------------------------------- +// + TInt CAriMp3DecMmfCodec::CopyFromSrcBuffer( const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed ) + { + PRINT_ENTRY; + TInt numberOfBytesToBeCopied; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + + // calculate the source buffer remaining bytes + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + // calculate internal input buffer remaining bytes + TInt internalInputBufferRemaingBytes = KMinBytesInput + - iInternalInputBufferResidueLen; + + if ( internalInputBufferRemaingBytes > srcBufferRemainingBytes ) + { + numberOfBytesToBeCopied = srcBufferRemainingBytes; + } + else + { + numberOfBytesToBeCopied = internalInputBufferRemaingBytes; + } + + // copy data from source buffer to internal input buffer + Mem::Copy( iInternalInputBuffer + iInternalInputBufferResidueLen, + srcPtr + srcBufferPos + aSrcBytesConsumed, + numberOfBytesToBeCopied ); + + // update internal input buffer residue length + iInternalInputBufferResidueLen += numberOfBytesToBeCopied; + aSrcBytesConsumed += numberOfBytesToBeCopied; + PRINT_EXIT; + return numberOfBytesToBeCopied; + } +//--------------------------------------------------------------------------- +// Moves the data of the internal input buffer to the start position +//--------------------------------------------------------------------------- +// +void CAriMp3DecMmfCodec::ShiftData( TInt aFromPos, TInt aToPos ) + { + PRINT_ENTRY; + for ( TInt i = aToPos; i < ( iInternalInputBufferResidueLen - aFromPos ); + i++ ) + { + iInternalInputBuffer[i] = iInternalInputBuffer[i + aFromPos]; + } + iInternalInputBufferResidueLen -= aFromPos; + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +// Gets the new data from the source buffer. +// checks whether it is last buffer from the source buffer and copies the data +// and then checks if source buffer remianing bytes are not and returns the +// result of the processing. +//--------------------------------------------------------------------------- +// +TCodecProcessResult CAriMp3DecMmfCodec::GetNewData( + const CMMFDataBuffer* aSrc, + TInt &aSrcBytesConsumed, TInt &aDstBytesConsumed ) + { + PRINT_ENTRY; + TUint8* srcPtr = const_cast ( aSrc->Data().Ptr() ); + TInt srcBufferLen = aSrc->Data().Length(); + TInt srcBufferPos = aSrc->Position(); + TBool lastFrame = aSrc->LastBuffer(); + // calculate source buffer remaining bytes + TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos + - aSrcBytesConsumed; + + TCodecProcessResult result; + result.iStatus = TCodecProcessResult::EProcessError; + + // if it is last frame return end of data + if ( ( lastFrame ) && ( srcBufferRemainingBytes == 0 ) ) + { + iInternalInputBufferResidueLen = 0; + iInternalOutputBufferResidueLen = 0; + iInternalOutputBufferPos = 0; + PRINT_EXIT; + return Result( TCodecProcessResult::EEndOfData, + aSrcBytesConsumed, aDstBytesConsumed ); + } + else + { + iInternalInputBufferResidueLen = 0; + TInt numberOfBytesToBeCopied = CopyFromSrcBuffer( aSrc, + aSrcBytesConsumed ); + + if ( iInternalInputBufferResidueLen < KMinBytesInput ) + { + PRINT_EXIT; + return Result( TCodecProcessResult::EDstNotFilled, + aSrcBytesConsumed, aDstBytesConsumed ); + } + } + PRINT_EXIT; + return result; + } +/* __________________________________________________________________________ +* Exported proxy for instantiation method resolution +* Define the interface UIDs +*/ + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( KUidMp3DecCodecImplUid, + CAriMp3DecMmfCodec::NewL ) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) +{ + PRINT_ENTRY; + aTableCount = sizeof( ImplementationTable ) + / sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; +} + +//--------------------------------------------------------------------------- +// End of File +//--------------------------------------------------------------------------- diff -r 000000000000 -r bb31fbe78861 mp3_dec/arimp3decwrapper/export_hdr/arimp3decwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp3_dec/arimp3decwrapper/export_hdr/arimp3decwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for Wrapper APIs.Interface class for +* Mp3 Decoder Wrapper.The member functions are pure virtual functions which +* are to be implemented by the derived class. +* +*/ + +#ifndef ARIMP3DECWRAPPER_H +#define ARIMP3DECWRAPPER_H + +// System includes +#include + +// Class declaration +class TMp3FrameInfo + { + +public: + TInt iSamplingFrequency; + TInt iNumberOfChannels; + TInt iBufferSize; + TInt iBitRate; + + }; + +// Class declaration +class CAriMp3DecWrapper : public CBase + { + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriMp3DecWrapper + */ + IMPORT_C static CAriMp3DecWrapper* NewL(); + /**> Destructor */ + virtual ~CAriMp3DecWrapper(); + /** + * The function resets the decoder. + * @param + * @return return status + */ + virtual TInt Reset() = 0 ; + /** + * The function Gets frame information for the given source. + * @param aBuf + * Pointer to buffer containing the header of input stream data + * @param aBufLen + * Size of Buffer in bytes + * @param aFrameLen + * Length of the frame + * @param aInfo + * Reference to the structure TMp3FrameInfo + * @return return status + */ + virtual TInt GetFrameInfo( const TUint8* aBuf, TInt aBufLen, + TInt &aFrameLen, TMp3FrameInfo& aInfo ) = 0 ; + /** + * The function Gets maximum out put frame length with the information + * @param aFrameLen + * Length of the maximum out put frame + * @param aInfo + * Reference to the structure TMp3FrameInfo + * @return return status + */ + virtual TInt GetMaxFrameInfo( TInt &aFrameLen, + TMp3FrameInfo& aInfo ) = 0 ; + /** + * The function gives the offset value of the buffer from where frame + * starts. + * @param aBuf + * Pointer to the input buffer + * @param aBufLen + * Length of the input buffer + * @param aSyncPos + * Offset value of the buffer from where frame starts + * @return return status + */ + virtual TInt SeekSync( const TUint8* aBuf, TInt aBufLen, + TInt &aSyncPos ) = 0 ; + /** + * The function decodes the aSrc buffer. + * @param aSrc + * Pointer to the source buffer + * @param aSrcUsed + * Size of the source buffer + * @param aDst + * Pointer to the destination buffer + * @param aDstLen + * Size of the destination buffer + * @return return status + */ + virtual TInt Decode( TUint8* aSrc, TInt& aSrcUsed, TUint8* aDst, + TInt& aDstLen ) = 0 ; + + }; + +#endif //ARIMP3DECWRAPPER_H + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/group/arimpeg4aspdechwdevice.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/group/arimpeg4aspdechwdevice.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for Mpeg4/H263 Video Decode HwDevice. +*/ + +#include +#include "..\inc\arimpeg4aspdechwdeviceuid.hrh" + +TARGET arimpeg4aspdechwdevice.dll + +TARGETTYPE PLUGIN + +#ifdef SYMBIAN_SECURE_ECOM +TARGETTYPE PLUGIN +#else +TARGETTYPE ECOMIIC +#endif + +UID 0x10009D8D KUidMp4DecoderHwDeviceDllUid + +CAPABILITY ALL -TCB + +SOURCEPATH ..\src +SOURCE arimpeg4aspdechwdevice.cpp + +START RESOURCE 200298FA.rss + TARGET arimpeg4aspdechwdevice.rsc +END + +MACRO LOGLEVEL_CRITICAL + +USERINCLUDE ..\inc +USERINCLUDE ..\..\arimpeg4aspdecwrapper\Export_hdr +USERINCLUDE ..\..\..\Utilities\log +USERINCLUDE ..\..\..\Utilities\ariprocessengine\inc +USERINCLUDE ..\..\..\Utilities\aristatemachine\inc + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\libc +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\devvideo +SYSTEMINCLUDE \epoc32\include\oem + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib estlib.lib +LIBRARY efsrv.lib +LIBRARY aristatemachine.lib +LIBRARY devvideo.lib +LIBRARY arimpeg4aspdecwrapper.lib ariprocessengine.lib diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for H264 Video Decode HwDevice. +* +*/ + +PRJ_PLATFORMS +winscw armv5 armv6 + +PRJ_MMPFILES +arimpeg4aspdechwdevice.mmp + +//----------------------------------------------------------------------------- +// End of BLD.INF +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/inc/arimpeg4aspdechwdevice.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/inc/arimpeg4aspdechwdevice.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,1232 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Header file to MPEG4ASPHwDevice. +* +*/ + +#ifndef MP4DECHWDEVICE_H +#define MP4DECHWDEVICE_H + +//System includes +#include +#include +#include + +//User includes +#include "aribaseengine.h" +#include "arimpeg4aspdecwrapper.h" +#include "arimpeg4aspdechwdeviceuid.hrh" + + +// CONSTANTS + +const TInt KMaxAllowPicLoss = 75; + +const TInt KPicRate = 30; + +const TInt KMP4Level11 = 11; +const TInt KMP4Level1 = 1; +const TInt KMP4Level2 = 2; +const TInt KMP4Level3 = 3; +const TInt KMP4Level4 = 4; +const TInt KMP4Level5 = 5; + +const TInt KH263Level10 = 10; +const TInt KH263Level20 = 20; +const TInt KH263Level30 = 30; +const TInt KH263Level45 = 45; + +const TInt KMaxInputBufferSize = ( 248 * 2048 ); +const TInt KMaxOutputBuffers = 2; +const TInt KMaxInputBuffers = 2; +const TInt KMinInputBuffers = 2; + +//Implementatino uid for hwdevice +const TUid KUidMp4H263DecoderHwDevice = {KUidMp4DecoderHwDeviceImplUid}; + +const TUint KMaxBitRate = 15*1024*1024; + +//Max number of mimetypes decoder supprots +const TInt KDecoderInfoCount = 14; + +const TText8* const KDecoderInfoMimeArray[KDecoderInfoCount] = + { + _S8("video/mp4v-es"), + _S8("video/mp4v-es; profile-level-id=8"), + _S8("video/mp4v-es; profile-level-id=9"), + _S8("video/mp4v-es; profile-level-id=1"), + _S8("video/mp4v-es; profile-level-id=2"), + _S8("video/mp4v-es; profile-level-id=3"), + _S8("video/mp4v-es; profile-level-id=4"), + _S8("video/mp4v-es; profile-level-id=5"), + _S8("video/h263-2000"), + _S8("video/h263-2000;profile=0;level=10"), + _S8("video/h263-2000;profile=0;level=20"), + _S8("video/h263-2000;profile=0;level=30"), + _S8("video/h263-2000;profile=0;level=45"), + _S8("video/h263-1998") + }; + +// FORWARD DECLARTIONS +class CAriMpeg4aspdecWrapper; +class CStateMachine; + +//CLASS DECLARATIONS + +/** + * This class is part of Aricent's Mpeg4 ASP/H263 decoder HwDevice plugin used for + * decoding Mpeg4 ASP/H263 content to yuv420. + * Provides implementation for standard MDF HwDevice plugin APIs as well as private functions + * used internal to this class for .This class also implements callback APIs from + * MMmfVideoBufferManagementObserver and MProcessEngineObserver which are called from CBaseEngine, + * MCodecObserver which are called from the codec wrapper. + */ +class CAriMpeg4aspdecHwDevice: public CMMFVideoDecodeHwDevice, + public MProcessEngineObserver, + public MMmfVideoBufferManagementObserver, + public MCodecObserver +{ +public: //Constructors and destructor + + /** + * Two-phased constructor. + * @return pointer to an instance of CMMFVideoDecodeHwDevice + */ + static CMMFVideoDecodeHwDevice* NewL(); + + /** + * Function to destroy resources allocated by this object + */ + virtual ~CAriMpeg4aspdecHwDevice(); + +public: //CMMFVideoHwDevice Functions + + /** + * Retrieves a custom interface to the specified hardware device + + * @param aInteface Interface UID, defined with the custom interface + * @return Pointer to the interface implementation, or NULL if the + * device does not implement the interface requested. + * The return value must be cast to the correct type by the user. + */ + virtual TAny* CustomInterface( TUid aInterface ); + +public: //CMMFVideoDecodeHwDevice Functions + + /** + * Retrieves decoder information about this hardware device. + * The device creates a CVideoDecoderInfo structure, + * fills it with correct data, pushes it to cleanup stack and returns it. + * The client will delete the object when it is no longer needed + + * @return Decoder information as a CVideoDecoderInfo object. + * The object is pushed to the cleanup stack, and must be deallocated by + * the caller. + + * @leave The method will leave if an error occurs. + */ + virtual CVideoDecoderInfo* VideoDecoderInfoLC(); + + /** + * Reads header information from a coded data unit. + + * @param aDataUnitType The type of the coded data unit that is contained + * in aDataUnit. + * If the data is a simple piece of bitstream, use + * EDuArbitraryStreamSection. + * @param aEncapsulation The encapsulation type used for the coded data. + * If the data is a simple piece of bitstream, use + * EDuElementaryStream. + * @param aDataUnit The coded data unit, contained in a + * TVideoInputBuffer. + + * @return Header information for the data unit, or NULL if + * the coded data unit did not contain enough data + * to parse the header.The header data must be + * returned to device using ReturnHeader() before + * Initialize() is called or decoder is destroyed. + * The data remains valid until it is returned. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called before hwdevice + * has been initialized with Initialize() + */ + virtual TVideoPictureHeader* GetHeaderInformationL( + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TVideoInputBuffer* aDataUnit ); + + /** + * Returns a header from GetHeaderInformationL() back to the decoder so + * that the memory can be freed. + + * @param aHeader The header to return + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void ReturnHeader( TVideoPictureHeader* aHeader ); + + /** + * Sets the device input format to a compressed video format. + + * @param aFormat The input format to use + * @param aDataUnitType The encapsulation type used for the coded data + * @param aEncapsulation The encapsulation type used for the coded data + * @param aDataInOrder True if the input data is written in correct + * decoding order, false if will be written in + * arbitrary order. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called before hwdevice + * has been initialized with Initialize() + */ + virtual void SetInputFormatL( const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TBool aDataInOrder ); + + /** + * Sets whether decoding should be synchronzed to the current clock source, + * if any, or if pictures should instead be decoded as soon as possible. + * If decoding is synchronized, decoding timestamps are used if available, + * presentation timestamps are used if not. When decoding is not + * synchronized, pictures are decoded as soon as source data is available + * for them, and the decoder has a free output buffer. If a clock source is + * not available, decoding will not be synchronized. + + * @param aSynchronize True if decoding should be synchronized to a clock + * source. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SynchronizeDecoding( TBool aSynchronize ); + + /** + * Sets decoder buffering options + + * @param aOptions Buffering options + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual void SetBufferOptionsL( + const CMMFDevVideoPlay::TBufferOptions& aOptions ); + + /** + * Gets the video decoder buffer options actually in use. This can be used + * before calling SetBufferOptions() to determine the default options, or + * afterwards to check the values actually in use ( if some default values + * were used ). + + * @param aOptions Buffering options structure to fill. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual void GetBufferOptions( + CMMFDevVideoPlay::TBufferOptions& aOptions ); + + /** + * Indicates which HRD/VBV specification is fulfilled in the input stream + * and any related parameters. + + * @param aHrdVbvSpec The HRD/VBV specification fulfilled + * @param aHrdVbvParams HRD/VBV parameters. The data format depends on the + * parameters chosen. For 3GPP TS 26.234. parameters + * aHrdVbvSpec=EHrdVbv3GPP, data in the descriptor + * is a package of type TPckC + * If no HRD/VBV parameters are used, the descriptor + * is empty. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SetHrdVbvSpec( THrdVbvSpecification aHrdVbvSpec, + const TDesC8& aHrdVbvParams ); + + /** + * Sets the output post-procesor device to use. If an output device is set, + * all decoded pictures are delivered to that device, and not drawn on + * screen or returned to the client. Pictures are written using + * CMMDVideoPostProcDevice::WritePictureL() or a custom interface after + * they have been decoded. The post-processor must then synchronize + * rendering to the clock source if necessary. + * + * @param aDevice The output post-processor device to use. + + * @pre This method can only be called before the hwdevice + * has been initialized with Initialize() + */ + virtual void SetOutputDevice( CMMFVideoPostProcHwDevice* aDevice ); + + /** + * Returns the current decoding position, i.e. the timestamp for the most + * recently decoded picture. + + * @return Current decoding position. + + * @pre This method can only be called before the hwdevice has + * been initialized with Initialize() + */ + virtual TTimeIntervalMicroSeconds DecodingPosition(); + + /** + * Returns the current pre-decoder buffer size + + * @return The number of bytes of data in the pre-decoder buffer. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint PreDecoderBufferBytes(); + + /** + * Reads various counters related to the received input bitstream and coded + * data units. + + * @param aCounters The counter structure to fill. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetBitstreamCounters( + CMMFDevVideoPlay::TBitstreamCounters& aCounters ); + + /** + * Retrieves the number of free input buffers the decoder has available + + * @return Number of free input buffers the decoder has available. + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint NumFreeBuffers(); + + /** + * Retrieves an empty video input buffer from the decoder. After input data + * has been written to the buffer, it can be written to the decoder using + * WriteCodedDataL(). The number of buffers the decoder must be able + * to provide before expecting any back, and the maximum size for each + * buffer, are specified in the buffer options.The decoder maintains + * ownership of the buffers even while they have been retrieved by client, + * and will take care of deallocating them. + + * @param aBufferSize Required buffer size, in bytes. The resulting + * buffer can be larger than this, but not smaller + + * @return A new input data buffer. The buffer is at least + * as large as requested, but it may be larger. + * If no free buffers are available, the return value + * is NULL. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual TVideoInputBuffer* GetBufferL( TUint aBufferSize ); + + /** + * Writes a piece of coded video data to the decoder. The data buffer must + * be retrieved from the decoder with GetBufferL(). + + * @param aBuffer The coded data unit to write. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void WriteCodedDataL( TVideoInputBuffer* aBuffer ); + +#ifdef SYMBIAN_MDF_API_V2 + /** + * Configures the Decoder using header information known by the client. + * @param aVideoPictureHeader Header information to configure the + * decoder with + * @leave The method will leave if an error occurs. Running out of data + * is not considered an error, + * as described above. + * @pre This method can only be called before the hwdevice has been + * initialized with Initialize(). + */ + virtual void ConfigureDecoderL( + const TVideoPictureHeader& aVideoPictureHeader ); + +#endif + +public: //Inherited from CMMFVideoPlayHwDevice + + /** + * Retrieves post-processing information about this hardware device. The + * device creates a CPostProcessorInfo structure defined in [3] ), fills + * it with correct data, pushes it to the cleanup stack and returns it. The + * client will delete the object when it is no longer needed. + + * @return Post-processor information as a CPostProcessorInfo object. + * The object is pushed to the cleanup stack, and must be + * deallocated by the caller. + + * @leave This method may leave with one of the standard error codes + */ + virtual CPostProcessorInfo* PostProcessorInfoLC(); + + /** + * Retrieves the list of the output formats that the device supports. The + * list is ordered in plug-in preference order, with the preferred formats + * at the beginning of the list. The list can depend on the device source + * format, and therefore SetSourceFormatL() must be called before calling + * this method. + + * @param aFormats An array for the result format list. The array + * must be created and destroyed by the caller. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetOutputFormatListL ( + RArray& aFormats ); + + /** + * Sets the device output format. + + * @param aDataUnit The format to use. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetOutputFormatL( const TUncompressedVideoFormat &aFormat ); + + /** + * Sets the clock source to use for video timing. See [3] for a discussion + * about audio/video synchronization. If no clock source is set. video + * playback will not be synchronized, but will proceed as fast as possible, + * depending on input data and output buffer availability. + + * @param aDataUnitType The clock source to use. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetClockSource ( MMMFClockSource* aClock ); + + /** + * Sets the device video output destination. The destination can be the + * screen using direct screen access ) or memory buffers. By default + * memory buffers are used. If data is written to another device, this + * method is ignored, and suitable memory buffers are always used. + + * @param aScreen True if video output destination is the screen, false + * if memory buffers. + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void SetVideoDestScreenL( TBool aScreen ); + + /** + * Sets the post-processing types to be used. + + * @param aPostProcCombination The post-processing steps to perform, a + * bitwise or of values from TPostProcessType + * @leave This method may leave with one of the + * standard error codes. + + * @pre This method can be called either before + * or after the hwdevice has been initialized + * with Initialize(). If called after + * with initialization, the change will only + * with be committed once CommitL() is called + */ + virtual void SetPostProcessTypesL ( TUint32 aPostProcCombination ); + + /** + * Sets post-processing options for input pan-scan ) cropping. + + * @param aRect The type of the coded data unit that is contained in + * aDataUnit. + + * @leave This method may leave with one of the standard error codes + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If called + * after initialization, the change will only be committed + * once CommitL() is called. + */ + virtual void SetInputCropOptionsL( const TRect& aRect ); + + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aOptions The conversion options to use + * @param aYuvFormat Conversion source YUV format, if specified. + * @param aRgbFormat Conversion target RGB format, if specified.. + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If + * called after initialization, the change will only be + * committed once CommitL() is called. + */ + virtual void SetYuvToRgbOptionsL( const TYuvToRgbOptions& aOptions, + const TYuvFormat& aYuvFormat, + TRgbFormat aRgbFormat ); + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aOptions The conversion options to use + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized + * with Initialize(). If called after initialization, + * the change will only be committed once CommitL() is + * called + */ + virtual void SetYuvToRgbOptionsL( const TYuvToRgbOptions& aOptions ); + + /** + * Sets post-processing options for YUV to RGB color space conversion. The + * first variant specifies the input YUV and output RGB formats to use + * explicitly, while the second variant uses the device input and output + * formats. For decoder devices the default YUV format used is the format + * specified in the input bitstream. SetSourceFormatL(), SetOutputFormatL() + * and SetPostProcessTypesL() must be called before this method is used + + * @param aRotationType The rotation to perform. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can be called either before or after + * the hwdevice has been initialized with Initialize(). + * If called after initialization, the change will only + * be committed once CommitL() is called. + */ + virtual void SetRotateOptionsL( TRotationType aRotationType ); + + /** + * @param aRotationType The rotation to perform. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can be called either before or after + * the hwdevice has been initialized with Initialize(). + * If called after initialization, the change will + * only be committed once CommitL() is called. + */ + virtual void SetScaleOptionsL( const TSize& aTargetSize, + TBool aAntiAliasFiltering ); + + /** + * Sets post-processing options for output cropping. SetPostProcessTypesL() + * must be called before this method is used. + + * @param aRect Output cropping area + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If called + * after initialization, the change will only be committed + * once CommitL() is called. + */ + virtual void SetOutputCropOptionsL( const TRect& aRect ); + + /** + * Sets post-processing plug-in specific options. SetPostProcessTypesL() + * must be called before this method is used. + + * @param aOptions The format is plug-in specific + + * @leave This method may leave with one of the standard error + * codes. + + * @pre This method can be called either before or after the + * hwdevice has been initialized with Initialize(). If + * called after initialization, the change will only be + * committed once CommitL() is called. + */ + virtual void SetPostProcSpecificOptionsL( const TDesC8& aOptions ); + + /** + * Initializes the device. This method is asynchronous, the device will + * call MMFVideoPlayProxy::MdvppInitializeComplete() after initialization + * has completed. After this method has successfully completed, further + * configuration changes are not possible except where separately noted + + * @leave This method may leave with one of the standard error codes. + */ + virtual void Initialize(); + + /** + * Commit all configuration changes since the last CommitL(), Revert() or + * Initialize(). This only applies to methods that can be called both + * before AND after the hwdevice has been initialized. + + @leave This method may leave with one of the standard error codes. + */ + virtual void CommitL(); + + /** + * Revert any configuration changes that have not yet been committed using + * CommitL(). This only applies to methods that can be called both before + * AND after the hwdevice has been initialized. + + * @leave This method may leave with one of the standard error codes. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Revert(); + + /** + * Starts writing output directly to the display frame buffer using Direct + * Screen Access. + + * @param aVideoRect The video output rectangle on screen. + * @param aScreenDevice The screen device to use. The screen device object + * must be valid in the current thread. + * @param aClipRegion Initial clipping region to use. + + * @leave This method may leave with one of the standard + * error codes. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void StartDirectScreenAccessL( const TRect& aVideoRect, + CFbsScreenDevice& aScreenDevice, + const TRegion& aClipRegion ); + + /** + * Sets a new clipping region for Direct Screen Access. After the method + * returns, no video will be drawn outside of the region. If clipping is + * not supported, or the clipping region is too complex, either playback + * will pause or will resume without video display, depending on the + * current setting of SetPauseOnClipFail(), and the result can be verified + * with IsPlaying(). Clipping can be disabled by setting a new clipping + * region that includes the whole video window. + + * @param aRegion The new clipping region. After the method returns, + * no video will be drawn outside the region. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetScreenClipRegion( const TRegion& aRegion ); + + /** + * Sets whether the system should pause playback when it gets a clipping + * region it cannot handle, or Direct Screen Access is aborted completely. + * If not, processing will proceed normally, but no video will be drawn. + * By default, playback is paused. + + * @param aPause True if playback should be paused when clipping fails, + * false if not. + * If playback is not paused, it will be continued + * If without video display + * + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void SetPauseOnClipFail( TBool aPause ); + + /** + * Aborts Direct Screen Access completely, to be called from + * MAbortDirectScreenAccess::AbortNow() and similar methods. DSA can be + * resumed by calling StartDirectScreenAccessL(). + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void AbortDirectScreenAccess(); + + /** + * Indicates Whether playback is proceeding + * @return ETrue if video is still being played even if not + * necessarily displayed ) + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TBool IsPlaying(); + + /** + * Re-draws the latest video picture.Only available when DSA is being used. + * If DSA is aborted or a non-supported clipping region has been set, the + * request may be ignored. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Redraw(); + + /** + * Starts video playback, including decoding, post-processing, and + * rendering. Playback will proceed until it has been stopped or paused, or + * the end of the bitstream is reached. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Start(); + + /** + * Stops video playback. No new pictures will be decoded, post-processed, + * or rendered. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Stop(); + + /** + * Pauses video playback, including decoding, post-processing, and + * rendering. No pictures will be decoded, post-processed, or rendered + * until playback has been resumed. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Pause(); + + /** + * Resumes video playback after a pause. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void Resume(); + + /** + * Changes to a new decoding and playback position, used for randomly + * accessing seeking ) the input stream. The position change flushes all + * input and output buffers, pre-decoder and post-decoder buffering are + * handled as if a new bitstream was. If the device still has buffered + * pictures that precede the new playback position, they will be discarded. + * If playback is synchronized to a clock source, the client is responsible + * for setting the clock source to the new position. + + * @param aPlaybackPositio The new playback position in the video stream. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void SetPosition( + const TTimeIntervalMicroSeconds& aPlaybackPosition ); + + /** + * Freezes a picture on the screen. After the picture has been frozen, no + * new pictures are displayed until the freeze is released with + * ReleaseFreeze(). If the device output is being written to memory buffers + * or to another plug-in, instead of the screen, no decoded pictures will + * be delivered while the freeze is active, and they are simply discarded. + + * @param aTimestamp The presentation timestamp of the picture to + * freeze. The frozen picture will be the first + * picture with a timestamp greater than or equal to + * this parameter + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void FreezePicture( const TTimeIntervalMicroSeconds& aTimestamp ); + + /** + * Releases a picture frozen with FreezePicture() + + * @param aTimestamp The presentation timestamp of the picture to + * release. The first picture displayed after the + * release will be the first picture with a timestamp + * greater than or equal to this parameter. To + * greater release the freeze immediately, set the + * greater timestamp to zero. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void ReleaseFreeze( const TTimeIntervalMicroSeconds& aTimestamp ); + + /** + * Returns the current playback position, i.e. the timestamp for the most + * recently displayed or virtually displayed picture. If the device output + * is written to another device, the most recent output picture is used. + + * @return Current playback position + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TTimeIntervalMicroSeconds PlaybackPosition(); + + /** + * Returns the total amount of memory allocated for uncompressed pictures. + * This figure only includes the pictures actually allocated by the plug-in + * itself, so that the total number of bytes allocated in the system can be + * calculated by taking the sum of the values from all plug-ins. + + * @return Total number of bytes of memory allocated for uncompressed + * pictures. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint PictureBufferBytes(); + + /** + * Reads various counters related to decoded pictures. See the definition + * of TPictureCounters for a description of the counters. The counters are + * reset when Initialize() or this method is called, and thus they only + * include pictures processed since the last call. + + * @param aCounters The counter structure to fill + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void GetPictureCounters( + CMMFDevVideoPlay::TPictureCounters& aCounters ); + + /** + * Sets the computational complexity level to use. If separate complexity + * levels are not available, the method call is ignored. If the level + * specified is not available, the results are undefined. Typically the + * device will either ignore the request or use the nearest suitable level. + + * @param aLevel The computational complexity level to use. Level zero ( 0 ) + * is the most complex one, with the highest quality. Higher + * level numbers require less processing and may have lower + * quality + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void SetComplexityLevel( TUint aLevel ); + + /** + * Gets the number of complexity levels available. + + * @return The number of complexity control levels available, or zero if + * the information is not available yet. The information may not + * be available if the number of levels depends on the input + * data, and enough input data has not been read yet. In that + * case, using level zero is safe. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual TUint NumComplexityLevels(); + + /** + * Gets information about a computational complexity level. This method can + * be called after NumComplexityLevels() has returned a non-zero value - at + * that point the information is guaranteed to be available. Some hardware + * device implementations may not be able to provide all values, in that + * case the values will be approximated. + + * @param aLevel The computational complexity level to query. The level + * numbers range from zero the most complex ) to + * NumComplexityLevels()-1. + * @param aInfo The information structure to fill + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void GetComplexityLevelInfo( TUint aLevel, + CMMFDevVideoPlay::TComplexityLevelInfo& aInfo ); + + /** + * Returns a picture back to the device. This method is called by + * CDevVideoPlay to return pictures from the client after they have been + * written with NewPicture() ), or by the output device when it has + * finished using a picture. + + * @param aPicture The picture to return. The device can re-use the + * memory for the picture. + + * @pre This method can only be called after the hwdevice has + * been initialized with Initialize(). + */ + virtual void ReturnPicture( TVideoPicture* aPicture ); + + /** + * Gets a copy of the latest picture sent to output + + * @param aPictureData Target picture. The memory for the picture + * must be allocated by the caller, and + * initialized properly. The data formats must + * match the snapshot format requested. + * @param aFormat The picture format to use for the snapshot. + + * @return ETrue if the snapshot was taken, EFalse if a + * picture is not available. The picture may not + * be available if decoding has not progressed + * far enough yet. + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the + * hwdevice has been initialized with Initialize(). + */ + virtual TBool GetSnapshotL( TPictureData& aPictureData, + const TUncompressedVideoFormat& aFormat ); + + /** + * Gets a copy of a specified picture.When the snapshot is available, it + * will be returned to the client using the TimedSnapshotComplete() + * callback. To cancel a timed snapshot request, use CancelTimedSnapshot(). + * Only one timed snapshot request can be active at a time. + + * @param aPictureData Target picture. The memory for the picture + * must be allocated by the caller, and + * initialized properly. The data formats + * must match the snapshot format requested. + * The picture must remain valid until + * the snapshot has been taken or until the + * the request has been cancelled with + * the CancelTimedSnapshot(). + * @param aFormat The picture format to use for the snapshot + * @param aPresentationTimestamp Presentation timestamp for the picture to + * copy. The timestamp + * must match the timestamp in the picture + * must exactly, so the same clock frequency + * must should be used. Used for the first + * must method variant + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the + * hwdevice has been initialized with + * Initialize(). + */ + + virtual void GetTimedSnapshotL( TPictureData* aPictureData, + const TUncompressedVideoFormat& aFormat, + const TTimeIntervalMicroSeconds& aPresentationTimestamp ); + + /** + * Gets a copy of a specified picture.When the snapshot is available, it + * will be returned to the client using the TimedSnapshotComplete() + * callback. To cancel a timed snapshot request, use CancelTimedSnapshot(). + * Only one timed snapshot request can be active at a time. + + * @param aPictureData Target picture. The memory for the picture must be + * allocated by the caller, and initialized properly. + * The data formats must match the snapshot format + * requested. The picture must remain valid until + the snapshot has been taken or until the request + has been cancelled with CancelTimedSnapshot(). + * @param aFormat The picture format to use for the snapshot. + * @param aPictureId Picture identifier for the picture to copy. Used + * for the second method variant + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetTimedSnapshotL( TPictureData* aPictureData, + const TUncompressedVideoFormat& aFormat, + const TPictureId& aPictureId ); + /** + * Cancels a timed snapshot request + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void CancelTimedSnapshot(); + + /** + * Gets a list of the supported snapshot picture formats. + + * @param aFormats An array for the result format list. The array + * must be created and destroyed by the caller + + * @leave The method will leave if an error occurs. + + * @pre This method can only be called after the hwdevice + * has been initialized with Initialize(). + */ + virtual void GetSupportedSnapshotFormatsL( + RArray& aFormats ); + + /** + * Notifies the hardware device that the end of input data has been reached + * and no more input data will be written. The hardware device can use this + * signal to ensure that the remaining data gets processed, without waiting + * for new data. After the remaining data has been processed, the hardware + * device must notify call the proxy MdvppStreamEnd() callback.This method + * is mainly useful for file-to-file conversions and other non-realtime + * processing. For real-time playback all video pictures are processed or + * discarded according to their timestamps. + + * @pre This method can only be called after the hwdevice has been + * initialized with Initialize(). + */ + virtual void InputEnd(); + +public: // MProcessEngineObserver Function + + /** + * Callback from Engine to represent buffer has been consumed + * @param aInp pointer to the used input buffer + * @param aError error value + * @return TInt KErrNone or KErrCancel + */ + virtual TInt InputBufferConsumed ( TAny* aInp, TInt aError ); + + /** + * Callback to reprsent that output buffer is ready + * @param aOup pointer to the used input buffer + * @param aError error value + * @return TInt KErrNone or KErrCancel + */ + virtual TInt OutputBufferReady ( TAny* aOup, TInt aError ); + + /** + * CallBack to handle error + * @return None + */ + virtual void FatalErrorFromProcessEngine ( TInt aError ); + + //Callback to indicate the completion of callback + virtual void CommandProcessed ( TInt aCmd, TAny* aCmdData, TInt aError ); + +public : // MMmfVideoBufferManagementObserver Functions + + /** + * Notifies the observer that one or more new input buffers are available. + * The client can then use MmvbmGetBufferL() to get a buffer. + */ + virtual void MmvbmoNewBuffers() ; + + /** + * Notifies the observer all outstanding input buffers must be + * released immediately + */ + virtual void MmvbmoReleaseBuffers(); + +public : //MCodedObserver Functions + + /** + * Call back from the codec wrapper when there is new config information. + + * @param "None". + */ + virtual void NewConfigFound (); + + /** + * Call back from the codec wrapper when EInputConsumed for Not yet get I frame. + + * @param "None". + */ + virtual void EInputConsumed(); + + +protected: + + /** + * Set the proxy implementation to be used. Called just after the object is + * constructed. + + * @param aProxy The proxy to use. + */ + virtual void SetProxy( MMMFDevVideoPlayProxy& aProxy ); + +private: + /** + * C++ default constructor. + */ + CAriMpeg4aspdecHwDevice(); + + /** + * Symbian 2nd phase constructor . + */ + void ConstructL(); + + /** + *Creates o/p buffers based on the o/p formats supported + *@param : None + */ + void CreateOutputBuffersL(); + + /** + * Gives call backs to clinet regarding slice and picture loss + * @param : None + */ + + void SliceAndPictureLoss(); + + /** + * Allcotion and reallocation of input buffers + * @param : None + */ + + void CreateInputBufferL( TUint aBufferSize, TBool aReallocate ); + + /** + * HandleInputEndInStopping + * @param : None + */ + void HandleInputEndInStopping(); + + /** + * Function to get the last frame + * @param : None + */ + void GetLastFrame(); + + +private : // Data + + + // Reference to Input Free Buffer Queue + RArray iInputFreeBufferQueue; + + // Free Input Buffers + TVideoInputBuffer* iInputFreeBuffers; + + // Reference to Output Device + CMMFVideoPostProcHwDevice* iOutputDevice; + + // Reference to Proxy Object + MMMFDevVideoPlayProxy* iMMFDevVideoPlayProxy; + + // Represents the state of the Decoder Hw Device + CStateMachine *iState; + + // Reference to Video Picture Header + TVideoPictureHeader* iVideoPictureHeader; + + // Current Decoding Position + TTimeIntervalMicroSeconds iDecodingPosition; + + // Handle to the Compressed video format + CCompressedVideoFormat* iInputFormat; + + // Uncompressed Output format + TUncompressedVideoFormat iOutputFormat; + + // Buffer Options Set by the Client + CMMFDevVideoPlay::TBufferOptions iBufferOptions; + + // Current Picture Counter value + CMMFDevVideoPlay::TPictureCounters iPictureCounters; + + // Current Bit Stream Counter value + CMMFDevVideoPlay::TBitstreamCounters iBitstreamCounters; + + // Codec Reference + CAriMpeg4aspdecWrapper* iCodec; + + // Base Process Engine Reference + CBaseEngine* iEngine; + + // To Check whether inputend is called or not + TBool iInputEndCalled; + + // OutPut Buffers + TVideoPicture* iOutputFreeBuffer; + + // Free OutPut Buffer Queue + RArray iOutputFreeBufferQueue; + + // counter to keep track of the no of buffers added to the engine + TInt iFilledBufferCounter; + + // data unit type set by the client + TVideoDataUnitType iDataUnitType; + + // Encapulation set by the client + TVideoDataUnitEncapsulation iEncapsulation; + + // represents the o/p buffer size + TInt iOutputBufferSize; + + // flag to whether o/p buffers created or not + TBool iOutputBuffersCreated; + + // Picture Number + TUint iPictureNumber; + + // represents the number of inputbuffers created so avoids reallocation + TUint iNumberOfInputBuffersAllocated; + + // Reference to the custom buffer interface + MMmfVideoBufferManagement* iCustomBufferHandle; + + // buffer options for the custom interface + MMmfVideoBufferManagement::TBufferOptions *iCustomBufferOptions; + + // represents whether the o/p buffers should be added to engine or not + TBool iBufferAdded; + + // flag to indciate that ConfigureDecoderL is called + TBool iConfigureDecoderCalled; + + // flag to indciate that decoder has been configured + TBool iDecoderConfigured; + + // flag to indicate EOS reached + TInt iInputBufferConsumedCounter; + + //Flag to indicate that the last input frame has generated an output + TBool iNoLastOut; + + // array which holds the list of supported formats + RArray iSupportedFormats; + + // array which holds the max value of the picture rates + RArray iMaxPictureRates; +}; + +#endif //__MP4DECHWDEVICE_H__ diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/inc/arimpeg4aspdechwdeviceuid.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/inc/arimpeg4aspdechwdeviceuid.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Information file for the MP4/H263 Video Decode HwDevice. +*/ + +#ifndef MP4DECHWDEVICE_HRH +#define MP4DECHWDEVICE_HRH + +#define KUidMp4DecoderHwDeviceImplUid 0x200298F9 +#define KUidMp4DecoderHwDeviceDllUid 0x200298FA + +#endif //MP4DECHWDEVICE diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/src/200298FA.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/src/200298FA.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for the MP4/H263 Video Decode HwDevice +* +*/ + +#include "RegistryInfo.rh" +#include "DevVideoPluginInterfaceUIDs.hrh" +#include "arimpeg4aspdechwdeviceuid.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidMp4DecoderHwDeviceDllUid; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidDevVideoDecoderHwDeviceDefine; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidMp4DecoderHwDeviceImplUid; + version_no = 1; + display_name = "Aricent MP4 Video Dec HwDevice"; + default_data ="video/mp4v-es||video/mp4v-es;profile-level-id=?||video/h263-2000||video/h263-2000;profile=0;level=?0||video/h263-1998||video/h263-1998;profile=0;level=?0"; + opaque_data = "0"; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdechwdevice/src/arimpeg4aspdechwdevice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdechwdevice/src/arimpeg4aspdechwdevice.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,2417 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This is a source file, which is required for Mp4DecHwDevice. +* +*/ + +//User includes +#include "arimpeg4aspdechwdevice.h" +#include "aristatemachine.h" +#include "ariprint.h" + +//manufacturer name +_LIT( KManufacturer, "Aricent" ); + +_LIT( KIdentifier, "MPEG4/H263 Video Decoder" ); + +//supported mime types for mp4 +_LIT8( KMPEG4SupportedMimeType, "video/mp4v-es" ); +// profile level 0 +_LIT8( KMPEG4SupportedProfileLevel_0, "video/mp4v-es; profile-level-id=8" ); +// profile level 0b / 11 +_LIT8( KMPEG4SupportedProfileLevel_0b, "video/mp4v-es; profile-level-id=9" ); +// profile level 1 +_LIT8( KMPEG4SupportedProfileLevel_1, "video/mp4v-es; profile-level-id=1" ); +// profile level 2 +_LIT8( KMPEG4SupportedProfileLevel_2, "video/mp4v-es; profile-level-id=2" ); +// profile level 3 +_LIT8( KMPEG4SupportedProfileLevel_3, "video/mp4v-es; profile-level-id=3" ); +// profile level 4 +_LIT8( KMPEG4SupportedProfileLevel_4, "video/mp4v-es; profile-level-id=4" ); +// profile level 5 +_LIT8( KMPEG4SupportedProfileLevel_5, "video/mp4v-es; profile-level-id=5" ); + +//supported mime types for h263 +_LIT8( KH263SupportedMimeType, "video/h263-2000" ); +_LIT8( KH26398SupportedMimeType, "video/h263-1998" ); + +// h263 profile level 10 +_LIT8( KH263SupportedProfileLevel_10, "video/h263-2000;profile=0;level=10" ); +// h263 profile level 20 +_LIT8( KH263SupportedProfileLevel_20, "video/h263-2000;profile=0;level=20" ); +// h263 profile level 30 +_LIT8( KH263SupportedProfileLevel_30, "video/h263-2000;profile=0;level=30" ); +// h263 profile level 45 +_LIT8( KH263SupportedProfileLevel_45, "video/h263-2000;profile=0;level=45" ); + + +//--------------------------------------------------------------------------- +//1st phase constructor of CAriMpeg4aspdecHwDevice +//--------------------------------------------------------------------------- +// +CMMFVideoDecodeHwDevice* CAriMpeg4aspdecHwDevice::NewL() + { + PRINT_ENTRY; + CAriMpeg4aspdecHwDevice* self = new ( ELeave ) CAriMpeg4aspdecHwDevice; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return self; + } + + +//--------------------------------------------------------------------------- +//Destructor +//--------------------------------------------------------------------------- +// +CAriMpeg4aspdecHwDevice::~CAriMpeg4aspdecHwDevice() + { + PRINT_ENTRY; + delete iInputFormat; + delete iEngine; + delete iCodec; + delete iState; + + delete iVideoPictureHeader; + + // This is required becoz user may say exit before start at that point + // OutputFreeBuffer is not created + if ( iOutputFreeBuffer ) + { + for ( TInt i = 0 ; i < KMaxOutputBuffers; i++ ) + { + if ( ( iOutputFreeBuffer + i )->iHeader ) + { + delete ( iOutputFreeBuffer + i )->iHeader; + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete + ( TUint8* )( iOutputFreeBuffer + i )->iData.iRawData->Ptr(); + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete ( iOutputFreeBuffer + i )->iData.iRawData; + } + } + delete [] iOutputFreeBuffer; + } + + if ( iInputFreeBuffers ) + { + TInt i; + for ( i = 0 ; i < TInt( iBufferOptions.iMinNumInputBuffers ); i++ ) + { + delete [] ( TUint8* )iInputFreeBuffers[i].iData.Ptr(); + delete iInputFreeBuffers[i].iUser; + } + delete [] iInputFreeBuffers; + } + + if ( iCustomBufferOptions ) + { + delete iCustomBufferOptions; + } + iOutputFreeBufferQueue.Close(); + iInputFreeBufferQueue.Close(); + + iMaxPictureRates.Reset(); + iMaxPictureRates.Close(); + iSupportedFormats.Reset(); + iSupportedFormats.Close(); + + iOutputDevice = NULL; + iMMFDevVideoPlayProxy = NULL; + iCustomBufferHandle = NULL; + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//Retrieves a custom interface to the device. +//--------------------------------------------------------------------------- +// +TAny* CAriMpeg4aspdecHwDevice::CustomInterface( TUid /*aInterface*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + + return NULL; + } + + +//--------------------------------------------------------------------------- +//Retrieves decoder information about this hardware device. The device +//creates a CVideoDecoderInfo structure, fills it with correct data, +//pushes it to the cleanup stack and returns it. The client will delete the +//object when it is no longer needed. +//--------------------------------------------------------------------------- +// +CVideoDecoderInfo* CAriMpeg4aspdecHwDevice::VideoDecoderInfoLC() + { + PRINT_ENTRY; + for ( TUint i = 0; i < KDecoderInfoCount; i++ ) + { + // construct the video types for iVidTypes + CCompressedVideoFormat* format = NULL; + TPtrC8 mimeType = KDecoderInfoMimeArray[i]; + format = CCompressedVideoFormat::NewL( mimeType ); + CleanupStack::PushL(format); + TInt status = iSupportedFormats.Append( format ); + if ( status != KErrNone ) + { + PRINT_MSG( LEVEL_LOW, ( " Format support is not done, retval of " + "append = %d \n", status ) ); + } + CleanupStack::Pop( format ); + + // max picture rates + TPictureRateAndSize pictureRateAndSize; + pictureRateAndSize.iPictureSize = TSize( KMaxFrameWidth, + KMaxFrameHeight ); + pictureRateAndSize.iPictureRate = KPicRate; + status = iMaxPictureRates.Append(pictureRateAndSize); + if ( status != KErrNone ) + { + PRINT_MSG( LEVEL_LOW, ( " error in appendng picturerates = %d \n", + status ) ); + } + } + + TUint maxBitRate = KMaxBitRate; + + CVideoDecoderInfo* videoDecoderInfo = CVideoDecoderInfo::NewL( + KUidMp4H263DecoderHwDevice, + KManufacturer, + KIdentifier, + TVersion( 1, 0, 0 ), + iSupportedFormats.Array(), + EFalse, + EFalse, + TSize( KMaxFrameWidth, KMaxFrameHeight ), + maxBitRate, + iMaxPictureRates.Array(), + ETrue, + ETrue ); + + CleanupStack::PushL( videoDecoderInfo ); + + PRINT_MSG( LEVEL_LOW, ( "Closing maxPictureRates&supportedFormats\n" ) ); + + PRINT_EXIT; + + return videoDecoderInfo; +} + +//--------------------------------------------------------------------------- +//Reads header information from a coded data unit. +//--------------------------------------------------------------------------- +// +TVideoPictureHeader* CAriMpeg4aspdecHwDevice::GetHeaderInformationL( + TVideoDataUnitType /*aDataUnitType*/, + TVideoDataUnitEncapsulation aEncapsulation, + TVideoInputBuffer* aDataUnit ) + { + PRINT_ENTRY; + if ( !aDataUnit ) + { + PRINT_ERR( "Input argument is not proper, aDataUnit is null \n" ); + User::Leave( KErrArgument ); + } + + if ( aEncapsulation != EDuElementaryStream ) + { + PRINT_ERR( "aEncapsulation is not supported type \n" ); + User::Leave( KErrNotSupported ); + } + + iVideoPictureHeader = new ( ELeave ) TVideoPictureHeader; + + TRAPD( err, CAriMpeg4aspdecWrapper::GetHeaderInfoL( *aDataUnit, + *iVideoPictureHeader ) ); + + if ( err == KErrNone ) + { + PRINT_EXIT; + return ( iVideoPictureHeader ); + } + delete iVideoPictureHeader; + iVideoPictureHeader = NULL; + + switch ( err ) + { + case KErrCorrupt: + case KErrNoMemory: + case KErrArgument: + case KErrNotSupported: + { + PRINT_ERR( "GetHeaderInfoL is returned with error \n" ); + User::Leave( err ); + break; + } + case KErrUnderflow: + { + PRINT_ERR( "GetHeaderInfoL returnd with error KErrUnderflow\n" ); + break; + } + default: + { + PRINT_ERR( "GetHeaderInfoL is returned with error \n" ); + User::Leave( KErrGeneral ); + } + }; + + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +//Returns a header from GetHeaderInformationL() back to the decoder so that +//the memory can be freed. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::ReturnHeader( TVideoPictureHeader* aHeader ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( iVideoPictureHeader == aHeader ) + { + delete iVideoPictureHeader; + iVideoPictureHeader = NULL; + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Sets the device input format to a compressed video format. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetInputFormatL( + const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aEncapsulation, + TBool aDataInOrder ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( ( !aDataInOrder ) || + ( aEncapsulation == EDuGenericPayload ) || + ( aEncapsulation == EDuRtpPayload ) || + ( aDataUnitType == EDuArbitraryStreamSection ) ) + User::Leave( KErrNotSupported ); + + if ( ( aFormat.MimeType().FindF( KMPEG4SupportedMimeType ) != + KErrNotFound ) || + ( aFormat.MimeType().FindF( KH263SupportedMimeType ) != + KErrNotFound ) || + ( aFormat.MimeType().FindF( KH26398SupportedMimeType ) != + KErrNotFound ) ) + + { + iInputFormat = CCompressedVideoFormat::NewL( aFormat ); + iDataUnitType = aDataUnitType; + iEncapsulation = aEncapsulation; + } + else + { + PRINT_ERR( "aFormat is not supported \n" ); + User::Leave( KErrNotSupported ); + } + } + else + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Sets whether decoding should be synchronized to the current clock source, +//if any, or if pictures should instead be decoded as soon as possible. +//If decoding is synchronized, decoding timestamps are used if available, +//presentation timestamps are used if not. When decoding is not synchronized, +//pictures are decoded as soon as source data is available for them, and the +//decoder has a free output buffer. If a clock source is not available, +//decoding will not be synchronized. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SynchronizeDecoding( TBool /*aSynchronize*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + return; + } + + +//--------------------------------------------------------------------------- +//Sets the Buffer Options as specified by the client. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetBufferOptionsL( + const CMMFDevVideoPlay::TBufferOptions& aOptions ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + TTimeIntervalMicroSeconds zerotime( 0 ); + if ( ( aOptions.iMinNumInputBuffers < KMinInputBuffers ) || + ( aOptions.iPreDecodeBufferSize != 0 ) || + ( aOptions.iMaxPostDecodeBufferSize != 0 ) || + ( aOptions.iPreDecoderBufferPeriod != zerotime ) || + ( aOptions.iPostDecoderBufferPeriod != zerotime ) ) + { + User::Leave( KErrArgument ); + } + + if ( ( aOptions.iMinNumInputBuffers > KMaxInputBuffers ) || + ( aOptions.iMaxInputBufferSize > KMaxInputBufferSize ) ) + { + User::Leave( KErrNotSupported ); + } + + iBufferOptions = aOptions; + } + else + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Gets the video decoder buffer options actually in use. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetBufferOptions( + CMMFDevVideoPlay::TBufferOptions& aOptions ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + aOptions = iBufferOptions; + } + else + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Indicates which HRD/VBV specification is fulfilled in the input stream and +//any related parameters. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetHrdVbvSpec( + THrdVbvSpecification /*aHrdVbvSpec*/, + const TDesC8& /*aHrdVbvParams*/ ) + { + PRINT_ENTRY; + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Sets the output post-processor device to use. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetOutputDevice( + CMMFVideoPostProcHwDevice* aDevice ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( !aDevice ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + else + { + iOutputDevice = aDevice; + + // checks whether customBuffer supported by o/p device + iCustomBufferHandle = + ( MMmfVideoBufferManagement* )( iOutputDevice->CustomInterface( + KMmfVideoBuffermanagementUid ) ); + } + } + else + { + PRINT_ERR( "istate is not initialized yet, " + "calling MdvppFatalError on iMMFDevVideoPlayProxy\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Returns the current decoding position, i.e. +//the timestamp for the most recently decoded picture. +//--------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriMpeg4aspdecHwDevice::DecodingPosition() + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_EXIT; + return iDecodingPosition; + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + PRINT_EXIT; + return ( TTimeIntervalMicroSeconds( 0 ) ); + } + } + +//--------------------------------------------------------------------------- +//Returns the current pre-decoder buffer size. +//--------------------------------------------------------------------------- +// +TUint CAriMpeg4aspdecHwDevice::PreDecoderBufferBytes() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + PRINT_EXIT; + return ( 0 ); + } + + PRINT_EXIT; + return 0; + } + +//--------------------------------------------------------------------------- +//Reads various counters related to the received input bitstream +//and coded data units. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetBitstreamCounters( + CMMFDevVideoPlay::TBitstreamCounters& aCounters ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + aCounters = iBitstreamCounters; + //Reset the counters to Zero + iBitstreamCounters.iLostPackets = 0; + iBitstreamCounters.iTotalPackets = 0; + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Retrieves the number of free input buffers the decoder has available +//--------------------------------------------------------------------------- +// +TUint CAriMpeg4aspdecHwDevice::NumFreeBuffers() + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + if ( iNumberOfInputBuffersAllocated == 0 ) + { + PRINT_EXIT; + return ( iBufferOptions.iMinNumInputBuffers ); + } + else + { + PRINT_EXIT; + return ( iInputFreeBufferQueue.Count() ); + } + } + else + { + PRINT_ERR( "iState is not initialised, calling MdvppFatalError\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + PRINT_EXIT; + return( KErrNone ); + } + } + +//--------------------------------------------------------------------------- +//Returns an input buffer of size aBufferSize. If no buffer is available +//then NULL is returned. +//--------------------------------------------------------------------------- +// +TVideoInputBuffer* CAriMpeg4aspdecHwDevice::GetBufferL( TUint aBufferSize ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialized yet\n" ); + User::Leave( KErrNotReady ); + } + + if ( iState->IsInputEndPending() ) + { + PRINT_ERR( "input is pending\n" ); + User::Leave( KErrNotReady ); + } + + if ( aBufferSize > iBufferOptions.iMaxInputBufferSize ) + { + PRINT_ERR( "aBufferSize is more than the allowed size\n" ); + PRINT_MSG( LEVEL_HIGH, ( "reqBufSize = %d, maxAllowedBufSize = %d", + aBufferSize, iBufferOptions.iMaxInputBufferSize ) ); + User::Leave( KErrArgument ); + } + + TVideoInputBuffer *inBuffer = NULL; + + if ( iNumberOfInputBuffersAllocated == + iBufferOptions.iMinNumInputBuffers ) + { + if ( iInputFreeBufferQueue.Count() ) + { + // Reallocate the input buffer if needed + PRINT_MSG( LEVEL_HIGH, ( "Reallocate input buffer if needed" ) ); + CreateInputBufferL( aBufferSize, ETrue ); + inBuffer = iInputFreeBufferQueue[0]; + iInputFreeBufferQueue.Remove( 0 ); + } + else + { + PRINT_ERR( "No input free buffers available \n" ); + return NULL; + } + } + else if ( iNumberOfInputBuffersAllocated < + iBufferOptions.iMinNumInputBuffers ) + { + // Allocate new buffer of the requested size + //PRINT_ERR( "CreateInputBufferL returned EFALSE\n" ); + CreateInputBufferL( aBufferSize, EFalse ); + + // remove the last created buffer + inBuffer = iInputFreeBufferQueue[ iInputFreeBufferQueue.Count() - 1]; + + iInputFreeBufferQueue.Remove( iInputFreeBufferQueue.Count() - 1 ); + } + else + { + PRINT_ERR( "iNumberOfInputBuffersAllocated is less " + " iBufferOptions.iMinNumInputBuffers\n" ); + User::Leave( KErrGeneral ); + } + + PRINT_EXIT; + return inBuffer; + } + +//--------------------------------------------------------------------------- +//Called by DevVideoPlay to write the coded data. +//Writes a piece of coded video data to the decoder. The data buffer must +//be retrieved from the decoder with GetBufferL().. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::WriteCodedDataL( TVideoInputBuffer* aBuffer ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + PRINT_ERR( "istate is not initialized yet \n" ); + User::Leave( KErrNotReady ); + } + + if ( !aBuffer ) + { + PRINT_ERR( "aBuffer is null \n" ); + User::Leave( KErrArgument ); + } + + if ( aBuffer->iData.Length() == 0 ) + { + PRINT_ERR( "length of aBuffer is zero \n" ); + User::Leave( KErrArgument ); + } + + if ( iState->IsInputEndPending() ) + { + PRINT_ERR( "IsInputEndPending is true \n" ); + User::Leave( KErrEof ); + } + + if ( ( iDataUnitType == EDuSeveralSegments ) || + ( iDataUnitType == EDuVideoSegment ) ) + { + iBitstreamCounters.iTotalPackets++; + } + + // if custom interface is supported by o/p device get all the buffers + // and add it to Engine + if ( !iOutputBuffersCreated ) + { + // Set Stream information + if ( !iDecoderConfigured ) + { + iCodec->ConfigDecoderL( &( aBuffer->iData ) ); + // set input & output formats to Codec + iCodec->SetFormatsL( iDataUnitType, iOutputFormat ); + iDecoderConfigured = ETrue; + } + + if ( !iCustomBufferHandle ) + { + // Get o/p buffer length for creation + iOutputBufferSize = iCodec->GetOutputBufferLength(); + CreateOutputBuffersL(); + } + iOutputBuffersCreated = ETrue; + } + + // add all the o/p buffers to engine + if ( !iBufferAdded ) + { + if ( iCustomBufferHandle ) + { + TVideoPicture* videoPicture = NULL; + for ( TInt i = 0; + i < TInt( iCustomBufferOptions->iNumInputBuffers ); + i++ ) + { + videoPicture = iCustomBufferHandle->MmvbmGetBufferL( + iCustomBufferOptions->iBufferSize ); + if ( videoPicture ) + { + TRAPD( lErr, videoPicture->iHeader = + new ( ELeave ) TVideoPictureHeader ) ; + if ( lErr != KErrNone ) + { + iCustomBufferHandle->MmvbmReleaseBuffer( + videoPicture ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, + KErrArgument ); + } + else + { + iEngine->AddOutput( videoPicture ); + } + } + else + { + break; + } + } + } + else + { + for ( TInt i = 0; i < iOutputFreeBufferQueue.Count(); i++ ) + { + iEngine->AddOutput( iOutputFreeBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + } + } + iBufferAdded = ETrue; + } + + iPictureCounters.iTotalPictures++; + iFilledBufferCounter++; + TInt err = iEngine->AddInput( aBuffer ); + PRINT_MSG( LEVEL_LOW, ( "WriteCodedDataL, addinput err = %d", err ) ); + PRINT_EXIT; + } + + +#ifdef SYMBIAN_MDF_API_V2 +//--------------------------------------------------------------------------- +//Configures the Mpeg4/H263 decoder by passing the required header +//information for the stream that is getting decoded. The header +//structurespecific to the Decoder is passed as iOptional member. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::ConfigureDecoderL( + const TVideoPictureHeader& aVideoPictureHeader ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is already initialised \n" ); + User::Leave( KErrNotReady ); + } + + TInt level = aVideoPictureHeader.iLevel; + PRINT_MSG( LEVEL_LOW, ( "ConfigureDecoderL,level = %d \n", level ) ); + if ( aVideoPictureHeader.iOptional ) + { + // Mpeg-4 + switch ( level ) + { + case 0: + case KMP4Level11: //level 0b + case KMP4Level1: + case KMP4Level2: + case KMP4Level3: + case KMP4Level4: + case KMP4Level5: + case -1: + break; + default: + { + PRINT_ERR( "level is not supported \n" ); + User::Leave( KErrNotSupported ); + } + } + } + else + { + // H.263 + switch ( level ) + { + case KH263Level10: + case KH263Level20: + case KH263Level30: + case KH263Level45: + case -1: + break; + default: + { + PRINT_ERR( "level is not supported \n" ); + User::Leave( KErrNotSupported ); + } + } + } + + // Create Codec and configure the decoder + iCodec = CAriMpeg4aspdecWrapper::NewL( this ); + + // configure the decoder in case of mpeg-4 otherwise ie in + // case of h.263 wait till the first call of WriteCodedDataL() + if ( aVideoPictureHeader.iOptional ) + { + iCodec->ConfigDecoderL( aVideoPictureHeader.iOptional ); + iDecoderConfigured = ETrue; + } + iConfigureDecoderCalled = ETrue; + + PRINT_EXIT; + } +#endif + +//--------------------------------------------------------------------------- +//Retrieves post-processing information about this hardware device. +//The device creates a CPostProcessorInfo structure, fills it with correct +//data, pushes it to the cleanup stack and returns it. The client will +//delete the object when it is no longer needed. +//--------------------------------------------------------------------------- +// +CPostProcessorInfo* CAriMpeg4aspdecHwDevice::PostProcessorInfoLC() + { + PRINT_ENTRY; + //Aricent decoder does not support any post processing functionality + RArray supportedFormats; + CleanupClosePushL( supportedFormats ); + + RArray supportedCombinations; + CleanupClosePushL( supportedCombinations ); + + TYuvToRgbCapabilities yuvToRgbCapabilities; + RArray supportedScaleFactors; + CleanupClosePushL( supportedScaleFactors ); + + yuvToRgbCapabilities.iSamplingPatterns = 0; + yuvToRgbCapabilities.iCoefficients = 0; + yuvToRgbCapabilities.iRgbFormats = 0; + yuvToRgbCapabilities.iLightnessControl = EFalse; + yuvToRgbCapabilities.iSaturationControl = EFalse; + yuvToRgbCapabilities.iContrastControl = EFalse; + yuvToRgbCapabilities.iGammaCorrection = EFalse; + yuvToRgbCapabilities.iDitherTypes = 0; + + + CPostProcessorInfo* info = CPostProcessorInfo::NewL( + KUidMp4H263DecoderHwDevice, + KManufacturer, + KIdentifier, + TVersion( 1, 0, 0 ), + supportedFormats.Array(), + supportedCombinations.Array(), + //Accelerated or not + EFalse, + //supports DSA + EFalse, + yuvToRgbCapabilities, + //supported rotations + ERotateNone, + //supports Arbitrary scaling + EFalse, + supportedScaleFactors.Array(), + //supports antialiased scaling + EFalse ); + + CleanupStack::PushL( info ); + CleanupStack::Pop( &supportedScaleFactors ); + supportedScaleFactors.Close(); + CleanupStack::Pop( &supportedCombinations ); + supportedCombinations.Close(); + CleanupStack::Pop( &supportedFormats ); + supportedFormats.Close(); + + PRINT_EXIT; + return info; + } + +//--------------------------------------------------------------------------- +//Retrieves the list of the output formats that the device supports. +//The list can depend on the device source format, and therefore +//SetSourceFormatL() must be called before calling this method. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetOutputFormatListL( + RArray& aFormats ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is already initialised \n" ); + User::Leave( KErrNotReady ); + } + + if ( !iInputFormat ) + { + //Input format should be set before calling this function, as output + // format is decided based on input format + PRINT_ERR( "iInputFormat is not set yet \n" ); + User::Leave( KErrNotReady ); + } + + TUncompressedVideoFormat format; + format.iDataFormat = EYuvRawData; + format.iYuvFormat.iYuv2RgbMatrix = NULL; + format.iYuvFormat.iRgb2YuvMatrix = NULL; + format.iYuvFormat.iAspectRatioNum = 1; + format.iYuvFormat.iAspectRatioDenom = 1; + + aFormats.Reset(); + + //The following formats are supported by both H.263 and Mpeg-4 + + //YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt601Range0; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //The following formats are only supported by Mpeg-4 + if ( iInputFormat->MimeType().FindF( KMPEG4SupportedMimeType ) != + KErrNotFound ) + { + //BT 601.5 Full Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt601Range1; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //BT 709 Reduced Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt709Range0; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + + //BT 709 Full Range + // YUV 420 Chroma0 Planar + format.iYuvFormat.iCoefficients = EYuvBt709Range1; + format.iYuvFormat.iPattern = EYuv420Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataPlanar; + aFormats.Append( format ); + + //YUV 422 Chroma LE Interleaved + format.iYuvFormat.iPattern = EYuv422Chroma1; + format.iYuvFormat.iDataLayout = EYuvDataInterleavedLE; + aFormats.Append( format ); + + //YUV 422 Chroma BE Interleaved + format.iYuvFormat.iDataLayout = EYuvDataInterleavedBE; + aFormats.Append( format ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the device output format. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetOutputFormatL( + const TUncompressedVideoFormat &aFormat ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "istate is already initialised \n" ); + User::Leave( KErrNotReady ); + } + + if ( !iInputFormat ) + { + //Input format should be set before calling this function, as output + // format is decided based on input format + PRINT_ERR( "iInputFormat is not set yet \n" ); + User::Leave( KErrNotReady ); + } + + // check whether output format is supported or not.if not supported leave + RArray formats; + CleanupClosePushL( formats ); + GetOutputFormatListL( formats ); + + TBool flag = EFalse; + + for ( TInt i = 0; i < formats.Count(); i++ ) + { + if ( aFormat == formats[i] ) + { + flag = ETrue; + break; + } + } + CleanupStack::Pop ( &formats ); + formats.Close(); + + if ( !flag ) + { + PRINT_ERR( "outputformat is not supported \n" ); + User::Leave( KErrNotSupported ); + } + + iOutputFormat = aFormat; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the clock source to use for video timing. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetClockSource( MMMFClockSource* /*aClock*/ ) + { + PRINT_ENTRY; + if ( iState->IsInitialized() ) + { + PRINT_ERR( "iState is initialised,calling MdvppFatalError \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +// Sets the device video output destination. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetVideoDestScreenL( TBool aScreen ) + { + PRINT_ENTRY; + if ( !iState->IsInitialized() ) + { + if ( aScreen ) + { + PRINT_ERR( "KErrNotSupported \n" ); + User::Leave( KErrNotSupported ); + } + } + else + { + PRINT_ERR( "KErrNotSupported \n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the post-processing types to be used. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetPostProcessTypesL( + TUint32 /*aPostProcCombination*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for input (pan-scan ) cropping. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetInputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for YUV to RGB color space conversion +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetYuvToRgbOptionsL( + const TYuvToRgbOptions& /*aOptions*/, + const TYuvFormat& /*aYuvFormat*/, + TRgbFormat /*aRgbFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for YUV to RGB color space conversion. Uses +//the device input and output formats. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetYuvToRgbOptionsL( + const TYuvToRgbOptions& /*aOptions*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets post-processing options for rotation. SetPostProcessTypesL() must be +//called before this method is used. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetRotateOptionsL( + TRotationType /*aRotationType*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets post-processing options for scaling. SetPostProcessTypesL() must be +//called before this method is used. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetScaleOptionsL( const TSize& /*aTargetSize*/, + TBool /*aAntiAliasFiltering*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets post-processing options for output cropping. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetOutputCropOptionsL( const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Sets post-processing plug-in specific options. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetPostProcSpecificOptionsL( + const TDesC8& /*aOptions*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "KErrNotSupported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Initializes the device. This method is asynchronous, the device calls +//MdvppInitializeComplete() of MMFVideoPlayProxy after initialization has +//completed. After this method has successfully completed, further +//configuration changes are not possible except where separately noted. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Initialize() + { + PRINT_ENTRY; + if ( !iState->IsTransitionValid( CStateMachine::EInitializeCommand ) ) + { + PRINT_ERR( "state is not valid in statemachine \n" ); + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, KErrNotReady ); + return; + } + + TRAPD( err, iInputFreeBuffers = + new ( ELeave ) TVideoInputBuffer[iBufferOptions.iMinNumInputBuffers] ); + if ( err ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "creation of iInputFreeBuffers returned error\n" ); + return; + } + + iPictureCounters.iPicturesDisplayed = 0; + iPictureCounters.iPicturesSkipped = 0; + iPictureCounters.iTotalPictures = 0; + iPictureCounters.iPicturesDecoded = 0; + + iBitstreamCounters.iLostPackets = 0; + iBitstreamCounters.iTotalPackets = 0; + + // if custom interface is supported then enable the interface + if ( iCustomBufferHandle ) + { + + TRAP( err, iCustomBufferOptions = + new ( ELeave ) MMmfVideoBufferManagement::TBufferOptions ); + + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "creation of iCustomBuffeOptions returned error \n" ); + return; + } + + iCustomBufferOptions->iNumInputBuffers = KMaxOutputBuffers + 1; + iCustomBufferOptions->iBufferSize = TSize( KMaxFrameWidth, + KMaxFrameHeight ); + + iCustomBufferHandle->MmvbmSetObserver( + ( MMmfVideoBufferManagementObserver * )this ); + + iCustomBufferHandle->MmvbmEnable( ETrue ); + + TRAP( err, + iCustomBufferHandle->MmvbmSetBufferOptionsL( + *iCustomBufferOptions ) ); + + if ( err != KErrNone ) + { + PRINT_ERR( "iCustomBufferHandle->MmvbmSetBufferOptionsL \n" ); + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + return; + } + } + + if ( !iConfigureDecoderCalled ) + { + TRAP( err, iCodec = CAriMpeg4aspdecWrapper::NewL( this ) ); + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "CCodecInterface::NewL returned error \n" ); + return; + } + } + + // Engine Creation + TRAP( err, iEngine = CBaseEngine::NewL( + this, ( MBaseCodec* )iCodec, EFalse ) ); + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "CBaseEngine::NewL returned error \n" ); + return; + } + + // set input & output formats to Codec + if ( iConfigureDecoderCalled ) + { + TRAP( err, iCodec->SetFormatsL( iDataUnitType, iOutputFormat ) ); + if ( err != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "iCodec->SetFormatsL returned error \n" ); + return; + } + } + + err = iState->Transit( CStateMachine::EInitializeCommand ); + if ( err ) + { + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, err ); + PRINT_ERR( "state is not set to initialised \n" ); + return; + } + + iMMFDevVideoPlayProxy->MdvppInitializeComplete( this, KErrNone ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Commit all changes since the last CommitL(), Revert() or Initialize() +//to the hardware device. This only applies to methods which can be called +//both before AND after DevVideoPlay has been initialized. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::CommitL() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + User::Leave( KErrNotReady ); + } + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Revert all changes since the last CommitL(), Revert() or Initialize() back +//to their previous settings. This only applies to methods which can be +//called both before AND after DevVideoPlay has been initialized.. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Revert() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + } + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::StartDirectScreenAccessL( + const TRect& /*aVideoRect*/, + CFbsScreenDevice& /*aScreenDevice*/, + const TRegion& /*aClipRegion*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetScreenClipRegion( const TRegion& /*aRegion*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetPauseOnClipFail( TBool /*aPause*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::AbortDirectScreenAccess() + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Indicates whether playback is proceeding. This method can be used to check +//whether playback was paused or not in response to a new clipping region +//or DSA abort +//--------------------------------------------------------------------------- +// +TBool CAriMpeg4aspdecHwDevice::IsPlaying() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "istate is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + return ( iState->IsStarted() ); + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Redraw() + { + PRINT_ENTRY; + PRINT_ERR( "Not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Starts video playback, including decoding, post-processing, and rendering. +//Playback will proceed until it has been stopped or paused, or the end of +//the bitstream is reached. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Start() + { + PRINT_ENTRY; + if ( iState->IsPlaying() ) + { + PRINT_EXIT; + PRINT_ERR( "already in playing state \n" ); + return; + } + if ( !iState->IsTransitionValid( CStateMachine::EStartCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iDecodingPosition = TTimeIntervalMicroSeconds( 0 ); + iEngine->Start(); + + TInt error = iState->Transit( CStateMachine::EStartCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Stops video playback. No new pictures will be decoded, post-processed, +//or rendered. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Stop() + { + PRINT_ENTRY; + if ( iState->IsStopped() ) + { + PRINT_EXIT; + PRINT_ERR( "already in stopped state \n" ); + return; + } + if ( !iState->IsTransitionValid( CStateMachine::EStopCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iPictureNumber = 0; + // Stop & Reset the Engine + iEngine->Stop(); + iEngine->Reset(); + iBufferAdded = EFalse; + iFilledBufferCounter = 0; + iInputEndCalled = EFalse; + iNoLastOut = EFalse; + iInputBufferConsumedCounter = 0; + TInt error = iState->Transit( CStateMachine::EStopCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Pauses video playback, including decoding, post-processing, and rendering. +//No pictures will be decoded, post-processed, or rendered until playback has +//been resumed. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Pause() + { + PRINT_ENTRY; + if ( iState->IsPaused() ) + { + PRINT_EXIT; + PRINT_ERR( "already in paused state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EPauseCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + //Stop the Engine + iEngine->Stop(); + + TInt error = iState->Transit( CStateMachine::EPauseCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Resumes video playback after a pause. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::Resume() + { + PRINT_ENTRY; + if ( iState->IsPlaying() ) + { + PRINT_EXIT; + PRINT_ERR( "already in playing state \n" ); + return; + } + + if ( !iState->IsTransitionValid( CStateMachine::EResumeCommand ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + // Start The Engine + iEngine->Start(); + + TInt error = iState->Transit( CStateMachine::EResumeCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Changes to a new decoding and playback position,used for randomly accessing +//(seeking)the input stream. The position change flushes all input and output +//buffers. Pre-decoder and post-decoder buffering are handled as if a new +//bitstream was being decoded. If the device still has buffered pictures that +//precede the new playback position, they will be discarded. If playback is +//synchronized to a clock source, the client is responsible for setting the +//clock source to the new position.. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetPosition( + const TTimeIntervalMicroSeconds& aPlaybackPosition ) + { + PRINT_ENTRY; + //Start Decoding from new position + if ( iState->IsInitialized() ) + { + iEngine->Stop(); + iEngine->Reset(); + iDecodingPosition = aPlaybackPosition; + iBufferAdded = EFalse; + iEngine->Start(); + } + else + { + PRINT_ERR( "istate is not initialised yet\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::FreezePicture( + const TTimeIntervalMicroSeconds& /*aTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Not Supported. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::ReleaseFreeze( + const TTimeIntervalMicroSeconds& /*aTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + +//--------------------------------------------------------------------------- +//Returns the current playback position, i.e. the timestamp for the most +//recently displayed or virtually displayed picture. If the device output +//is written to another device, the most recent output picture is used +//--------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriMpeg4aspdecHwDevice::PlaybackPosition() + { + PRINT_ENTRY; + // In Decoder case decoding position is same as playback position + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + return iDecodingPosition; + } + +//--------------------------------------------------------------------------- +//Returns the total amount of memory allocated for uncompressed pictures. +//--------------------------------------------------------------------------- +// +TUint CAriMpeg4aspdecHwDevice::PictureBufferBytes() + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised yet \n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + PRINT_EXIT; + return( KMaxOutputBuffers * iOutputBufferSize ); + } + +//--------------------------------------------------------------------------- +//Reads various counters related to decoded pictures. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetPictureCounters( + CMMFDevVideoPlay::TPictureCounters& aCounters ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised yet\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + aCounters = iPictureCounters; + + //Reset the counters to Zero + iPictureCounters.iPicturesDisplayed = 0; + iPictureCounters.iPicturesSkipped = 0; + iPictureCounters.iTotalPictures = 0; + iPictureCounters.iPicturesDecoded = 0; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetComplexityLevel( TUint /*aLevel*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +TUint CAriMpeg4aspdecHwDevice::NumComplexityLevels() + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return 0; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetComplexityLevelInfo( TUint /*aLevel*/, + CMMFDevVideoPlay::TComplexityLevelInfo& /*aInfo*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Called by the Post Proc hwdevice when a picture is displayed on the screen. +//Returns a picture back to the device. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::ReturnPicture( TVideoPicture* aPicture ) + { + PRINT_ENTRY; + if ( !( iState->IsInitialized() ) ) + { + PRINT_ERR( "iState is not initialised yet\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + if ( iCustomBufferHandle ) + { + delete aPicture->iHeader ; + aPicture->iHeader = NULL ; + } + else + { + // add to engine if state is not stopped + if ( iState->IsStopped() ) + { + iOutputFreeBufferQueue.Append( aPicture ); + } + else + { + iEngine->AddOutput( aPicture ); + } + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +TBool CAriMpeg4aspdecHwDevice::GetSnapshotL( TPictureData& /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + return( KErrNone ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetTimedSnapshotL( TPictureData* /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/, + const TTimeIntervalMicroSeconds& /*aPresentationTimestamp*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + //Should take it from Post Proc HwDevice + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetTimedSnapshotL( TPictureData* /*aPictureData*/, + const TUncompressedVideoFormat& /*aFormat*/, + const TPictureId& /*aPictureId*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + //Should take it from Post Proc HwDevice + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::CancelTimedSnapshot() + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotSupported ); + PRINT_EXIT; + return; + } + + +//--------------------------------------------------------------------------- +//Not supported API. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetSupportedSnapshotFormatsL( + RArray& /*aFormats*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +//sets the Flag iInputEndCalled to ETrue +//Notifies the hardware device that the end of input data has been reached +//and no more input data will be written +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::InputEnd() + { + PRINT_ENTRY; + if ( !( iState->IsTransitionValid( CStateMachine::EInputEndCommand ) ) ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + iInputEndCalled = ETrue; + + if ( ( iFilledBufferCounter - iInputBufferConsumedCounter ) == 1 ) + { + GetLastFrame(); + Stop(); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + PRINT_EXIT; + return; + } + + TInt error = iState->Transit( CStateMachine::EInputEndCommand ); + + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Notifies the Hw Device that input buffer is free +//--------------------------------------------------------------------------- +// +TInt CAriMpeg4aspdecHwDevice::InputBufferConsumed ( TAny* aInp, TInt aError ) + { + PRINT_ENTRY; + + if ( aInp ) + { + iInputFreeBufferQueue.Append( REINTERPRET_CAST( TVideoInputBuffer*, + aInp ) ); + + //call back to clinet + if ( ( aError != KErrCancel ) && ( !iInputEndCalled ) ) + iMMFDevVideoPlayProxy->MdvppNewBuffers(); + } + if ( iInputEndCalled && iNoLastOut ) + { + HandleInputEndInStopping(); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + } + + PRINT_EXIT; + return ( KErrNone ); + } + +//--------------------------------------------------------------------------- +//Notifies the Hw Device that out buffer has decoded data +//--------------------------------------------------------------------------- +// +TInt CAriMpeg4aspdecHwDevice::OutputBufferReady ( TAny* aOut, TInt aError ) + { + PRINT_ENTRY; + if ( aError == KErrNone ) + { + iPictureNumber++; + // call back information regarding slice and picture loss + + SliceAndPictureLoss(); + + //Decoded Buffer is available + TVideoPicture* videoPicture = REINTERPRET_CAST( TVideoPicture*, + aOut ); + + videoPicture->iHeader->iPictureNumber = iPictureNumber; + + iFilledBufferCounter--; + + iPictureCounters.iPicturesDecoded++; + iPictureCounters.iPicturesDisplayed++; + + iDecodingPosition = videoPicture->iTimestamp; + + if ( !iOutputDevice ) + { + iMMFDevVideoPlayProxy->MdvppNewPicture( videoPicture ); + + if ( iInputEndCalled && + ( ( iFilledBufferCounter - iInputBufferConsumedCounter ) + == 1 ) + ) + { + GetLastFrame(); + Stop(); + PRINT_ERR( "calling streamend\n" ); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + } + PRINT_EXIT; + return( KErrNone ); + } + else + { + TRAPD( error, iOutputDevice->WritePictureL( videoPicture ) ); + + if ( error == KErrNone ) + { + if ( iInputEndCalled && + ( ( iFilledBufferCounter - iInputBufferConsumedCounter ) + == 1 ) ) + { + GetLastFrame(); + HandleInputEndInStopping(); + PRINT_ERR( "calling streamend\n" ); + iMMFDevVideoPlayProxy->MdvppStreamEnd(); + } + } + else if ( error ) // KErrArgument, KErrNotReady + { + iPictureCounters.iPicturesDisplayed--; + // Currently not handled + } + } + } + + else if ( aError == KErrCancel ) + { + // Add buffers to output free buffer queue if cutombuffer is not set + if ( !iCustomBufferHandle ) + { + iOutputFreeBufferQueue.Append( REINTERPRET_CAST( TVideoPicture*, + aOut ) ); + } + else + { + + delete ( ( TVideoPicture* )aOut )->iHeader; + ( ( TVideoPicture* )aOut )->iHeader = NULL; + + // release the buffer + iCustomBufferHandle->MmvbmReleaseBuffer( REINTERPRET_CAST( + TVideoPicture*, aOut ) ); + } + + } + + else // other errors + { + // currently not handled + } + + PRINT_EXIT; + return ( KErrNone ); + } + +//--------------------------------------------------------------------------- +//Notifies the hw devcie that Error has occured in PE +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::FatalErrorFromProcessEngine ( TInt aError ) + { + PRINT_ENTRY; + PRINT_ERR( "not supported API\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, aError ); + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//Callback to indicate the command has been processed +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::CommandProcessed ( TInt aCmd, TAny* aCmdData, + TInt aError ) + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Call back from output device, indicates buffers availability +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::MmvbmoNewBuffers() + { + PRINT_ENTRY; + TVideoPicture* videoPicture = NULL; + + TRAPD( err, videoPicture = iCustomBufferHandle->MmvbmGetBufferL( + iCustomBufferOptions->iBufferSize ) ); + + if ( err != KErrNone ) + { + PRINT_ERR( "iCustomBufferHandle->MmvbmGetBufferL returned error\n" ); + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + if ( videoPicture ) + { + if ( videoPicture->iHeader ) + { + delete videoPicture->iHeader; + videoPicture->iHeader = NULL; + } + + TRAPD( err1, videoPicture->iHeader = + new ( ELeave ) TVideoPictureHeader ) ; + + if ( err1 != KErrNone ) + { + iCustomBufferHandle->MmvbmReleaseBuffer( videoPicture ) ; + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrArgument ); + } + else + { + iEngine->AddOutput( videoPicture ); + } + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Callback from output device. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::MmvbmoReleaseBuffers() + { + PRINT_ENTRY; + iEngine->Stop(); + iEngine->Reset(); + PRINT_EXIT; + } + + + +//--------------------------------------------------------------------------- +//Call back from the codec wrapper when there is new config information. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::NewConfigFound() + { + PRINT_ENTRY; + + /* Reset the all the output buffers added to the ProcessEngine. + * Create them again if custom buffers are not used. + */ + while ( iEngine->NumOutputBuffers() ) + OutputBufferReady ( iEngine->FetchOutputBuffer(), KErrCancel ); + + iOutputBuffersCreated = EFalse; + iBufferAdded = EFalse; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Call back from the codec wrapper when EInputConsumed for Not yet get I frame +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::EInputConsumed() + { + PRINT_ENTRY; + + iInputBufferConsumedCounter++; + + if ( iInputEndCalled && ( iFilledBufferCounter == + ( iInputBufferConsumedCounter + 1 ) ) ) + { + iNoLastOut = ETrue; + } + + PRINT_EXIT; + } +//--------------------------------------------------------------------------- +//Set the proxy implementation to be used. Called just +//after the object is constructed +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SetProxy( MMMFDevVideoPlayProxy& aProxy ) + { + PRINT_ENTRY; + iMMFDevVideoPlayProxy = &aProxy; + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//Default constructor of CAriMpeg4aspdecHwDevice +//--------------------------------------------------------------------------- +// +CAriMpeg4aspdecHwDevice::CAriMpeg4aspdecHwDevice() + :iInputFreeBuffers( NULL ), + iOutputDevice( NULL ), + iMMFDevVideoPlayProxy( NULL ), + iState( NULL ), + iVideoPictureHeader( NULL ), + iDecodingPosition( TTimeIntervalMicroSeconds( 0 ) ), + iInputFormat( NULL ), + iCodec( NULL ), + iEngine( NULL ), + iInputEndCalled( EFalse ), + iOutputFreeBuffer( NULL ), + iFilledBufferCounter( 0 ), + iDataUnitType( EDuCodedPicture ), + iEncapsulation( EDuElementaryStream ), + iOutputBufferSize( 0 ), + iOutputBuffersCreated( EFalse ), + iPictureNumber( 0 ), + iNumberOfInputBuffersAllocated( 0 ), + iCustomBufferHandle( NULL ), + iCustomBufferOptions( NULL ), + iBufferAdded( EFalse ), + iConfigureDecoderCalled( EFalse ), + iDecoderConfigured( EFalse ), + iInputBufferConsumedCounter( 0 ), + iNoLastOut( EFalse ) + { + PRINT_ENTRY; + iBufferOptions.iPreDecodeBufferSize = 0; + iBufferOptions.iMaxPostDecodeBufferSize = 0; + iBufferOptions.iPreDecoderBufferPeriod = 0; + iBufferOptions.iPostDecoderBufferPeriod = 0; + iBufferOptions.iMinNumInputBuffers = KMaxInputBuffers; + iBufferOptions.iMaxInputBufferSize = KMaxInputBufferSize; + + + // Initializing iOutputFormat with one of the combination supported by + // Mpeg-4/H.263 hwdevice + + iOutputFormat.iDataFormat = EYuvRawData; + // For H.263 it is always Bt 601.5 reduced range + // For Mpeg-4 input stream contains this information + iOutputFormat.iYuvFormat.iCoefficients = EYuvBt601Range0; + // The input stream format ( H.263 & Mpeg-4 ) comes in Chroma1 format and + //so output is also decoded into Chroma1 format + iOutputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + iOutputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + iOutputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + iOutputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + iOutputFormat.iYuvFormat.iAspectRatioNum = 1; + iOutputFormat.iYuvFormat.iAspectRatioDenom = 1; + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//This is the 2nd phase constructor +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::ConstructL() + { + PRINT_ENTRY; + iState = CStateMachine::NewL(); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Module to create output data +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::CreateOutputBuffersL() + { + PRINT_ENTRY; + if ( iOutputFreeBuffer ) + { + for ( TInt i = 0 ; i < KMaxOutputBuffers; i++ ) + { + if ( ( iOutputFreeBuffer + i )->iHeader ) + { + delete ( iOutputFreeBuffer + i )->iHeader; + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete + ( TUint8* )( iOutputFreeBuffer + i )->iData.iRawData->Ptr(); + } + if ( ( iOutputFreeBuffer + i )->iData.iRawData ) + { + delete ( iOutputFreeBuffer + i )->iData.iRawData; + } + } + delete [] iOutputFreeBuffer; + } + for ( TInt i = 0; i < iOutputFreeBufferQueue.Count(); i++ ) + { + iOutputFreeBufferQueue.Remove( 0 ); + } + // Create the output Buffer( s ) and buffers to engine + iOutputFreeBuffer = new ( ELeave ) TVideoPicture[KMaxOutputBuffers]; + TInt i; + for ( i = 0 ; i < KMaxOutputBuffers; i++ ) + { + ( iOutputFreeBuffer + i )->iData.iRawData = NULL; + ( iOutputFreeBuffer + i )->iHeader = NULL; + } + + for ( i = 0 ; i < KMaxOutputBuffers; i++ ) + { + TUint8* ptr; + TPtr8* temp; + + ptr = new ( ELeave ) TUint8[iOutputBufferSize]; + CleanupStack::PushL( ptr ); + temp = new ( ELeave ) TPtr8( ptr, 0, iOutputBufferSize ); + CleanupStack::Pop( ptr ); + + ( iOutputFreeBuffer + i )->iData.iRawData = temp; + ( iOutputFreeBuffer + i )->iHeader = + new ( ELeave ) TVideoPictureHeader; + + //Add o/p buffer( s ) to the Queue + iEngine->AddOutput( ( iOutputFreeBuffer + i ) ); + } + iBufferAdded = ETrue; + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//Gives callbacks to client regarding slice and picture loss +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::SliceAndPictureLoss() + { + PRINT_ENTRY; + TUint firstMacroblock; + TUint numMacroblocks; + TPictureId pictureId; + pictureId.iIdType = TPictureId::EPictureNumber; + + // call back to client regading picture loss + if ( ( iCodec->GetPictureLossInfo() ) >= KMaxAllowPicLoss ) + { + PRINT_MSG( LEVEL_LOW, ( "Mpeg4aspdecHwDevice::SliceAndPictureLoss, " + " calling callback regading picture loss" ) ); + iMMFDevVideoPlayProxy->MdvppPictureLoss(); + } + + PRINT_MSG( LEVEL_LOW, ( "CAriMpeg4aspdecHwDevice::SliceAndPictureLoss, " + " calling callback regarding slice loss" ) ); + // call back to clinet regarding slice loss + iCodec->GetSliceLossInfo( firstMacroblock, numMacroblocks ); + + if ( ( firstMacroblock != 0 ) || ( numMacroblocks != 0 ) ) + iMMFDevVideoPlayProxy->MdvppSliceLoss( firstMacroblock, + numMacroblocks, + pictureId ); + + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +//Creates one input Buffer +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::CreateInputBufferL( TUint aBufferSize, + TBool aReallocate ) + { + PRINT_ENTRY; + + if ( !aReallocate ) + { + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 1++" ) ); + // Create the Buffer and add it to Queue + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 2++" ) ); + TInt* lastBufferFlag = new ( ELeave ) TInt[sizeof( TInt )]; + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 3++" ) ); + iInputFreeBuffers[iNumberOfInputBuffersAllocated].iData.Set( ptr, + 0, + TInt( aBufferSize ) ); + iInputFreeBuffers[iNumberOfInputBuffersAllocated].iUser = + REINTERPRET_CAST( TAny*, lastBufferFlag ); + iInputFreeBufferQueue.Append( + iInputFreeBuffers + iNumberOfInputBuffersAllocated ); + iNumberOfInputBuffersAllocated++; + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 4++" ) ); + } + + else // input buffers are already created and do reallocation here + { + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 5++" ) ); + TVideoInputBuffer* inBuffer = iInputFreeBufferQueue[0]; + // check the size of the current with the size + //of the buffer present in i/p Q + if ( aBufferSize > TUint( inBuffer->iData.MaxLength() ) ) + { + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 6++" ) ); + // delete the previous buffer + delete [] ( TUint8* )inBuffer->iData.Ptr(); + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 7++" ) ); + delete inBuffer->iUser; + + // reallocate the buffer + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + PRINT_MSG( LEVEL_LOW, ( "CreateInputBufferL 8++" ) ); + //delete inBuffer->iUser; + TInt* lastBufferFlag = new ( ELeave ) TInt[sizeof( TInt )]; + inBuffer->iData.Set( ptr, 0, TInt( aBufferSize ) ); + inBuffer->iUser = REINTERPRET_CAST( TAny*, lastBufferFlag ); + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//When InputEnd is called while the hw device in Stopping State. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::HandleInputEndInStopping() + { + PRINT_ENTRY; + if ( iState->IsInputEndPending() ) + { + iPictureNumber = 0; + // Stop & Reset the Engine + iEngine->Stop(); + iBufferAdded = EFalse; + iFilledBufferCounter = 0; + iInputEndCalled = EFalse; + iInputBufferConsumedCounter = 0; + iNoLastOut = EFalse; + TInt error = iState->Transit( CStateMachine::EStopCommand ); + if ( error != KErrNone ) + { + iMMFDevVideoPlayProxy->MdvppFatalError( this, KErrNotReady ); + } + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Gets the last frame of the sequence. +//--------------------------------------------------------------------------- +// +void CAriMpeg4aspdecHwDevice::GetLastFrame() + { + PRINT_ENTRY; + TInt err = KErrNone; + + if ( ( iEngine->NumOutputBuffers() ) > 0 ) + { + TVideoPicture* lVideoPicture = + ( TVideoPicture* )( iEngine->FetchOutputBuffer() ); + err = iCodec->GetLastFrame( lVideoPicture ); + + if ( err == KErrNone ) + { + lVideoPicture->iHeader->iPictureNumber = iPictureNumber; + + iPictureCounters.iPicturesDecoded++; + iPictureCounters.iPicturesDisplayed++; + + iDecodingPosition = lVideoPicture->iTimestamp; + + if ( !iOutputDevice ) + { + iMMFDevVideoPlayProxy->MdvppNewPicture( lVideoPicture ); + } + else + { + TRAPD( error, + iOutputDevice->WritePictureL( lVideoPicture ) ); + if ( error != KErrNone ) + { + iPictureCounters.iPicturesDisplayed--; + // Currently not handled + } + } + } + else + { + //Add the output buffer back to ProcessEngine + iEngine->AddOutput( lVideoPicture ); + } + } + PRINT_EXIT; + } + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( KUidMp4DecoderHwDeviceImplUid, + CAriMpeg4aspdecHwDevice::NewL ) + }; + + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) + { + PRINT_ENTRY; + aTableCount = + sizeof( ImplementationTable ) / sizeof( TImplementationProxy ); + PRINT_EXIT; + return ImplementationTable; + } diff -r 000000000000 -r bb31fbe78861 mp4asp_dec/arimpeg4aspdecwrapper/export_hdr/arimpeg4aspdecwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4asp_dec/arimpeg4aspdecwrapper/export_hdr/arimpeg4aspdecwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Header file to the Mpeg4Asp Decoder wrapper Implementation. +* +*/ + +#ifndef ARIMPEG4ASPDECWRAPPER_H +#define ARIMPEG4ASPDECWRAPPER_H + +//System includes +#include +#include +#include + +//User includes +#include "aribasecodec.h" +#include "ariprint.h" + +const TInt KMaxFrameWidth = 640;//should be 1280 for enabling 720P decoding; +const TInt KMaxFrameHeight = 480;//should be 720 for enabling 720P decoding; + +// FORWARD DECLARATIONS +class TUncompressedVideoFormat; +class TVideoInputBuffer; +class TVideoPictureHeader; + +/** + * Class MCodecObserver + * whenever a new configuration information finds in the file, ti should + * be informated to the hwdevice. so that it will delete the existing + * codec object and wil create a new object and configures the codec with + * the new configuration information. + */ + +class MCodecObserver + { + public: + /** + * Callback to inform the HW device when there is new config. + * @return "None" + */ + virtual void NewConfigFound()=0; + + /** + * Callback to inform the HW device when there is new config. + * @return "None" + */ + virtual void EInputConsumed()=0; + }; +/** + * Class CCodecInterface + * This class is base class whish is part of Aricent's Mpeg4 ASP/H263 decoder wrapper + * used by the Mpeg4 ASP/H263. This HwDevice Plugin to decode Mpeg4 ASP/H263 content to + * yuv420. + * + */ +class CAriMpeg4aspdecWrapper: public MBaseCodec, public CBase + { + public:// Constructor and Destructor + + /** + * Two-phased constructor. + * @return pointer to an instance of CAriMpeg4aspdecWrapper + */ + IMPORT_C static CAriMpeg4aspdecWrapper* NewL( + MCodecObserver* aObserver ); + + /** + * Destructor + */ + virtual ~CAriMpeg4aspdecWrapper(); + + + public:// MBaseCodec functions + + /** + * Retrieves a custom interface to the specified hardware device + + * @param aInpBuf Coded input data passed by Engine. + * @param aOutBuf Decoded output data. + + * @leave "The method will leave if an error occurs". + + * @return one of the TCodecState + */ + virtual TInt DoProcessL( TAny *aInpBuf, TAny* aOutBuf = NULL ) = 0; + + /** + * Resets the Decoder + * @return None + */ + virtual void Reset() = 0; + + public: // New Functions + /** + * Common API to set the values to the decoder. + * @param aCommand indicates the action to do. + * @param aCmdData Any input data required + + * @leave "The method will leave if an error occurs". + */ + virtual TInt SetParam( TInt aCommand, TAny* aCmdData ) = 0; + + /** + * Common API to get the values to the decoder. + * @param aCommand indicates the action to do. + * @param aCmdData Any output data required + + * @leave "The method will leave if an error occurs". + */ + virtual TInt GetParam( TInt aCommand, TAny* aCmdData ) = 0; + /** + * Returns the stream information and creates the decoder + * @param aInpBuf Coded input data. + * @param aOutBuf Decoded output data. + + * @leave The method will leave if an error occurs. + */ + virtual void SetFormatsL( TVideoDataUnitType &aInputFormat, + TUncompressedVideoFormat &aOutputFormat ) = 0; + + /** + * Configure the decoder using the stream passed + * @param aInpBuf Coded input data. + + * @leave The method will leave if an error occurs. + */ + virtual void ConfigDecoderL( const TDesC8* aInpBuf ) = 0; + + /** + * Returns the length of the ouput frame + * @return + + * @leave The method will leave if an error occurs. + */ + virtual TInt GetOutputBufferLength() = 0; + + /** + * Gets the slice loss information + * @param aFirstMacroBlock + * @param aNumMacroBlocks + */ + virtual void GetSliceLossInfo( TUint& aFirstMacroblock, + TUint& aNumMacroblocks ) = 0; + + /** + * Gets the picture Loss Information + * @return percentage value + */ + virtual TUint GetPictureLossInfo() = 0; + + /** + * Gets the Last frame + * @return none + */ + virtual TInt GetLastFrame( TAny* aOutput ) = 0; + + /** + * Gets the header info + * @param aDataUnit Input stream data. + * @param aHeaderPtr Output header information returned. + + * @leave The method will leave if an error occurs + KErrArgument - input data is null or zero length + KErrCorrupt - input stream is corrupt + KErrUnderflow - input stream is insufficient. + */ + IMPORT_C + static void GetHeaderInfoL( TVideoInputBuffer& aDataUnit, + TVideoPictureHeader& aHeaderPtr ); + }; + +#endif //ARIMPEG4ASPDECWRAPPER_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/group/arimp4spenchwdevice.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/group/arimp4spenchwdevice.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for Mpeg4SP/H263 encoder. The file specifies the +* include paths, source files and libraries to be used to build the +* Mpeg4SP/H263 encoder plugin binaries. +* +*/ + +#include "..\inc\arimp4spenchwdeviceuids.hrh" +#include + +TARGET arimp4spenchwdevice.dll + +TARGETTYPE PLUGIN + +UID 0x10009D8D KUidMpeg4H263EncoderHwDeviceDllUid + +CAPABILITY All -TCB + +SOURCEPATH ..\src +SOURCE arimp4spenchwdeviceimpl.cpp + +START RESOURCE 200298FD.rss +TARGET arimp4spenchwdevice.rsc +END + +MACRO LOGLEVEL_CRITICAL + +USERINCLUDE ..\inc +USERINCLUDE ..\..\..\utilities\ariprocessengine\inc +USERINCLUDE ..\..\arimp4spencwrapper\export_hdr +USERINCLUDE ..\..\..\utilities\aristatemachine\inc +USERINCLUDE ..\..\arimp4spencwrapper\codec\export_hdr +USERINCLUDE ..\..\..\utilities\log + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE \epoc32\include\ecom +SYSTEMINCLUDE \epoc32\include\mmf\devvideo +SYSTEMINCLUDE \epoc32\include + +LIBRARY euser.lib +LIBRARY devvideo.lib +LIBRARY aristatemachine.lib +LIBRARY ariprocessengine.lib +LIBRARY arimp4spencwrapper.lib \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for Mpeg4SP/H263 encoder HwDevice plugin. This file specifies the +* mmp to be used to build the Mpeg4SP/H263 encoder plugin binaries. +* +*/ + +PRJ_PLATFORMS +winscw armv5 armv6 + +PRJ_MMPFILES +arimp4spenchwdevice.mmp + + + +//----------------------------------------------------------------------------- +// End of BLD.INF +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/inc/arimp4spenchwdeviceimpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/inc/arimp4spenchwdeviceimpl.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,1118 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Declares plugin class for Mpeg4SP/H263 encoder HwDevice. This class inherits +* from CMMFVideoEncodeHwDevice and implements the pure virtual functions.The +* class also contains implementation specific private methods. +* +*/ + +#ifndef ARIMP4SPENCHWDEVICEIMPL_H +#define ARIMP4SPENCHWDEVICEIMPL_H + +//System Includes +#include +#include +#include +#include +#include + +//User Includes +#include "arivideoenccommon.h" +#include "aristatemachine.h" +#include "aribaseengine.h" +#include "arimp4spencwrapper.h" +//#include "arimp4spenchwdevice.h" +#include "arimp4spenchwdeviceuids.hrh" +#include "ariprint.h" + +// Forward declarations + +/** + * This class is part of Aricent's Mpeg4-sp/H263 encoder HwDevice plugin used + * for encoding yuv420 input to Mpeg4-sp/H263 content. + * Provides implementation for standard MDF HwDevice plugin APIs as well as + * private functions used internal to this class for .This class also + * implements callback APIs from MProcessEngineObserver which are called + * from CBaseEngine. + */ +class CAriMp4spencHwDeviceImpl: public CMMFVideoEncodeHwDevice, + public MProcessEngineObserver +{ + +public: + /** + * Two-phased constructor. + * @return pointer to an instance of CAriMp4spencHwDeviceImpl + * @leave "The method will leave if an error occurs" + */ + static CAriMp4spencHwDeviceImpl* NewL(); + + /**> Destructor */ + ~CAriMp4spencHwDeviceImpl(); + +public: + /** + * From CMMFVideoHwDevice + * The function retrieves a custom interface to the HwDevice. + * @param aInterface + * UID of the interface to be retrieved. It is defined with the custom + * interface + * @return returns pointer to the interface + */ + TAny* CustomInterface( TUid aInterface ); + +public: + /** + * From CMMFVideoEncodeHwDevice + * The function retrieves information about the video encoder + * @return "returns pointer to the object with encoder information" + * @leave "The method will leave if an error occurs" + */ + CVideoEncoderInfo* VideoEncoderInfoLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder output format. + * @param aFormat + * UID of the interface to be retrieved. It is defined with the custom + * interface + * @param aDataUnitType + * The type of output coded data units + * @param aDataEncapsulation + * Data encapsulation type for output encoded data units + * @param aSegmentationAllowed + * Indicates if segmentation is allowed or not + * @leave "The method will leave if an error occurs" + */ + void SetOutputFormatL( const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aDataEncapsulation, + TBool aSegmentationAllowed=EFalse ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the pre-processor hwdevice that will write data to + * this encoder. + * @param aDevice + * Pre-processor device that will write to this encoder + */ + void SetInputDevice( CMMFVideoPreProcHwDevice* aDevice ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the number of bit-rate scalability layers to use. + * @param aNumLayers + * The number of bit-rate scalability layers to use + * @leave "The method will leave if an error occurs" + */ + void SetNumBitrateLayersL( TUint aNumLayers ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the scalability type for a bit-rate scalability layer + * @param aLayer + * The layer number + * @param aScalabilityType + * Layer scalability type + * @leave "The method will leave if an error occurs" + */ + void SetScalabilityLayerTypeL( TUint aLayer, + TScalabilityType aScalabilityType); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the reference picture options to be used for all + * scalability layers + * @param aMaxReferencePictures + * Maximum number of reference pictures to be used + * @param aMaxPictureOrderDelay + * The maximum picture order delay, in number of pictures. + */ + void SetGlobalReferenceOptions( TUint aMaxReferencePictures, + TUint aMaxPictureOrderDelay ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the reference picture options to be used for a + * particular scalability layer + * @param aLayer + * The layer number + * @param aMaxReferencePictures + * Maximum number of reference pictures to be used for this layer + * @param aMaxPictureOrderDelay + * The maximum picture order delay for this layer, in number of + * pictures. + */ + void SetLayerReferenceOptions( TUint aLayer,TUint aMaxReferencePictures, + TUint aMaxPictureOrderDelay ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder buffering options + * @param aOptions + * Buffering options to be used + * @leave "The method will leave if an error occurs" + */ + void SetBufferOptionsL( const TEncoderBufferOptions& aOptions ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the encoder output rectangle + * @param aRect + * Output rectangle to be used + * @leave "The method will leave if an error occurs" + */ + void SetOutputRectL( const TRect& aRect ); + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder whether bit errors or packets losses + * can be expected in the video transmission + * @param aBitErrors + * Boolean to indicate if bit errors can be expected + * @param aPacketLosses + * Boolean to indicate if packet losses can be expected + */ + void SetErrorsExpected( TBool aBitErrors, TBool aPacketLosses ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the minimum random access rate to be used + * @param aRate + * The minimum random access rate + */ + void SetMinRandomAccessRate( TReal aRate ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the coding standard specific options to be used. + * @param aOptions + * Coding standard specific options to be used + * @leave "The method will leave if an error occurs" + */ + void SetCodingStandardSpecificOptionsL( const TDesC8& aOptions ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the implementation specific options to be used + * @param aOptions + * Implementation specific options to be used. + * @leave "The method will leave if an error occurs" + */ + void SetImplementationSpecificEncoderOptionsL( const TDesC8& aOptions ); + + /** + * From CMMFVideoEncodeHwDevice + * The function returns coding-standard specific initialization output + * from the encoder + * @return Returns the pointer to buffer holding coding-standard specific + * initialization output + * @leave "The method will leave if an error occurs" + */ + HBufC8* CodingStandardSpecificInitOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the implementation specific initialization output from + * the encoder + * @return Returns the pointer to buffer holding implementation specific + * initialization output + * @leave "The method will leave if an error occurs" + */ + HBufC8* ImplementationSpecificInitOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function the number of unequal error protection levels. + * @param aNumLevels + * The number of unequal error protection levels to be used + * @param aSeparateBuffers + * Boolean indicating whether each unequal error protection level of a + * coded data unit shall be encapsulated in its own output buffer + * @leave "The method will leave if an error occurs" + */ + void SetErrorProtectionLevelsL( TUint aNumLevels, + TBool aSeparateBuffers ); + + /** + * From CMMFVideoEncodeHwDevice + * The function the number of unequal error protection levels. + * @param aNumLevels + * The number of unequal error protection levels to be used + * @param aSeparateBuffers + * Boolean indicating whether each unequal error protection level of a + * coded data unit shall be encapsulated in its own output buffer + * @param aStrength + * Forward error control strength for this error protection level + * @leave "The method will leave if an error occurs" + */ + void SetErrorProtectionLevelL( TUint aLevel, TUint aBitrate, + TUint aStrength ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the expected or prevailing channel conditions for an + * unequal error protection + * level in terms of expected packet loss rate. + * @param aLevel + * Error protection level number + * @param aLossRate + * Packet loss rate, in number of packets lost per second. + * @param aLossBurstLength + * Expected average packet loss burst length + */ + void SetChannelPacketLossRate( TUint aLevel, TReal aLossRate, + TTimeIntervalMicroSeconds32 aLossBurstLength ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the expected or prevailing channel conditions for an + * unequal error + * protection level, in terms of expected bit error rate + * @param aLevel + * Error protection level number + * @param aErrorRate + * Expected bit error rate + * @param aStdDeviation + * Expected bit error rate standard deviation + */ + void SetChannelBitErrorRate( TUint aLevel, TReal aErrorRate, + TReal aStdDeviation ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the segment size. To be used only for packet mode + * @param aLayer + * Layer number + * @param aSizeBytes + * Segment size in bytes + * @param aSizeMacroblocks + * Size of the macro blocks + */ + void SetSegmentTargetSize( TUint aLayer, TUint aSizeBytes, + TUint aSizeMacroblocks ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the bit-rate control options for a layer + * @param aLayer + * Bit-rate scalability layer number + * @param aOptions + * Bit-rate control options to be used + */ + void SetRateControlOptions( TUint aLayer, + const TRateControlOptions& aOptions ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the in-layer scalability options for a layer + * @param aLayer + * Bit-rate scalability layer number + * @param aNumSteps + * The number of in-layer scalability steps to use + * @param aScalabilityType + * Bit-rate share for each scalability step + * @param aBitrateShare + * Picture rate share for each scalability step + * @param aPictureShare + * The scalability type to use + * @leave "The method will leave if an error occurs" + */ + void SetInLayerScalabilityL( TUint aLayer,TUint aNumSteps, + TInLayerScalabilityType aScalabilityType, + const TArray& aBitrateShare, + const TArray& aPictureShare ); + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the segment size. To be used only for packet mode + * @param aLayer + * Layer number + * @param aPeriod + * The number of in-layer scalability steps to use + */ + void SetLayerPromotionPointPeriod( TUint aLayer, TUint aPeriod ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the coding-standard specific settings output from the + * encoder + * @return Returns the pointer to buffer holding coding-standard specific + * settings output + * @leave "The method will leave if an error occurs" + */ + HBufC8* CodingStandardSpecificSettingsOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the Implementation specific settings output from the + * encoder + * @return Returns the pointer to buffer holding Implementation specific + * settings output + * @leave "The method will leave if an error occurs" + */ + HBufC8* ImplementationSpecificSettingsOutputLC(); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to send supplemental information in + * the bit stream + * @param aData + * Supplemental information data to send + * @leave "The method will leave if an error occurs" + */ + void SendSupplementalInfoL( const TDesC8& aData ); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to send supplemental information in + * the bit stream + * @param aData + * Supplemental information data to send + * @param aTimestamp + * Timestamp for the picture in which the supplemental information + * should be included + * @leave "The method will leave if an error occurs" + */ + void SendSupplementalInfoL( const TDesC8& aData, + const TTimeIntervalMicroSeconds& aTimestamp ); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to cancel the current supplemental + * information send request + */ + void CancelSupplementalInfo(); + + /** + * From CMMFVideoEncodeHwDevice + * The function gets the current output buffer status + * @param aNumFreeBuffers + * Target for the number of free output buffers + * @param aTotalFreeBytes + * Target for the total free buffer size in bytes + */ + void GetOutputBufferStatus( TUint& aNumFreeBuffers, + TUint& aTotalFreeBytes ); + + /** + * From CMMFVideoEncodeHwDevice + * The function returns a used output buffer back to the encoder + * @param aBuffer + * The buffer to be returned + */ + void ReturnBuffer( TVideoOutputBuffer* aBuffer ); + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder that a picture loss has occurred + * without specifying the lost picture. + */ + void PictureLoss(); + + + /** + * From CMMFVideoEncodeHwDevice + * The function notifies the encoder that a picture loss has occurred + * @param aPictures + * Picture identifiers of lost pictures + */ + void PictureLoss( const TArray& aPictures ); + + /** + * From CMMFVideoEncodeHwDevice + * The function notify the encoder that slice loss has occurred, giving + * the details of the macroblocks and the picture to which they belong + * @param aFirstMacroblock + * The first lost macroblock. + * @param aNumMacroblocks + * The number of macroblocks in the lost slice + * @param aPicture + * The picture identified for the picture where the slice was lost + */ + void SliceLoss( TUint aFirstMacroblock, TUint aNumMacroblocks, + const TPictureId& aPicture ); + + /** + * From CMMFVideoEncodeHwDevice + * The function requests the encoder to use reference picture selection + * @param aSelectionData + * The reference picture selection request message + */ + void ReferencePictureSelection( const TDesC8& aSelectionData ); + + +public: + + /** + * From CMMFVideoRecordHwDevice + * The function initializes the encoder HwDevice with the configuration + * settings and reserve + * the hardware resources required + */ + void Initialize(); + + /** + * From CMMFVideoRecordHwDevice + * The function commits all changes since the last CommitL(), Revert() or + * Initialize() to the hardware device + * @leave "The method will leave if an error occurs" + */ + void CommitL(); + + /** + * From CMMFVideoRecordHwDevice + * The function reverts all changes since the last CommitL(), Revert() or + * Initialize() + * back to their previous settings. + */ + void Revert(); + + /** + * From CMMFVideoRecordHwDevice + * The function writes an uncompressed input picture + * @param aPicture + * The picture to write + * @leave "The method will leave if an error occurs" + */ + void WritePictureL( TVideoPicture* aPicture ); + + /** + * From CMMFVideoRecordHwDevice + * The function notifies the hardware device that the end of input data + * has been reached. + */ + void InputEnd(); + + /** + * From CMMFVideoRecordHwDevice + * The function starts recording video. + */ + void Start(); + + static TInt TimerCallBack( TAny* aPtr ); + + /** + * From CMMFVideoRecordHwDevice + * The function stops recording video + */ + void Stop(); + + /** + * From CMMFVideoRecordHwDevice + * The function pauses video recording. + */ + void Pause(); + + + /** + * From CMMFVideoRecordHwDevice + * The function resumes video recording after a pause. + */ + void Resume(); + + + /** + * From CMMFVideoRecordHwDevice + * The function freezes the input picture + */ + void Freeze(); + + + /** + * From CMMFVideoRecordHwDevice + * The function releases a frozen input picture. + */ + void ReleaseFreeze(); + + + /** + * From CMMFVideoRecordHwDevice + * The function returns the current recording position + * @return Returns the current recording position + */ + TTimeIntervalMicroSeconds RecordingPosition(); + + + /** + * From CMMFVideoRecordHwDevice + * The function reads various counters related to processed video pictures + * @param aCounters + * The counter structure to fill + */ + void GetPictureCounters( CMMFDevVideoRecord:: + TPictureCounters& aCounters ); + + /** + * From CMMFVideoRecordHwDevice + * The function reads the frame stabilisation output picture position + * @param aRect + * Output rect which holds frame stabilisation output + */ + void GetFrameStabilisationOutput( TRect& aRect ); + + /** + * From CMMFVideoRecordHwDevice + * The function retrieves the number of complexity control levels + * available for this hardware device + * @return Returns the number of complexity level + */ + TUint NumComplexityLevels(); + + + /** + * From CMMFVideoRecordHwDevice + * The function sets the complexity level to use for video processing in a + * hardware device + * @param aLevel + * The computational complexity level to use. + */ + void SetComplexityLevel( TUint aLevel ); + + /** + * From CMMFVideoRecordHwDevice + * The function gets the information about the pre-processing capabilities + * of the encoder hwdevice + * @return Returns the pointer to object holding preprocessor info + * @leave "The method will leave if an error occurs" + */ + CPreProcessorInfo* PreProcessorInfoLC(); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the hardware device input format + * @param aFormat + * The input format to use + * @param aPictureSize + * The input picture size in pixels + * @leave "The method will leave if an error occurs" + */ + void SetInputFormatL( const TUncompressedVideoFormat& aFormat, + const TSize& aPictureSize ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the data source to be a camera + * @param aCameraHandle + * Camera handle to be used + * @param aPictureRate + * Video capture frame rate + * @leave "The method will leave if an error occurs" + */ + void SetSourceCameraL( TInt aCameraHandle, TReal aPictureRate ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the data source to be memory buffers + * @param aMaxPictureRate + * The maximum picture rate for input pictures. + * @param aConstantPictureRate + * Flag indicating if picture rate is constant or not + * @param aProcessRealtime + * Flag indicating real time processing should be done or not + * @leave "The method will leave if an error occurs" + */ + void SetSourceMemoryL( TReal aMaxPictureRate, TBool aConstantPictureRate, + TBool aProcessRealtime ); + + /** + * From CMMFVideoRecordHwDevice + * The function enables synchronized encoding and set the clock source to + * use for synchronization. + * @param aClock + * Clock source to be used. + */ + void SetClockSource( MMMFClockSource* aClock ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for RGB to YUV color space + * conversion + * @param aRange + * Input RGB data range + * @param aOutputFormat + * Conversion output YUV format + * @leave "The method will leave if an error occurs" + */ + void SetRgbToYuvOptionsL( TRgbRange aRange, + const TYuvFormat& aOutputFormat); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for YUV to YUV data format + * conversion + * @param aRange + * Conversion input format + * @param aOutputFormat + * Conversion output YUV format + * @leave "The method will leave if an error occurs" + */ + void SetYuvToYuvOptionsL( const TYuvFormat& aInputFormat, + const TYuvFormat& aOutputFormat ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets the pre-processing types to be used + * @param aPreProcessTypes + * The pre-processing steps to perform, a bitwise OR of values from + * TPrePostProcessType + * @leave "The method will leave if an error occurs" + */ + void SetPreProcessTypesL( TUint32 aPreProcessTypes ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for rotation + * @param aRotationType + * The rotation to perform + * @leave "The method will leave if an error occurs" + */ + void SetRotateOptionsL( TRotationType aRotationType ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for scaling. + * @param aTargetSize + * Target picture size. + * @param aAntiAliasFiltering + * True if anti-aliasing filtering should be used + * @leave "The method will leave if an error occurs" + */ + void SetScaleOptionsL( const TSize& aTargetSize, + TBool aAntiAliasFiltering ); + + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for input cropping. + * @param aRect + * The input cropping rectangle specifying the area of the picture to + * use + * @leave "The method will leave if an error occurs" + */ + void SetInputCropOptionsL( const TRect& aRect ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for output cropping. + * @param aRect + * The output cropping rectangle specifying the area of the picture to + * use + * @leave "The method will leave if an error occurs" + */ + void SetOutputCropOptionsL( const TRect& aRect ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets pre-processing options for output padding + * @param aOutputSize + * The padded output picture size. + * @param aPicturePos + * The position for the original picture in the new padded picture. + * @leave "The method will leave if an error occurs" + */ + void SetOutputPadOptionsL( const TSize& aOutputSize, + const TPoint& aPicturePos ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets color enhancement pre-processing options. + * @param aOptions + * Color enchancement options + * @leave "The method will leave if an error occurs" + */ + void SetColorEnhancementOptionsL( + const TColorEnhancementOptions& aOptions); + + /** + * From CMMFVideoRecordHwDevice + * The function sets frame stabilisation options + * @param aOutputSize + * Output picture size. + * @param aFrameStabilisation + * True if frame stabilisation should be used + * @leave "The method will leave if an error occurs" + */ + void SetFrameStabilisationOptionsL( const TSize& aOutputSize, + TBool aFrameStabilisation ); + + /** + * From CMMFVideoRecordHwDevice + * The function sets custom implementation-specific pre-processing options + * @param aOptions + * Post-processing options + * @leave "The method will leave if an error occurs" + */ + void SetCustomPreProcessOptionsL( const TDesC8& aOptions ); + + + /** + * From CMMFVideoEncodeHwDevice + * The function sets the proxy implementation to be used + * @param aProxy + * The proxy to use + */ + void SetProxy( MMMFDevVideoRecordProxy& aProxy ); + + + +public: + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the input buffer is consumed + * @param aInp + * Pointer to the input picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + TInt InputBufferConsumed( TAny* aInp, TInt aError); + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the output buffer is ready + * @param aOup + * Pointer to the output picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + TInt OutputBufferReady( TAny* aOup, TInt aError ); + + /** + * From MProcessEngineObserver + * The function indicates to hwdevice that process engine has finished + * with the processing of command requested by hwdevice + * @param aCmd + * Command that has been processed by process engine + * @param aCmdData + * Pointer to command data that has been processed by process engine + * @param aError + * Error code corresponding to the command + */ + void CommandProcessed( TInt aCmd, TAny* aCmdData, TInt aError ); + + /** + * From CMMFVideoEncodeHwDevice + * The function indicates to hwdevice that process engine has met with an + * unrecoverable error during its processing + * @param aError + * The fatal error code + */ + void FatalErrorFromProcessEngine( TInt aError ); + +private: + + /** + * The function is the default constructor for class + * CAriMp4spencHwDeviceImpl + */ + CAriMp4spencHwDeviceImpl(); + + /** + * Symbian 2 phase constructor + */ + void ConstructL(); + + /** + * Updates the time periodically i.e gets the clock source values from + * client + * @return returns system wide error code on error + */ + TInt UpdateTime(); + + /** + * Creates coded Output buffers for the hw device. + * @param aSize + * Size of buffers to be created + */ + void CreateCodedOutputBuffersL( TUint aSize ); + + + /** + * Creates Internal buffers in segment mode, to hold the complete + * encoded frame returned from the codec + * @param aSize + * Size of buffers to be created + */ + void CreateInternalOutputBuffersL( TUint aBufferSize ); + + /** + * Creates packet offset info buffers + * @param aSize + * Size of buffers to be created + */ + void CreatePacketOffsetLengthInfoBuffersL( TUint aSize ); + + /** + * Decides whether this input picture can be encoded or not + * @param aPicture + * Pointer to the input picture + */ + TBool CanEncode( TVideoPicture *aPicture ); + + /** + * Input picture is not processed, returned back to client + * @param aPicture + * Pointer to the input picture + */ + void SkipInputPicture( TVideoPicture *aPicture ); + + + /** + * Checks whether this input picture is coded as i-frame or not + * @param aPicture + * Pointer to the input picture + */ + TBool IsForcedIFrameRequired( TVideoPicture* aPicture ); + + /** + * Fills one segment data from the internal buffer to output buffer + * @param aOutBuf + * Destination buffer to hold the packet + * @param aSrcBuf + * Buffer which contains encoder output frame + */ + void FillVideoSegment( TVideoOutputBuffer* aOutBuf, + TVideoOutputBuffer* aSrcBuf ); + + + /** + * Initializes the members of the output coded buffers created + * @param aOutputBuffer + * Output buffer for which members are to be initialized + */ + void InitializeOuputCodedBuffer( TVideoOutputBuffer& aOutputBuffer ); + + /** + * Checks if the specified input format is supported or not + * @param aFormat + * Input format to be checked + * @return Returns True if input format is supported else false + */ + TBool CheckInputFormat( const TUncompressedVideoFormat& aFormat ); + + /** + * Notifies the client that the hw device has encountered with error + * @param aError + * Error code indicating type of fatal error + */ + void ClientFatalError ( TInt aError ); + +private: + + /** + * Handle to proxy i.e observer + */ + MMMFDevVideoRecordProxy* iMMFDevVideoRecordProxy; + + /** + * Handle to preprocessor hw device + */ + CMMFVideoPreProcHwDevice* iInputDevice; + + /** + * Reference to clock source if client + */ + MMMFClockSource* iClockSource; + + /** + * Flag to indicate whether the buffer is returned to inputdevice + */ + TBool iInputBufReturnToPreProc; + + /** + * Hold the parameters that are required after initialize + */ + TMpeg4H263EncoderInitParams iCurSetMpeg4H263HWParams; + + /** + * Hold all the parameters before initialize + */ + TMpeg4H263EncoderInitParams iSetMpeg4H263HWParams; + + /** + * pointer to state machine object + */ + CStateMachine* iEncStateMac; + + /** + * All levels information is stored + */ + RArray iLevels; + + /** + * Supported Input format information + */ + RArray iSupportedInputFormats; + + /** + * Supported output formats information + */ + RArray iSupportedOutputFormats; + + /** + * All supported data unit types + */ + TUint32 iSupportedDataUnitTypes; + + /** + * All supported data unit encapsulation + */ + TUint32 iSupportedDataUnitEncapsulations; + + /** + * Timer for updates + */ + CPeriodic* iPeriodicTimer; + + /** + * Stores tha value when clock is paused + */ + TInt64 iClockTimeWhenPaused; + + /** + * Polling interval to be used + */ + TTimeIntervalMicroSeconds32 iPollingInterval; + + /** + * Codec Reference + */ + CAriMp4spencWrapper* iCodec; + + /** + * Pointer to base process engine object + */ + CBaseEngine* iEngine; + + /** + * Output Free buffers can be segment or coded buffers + */ + TVideoOutputBuffer* iOutputBuffers; + + /** + * Output buffer queue + */ + RPointerArray iOutputFreeBufferQueue; + + /** + * Output buffer size of the coded picture + */ + TInt iOutputBufferSize; + + + /** + * Pause offset i.e offset between pause and resume + */ + TInt64 iPauseOffset; + + /** + * Total time deviation from client clock source + */ + TInt64 iTotalTime; + + /** + * Last encoded picture time stamp + */ + TInt64 iLastEncodedPictureTimestamp; + + /** + * Indicates picture loss + */ + TBool iPictureLoss; + + /** + * Indicates input end called + */ + TBool iInputEndCalled; + + /** + * Picture Counters + */ + CMMFDevVideoRecord::TPictureCounters iPictureCounters; + + /** + * Indicates whether HwDevice is frozen by calling Freeze () + */ + TBool iFrozen; + + /** + * Current postion in the coded frame in packet mode + */ + TUint iTotalLengthFilledSoFarInPacketMode; + + /** + * Total Output buffer Length of the coded picture in packet mode + */ + TUint iTotalOutputBufferLengthInPacketMode; + + /** + * Pointer to current offset position within a frame - used in packet mode + * only + */ + TUint* iPacketOffSetCurrentPosition; + + /** + * Holds offsets and length information array + */ + TUint** iPacketOffSetAndLengthInfoBuffers; + + /** + * Free buffer queue for packet offset information + */ + RPointerArray iFreeBufferQueueForPacketOffsetInfo; + + /** + * Filled buffer queue for packet offset information + */ + RPointerArray iFilledBufferQueueForPacketOffsetInfo; + + /** + * Temporary output buffers + */ + TVideoOutputBuffer* iInternalOutputBuffers; + + /** + * Holds temporary o/p buffers + */ + RPointerArray iInternalOutputBufferQueue; + + /** + * Indicates if all the packets in a frame are sent to above layer or not + */ + TBool iPacketsPending; + + /** + * Stores config data + */ + HBufC8* iConfigData; + + /** + * Stores value of max no of buffers + */ + TUint iMaxNumOfPackets; + + /** + * Buffer to store packet length info + */ + TPtr8* iPacketOffsetBuf; +}; + +#endif //ARIMP4SPENCHWDEVICEIMPL_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/inc/arimp4spenchwdeviceuids.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/inc/arimp4spenchwdeviceuids.hrh Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the Uids used in Mpeg4SP/H263 encoder plugin. +* +*/ + + +#ifndef ARIMP4SPENCHWDEVICEUIDS_H +#define ARIMP4SPENCHWDEVICEUIDS_H + +#define KUidMpeg4H263EncoderHwDeviceImplUid 0x200298FC +#define KUidMpeg4H263EncoderHwDeviceDllUid 0x200298FD + +#endif //ARIMP4SPENCHWDEVICEUIDS_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/inc/arimp4sphwdeviceconstants.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/inc/arimp4sphwdeviceconstants.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,173 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This file defines the constants used in Mpeg4SP/H263 encoder plugin. +* +*/ + + +#ifndef ARIMP4SPENCHWDEVICECONSTANTS_H +#define ARIMP4SPENCHWDEVICECONSTANTS_H + +// Compressed Mpeg4 Video Formats Supported +_LIT8(KMPEG4MimeType, "video/mp4v-es"); +_LIT8(KMPEG4VTMimeType, "video/MP4V-ES"); +_LIT8(KMPEG4MimeTypeLevel0, "video/mp4v-es; profile-level-id=8"); +_LIT8(KMPEG4MimeTypeLevel0B, "video/mp4v-es; profile-level-id=9"); +_LIT8(KMPEG4MimeTypeLevel1, "video/mp4v-es; profile-level-id=1"); +_LIT8(KMPEG4MimeTypeLevel2, "video/mp4v-es; profile-level-id=2"); +_LIT8(KMPEG4MimeTypeLevel3, "video/mp4v-es; profile-level-id=3"); +_LIT8(KMPEG4MimeTypeLevel4, "video/mp4v-es; profile-level-id=4"); +_LIT8(KMPEG4MimeTypeLevel5, "video/mp4v-es; profile-level-id=5"); +_LIT8(KMPEG4MimeTypeLevel6, "video/mp4v-es; profile-level-id=6"); +_LIT8(KMPEG4MimeTypeLevel7, "video/mp4v-es; profile-level-id=7"); + + +// Compressed H263 Video Formats Supported +_LIT8(KH263MimeType, "video/H263-2000"); +_LIT8(KH263MimeTypeProfile0, "video/H263-2000; profile=0"); +_LIT8(KH263MimeTypeLevel10, "video/H263-2000; profile=0; level=10"); +_LIT8(KH263MimeTypeLevel20, "video/H263-2000; profile=0; level=20"); +_LIT8(KH263MimeTypeLevel30, "video/H263-2000; profile=0; level=30"); +_LIT8(KH263MimeTypeLevel40, "video/H263-2000; profile=0; level=40"); +_LIT8(KH263MimeTypeLevel45, "video/H263-2000; profile=0; level=45"); + + +// Mpeg4 and H263 Levels +#define KMPEG4_LEVEL_UNKNOWN 200 +#define KMPEG4_LEVEL_0 0 +#define KMPEG4_LEVEL_0B 10 +#define KMPEG4_LEVEL_1 1 +#define KMPEG4_LEVEL_2 2 +#define KMPEG4_LEVEL_3 3 +#define KMPEG4_LEVEL_4 4 +#define KMPEG4_LEVEL_5 5 +#define KMPEG4_LEVEL_6 6 +#define KMPEG4_LEVEL_7 7 + +#define KH263_LEVEL_UNKNOWN 300 +#define KH263_LEVEL_10 10 +#define KH263_LEVEL_20 20 +#define KH263_LEVEL_30 30 +#define KH263_LEVEL_40 40 +#define KH263_LEVEL_45 45 + + +_LIT(KMPEG4H263EncManufacturer,"Aricent"); +_LIT(KMPEG4H263EncIdentifier, "ARM MPEG4 H263 Video Encoder Hw Device"); + +// 1 SPS and 1 PPS +const TInt KWordLength = 4; +const TInt KDoubleWordLength = 8; + + +const TInt KMPEG4H263ENCIMPL_MAJOR_VERSION = 1; +const TInt KMPEG4H263ENCIMPL_MINOR_VERSION = 0; +const TInt KMPEG4H263ENCIMPL_BUILD_VERSION = 0; + +// Size - width,height related + +const TInt KMPEG4H263ENCIMPL_CIF_WIDTH = 352; +const TInt KMPEG4H263ENCIMPL_CIF_HEIGHT = 288; + +const TInt KMPEG4H263ENCIMPL_QCIF_WIDTH = 176; +const TInt KMPEG4H263ENCIMPL_QCIF_HEIGHT = 144; + +const TInt KMPEG4H263ENCIMPL_SQCIF_WIDTH = 128; +const TInt KMPEG4H263ENCIMPL_SQCIF_HEIGHT = 96; + +const TInt KMPEG4H263ENCIMPL_QVGA_WIDTH = 320; +const TInt KMPEG4H263ENCIMPL_QVGA_HEIGHT = 240; + +const TInt KMPEG4H263ENCIMPL_VGA_WIDTH = 640; +const TInt KMPEG4H263ENCIMPL_VGA_HEIGHT = 480; + +const TInt KMPEG4H263ENCIMPL_720P_WIDTH = 1280; +const TInt KMPEG4H263ENCIMPL_720P_HEIGHT = 720; + +//Level for H263 +const TInt KH263ENCIMPL_LEVEL10 = 10; +const TInt KH263ENCIMPL_LEVEL20 = 20; +const TInt KH263ENCIMPL_LEVEL30 = 30; +const TInt KH263ENCIMPL_LEVEL40 = 40; +const TInt KH263ENCIMPL_LEVEL45 = 45; + +//Level for MPEG4 +const TInt KMPEG4ENCIMPL_LEVEL_0 = 0; +const TInt KMPEG4ENCIMPL_LEVEL_1 = 1; +const TInt KMPEG4ENCIMPL_LEVEL_2 = 2; +const TInt KMPEG4ENCIMPL_LEVEL_3 = 3; +const TInt KMPEG4ENCIMPL_LEVEL_4A = 4; +const TInt KMPEG4ENCIMPL_LEVEL_5 = 5; +const TInt KMPEG4ENCIMPL_LEVEL_6 = 6; +const TInt KMPEG4ENCIMPL_LEVEL_7 = 7; +const TInt KMPEG4ENCIMPL_LEVEL_0B = 10; + +// Bitrate related (bits per second) for H263 +const TInt KH263ENCIMPL_DEFAULT_BITRATE = 64000; +const TInt KH263ENCIMPL_BITRATE_LEVEL_10 = 64000; +const TInt KH263ENCIMPL_BITRATE_LEVEL_20 = 128000; +const TInt KH263ENCIMPL_BITRATE_LEVEL_30 = 384000; +const TInt KH263ENCIMPL_BITRATE_LEVEL_40 = 2048000; +const TInt KH263ENCIMPL_BITRATE_LEVEL_45 = 128000; + +// Bitrate (bits per second) for MPEG4 +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_0 = 64000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_1 = 64000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_2 = 128000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_3 = 384000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_4A = 4000000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_5 = 8000000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_6 = 12000000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_7 = 38400000; +const TInt KMPEG4ENCIMPL_BITRATE_LEVEL_0B = 128000; + +// Level related mapping +const TInt KH263ENCIMPL_LEVEL_UNKNOWN = 0; + +// o/p buffer related +const TInt KMPEG4H263ENCIMPL_MAXNUM_OUTPUTBUFFERS = 2; +const TInt KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS = 2; +const TInt KMPEG4H263ENCIMPL_MAXNUM_SEGMENTBUFFERS = 30; +const TInt KMPEG4H263ENCIMPL_FACTOR_FOR_OUTPUTBUFFERSIZE_IN_PACKETMODE = 2; + +// o/p buffer size related +const TInt KMPEG4H263ENCIMPL_DEFAULT_SEGMENTSIZE = 256; +const TInt KMPEG4H263ENCIMPL_MIN_SEGMENTSIZE = 192; +const TInt KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE = 300; + +// Max coded picture size in case of Level 1b +const TInt KH263ENCIMPL_LEVEL1b_MAXCPBSIZE = 39375; + +// Max coded picture size in case of Level 1.1 +const TInt KH263ENCIMPL_LEVEL11_MAXCPBSIZE = 56250; + +// picture rate related +const TReal KMPEG4H263ENCIMPL_MAX_PICTURERATE = 30.0; +const TReal KMPEG4H263ENCIMPL_DEFAULT_PICTURERATE = 15.0; + +const TInt KMPEG4H263ENCIMPL_NUM_COMPLEXITYLEVELS = 4; +const TInt KMPEG4H263ENCIMPL_MAXNUM_REFERENCEPICTURES = 1; + +// Default random access rate- 1 per 3 seconds i.e.1 after 45 frames at 15 fps +const TReal KMPEG4H263ENCIMPL_DEFAULT_RANDOMACCESSRATE = 0.3333333; + +const TInt KMPEG4SUPPMIMEARRAYMAXINDEXVALUE = 10; +const TInt KH263SUPPMIMEARRAYMAXINDEXVALUE = 17; + +const TUint KMaxSupportedBitRate = 38400000; + +const TUint KDefaultTimerResolution = 30000; + +#endif //ARIMP4SPENCHWDEVICECONSTANTS_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/src/200298FD.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/src/200298FD.rss Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Resource file for Mpeg4SP/H263 encoder plugin. +* +*/ +#include "RegistryInfo.rh" +#include "DevVideoPluginInterfaceUIDs.hrh" +#include "arimp4spenchwdeviceuids.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidMpeg4H263EncoderHwDeviceDllUid; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidDevVideoEncoderHwDeviceDefine; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidMpeg4H263EncoderHwDeviceImplUid; + version_no = 1; + display_name = "Mpeg4 H263 Encoder HwDevice"; + default_data = "video/mp4v-es||video/H263-2000; profile-level-id=*"; + opaque_data = "0"; + } + }; + } + }; + } + diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spenchwdevice/src/arimp4spenchwdeviceimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spenchwdevice/src/arimp4spenchwdeviceimpl.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,3974 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of member functions of Mpeg4SP/H263 encoder plugin class - +* CAriMp4spencHwDeviceImpl. +* +*/ + +//Includes +#include "arimp4spenchwdeviceimpl.h" +#include "arimp4sphwdeviceconstants.h" +#include "aricommon.h" + +#include +#include +#include +#include + +//--------------------------------------------------------------------------- +// Maps the num/denom from the MDF to the aspect_ratio_idc value supported +//--------------------------------------------------------------------------- +// + +TInt32 MapAspectRatio( TUint32 aNumerator, TUint32 aDenominator ) + { + PRINT_ENTRY; + + TInt32 aspectratio = -1; + switch ( aDenominator ) + { + case 1: + if ( aNumerator == 1 ) + { + aspectratio = 1; + } + break; + case 11: + switch ( aNumerator ) + { + case 12: + aspectratio = 2; + break; + case 10: + aspectratio = 3; + break; + case 16: + aspectratio = 4; + break; + case 24: + aspectratio = 6; + break; + case 20: + aspectratio = 7; + break; + case 32: + aspectratio = 8; + break; + case 18: + aspectratio = 10; + break; + case 15: + aspectratio = 11; + break; + default: + break; + } + break; + case 33: + switch ( aNumerator ) + { + case 40: + aspectratio = 5; + break; + case 80: + aspectratio = 9; + break; + case 64: + aspectratio = 12; + break; + default: + break; + } + break; + case 99: + if ( aNumerator == 160 ) + { + aspectratio = 13; + } + + break; + default: + break; + } + + PRINT_EXIT; + return aspectratio; + } + +//--------------------------------------------------------------------------- +// Two phase constructor for an object of CAriMp4spencHwDeviceImpl +//--------------------------------------------------------------------------- +// +CAriMp4spencHwDeviceImpl* CAriMp4spencHwDeviceImpl::NewL() + { + PRINT_ENTRY; + + CAriMp4spencHwDeviceImpl* self = + new ( ELeave ) CAriMp4spencHwDeviceImpl(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + PRINT_EXIT; + return self; + } + +//--------------------------------------------------------------------------- +// Default constructor +//--------------------------------------------------------------------------- +// +CAriMp4spencHwDeviceImpl::CAriMp4spencHwDeviceImpl() : + iMMFDevVideoRecordProxy( NULL ), + iInputDevice( NULL ), + iClockSource( NULL ), + iInputBufReturnToPreProc( EFalse ), + iPeriodicTimer( NULL ), + iClockTimeWhenPaused( 0 ), + //100 milli seconds + iPollingInterval( TTimeIntervalMicroSeconds32( 100000 ) ), + iCodec( NULL ), iEngine( NULL ), iOutputBuffers( NULL ), + iOutputBufferSize( 0 ), iPauseOffset( 0 ), iTotalTime( 0 ), + iLastEncodedPictureTimestamp( 0 ), iPictureLoss( EFalse ), + iInputEndCalled( EFalse ), iFrozen( EFalse ), + iTotalLengthFilledSoFarInPacketMode( 0 ), + iTotalOutputBufferLengthInPacketMode( 0 ), + iPacketOffSetCurrentPosition( NULL ), + iPacketOffSetAndLengthInfoBuffers( NULL ), + iInternalOutputBuffers( NULL ), iPacketsPending( EFalse ) + + { + PRINT_ENTRY; + + iSupportedDataUnitTypes = EDuCodedPicture | EDuVideoSegment; + iSupportedDataUnitEncapsulations = EDuElementaryStream; + + // Default values for Init params - full range + TUncompressedVideoFormat inputFormat; + inputFormat.iDataFormat = EYuvRawData; + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range0; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + inputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + inputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + inputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + inputFormat.iYuvFormat.iAspectRatioNum = 1; + inputFormat.iYuvFormat.iAspectRatioDenom = 1; + + iSetMpeg4H263HWParams.iInputFormat = inputFormat; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_UNKNOWN; + iSetMpeg4H263HWParams.iAfterInitialize = 0; + iSetMpeg4H263HWParams.iOutputFormat = EH263; + iSetMpeg4H263HWParams.iMinNumOutputBuffers + = KMPEG4H263ENCIMPL_MAXNUM_OUTPUTBUFFERS; + + iSetMpeg4H263HWParams.iPacketSize = KMPEG4H263ENCIMPL_DEFAULT_SEGMENTSIZE; + iSetMpeg4H263HWParams.iMaxPictureRate + = KMPEG4H263ENCIMPL_DEFAULT_PICTURERATE; + + // initialize picture counters + iPictureCounters.iPicturesSkippedBufferOverflow = 0; + iPictureCounters.iPicturesSkippedProcPower = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + iPictureCounters.iInputPictures = 0; + iSetMpeg4H263HWParams.iDataEncapsulation = EDuElementaryStream; + + // default packet mode is off + iSetMpeg4H263HWParams.iDataUnitType = EDuCodedPicture; + + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_DEFAULT_BITRATE; + iSetMpeg4H263HWParams.iTargetPictureRate + = KMPEG4H263ENCIMPL_DEFAULT_PICTURERATE; + iSetMpeg4H263HWParams.iRandomAccessRate + = KMPEG4H263ENCIMPL_DEFAULT_RANDOMACCESSRATE; + // scene detection is ON + iSetMpeg4H263HWParams.iSceneCutDetection = 1; + //preprocessing disabled by default + iSetMpeg4H263HWParams.iPreprocessing = 0; + iSetMpeg4H263HWParams.iRCModel = CBR; + iSetMpeg4H263HWParams.iComplexityLevel = HIGH; + iSetMpeg4H263HWParams.iSearchRange = 31; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Destructor +//--------------------------------------------------------------------------- +// +CAriMp4spencHwDeviceImpl::~CAriMp4spencHwDeviceImpl() + { + PRINT_ENTRY; + + PRINT_MSG( LEVEL_LOW, ( "this is %x", this ) ); + iSupportedInputFormats.Close(); + iLevels.Close(); + + //allocated formats should be deleted before closing + while ( iSupportedOutputFormats.Count() > 0 ) + { + CCompressedVideoFormat* lCompFormat = iSupportedOutputFormats[0]; + iSupportedOutputFormats.Remove( 0 ); + delete lCompFormat; + } + iSupportedOutputFormats.Close(); + + // Stop processing + if ( !iEncStateMac->IsStopped() && ( !iEncStateMac->IsInDeadState() ) ) + { + if ( iEncStateMac->IsInitialized() ) + { + Stop(); + } + } + + if ( iEngine ) + { + iEngine->Reset(); + delete iEngine; + iEngine = NULL; + } + + if ( iCodec ) + { + delete iCodec; + iCodec = NULL; + } + + //delete output buffers + iOutputFreeBufferQueue.Reset(); + iOutputFreeBufferQueue.Close(); + + if ( iOutputBuffers ) + { + if ( iSetMpeg4H263HWParams.iMinNumOutputBuffers ) + { + for ( TInt i = 0; i < iSetMpeg4H263HWParams.iMinNumOutputBuffers; + i++ ) + { + if ( iOutputBuffers[i].iData.Ptr() ) + { + delete ( TUint8* ) iOutputBuffers[i].iData.Ptr(); + } + } + } + + delete[] iOutputBuffers; + iOutputBuffers = NULL; + } + + if ( iPeriodicTimer ) + { + delete iPeriodicTimer; + iPeriodicTimer = NULL; + } + + if ( iPacketOffSetAndLengthInfoBuffers ) + { + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; + i++ ) + { + delete[] ( TUint8* ) iPacketOffSetAndLengthInfoBuffers[i]; + } + delete[] ( TUint* ) iPacketOffSetAndLengthInfoBuffers; + iPacketOffSetAndLengthInfoBuffers = NULL; + } + + //delete temp output buffers + iInternalOutputBufferQueue.Reset(); + iInternalOutputBufferQueue.Close(); + + if ( iInternalOutputBuffers ) + { + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; + i++ ) + { + if ( iInternalOutputBuffers[i].iData.Ptr() ) + { + delete ( TUint8* ) iInternalOutputBuffers[i].iData.Ptr(); + } + } + delete[] iInternalOutputBuffers; + iInternalOutputBuffers = NULL; + } + + iFreeBufferQueueForPacketOffsetInfo.Reset(); + iFilledBufferQueueForPacketOffsetInfo.Reset(); + + if ( iConfigData ) + { + delete iConfigData; + iConfigData = NULL; + } + + if ( iPacketOffsetBuf ) + { + delete iPacketOffsetBuf; + iPacketOffsetBuf = NULL; + } + + if ( iEncStateMac ) + { + delete iEncStateMac; + iEncStateMac = NULL; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Custom Interface supported by the HwDevice plugin +//--------------------------------------------------------------------------- +// +TAny* CAriMp4spencHwDeviceImpl::CustomInterface( TUid /* aInterface */ ) + { + PRINT_ENTRY; + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +// Returns information about this Encoder HW Device +//--------------------------------------------------------------------------- +// +CVideoEncoderInfo* CAriMp4spencHwDeviceImpl::VideoEncoderInfoLC() + { + PRINT_ENTRY; + + TSize maxPictureSize = TSize( KMPEG4H263ENCIMPL_720P_WIDTH, + KMPEG4H263ENCIMPL_720P_HEIGHT ); + + TUint32 maxBitRate = KMaxSupportedBitRate; + RArray maxPictureRatesAndSizes; + CleanupClosePushL( maxPictureRatesAndSizes ); + TPictureRateAndSize pictureRateAndSize; + TInt error = KErrNone; + + // Max frame rate in mpeg4 sp encoding for any resolution is 15 fps. + // 30 fps is supported only in H263 encoding for SQCIF, QCIF, CIF only. + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_SQCIF_WIDTH, + KMPEG4H263ENCIMPL_SQCIF_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_QCIF_WIDTH, + KMPEG4H263ENCIMPL_QCIF_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate30; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_CIF_WIDTH, + KMPEG4H263ENCIMPL_CIF_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate15; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_QVGA_WIDTH, + KMPEG4H263ENCIMPL_QVGA_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate15; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_VGA_WIDTH, + KMPEG4H263ENCIMPL_VGA_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + pictureRateAndSize.iPictureRate = KPictureRate15; + pictureRateAndSize.iPictureSize = TSize( KMPEG4H263ENCIMPL_720P_WIDTH, + KMPEG4H263ENCIMPL_720P_HEIGHT ); + + error = maxPictureRatesAndSizes.Append( pictureRateAndSize ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + TUint32 lSupportedPictureOptions = TVideoPicture::ETimestamp + | TVideoPicture::EReqInstantRefresh | TVideoPicture::ESceneCut; + + TUint32 supportedDataUnitEncapsulations = EDuElementaryStream; + TUint32 supportedDataUnitTypes = EDuCodedPicture | EDuVideoSegment; + CVideoEncoderInfo* videoEncoderInfo = CVideoEncoderInfo::NewL( TUid::Uid( + KUidMpeg4H263EncoderHwDeviceImplUid ), + KMPEG4H263EncManufacturer, + KMPEG4H263EncIdentifier, + TVersion( KMPEG4H263ENCIMPL_MAJOR_VERSION, + KMPEG4H263ENCIMPL_MINOR_VERSION, + KMPEG4H263ENCIMPL_BUILD_VERSION ), + // Accelerated + EFalse, + // Enc doesnt support direct capture + EFalse, + iSupportedInputFormats.Array(), + iSupportedOutputFormats.Array(), + maxPictureSize, + supportedDataUnitTypes, + // Max bitrate layers + supportedDataUnitEncapsulations, 1, + //aSupportsSupplementalEnhancementInfo + EFalse, + //aMaxUnequalErrorProtectionLevels + 1, + maxBitRate, maxPictureRatesAndSizes.Array(), + 1, + //aSupportsPictureLoss + lSupportedPictureOptions, + ETrue, + //aSupportsSliceLoss + ETrue, + //aCodingStandardSpecificInfo + KNullDesC8, + //aImplementationSpecificInfo + KNullDesC8 ); + + CleanupStack::PopAndDestroy(); + CleanupStack::PushL( videoEncoderInfo ); + + PRINT_EXIT; + return videoEncoderInfo; + } + +//--------------------------------------------------------------------------- +// Sets the encoder output format +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetOutputFormatL( + const CCompressedVideoFormat& aFormat, + TVideoDataUnitType aDataUnitType, + TVideoDataUnitEncapsulation aDataEncapsulation, + TBool aSegmentationAllowed ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetOutputFormatL () called before Initialize ()" ); + User::Leave( KErrPermissionDenied ); + } + + TInt error = KErrNotFound; + TPtrC8 mimeType( aFormat.MimeType() ); + TInt i; + for ( i = 0; i < iSupportedOutputFormats.Count(); i++ ) + { + CCompressedVideoFormat* format = iSupportedOutputFormats[i]; + if ( mimeType.CompareF( format->MimeType() ) == 0 ) + { + iSetMpeg4H263HWParams.iLevel = iLevels[i]; + error = KErrNone; + break; + } + } + + if ( error == KErrNotFound ) + { + PRINT_ERR( "CAriMp4spencHwDeviceImpl::SetOutputFormatL() Leaving" + " because of unsupported output mimetype" ); + User::Leave( KErrNotSupported ); + return; + } + + // Index values 0 - 10 contain MPEG4 mime types and 11-17 contain + // H263 mime types + if ( i >= 0 && i <= KMPEG4SUPPMIMEARRAYMAXINDEXVALUE ) + { + iSetMpeg4H263HWParams.iOutputFormat = EMpeg4; + } + + else if ( i >= KMPEG4SUPPMIMEARRAYMAXINDEXVALUE + 1 && i + <= KH263SUPPMIMEARRAYMAXINDEXVALUE ) + { + iSetMpeg4H263HWParams.iOutputFormat = EH263; + } + + PRINT_MSG( LEVEL_HIGH, ( "level is set to %d" + ,(TInt)iSetMpeg4H263HWParams.iLevel ) ); + + if ( ( ( aDataUnitType != EDuCodedPicture ) && ( aDataUnitType + != EDuVideoSegment) ) || ( aDataEncapsulation + != EDuElementaryStream ) || (aSegmentationAllowed ) ) + + { + PRINT_ERR( "CAriMp4spencHwDeviceImpl::SetOutputFormatL() Leaving" + " because of unsupported data unit type or data unit" + " encapsulation" ); + User::Leave( KErrNotSupported ); + } + + if ( aDataUnitType == EDuCodedPicture ) + { + iSetMpeg4H263HWParams.iPacketmode = EFalse; + iSetMpeg4H263HWParams.iNumOfGOBHdrs = 0; + PRINT_MSG( LEVEL_HIGH, ( "CAriMp4spencHwDeviceImpl::" + "SetOutputFormatL() Packet mode is OFF " ) ); + } + else + { + iSetMpeg4H263HWParams.iPacketmode = ETrue; + if ( iSetMpeg4H263HWParams.iOutputFormat == EH263 ) + { + iSetMpeg4H263HWParams.iNumOfGOBHdrs = 1; + } + PRINT_MSG( LEVEL_HIGH, ( "CAriMp4spencHwDeviceImpl::" + "SetOutputFormatL() Packet mode is ON " ) ); + + // must be calculated from and levels set by the client + iSetMpeg4H263HWParams.iMinNumOutputBuffers + = KMPEG4H263ENCIMPL_MAXNUM_SEGMENTBUFFERS; + } + + iSetMpeg4H263HWParams.iDataUnitType = aDataUnitType; + iSetMpeg4H263HWParams.iDataEncapsulation = aDataEncapsulation; + iSetMpeg4H263HWParams.iSegmentationAllowed = aSegmentationAllowed; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncOutputFormat; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the pre-processor device that will write data to this encoder +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetInputDevice( + CMMFVideoPreProcHwDevice* aDevice ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( !aDevice ) + { + ClientFatalError( KErrArgument ); + return; + } + + iInputDevice = aDevice; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncInputDevice; + iInputBufReturnToPreProc = ETrue; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the number of bit-rate scalability layers to use +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetNumBitrateLayersL( TUint aNumLayers ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetNumBitrateLayersL () called before Initialize" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + if (aNumLayers != 1) + { + PRINT_ERR( "Wrong value passed for aNumLayers... Leaving" ); + User::Leave( KErrNotSupported ); + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the scalability type for a bit-rate scalability layer. Currently not +// supported +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetScalabilityLayerTypeL( TUint /*aLayer*/, + TScalabilityType /*aScalabilityType*/ ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetScalabilityLayerTypeL() called before Initialize" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + PRINT_ERR( "SetScalabilityLayerTypeL() not supported...Leaving with " + "KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the reference picture options to be used for all scalability layers +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetGlobalReferenceOptions( + TUint aMaxReferencePictures, TUint aMaxPictureOrderDelay ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( aMaxPictureOrderDelay != 0 || aMaxReferencePictures + > KMPEG4H263ENCIMPL_MAXNUM_REFERENCEPICTURES ) + { + ClientFatalError( KErrNotSupported ); + return; + } + + iSetMpeg4H263HWParams.iLayerReferenceOptions[0].iMaxReferencePictures + = aMaxReferencePictures; + + iSetMpeg4H263HWParams.iLayerReferenceOptions[0].iMaxPictureOrderDelay + = aMaxPictureOrderDelay; + + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncGlobalRefOptions; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the reference picture options to be used for a single scalability +// layer +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetLayerReferenceOptions( TUint /*aLayer*/, + TUint /*aMaxReferencePictures*/, TUint /*aMaxPictureOrderDelay*/ ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets encoder buffering options +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetBufferOptionsL( + const TEncoderBufferOptions& aOptions ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetBufferOptionsL () called before Initialize ()" ); + User::Leave( KErrPermissionDenied ); + } + + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iMaxPreEncoderBufferPictures = %d" , + (TInt)aOptions.iMaxPreEncoderBufferPictures ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iMaxOutputBufferSize = %d", + ( TInt ) aOptions.iMaxOutputBufferSize ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iMaxCodedPictureSize = %d" , + ( TInt )aOptions.iMaxCodedPictureSize ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iHrdVbvSpec = %x", ( TInt ) aOptions.iHrdVbvSpec ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iMinNumOutputBuffers = %d" , + ( TInt ) aOptions.iMinNumOutputBuffers ) ); + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetBufferOptionsL() " + "iMaxCodedSegmentSize = %d" , + ( TInt ) aOptions.iMaxCodedSegmentSize ) ); + + if ( ( aOptions.iMaxPreEncoderBufferPictures == 0 ) + || ( aOptions.iMaxOutputBufferSize == 0 ) + || ( aOptions.iMinNumOutputBuffers == 0 ) + || ( aOptions.iHrdVbvSpec == EHrdVbv3GPP ) ) + { + PRINT_ERR( "SetBufferOptionsL () - incorrect parameter passed ..." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + return; + } + + iSetMpeg4H263HWParams.iMaxPreEncoderBufferPictures + = aOptions.iMaxPreEncoderBufferPictures; + iSetMpeg4H263HWParams.iMaxOutputBufferSize + = aOptions.iMaxOutputBufferSize; + iSetMpeg4H263HWParams.iMaxCodedPictureSize + = aOptions.iMaxCodedPictureSize; + iSetMpeg4H263HWParams.iPacketSize = aOptions.iMaxCodedSegmentSize; + iSetMpeg4H263HWParams.iMinNumOutputBuffers + = aOptions.iMinNumOutputBuffers; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncBufferOptions; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the encoder output rectangle +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetOutputRectL( const TRect& aRect ) + { + PRINT_ENTRY; + + if ( ( aRect.iTl.iX >= aRect.iBr.iX ) + || ( aRect.iTl.iY >= aRect.iBr.iY ) ) + { + PRINT_ERR( " Invalid parameteres passed..Leaving " ); + User::Leave( KErrNotSupported ); + return; + } + + iSetMpeg4H263HWParams.iOutputRect = aRect; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncOutputRectSize; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets whether bit errors or packets losses can be expected in the video +// transmission +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetErrorsExpected( TBool aBitErrors, + TBool aPacketLosses ) + { + PRINT_ENTRY; + + // This can bel called before and after initialize + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SetErrorsExpected()" + " BitErrors is set to [ %d ]", aBitErrors ) ); + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::SetErrorsExpected() " + "iPacketLosses is set to [ %d ]", aPacketLosses ) ); + + if ( iEncStateMac->IsInitialized() ) + { + iCurSetMpeg4H263HWParams.iBitErrors = aBitErrors; + iCurSetMpeg4H263HWParams.iPacketLosses = aPacketLosses; + iCurSetMpeg4H263HWParams.iAfterInitialize |= EEncErrorsExpected; + } + else + { + iSetMpeg4H263HWParams.iBitErrors = aBitErrors; + iSetMpeg4H263HWParams.iPacketLosses = aPacketLosses; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncErrorsExpected; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the minimum frequency (in time) for instantaneous random access points +// in the bitstream +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetMinRandomAccessRate( TReal aRate ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + // simply return no further action is taken + if ( aRate <= 0.0 ) + { + return; + } + iCurSetMpeg4H263HWParams.iRandomAccessRate = aRate; + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl" + "::SetMinRandomAccessRate() iRandomAccessRate is %f" , + ( TReal )iSetMpeg4H263HWParams.iRandomAccessRate ) ); + iCurSetMpeg4H263HWParams.iAfterInitialize |= EEncRandomAccessRate; + } + else + { + if ( aRate <= 0.0 ) + { + ClientFatalError( KErrNotSupported ); + return; + } + iSetMpeg4H263HWParams.iRandomAccessRate = aRate; + + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncRandomAccessRate; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets coding-standard specific encoder options. +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetCodingStandardSpecificOptionsL( + const TDesC8& /*aOptions*/ ) + { + PRINT_ENTRY; + User::Leave( KErrNotSupported ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets coding-standard specific encoder options. +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetImplementationSpecificEncoderOptionsL( + const TDesC8& /*aOptions*/ ) + { + PRINT_ENTRY; + + //This API can be called at any point of time + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns coding-standard specific initialization output from the encoder +//--------------------------------------------------------------------------- +// + +HBufC8* CAriMp4spencHwDeviceImpl::CodingStandardSpecificInitOutputLC() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CodingStandardSpecificInitOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + TUint configLength; + TUint err = iCodec->GetParam( CONTROL_CMD_GET_CONFIGDATALENGTH, + &configLength ); + if ( err ) + { + User::Leave( err ); + } + + iConfigData = HBufC8::NewL( configLength ); + err = iCodec->GetParam( CONTROL_CMD_GET_CONFIGDATA, iConfigData ); + + if ( err ) + { + PRINT_ERR("GetParam failure"); + User::Leave( err ); + } + + PRINT_EXIT; + return iConfigData; + } + +//--------------------------------------------------------------------------- +// Returns coding-standard specific initialization output from the encoder +//--------------------------------------------------------------------------- +// + +HBufC8* CAriMp4spencHwDeviceImpl::ImplementationSpecificInitOutputLC() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "ImplementationSpecificInitOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + return NULL; + } + + PRINT_ERR( "ImplementationSpecificInitOutputLC () not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +// Sets the number of unequal error protection levels +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetErrorProtectionLevelsL( + TUint /*aNumLevels*/, TBool /*aSeparateBuffers*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetErrorProtectionLevelsL() not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the number of unequal error protection levels +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetErrorProtectionLevelL(TUint /*aLevel*/, + TUint /*aBitrate*/, TUint /*aStrength*/) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetErrorProtectionLevelsL() not supported...leaving" + "with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the expected or prevailing channel conditions for an unequal +// error protection level, in terms of expected packet loss rate +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetChannelPacketLossRate(TUint /*aLevel*/, + TReal /*aLossRate*/, TTimeIntervalMicroSeconds32 /*aLossBurstLength*/) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + PRINT_EXIT; + ClientFatalError( KErrNotSupported ); + + } + +//--------------------------------------------------------------------------- +// Sets the expected or prevailing channel conditions for an unequal error +// protection level, in terms of expected bit error rate +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetChannelBitErrorRate(TUint /*aLevel*/, + TReal aErrorRate, TReal /*aStdDeviation*/) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // ignore the negative and 0 error rate values - #AANV-6QSC9N + if ( aErrorRate < 0.0 ) + { + return; + } + + TReal* bitErrorRate = NULL; + TRAPD ( error , bitErrorRate = new ( ELeave ) TReal ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + *bitErrorRate = aErrorRate; + TRAP ( error, iEngine->AddCommandL( CBaseEngine::EHighPriority, + CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE, bitErrorRate ) ); + + if ( error != KErrNone ) + { + delete bitErrorRate; + ClientFatalError( error ); + return; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the target size of each coded video segment +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetSegmentTargetSize( TUint aLayer, + TUint aSizeBytes, TUint /*aSizeMacroblocks*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( iSetMpeg4H263HWParams.iDataUnitType != EDuVideoSegment ) + { + return; + } + + // aLayer should be zero since layered bit-rate scalability is not used. + if ( aLayer != 0 ) + { + return; + } + + TUint calculatedSegmentSize = 0; + // if value < 0 or > iMaxOutputBufferSize the adjust this value + if ( aSizeBytes < KMPEG4H263ENCIMPL_MIN_SEGMENTSIZE ) + { + calculatedSegmentSize = KMPEG4H263ENCIMPL_MIN_SEGMENTSIZE; + } + else + { + if ( iSetMpeg4H263HWParams.iMaxOutputBufferSize + > KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE ) + { + if ( aSizeBytes < KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE ) + { + calculatedSegmentSize = aSizeBytes; + } + else + { + calculatedSegmentSize = KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE; + } + } + else + { + if ( aSizeBytes < iSetMpeg4H263HWParams.iMaxOutputBufferSize ) + { + calculatedSegmentSize = aSizeBytes; + } + else + { + calculatedSegmentSize + = iSetMpeg4H263HWParams.iMaxOutputBufferSize; + } + } + } + + // Set the target size on codec + + TInt error = iCodec->SetParam( CONTROL_CMD_SET_PACKETSIZE, + &calculatedSegmentSize ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + iSetMpeg4H263HWParams.iPacketSize = calculatedSegmentSize; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the bit-rate control options for a layer +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetRateControlOptions( TUint aLayer, + const TRateControlOptions& aOptions ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // Since layered bit-rate scalability is not used, options are set for the + //entire stream + + if ( aLayer != 0 ) + { + return; + } + + if ( ( aOptions.iPictureRate <= 0 ) || + ( aOptions.iControl & EBrControlPicture ) ) + { + return; + } + + if ( aOptions.iControl & EBrControlStream ) + { + if ( ( aOptions.iQualityTemporalTradeoff < 0 ) + || ( aOptions.iQualityTemporalTradeoff > 1 ) + || ( aOptions.iLatencyQualityTradeoff < 0 ) + || ( aOptions.iLatencyQualityTradeoff > 1 ) + || ( aOptions.iBitrate == 0 ) ) + { + return; + } + } + + TRateControlOptions* rateControlOptions = NULL; + TRAPD ( error, rateControlOptions = new ( ELeave ) TRateControlOptions ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + rateControlOptions->iControl = aOptions.iControl; + // default bit rate used + if ( aOptions.iControl & EBrControlNone ) + { + rateControlOptions->iBitrate = iSetMpeg4H263HWParams.iBitRate; + } + else + { + rateControlOptions->iBitrate = ( aOptions.iBitrate + <= iSetMpeg4H263HWParams.iBitRate ) ? ( aOptions.iBitrate ) + : ( iSetMpeg4H263HWParams.iBitRate ); + } + + rateControlOptions->iPictureQuality = aOptions.iPictureQuality; + rateControlOptions->iPictureRate = aOptions.iPictureRate; + rateControlOptions->iQualityTemporalTradeoff + = aOptions.iQualityTemporalTradeoff; + rateControlOptions->iLatencyQualityTradeoff + = aOptions.iLatencyQualityTradeoff; + + TRAP ( error, iEngine->AddCommandL( CBaseEngine::EHighPriority, + CONTROL_CMD_SET_RATE_CONTROL_OPTIONS, rateControlOptions ) ); + + if ( error != KErrNone ) + { + delete rateControlOptions; + ClientFatalError( error ); + return; + } + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + "iBitrate is %d", ( TInt )aOptions.iBitrate ) ); + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + "iPictureQuality is %d" , ( TInt )aOptions.iPictureQuality ) ); + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + " iPictureRate is %f", ( TReal )aOptions.iPictureRate ) ); + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + "iQualityTemporalTradeoff is %f" , + ( TReal )aOptions.iQualityTemporalTradeoff ) ); + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + " iLatencyQualityTradeoff is %f " , + ( TReal ) aOptions.iLatencyQualityTradeoff ) ); + + PRINT_MSG( LEVEL_LOW,( "CAriMp4spencHwDeviceImpl::SetRateControlOptions" + "iControl is %x" , ( TInt ) aOptions.iControl ) ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets in-layer scalability options for a layer +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetInLayerScalabilityL( TUint /*aLayer*/, + TUint /*aNumSteps*/, TInLayerScalabilityType /*aScalabilityType*/, + const TArray& /*aBitrateShare*/, + const TArray& /*aPictureShare*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetInLayerScalabilityL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SetInLayerScalabilityL () not supported..leaving with " + "KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the period for layer promotions points for a scalability layer +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetLayerPromotionPointPeriod( + TUint /*aLayer*/, + TUint /*aPeriod*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns coding-standard specific settings output from the encoder +//--------------------------------------------------------------------------- +// +HBufC8* CAriMp4spencHwDeviceImpl::CodingStandardSpecificSettingsOutputLC() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CodingStandardSpecificSettingsOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + PRINT_ERR( "CodingStandardSpecificSettingsOutputLC () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +// Returns implementation-specific settings output from the encoder +//--------------------------------------------------------------------------- +// +HBufC8* CAriMp4spencHwDeviceImpl::ImplementationSpecificSettingsOutputLC() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "ImplementationSpecificSettingsOutputLC () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "ImplementationSpecificSettingsOutputLC () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + return NULL; + } + +//--------------------------------------------------------------------------- +// Requests the encoder to sends supplemental information in the bitstream +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SendSupplementalInfoL( + const TDesC8& /*aData*/) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SendSupplementalInfoL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SendSupplementalInfoL () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Requests the encoder to sends supplemental information in the bitstream +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SendSupplementalInfoL( + const TDesC8& /*aData*/, + const TTimeIntervalMicroSeconds& /*aTimestamp*/) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SendSupplementalInfoL () called before " + "Initialize ()" ); + User::Leave( KErrNotReady ); + } + + PRINT_ERR( "SendSupplementalInfoL () not supported.." + "leaving with KErrNotSupported" ); + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Cancels the current supplemental information send request +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::CancelSupplementalInfo() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Gets the current output buffer status. The information includes +// the number of free output buffers and the total size of free buffers in +// bytes. +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::GetOutputBufferStatus( + TUint& aNumFreeBuffers, + TUint& aTotalFreeBytes ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + aNumFreeBuffers = iEngine->NumOutputBuffers() + + iOutputFreeBufferQueue.Count(); + aTotalFreeBytes = aNumFreeBuffers * iOutputBufferSize; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns a used output buffer back to the encoder +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::ReturnBuffer( TVideoOutputBuffer* aBuffer ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if (iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment) + { + TInt error = KErrNone; + error = iOutputFreeBufferQueue.Append( aBuffer ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + if ( !iPacketsPending ) + { + return; + } + + // still has packets in temporary buffer + if ( iTotalLengthFilledSoFarInPacketMode + < iTotalOutputBufferLengthInPacketMode ) + { + TVideoOutputBuffer *outBuf = iOutputFreeBufferQueue[0]; + FillVideoSegment( outBuf, iInternalOutputBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + else + { + + aBuffer->iData.Set( ( TUint8* ) aBuffer->iData.Ptr() + , iOutputBufferSize ); + + // add the buffer back to queue or process engine + if ( ( !iEncStateMac->IsInputEndPending() ) + && ( !iEncStateMac->IsStopped() ) ) + { + iEngine->AddOutput( ( TAny* ) aBuffer ); + } + else + { + TInt error = iOutputFreeBufferQueue.Append( aBuffer ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Indicates a picture loss to the encoder, without specifying the lost +// picture +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::PictureLoss() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + iPictureLoss = ETrue; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Indicates to the encoder the pictures that have been lost +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::PictureLoss( + const TArray& /*aPictures*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + iPictureLoss = ETrue; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Indicates a slice loss to the encoder. +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SliceLoss( TUint aFirstMacroblock, + TUint aNumMacroblocks, const TPictureId& /*aPicture*/ ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( ( aFirstMacroblock == 0 ) || ( aNumMacroblocks == 0 ) ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::SliceLoss() " + "aNumMacroblocks or aFirstMacroblock = 0 return" ) ); + return; + } + + TMPEG4H263EncSliceLoss* sliceLossParams = NULL; + TRAPD ( error, sliceLossParams = new( ELeave ) TMPEG4H263EncSliceLoss ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + sliceLossParams->iFirstMacroblock = aFirstMacroblock; + sliceLossParams->iNumMacroblocks = aNumMacroblocks; + + TRAP ( error, iEngine->AddCommandL( CBaseEngine::ENormalPriority + , CONTROL_CMD_SET_SLICELOSS, sliceLossParams ) ); + + if ( error != KErrNone ) + { + delete sliceLossParams; + ClientFatalError( error ); + return; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sends a reference picture selection request to the encoder +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::ReferencePictureSelection( + const TDesC8& /*aSelectionData*/) + { + PRINT_ENTRY; + + if (!iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + ClientFatalError( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Initializes the device, and reserves hardware resources +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::Initialize() + { + PRINT_ENTRY; + + //Device should be in unintialized state + if ( !iEncStateMac->IsTransitionValid( + CStateMachine::EInitializingCommand ) ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrPermissionDenied ); + return; + } + + // check for input and output formats set by the client + if ( !( iSetMpeg4H263HWParams.iBeforeInitialize & EEncInputFormat ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriMp4spencHwDeviceImpl::Initialize() " + "- SetInputFormat not called" ) ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this + , KErrNotSupported ); + return; + } + + // check for buffer sizes + if ( iSetMpeg4H263HWParams.iBeforeInitialize & EEncBufferOptions ) + { + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + // Buffer size related checks + if ( ( iSetMpeg4H263HWParams.iPacketSize + > KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE ) + || ( iSetMpeg4H263HWParams.iPacketSize + > iSetMpeg4H263HWParams.iMaxOutputBufferSize ) + || ( iSetMpeg4H263HWParams.iPacketSize == 0 ) ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + } + + else if ( iSetMpeg4H263HWParams.iDataUnitType == EDuCodedPicture ) + { + if ( ( iSetMpeg4H263HWParams.iMaxCodedPictureSize + > iSetMpeg4H263HWParams.iMaxOutputBufferSize ) + || ( iSetMpeg4H263HWParams.iMaxCodedPictureSize == 0 ) ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + } + } + else + { + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + iSetMpeg4H263HWParams.iMinNumOutputBuffers + = KMPEG4H263ENCIMPL_MAXNUM_SEGMENTBUFFERS; + iSetMpeg4H263HWParams.iPacketSize + = KMPEG4H263ENCIMPL_DEFAULT_SEGMENTSIZE; + iSetMpeg4H263HWParams.iMaxOutputBufferSize + = KMPEG4H263ENCIMPL_MAX_SEGMENTSIZE; + } + else + { + iSetMpeg4H263HWParams.iMinNumOutputBuffers + = KMPEG4H263ENCIMPL_MAXNUM_OUTPUTBUFFERS; + } + } + + if ( iSetMpeg4H263HWParams.iOutputFormat == EMpeg4 ) + { + if ( iSetMpeg4H263HWParams.iLevel == KMPEG4_LEVEL_UNKNOWN ) + { + + if ( ( ( iSetMpeg4H263HWParams.iLevel == KMPEG4_LEVEL_UNKNOWN ) + && ( iSetMpeg4H263HWParams.iPictureSize.iWidth + == KMPEG4H263ENCIMPL_QCIF_WIDTH + && iSetMpeg4H263HWParams.iPictureSize.iHeight + == KMPEG4H263ENCIMPL_QCIF_HEIGHT ) ) + || ( iSetMpeg4H263HWParams.iLevel == KMPEG4_LEVEL_0 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_0; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_0; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN ) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 99 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_1 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_1; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_1; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 396 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_3 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_3; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_3; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN ) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 1200 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_4 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_4A; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_4; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 1620 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_5 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_5; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_5; + } + + else if ( ( (iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN ) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 3600 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_6 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_6; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_6; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_UNKNOWN ) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 8160 ) ) || (iSetMpeg4H263HWParams.iLevel + == KMPEG4_LEVEL_7 ) ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_7; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_7; + } + + else if ( iSetMpeg4H263HWParams.iLevel == KMPEG4_LEVEL_0B ) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_0B; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_0B; + } + + else if (iSetMpeg4H263HWParams.iLevel == KMPEG4_LEVEL_2) + { + iSetMpeg4H263HWParams.iBitRate + = KMPEG4ENCIMPL_BITRATE_LEVEL_2; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KMPEG4_LEVEL_2; + } + } + + } + else if ( iSetMpeg4H263HWParams.iOutputFormat == EH263 ) + { + if ( ( ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_UNKNOWN) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 99 ) ) || ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_10 ) ) + { + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_BITRATE_LEVEL_10; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + iSetMpeg4H263HWParams.iLevel = KH263_LEVEL_10; + } + + else if ( ( ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_UNKNOWN ) + && ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256 + <= 396 ) ) || ( iSetMpeg4H263HWParams.iLevel + == KH263_LEVEL_30 ) ) + { + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_BITRATE_LEVEL_30; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate30; + iSetMpeg4H263HWParams.iLevel = KH263_LEVEL_30; + } + + else if ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_20 ) + { + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_BITRATE_LEVEL_20; + iSetMpeg4H263HWParams.iLevel = KH263ENCIMPL_LEVEL20; + if ( ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256) <= 396 ) + { + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate15; + } + else if ( ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight ) / 256) <= 99 ) + { + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate30; + } + } + + else if ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_40 ) + { + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_BITRATE_LEVEL_40; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate30; + iSetMpeg4H263HWParams.iLevel = KH263ENCIMPL_LEVEL40; + } + + else if ( iSetMpeg4H263HWParams.iLevel == KH263_LEVEL_45 ) + { + iSetMpeg4H263HWParams.iBitRate = KH263ENCIMPL_BITRATE_LEVEL_45; + iSetMpeg4H263HWParams.iTargetPictureRate = KPictureRate30; + iSetMpeg4H263HWParams.iLevel = KH263ENCIMPL_LEVEL45; + } + } + + if ( iSetMpeg4H263HWParams.iOutputFormat == EH263 ) + { + iSetMpeg4H263HWParams.iTimerResolution = KDefaultTimerResolution; + iSetMpeg4H263HWParams.iReversibleVLC = E_ON; + iSetMpeg4H263HWParams.iDataPartitioning = E_ON; + iSetMpeg4H263HWParams.iMAPS = E_ON; + } + else + { + iSetMpeg4H263HWParams.iTimerResolution = KDefaultTimerResolution; + iSetMpeg4H263HWParams.iReversibleVLC = E_OFF; + iSetMpeg4H263HWParams.iDataPartitioning = E_OFF; + iSetMpeg4H263HWParams.iMAPS = E_OFF; + } + + TUint maxNumOfPackets; + // create codec + TRAPD ( error, iCodec + = CAriMp4spencWrapper::NewL ( iSetMpeg4H263HWParams ) ); + + if ( error != KErrNone ) + { + // init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + // set the sync options to the codec + if ( iClockSource ) + { + TInt error = iCodec->SetSyncOptions( iClockSource ); + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + } + + //create engine + TRAP ( error, iEngine + = CBaseEngine::NewL( this, ( MBaseCodec* )iCodec, EFalse ) ); + + if ( error != KErrNone ) + { + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + //get the max buffer length from the codec + TUint maxOutputBufferSize = 0; + error = iCodec->GetParam( CONTROL_CMD_GET_MAXBUFFERLENGTH, + &maxOutputBufferSize ); + + if ( error != KErrNone ) + { + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + // if EduCodedPicture mode then check for buffer size passed + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuCodedPicture ) + { + if ( iSetMpeg4H263HWParams.iBeforeInitialize & EEncBufferOptions ) + { + if ( maxOutputBufferSize + > iSetMpeg4H263HWParams.iMaxCodedPictureSize ) + { + //init complete with error message + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, + KErrNotSupported ); + return; + } + } + else + { + iSetMpeg4H263HWParams.iMaxOutputBufferSize = maxOutputBufferSize; + iSetMpeg4H263HWParams.iMaxCodedPictureSize = maxOutputBufferSize; + } + } + + // if packet mode is on then allocate memory for NAL information + iMaxNumOfPackets = 0; + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + error = iCodec->GetParam( CONTROL_CMD_GET_MAXNUMOFPACKETS, + &iMaxNumOfPackets ); + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + maxNumOfPackets = iMaxNumOfPackets * KDoubleWordLength; + } + + if ( iSetMpeg4H263HWParams.iDataUnitType != EDuVideoSegment ) + { + TRAP ( error,CreateCodedOutputBuffersL( ( + maxOutputBufferSize ) ) ); + } + + else + { + // Allocate sufficient segment mode buffers + iSetMpeg4H263HWParams.iMinNumOutputBuffers = ( maxOutputBufferSize + / iSetMpeg4H263HWParams.iPacketSize ) + * KMPEG4H263ENCIMPL_MAXNUM_OUTPUTBUFFERS; + + TRAP ( error, CreateInternalOutputBuffersL( maxOutputBufferSize ) ); + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + TRAP( error, CreatePacketOffsetLengthInfoBuffersL( + maxNumOfPackets ) ); + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + TUint* ptr = iFreeBufferQueueForPacketOffsetInfo[0]; + TRAPD ( err, iPacketOffsetBuf = new( ELeave ) TPtr8( ( TUint8* ) ptr, + maxNumOfPackets, maxNumOfPackets ) ); + if ( err ) + { + ClientFatalError( KErrNoMemory ); + } + + //segment size will be the max segment size + TUint segmentSize = iSetMpeg4H263HWParams.iPacketSize; + TRAP ( error, CreateCodedOutputBuffersL( segmentSize ) ); + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + } + + if ( error != KErrNone ) + { + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, error ); + return; + } + + //reset the picture counters + iPictureCounters.iInputPictures = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + // reset the options set by client + iSetMpeg4H263HWParams.iBeforeInitialize = 0; + iCurSetMpeg4H263HWParams = iSetMpeg4H263HWParams; + iEncStateMac->Transit( CStateMachine::EInitializingCommand ); + iEncStateMac->Transit( CStateMachine::EInitializeCommand ); + iMMFDevVideoRecordProxy->MdvrpInitializeComplete( this, KErrNone ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Commit all changes since the last CommitL(), Revert() or Initialize() +// to the Hw device +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::CommitL() + { + PRINT_ENTRY; + + // This method can only be called after Initialize + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "CommitL () called before Initialize ()" ); + User::Leave( KErrNotReady ); + } + + // Methods that will be affected by CommitL in our case: + // SetOutputRectL + // SetCodingStandardSpecificOptionsL + // SetErrorsExpected + // SetMinRandomAccessRate + + TMpeg4H263EncoderInitParams *currentParams = + new ( ELeave ) TMpeg4H263EncoderInitParams; + + CleanupStack::PushL( currentParams ); + *currentParams = iCurSetMpeg4H263HWParams; + + // Add command apply commit settings to the codec + iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_COMMIT_OPTIONS, currentParams ); + + iCurSetMpeg4H263HWParams.iAfterInitialize = 0; + iSetMpeg4H263HWParams = iCurSetMpeg4H263HWParams; + CleanupStack::Pop( currentParams ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Revert all changes since the last CommitL(), Revert() or Initialize() +// back to their previous settings +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::Revert() + { + PRINT_ENTRY; + + // This method can only be called after Initialize + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + // Methods that will be affected by Revert in our case: + // SetOutputRectL + // SetCodingStandardSpecificOptionsL + // SetErrorsExpected + // SetMinRandomAccessRate + iCurSetMpeg4H263HWParams = iSetMpeg4H263HWParams; + iCurSetMpeg4H263HWParams.iAfterInitialize = 0; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// This method is called only in case of client memory buffers +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::WritePictureL( TVideoPicture* aPicture ) + { + PRINT_ENTRY; + + // This method should only be called only in following states + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "WritePictureL () called before Initialize ()" ); + User::Leave( KErrNotReady ); + } + + if ( iEncStateMac->IsInputEndPending() ) + { + PRINT_ERR( "Input end is pending.. leaving with KErrEof" ); + User::Leave( KErrEof ); + } + + if ( !aPicture || ( aPicture->iData.iRawData->Length() == 0 ) + || ( aPicture->iData.iRawData->Length() + != ( ( iSetMpeg4H263HWParams.iPictureSize.iWidth + * iSetMpeg4H263HWParams.iPictureSize.iHeight * 3 ) / 2 ) ) + || ( aPicture->iData.iDataFormat != EYuvRawData ) ) + { + PRINT_ERR( "Incorrect parameter passed" ); + User::Leave( KErrArgument ); + return; + } + + // Added a check to return the input picture if application tries to add + // pictures after calling InputEnd() or Stop() and before calling + // Start() again. + if ( iEncStateMac->IsStopped() ) + { + SkipInputPicture( aPicture ); + return; + } + + // counter to represent the num of input pictures received + iPictureCounters.iInputPictures++; + if ( IsForcedIFrameRequired( aPicture ) ) + { + iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_FORCED_I_FRAME, NULL ); + iPictureLoss = EFalse; + } + + //Check if clock source is enabled skip logic + if ( iClockSource ) + { + if ( ( !CanEncode( aPicture ) ) || iFrozen ) + { + SkipInputPicture( aPicture ); + return; + } + } + + TInt error = iEngine->AddInput( aPicture ); + if ( error != KErrNone ) + { + PRINT_ERR( "CAriMp4spencHwDeviceImpl::WritePictureL()" + " AddInput() failed" ); + User::Leave( error ); + return; + } + + //If output buffer is available for encoding immedietly, only then send it + // for encoding + if ( this->iSetMpeg4H263HWParams.iProcessRealtime ) + { + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + TInt perPictureSegmentBuffers = + iSetMpeg4H263HWParams.iMinNumOutputBuffers + / KMPEG4H263ENCIMPL_MAXNUM_OUTPUTBUFFERS; + TInt queueCount = iOutputFreeBufferQueue.Count(); + // Check for availability of segment buffers + if ( queueCount < perPictureSegmentBuffers ) + { + // Sufficient number of segment buffers are not present + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl" + "::WritePictureL() Input returned EDuVideoSegment " ) ); + /* Return the earlier input picture added to the queue. */ + iEngine->ReturnInput(); + return; + } + } + else + { + // Check for availability of buffers + if ( iEngine->NumOutputBuffers() == 0 ) + { + // Return the earlier input picture added to the queue + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl" + "::WritePictureL() Input returned EDuCodedPicture " ) ); + iEngine->ReturnInput(); + return; + } + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Notifies the hardware device that the end of input data has been reached +// and no more input pictures will be written +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::InputEnd() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EInputEndCommand ) ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( iEngine->NumInputBuffers() == 0 ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriMp4spencHwDeviceImpl::InputEnds()" ) ); + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return; + } + else + { + iInputEndCalled = ETrue; + } + iEncStateMac->Transit( CStateMachine::EInputEndCommand ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Starts recording video +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::Start() + { + PRINT_ENTRY; + + if ( iEncStateMac->IsPlaying() && !iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ( "CAriMp4spencHwDeviceImpl::Start()-already " + "in started state, So ignore" ) ); + return; + } + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EStartCommand ) ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + // Enable flag which indicates that all picture params and sequence + // params are put into 1st buffer + for ( TInt i = 0; i <= iInternalOutputBufferQueue.Count(); i++ ) + { + TVideoOutputBuffer *outputBuffer = iInternalOutputBufferQueue[0]; + iEngine->AddOutput( ( TAny* ) outputBuffer ); + iInternalOutputBufferQueue.Remove( 0 ); + } + } + else + { + // add all output buffers to engine + for ( TInt i = 0; i <= iOutputFreeBufferQueue.Count(); i++ ) + { + TVideoOutputBuffer *outputBuffer = iOutputFreeBufferQueue[0]; + iEngine->AddOutput( ( TAny* ) outputBuffer ); + iOutputFreeBufferQueue.Remove( 0 ); + } + } + + if ( iClockSource ) + { + TTime lSystemTime; + lSystemTime.UniversalTime(); + UpdateTime(); + iPeriodicTimer->Start( iPollingInterval, iPollingInterval, TCallBack( + CAriMp4spencHwDeviceImpl::TimerCallBack, ( TAny* ) this ) ); + } + + iEngine->Start(); + PRINT_MSG( LEVEL_LOW,("CAriMp4spencHwDeviceImpl::Start()Change to start" + "state**") ) ; + iEncStateMac->Transit( CStateMachine::EStartCommand ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Callback function to CPeriodicTimer object +//--------------------------------------------------------------------------- +// +TInt CAriMp4spencHwDeviceImpl::TimerCallBack( TAny* aPtr ) + { + PRINT_ENTRY; + + if ( !aPtr ) + { + ( ( CAriMp4spencHwDeviceImpl* ) aPtr )->ClientFatalError( + KErrArgument ); + return KErrNone; + } + + PRINT_EXIT; + return ( ( CAriMp4spencHwDeviceImpl* ) aPtr )->UpdateTime(); + } + +//--------------------------------------------------------------------------- +// Stops recording video. +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::Stop() + { + PRINT_ENTRY; + + if ( iEncStateMac->IsStopped() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::Stop() -> already" + "stop state, so ignore" ) ); + return; + } + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EStopCommand ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriMp4spencHwDeviceImpl::Stop() -> " + "fatalerror because Stop called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + iInputEndCalled = EFalse; + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + iTotalOutputBufferLengthInPacketMode = 0; + iTotalLengthFilledSoFarInPacketMode = 0; + iPacketsPending = EFalse; + } + + iEngine->Stop(); + iEngine->Reset(); + iFrozen = EFalse; + if ( iPeriodicTimer ) + { + iPeriodicTimer->Cancel(); + } + iEncStateMac->Transit( CStateMachine::EStopCommand ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Pauses video recording +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::Pause() + { + PRINT_ENTRY; + + if ( iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::Pause()-> already " + " Paused state, so ignore" ) ); + return; + } + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EPauseCommand ) ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::Pause() Pause " + "called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( iClockSource ) + { + iPeriodicTimer->Cancel(); + //Note down the clock when paued + iClockTimeWhenPaused = iClockSource->Time().Int64(); + } + + // Stop the engine + iEngine->Stop(); + + //Change the state of the encoder + iEncStateMac->Transit( CStateMachine::EPauseCommand ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Resumes video recording +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::Resume() + { + PRINT_ENTRY; + + // doing it before transitionvalid check because initialize->resume is + // not added + if ( iEncStateMac->IsInInitializedState() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::Resume()->Got " + "resume in initialized state. So go to start()" ) ); + Start(); + return; + } + + if ( iEncStateMac->IsPlaying() && !iEncStateMac->IsPaused() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::Resume()->already " + "in playing-not-paused state, so ignore" ) ); + return; + } + + if ( !iEncStateMac->IsTransitionValid( CStateMachine::EResumeCommand ) ) + { + PRINT_MSG( LEVEL_CRITICAL, ("Resume called in invalid state" ) ); + ClientFatalError( KErrPermissionDenied ); + return; + } + + // No arguments to be passed in Resume + if ( iClockSource ) + { + //Clock may or may not be paused, when HWDevice is paused, so + //add the paused duration to clock + iPauseOffset = iClockSource->Time().Int64(); + iPauseOffset -= iClockTimeWhenPaused; + + //calculate the total time and deviation + iTotalTime += iPauseOffset; + TTime lSystemTime; + lSystemTime.UniversalTime(); + + // Send Update time before sending Resume command, so that clock source + // is set before + UpdateTime(); + iPeriodicTimer->Start( iPollingInterval, iPollingInterval, TCallBack( + CAriMp4spencHwDeviceImpl::TimerCallBack, ( TAny* ) this ) ); + } + + // Start the engine + iEngine->Start(); + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + // send the remaining pending packets to client + while ( iOutputFreeBufferQueue.Count() && iPacketsPending ) + { + TVideoOutputBuffer *outBuf = iOutputFreeBufferQueue[0]; + FillVideoSegment( outBuf, iInternalOutputBufferQueue[0] ); + iOutputFreeBufferQueue.Remove( 0 ); + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + + //Change the state of the encoder + PRINT_EXIT; + iEncStateMac->Transit( CStateMachine::EResumeCommand ); + } + +//--------------------------------------------------------------------------- +// Freezes the input picture +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::Freeze() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_CRITICAL,("CAriMp4spencHwDeviceImpl::Freeze() Freeze" + " called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return; + } + iFrozen = ETrue; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Releases a frozen input picture +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::ReleaseFreeze() + { + + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::ReleaseFreeze() " + "called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return; + } + iFrozen = EFalse; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns the current recording position +//--------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CAriMp4spencHwDeviceImpl::RecordingPosition() + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriMp4spencHwDeviceImpl::" + "RecordingPosition() called in invalid state" ) ); + ClientFatalError( KErrNotReady ); + return TTimeIntervalMicroSeconds( 0 ); + } + + PRINT_EXIT; + return TTimeIntervalMicroSeconds( iLastEncodedPictureTimestamp ); + } + +//--------------------------------------------------------------------------- +// Reads various counters related to processed video pictures +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::GetPictureCounters( + CMMFDevVideoRecord::TPictureCounters& aCounters ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + TUint numofpacktsskipped; + TUint err = iCodec->GetParam( CONTROL_CMD_GET_NUMOFPICTSKIPPED, + &numofpacktsskipped ); + iPictureCounters.iPicturesSkippedRateControl + = iPictureCounters.iPicturesSkippedRateControl + numofpacktsskipped; + iPictureCounters.iPicturesProcessed = iPictureCounters.iInputPictures + - iPictureCounters.iPicturesSkippedRateControl; + + aCounters = iPictureCounters; + //reset the counters + iPictureCounters.iInputPictures = 0; + iPictureCounters.iPicturesSkippedRateControl = 0; + iPictureCounters.iPicturesProcessed = 0; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Reads the frame stabilisation output picture position. +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::GetFrameStabilisationOutput( + TRect&/* aRect*/) + { + PRINT_ENTRY; + PRINT_EXIT; + ClientFatalError( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Retrieves the number of complexity control levels available for this +// hardware device +//--------------------------------------------------------------------------- +// +TUint CAriMp4spencHwDeviceImpl::NumComplexityLevels() + { + + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return 0; + } + + PRINT_EXIT; + return ( KMPEG4H263ENCIMPL_NUM_COMPLEXITYLEVELS ); + } + +//--------------------------------------------------------------------------- +// Sets the complexity level to use for video processing in a hardware device +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::SetComplexityLevel( TUint aLevel ) + { + PRINT_ENTRY; + + if ( !iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrNotReady ); + return; + } + + if ( aLevel >= KMPEG4H263ENCIMPL_NUM_COMPLEXITYLEVELS ) + { + PRINT_MSG( LEVEL_CRITICAL, ("CAriMp4spencHwDeviceImpl" + "::SetComplexityLevel() Unsupported level Passed" ) ); + ClientFatalError( KErrArgument ); + } + + iSetMpeg4H263HWParams.iComplexityLevel = aLevel; + TMpeg4H263EncoderInitParams *currentParams = NULL; + TRAPD ( error, currentParams + = new ( ELeave ) TMpeg4H263EncoderInitParams ); + + *currentParams = iSetMpeg4H263HWParams; + + // Add command apply commit settings to the codec + TRAP ( error, iEngine->AddCommandL( CBaseEngine::ENormalPriority, + CONTROL_CMD_SET_COMPLEXITY_LEVEL, currentParams ) ); + + if ( error != KErrNone ) + { + delete currentParams; + ClientFatalError( error ); + return; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Retrieves information about the pre-processing capabilities of this +// hardware device. +//--------------------------------------------------------------------------- +// +CPreProcessorInfo* CAriMp4spencHwDeviceImpl::PreProcessorInfoLC() + { + PRINT_ENTRY; + + TInt cleanupStackPushCount = 0; + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetErrorProtectionLevelsL () called after Initialize()" + "..leaving" ); + User::Leave( KErrPermissionDenied ); + } + _LIT( KManufacturer, "" ); + _LIT( KIdentifier, "" ); + + TPtrC8 implementationSpecificInfo( NULL, 0 ); + RArray inputFormats; + CleanupClosePushL( inputFormats ); + cleanupStackPushCount++; + inputFormats.Reset(); + + RArray outputFormats; + CleanupClosePushL( outputFormats ); + cleanupStackPushCount++; + outputFormats.Reset(); + + RArray supportedCombinations; + CleanupClosePushL( supportedCombinations ); + cleanupStackPushCount++; + supportedCombinations.Reset(); + + RArray supportedScaleFactors; + CleanupClosePushL( supportedScaleFactors ); + cleanupStackPushCount++; + supportedScaleFactors.Reset(); + + TYuvToYuvCapabilities yuvToYuvCapabilities; + TUid uid; + CPreProcessorInfo *preProcessorInfo = CPreProcessorInfo::NewL( uid.Null(), + KManufacturer, KIdentifier, TVersion( 0, 0, 0 ), EFalse, EFalse, + inputFormats.Array(), outputFormats.Array(), + supportedCombinations.Array(), EFalse, EFalse, + supportedScaleFactors.Array(), yuvToYuvCapabilities, 0, 0, + implementationSpecificInfo ); + + CleanupStack::PushL( preProcessorInfo ); + CleanupStack::Pop( cleanupStackPushCount ); + + PRINT_EXIT; + return preProcessorInfo; + } + +//--------------------------------------------------------------------------- +// Sets the hardware device input format +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetInputFormatL( + const TUncompressedVideoFormat& aFormat, const TSize& aPictureSize ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetInputFormatL () called after Initialize()..leaving" ); + User::Leave( KErrPermissionDenied ); + } + + if ( !CheckInputFormat( aFormat ) ) + { + PRINT_ERR("CAriMp4spencHwDeviceImpl" + "::SetInputFormatL() Leaving because of not support input format" ); + User::Leave( KErrNotSupported ); + } + + TInt32 aspectRatio = ::MapAspectRatio( + aFormat.iYuvFormat.iAspectRatioNum, + aFormat.iYuvFormat.iAspectRatioDenom ); + if ( aspectRatio == -1 ) + { + User::Leave( KErrNotSupported ); + } + + iSetMpeg4H263HWParams.iAspectRatio = aspectRatio; + iSetMpeg4H263HWParams.iInputFormat = aFormat; + iSetMpeg4H263HWParams.iPictureSize = aPictureSize; + TInt height = iSetMpeg4H263HWParams.iPictureSize.iHeight; + TInt width = iSetMpeg4H263HWParams.iPictureSize.iWidth; + + if ( height > KMPEG4H263ENCIMPL_720P_HEIGHT || + width > KMPEG4H263ENCIMPL_720P_WIDTH ) + { + User::Leave( KErrNotSupported ); + } + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncInputFormat; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the data source to be a camera, and sets the device to use direct . +// capture for input +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetSourceCameraL( TInt /*aCameraHandle*/ +, TReal /*aPictureRate*/ ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + PRINT_ERR( "SetSourceCameraL() called after Initialize()..leaving" ); + User::Leave( KErrPermissionDenied ); + return; + } + User::Leave( KErrNotSupported ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the data source to be memory buffers. +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetSourceMemoryL( TReal aMaxPictureRate, + TBool aConstantPictureRate, TBool aProcessRealtime ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + User::Leave( KErrPermissionDenied ); + return; + } + + if ( ( aMaxPictureRate <= 0 ) || ( aMaxPictureRate + > KMPEG4H263ENCIMPL_MAX_PICTURERATE ) ) + { + PRINT_ERR( "Incorrect value of max picture rate..leaving" ); + User::Leave( KErrNotSupported ); + return; + } + + // Check for the picture rates supported + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::SetSourceMemoryL() " + "Memory Picture rate is set as %f", aMaxPictureRate ) ); + iSetMpeg4H263HWParams.iMaxPictureRate = aMaxPictureRate; + iSetMpeg4H263HWParams.iConstantPictureRate = aConstantPictureRate; + iSetMpeg4H263HWParams.iProcessRealtime = aProcessRealtime; + iSetMpeg4H263HWParams.iBeforeInitialize |= EEncSourceMemory; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets the clock source to use for video timing. If no clock +// source is set. video encoding will not be synchronized, but +// will proceed as fast as possible, depending on input data and +// output buffer availability. +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetClockSource( MMMFClockSource* aClock ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + + if ( !aClock ) + { + ClientFatalError( KErrArgument ); + return; + } + + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::SetClockSource() " + "Encoder ClockSource is %x", ( TInt ) aClock ) ); + iClockSource = aClock; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for RGB to YUV color space conversion +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetRgbToYuvOptionsL( TRgbRange /*aRange*/, + const TYuvFormat& /*aOutputFormat*/ ) + { + PRINT_ENTRY; + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//---------------------------------------------------------------------------- +// Sets pre-processing options for YUV to YUV data format conversion +//--------------------------------------------------------------------------- +// + + +void CAriMp4spencHwDeviceImpl::SetYuvToYuvOptionsL( + const TYuvFormat& /*aInputFormat*/, + const TYuvFormat& /*aOutputFormat*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetYuvToYuvOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets the pre-processing types to be used in a hardware device +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetPreProcessTypesL( + TUint32 /*aPreProcessTypes*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetPreProcessTypesL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for rotation +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetRotateOptionsL( + TRotationType /*aRotationType*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetRotateOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for scaling +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetScaleOptionsL( + const TSize& /*aTargetSize*/, + TBool /*aAntiAliasFiltering*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetScaleOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for input cropping +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetInputCropOptionsL( + const TRect& /*aRect*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetInputCropOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for output cropping +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetOutputCropOptionsL( + const TRect& /*aRect*/) + { + PRINT_ENTRY; + PRINT_ERR( "SetOutputCropOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets pre-processing options for output padding +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetOutputPadOptionsL( + const TSize& /*aOutputSize*/, const TPoint& /*aPicturePos*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetOutputPadOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets color enhancement pre-processing options +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetColorEnhancementOptionsL( + const TColorEnhancementOptions& /*aOptions*/) + { + PRINT_ENTRY; + PRINT_ERR( "SetColorEnhancementOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets frame stabilisation options +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetFrameStabilisationOptionsL( + const TSize& /*aOutputSize*/, TBool /*aFrameStabilisation*/ ) + { + PRINT_ENTRY; + PRINT_ERR( "SetFrameStabilisationOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Sets custom implementation-specific pre-processing options. +//--------------------------------------------------------------------------- +// +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetCustomPreProcessOptionsL( + const TDesC8& /*aOptions*/) + { + PRINT_ENTRY; + PRINT_ERR( "SetCustomPreProcessOptionsL not supported...leaving \n" ); + PRINT_EXIT; + User::Leave( KErrNotSupported ); + } + +//--------------------------------------------------------------------------- +// Proxy which recieves callbacks from Hw Device +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SetProxy( MMMFDevVideoRecordProxy& aProxy ) + { + PRINT_ENTRY; + + if ( iEncStateMac->IsInitialized() ) + { + ClientFatalError( KErrPermissionDenied ); + return; + } + iMMFDevVideoRecordProxy = &aProxy; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Callback to indicate the input buffer is consumed +//--------------------------------------------------------------------------- +// + +TInt CAriMp4spencHwDeviceImpl::InputBufferConsumed( TAny* aInp, + TInt aError ) + { + PRINT_ENTRY; + + if ( !aInp ) + { + return KErrArgument; + } + + TVideoPicture *picture = (TVideoPicture *) aInp; + if ( ( picture->iOptions & TVideoPicture::ETimestamp ) && aError + != ( KErrCancel ) ) + { + iLastEncodedPictureTimestamp = picture->iTimestamp.Int64(); + } + + // if custom buffer emabled then add it to queue else return the picture + // to client + if ( !iInputBufReturnToPreProc ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl" + "::InputBufferConsumed()-return picture back to client" ) ); + + iMMFDevVideoRecordProxy->MdvrpReturnPicture( picture ); + } + else + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl" + "::InputBufferConsumed()-return picture back to Input Device" ) ); + iInputDevice->ReturnPicture( picture ); + } + + if ( iInputEndCalled && ( iEngine->NumInputBuffers() == 0 ) + && ( iCodec->IsCurrentPictureSkipped() ) ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriMp4spencHwDeviceImpl" + "::InputBufferConsumed()::Calling stream end " ) ); + + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return ( KErrNone ); + } + + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Callback to indicate the output buffer is ready +//--------------------------------------------------------------------------- +// + +TInt CAriMp4spencHwDeviceImpl::OutputBufferReady( TAny* aOup, TInt aError ) + { + PRINT_ENTRY; + + TVideoOutputBuffer *outputBuf = ( TVideoOutputBuffer* ) aOup; + TInt error = KErrNone; + if ( iFrozen ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::OutputBufferReady()" + "Frozen state, so drop output picture" ) ); + + outputBuf->iData.Set( ( TUint8* ) outputBuf->iData.Ptr(), + iOutputBufferSize ); + + iEngine->AddOutput( outputBuf ); + return KErrNone; + } + + if ( aError == KErrNone ) + { + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + error = iInternalOutputBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + // get the packet offset infor + TUint* ptr = iFreeBufferQueueForPacketOffsetInfo[0]; + iPacketOffsetBuf->Set( ( TUint8* ) ptr, iMaxNumOfPackets + * KDoubleWordLength, iMaxNumOfPackets * KDoubleWordLength); + + error = iCodec->GetParam( CONTROL_CMD_GET_PACKETBOUNDARYDATA, + iPacketOffsetBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + //remove the first element and add it to filled Queue + TUint* filledOffsetLengthInfoBuffer = + iFreeBufferQueueForPacketOffsetInfo[0]; + iFreeBufferQueueForPacketOffsetInfo.Remove( 0 ); + error = iFilledBufferQueueForPacketOffsetInfo.Append( + filledOffsetLengthInfoBuffer ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + if ( !iTotalLengthFilledSoFarInPacketMode ) + { + iTotalOutputBufferLengthInPacketMode + = iInternalOutputBufferQueue[0]->iData.Length(); + if ( iTotalOutputBufferLengthInPacketMode != 0 ) + { + iPacketOffSetCurrentPosition + = iFilledBufferQueueForPacketOffsetInfo[0]; + + iPacketsPending = ETrue; + while ( iOutputFreeBufferQueue.Count() + && iPacketsPending ) + { + TVideoOutputBuffer *outBuf + = iOutputFreeBufferQueue[0]; + + FillVideoSegment( outBuf, + iInternalOutputBufferQueue[0] ); + + iOutputFreeBufferQueue.Remove( 0 ); + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outBuf ); + } + } + else + { + iPacketsPending = EFalse; + + // remove packet offset info buffer from filled Q and + // add it to free Q + TUint* freeOffsetLengthInfoBuffer = + iFilledBufferQueueForPacketOffsetInfo[0]; + iFilledBufferQueueForPacketOffsetInfo.Remove( 0 ); + + TInt error = iFreeBufferQueueForPacketOffsetInfo .Append( + freeOffsetLengthInfoBuffer ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + + // Remove the internal buffer and add it back to process + // engine + if ( iInternalOutputBufferQueue.Count() ) + { + TVideoOutputBuffer* outBuf = + iInternalOutputBufferQueue[0]; + iInternalOutputBufferQueue.Remove( 0 ); + + outBuf->iData.Set( ( TUint8* )outBuf->iData.Ptr(), + iOutputBufferSize ); + + // Add the Buffer back to the Process Engine + if ( ( !iEncStateMac->IsInputEndPending() ) + && ( !iEncStateMac->IsStopped() ) ) + { + iEngine->AddOutput( ( TAny* )outBuf ); + } + } + } + } + } + else + { + // inform devvideo record that the new encoded buffer is avaibable + iMMFDevVideoRecordProxy->MdvrpNewBuffer( outputBuf ); + } + } + + else if ( aError == KErrCancel ) + { + // add the buffer back to outputQueue + outputBuf->iData.Set( ( TUint8* )outputBuf->iData.Ptr(), + iOutputBufferSize ); + + if ( iSetMpeg4H263HWParams.iDataUnitType == EDuVideoSegment ) + { + error = iInternalOutputBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + else + { + error = iOutputFreeBufferQueue.Append( outputBuf ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return KErrNone; + } + } + else + { + ClientFatalError( aError ); + return KErrNone; + } + + if ( iInputEndCalled && ( iEngine->NumInputBuffers() == 0 ) ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriMp4spencHwDeviceImpl" + "::OutputBufferReady()::Calling stream end " ) ); + Stop(); + iMMFDevVideoRecordProxy->MdvrpStreamEnd(); + return ( KErrNone ); + } + + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Callback to indicate the command has been processed +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::CommandProcessed( TInt aCmd, TAny* aCmdData, + TInt aError ) + { + PRINT_ENTRY; + + switch ( aCmd ) + { + case CONTROL_CMD_SET_RATE_CONTROL_OPTIONS: + { + TRateControlOptions *options = ( TRateControlOptions* ) aCmdData; + delete options; + } + break; + + case CONTROL_CMD_SET_FORCED_I_FRAME: + { + } + break; + + case CONTROL_CMD_SET_COMMIT_OPTIONS: + { + TMpeg4H263EncoderInitParams *currentParams = + ( TMpeg4H263EncoderInitParams* ) aCmdData; + + if ( ( aError != KErrNone ) || ( aError != KErrCancel ) ) + { + delete currentParams; + return; + } + else + { + iSetMpeg4H263HWParams.iBitErrors = currentParams->iBitErrors; + iSetMpeg4H263HWParams.iPacketLosses + = currentParams->iPacketLosses; + iSetMpeg4H263HWParams.iRandomAccessRate + = currentParams->iRandomAccessRate; + delete currentParams; + } + } + break; + + case CONTROL_CMD_SET_COMPLEXITY_LEVEL: + { + TMpeg4H263EncoderInitParams *currentParams = + ( TMpeg4H263EncoderInitParams* ) aCmdData; + delete currentParams; + } + break; + + case CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE: + { + TReal* currentParams = ( TReal* ) aCmdData; + delete currentParams; + } + break; + + case CONTROL_CMD_SET_SLICELOSS: + { + TMPEG4H263EncSliceLoss* currentParams = + ( TMPEG4H263EncSliceLoss* ) aCmdData; + delete currentParams; + } + break; + + default: + break; + } + PRINT_EXIT; + + return; + } + +//---------------------------------------------------------------------------- +// Called when a fatal error occurs in process engine +//---------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::FatalErrorFromProcessEngine( TInt aError ) + { + PRINT_ENTRY; + ClientFatalError( aError ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// 2 phase constructor +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::ConstructL() + { + PRINT_ENTRY; + + TInt index = 0; + TInt error = KErrNone; + + // Create Array of Supported Input Formats + TUncompressedVideoFormat inputFormat; + inputFormat.iDataFormat = EYuvRawData; + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range0; + inputFormat.iYuvFormat.iPattern = EYuv420Chroma1; + inputFormat.iYuvFormat.iDataLayout = EYuvDataPlanar; + inputFormat.iYuvFormat.iYuv2RgbMatrix = NULL; + inputFormat.iYuvFormat.iRgb2YuvMatrix = NULL; + inputFormat.iYuvFormat.iAspectRatioNum = 1; + inputFormat.iYuvFormat.iAspectRatioDenom = 1; + + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt601Range0; + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + inputFormat.iYuvFormat.iPattern = EYuv420Chroma2; + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range0; + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt709Range1; + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + inputFormat.iYuvFormat.iCoefficients = EYuvBt601Range1; + error = iSupportedInputFormats.Append( inputFormat ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + // Create Array of Supported Output Formats + CCompressedVideoFormat* compressedVideoFormat[18]; + + //Adding mime types for all supported MPEG4 levels. + compressedVideoFormat[index] + = CCompressedVideoFormat::NewL( KMPEG4MimeType ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + error = iLevels.Append( KMPEG4_LEVEL_UNKNOWN ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] + = CCompressedVideoFormat::NewL( KMPEG4VTMimeType ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_UNKNOWN ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel0 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_0 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel0B ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_0B ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel1 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_1 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel2 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_2 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel3 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_3 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel4 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_4 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel5 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_5 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel6 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_6 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KMPEG4MimeTypeLevel7 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_7 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + //Adding mime types for all supported H263 levels. + compressedVideoFormat[index] + = CCompressedVideoFormat::NewL( KH263MimeType ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_UNKNOWN ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeProfile0 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KMPEG4_LEVEL_7 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeLevel10 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_10 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeLevel20 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_20 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeLevel30 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_30 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeLevel40 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_40 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + compressedVideoFormat[index] = CCompressedVideoFormat::NewL( + KH263MimeTypeLevel45 ); + CleanupStack::PushL( compressedVideoFormat[index] ); + index++; + + error = iLevels.Append( KH263_LEVEL_45 ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + + //Append all the formats to the array + for ( TInt i = 0; i < index; i++ ) + { + error = iSupportedOutputFormats.Append( compressedVideoFormat[i] ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + } + + iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityIdle ); + iOutputFreeBufferQueue.Reset(); + iInternalOutputBufferQueue.Reset(); + iEncStateMac = CStateMachine::NewL(); + + // pop all the pushed items from cleanup stack. + CleanupStack::Pop( index ); + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Sends the updated time to the codec +//--------------------------------------------------------------------------- +// + +TInt CAriMp4spencHwDeviceImpl::UpdateTime() + { + PRINT_ENTRY; + + if ( !iClockSource ) + { + ClientFatalError( KErrBadHandle ); + return -1; + } + // send the time values to the codec + iCodec->SetUpdatedRefernceTime( iTotalTime ); + + PRINT_EXIT; + return 1; + } + +//--------------------------------------------------------------------------- +// Create the output buffers in Coded picture mode +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::CreateCodedOutputBuffersL( TUint aSize ) + { + PRINT_ENTRY; + + if ( iSetMpeg4H263HWParams.iDataUnitType != EDuVideoSegment ) + { + iOutputBufferSize = aSize; + } + + // Allocate memory for TVideoOutputBuffer + iOutputBuffers + = new ( ELeave ) TVideoOutputBuffer[ + iSetMpeg4H263HWParams.iMinNumOutputBuffers]; + + for ( TInt i = 0; i < iSetMpeg4H263HWParams.iMinNumOutputBuffers; i++ ) + { + iOutputBuffers[i].iData.Set( NULL, 0 ); + } + + // Create the Buffer and add it to Queue + for ( TInt i = 0; i < iSetMpeg4H263HWParams.iMinNumOutputBuffers; i++ ) + { + TUint8* ptr = new ( ELeave ) TUint8[aSize]; + CleanupStack::PushL( ptr ); + iOutputBuffers[i].iData.Set( ptr, aSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( iOutputBuffers[i] ); + TInt error = iOutputFreeBufferQueue.Append( iOutputBuffers + i ); + if ( error != KErrNone ) + { + User::Leave( error ); + return; + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Creates the temporary output buffers +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::CreateInternalOutputBuffersL( + TUint aBufferSize ) + { + PRINT_ENTRY; + + iOutputBufferSize = aBufferSize; + + // Allocate memory for TVideoOutputBuffer + iInternalOutputBuffers + = new ( ELeave ) TVideoOutputBuffer + [KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS]; + + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iInternalOutputBuffers[i].iData.Set( NULL, 0 ); + } + + // Create the Buffer and add it to Queue + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + TUint8* ptr = new ( ELeave ) TUint8[aBufferSize]; + CleanupStack::PushL( ptr ); + iInternalOutputBuffers[i].iData.Set( ptr, aBufferSize ); + CleanupStack::Pop(); + InitializeOuputCodedBuffer( iInternalOutputBuffers[i] ); + TInt error = iInternalOutputBufferQueue.Append( + iInternalOutputBuffers + i ); + + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Creates the buffers required to store length and offset +// info of packets +//--------------------------------------------------------------------------- +// + + +void CAriMp4spencHwDeviceImpl::CreatePacketOffsetLengthInfoBuffersL( + TUint aNumOfPackets ) + { + PRINT_ENTRY; + iPacketOffSetAndLengthInfoBuffers + = new ( ELeave ) (TUint*[KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS]); + + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iPacketOffSetAndLengthInfoBuffers[i] = NULL; + } + + for ( TInt i = 0; i < KMPEG4H263ENCIMPL_MAXNUM_TEMPOUTPUTBUFFERS; i++ ) + { + iPacketOffSetAndLengthInfoBuffers[i] + = ( TUint* ) ( new ( ELeave ) TUint8[aNumOfPackets] ); + TInt error = iFreeBufferQueueForPacketOffsetInfo.Append( + iPacketOffSetAndLengthInfoBuffers[i] ); + if ( error != KErrNone ) + { + User::Leave( error ); + } + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// decides whether picture can be encoded or not +//--------------------------------------------------------------------------- +// + +TBool CAriMp4spencHwDeviceImpl::CanEncode( TVideoPicture *aPicture ) + { + PRINT_ENTRY; + + // check with the lastly encoded picture and decide whether it can be + // processed or skipped + if ( aPicture->iTimestamp.Int64() < iLastEncodedPictureTimestamp ) + { + return EFalse; + } + + // check with current clock + if ( ( aPicture->iTimestamp.Int64() ) < ( ( iClockSource->Time().Int64() + - iTotalTime ) ) ) + { + return EFalse; + } + + PRINT_EXIT; + return ETrue; + } + +//--------------------------------------------------------------------------- +// Skips the Input Picture +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::SkipInputPicture( TVideoPicture *aPicture ) + { + PRINT_ENTRY; + + // add the buffer back to queue + if ( !iInputBufReturnToPreProc ) + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::SkipInputPicture()" + "-return picture back to client" ) ); + iMMFDevVideoRecordProxy->MdvrpReturnPicture( aPicture ); + } + else + { + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::SkipInputPicture()-" + "return picture back to Input Device" ) ); + iInputDevice->ReturnPicture( aPicture ); + } + + if ( !iFrozen ) + { + iPictureCounters.iPicturesSkippedRateControl++; + } + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Indicates whether the next frame is to be encoded as an I frame +//--------------------------------------------------------------------------- +// +TBool CAriMp4spencHwDeviceImpl::IsForcedIFrameRequired( + TVideoPicture* aPicture ) + { + PRINT_ENTRY; + + if ( ( aPicture->iOptions & TVideoPicture::EReqInstantRefresh ) + || iPictureLoss ) + { + PRINT_MSG( LEVEL_HIGH, ("CAriMp4spencHwDeviceImpl" + "::IsForcedIFrameRequired() ETrue 1--" ) ); + return ETrue; + } + + PRINT_EXIT; + return EFalse; + } + +//--------------------------------------------------------------------------- +// Extracts 1 packet from a frame and fills output buffer with the same +//--------------------------------------------------------------------------- +// +void CAriMp4spencHwDeviceImpl::FillVideoSegment( + TVideoOutputBuffer* aOutputBuf, TVideoOutputBuffer* aSrcOutputBuf ) + { + PRINT_ENTRY; + + TUint currentPacketLength = *( iPacketOffSetCurrentPosition ); + PRINT_MSG( LEVEL_LOW, ("CAriMp4spencHwDeviceImpl::FillVideoSegment()" + " currentPacketLength is %d", ( TInt )currentPacketLength ) ); + + if ( iTotalLengthFilledSoFarInPacketMode + < iTotalOutputBufferLengthInPacketMode ) + { + Mem::Copy( ( TUint8* ) ( aOutputBuf->iData.Ptr() ), + ( TUint8* ) ( aSrcOutputBuf->iData.Ptr() + + iTotalLengthFilledSoFarInPacketMode ), currentPacketLength ); + + aOutputBuf->iData.Set( aOutputBuf->iData.Ptr(), currentPacketLength ); + + iTotalLengthFilledSoFarInPacketMode + = iTotalLengthFilledSoFarInPacketMode + currentPacketLength; + + if ( iTotalLengthFilledSoFarInPacketMode + == iTotalOutputBufferLengthInPacketMode ) + { + iTotalLengthFilledSoFarInPacketMode = 0; + iPacketsPending = EFalse; + + // remove packet offset info buffer from filled Q and add it + // to free Q + TUint* freeOffsetLengthInfoBuffer = + iFilledBufferQueueForPacketOffsetInfo[0]; + iFilledBufferQueueForPacketOffsetInfo.Remove( 0 ); + TInt error = iFreeBufferQueueForPacketOffsetInfo.Append( + freeOffsetLengthInfoBuffer ); + if ( error != KErrNone ) + { + ClientFatalError( error ); + return; + } + + // Remove the internal buffer and add it back to process engine + if ( iInternalOutputBufferQueue.Count() ) + { + TVideoOutputBuffer* outBuf = iInternalOutputBufferQueue[0]; + iInternalOutputBufferQueue.Remove( 0 ); + outBuf->iData.Set( ( TUint8* )outBuf->iData.Ptr(), + iOutputBufferSize ); + + // Add the Buffer back to the Process Engine + if ( ( !iEncStateMac->IsInputEndPending() ) + && ( !iEncStateMac->IsStopped() ) ) + { + iEngine->AddOutput( ( TAny* )outBuf ); + } + } + + // Still more encoded packets are available + if ( iInternalOutputBufferQueue.Count() ) + { + iPacketsPending = ETrue; + iTotalOutputBufferLengthInPacketMode + = iInternalOutputBufferQueue[0]->iData.Length(); + + // Get the packet offset info buffer + // is this check required - will be valid always + if ( iFilledBufferQueueForPacketOffsetInfo.Count() ) + { + iPacketOffSetCurrentPosition + = iFilledBufferQueueForPacketOffsetInfo[0]; + } + } + } + else + { + ++iPacketOffSetCurrentPosition; + } + } + + // Update the specific members of the output buffer + aOutputBuf->iRequiredSeveralPictures + = aSrcOutputBuf->iRequiredSeveralPictures; + aOutputBuf->iRandomAccessPoint = aSrcOutputBuf->iRandomAccessPoint; + aOutputBuf->iCaptureTimestamp = aSrcOutputBuf->iCaptureTimestamp; + + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Initializes the members of the output coded buffers created +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::InitializeOuputCodedBuffer( + TVideoOutputBuffer& aOutputBuffer ) + { + PRINT_ENTRY; + aOutputBuffer.iOrderNumber = 0; + aOutputBuffer.iMinErrorProtectionLevel = 1; + aOutputBuffer.iMaxErrorProtectionLevel = 1; + aOutputBuffer.iRequiredThisPicture = EFalse; + aOutputBuffer.iLayer = 0; + aOutputBuffer.iInLayerScalabilityStep = 0; + aOutputBuffer.iDataPartitionNumber = 0; + aOutputBuffer.iHrdVbvParams.Set( NULL, 0 ); + aOutputBuffer.iCodingStandardSpecificData.Set( NULL, 0 ); + aOutputBuffer.iImplementationSpecificData.Set( NULL, 0 ); + + // The following members will be modified later during execution + aOutputBuffer.iRequiredSeveralPictures = EFalse; + aOutputBuffer.iRandomAccessPoint = EFalse; + aOutputBuffer.iCaptureTimestamp = 0; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Checks if the specified input format is supported or not +//--------------------------------------------------------------------------- +// + +TBool CAriMp4spencHwDeviceImpl::CheckInputFormat( + const TUncompressedVideoFormat& aFormat ) + { + PRINT_ENTRY; + + TInt i = 0; + for ( TInt i = 0; i < iSupportedInputFormats.Count(); i++ ) + { + TUncompressedVideoFormat inputFormat = iSupportedInputFormats[i]; + if ( inputFormat == aFormat ) + return ETrue; + } + PRINT_EXIT; + + return EFalse; + } + +//--------------------------------------------------------------------------- +// Nofities the client that the fatal error happend in Hw device +//--------------------------------------------------------------------------- +// + +void CAriMp4spencHwDeviceImpl::ClientFatalError( TInt aError ) + { + PRINT_ENTRY; + + PRINT_MSG( LEVEL_CRITICAL, ("CAriMp4spencHwDeviceImpl::ClientFatalError()" + " Error is %d", aError ) ); + if ( iClockSource ) + { + iPeriodicTimer->Cancel(); + } + + // Stop processing + if ( !iEncStateMac->IsStopped() ) + { + if ( iEncStateMac->IsInitialized() ) + { + Stop(); + } + } + iEncStateMac->Transit( CStateMachine::EDeadStateCommand ); + iMMFDevVideoRecordProxy->MdvrpFatalError( this, aError ); + + PRINT_EXIT; + } + +//---------------------------------------------------------------------------- +// The implementation table entry which indicates the 1st function +// to call when Mpeg4-h263 encoder hwdevice plugin is selected +//---------------------------------------------------------------------------- +// +const TImplementationProxy ImplementationTable[] = + { + { KUidMpeg4H263EncoderHwDeviceImplUid, + ( TProxyNewLPtr )( CAriMp4spencHwDeviceImpl::NewL ) } + }; + +//---------------------------------------------------------------------------- +// Returns the implementation table +//---------------------------------------------------------------------------- +// +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( + TInt& aTableCount ) +{ + aTableCount = sizeof( ImplementationTable ) / + sizeof( TImplementationProxy ); + return ImplementationTable; +} diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spencwrapper/export_hdr/aricommon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spencwrapper/export_hdr/aricommon.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Common header used by plugin, wrapper and codec. +*/ + +#ifndef ARICOMMON_H +#define ARICOMMON_H + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int int16; +typedef unsigned short int uint16; +typedef int int32; +typedef unsigned int uint32; + +typedef float flt32; +typedef double flt64; + +typedef unsigned char tBool; +typedef signed int tError; + + +enum {I_VOP, P_VOP, B_VOP, ACCESS_VOP, SKIP_VOP}; +enum {LOW, MEDIUM, HIGH, COMPLEX}; +enum {CBR, VBR, HQVBR}; +enum {H263,MPEG4}; + +#define E_TRUE 1 +#define E_FALSE 0 + +#define E_ON 1 +#define E_OFF 0 + +#define E_DEBUG 1 +#define E_RELEASE 0 + +#define E_SUCCESS 0 +#define E_FAILURE (-1) +#define E_OUT_OF_MEMORY (-2) +#define E_OUT_OF_RANGE (-3) +#define E_FILE_CREATE_FAIL (-4) +#define E_UNDEFINED_FLAG (-5) +#define E_FILE_READ_FAIL (-6) +#define E_FILE_OPEN_FAIL (-7) +#define E_END_OF_FILE (-8) +#define E_NOT_COMPLETE (-9) +#define E_OUTBUF_OVERFLOW (-10) +#define E_USER_ERROR_BASE (-1000) +#define mIsSuccess(code) ((code)>=0) +#define mIsFailure(code) ((code)<0) + +#if defined(__MARM_ARM4__) || defined(__MARM_ARMI__) || defined(__MARM_ARM5__) || defined(__MARM_ARMV5__) || defined(__MARM_ARMV6__) + + #ifndef USE_UNOPTIMIZED + #define ARM9TDMI_INLINE + #endif +#endif + +#endif // ARICOMMON_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spencwrapper/export_hdr/arimp4spencwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spencwrapper/export_hdr/arimp4spencwrapper.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Export header file for wrapper APIs.Interface class for +* Mpeg4SP/H263 encoder wrapper.The member functions are pure virtual functions +* which are to be implemented by the derived class. +* +*/ + + +#ifndef ARIMP4SPENCWRAPPER_H +#define ARIMP4SPENCWRAPPER_H + +// INCLUDES +#include +#include +#include +#include "aribasecodec.h" + + +// FORWARD DECLARATIONS +class MBaseCodecObserver; +class TMpeg4H263HWDeviceInitParams; +class TMpeg4H263EncoderInitParams; + + +class CAriMp4spencWrapper: public CBase, public MBaseCodec + { + + public:// Constructor and Destructor + + /** + * Two-phased constructor. + * @param aEncoderParams + * Encoder params used to create the encoder. + * @return pointer to an instance of CAriMp4spencWrapper + */ + IMPORT_C static CAriMp4spencWrapper* NewL(TMpeg4H263EncoderInitParams &aParams); + + /**> Destructor */ + virtual ~CAriMp4spencWrapper(); + + + public:// MBaseCodec functions + + /** + * From MBaseCodec + * Encodes an input buffer + * @param aInpBuf + * Coded input data passed by Engine. + * @param aOutBuf + * Encoded output data + * @leave "The method will leave if an error occurs". + * @return one of the TCodecState + */ + virtual TInt DoProcessL( TAny *aInpBuf, TAny* aOutBuf) = 0; + + /** + * From MBaseCodec + * Encodes an input buffer + * @param aCommand + * The command passed - indicates encoder parameter to be set. + * @param aOutBuf + * The value used to set the parameter. + * @leave "The method will leave if an error occurs". + * @return one of the TCodecState + */ + + virtual TInt SetParam( TInt aCommand, TAny* aCmdData ) = 0; + + /** + * Used to get codec parameteres + * @param aCommand + * Indicates the encoder parameter to get + * @param aCmdData + * The value of the encoder parameter (OUT) + * @return symbian wide error code + */ + virtual TInt GetParam (TInt aCommand, TAny* aCmdData) = 0; + + + /** + * Cancels all processing of the commands + * @return None + */ + virtual void Reset () = 0; + + + /** + * Sets the clocksource. + * @param aClockSource + * The clocksource which will be used by wrapper. + * @param aProcessingTime + * Not used currently. + * @return TInt KErrArgument if clocksource is NULL + * else returns KErrNone + */ + virtual TInt SetSyncOptions( TAny* aClockSource, + TInt aProcessingTime = 0 ) = 0; + + /** + * Sets the reference time to be used by wrapper. + * @param aReferenceTime + * The reference time passed by the plugin + * @return None + */ + + virtual void SetUpdatedRefernceTime( TInt64 &aReferenceTime ) = 0; + + /** + * Indicates whether current picture has been encoded or not. + * @return TBool ETrue if ppicture is skipped. + */ + + virtual TBool IsCurrentPictureSkipped() = 0; + + }; + +#endif //ARIMP4SPENCWRAPPER_H diff -r 000000000000 -r bb31fbe78861 mp4sp_enc/arimp4spencwrapper/export_hdr/arivideoenccommon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mp4sp_enc/arimp4spencwrapper/export_hdr/arivideoenccommon.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,230 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Defines the structures shared by HwDevice and wrapper +* +*/ + +#ifndef ARIVIDEOENCCOMMON_H +#define ARIVIDEOENCCOMMON_H + +//Includes +#include +#include +#include + +#define MAX_SCALABILITY_LAYERS 1 + +enum TSetCommands +{ + CONTROL_CMD_SET_BIT_RATE = 2051, + CONTROL_CMD_SET_FRAME_RATE, + CONTROL_CMD_SET_FORCED_I_FRAME, + CONTROL_CMD_SET_GOVLENGTH, + CONTROL_CMD_SET_CHANNEL_PACKET_LOSS_RATE, + CONTROL_CMD_SET_CHANNEL_BIT_ERROR_RATE, + CONTROL_CMD_SET_SEGMENT_TARGET_SIZE, + CONTROL_CMD_SET_RATE_CONTROL_OPTIONS, + CONTROL_CMD_SET_COMMIT_OPTIONS, + CONTROL_CMD_GET_CONFIG_HEADER, + CONTROL_CMD_SET_COMPLEXITY_LEVEL, + CONTROL_CMD_SET_SLICELOSS, + CONTROL_CMD_SET_PACKETSIZE +}; + +enum TGetCommands +{ + + CONTROL_CMD_GET_MAXBUFFERLENGTH = 3051, + CONTROL_CMD_GET_NUMOFPICTSKIPPED, + CONTROL_CMD_GET_MAXNUMOFPACKETS, + CONTROL_CMD_GET_NUMOFPACKETS, + CONTROL_CMD_GET_PACKETBOUNDARYDATA, + CONTROL_CMD_GET_PACKETSIZE, + CONTROL_CMD_GET_CONFIGDATA, + CONTROL_CMD_GET_CONFIGDATALENGTH +}; + + + +/* + * Enumeration covering SetInputFormatL, SetOutputFormatL, SetInputDevice, SetNumBitrateLayersL, + * SetScalabilityLayerTypeL, SetGlobalReferenceOptions, SetBufferOptionsL, SetMinRandomAccessRate + * SetSourceMemoryL of Hw Device. All these seven methods can be called only before + * Initialize. +*/ + +enum TOutputFormat + { + EH263 = 0x00000000, + EMpeg4 = 0x00000001, + }; + + +enum TPanicCodes + { + EPanicArgument=1, + EPanicInitializationPreCondViolation, + EPanicNotSupported, + EPanicNotPaused, + EPanicNotFreezed, + EPanicInvalidState, + EPanicAlreadyStopped + }; + +enum TEncBeforeInitialize + { + EEncBeforeInitNone = 0x00000000, + EEncInputFormat = 0x00000001, + EEncOutputFormat = 0x00000002, + EEncInputDevice = 0x00000004, + EEncNumBitrateLayers = 0x00000008, + EEncScalabilityLayer = 0x00000010, + EEncGlobalRefOptions = 0x00000020, + EEncBufferOptions = 0x00000040, + EEncRandomAccessRate = 0x00000080, + EEncSourceMemory = 0x00000100, + EEncInpBufferOptions = 0x00000200, + EEncErrorProtectionLevelFEC = 0x00000400, + EEncSegmentTargetSize = 0x00000800, + EEncCodingStandardSpecificOptions = 0x00001000, + EEncOutputRectSize = 0x00002000, + EEncErrorsExpected = 0x00004000, + EEncSourceCamera = 0x00008000, + EEncComplexityLevel = 0x00010000, + EEncLayerRefOptions = 0x00020000, + }; + +class TH264EncLayerReferenceOptions +{ +public: + TUint iMaxReferencePictures; + TUint iMaxPictureOrderDelay; + + TH264EncLayerReferenceOptions () : + iMaxReferencePictures (1), + iMaxPictureOrderDelay (0) + { + } +}; + +class TMpeg4H263EncoderInitParams + { +public: + // Specifies which parameters are being sent in the Initialize method + + TUint32 iBeforeInitialize; + TUint32 iAfterInitialize; + + TSize iPictureSize; + TInt iVopRate; + TInt iNumOfGOBHdrs; + TInt iGOVLength; + TInt iSceneCutDetection; + TInt iBandwidthAdaptation; + TInt iPreprocessing; + TInt iRCModel; + TInt iSearchRange; + TUint32 iTimerResolution; + TInt iPacketmode; + TInt iPacketSize; + TInt iReversibleVLC; + TInt iDataPartitioning; + TInt iMAPS; + + // For SetOutputFormatL + TOutputFormat iOutputFormat; + TVideoDataUnitType iDataUnitType; + TVideoDataUnitEncapsulation iDataEncapsulation; + TBool iSegmentationAllowed; + + // For SetSourceMemoryL + TReal iMaxPictureRate; + TBool iConstantPictureRate; + TBool iProcessRealtime; + + // For SetRamdomAccessRate + TReal iRandomAccessRate; + + // For SetErrorsExpected + TBool iBitErrors; + TBool iPacketLosses; + + // For SetMinRandomAccessRate + TInt iLevel; + + TUint iBitRate; + TReal iTargetPictureRate; + // complexity level + TUint iComplexityLevel; + + TUncompressedVideoFormat iInputFormat; + TInt32 iAspectRatio; + TUint iNumInputBuffers; + TSize iInputSize; + // For SetNumBitrateLayersL + TUint iNumBitRateLayers; + + // For SetScalabilityLayerTypeL + TUint iLayer; + TScalabilityType iScalabilityType; + TH264EncLayerReferenceOptions iLayerReferenceOptions[MAX_SCALABILITY_LAYERS]; + + // For SetBufferOptionsL + TUint iMaxPreEncoderBufferPictures; + THrdVbvSpecification iHrdVbvSpec; + T3gppHrdVbvParams iHrdVbvParams; + TUint iMaxOutputBufferSize; + TUint iMaxCodedPictureSize; + TUint iMaxCodedSegmentSize; + TUint iMinNumOutputBuffers; + TMPEG4VisualMode iCodingStandardSpecificOptions; + TRect iOutputRect; + + }; + +/* + * slice loss structure +*/ +class TMPEG4H263EncSliceLoss +{ +public: + TUint iFirstMacroblock; + TUint iNumMacroblocks; + + TMPEG4H263EncSliceLoss() : + iFirstMacroblock (0), + iNumMacroblocks (0) + { + } +}; + +/* + * Parameters used by the hw device which are sent to codec +*/ + + + + +class TPictureCountersInfo + { +public: + TUint iPicturesSkippedBufferOverflow; + TUint iPicturesSkippedProcPower; + TUint iPicturesSkippedRateControl; + TUint iPicturesProcessed; + TUint iInputPictures; + }; + +#endif //ARIVIDEOENCCOMMON_H diff -r 000000000000 -r bb31fbe78861 package_definition_2.0.1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_definition_2.0.1.xml Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/bwins/ariprocessengine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/bwins/ariprocessengine.def Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,3 @@ +EXPORTS + ?NewL@CBaseEngine@@SAPAV1@PAVMProcessEngineObserver@@PAVMBaseCodec@@HH@Z @ 1 NONAME ; class CBaseEngine * CBaseEngine::NewL(class MProcessEngineObserver *, class MBaseCodec *, int, int) + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/eabi/ariprocessengine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/eabi/ariprocessengine.def Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,3 @@ +EXPORTS + _ZN11CBaseEngine4NewLEP22MProcessEngineObserverP10MBaseCodecii @ 1 NONAME + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/group/ariprocessengine.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/group/ariprocessengine.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file of base process engine +* +*/ +#include + +TARGET ariprocessengine.dll +TARGETTYPE DLL + +UID 0x1000008D 0x2002AD88 + +CAPABILITY All -TCB +VENDORID 0x101FB657 + +DEFFILE ariprocessengine.def +NOSTRICTDEF + +MACRO LOGLEVEL_CRITICAL +SOURCEPATH ..\src +SOURCE ariprocessengine.cpp + +USERINCLUDE ..\inc +USERINCLUDE ..\..\log + +SYSTEMINCLUDE \epoc32\include + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib + + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for base process engine +* +*/ + +PRJ_PLATFORMS +armv5 winscw armv6 + +PRJ_MMPFILES +ariprocessengine.mmp + + + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/inc/aribasecodec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/inc/aribasecodec.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Declares interface class MBaseCodec whose pure virtual functions should be +* implemented by all video encoder/decoder wrappers +* +*/ + + +#ifndef ARIBASECODEC_H +#define ARIBASECODEC_H + +#include + +class MBaseCodec + { + public: + /** + * This enumeration should be used to indicate the result + * of a call to DoProcessL + */ + enum TCodecState { + EInputConsumed, + EOutputConsumed, + EConsumed, + ENotConsumed + }; + public: + + /** + * Processes an input buffer , returns one of the TCodecState + * @param aInpBuf + * Coded input data + * @param aOutBuf + * Decoded output data + * @leave The method will leave if an error occurs + * @return one of the TCodecState members + */ + virtual TInt DoProcessL( TAny *aInpBuf, TAny* aOutBuf = NULL ) = 0; + + /** + * Used to set codec parameteres + * @param aCommand + * Indicates the encoder parameter to set + * @param aCmdData + * The value to which the encoder parameter should be set + * @return symbian wide error code + */ + virtual TInt SetParam( TInt aCommand, TAny* aCmdData ) = 0; + + /** + * Used to get codec parameteres + * @param aCommand + * Indicates the encoder parameter to get + * @param aCmdData + * The value of the encoder parameter (OUT) + * @return symbian wide error code + */ + virtual TInt GetParam( TInt aCommand, TAny* aCmdData ) = 0; + + /** + * Cancels all processing of the commands + */ + virtual void Reset() = 0; + + }; + +#endif //ARIBASECODEC_H + + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/inc/aribaseengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/inc/aribaseengine.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,256 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Contains base class for process engine (CBaseEngine) and an abstract class +* (MProcessEngineObserver) which has callback methods to indicate events like +* completion of encoding, processing of a command etc. +* +*/ + + +#ifndef ARIBASEENGINE_H +#define ARIBASEENGINE_H + +#include +#include "aribasecodec.h" + +/** + * An abstract class which contains call back functions to be derived and + * implemented by any module wishing to use the process engine. + */ + +class MProcessEngineObserver + { + public: + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the input buffer is consumed + * @param aInp + * Pointer to the input picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + virtual TInt InputBufferConsumed( TAny* aInp, TInt aError ) = 0; + + /** + * From MProcessEngineObserver + * The function is a callback to indicate the output buffer is ready + * @param aOup + * Pointer to the output picture that has been processed + * @param aError + * Error code returned by process engine + * @return error value + */ + virtual TInt OutputBufferReady( TAny* aOup, TInt aError ) = 0; + + /** + * From MProcessEngineObserver + * The function indicates to hwdevice that process engine has finished + * with the processing of command requested by hwdevice + * @param aCmd + * Command that has been processed by process engine + * @param aCmdData + * Pointer to command data that has been processed by process engine + * @param aError + * Error code corresponding to the command + */ + virtual void CommandProcessed( TInt aCmd, TAny* aCmdData, + TInt aError ) = 0; + /** + * From CMMFVideoEncodeHwDevice + * The function indicates to hwdevice that process engine has met with + * an unrecoverable error during its processing + * @param aError + * The fatal error code + */ + virtual void FatalErrorFromProcessEngine( TInt aError ) = 0; + }; + + + /** + * Base class for base process engine. This calls creates class + * CAriH264encHwDeviceImpl which derives this class & provides + * implementation for pure virtual functions present in this class. + */ +class CBaseEngine + { + public: + + /** + * Enumeration to be used to set priority of an command + */ + enum TCmdPriority + { + ENormalPriority = 0, + EStandardPriority = 1, + EHighPriority = 2, + EVeryHighPriority = 3 + }; + + /** + * Two-phased constructor. + * @param aObserver + * Pointer to observer to the process engine - HwDevice + * @param aCodec + * Pointer to wrapper + * @param aInPlaceProcessing + * + * @param aProcessingAutomatic + * + * @return pointer to an instance of CBaseProcessEngine + */ + + IMPORT_C static CBaseEngine* NewL( MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic = ETrue ); + + /**> Destructor */ + virtual ~CBaseEngine () + { + } + + + public: + + /** + * Adds an input buffer to the Q + * @param aBuffer + * Pointer to an input buffer. + * @return symbian wide error code + */ + virtual TInt AddInput( TAny* aBuffer ) = 0; + + /** + * Adds an output buffer to the Q + * @param aBuffer + * Pointer to an output buffer. + * @return symbian wide error code + */ + virtual TInt AddOutput( TAny* aBuffer ) = 0; + + /** + * Starts the processing + * @return symbian wide error code, KErrNone on success + */ + virtual TInt Start() = 0; + + /** + * Stops the processing + * @return symbian wide error code, KErrNone on success + */ + virtual TInt Stop() = 0; + + /** + * Processes the commands + * @param aPriority + * Priority of the encode command object + */ + virtual void DoProcessL( TInt aPriority ) = 0; + + /** + * Adds a new command to the priority queue of commands + * @param aPriority + * Priority of the command object + * @param aCmd + * The command + * @param aCmdData + * Command specific data + */ + virtual void AddCommandL( TInt aPriority, TInt aCmd, TAny* aCmdData ) = 0; + + /** + * Resets the processing engine and flushes all the pending input and + * output buffers. + * Calls InputBufferConsumed and OutputBufferReady to give pending + * input & output buffers with aError = KErrCancel. + */ + virtual void Reset() = 0; + + /** + * Returns a output buffer back to the HwDevice + */ + virtual void ReturnOutputBuffers() = 0; + + /** + * Gets the number of input buffers + * @return returns the number of input buffers in process engine q + */ + virtual TInt NumInputBuffers() = 0; + + /** + * Gets the number of output buffers + * @return returns the number of output buffers in process engine q + */ + virtual TInt NumOutputBuffers() = 0; + + /** + * Returns whether processing of an input buffer is going on or else + * @return ETrue if processing in on going, else EFalse + */ + virtual TBool IsProcessing() = 0; + + /** + * Returns input buffer back to the HwDevice + */ + virtual void ReturnInputBuffers() = 0; + + /** + * Returns all the input pictures added previously. + */ + virtual void ReturnInput() = 0; + + public: + + /** + * Called by MBaseCodec when processing is complete + * @param aInpBuf + * The input buffer sent for processing + * @param aOutBuf + * The output buffer + * @param aState + * The result of processing + * @param aError + * Error value returned from DoProcessL + */ + virtual void ProcessingComplete( TAny *aInpBuf, TAny* aOutBuf, + MBaseCodec::TCodecState aState, TInt aError ) = 0; + + /** + * Called by MBaseCodec when processing of commmands is complete + * @param aCommand + * The command which has been processed + * @param aCmdData + * Command specific data + * @param aState + * The result of processing + * @param aError + * Result of processing command + */ + + virtual void ProcessingCommandComplete( TInt aCommand, TAny* aCmdData, + TInt aError ) = 0; + /** + * Returns the 1st buffer from the output buffer queue + * @return returns pointer to the fetched output buffer + */ + virtual TAny* FetchOutputBuffer() = 0; + }; + +#endif //ARIBASEENGINE_H + + + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/inc/ariprocessengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/inc/ariprocessengine.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Header file of process engine. Declares class CBaseProcessEngine +* which derives from CBaseEngine and provides implementation for +* all pure virtual functions +* +*/ +#ifndef ARIPROCESSENGINE_H +#define ARIPROCESSENGINE_H + +#include +#include "aribaseengine.h" +#include "ariprint.h" + +NONSHARABLE_CLASS (CCmdPckg): public CBase + { + public: + /** + * Enumeration to be used to specify command type. All commands should + * be of one of the 2 types given in this enumeration. + */ + enum TCmdType + { + /** + * All commands for encoding a buffer should be of this type + * @see CCmdPckg::CCmdPckg + * + */ + EDoProcess, + + /** + * Rest of the commands will be of this type + */ + EOther + }; + /** + * Default constructor.Assigns the parameteres to corresponding + * member variables. + * @param aCmdType + * The type of command (EDoProcess/EOther) + * @param aPriority + * The priority assigned to this command + * @param aCmd + * The command + * @param aCmdData + * Command specific data + */ + CCmdPckg ( TCmdType aCmdType, TInt aPriority, TInt aCmd = -1, + TAny* aCmdData = NULL ); + + /**> Destructor */ + ~CCmdPckg(); + public: + /** + * Command type which will be either one of - EDoProcess/EOther + */ + TCmdType iCmdType; + + /** + * The command. Any command which is not of type EDoProcess will be + * processed in the wrapper. + */ + TInt iCmd; + + /** + * Command specific data. + */ + TAny* iCmdData; + + /** + * The priority link to store the commands in a priority based doubly + * linked list. + */ + TPriQueLink iPriorityLink; + }; + +NONSHARABLE_CLASS ( CBaseProcessEngine ) : public CBaseEngine, + public CActive +{ + public: + + /** + * Enumeration to be used to specify the state of the process engine + */ + enum TState + { + EStart, + EStop + }; + + public: + /** + * Two-phased constructor. + * @param aObserver + * Pointer to observer to the process engine - HwDevice + * @param aCodec + * Pointer to wrapper + * @param aInPlaceProcessing + * + * @param aProcessingAutomatic + * + * @return pointer to an instance of CBaseProcessEngine + */ + static CBaseProcessEngine* NewL ( MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic = ETrue ); + /**> Destructor */ + virtual ~CBaseProcessEngine (); + + /** + * Default constructor + */ + CBaseProcessEngine(); + + public: + /** + * From CBaseEngine + * To add the input buffer to the Q + * @param aBuffer + * Pointer to an input buffer. + * @return symbian wide error code + */ + TInt AddInput( TAny* aBuffer); + + /** + * From CBaseEngine + * To add the output buffer to the Q + * @param aBuffer + * Pointer to an output buffer. + * @return symbian wide error code, KErrNone on success + */ + TInt AddOutput( TAny* aBuffer); + + /** + * From CBaseEngine + * Starts the processing + * @return symbian wide error code, KErrNone on success + */ + TInt Start(); + + /** + * From CBaseEngine + * Stops the processing + * @return symbian wide error code, KErrNone on success + */ + TInt Stop(); + + /** + * From CBaseEngine + * Processes the commands + * @param aPriority + * Priority of the encode command object + */ + void DoProcessL( TInt aPriority); + + /** + * From CBaseEngine + * Adds a new command to the priority queue of commands + * @param aPriority + * Priority of the command object + * @param aCmd + * The command + * @param aCmdData + * Command specific data + */ + void AddCommandL( TInt aPriority, TInt aCmd, TAny* aCmdData ); + + + /** + * From CBaseEngine + * Resets the processing engine and flushes all the pending input and + * output buffers. + * Calls InputBufferConsumed and OutputBufferReady to give pending + * input & output buffers with aError = KErrCancel. + */ + void Reset(); + + /** + * From CBaseEngine + * Returns a output buffer back to the HwDevice + */ + void ReturnOutputBuffers(); + + /** + * From CBaseEngine + * Gets the number of input buffers + * @return returns the number of input buffers in process engine q + */ + TInt NumInputBuffers(); + + /** + * From CBaseEngine + * Gets the number of output buffers + * @return returns the number of output buffers in process engine q + */ + TInt NumOutputBuffers(); + + /** + * From CBaseEngine + * Returns whether processing of an input buffer is going on or else + * @return ETrue if processing in on going, else EFalse + */ + TBool IsProcessing(); + + /** + * From CBaseEngine + * Returns input buffer back to the HwDevice through callback + */ + void ReturnInputBuffers(); + + /** + * From CBaseEngine + * Returns all the input pictures added previously through callback + */ + void ReturnInput(); + + + /** + * From CBaseEngine + * Returns the 1st buffer from the output buffer queue + * @return returns pointer to the fetched output buffer + */ + virtual TAny* FetchOutputBuffer(); + + public: + /** + * From CBaseEngine + * Called by MBaseCodec when processing is complete + * @param aInpBuf + * The input buffer sent for processing + * @param aOutBuf + * The output buffer + * @param aState + * The result of processing + * @param aError + * Error value returned from DoProcessL + */ + void ProcessingComplete( TAny *aInpBuf, TAny* aOutBuf, + MBaseCodec::TCodecState aState, + TInt aError ); + + /** + * From CBaseEngine + * Called by MBaseCodec when processing of commmands is complete + * @param aCommand + * The command which has been processed + * @param aCmdData + * Command specific data + * @param aState + * The result of processing + * @param aError + * Result of processing command + */ + void ProcessingCommandComplete( TInt aCommand, TAny* aCmdData, + TInt aError ); + + private: + + void RunL (); + + void DoCancel (); + + TInt RunError( TInt aError ); + + private: + + void IssueRequest (); + + void ConstructL( MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic ); + + TBool IsReadyForProcessing (); + + void ProcessNextCommand (); + + private: + + TPriQue iCmdArray; + RArray iInputArray; + RArray iOutputArray; + TState iState; + MProcessEngineObserver* iProcEngineObserver; + MBaseCodec* iCodec; + TBool iInPlaceProc; + TBool iAutomaticProc; + TAny* iCurInputBuf; + TAny* iCurOutputBuf; + CCmdPckg* iCurCmd; + TBool iIsProcessing; + TBool iOutputBufferReadyCallBackPending; + TInt iError; + + TInt iInputBufsAddedSoFar; + TInt iOutputBufsAddedSoFar; +}; + + +#endif //ARIPROCESSENGINE_H + + + diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/src/ariprocessengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/ariprocessengine/src/ariprocessengine.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,831 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Implementation of Base process engine +* +*/ +#include "ariprocessengine.h" +#include + +//--------------------------------------------------------------------------- +// Default constructor +//---------------------------------------------------------------------------- +// +CBaseProcessEngine::CBaseProcessEngine () + : CActive( CActive::EPriorityStandard ) + { + PRINT_ENTRY; + iState = EStop; + iCurInputBuf = NULL; + iCurOutputBuf = NULL; + + iCmdArray.SetOffset( _FOFF( CCmdPckg,iPriorityLink ) ); + + iProcEngineObserver = NULL; + iCodec = NULL; + iCurInputBuf = NULL; + iCurOutputBuf = NULL; + iCurCmd = NULL; + iIsProcessing = EFalse; + + iInputBufsAddedSoFar = 0; + iOutputBufsAddedSoFar = 0; + iOutputBufferReadyCallBackPending = EFalse; + + CActiveScheduler::Add( this ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// 2 - phase construtor of CBaseEngine +//---------------------------------------------------------------------------- +// +EXPORT_C CBaseEngine* CBaseEngine::NewL ( MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic ) + { + PRINT_ENTRY; + PRINT_EXIT; + return CBaseProcessEngine::NewL ( aObserver, aCodec, aInPlaceProcessing, + aProcessingAutomatic ); + } + +//--------------------------------------------------------------------------- +// 2 - phase construtor of CBaseProcessEngine +//---------------------------------------------------------------------------- +// +CBaseProcessEngine* CBaseProcessEngine::NewL ( + MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic ) + { + PRINT_ENTRY; + CBaseProcessEngine* uSelf = new ( ELeave ) CBaseProcessEngine; + CleanupStack::PushL( uSelf ); + uSelf->ConstructL( aObserver, aCodec, aInPlaceProcessing, + aProcessingAutomatic); + CleanupStack::Pop(); + PRINT_EXIT; + return uSelf; + } + +//--------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- +// + +CBaseProcessEngine::~CBaseProcessEngine () + { + PRINT_ENTRY; + Cancel(); + //Flushes out all buffers. + Reset(); + iInputArray.Close(); + iOutputArray.Close(); + iCmdArray.Reset(); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Second phase constructor +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::ConstructL ( MProcessEngineObserver* aObserver, + MBaseCodec* aCodec, + TBool aInPlaceProcessing, + TBool aProcessingAutomatic ) + { + PRINT_ENTRY; + iProcEngineObserver = aObserver; + iCodec = aCodec; + iInPlaceProc = aInPlaceProcessing; + iAutomaticProc = aProcessingAutomatic; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Starts the engine +//---------------------------------------------------------------------------- +// + +TInt CBaseProcessEngine::Start () + { + PRINT_ENTRY; + iState = EStart; + IssueRequest(); + return KErrNone; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Stops the engine +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::Stop () + { + PRINT_ENTRY; + Cancel(); + iState = EStop; + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Adds an input buffer to the input q +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::AddInput ( TAny* aInput ) + { + PRINT_ENTRY; + if( !aInput ) + { + return KErrArgument; + } + TInt lError = KErrNone; + lError = iInputArray.Append( aInput ); + if ( lError ) + { + return lError; + } + + iInputBufsAddedSoFar++; + + if( iAutomaticProc ) // true + { + CCmdPckg* lCmd = NULL; + TRAP( lError,lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EDoProcess, + ENormalPriority ) ); + if( lError ) + { + return lError; + } + iCmdArray.Add( *lCmd ); + } + // RunL should be scheduled in Start state. Also, if it is already + // processing i.e iIsProcessing is ETrue,RunL should not be scheduled + + if ( ( iState == EStart ) && !iIsProcessing ) + { + IssueRequest(); + } + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Adds a buffer to the output q +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::AddOutput ( TAny* aOutput ) + { + PRINT_ENTRY; + if( !aOutput ) + { + return KErrArgument; + } + else if( iInPlaceProc ) + { + return KErrNotSupported; + } + TInt lError = KErrNone; + lError = iOutputArray.Append( aOutput ); + if ( lError ) + { + return lError; + } + + iOutputBufsAddedSoFar++; + + // RunL should be scheduled in Start state. Also, if it is already + // processing i.e iIsProcessing is ETrue,RunL should not be scheduled + + if ( ( iState == EStart ) && !iIsProcessing ) + { + IssueRequest(); + } + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Resets the processing engine and flushes all the pending input +// and output buffers.Calls InputBufferConsumed and OutputBufferReady +// to give pending input & output buffers with aError = KErrCancel. +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::Reset () + { + PRINT_ENTRY; + Stop(); + + iCodec->Reset(); + + iIsProcessing = EFalse; + + if ( iCurInputBuf ) + { + TAny* lTempBuf = iCurInputBuf; + iCurInputBuf = NULL; + + delete iCurCmd; + iCurCmd = NULL; + + iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel ); + } + while ( iInputArray.Count() ) + { + TAny* lTempBuf = iInputArray[0]; + iInputArray.Remove( 0 ); + + delete iCurCmd; + iCurCmd = NULL; + + iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel ); + } + if ( iCurOutputBuf ) + { + TAny* lTempBuf = iCurOutputBuf; + iCurOutputBuf = NULL; + iProcEngineObserver->OutputBufferReady (lTempBuf, KErrCancel); + } + while ( iOutputArray.Count() ) + { + TAny* lTempBuf = iOutputArray[0]; + iOutputArray.Remove( 0 ); + iProcEngineObserver->OutputBufferReady( lTempBuf, KErrCancel ); + } + if ( iCurCmd ) + { + if ( iCurCmd->iCmdType != CCmdPckg::EDoProcess ) + { + iProcEngineObserver->CommandProcessed( iCurCmd->iCmd, + iCurCmd->iCmdData, KErrCancel ); + } + delete iCurCmd; + } + while ( !iCmdArray.IsEmpty() ) + { + CCmdPckg* lCurCmd = iCmdArray.First(); + lCurCmd->iPriorityLink.Deque(); + if ( lCurCmd->iCmdType != CCmdPckg::EDoProcess ) + { + iProcEngineObserver->CommandProcessed( lCurCmd->iCmd, + lCurCmd->iCmdData, KErrCancel ); + } + delete lCurCmd; + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns output buffers. +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::ReturnOutputBuffers () + { + PRINT_ENTRY; + while ( iOutputArray.Count() ) + { + iProcEngineObserver->OutputBufferReady( iOutputArray[0], KErrCancel ); + iOutputArray.Remove( 0 ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Returns input buffers +//---------------------------------------------------------------------------- +// + +void CBaseProcessEngine::ReturnInputBuffers () + { + PRINT_ENTRY; + + //Cancel any on-going processing + if( iIsProcessing ) + { + iCodec->Reset(); + iIsProcessing = EFalse; + } + + // return the current input buffer and delete the corresponding doprocessL + // command + if ( iCurInputBuf ) + { + TAny* lTempBuf = iCurInputBuf; + iCurInputBuf = NULL; + + delete iCurCmd; + iCurCmd = NULL; + + iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel ); + } + + //Since processing is canceled, output is not valid. + //So add the output buffer back to the queue for reuse + if( iCurOutputBuf ) + { + iOutputArray.Append ( iCurOutputBuf ); + iCurOutputBuf = NULL; + } + + RPointerArray lTempCmdArray; + + //Since all the input buffers are going to be returned, delete all + // DoProcess commands from the command array. + // Other commands should be put into the queue as it is. + + while( !iCmdArray.IsEmpty() ) + { + CCmdPckg* lCurCmd = iCmdArray.First(); + lCurCmd->iPriorityLink.Deque(); + + if ( lCurCmd->iCmdType == CCmdPckg::EDoProcess ) + { + delete lCurCmd; + } + else + { + // Store non-DoProcess commands in temporary array. And put them + // back in the iCmdArray after all the DoProcess commands are + // removed.Appending to the array to keep the order of commands + // intact. + lTempCmdArray.Append( lCurCmd ); + } + } + + while ( lTempCmdArray.Count() ) + { + iCmdArray.Add ( *( lTempCmdArray[0] ) ); + lTempCmdArray.Remove( 0 ); + } + + lTempCmdArray.Close(); + + //return all the input buffers + while ( iInputArray.Count() ) + { + TAny* lTempBuf = iInputArray[0]; + iInputArray.Remove( 0 ); + iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Processes the commands +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::DoProcessL( TInt aPriority ) + { + PRINT_ENTRY; + CCmdPckg* lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EDoProcess, + aPriority ); + iCmdArray.Add ( *lCmd ); + + // RunL should be scheduled in Start state. Also, if it is already + // processing i.e iIsProcessing is ETrue,RunL should not be scheduled + if ( iState == EStart || !iIsProcessing ) + { + IssueRequest(); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Adds a new command to the priority queue of commands +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::AddCommandL(TInt aPriority, TInt aCmd, + TAny* aCmdData ) + { + PRINT_ENTRY; + CCmdPckg* lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EOther, aPriority, + aCmd, aCmdData ); + iCmdArray.Add (*lCmd); + // RunL should be scheduled in Start state. Also, if it is already + // processing i.e iIsProcessing is ETrue,RunL should not be scheduled + + if ( iState == EStart || !iIsProcessing ) + { + IssueRequest(); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Called by MBaseCodec when processing is complete +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::ProcessingComplete( TAny *aInpBuf, TAny* aOutBuf, + MBaseCodec::TCodecState aState, TInt aError ) + { + PRINT_ENTRY; + TAny* lTempBuf = NULL; + + iError = aError; + if ( iCurInputBuf != aInpBuf ) + { + /*This should never happen*/ + User::Panic( _L ( "iCurInputBuf != aInpBuf" ) , 0 ); + + } + if ( iCurOutputBuf != aOutBuf ) + { + /*This should never happen*/ + User::Panic (_L("iCurOutputBuf != aOutBuf" ) , 1 ); + + } + if ( !iIsProcessing ) + { + /*This should never happen*/ + User::Panic (_L("!iIsProcessing " ) , 2 ); + + } + + // error returned by the DoProcessL must be handled here + if( aError ) + { + // call fatal error on hw device + iProcEngineObserver->FatalErrorFromProcessEngine( aError ); + return; + } + + if ( iState == EStart ) + { + IssueRequest(); + } + + if ( iInPlaceProc ) + { + switch ( aState ) + { + case MBaseCodec::EInputConsumed : + case MBaseCodec::EConsumed : + /*Callback should be the last statement*/ + iIsProcessing = EFalse; + lTempBuf = iCurInputBuf; + iCurInputBuf = NULL; + + delete iCurCmd; + iCurCmd = NULL; + + iProcEngineObserver->InputBufferConsumed( lTempBuf, iError ); + return; + + case MBaseCodec::EOutputConsumed : + case MBaseCodec::ENotConsumed : + default: + return; + } + } + else + { + switch ( aState ) + { + case MBaseCodec::EInputConsumed : + /*CallBack should be the last statement*/ + iIsProcessing = EFalse; + lTempBuf = iCurInputBuf; + iCurInputBuf = NULL; + + delete iCurCmd; + iCurCmd = NULL; + + iProcEngineObserver->InputBufferConsumed( lTempBuf, iError ); + return; + + case MBaseCodec::EConsumed : + /*CallBack should be the last statement*/ + lTempBuf = iCurInputBuf; + iCurInputBuf = NULL; + + delete iCurCmd; + iCurCmd = NULL; + + + iProcEngineObserver->InputBufferConsumed( lTempBuf, iError ); + lTempBuf = iCurOutputBuf; + iCurOutputBuf = NULL; + iProcEngineObserver->OutputBufferReady( lTempBuf, iError ); + + return; + + case MBaseCodec::EOutputConsumed : + /*CallBack should be the last statement*/ + iIsProcessing = EFalse; + lTempBuf = iCurOutputBuf; + iCurOutputBuf = NULL; + iProcEngineObserver->OutputBufferReady ( lTempBuf, iError ); + return; + case MBaseCodec::ENotConsumed : + default: + return; + } + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Called by MBaseCodec when processing of commmands is complete +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::ProcessingCommandComplete( TInt aCommand, + TAny* aCmdData, TInt aError ) + { + PRINT_ENTRY; + iIsProcessing = EFalse; + delete iCurCmd; + iCurCmd = NULL; + IssueRequest(); + iProcEngineObserver->CommandProcessed( aCommand, aCmdData, aError ); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Gets the number of input buffers +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::NumInputBuffers () + { + PRINT_ENTRY; + TInt lCnt = iInputArray.Count(); + if ( iCurInputBuf ) + { + lCnt = lCnt + 1; + } + PRINT_EXIT; + return lCnt; + } + +//--------------------------------------------------------------------------- +// Gets the number of output buffers +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::NumOutputBuffers () + { + PRINT_ENTRY; + TInt lCnt = iOutputArray.Count(); + if ( iCurOutputBuf ) + { + lCnt = lCnt + 1; + } + PRINT_EXIT; + return lCnt; + } + +//--------------------------------------------------------------------------- +// Runl() of CBaseProcessEngine. Scheduled whenever a new command needs to +// be processed +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::RunL () + { + PRINT_ENTRY; + /*If in stopped state, or it is already processing, don't do anything*/ + if ( iState == EStop || iIsProcessing ) + { + return; + } + + ProcessNextCommand(); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Processeses the next command in the queue +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::ProcessNextCommand() + { + PRINT_ENTRY; + if( iCurCmd || !iCmdArray.IsEmpty() ) + { + if( !iCurCmd ) + { + iCurCmd = iCmdArray.First(); + iCurCmd->iPriorityLink.Deque(); + } + + if( iCurCmd->iCmdType == CCmdPckg::EDoProcess ) + { + if( IsReadyForProcessing() ) + { + iIsProcessing = ETrue; + + TInt result = KErrNone; + + TRAPD( lError, result = iCodec->DoProcessL( iCurInputBuf, + iCurOutputBuf ) ); + + // based on the result call + ProcessingComplete( iCurInputBuf, iCurOutputBuf, + ( MBaseCodec::TCodecState )result, lError ); + + iIsProcessing = EFalse; + + IssueRequest (); + } + } + else + { + iIsProcessing = ETrue; + + TInt lError = iCodec->SetParam( iCurCmd->iCmd, + iCurCmd->iCmdData ); + + ProcessingCommandComplete( iCurCmd->iCmd, iCurCmd->iCmdData, + lError ); + + iIsProcessing = EFalse; + } + } + PRINT_EXIT; + } + + +//--------------------------------------------------------------------------- +// Indicates if process engine is ready for processing a new buffer i.e +// if process engine has both input and output buffers in its respective +// queues +//---------------------------------------------------------------------------- +// +TBool CBaseProcessEngine::IsReadyForProcessing() + { + PRINT_ENTRY; + if( !iCurInputBuf ) + { + if( iInputArray.Count() ) + { + iCurInputBuf = iInputArray[0]; + iInputArray.Remove( 0 ); + if ( iInPlaceProc ) + { + return ETrue; + } + } + else + { + return EFalse; + } + } + if ( !iCurOutputBuf ) + { + if ( iOutputArray.Count() ) + { + iCurOutputBuf = iOutputArray[0]; + iOutputArray.Remove( 0 ); + return ETrue; + } + return EFalse; + } + PRINT_EXIT; + return ETrue; + } +//--------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::DoCancel () + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Issue a new request for processing a command i.e schedule Runl() +//---------------------------------------------------------------------------- +// +void CBaseProcessEngine::IssueRequest () + { + PRINT_ENTRY; + if ( IsActive() ) + { + return; + } + + TRequestStatus* uStatus = &iStatus; + User::RequestComplete( uStatus, KErrNone ); + SetActive(); + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Indicates whether processing of an input buffer is going on or else +//---------------------------------------------------------------------------- +// +TBool CBaseProcessEngine::IsProcessing () + { + PRINT_ENTRY; + PRINT_EXIT; + return iIsProcessing; + } + +//--------------------------------------------------------------------------- +// This func is called if RunL leaves +//---------------------------------------------------------------------------- +// +TInt CBaseProcessEngine::RunError( TInt aError ) + { + PRINT_ENTRY; + iProcEngineObserver->FatalErrorFromProcessEngine( aError ); + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +// Constructor for CCmdPckg +//---------------------------------------------------------------------------- +// +CCmdPckg::CCmdPckg ( TCmdType aCmdType, TInt aPriority, TInt aCmd, + TAny* aCmdData ) + { + PRINT_ENTRY; + iCmdType = aCmdType; + iCmd = aCmd; + iCmdData = aCmdData; + iPriorityLink.iPriority = aPriority; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// Destructor for CCmdPckg +//---------------------------------------------------------------------------- +// +CCmdPckg::~CCmdPckg () + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// returns an Input picture back to the client +//---------------------------------------------------------------------------- +// + +void CBaseProcessEngine::ReturnInput() + { + PRINT_ENTRY; + TAny* lTempBuf = 0; + if ( iCurInputBuf ) + { + lTempBuf = iCurInputBuf; + delete iCurCmd; + iCurCmd = NULL; + } + else + { + if( iInputArray.Count() ) + { + lTempBuf = iInputArray[0]; + iInputArray.Remove( 0 ); + iCurCmd = iCmdArray.First(); + iCurCmd->iPriorityLink.Deque(); + delete iCurCmd; + iCurCmd = NULL; + } + } + // return input buffer back to the HwDevice and from there to the client + if( iProcEngineObserver && lTempBuf ) + { + iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel ); + } + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +// returns an output buffer back to the client +//---------------------------------------------------------------------------- +// +TAny* CBaseProcessEngine::FetchOutputBuffer() + { + PRINT_ENTRY; + TAny* lTempOutput=NULL; + lTempOutput=iCurOutputBuf; + + if ( !iOutputArray.Count() ) + { + iCurOutputBuf = NULL; + return lTempOutput; + } + TAny* uBuffer = iOutputArray[0]; + iOutputArray.Remove( 0 ); + + iCurOutputBuf = uBuffer; + PRINT_EXIT; + return lTempOutput; + + } diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/bwins/aristatemachine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/bwins/aristatemachine.def Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,16 @@ +EXPORTS + ?IsInDeadState@CStateMachine@@QAEHXZ @ 1 NONAME ; int CStateMachine::IsInDeadState(void) + ?IsPaused@CStateMachine@@QAEHXZ @ 2 NONAME ; int CStateMachine::IsPaused(void) + ?Reset@CStateMachine@@QAEXXZ @ 3 NONAME ; void CStateMachine::Reset(void) + ?IsInitializing@CStateMachine@@QAEHXZ @ 4 NONAME ; int CStateMachine::IsInitializing(void) + ?Transit@CStateMachine@@QAEHW4TCommand@1@@Z @ 5 NONAME ; int CStateMachine::Transit(enum CStateMachine::TCommand) + ?IsInInitializedState@CStateMachine@@QAEHXZ @ 6 NONAME ; int CStateMachine::IsInInitializedState(void) + ?IsInitialized@CStateMachine@@QAEHXZ @ 7 NONAME ; int CStateMachine::IsInitialized(void) + ?NewL@CStateMachine@@SAPAV1@XZ @ 8 NONAME ; class CStateMachine * CStateMachine::NewL(void) + ?IsTransitionValid@CStateMachine@@QAEHW4TCommand@1@@Z @ 9 NONAME ; int CStateMachine::IsTransitionValid(enum CStateMachine::TCommand) + ?IsStarted@CStateMachine@@QAEHXZ @ 10 NONAME ; int CStateMachine::IsStarted(void) + ?IfIsStateInInitailize@CStateMachine@@QAEHXZ @ 11 NONAME ; int CStateMachine::IfIsStateInInitailize(void) + ?IsPlaying@CStateMachine@@QAEHXZ @ 12 NONAME ; int CStateMachine::IsPlaying(void) + ?IsStopped@CStateMachine@@QAEHXZ @ 13 NONAME ; int CStateMachine::IsStopped(void) + ?IsInputEndPending@CStateMachine@@QAEHXZ @ 14 NONAME ; int CStateMachine::IsInputEndPending(void) + diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/eabi/aristatemachine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/eabi/aristatemachine.def Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,18 @@ +EXPORTS + _ZN13CStateMachine13IsInDeadStateEv @ 1 NONAME + _ZN13CStateMachine13IsInitializedEv @ 2 NONAME + _ZN13CStateMachine14IsInitializingEv @ 3 NONAME + _ZN13CStateMachine17IsInputEndPendingEv @ 4 NONAME + _ZN13CStateMachine17IsTransitionValidENS_8TCommandE @ 5 NONAME + _ZN13CStateMachine20IsInInitializedStateEv @ 6 NONAME + _ZN13CStateMachine21IfIsStateInInitailizeEv @ 7 NONAME + _ZN13CStateMachine4NewLEv @ 8 NONAME + _ZN13CStateMachine5ResetEv @ 9 NONAME + _ZN13CStateMachine7TransitENS_8TCommandE @ 10 NONAME + _ZN13CStateMachine8IsPausedEv @ 11 NONAME + _ZN13CStateMachine9IsPlayingEv @ 12 NONAME + _ZN13CStateMachine9IsStartedEv @ 13 NONAME + _ZN13CStateMachine9IsStoppedEv @ 14 NONAME + _ZTI13CStateMachine @ 15 NONAME + _ZTV13CStateMachine @ 16 NONAME + diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/group/aristatemachine.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/group/aristatemachine.mmp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Project file for state machine which is used by all video hwdevice plugins +* +*/ +#include + +TARGET aristatemachine.dll +TARGETTYPE DLL + +UID 0x1000008D 0x102749FE + +CAPABILITY ALL -TCB + +DEFFILE aristatemachine.def +NOSTRICTDEF + +MACRO LOGLEVEL_CRITICAL + +SOURCEPATH ..\src +SOURCE aristatemachine.cpp + +USERINCLUDE ..\inc +USERINCLUDE ..\..\log + +SYSTEMINCLUDE \epoc32\include + +MW_LAYER_SYSTEMINCLUDE +LIBRARY EUser.lib + + +//----------------------------------------------------------------------------- +// End of File +//----------------------------------------------------------------------------- + diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/group/bld.inf Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* Build file for state machine which is used by all video hwdevice plugins +* +*/ + +PRJ_PLATFORMS +winscw armv5 armv6 + +PRJ_MMPFILES +aristateMachine.mmp + +//----------------------------------------------------------------------------- +// End of BLD.INF +//----------------------------------------------------------------------------- \ No newline at end of file diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/inc/aristatemachine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/inc/aristatemachine.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* State machine for all video hwdevice plugins. +* +*/ + +#ifndef ARISTATEMACHINE_H +#define ARISTATEMACHINE_H + +#include + +#include "ariprint.h" + + +// Constants +const TUint KNumOfStates = 13; +const TUint KNumOfCommands = 8; + +class CStateMachine : public CBase +{ +public: + /** + * All the states of the state machine. + */ + enum TState + { + EUnInitialized = 0, + EInitializing, + EInitialized, + EStart, + EPause, + EStop, + EInitializedInStopping, + EStopping, + EPauseInStopping, + EStopInInputEnd, + EInitializedDeadState, + ENonInitializedDeadState, + EInvalidState + }; + /** + * Commands that are given to state machine + */ + enum TCommand + { + EInitializeCommand = 0 , + EInitializingCommand, + EStartCommand, + EPauseCommand, + EResumeCommand, + EInputEndCommand, + EStopCommand, + EDeadStateCommand + }; + +public: + + /** + *Constructor. State will be in EUnInitialized + * + *@param "None" + *@leave "None" + *@return "None" + */ + IMPORT_C static CStateMachine* NewL(); + + /** + *Checks whether transition to new state is possible or not + * + *@param "aCommand" "Command for the transition" + *@leave "None" + *@return "Return ETrue if transition is valid, else EFalse + */ + IMPORT_C TBool IsTransitionValid (TCommand aCommand); + + /** + *Transits to new state. If transition cann't be done, object will + *remain in the previous state. + * + *@param "aCommand" "Command for the transition" + *@return "Return KErrNone if transition happens else error. + */ + IMPORT_C TInt Transit (TCommand aCommand); + + /** + *Tells whether the state is initialized or not. Here initilized means + *if the state is in any state other than EUnInitialized + * + *@param "None" + *@return "Return ETrue, if state is initialized else EFalse. + */ + IMPORT_C TBool IsInitialized (); + + /** + *Tells whether the state is exactly in EInitialized state or not. + * + *@param "None" + *@return Return ETrue, if in EInitialized state else EFalse. + */ + IMPORT_C TBool IsInInitializedState (); + + /** + *Tells whether the state is in initializing state or not. + * + *@param "None" + *@return "Return ETrue, if state is initializing else EFalse. + */ + IMPORT_C TBool IsInitializing (); + + /** + *Tells whether the state is in any one of the input ending states i.e + * EInitializedInStopping, + * EStopping, + * EPauseInStopping, + * EStopInInputEnd + * + * + *@param None + *@return Return ETrue, if state is in any of inputend state else EFalse + */ + IMPORT_C TBool IsInputEndPending (); + + /** + *Tells whether state is in EStart state + * + *@param "None" + *@return "Return ETrue if state is EStart, elase EFalse + */ + IMPORT_C TBool IsStarted (); + + /** + *Tells whether state is in EPause state + * + *@param "None" + *@return "Return ETrue if state is EPause, elase EFalse + */ + IMPORT_C TBool IsPaused (); + + /** + *Tells whether state is in EStop state + * + *@param "None" + *@return "Return ETrue if state is EStop, elase EFalse + */ + IMPORT_C TBool IsStopped (); + + /** + *Tells whether state is in EPlaying state + * + *@param "None" + *@return "Return ETrue if state is EPlaying, elase EFalse + */ + IMPORT_C TBool IsPlaying (); + + /** + *Tells whether state is in EInitializedDeadState/ENonInitializedDeadState + *state + * + *@param "None" + *@return "Return ETrue if state is + * Return EInitializedDeadState/ENonInitializedDeadState, + * elase EFalse" + */ + IMPORT_C TBool IsInDeadState (); + + /** + *Resets the state machine to EUnInitialized state + * + *@param "None" + *@return "None" + */ + IMPORT_C void Reset(); + + /** + * Returns whether the current state is in initailize or not + * + *@return "ETrue if current state is in Initailize" + */ + IMPORT_C TBool IfIsStateInInitailize(); + + + /** + * Destructor of the statemachine + * + *@return "None" + */ + ~CStateMachine(); + +private: + + /** + *Symbian 2nd phase constructor + *@return "None" + */ + void ConstructL(); + + /** + *Default Constructor + */ + CStateMachine(); + +private: + //Stores the state of the state machine + TState iState; + + TState iStateChanges[KNumOfStates][KNumOfCommands]; +}; + +#endif // ARISTATEMACHINE_H + diff -r 000000000000 -r bb31fbe78861 utilities/aristatemachine/src/aristatemachine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/aristatemachine/src/aristatemachine.cpp Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,381 @@ + /* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* State machine for all video hwdevice plugins. +* +*/ + +//User includes +#include "aristatemachine.h" + +//--------------------------------------------------------------------------- +//Default Constrcutor. +//--------------------------------------------------------------------------- +// +CStateMachine::CStateMachine():iState( EUnInitialized ) + { + PRINT_ENTRY; + // Initailization + for ( TInt i = 0; i < KNumOfStates; i++ ) + { + for ( TInt j = 0; j < KNumOfCommands; j++ ) + { + iStateChanges [i][j] = EInvalidState; + } + } + + // set the valid transition states in the table + + // valid state changes from Uninitailize + iStateChanges [EUnInitialized][EInitializeCommand] = EInitialized; + iStateChanges [EUnInitialized][EInitializingCommand] = EInitializing; + iStateChanges [EUnInitialized][EDeadStateCommand] + = ENonInitializedDeadState; + + + // valid state changes from Initailize + iStateChanges [EInitialized][EStartCommand] = EStart; + iStateChanges [EInitialized][EPauseCommand] = EPause; + iStateChanges [EInitialized][EResumeCommand] = EStart; + iStateChanges [EInitialized][EInputEndCommand] = EInitializedInStopping; + iStateChanges [EInitialized][EStopCommand] = EStop; + iStateChanges [EInitialized][EDeadStateCommand] = EInitializedDeadState; + + iStateChanges [EInitializing][EDeadStateCommand] = EInitializedDeadState; + iStateChanges [EInitializing][EInitializeCommand] = EInitialized; + + // valid state changes from Start + iStateChanges [EStart][EStartCommand] = EStart; + iStateChanges [EStart][EPauseCommand] = EPause; + iStateChanges [EStart][EInputEndCommand] = EStopping; + iStateChanges [EStart][EStopCommand] = EStop; + iStateChanges [EStart][EDeadStateCommand] = ENonInitializedDeadState; + + // valid State changes from pause + iStateChanges [EPause][EPauseCommand] = EPause; + iStateChanges [EPause][EResumeCommand] = EStart; + iStateChanges [EPause][EInputEndCommand] = EPauseInStopping; + iStateChanges [EPause][EStopCommand] = EStop; + iStateChanges [EPause][EDeadStateCommand] = ENonInitializedDeadState; + + // valid state changes from Stop + iStateChanges [EStop][EStartCommand] = EStart; + iStateChanges [EStop][EInputEndCommand] = EStopInInputEnd; + iStateChanges [EStop][EStopCommand] = EStop; + iStateChanges [EStop][EDeadStateCommand]= ENonInitializedDeadState; + + // valid state changes from InitailizeInStopping + iStateChanges [EInitializedInStopping][EStartCommand] = EStopping; + iStateChanges [EInitializedInStopping][EDeadStateCommand] + = ENonInitializedDeadState; + + // valid State Changes from EStopping + iStateChanges [EStopping][EPauseCommand] = EPauseInStopping; + iStateChanges [EStopping][EStopCommand] = EStop; + iStateChanges [EStopping][EDeadStateCommand] = ENonInitializedDeadState; + + // valid state changes from PauseInStopping + iStateChanges [EPauseInStopping][EResumeCommand] = EStopping; + iStateChanges [EPauseInStopping][EStopCommand] = EStop; + iStateChanges [EPauseInStopping][EDeadStateCommand] + = ENonInitializedDeadState; + + // valid state changes frm StopInInputEnd + iStateChanges [EStopInInputEnd][EStartCommand] = EStopping; + iStateChanges [EStopInInputEnd][EStopCommand] = EStop; + iStateChanges [EStopInInputEnd][EDeadStateCommand] + = ENonInitializedDeadState; + } + +//--------------------------------------------------------------------------- +//Constrcutor. +//--------------------------------------------------------------------------- +// +EXPORT_C CStateMachine* CStateMachine::NewL() + { + PRINT_ENTRY; + CStateMachine* self = new ( ELeave ) CStateMachine(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + PRINT_EXIT; + return( self ); + } + +//--------------------------------------------------------------------------- +//Symbian 2nd Phase Constrcutor. +//--------------------------------------------------------------------------- +// +void CStateMachine::ConstructL() + { + PRINT_ENTRY; + PRINT_EXIT; + } + +//--------------------------------------------------------------------------- +//Checks whether transition to new state is possible or not. +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsTransitionValid( TCommand aCommand ) + { + PRINT_ENTRY; + + if ( iStateChanges[iState][aCommand] != EInvalidState ) + { + PRINT_EXIT; + return( ETrue ); + } + else + { + PRINT_EXIT; + return( EFalse ); + } + } + +//--------------------------------------------------------------------------- +//Transits to new state. If transition cann't be done, object will remain in +//the previous state. +//--------------------------------------------------------------------------- +// +EXPORT_C TInt CStateMachine::Transit( TCommand aCommand ) + { + PRINT_ENTRY; + if ( !IsTransitionValid ( aCommand ) ) + { + return KErrGeneral; + } + iState = iStateChanges[iState][aCommand]; + PRINT_EXIT; + return KErrNone; + } + +//--------------------------------------------------------------------------- +//Tells whether the state is initialized or not. Here initilized means if the +//state is in any state other than EUnInitialized +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsInitialized() + { + PRINT_ENTRY; + if ( iState != EUnInitialized ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether the state is exactly in EInitialized state or not. +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsInInitializedState() + { + PRINT_ENTRY; + if ( iState == EInitialized ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether the state is initializing or not. +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsInitializing() + { + PRINT_ENTRY; + if ( iState == EInitializing ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether the state is in any one of the input ending +//states i.e +//EInitializedInStopping, +//EStopping, +//EPauseInStopping, +//EStopInInputEnd +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsInputEndPending() + { + PRINT_ENTRY; + if ( iState == EInitializedInStopping || + iState == EStopping || + iState == EPauseInStopping || + iState == EStopInInputEnd ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether state is in EStart state +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsStarted() + { + PRINT_ENTRY; + if ( iState == EStart ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether stae is in EPlaying state +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsPlaying() + { + PRINT_ENTRY; + if ( iState == EStart || iState == EStopping ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether state is in EPause state +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsPaused() + { + PRINT_ENTRY; + if ( ( iState == EPause ) || ( iState == EPauseInStopping ) ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether stae is in EStop state +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsStopped() + { + PRINT_ENTRY; + if ( iState == EStop ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Tells whether stae is in EInitailize or not +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IfIsStateInInitailize() + { + PRINT_ENTRY; + if ( iState == EInitialized ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Resets the state machine to EUnInitialized state. +//--------------------------------------------------------------------------- +// +EXPORT_C void CStateMachine::Reset() + { + PRINT_ENTRY; + iState = EUnInitialized; + PRINT_EXIT; + } + + + +//--------------------------------------------------------------------------- +//Tells whether stae is in EDeadState state +//--------------------------------------------------------------------------- +// +EXPORT_C TBool CStateMachine::IsInDeadState() + { + PRINT_ENTRY; + if ( ( iState == EInitializedDeadState ) || + ( iState == ENonInitializedDeadState ) ) + { + PRINT_EXIT; + return ETrue; + } + else + { + PRINT_EXIT; + return EFalse; + } + } + +//--------------------------------------------------------------------------- +//Destructor for StateMachine +//--------------------------------------------------------------------------- +// +CStateMachine::~CStateMachine() + {} diff -r 000000000000 -r bb31fbe78861 utilities/log/ariprint.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/log/ariprint.h Fri Jul 23 16:58:44 2010 +0100 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2009 Aricent and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Aricent - initial contribution. +* +* Contributors: +* +* Description: +* This is a header file, which is required for +* enabling / disabling debug prints +* +*/ + + +#ifndef ARIPRINT_H__ +#define ARIPRINT_H__ + +#include + + +#define LEVEL_LOW 2 +#define LEVEL_HIGH 1 +#define LEVEL_CRITICAL 0 +#define LEVEL_NONE -1 + +#ifdef LOGLEVEL_LOW +#undef LOGLEVEL_HIGH +#undef LOGLEVEL_CRITICAL +#undef LOGLEVEL_NONE +#define PRINT(x, y) {if(x <= LEVEL_LOW) RDebug::Printf y;} +#endif + +#ifdef LOGLEVEL_HIGH +#undef LOGLEVEL_LOW +#undef LOGLEVEL_CRITICAL +#undef LOGLEVEL_NONE +#define PRINT(x, y) {if(x <= LEVEL_HIGH) RDebug::Printf y;} +#endif + +#ifdef LOGLEVEL_CRITICAL +#undef LOGLEVEL_HIGH +#undef LOGLEVEL_LOW +#undef LOGLEVEL_NONE +#define PRINT(x, y) {if(x <= LEVEL_CRITICAL) RDebug::Printf y;} +#endif + +#ifdef LOGLEVEL_NONE +#undef LOGLEVEL_HIGH +#undef LOGLEVEL_CRITICAL +#undef LOGLEVEL_LOW +#define PRINT(x, y) {;} +#endif + + +#define PRINT_ENTRY PRINT(LEVEL_LOW, ("--> %s", __PRETTY_FUNCTION__)) +#define PRINT_EXIT PRINT(LEVEL_LOW, ("<-- %s", __PRETTY_FUNCTION__)) +#define PRINT_ERR(y) PRINT(LEVEL_CRITICAL, ("ERROR: %s, Ln: %d, %s", __PRETTY_FUNCTION__, __LINE__, y)) +#define PRINT_MSG(x, y) PRINT(x, y) + + +#endif // ARIPRINT_H__