sl@0: // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #ifndef __MMFSWCODECWRAPPER_H__
sl@0: #define __MMFSWCODECWRAPPER_H__
sl@0: 
sl@0: #include <mmf/server/mmfhwdevice.h>
sl@0: #include <mmf/server/mmfhwdevicesetup.h>
sl@0: 
sl@0: class CMMFSwCodecDataPath; //forward reference
sl@0: 
sl@0: /** 
sl@0: @publishedAll
sl@0: @released
sl@0: 
sl@0: Class for a software codec used by the CMMFSwCodecWrapper class to make the CMMFSwCodec a 
sl@0: CMMFHwDevice plugin. The CMMFSwCodec processes source data in a certain fourCC coding type and
sl@0: converts it to a destination buffer of another fourCC coding type.
sl@0: 
sl@0: A CMMFSwCodec object would usually not be instantiated directly
sl@0: but instead would be instantiated via the CMMFSwCodecWrapper class's Codec()
sl@0: method.
sl@0: 
sl@0: The processing of the data is handled by the codecs ProcessL() member.
sl@0: The intention is that the source buffer for conversion is converted to the appropriate coding type
sl@0: in the destination buffer.  The size of the buffers passed in are determined by SourceBufferSize()
sl@0: and SinkBufferSize() methods.  The buffer sizes should be chosen such that
sl@0: the ProcessL() method can be guaranteed to have enough destination buffer to
sl@0: completely process one source buffer.
sl@0: 
sl@0: The ProcessL should return a TCodecProcessResult returning the number of source bytes processed
sl@0: and the number of destination bytes processed along with a process result code defined thus:
sl@0: - EProcessComplete: the codec processed all the source data into the sink buffer
sl@0: - EProcessIncomplete: the codec filled sink buffer before all the source buffer was processed
sl@0: - EDstNotFilled: the codec processed the source buffer but the sink buffer was not filled
sl@0: - EEndOfData: the codec detected the end data - all source data in processed but sink may not be full
sl@0: - EProcessError: the codec process error condition
sl@0: 
sl@0: Unlike the 7.0s CMMFCodec::ProcessL method, the CMMFSwCodec::ProcessL method
sl@0: should not return EProcessIncomplete as this case is not handled by the
sl@0: CMMFSwCodecWrapper.
sl@0: */
sl@0: class CMMFSwCodec : public CBase
sl@0: 	{
sl@0: public:
sl@0: 	/**
sl@0: 	@publishedAll
sl@0: 	@released
sl@0: 
sl@0: 	Indicates the result of processing data from the source buffer to a destination buffer
sl@0: 	and provides functions to compare the result code.
sl@0: 	The CMMFSwCodec buffer sizes should be set to return EProcessComplete
sl@0: 	The other return codes are to keep the ProcessL method compatible with
sl@0: 	the 7.0s CMMFCodec API.
sl@0: 	*/
sl@0: 	class TCodecProcessResult
sl@0: 		{
sl@0: 	public:
sl@0: 		/**
sl@0: 		Flag to track the codec's processing status.
sl@0: 		*/
sl@0: 		enum TCodecProcessResultStatus
sl@0: 			{
sl@0: 			/** The codec has successfully completed its processing. */
sl@0: 			EProcessComplete,
sl@0: 			/** Could not empty the source buffer because the destination buffer became full. */
sl@0: 			EProcessIncomplete,
sl@0: 			/** Codec came across an end of data. */
sl@0: 			EEndOfData,
sl@0: 			/** Could not fill the destination buffer because the source buffer has been emptied. */
sl@0: 			EDstNotFilled,
sl@0: 			/** An error occured. */
sl@0: 			EProcessError
sl@0: 			};
sl@0: 
sl@0: 		/** Overloaded operator to test equality. */
sl@0: 		TBool operator==(const TCodecProcessResultStatus aStatus) const {return (iCodecProcessStatus == aStatus);}
sl@0: 		/** Overloaded operator to test inequality. */
sl@0: 		TBool operator!=(const TCodecProcessResultStatus aStatus) const {return (iCodecProcessStatus != aStatus);}
sl@0: 
sl@0: 		/**
sl@0: 		Default constructor.
sl@0: 		*/
sl@0: 		TCodecProcessResult()
sl@0: 			:iCodecProcessStatus(EProcessError), iSrcBytesProcessed(0), iDstBytesAdded(0) {};
sl@0: 
sl@0: 		public:
sl@0: 		/**
sl@0: 		The codec's processing status
sl@0: 
sl@0: 		@see enum TCodecProcessResultStatus
sl@0: 		*/
sl@0: 		TCodecProcessResultStatus iCodecProcessStatus;
sl@0: 
sl@0: 		/** The number of source bytes processed */
sl@0: 		TUint iSrcBytesProcessed;
sl@0: 
sl@0: 		/** The number of bytes added to the destination buffer */
sl@0: 		TUint iDstBytesAdded;
sl@0: 		};
sl@0: public:
sl@0: 
sl@0: 	/**
sl@0: 	Processes the data in the specified source buffer and writes the processed data to
sl@0: 	the specified destination buffer.
sl@0: 
sl@0: 	This function is synchronous, when the function returns the data has been processed.
sl@0: 	This is a virtual function that each derived class must implement.
sl@0: 
sl@0: 	@param	aSource
sl@0: 			The source buffer containing data to encode or decode.
sl@0: 	@param	aDest
sl@0: 	 		The destination buffer to hold the data after encoding or decoding.
sl@0: 
sl@0: 	@return	The result of the processing.
sl@0: 
sl@0: 	@see    TCodecProcessResult
sl@0: 	*/
sl@0: 	virtual TCodecProcessResult ProcessL(const CMMFBuffer& aSource, CMMFBuffer& aDest) = 0;
sl@0: 
sl@0: 	/**
sl@0: 	Gets the max size of the source buffer passed into the
sl@0: 	CMMFSwCodec::ProcessL function. 
sl@0: 
sl@0: 	Note that this means that this is the Max size of each buffer passed to the codec.  The actual 
sl@0: 	size of the data could be less than the max size. This is a virtual function that each derived 
sl@0: 	class must implement.
sl@0: 
sl@0: 	@return The max size of the source buffer in bytes.
sl@0: 	*/
sl@0: 	virtual TUint SourceBufferSize() = 0;
sl@0: 
sl@0: 	/**
sl@0: 	Gets the max size of the sink (destination) buffer passed into the
sl@0: 	CMMFSwCodec::ProcessL method.  
sl@0: 
sl@0: 	Note that this means that this is the Max size of each buffer passed to the codec.  The actual 
sl@0: 	size of the data written to this buffer could be less than the max size. This is a virtual 
sl@0: 	function that each derived class must implement.
sl@0: 
sl@0: 	@return The max size of the sink buffer in bytes.
sl@0: 	*/
sl@0: 	virtual TUint SinkBufferSize() = 0;
sl@0: 
sl@0: 	/**
sl@0: 	@internalAll
sl@0: 
sl@0: 	Function that needs to be overriden if the codec is a 'Null' codec
sl@0: 	ie. it does not perform any data type transformation.  The 'Null' codec
sl@0: 	should override this to return ETrue and provide a dummy
sl@0: 	ProcessL. The CMMFSwCodecWrapper will then use the same buffer
sl@0: 	for both the source and the sink. Null codecs should return the same
sl@0: 	buffer size for both the Source and SinkBufferSize methods.
sl@0: 	Since most CMMFSwCodec implementations will not be null codecs
sl@0: 	this method can be ignored.
sl@0: 
sl@0: 	Would not normally expect 3rd parties to have to implement this.
sl@0: 	*/
sl@0: 	virtual TBool IsNullCodec() {return EFalse;};
sl@0: 	};
sl@0: 
sl@0: /** 
sl@0: @publishedAll
sl@0: @released
sl@0: 
sl@0: Class to make a CMMFSwCodec into a CMMFHwDevice ECOM plugin.
sl@0: 
sl@0: Most of the code to make a CMMFSwCodec into a CMMFHwDevice ECOM plugin is provided
sl@0: in CMMFSwCodecWrapper.  Someone writing a plugin derrived from CMMFSwCodecWrapper
sl@0: only needs to provide the standard ECOM implementation code, constructors
sl@0: and destructors and implement the Codec() function which should return the
sl@0: appropriate CMMFSwCodec.
sl@0: 
sl@0: Third parties using CMMFSwCodecWrapper that do not use the RMdaDevSound API
sl@0: to talk to the sound drivers would need to port the datapaths for their own
sl@0: sound drivers. Third parties would also need to change the custom interfaces
sl@0: where necessary.
sl@0: */
sl@0: class CMMFSwCodecWrapper : public CMMFHwDevice
sl@0: 	{
sl@0: public:
sl@0: 	IMPORT_C virtual ~CMMFSwCodecWrapper();
sl@0: protected:
sl@0: 	IMPORT_C CMMFSwCodecWrapper();
sl@0: 	IMPORT_C virtual TInt Init(THwDeviceInitParams &aDevInfo);
sl@0: 	IMPORT_C virtual TInt Start(TDeviceFunc aFuncCmd, TDeviceFlow aFlowCmd);
sl@0: 	IMPORT_C virtual TInt Stop();
sl@0: 	IMPORT_C virtual TInt Pause();
sl@0: 	IMPORT_C virtual TAny* CustomInterface(TUid aInterfaceId);
sl@0: 	IMPORT_C virtual TInt ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr);
sl@0: 	IMPORT_C virtual TInt ThisHwBufferEmptied(CMMFBuffer& aBuffer);
sl@0: 	IMPORT_C virtual TInt SetConfig(TTaskConfig& aConfig);
sl@0: 	IMPORT_C virtual TInt StopAndDeleteCodec();
sl@0: 	IMPORT_C virtual TInt DeleteCodec();
sl@0: 	/**
sl@0: 	This method must return the CMMFSwCodec used by the derived
sl@0: 	CMMFSwCodecWrapper class.  The method should create the CMMFSwCodec
sl@0: 	if it hasn't done so already.
sl@0: 
sl@0: 	This is a virtual function that each derived class must implement.
sl@0: 
sl@0: 	@return The CMMFSwCodec used by the derrived CMMFSwCodecWrapper
sl@0: 	*/
sl@0: 	virtual CMMFSwCodec& Codec() = 0;
sl@0: 	IMPORT_C void SetVbrFlag();
sl@0: private:
sl@0: 	TInt StartEncode();
sl@0: 	TInt StartDecode();
sl@0: 	TInt StartConvert();
sl@0: 	
sl@0: protected: 
sl@0: 	/** 
sl@0: 	The software codec used
sl@0: 	*/
sl@0: 	CMMFSwCodec* iCodec;
sl@0: 	
sl@0: 	/** 
sl@0: 	The source buffer for the codec
sl@0: 	*/
sl@0: 	CMMFDataBuffer* iSourceBuffer;
sl@0: 	
sl@0: 	/** 
sl@0: 	The sink buffer for the codec
sl@0: 	*/
sl@0: 	CMMFDataBuffer* iSinkBuffer;
sl@0: 	
sl@0: 	/** 
sl@0: 	The datapath used to transfer the data
sl@0: 	*/
sl@0: 	CMMFSwCodecDataPath* iDataPath;
sl@0: 	
sl@0: 	/** 
sl@0: 	The play custom interface
sl@0: 	*/
sl@0: 	MPlayCustomInterface* iPlayCustomInterface;
sl@0: 	
sl@0: 	/** 
sl@0: 	The record custom interface
sl@0: 	*/
sl@0: 	MRecordCustomInterface* iRecordCustomInterface;
sl@0: 	
sl@0: 	/** 
sl@0: 	The buffer size of the sound device
sl@0: 	*/
sl@0: 	TUint iDeviceBufferSize;
sl@0: 	
sl@0: 	/**
sl@0: 	The sample rate of the sound device
sl@0: 	*/
sl@0: 	TInt iSampleRate;
sl@0: 
sl@0: 	/**
sl@0: 	The number of channels of the sound device
sl@0: 	*/
sl@0: 	TInt iChannels;
sl@0: 	};
sl@0: 
sl@0: #endif
sl@0: