1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/inc/mmf/server/mmfdatapath.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,482 @@
1.4 +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// source\server\mmfdatapath.h
1.18 +//
1.19 +//
1.20 +
1.21 +#ifndef MMFDATAPATH_H
1.22 +#define MMFDATAPATH_H
1.23 +
1.24 +#include <mmf/common/mmfcontroller.h>
1.25 +#include <mmf/server/mmfdatasource.h>
1.26 +#include <mmf/server/mmfdatasink.h>
1.27 +#include <mmf/server/mmfcodec.h>
1.28 +#include <mmf/server/mmfbuffer.h>
1.29 +#include <mmf/common/mmfutilities.h>
1.30 +#include <mmf/server/mmfformat.h>
1.31 +#include <mmf/server/mmfsubthreadbase.h>
1.32 +
1.33 +/**
1.34 + * @publishedAll
1.35 + * @deprecated
1.36 + *
1.37 + * Datapath general error code used when sending events to clients
1.38 + */
1.39 +const TUid KMMFErrorCategoryDataPathGeneralError = {0x101F76DC};
1.40 +
1.41 +
1.42 +
1.43 +/**
1.44 +@publishedAll
1.45 +@deprecated
1.46 +
1.47 +Abstract utility class that moves data from a single data source to a single data sink, via a codec if required.
1.48 +
1.49 +All functions are exported form the DLL and are virtual to allow plugins to define their own data paths.
1.50 +*/
1.51 +class CMMFDataPath : public CActive,
1.52 + public MDataSink,
1.53 + public MDataSource,
1.54 + public MAsyncEventHandler
1.55 + {
1.56 +public:
1.57 +
1.58 + //CMMFDataPath constructor if codec Uid is not already known by CMMFController
1.59 + //and there is no data path ambiguity - ie only one data path is possible
1.60 + IMPORT_C static CMMFDataPath* NewL(MAsyncEventHandler& aEventHandler);
1.61 +
1.62 + //CMMFDataPath constructor if codec Uid is not already known by CMMFController
1.63 + //and there is ambiguity ie more than one possible data path TMediaId used to select path
1.64 + IMPORT_C static CMMFDataPath* NewL(TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
1.65 +
1.66 + //CMMFDataPath constructor if codec Uid is already known by CMMFController
1.67 + //and there is no data path ambiguity - ie only one data path is possible
1.68 + IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler);
1.69 +
1.70 + //CMMFDataPath constructor if codec Uid is already known by CMMFController
1.71 + //and there is ambiguity ie more than one possible data path TMediaId used to select path
1.72 + IMPORT_C static CMMFDataPath* NewL(TUid aCodecUid, TMediaId aMediaId, MAsyncEventHandler& aEventHandler);
1.73 +
1.74 + IMPORT_C virtual ~CMMFDataPath();
1.75 +
1.76 + // Called when source and sink needs to be de-referenced
1.77 + IMPORT_C virtual void ResetL();
1.78 +
1.79 + //from MDataSink - CMMFData path is a sink to its MDataSource
1.80 + IMPORT_C virtual void EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId); //only required for an active push MDataSource requesting a buffer empty - not implemented
1.81 + IMPORT_C virtual void BufferFilledL(CMMFBuffer* aBuffer); //called by the CMMFDataPath's MDataSource when it has filled the buffer
1.82 + IMPORT_C virtual TBool CanCreateSinkBuffer(); //from both MDataSource & MDataSink?
1.83 + IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
1.84 + IMPORT_C virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
1.85 +
1.86 + IMPORT_C virtual TFourCC SinkDataTypeCode(TMediaId aMediaId);
1.87 +
1.88 + //from MDataSource
1.89 + IMPORT_C virtual void FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId aMediaId); //only required for an active pull MDataSink requesting buffer fill - not implementated
1.90 + IMPORT_C virtual void BufferEmptiedL(CMMFBuffer* aBuffer);//called by the CMMFDataPath's MDataSink when it has emptied the buffer
1.91 + IMPORT_C virtual TBool CanCreateSourceBuffer(); //from both MDataSource & MDataSink?
1.92 + IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId); //CMMFDataPath can't create buffers
1.93 + IMPORT_C virtual CMMFBuffer* CreateSourceBufferL(TMediaId aMediaId, TBool &aReference); //CMMFDataPath can't create buffers
1.94 + IMPORT_C virtual TFourCC SourceDataTypeCode(TMediaId aMediaId);
1.95 +
1.96 + IMPORT_C virtual void AddDataSourceL(MDataSource* aSource);
1.97 + IMPORT_C virtual void AddDataSinkL(MDataSink* aSink);
1.98 +
1.99 + //could derive these from a mixin eg MMMFControle later for active MDataSource/Sinks
1.100 + IMPORT_C virtual void PrimeL();
1.101 + IMPORT_C virtual void PlayL();
1.102 + IMPORT_C virtual void Pause();
1.103 + IMPORT_C virtual void Stop();
1.104 +
1.105 + IMPORT_C virtual TTimeIntervalMicroSeconds Position() const;
1.106 + IMPORT_C virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
1.107 +
1.108 + // Play Window.
1.109 + IMPORT_C virtual void SetPlayWindowL( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd ) ;
1.110 + IMPORT_C virtual void ClearPlayWindowL() ;
1.111 +
1.112 + //State
1.113 + IMPORT_C virtual TInt State();
1.114 +
1.115 + //CActive implementations
1.116 + IMPORT_C void RunL();
1.117 + IMPORT_C void DoCancel();
1.118 + IMPORT_C TInt RunError(TInt aError);
1.119 +
1.120 + //error handling
1.121 + IMPORT_C TInt DoSendEventToClient(TUid aEventType, TInt aErrorCode);
1.122 +
1.123 + IMPORT_C TInt SetBlockLength(TUint aBlockLength);
1.124 + /**
1.125 +
1.126 + Indicates the state of the data path.
1.127 +
1.128 + Mimics typical MultiMedia behaviour of stopped, primed and playing
1.129 + */
1.130 + enum TDataPathState
1.131 + {
1.132 + /** Stopped.
1.133 + */
1.134 + EStopped,
1.135 + /** Primed.
1.136 + */
1.137 + EPrimed,
1.138 + /** Playing.
1.139 + */
1.140 + EPlaying,
1.141 + /** Recording.
1.142 + */
1.143 + ERecording,
1.144 + /** Converting.
1.145 + */
1.146 + EConverting
1.147 + };
1.148 +
1.149 + /**
1.150 + @internalComponent
1.151 + */
1.152 + class CCompleteCallback : public CActive
1.153 + {
1.154 + public:
1.155 + CCompleteCallback(CMMFDataPath& aDataPath, TBool aWaitForSink);
1.156 + ~CCompleteCallback();
1.157 +
1.158 + void SignalDataPathComplete(TInt aDataPathError);
1.159 + void SignalSinkComplete(TInt aSinkError);
1.160 + TRequestStatus& ActiveStatus();
1.161 +
1.162 + void DoCancel();
1.163 + private:
1.164 + void RunL();
1.165 + CMMFDataPath& iDataPath;
1.166 + TBool iDataPathComplete;
1.167 + TBool iSinkComplete;
1.168 + TBool iWaitForSink;
1.169 +
1.170 + TInt iSinkError;
1.171 + TInt iDataPathError;
1.172 + };
1.173 + friend class CCompleteCallback;
1.174 + friend class CMMFDataPath2;
1.175 +protected:
1.176 +
1.177 + /**
1.178 + Indicates the transfer state.
1.179 +
1.180 + Buffers maybe be filled, emptied, or have "one" shot initialisatings performed upon them.
1.181 +
1.182 + TTransferState is used within the datapath RunL which drives databuffer exchange.
1.183 + */
1.184 + enum TTransferState
1.185 + {
1.186 + /** Waiting on a BufferEmptied callback from sink
1.187 + */
1.188 + EWaitSink,
1.189 + /** Waiting on a BufferFilled callback from source
1.190 + */
1.191 + EWaitSource,
1.192 + /** Initialize the sink.
1.193 + */
1.194 + EInitializeSink,
1.195 + /** Initialize the source.
1.196 + */
1.197 + EInitializeSource,
1.198 + /** Source buffer does not contain data.
1.199 + */
1.200 + ENeedSourceData,
1.201 + /** Sink buffer does not contain data.
1.202 + */
1.203 + ENeedSinkData,
1.204 + /** There is more source data to send to the sink and need to match sink and source.
1.205 + */
1.206 + ENeedToMatchSourceToSink,
1.207 + /** Outstanding data to send to sink.
1.208 + */
1.209 + ESendDataToSink,
1.210 + /** End of data.
1.211 + */
1.212 + EEndOfData //indicates that the datapath has transferred all the data to the sink
1.213 + };
1.214 +
1.215 +
1.216 +
1.217 +
1.218 +protected:
1.219 + CMMFDataPath(TMediaId aMediaId, MAsyncEventHandler& aEventHandler) :
1.220 + CActive(EPriorityStandard), MDataSink(KUidMmfDataPath), MDataSource(KUidMmfDataPath),
1.221 + iEventHandler(aEventHandler), iMediaId(aMediaId), iState(EStopped)
1.222 + {CActiveScheduler::Add(this);};
1.223 +
1.224 + IMPORT_C void ConstructL(TUid aCodecUid = KNullUid);
1.225 + IMPORT_C virtual void ConstructSourceL( const TDesC8& aInitData ) ;
1.226 + IMPORT_C virtual void ConstructSinkL( const TDesC8& aInitData ) ;
1.227 + IMPORT_C virtual void EndOfData();
1.228 +
1.229 + //These methods use API on DevSound to determine how many samples have been played/recorded
1.230 + //and thereby determine the real position.
1.231 + TTimeIntervalMicroSeconds CalculateAudioOutputPosition() const;
1.232 + TTimeIntervalMicroSeconds CalculateAudioInputPosition() const;
1.233 +
1.234 + //These methods determine the position of either the input or the output.
1.235 + //The position may come from a format or from an audio input/output depending on
1.236 + //the operation the datapath is doing (Playing (output), Recording & Converting (input))
1.237 + TTimeIntervalMicroSeconds OutputPosition() const;
1.238 + TTimeIntervalMicroSeconds InputPosition() const;
1.239 +
1.240 +
1.241 + //Determines what buffers are required (see TNeedBuffer)
1.242 + //May leave KErrNotSupported if source/sinks can't supply the necessary buffers
1.243 + TInt DetermineBuffersToUseL(void) const;
1.244 +
1.245 + //Determines how many samples have been played by DevSound
1.246 + TInt AudioSamplesPlayed() const;
1.247 +
1.248 + //Determines how many samples have been recorded by DevSound
1.249 + TInt AudioSamplesRecorded() const;
1.250 +
1.251 +
1.252 +private:
1.253 + void ChangeDataPathTransferState(TTransferState aNewDataPathTransferState);
1.254 + void CreateDataPathL(MDataSource* aSource, MDataSink* aSink);
1.255 +
1.256 + void InitializeSinkL();
1.257 + void InitializeSourceL();
1.258 + void FillSourceBufferL();
1.259 + void FillSinkBufferL();
1.260 + void EmptySinkBufferL();
1.261 + void DoCleanupBuffers();
1.262 + void ObtainSyncBuffersL(); //tries to obtain synchronous data buffers from src/snk
1.263 +
1.264 + TTimeIntervalMicroSeconds Duration() const;
1.265 +
1.266 + void DoStopL();
1.267 + void DoPauseL();
1.268 + void DoEndOfDataL();
1.269 +
1.270 + IMPORT_C TInt SendEventToClient(const TMMFEvent& aEvent);
1.271 +
1.272 + void SetBuffersAvailable();
1.273 + void ResetRefBuffers();
1.274 +
1.275 +
1.276 +
1.277 +protected:
1.278 + /**
1.279 + Event handler.
1.280 + */
1.281 + MAsyncEventHandler& iEventHandler;
1.282 +
1.283 + /**
1.284 + The source of data to which the CMMFDataPath is a MDataSink for.
1.285 + */
1.286 + MDataSource* iDataSource;
1.287 + /**
1.288 + The sink of data for which the CMMFDataPath is a MDataSource for
1.289 + */
1.290 + MDataSink* iDataSink;
1.291 + /**
1.292 + Set to true when the sink is able to accept data. EFalse otherwise.
1.293 + */
1.294 + TBool iSinkCanReceive;
1.295 + /**
1.296 + The sink's data type. Same as the codec input data type.
1.297 + */
1.298 + TFourCC iSinkFourCC;
1.299 + /**
1.300 + The source's data type. Same as the codec output data type.
1.301 + */
1.302 + TFourCC iSourceFourCC;
1.303 + /**
1.304 + Identifies which media type and stream within MDataSource.
1.305 + */
1.306 + TMediaId iMediaId;
1.307 + /**
1.308 + Codec in use. Null Codec is signified by == NULL
1.309 + */
1.310 + CMMFCodec* iCodec;
1.311 +
1.312 + /**
1.313 + Result of processing the codec.
1.314 + */
1.315 + TCodecProcessResult iCodecProcessResult;
1.316 +
1.317 + /**
1.318 + Set to ETrue when the data path has a source and a sink and can send data from the source to the sink.
1.319 + */
1.320 + TBool iDataPathCreated;
1.321 +
1.322 + /**
1.323 + Current data path state.
1.324 + @see TDataPathState
1.325 + */
1.326 + TDataPathState iState;
1.327 +
1.328 + /**
1.329 + Current transfer state.
1.330 + @see TTransferState
1.331 + */
1.332 + TTransferState iTransferState;
1.333 +
1.334 + /**
1.335 + Set to true if data path has to use a supplied codec in its construction.
1.336 + */
1.337 + TBool iUseSuppliedCodecUid;
1.338 +
1.339 + /**
1.340 + This is set to point to whichever sink buffer is in use.
1.341 + */
1.342 + CMMFBuffer* iSinkBuffer;
1.343 +
1.344 + /**
1.345 + This is the pointer to whichever source buffer is in use
1.346 + */
1.347 + CMMFBuffer* iSourceBuffer;
1.348 +
1.349 + /**
1.350 + The source's position in terms of frames or some other time fixed parameter.
1.351 + */
1.352 + TUint iCurrentSourceFrameNumber;
1.353 +
1.354 + /**
1.355 + The sink's position in terms of frames or some other time fixed parameter.
1.356 + */
1.357 + TUint iCurrentSinkFrameNumber;
1.358 +
1.359 + /**
1.360 + Indicates that all data has been obtained from the source (ETrue if there is no more source data).
1.361 + */
1.362 + TBool iNoMoreSourceData;
1.363 +
1.364 + /**
1.365 + Indicates that all data has been sent to the sink.
1.366 + */
1.367 + TBool iAllDataSentToSink;
1.368 +
1.369 + /**
1.370 + Datapath completed because of an error; usually KErrNone.
1.371 + */
1.372 + TUint iDataPathCompletedErrorCode;
1.373 +
1.374 + /**
1.375 + Start position of the play window.
1.376 + */
1.377 + TTimeIntervalMicroSeconds iPlayWindowStartPosition ;
1.378 +
1.379 + /**
1.380 + End position of the play window.
1.381 + */
1.382 + TTimeIntervalMicroSeconds iPlayWindowEndPosition ;
1.383 +
1.384 + /**
1.385 + The position audio will start playing from.
1.386 + When stopping, this is set to iPlayWindowStartPosition.
1.387 + When pausing, this is set to the current position.
1.388 + */
1.389 + TTimeIntervalMicroSeconds iStartPosition;
1.390 +
1.391 + /**
1.392 + This value can be used to obtain the duration of the source when playing or converting.
1.393 + This is an optimisation as this value will not change if we are playing or converting.
1.394 + */
1.395 + TTimeIntervalMicroSeconds iCachedSourceDuration;
1.396 +
1.397 +
1.398 + /**
1.399 + ETrue if the source buffer is reference to object owned by someone else.
1.400 + */
1.401 + TBool iSrcBufRef;
1.402 +
1.403 + /**
1.404 + ETrue if sink buffer is reference to object owned by someone else
1.405 + */
1.406 + TBool iSnkBufRef;
1.407 +
1.408 + /**
1.409 + Indicates asynchrous buffers from AudioInput.
1.410 + */
1.411 + TBool iObtainingAsyncSourceBuffer;
1.412 +
1.413 + /**
1.414 + Indicates asynchrous buffers from AudioOutput.
1.415 + */
1.416 + TBool iObtainingAsyncSinkBuffer;
1.417 +
1.418 + /**
1.419 + Indicates DoPauseL() has been called.
1.420 + */
1.421 + TBool iPauseCalled;
1.422 +
1.423 + /**
1.424 + Flag to indicate that a buffer is with the source.
1.425 +
1.426 + This is necessary as it is imperrative that when a buffer is with the source, it must
1.427 + not be referenced in any way. The reason for this is that it is not mandated that sources
1.428 + maintain buffer references. For example, it is valid for DevSound to return recorded data in a
1.429 + different buffer to the one supplied to it.
1.430 + */
1.431 + TBool iSourceBufferWithSource;
1.432 +
1.433 + /**
1.434 + Flag to indicate that a buffer is with the sink.
1.435 +
1.436 + This are necessary as it is imperrative that when a buffer is with the sink, it must
1.437 + not be referenced in any way. The reason for this is that it is not mandated that sinks
1.438 + maintain buffer references. For example, it is valid for DevSound to request more audio data in a
1.439 + different buffer to the one supplied to it.
1.440 + */
1.441 + TBool iSinkBufferWithSink;
1.442 +
1.443 +
1.444 + /**
1.445 + Holds the number of samples played on audio output at a point where we
1.446 + want to reference play duration from.
1.447 + */
1.448 + TInt iReferenceAudioSamplesPlayed;
1.449 +
1.450 + /**
1.451 + Holds the number of samples recorded from audio input at a point where we
1.452 + want to reference record duration from.
1.453 + */
1.454 + TInt iReferenceAudioSamplesRecorded;
1.455 +
1.456 + /**
1.457 + Pointer to internal callback completion class
1.458 + */
1.459 + CCompleteCallback * iCompleteCallback;
1.460 +
1.461 + /**
1.462 + This indicates what buffers are required in order to operate.
1.463 + If a real Codec is in use, buffers are required from both source and sink,
1.464 + else only one is required and source is preferred.
1.465 + */
1.466 + enum TNeedBuffer
1.467 + {
1.468 + /** No buffers needed.
1.469 + */
1.470 + ENoBuffers = 0x0,
1.471 + /** Sink buffer needed.
1.472 + */
1.473 + ENeedSinkBuffer = 0x01,
1.474 + /** Source buffer needed.
1.475 + */
1.476 + ENeedSourceBuffer = 0x10
1.477 + };
1.478 +
1.479 + /** Holds the outcome of the call to DetermineBuffersToUseL
1.480 + */
1.481 + TInt iBuffersToUse;
1.482 + };
1.483 +
1.484 +#endif
1.485 +