1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // source\server\mmfdatapath.h
21 #include <mmf/common/mmfcontroller.h>
22 #include <mmf/server/mmfdatasource.h>
23 #include <mmf/server/mmfdatasink.h>
24 #include <mmf/server/mmfcodec.h>
25 #include <mmf/server/mmfbuffer.h>
26 #include <mmf/common/mmfutilities.h>
27 #include <mmf/server/mmfformat.h>
28 #include <mmf/server/mmfsubthreadbase.h>
34 * Datapath general error code used when sending events to clients
36 const TUid KMMFErrorCategoryDataPathGeneralError = {0x101F76DC};
44 Abstract utility class that moves data from a single data source to a single data sink, via a codec if required.
46 All functions are exported form the DLL and are virtual to allow plugins to define their own data paths.
48 class CMMFDataPath : public CActive,
51 public MAsyncEventHandler
55 //CMMFDataPath constructor if codec Uid is not already known by CMMFController
56 //and there is no data path ambiguity - ie only one data path is possible
57 IMPORT_C static CMMFDataPath* NewL(MAsyncEventHandler& aEventHandler);
59 //CMMFDataPath constructor if codec Uid is not already known by CMMFController
60 //and there is ambiguity ie more than one possible data path TMediaId used to select path
61 IMPORT_C static CMMFDataPath* NewL(TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
63 //CMMFDataPath constructor if codec Uid is already known by CMMFController
64 //and there is no data path ambiguity - ie only one data path is possible
65 IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler);
67 //CMMFDataPath constructor if codec Uid is already known by CMMFController
68 //and there is ambiguity ie more than one possible data path TMediaId used to select path
69 IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
71 IMPORT_C virtual ~CMMFDataPath();
73 // Called when source and sink needs to be de-referenced
74 IMPORT_C virtual void ResetL();
76 //from MDataSink - CMMFData path is a sink to its MDataSource
77 IMPORT_C virtual void EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId); //only required for an active push MDataSource requesting a buffer empty - not implemented
78 IMPORT_C virtual void BufferFilledL(CMMFBuffer* aBuffer); //called by the CMMFDataPath's MDataSource when it has filled the buffer
79 IMPORT_C virtual TBool CanCreateSinkBuffer(); //from both MDataSource & MDataSink?
80 IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
81 IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
83 IMPORT_C virtual TFourCC SinkDataTypeCode(TMediaId aMediaId);
86 IMPORT_C virtual void FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId aMediaId); //only required for an active pull MDataSink requesting buffer fill - not implementated
87 IMPORT_C virtual void BufferEmptiedL(CMMFBuffer* aBuffer);//called by the CMMFDataPath's MDataSink when it has emptied the buffer
88 IMPORT_C virtual TBool CanCreateSourceBuffer(); //from both MDataSource & MDataSink?
89 IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
90 IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
91 IMPORT_C virtual TFourCC SourceDataTypeCode(TMediaId aMediaId);
93 IMPORT_C virtual void AddDataSourceL(MDataSource* aSource);
94 IMPORT_C virtual void AddDataSinkL(MDataSink* aSink);
96 //could derive these from a mixin eg MMMFControle later for active MDataSource/Sinks
97 IMPORT_C virtual void PrimeL();
98 IMPORT_C virtual void PlayL();
99 IMPORT_C virtual void Pause();
100 IMPORT_C virtual void Stop();
102 IMPORT_C virtual TTimeIntervalMicroSeconds Position() const;
103 IMPORT_C virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
106 IMPORT_C virtual void SetPlayWindowL( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd ) ;
107 IMPORT_C virtual void ClearPlayWindowL() ;
110 IMPORT_C virtual TInt State();
112 //CActive implementations
113 IMPORT_C void RunL();
114 IMPORT_C void DoCancel();
115 IMPORT_C TInt RunError(TInt aError);
118 IMPORT_C TInt DoSendEventToClient(TUid aEventType, TInt aErrorCode);
120 IMPORT_C TInt SetBlockLength(TUint aBlockLength);
123 Indicates the state of the data path.
125 Mimics typical MultiMedia behaviour of stopped, primed and playing
149 class CCompleteCallback : public CActive
152 CCompleteCallback(CMMFDataPath& aDataPath, TBool aWaitForSink);
153 ~CCompleteCallback();
155 void SignalDataPathComplete(TInt aDataPathError);
156 void SignalSinkComplete(TInt aSinkError);
157 TRequestStatus& ActiveStatus();
162 CMMFDataPath& iDataPath;
163 TBool iDataPathComplete;
170 friend class CCompleteCallback;
171 friend class CMMFDataPath2;
175 Indicates the transfer state.
177 Buffers maybe be filled, emptied, or have "one" shot initialisatings performed upon them.
179 TTransferState is used within the datapath RunL which drives databuffer exchange.
183 /** Waiting on a BufferEmptied callback from sink
186 /** Waiting on a BufferFilled callback from source
189 /** Initialize the sink.
192 /** Initialize the source.
195 /** Source buffer does not contain data.
198 /** Sink buffer does not contain data.
201 /** There is more source data to send to the sink and need to match sink and source.
203 ENeedToMatchSourceToSink,
204 /** Outstanding data to send to sink.
209 EEndOfData //indicates that the datapath has transferred all the data to the sink
216 CMMFDataPath(TMediaId aMediaId, MAsyncEventHandler& aEventHandler) :
217 CActive(EPriorityStandard), MDataSink(KUidMmfDataPath), MDataSource(KUidMmfDataPath),
218 iEventHandler(aEventHandler), iMediaId(aMediaId), iState(EStopped)
219 {CActiveScheduler::Add(this);};
221 IMPORT_C void ConstructL(TUid aCodecUid = KNullUid);
222 IMPORT_C virtual void ConstructSourceL( const TDesC8& aInitData ) ;
223 IMPORT_C virtual void ConstructSinkL( const TDesC8& aInitData ) ;
224 IMPORT_C virtual void EndOfData();
226 //These methods use API on DevSound to determine how many samples have been played/recorded
227 //and thereby determine the real position.
228 TTimeIntervalMicroSeconds CalculateAudioOutputPosition() const;
229 TTimeIntervalMicroSeconds CalculateAudioInputPosition() const;
231 //These methods determine the position of either the input or the output.
232 //The position may come from a format or from an audio input/output depending on
233 //the operation the datapath is doing (Playing (output), Recording & Converting (input))
234 TTimeIntervalMicroSeconds OutputPosition() const;
235 TTimeIntervalMicroSeconds InputPosition() const;
238 //Determines what buffers are required (see TNeedBuffer)
239 //May leave KErrNotSupported if source/sinks can't supply the necessary buffers
240 TInt DetermineBuffersToUseL(void) const;
242 //Determines how many samples have been played by DevSound
243 TInt AudioSamplesPlayed() const;
245 //Determines how many samples have been recorded by DevSound
246 TInt AudioSamplesRecorded() const;
250 void ChangeDataPathTransferState(TTransferState aNewDataPathTransferState);
251 void CreateDataPathL(MDataSource* aSource, MDataSink* aSink);
253 void InitializeSinkL();
254 void InitializeSourceL();
255 void FillSourceBufferL();
256 void FillSinkBufferL();
257 void EmptySinkBufferL();
258 void DoCleanupBuffers();
259 void ObtainSyncBuffersL(); //tries to obtain synchronous data buffers from src/snk
261 TTimeIntervalMicroSeconds Duration() const;
267 IMPORT_C TInt SendEventToClient(const TMMFEvent& aEvent);
269 void SetBuffersAvailable();
270 void ResetRefBuffers();
278 MAsyncEventHandler& iEventHandler;
281 The source of data to which the CMMFDataPath is a MDataSink for.
283 MDataSource* iDataSource;
285 The sink of data for which the CMMFDataPath is a MDataSource for
287 MDataSink* iDataSink;
289 Set to true when the sink is able to accept data. EFalse otherwise.
291 TBool iSinkCanReceive;
293 The sink's data type. Same as the codec input data type.
297 The source's data type. Same as the codec output data type.
299 TFourCC iSourceFourCC;
301 Identifies which media type and stream within MDataSource.
305 Codec in use. Null Codec is signified by == NULL
310 Result of processing the codec.
312 TCodecProcessResult iCodecProcessResult;
315 Set to ETrue when the data path has a source and a sink and can send data from the source to the sink.
317 TBool iDataPathCreated;
320 Current data path state.
323 TDataPathState iState;
326 Current transfer state.
329 TTransferState iTransferState;
332 Set to true if data path has to use a supplied codec in its construction.
334 TBool iUseSuppliedCodecUid;
337 This is set to point to whichever sink buffer is in use.
339 CMMFBuffer* iSinkBuffer;
342 This is the pointer to whichever source buffer is in use
344 CMMFBuffer* iSourceBuffer;
347 The source's position in terms of frames or some other time fixed parameter.
349 TUint iCurrentSourceFrameNumber;
352 The sink's position in terms of frames or some other time fixed parameter.
354 TUint iCurrentSinkFrameNumber;
357 Indicates that all data has been obtained from the source (ETrue if there is no more source data).
359 TBool iNoMoreSourceData;
362 Indicates that all data has been sent to the sink.
364 TBool iAllDataSentToSink;
367 Datapath completed because of an error; usually KErrNone.
369 TUint iDataPathCompletedErrorCode;
372 Start position of the play window.
374 TTimeIntervalMicroSeconds iPlayWindowStartPosition ;
377 End position of the play window.
379 TTimeIntervalMicroSeconds iPlayWindowEndPosition ;
382 The position audio will start playing from.
383 When stopping, this is set to iPlayWindowStartPosition.
384 When pausing, this is set to the current position.
386 TTimeIntervalMicroSeconds iStartPosition;
389 This value can be used to obtain the duration of the source when playing or converting.
390 This is an optimisation as this value will not change if we are playing or converting.
392 TTimeIntervalMicroSeconds iCachedSourceDuration;
396 ETrue if the source buffer is reference to object owned by someone else.
401 ETrue if sink buffer is reference to object owned by someone else
406 Indicates asynchrous buffers from AudioInput.
408 TBool iObtainingAsyncSourceBuffer;
411 Indicates asynchrous buffers from AudioOutput.
413 TBool iObtainingAsyncSinkBuffer;
416 Indicates DoPauseL() has been called.
421 Flag to indicate that a buffer is with the source.
423 This is necessary as it is imperrative that when a buffer is with the source, it must
424 not be referenced in any way. The reason for this is that it is not mandated that sources
425 maintain buffer references. For example, it is valid for DevSound to return recorded data in a
426 different buffer to the one supplied to it.
428 TBool iSourceBufferWithSource;
431 Flag to indicate that a buffer is with the sink.
433 This are necessary as it is imperrative that when a buffer is with the sink, it must
434 not be referenced in any way. The reason for this is that it is not mandated that sinks
435 maintain buffer references. For example, it is valid for DevSound to request more audio data in a
436 different buffer to the one supplied to it.
438 TBool iSinkBufferWithSink;
442 Holds the number of samples played on audio output at a point where we
443 want to reference play duration from.
445 TInt iReferenceAudioSamplesPlayed;
448 Holds the number of samples recorded from audio input at a point where we
449 want to reference record duration from.
451 TInt iReferenceAudioSamplesRecorded;
454 Pointer to internal callback completion class
456 CCompleteCallback * iCompleteCallback;
459 This indicates what buffers are required in order to operate.
460 If a real Codec is in use, buffers are required from both source and sink,
461 else only one is required and source is preferred.
465 /** No buffers needed.
468 /** Sink buffer needed.
470 ENeedSinkBuffer = 0x01,
471 /** Source buffer needed.
473 ENeedSourceBuffer = 0x10
476 /** Holds the outcome of the call to DetermineBuffersToUseL