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