epoc32/include/mmf/server/mmfdatapath.h
branchSymbian2
changeset 2 2fe1408b6811
child 4 837f303aceeb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/epoc32/include/mmf/server/mmfdatapath.h	Tue Mar 16 16:12:26 2010 +0000
@@ -0,0 +1,482 @@
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// source\server\mmfdatapath.h
+// 
+//
+
+#ifndef MMFDATAPATH_H
+#define MMFDATAPATH_H
+
+#include <mmf/common/mmfcontroller.h>
+#include <mmf/server/mmfdatasource.h>
+#include <mmf/server/mmfdatasink.h>
+#include <mmf/server/mmfcodec.h>
+#include <mmf/server/mmfnullcodec.h>
+#include <mmf/server/mmfbuffer.h>
+#include <mmf/common/mmfutilities.h>
+#include <mmf/server/mmfformat.h>
+#include "mmfsubthreadbase.h"
+
+/**
+ * @publishedAll
+ * @deprecated
+ *
+ * Datapath general error code used when sending events to clients
+ */
+const TUid KMMFErrorCategoryDataPathGeneralError = {0x101F76DC};
+
+
+
+/**
+@publishedAll
+@deprecated
+
+Abstract utility class that moves data from a single data source to a single data sink, via a codec if required.
+
+All functions are exported form the DLL and are virtual to allow plugins to define their own data paths.
+*/
+class CMMFDataPath : public CActive,
+					 public MDataSink,
+					 public MDataSource, 
+					 public MAsyncEventHandler
+	{ 
+public:
+
+	//CMMFDataPath constructor if codec Uid is not already known by CMMFController
+	//and there is no data path ambiguity - ie only one data path is possible
+	IMPORT_C static CMMFDataPath* NewL(MAsyncEventHandler& aEventHandler); 
+
+	//CMMFDataPath constructor if codec Uid is not already known by CMMFController
+	//and there is ambiguity ie more than one possible data path TMediaId used to select path 
+	IMPORT_C static CMMFDataPath* NewL(TMediaId aMediaId, MAsyncEventHandler& aEventHandler); 
+
+	//CMMFDataPath constructor if codec Uid is already known by CMMFController
+	//and there is no data path ambiguity - ie only one data path is possible
+	IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler); 
+
+	//CMMFDataPath constructor if codec Uid is already known by CMMFController
+	//and there is ambiguity ie more than one possible data path TMediaId used to select path 
+	IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
+
+	IMPORT_C virtual ~CMMFDataPath();
+
+	// Called when source and sink needs to be de-referenced
+	IMPORT_C virtual void ResetL();
+
+	//from MDataSink - CMMFData path is a sink to its MDataSource
+	IMPORT_C virtual void EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId); //only required for an active push MDataSource requesting a buffer empty - not implemented
+	IMPORT_C virtual void BufferFilledL(CMMFBuffer* aBuffer); //called by the CMMFDataPath's MDataSource when it has filled the buffer
+	IMPORT_C virtual TBool CanCreateSinkBuffer(); //from both MDataSource & MDataSink?
+	IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
+	IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
+
+	IMPORT_C virtual TFourCC SinkDataTypeCode(TMediaId aMediaId);
+
+	//from MDataSource
+	IMPORT_C virtual void FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId aMediaId); //only required for an active pull MDataSink requesting buffer fill - not implementated
+	IMPORT_C virtual void BufferEmptiedL(CMMFBuffer* aBuffer);//called by the CMMFDataPath's MDataSink when it has emptied the buffer
+	IMPORT_C virtual TBool CanCreateSourceBuffer(); //from both MDataSource & MDataSink?
+	IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
+	IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
+	IMPORT_C virtual TFourCC SourceDataTypeCode(TMediaId aMediaId);
+
+	IMPORT_C virtual void AddDataSourceL(MDataSource* aSource);
+	IMPORT_C virtual void AddDataSinkL(MDataSink* aSink);
+
+	//could derive these from a mixin eg MMMFControle later for active MDataSource/Sinks
+	IMPORT_C virtual void PrimeL();
+	IMPORT_C virtual void PlayL();
+	IMPORT_C virtual void Pause();
+	IMPORT_C virtual void Stop();
+
+	IMPORT_C virtual TTimeIntervalMicroSeconds Position() const;
+	IMPORT_C virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
+
+	// Play Window.
+	IMPORT_C virtual void SetPlayWindowL( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd ) ;
+	IMPORT_C virtual void ClearPlayWindowL() ;
+
+	//State
+	IMPORT_C virtual TInt State();
+
+	//CActive implementations
+	IMPORT_C void RunL();
+	IMPORT_C void DoCancel();
+	IMPORT_C TInt RunError(TInt aError);
+
+	//error handling
+	IMPORT_C TInt DoSendEventToClient(TUid aEventType, TInt aErrorCode);
+
+	IMPORT_C TInt SetBlockLength(TUint aBlockLength);
+	/**
+	
+	Indicates the state of the data path.
+
+	Mimics typical MultiMedia behaviour of stopped, primed and playing
+	*/
+	enum TDataPathState
+		{
+		/** Stopped.
+		*/
+		EStopped,
+		/** Primed.
+		*/
+		EPrimed,
+		/** Playing.
+		*/
+		EPlaying,
+		/** Recording.
+		*/
+		ERecording,
+		/** Converting.
+		*/
+		EConverting
+		};
+
+	/**
+	@internalComponent
+	*/
+	class CCompleteCallback : public CActive
+		{
+	public:
+		CCompleteCallback(CMMFDataPath& aDataPath, TBool aWaitForSink);
+		~CCompleteCallback();
+
+		void SignalDataPathComplete(TInt aDataPathError);
+		void SignalSinkComplete(TInt aSinkError);
+		TRequestStatus& ActiveStatus();
+
+		void DoCancel();
+	private:
+		void RunL();
+		CMMFDataPath& iDataPath;
+		TBool iDataPathComplete;
+		TBool iSinkComplete;
+		TBool iWaitForSink;
+
+		TInt iSinkError;
+		TInt iDataPathError;
+		};
+	friend class CCompleteCallback;
+	friend class CMMFDataPath2;
+protected:
+
+	/**
+	Indicates the transfer state.
+	
+	Buffers maybe be filled, emptied, or have "one" shot initialisatings performed upon them.
+	
+	TTransferState is used within the datapath RunL which drives databuffer exchange.
+	*/
+	enum TTransferState
+		{
+		/** Waiting on a BufferEmptied callback from sink
+		*/
+		EWaitSink,
+		/** Waiting on a BufferFilled callback from source
+		*/
+		EWaitSource,
+		/** Initialize the sink.
+		*/
+		EInitializeSink,
+		/** Initialize the source.
+		*/
+		EInitializeSource,
+		/** Source buffer does not contain data.
+		*/
+		ENeedSourceData,
+		/** Sink buffer does not contain data.
+		*/
+		ENeedSinkData,
+		/** There is more source data to send to the sink and need to match sink and source.
+		*/
+		ENeedToMatchSourceToSink,
+		/** Outstanding data to send to sink.
+		*/
+		ESendDataToSink,
+		/** End of data.
+		*/
+		EEndOfData //indicates that the datapath has transferred all the data to the sink
+		};
+
+
+
+
+protected:
+	CMMFDataPath(TMediaId aMediaId, MAsyncEventHandler& aEventHandler) : 
+		CActive(EPriorityStandard), MDataSink(KUidMmfDataPath), MDataSource(KUidMmfDataPath),
+		iEventHandler(aEventHandler), iMediaId(aMediaId), iState(EStopped) 
+			{CActiveScheduler::Add(this);};
+
+	IMPORT_C void ConstructL(TUid aCodecUid = KNullUid);
+	IMPORT_C virtual void ConstructSourceL( const TDesC8& aInitData ) ;
+	IMPORT_C virtual void ConstructSinkL( const TDesC8& aInitData ) ;
+	IMPORT_C virtual void EndOfData();
+
+	//These methods use API on DevSound to determine how many samples have been played/recorded
+	//and thereby determine the real position.
+	TTimeIntervalMicroSeconds CalculateAudioOutputPosition() const;
+	TTimeIntervalMicroSeconds CalculateAudioInputPosition() const;
+
+	//These methods determine the position of either the input or the output.
+	//The position may come from a format or from an audio input/output depending on 
+	//the operation the datapath is doing (Playing (output), Recording & Converting (input))
+	TTimeIntervalMicroSeconds OutputPosition() const;
+	TTimeIntervalMicroSeconds InputPosition() const;
+
+
+	//Determines what buffers are required (see TNeedBuffer)
+	//May leave KErrNotSupported if source/sinks can't supply the necessary buffers
+	TInt DetermineBuffersToUseL(void) const; 
+
+	//Determines how many samples have been played by DevSound
+	TInt AudioSamplesPlayed() const;
+
+	//Determines how many samples have been recorded by DevSound
+	TInt AudioSamplesRecorded() const;
+
+
+private:
+	void ChangeDataPathTransferState(TTransferState aNewDataPathTransferState);
+	void CreateDataPathL(MDataSource* aSource, MDataSink* aSink);
+	
+	void InitializeSinkL();
+	void InitializeSourceL();
+	void FillSourceBufferL();
+	void FillSinkBufferL();
+	void EmptySinkBufferL();
+	void DoCleanupBuffers();
+	void ObtainSyncBuffersL(); //tries to obtain synchronous data buffers from src/snk
+
+	TTimeIntervalMicroSeconds Duration() const;
+
+	void DoStopL();
+	void DoPauseL();
+	void DoEndOfDataL();
+
+	IMPORT_C TInt SendEventToClient(const TMMFEvent& aEvent);
+
+	void SetBuffersAvailable();
+	void ResetRefBuffers();
+
+	
+
+protected:
+	/**
+    Event handler.
+	*/
+	MAsyncEventHandler& iEventHandler;
+
+	/** 
+	The source of data to which the CMMFDataPath is a MDataSink for.
+	*/
+	MDataSource* iDataSource;
+	/** 
+	The sink of data for which the CMMFDataPath is a MDataSource for
+	*/
+	MDataSink* iDataSink;
+	/** 
+	Set to true when the sink is able to accept data. EFalse otherwise.
+	*/
+	TBool iSinkCanReceive;
+	/**
+	The sink's data type. Same as the codec input data type.
+	*/
+	TFourCC iSinkFourCC;
+	/** 
+	The source's data type. Same as the codec output data type.
+	*/
+	TFourCC iSourceFourCC;
+	/** 
+	Identifies which media type and stream within MDataSource.
+	*/
+	TMediaId iMediaId;
+	/** 
+	Codec in use. Null Codec is signified by == NULL
+	*/
+	CMMFCodec* iCodec;
+
+	/**
+    Result of processing the codec.
+	*/
+	TCodecProcessResult iCodecProcessResult;
+
+	/**
+	Set to ETrue when the data path has a source and a sink and can send data from the source to the sink.
+	*/
+	TBool iDataPathCreated;
+	
+	/**
+	Current data path state. 
+	@see TDataPathState	
+	*/
+	TDataPathState iState;
+
+	/**
+    Current transfer state.
+	@see TTransferState
+	*/
+	TTransferState iTransferState;
+
+	/**
+	Set to true if data path has to use a supplied codec in its construction.
+	*/
+	TBool iUseSuppliedCodecUid;
+
+	/** 
+	This is set to point to whichever sink buffer is in use.
+	*/
+	CMMFBuffer* iSinkBuffer;
+
+	/**
+	This is the pointer to whichever source buffer is in use
+	*/
+	CMMFBuffer* iSourceBuffer;
+
+	/**
+	The source's position in terms of frames or some other time fixed parameter.
+	*/
+	TUint iCurrentSourceFrameNumber;
+
+	/**
+	The sink's position in terms of frames or some other time fixed parameter.
+	*/
+	TUint iCurrentSinkFrameNumber;
+
+	/**
+	Indicates that all data has been obtained from the source (ETrue if there is no more source data).
+	*/
+	TBool iNoMoreSourceData;
+
+	/** 
+	Indicates that all data has been sent to the sink.
+	*/
+	TBool iAllDataSentToSink;
+
+	/** 
+	Datapath completed because of an error; usually KErrNone.
+	*/
+	TUint iDataPathCompletedErrorCode;
+
+	/**
+	Start position of the play window.
+	*/
+	TTimeIntervalMicroSeconds iPlayWindowStartPosition ;
+	
+	/**
+	End position of the play window.
+	*/
+	TTimeIntervalMicroSeconds iPlayWindowEndPosition ;
+
+	/**	
+	The position audio will start playing from.
+	When stopping, this is set to iPlayWindowStartPosition.
+	When pausing, this is set to the current position.
+	*/
+	TTimeIntervalMicroSeconds iStartPosition;
+
+	/**	
+	This value can be used to obtain the duration of the source when playing or converting.
+	This is an optimisation as this value will not change if we are playing or converting.
+	*/
+	TTimeIntervalMicroSeconds iCachedSourceDuration;
+
+
+	/** 
+	ETrue if the source buffer is reference to object owned by someone else.
+	*/
+	TBool iSrcBufRef;
+
+	/**
+	ETrue if sink buffer is reference to object owned by someone else
+	*/
+	TBool iSnkBufRef;
+
+	/**
+	Indicates asynchrous buffers from AudioInput.
+	*/
+	TBool iObtainingAsyncSourceBuffer;
+
+	/**
+	Indicates asynchrous buffers from AudioOutput.
+	*/
+	TBool iObtainingAsyncSinkBuffer;
+
+	/** 
+	Indicates DoPauseL() has been called.
+	*/
+	TBool iPauseCalled;
+
+	/**	
+	Flag to indicate that a buffer is with the source.
+
+	This is necessary as it is imperrative that when a buffer is with the source, it must
+	not be referenced in any way. The reason for this is that it is not mandated that sources
+	maintain buffer references. For example, it is valid for DevSound to return recorded data in a
+	different buffer to the one supplied to it.
+    */
+	TBool iSourceBufferWithSource;
+
+	/**
+	Flag to indicate that a buffer is with the sink.
+
+	This are necessary as it is imperrative that when a buffer is with the sink, it must
+	not be referenced in any way. The reason for this is that it is not mandated that sinks
+	maintain buffer references. For example, it is valid for DevSound to request more audio data in a
+	different buffer to the one supplied to it.
+	*/
+	TBool iSinkBufferWithSink;
+
+
+	/** 
+	Holds the number of samples played on audio output at a point where we
+	want to reference play duration from.
+	*/
+	TInt iReferenceAudioSamplesPlayed;
+
+	/** 
+	Holds the number of samples recorded from audio input at a point where we
+	want to reference record duration from.
+	*/
+	TInt iReferenceAudioSamplesRecorded;
+
+	/** 
+	Pointer to internal callback completion class
+	*/
+	CCompleteCallback * iCompleteCallback;
+
+	/**
+	This indicates what buffers are required in order to operate.
+	If a real Codec is in use, buffers are required from both source and sink,
+	else only one is required and source is preferred.
+	*/
+	enum TNeedBuffer
+		{
+		/** No buffers needed.
+		*/
+		ENoBuffers = 0x0,
+		/** Sink buffer needed.
+		*/
+		ENeedSinkBuffer = 0x01,
+		/** Source buffer needed.
+		*/
+		ENeedSourceBuffer = 0x10
+		};
+
+	/** Holds the outcome of the call to DetermineBuffersToUseL
+	*/
+	TInt iBuffersToUse;
+	};
+
+#endif