mp4sp_enc/arimp4spenchwdevice/src/arimp4spenchwdeviceimpl.cpp
changeset 0 bb31fbe78861
--- /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 <E32base.h>
+#include <AVC.h>
+#include <H263.h>
+#include <Implementationproxy.h>
+
+//---------------------------------------------------------------------------
+//  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<TPictureRateAndSize> 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<TUint>& /*aBitrateShare*/,
+		const TArray<TUint>& /*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<TPictureId>& /*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<TUncompressedVideoFormat> inputFormats;
+	CleanupClosePushL( inputFormats );
+	cleanupStackPushCount++;
+	inputFormats.Reset();
+
+	RArray<TUncompressedVideoFormat> outputFormats;
+	CleanupClosePushL( outputFormats );
+	cleanupStackPushCount++;
+	outputFormats.Reset();
+
+	RArray<TUint32> supportedCombinations;
+	CleanupClosePushL( supportedCombinations );
+	cleanupStackPushCount++;
+	supportedCombinations.Reset();
+
+	RArray<TScaleFactor> 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;
+}