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 the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.symbianfoundation.org/legal/licencesv10.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/mmfnullcodec.h>
26 #include <mmf/server/mmfbuffer.h>
27 #include <mmf/common/mmfutilities.h>
28 #include <mmf/server/mmfformat.h>
29 #include "mmfsubthreadbase.h"
35 * Datapath general error code used when sending events to clients
37 const TUid KMMFErrorCategoryDataPathGeneralError = {0x101F76DC};
45 Abstract utility class that moves data from a single data source to a single data sink, via a codec if required.
47 All functions are exported form the DLL and are virtual to allow plugins to define their own data paths.
49 class CMMFDataPath : public CActive,
52 public MAsyncEventHandler
56 //CMMFDataPath constructor if codec Uid is not already known by CMMFController
57 //and there is no data path ambiguity - ie only one data path is possible
58 IMPORT_C static CMMFDataPath* NewL(MAsyncEventHandler& aEventHandler);
60 //CMMFDataPath constructor if codec Uid is not already known by CMMFController
61 //and there is ambiguity ie more than one possible data path TMediaId used to select path
62 IMPORT_C static CMMFDataPath* NewL(TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
64 //CMMFDataPath constructor if codec Uid is already known by CMMFController
65 //and there is no data path ambiguity - ie only one data path is possible
66 IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler);
68 //CMMFDataPath constructor if codec Uid is already known by CMMFController
69 //and there is ambiguity ie more than one possible data path TMediaId used to select path
70 IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
72 IMPORT_C virtual ~CMMFDataPath();
74 // Called when source and sink needs to be de-referenced
75 IMPORT_C virtual void ResetL();
77 //from MDataSink - CMMFData path is a sink to its MDataSource
78 IMPORT_C virtual void EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId); //only required for an active push MDataSource requesting a buffer empty - not implemented
79 IMPORT_C virtual void BufferFilledL(CMMFBuffer* aBuffer); //called by the CMMFDataPath's MDataSource when it has filled the buffer
80 IMPORT_C virtual TBool CanCreateSinkBuffer(); //from both MDataSource & MDataSink?
81 IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
82 IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
84 IMPORT_C virtual TFourCC SinkDataTypeCode(TMediaId aMediaId);
87 IMPORT_C virtual void FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId aMediaId); //only required for an active pull MDataSink requesting buffer fill - not implementated
88 IMPORT_C virtual void BufferEmptiedL(CMMFBuffer* aBuffer);//called by the CMMFDataPath's MDataSink when it has emptied the buffer
89 IMPORT_C virtual TBool CanCreateSourceBuffer(); //from both MDataSource & MDataSink?
90 IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
91 IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
92 IMPORT_C virtual TFourCC SourceDataTypeCode(TMediaId aMediaId);
94 IMPORT_C virtual void AddDataSourceL(MDataSource* aSource);
95 IMPORT_C virtual void AddDataSinkL(MDataSink* aSink);
97 //could derive these from a mixin eg MMMFControle later for active MDataSource/Sinks
98 IMPORT_C virtual void PrimeL();
99 IMPORT_C virtual void PlayL();
100 IMPORT_C virtual void Pause();
101 IMPORT_C virtual void Stop();
103 IMPORT_C virtual TTimeIntervalMicroSeconds Position() const;
104 IMPORT_C virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
107 IMPORT_C virtual void SetPlayWindowL( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd ) ;
108 IMPORT_C virtual void ClearPlayWindowL() ;
111 IMPORT_C virtual TInt State();
113 //CActive implementations
114 IMPORT_C void RunL();
115 IMPORT_C void DoCancel();
116 IMPORT_C TInt RunError(TInt aError);
119 IMPORT_C TInt DoSendEventToClient(TUid aEventType, TInt aErrorCode);
121 IMPORT_C TInt SetBlockLength(TUint aBlockLength);
124 Indicates the state of the data path.
126 Mimics typical MultiMedia behaviour of stopped, primed and playing
150 class CCompleteCallback : public CActive
153 CCompleteCallback(CMMFDataPath& aDataPath, TBool aWaitForSink);
154 ~CCompleteCallback();
156 void SignalDataPathComplete(TInt aDataPathError);
157 void SignalSinkComplete(TInt aSinkError);
158 TRequestStatus& ActiveStatus();
163 CMMFDataPath& iDataPath;
164 TBool iDataPathComplete;
171 friend class CCompleteCallback;
172 friend class CMMFDataPath2;
176 Indicates the transfer state.
178 Buffers maybe be filled, emptied, or have "one" shot initialisatings performed upon them.
180 TTransferState is used within the datapath RunL which drives databuffer exchange.
184 /** Waiting on a BufferEmptied callback from sink
187 /** Waiting on a BufferFilled callback from source
190 /** Initialize the sink.
193 /** Initialize the source.
196 /** Source buffer does not contain data.
199 /** Sink buffer does not contain data.
202 /** There is more source data to send to the sink and need to match sink and source.
204 ENeedToMatchSourceToSink,
205 /** Outstanding data to send to sink.
210 EEndOfData //indicates that the datapath has transferred all the data to the sink
217 CMMFDataPath(TMediaId aMediaId, MAsyncEventHandler& aEventHandler) :
218 CActive(EPriorityStandard), MDataSink(KUidMmfDataPath), MDataSource(KUidMmfDataPath),
219 iEventHandler(aEventHandler), iMediaId(aMediaId), iState(EStopped)
220 {CActiveScheduler::Add(this);};
222 IMPORT_C void ConstructL(TUid aCodecUid = KNullUid);
223 IMPORT_C virtual void ConstructSourceL( const TDesC8& aInitData ) ;
224 IMPORT_C virtual void ConstructSinkL( const TDesC8& aInitData ) ;
225 IMPORT_C virtual void EndOfData();
227 //These methods use API on DevSound to determine how many samples have been played/recorded
228 //and thereby determine the real position.
229 TTimeIntervalMicroSeconds CalculateAudioOutputPosition() const;
230 TTimeIntervalMicroSeconds CalculateAudioInputPosition() const;
232 //These methods determine the position of either the input or the output.
233 //The position may come from a format or from an audio input/output depending on
234 //the operation the datapath is doing (Playing (output), Recording & Converting (input))
235 TTimeIntervalMicroSeconds OutputPosition() const;
236 TTimeIntervalMicroSeconds InputPosition() const;
239 //Determines what buffers are required (see TNeedBuffer)
240 //May leave KErrNotSupported if source/sinks can't supply the necessary buffers
241 TInt DetermineBuffersToUseL(void) const;
243 //Determines how many samples have been played by DevSound
244 TInt AudioSamplesPlayed() const;
246 //Determines how many samples have been recorded by DevSound
247 TInt AudioSamplesRecorded() const;
251 void ChangeDataPathTransferState(TTransferState aNewDataPathTransferState);
252 void CreateDataPathL(MDataSource* aSource, MDataSink* aSink);
254 void InitializeSinkL();
255 void InitializeSourceL();
256 void FillSourceBufferL();
257 void FillSinkBufferL();
258 void EmptySinkBufferL();
259 void DoCleanupBuffers();
260 void ObtainSyncBuffersL(); //tries to obtain synchronous data buffers from src/snk
262 TTimeIntervalMicroSeconds Duration() const;
268 IMPORT_C TInt SendEventToClient(const TMMFEvent& aEvent);
270 void SetBuffersAvailable();
271 void ResetRefBuffers();
279 MAsyncEventHandler& iEventHandler;
282 The source of data to which the CMMFDataPath is a MDataSink for.
284 MDataSource* iDataSource;
286 The sink of data for which the CMMFDataPath is a MDataSource for
288 MDataSink* iDataSink;
290 Set to true when the sink is able to accept data. EFalse otherwise.
292 TBool iSinkCanReceive;
294 The sink's data type. Same as the codec input data type.
298 The source's data type. Same as the codec output data type.
300 TFourCC iSourceFourCC;
302 Identifies which media type and stream within MDataSource.
306 Codec in use. Null Codec is signified by == NULL
311 Result of processing the codec.
313 TCodecProcessResult iCodecProcessResult;
316 Set to ETrue when the data path has a source and a sink and can send data from the source to the sink.
318 TBool iDataPathCreated;
321 Current data path state.
324 TDataPathState iState;
327 Current transfer state.
330 TTransferState iTransferState;
333 Set to true if data path has to use a supplied codec in its construction.
335 TBool iUseSuppliedCodecUid;
338 This is set to point to whichever sink buffer is in use.
340 CMMFBuffer* iSinkBuffer;
343 This is the pointer to whichever source buffer is in use
345 CMMFBuffer* iSourceBuffer;
348 The source's position in terms of frames or some other time fixed parameter.
350 TUint iCurrentSourceFrameNumber;
353 The sink's position in terms of frames or some other time fixed parameter.
355 TUint iCurrentSinkFrameNumber;
358 Indicates that all data has been obtained from the source (ETrue if there is no more source data).
360 TBool iNoMoreSourceData;
363 Indicates that all data has been sent to the sink.
365 TBool iAllDataSentToSink;
368 Datapath completed because of an error; usually KErrNone.
370 TUint iDataPathCompletedErrorCode;
373 Start position of the play window.
375 TTimeIntervalMicroSeconds iPlayWindowStartPosition ;
378 End position of the play window.
380 TTimeIntervalMicroSeconds iPlayWindowEndPosition ;
383 The position audio will start playing from.
384 When stopping, this is set to iPlayWindowStartPosition.
385 When pausing, this is set to the current position.
387 TTimeIntervalMicroSeconds iStartPosition;
390 This value can be used to obtain the duration of the source when playing or converting.
391 This is an optimisation as this value will not change if we are playing or converting.
393 TTimeIntervalMicroSeconds iCachedSourceDuration;
397 ETrue if the source buffer is reference to object owned by someone else.
402 ETrue if sink buffer is reference to object owned by someone else
407 Indicates asynchrous buffers from AudioInput.
409 TBool iObtainingAsyncSourceBuffer;
412 Indicates asynchrous buffers from AudioOutput.
414 TBool iObtainingAsyncSinkBuffer;
417 Indicates DoPauseL() has been called.
422 Flag to indicate that a buffer is with the source.
424 This is necessary as it is imperrative that when a buffer is with the source, it must
425 not be referenced in any way. The reason for this is that it is not mandated that sources
426 maintain buffer references. For example, it is valid for DevSound to return recorded data in a
427 different buffer to the one supplied to it.
429 TBool iSourceBufferWithSource;
432 Flag to indicate that a buffer is with the sink.
434 This are necessary as it is imperrative that when a buffer is with the sink, it must
435 not be referenced in any way. The reason for this is that it is not mandated that sinks
436 maintain buffer references. For example, it is valid for DevSound to request more audio data in a
437 different buffer to the one supplied to it.
439 TBool iSinkBufferWithSink;
443 Holds the number of samples played on audio output at a point where we
444 want to reference play duration from.
446 TInt iReferenceAudioSamplesPlayed;
449 Holds the number of samples recorded from audio input at a point where we
450 want to reference record duration from.
452 TInt iReferenceAudioSamplesRecorded;
455 Pointer to internal callback completion class
457 CCompleteCallback * iCompleteCallback;
460 This indicates what buffers are required in order to operate.
461 If a real Codec is in use, buffers are required from both source and sink,
462 else only one is required and source is preferred.
466 /** No buffers needed.
469 /** Sink buffer needed.
471 ENeedSinkBuffer = 0x01,
472 /** Source buffer needed.
474 ENeedSourceBuffer = 0x10
477 /** Holds the outcome of the call to DetermineBuffersToUseL