First public contribution.
1 // Copyright (c) 2002-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.
17 #include <mmf/server/mmfdatapathproxy.h>
18 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
19 #include <mmf/server/mmfdatapathproxyserver.h>
23 Constructs a datapath event monitor object.
26 A reference to the observer of the active object. The observer will be notified when an
28 @param aMMFDataPathProxy
29 A reference to the client datapath proxy class.
31 @return A pointer to the new event monitor.
35 EXPORT_C CMMFDataPathEventMonitor* CMMFDataPathEventMonitor::NewL(MMMFDataPathEventMonitorObserver& aObserver,
36 RMMFDataPathProxy& aMMFDataPathProxy)
38 return (new(ELeave) CMMFDataPathEventMonitor(aObserver, aMMFDataPathProxy));
41 CMMFDataPathEventMonitor::CMMFDataPathEventMonitor(MMMFDataPathEventMonitorObserver& aObserver,
42 RMMFDataPathProxy& aMMFDataPathProxy) :
43 CActive(EPriorityStandard),
45 iMMFDataPathProxy(aMMFDataPathProxy)
47 CActiveScheduler::Add(this);
55 EXPORT_C CMMFDataPathEventMonitor::~CMMFDataPathEventMonitor()
61 Tells the datapath event monitor to start listening for events.
63 The datapath proxy must have been opened before this method is called.
67 EXPORT_C void CMMFDataPathEventMonitor::Start()
69 iMMFDataPathProxy.ReceiveEvents(iEventPckg, iStatus);
74 Internal active object function.
76 Starts the data path event monitor and handles an event if there is no error status.
78 Calls HandleEvent on iObserver.
82 EXPORT_C void CMMFDataPathEventMonitor::RunL()
84 if (iStatus.Int() == KErrNone)
86 iObserver.HandleEvent(iEventPckg());
91 //something's gone wrong with trying to receive events (e.g. server died etc)
92 TMMFEvent event(KMMFErrorCategoryDataPathGeneralError, iStatus.Int());
93 iObserver.HandleEvent(event);
94 //we don't want to receive events again here...
99 Cancels the outstanding request on iMMFDataPathProxy.
103 void CMMFDataPathEventMonitor::DoCancel()
105 iMMFDataPathProxy.CancelReceiveEvents();
109 Creates a subthread that will contain the datapath.
111 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
112 another of the system-wide error codes.
116 EXPORT_C TInt RMMFDataPathProxy::CreateSubThread()
118 //start the subthread with a unique name
119 TName subThreadName(_L("MMFDataPathThread"));
120 subThreadName.AppendNum(Math::Random(),EHex);
122 TInt error = DoCreateSubThread(subThreadName, &CMMFDataPathProxyServer::StartThread);
126 //now create a session with the subthread
127 error = CreateSession(subThreadName, KMMFDataPathProxyVersion);
132 // Note: in the following, we can pass straight addresses for writing since both client and server
133 // are in the same process.
135 Load the datapath in the new thread. Use this method if the codec UID is not known
136 and there is no datapath ambiguity, ie. only one datapath is possible.
138 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
139 another of the system-wide error codes.
143 EXPORT_C TInt RMMFDataPathProxy::LoadDataPath()
145 return SendReceive(EMMFDataPathProxyLoadDataPathBy);
149 Load the datapath in the new thread.
151 Use this method if the codec UID is not known but the TMediaId can be used to select which codec
155 The type of media to be handled by this datapath.
157 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
158 another of the system-wide error codes.
162 EXPORT_C TInt RMMFDataPathProxy::LoadDataPath(TMediaId aMediaId)
164 return SendReceive (EMMFDataPathProxyLoadDataPathByMediaId, TInt(&aMediaId));
168 Load the datapath in the new thread.
170 Use this method if the codec UID is known and there is no datapath ambiguity, ie. only one datapath
174 The UID of the codec plugin to be used by the datapath.
176 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
177 another of the system-wide error codes.
181 EXPORT_C TInt RMMFDataPathProxy::LoadDataPath(TUid aCodecUid)
183 return SendReceive(EMMFDataPathProxyLoadDataPathByCodecUid, TInt(&aCodecUid));
187 Loads the datapath in the new thread.
189 Use this method if the codec UID is known and there is datapath ambiguity. The TMediaId will be
190 used to choose the correct path.
193 The UID of the codec plugin to be used by the datapath.
195 The type of media to be handled by this datapath.
197 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
198 another of the system-wide error codes.
202 EXPORT_C TInt RMMFDataPathProxy::LoadDataPath(TUid aCodecUid, TMediaId aMediaId)
204 return SendReceive(EMMFDataPathProxyLoadDataPathByMediaIdCodecUid, TInt(&aCodecUid), TInt(&aMediaId));
208 Specify the data source for this datapath.
210 If the sink already exists, this function tries to establish a connection between the source and
211 sink. Note that only one data source can be added to the datapath.
214 A pointer to the data source.
216 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
217 another of the system-wide error codes.
221 EXPORT_C TInt RMMFDataPathProxy::AddDataSource(MDataSource* aSource)
223 return SendReceive(EMMFDataPathProxyAddDataSource, TInt(aSource));
227 Specify the data sink for this datapath.
229 If the source already exists, this function tries to establish a connection between the source and
230 the sink. Note that only one data sink can be added to the datapath.
233 A pointer to the data sink.
235 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
236 another of the system-wide error codes.
240 EXPORT_C TInt RMMFDataPathProxy::AddDataSink(MDataSink* aSink)
242 return SendReceive(EMMFDataPathProxyAddDataSink, TInt(aSink));
246 Transfer the datapath from the stopped into the primed state.
248 This function allocates buffers in preparation to play and must be called before calling PlayL().
250 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
251 another of the system-wide error codes.
255 EXPORT_C TInt RMMFDataPathProxy::Prime()
257 return SendReceive(EMMFDataPathProxyPrime);
261 Transfer the datapath from the primed into the playing state.
263 This function starts an active scheduler play loop and can only play from the primed state.
265 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
266 another of the system-wide error codes.
270 EXPORT_C TInt RMMFDataPathProxy::Play()
272 return SendReceive(EMMFDataPathProxyPlay);
278 This function transfers the datapath from the playing into the primed state and sends
279 KMMFErrorCategoryDataPathGeneralError to the client if an error occurs.
281 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
282 another of the system-wide error codes.
286 EXPORT_C TInt RMMFDataPathProxy::Pause()
288 return SendReceive(EMMFDataPathProxyPause);
294 This function transfers the datapath from the primed into the stopped state and resets the data
295 path position, but does not clean up buffers. It also sends KMMFErrorCategoryDataPathGeneralError
296 to the client if an error occurs.
298 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
299 another of the system-wide error codes.
303 EXPORT_C TInt RMMFDataPathProxy::Stop()
305 return SendReceive(EMMFDataPathProxyStop);
309 Gets the current position of the datapath in units of time.
312 The current position in micro seconds will be copied into this variable.
314 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
315 another of the system-wide error codes.
319 EXPORT_C TInt RMMFDataPathProxy::GetPosition(TTimeIntervalMicroSeconds& aPosition) const
321 return SendReceive(EMMFDataPathProxyGetPosition, TInt(&aPosition));
325 Sets the current position of the datapath in units of time.
328 The required position in micro seconds.
330 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
331 another of the system-wide error codes.
335 EXPORT_C TInt RMMFDataPathProxy::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
337 return SendReceive(EMMFDataPathProxySetPosition, TInt(&aPosition));
341 Sets the play window relative to the start of the entire clip.
344 The start position in micro seconds relative to the start of the clip.
346 The end position in micro seconds relative to the start of the clip.
348 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
349 another of the system-wide error codes.
353 EXPORT_C TInt RMMFDataPathProxy::SetPlayWindow( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd )
355 return SendReceive( EMMFDataPathProxySetPlayWindow, TInt(&aStart), TInt(&aEnd)) ;
359 Removes a previously defined play window.
361 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
362 another of the system-wide error codes.
366 EXPORT_C TInt RMMFDataPathProxy::ClearPlayWindow()
368 return SendReceive( EMMFDataPathProxyClearPlayWindow) ;
372 Gets the current datapath state.
375 The current state of the datapath will be copied into this variable.
377 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
378 another of the system-wide error codes.
382 EXPORT_C TInt RMMFDataPathProxy::State( TInt& aState )
384 return SendReceive( EMMFDataPathProxyState, TInt(&aState) ) ; // pass address, not value
388 Deletes the datapath and shuts down the datapath proxy thread.
390 Calls RMMFSubThreadBase::Shutdown(). This function will not return until the subthread has
391 exited, or a timeout has occurred.
395 EXPORT_C void RMMFDataPathProxy::Close()
405 CMMFDataPathProxyServer* CMMFDataPathProxyServer::NewL()
407 CMMFDataPathProxyServer* s = new(ELeave) CMMFDataPathProxyServer();
408 CleanupStack::PushL(s);
414 CMMFDataPathProxyServer::CMMFDataPathProxyServer() :
415 CMMFSubThreadServer(EPriorityStandard)
419 void CMMFDataPathProxyServer::ConstructL()
421 //just need to call baseclass's constructL here
422 CMMFSubThreadServer::ConstructL();
425 CMMFDataPathProxyServer::~CMMFDataPathProxyServer()
429 CMmfIpcSession* CMMFDataPathProxyServer::NewSessionL(const TVersion& aVersion) const
431 if (!User::QueryVersionSupported(KMMFDataPathProxyVersion, aVersion))
432 User::Leave(KErrNotSupported);
434 return CMMFDataPathProxySession::NewL();
437 TInt CMMFDataPathProxyServer::StartThread(TAny*)
440 //create cleanupstack
441 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
446 TRAP(err, DoStartThreadL());
452 void CMMFDataPathProxyServer::DoStartThreadL()
454 // create and install the active scheduler we need
455 CActiveScheduler* s=new(ELeave) CActiveScheduler;
456 CleanupStack::PushL(s);
457 CActiveScheduler::Install(s);
458 // create the server (leave it on the cleanup stack)
459 CleanupStack::PushL(CMMFDataPathProxyServer::NewL());
460 // Initialisation complete, now signal the client
461 RThread::Rendezvous(KErrNone);
463 CActiveScheduler::Start();
464 // Cleanup the server and scheduler
465 CleanupStack::PopAndDestroy(2);
466 REComSession::FinalClose(); // fix 047933
473 CMMFDataPathProxySession* CMMFDataPathProxySession::NewL()
475 return new(ELeave) CMMFDataPathProxySession();
478 CMMFDataPathProxySession::CMMFDataPathProxySession()
483 CMMFDataPathProxySession::~CMMFDataPathProxySession()
488 void CMMFDataPathProxySession::ServiceL(const RMmfIpcMessage& aMessage)
490 TBool complete = EFalse;
491 switch(aMessage.Function())
493 case EMMFDataPathProxyLoadDataPathBy:
494 complete = LoadDataPathByL(aMessage);
496 case EMMFDataPathProxyLoadDataPathByMediaId:
497 complete = LoadDataPathByMediaIdL(aMessage);
499 case EMMFDataPathProxyLoadDataPathByCodecUid:
500 complete = LoadDataPathByCodecUidL(aMessage);
502 case EMMFDataPathProxyLoadDataPathByMediaIdCodecUid:
503 complete = LoadDataPathByMediaIdCodecUidL(aMessage);
505 case EMMFDataPathProxyAddDataSource:
506 complete = AddDataSourceL(aMessage);
508 case EMMFDataPathProxyAddDataSink:
509 complete = AddDataSinkL(aMessage);
511 case EMMFDataPathProxyPrime:
512 complete = PrimeL(aMessage);
514 case EMMFDataPathProxyPlay:
515 complete = PlayL(aMessage);
517 case EMMFDataPathProxyPause:
518 complete = PauseL(aMessage);
520 case EMMFDataPathProxyStop:
521 complete = StopL(aMessage);
523 case EMMFDataPathProxyGetPosition:
524 complete = GetPositionL(aMessage);
526 case EMMFDataPathProxySetPosition:
527 complete = SetPositionL(aMessage);
529 case EMMFDataPathProxySetPlayWindow :
530 complete = SetPlayWindowL(aMessage) ;
532 case EMMFDataPathProxyClearPlayWindow:
533 complete = ClearPlayWindowL(aMessage);
535 case EMMFDataPathProxyState:
536 complete = StateL(aMessage);
538 case EMMFSubThreadReceiveEvents:
539 complete = ReceiveEventsL(aMessage);//provided by baseclass
541 case EMMFSubThreadCancelReceiveEvents:
542 complete = CancelReceiveEvents();//provided by baseclass
544 case EMMFSubThreadShutdown:
545 complete = ShutDown();//provided by baseclass
548 User::Leave(KErrNotSupported);
553 aMessage.Complete(KErrNone);
557 TBool CMMFDataPathProxySession::LoadDataPathByL(const RMmfIpcMessage& /*aMessage*/)
560 User::Leave(KErrAlreadyExists);
561 iDataPath = CMMFDataPath::NewL(*this);
565 TBool CMMFDataPathProxySession::LoadDataPathByMediaIdL(const RMmfIpcMessage& aMessage)
568 User::Leave(KErrAlreadyExists);
569 TMediaId* mediaId = REINTERPRET_CAST(TMediaId*, aMessage.Int0());
570 iDataPath = CMMFDataPath::NewL(*mediaId, *this);
574 TBool CMMFDataPathProxySession::LoadDataPathByCodecUidL(const RMmfIpcMessage& aMessage)
577 User::Leave(KErrAlreadyExists);
578 TUid* uid = REINTERPRET_CAST(TUid*, aMessage.Int0());
579 iDataPath = CMMFDataPath::NewL(*uid, *this);
583 TBool CMMFDataPathProxySession::LoadDataPathByMediaIdCodecUidL(const RMmfIpcMessage& aMessage)
586 User::Leave(KErrAlreadyExists);
587 TUid* uid = REINTERPRET_CAST(TUid*, aMessage.Int0());
588 TMediaId* mediaId = REINTERPRET_CAST(TMediaId*, aMessage.Int1());
589 iDataPath = CMMFDataPath::NewL(*uid, *mediaId, *this);
593 TBool CMMFDataPathProxySession::AddDataSourceL(const RMmfIpcMessage& aMessage)
595 CheckDataPathExistsL();
596 MDataSource* source = REINTERPRET_CAST(MDataSource*, aMessage.Int0());
597 iDataPath->AddDataSourceL(source);
601 TBool CMMFDataPathProxySession::AddDataSinkL(const RMmfIpcMessage& aMessage)
603 CheckDataPathExistsL();
604 MDataSink* sink = REINTERPRET_CAST(MDataSink*, aMessage.Int0());
605 iDataPath->AddDataSinkL(sink);
609 TBool CMMFDataPathProxySession::PrimeL(const RMmfIpcMessage& /*aMessage*/)
611 CheckDataPathExistsL();
616 TBool CMMFDataPathProxySession::PlayL(const RMmfIpcMessage& /*aMessage*/)
618 CheckDataPathExistsL();
623 TBool CMMFDataPathProxySession::PauseL(const RMmfIpcMessage& /*aMessage*/)
625 CheckDataPathExistsL();
630 TBool CMMFDataPathProxySession::StopL(const RMmfIpcMessage& /*aMessage*/)
632 CheckDataPathExistsL();
637 TBool CMMFDataPathProxySession::GetPositionL(const RMmfIpcMessage& aMessage) const
639 CheckDataPathExistsL();
640 TTimeIntervalMicroSeconds* t = REINTERPRET_CAST(TTimeIntervalMicroSeconds*, aMessage.Int0());
641 *t = iDataPath->Position();
645 TBool CMMFDataPathProxySession::SetPositionL(const RMmfIpcMessage& aMessage)
647 CheckDataPathExistsL();
648 TTimeIntervalMicroSeconds* t = REINTERPRET_CAST(TTimeIntervalMicroSeconds*, aMessage.Int0());
649 iDataPath->SetPositionL(*t);
653 TBool CMMFDataPathProxySession::SetPlayWindowL(const RMmfIpcMessage& aMessage)
655 CheckDataPathExistsL() ;
656 TTimeIntervalMicroSeconds* start = REINTERPRET_CAST( TTimeIntervalMicroSeconds*, aMessage.Int0() ) ;
657 TTimeIntervalMicroSeconds* end = REINTERPRET_CAST( TTimeIntervalMicroSeconds*, aMessage.Int1() ) ;
658 iDataPath->SetPlayWindowL( *start, *end ) ;
662 TBool CMMFDataPathProxySession::ClearPlayWindowL(const RMmfIpcMessage& /*aMessage*/)
664 CheckDataPathExistsL() ;
665 iDataPath->ClearPlayWindowL() ;
669 TBool CMMFDataPathProxySession::StateL(const RMmfIpcMessage& aMessage)
671 CheckDataPathExistsL() ;
672 TInt* state = REINTERPRET_CAST( TInt*, aMessage.Int0() ) ;
673 *state = iDataPath->State();