--- /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