2 * Copyright 2015, Dario Casalinuovo. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 #include "MediaClient.h"
8 #include <MediaConnection.h>
10 #include <MediaRoster.h>
11 #include <TimeSource.h>
13 #include "MediaClientNode.h"
18 namespace BPrivate
{ namespace media
{
23 ConnReleaser(BMediaConnection
* conn
)
27 virtual ~ConnReleaser()
32 bool operator== (const ConnReleaser
&c1
)
34 return c1
.fConn
== this->fConn
;
38 BMediaConnection
* Obj() const
44 BMediaConnection
* fConn
;
48 class InputReleaser
: public ConnReleaser
{
50 InputReleaser(BMediaInput
* input
)
52 ConnReleaser(input
) {}
54 BMediaInput
* Obj() const
56 return dynamic_cast<BMediaInput
*>(ConnReleaser::Obj());
61 class OutputReleaser
: public ConnReleaser
{
63 OutputReleaser(BMediaOutput
* output
)
65 ConnReleaser(output
) {}
67 BMediaOutput
* Obj() const
69 return dynamic_cast<BMediaOutput
*>(ConnReleaser::Obj());
78 BMediaClient::BMediaClient(const char* name
,
79 media_type type
, media_client_kinds kinds
)
85 fNode
= new BMediaClientNode(name
, this, type
);
88 fClient
.node
= fNode
->Node();
89 fClient
.kinds
= kinds
;
93 BMediaClient::~BMediaClient()
102 BMediaClient::Client() const
109 BMediaClient::InitCheck() const
118 BMediaClient::Kinds() const
122 return fClient
.Kinds();
127 BMediaClient::MediaType() const
131 // Right now ConsumerType() and ProducerType() are the same.
132 return fNode
->ConsumerType();
137 BMediaClient::RegisterInput(BMediaInput
* input
)
139 input
->_ConnectionRegistered(this, ++fLastID
);
146 BMediaClient::RegisterOutput(BMediaOutput
* output
)
148 output
->_ConnectionRegistered(this, ++fLastID
);
155 BMediaClient::Bind(BMediaInput
* input
, BMediaOutput
* output
)
163 if (input
->fOwner
!= this || output
->fOwner
!= this)
166 // TODO: Implement binding one input to more outputs.
167 if (input
->fBind
!= NULL
168 || output
->fBind
!= NULL
)
171 input
->fBind
= output
;
172 output
->fBind
= input
;
178 BMediaClient::Unbind(BMediaInput
* input
, BMediaOutput
* output
)
186 if (input
->fOwner
!= this || output
->fOwner
!= this)
190 output
->fBind
= NULL
;
196 BMediaClient::Connect(BMediaConnection
* ourConnection
,
197 BMediaConnection
* theirConnection
)
201 return Connect(ourConnection
, theirConnection
->Connection());
206 BMediaClient::Connect(BMediaConnection
* ourConnection
,
207 const media_connection
& theirConnection
)
211 BMediaOutput
* output
= dynamic_cast<BMediaOutput
*>(ourConnection
);
212 if (output
!= NULL
&& theirConnection
.IsInput())
213 return _ConnectInput(output
, theirConnection
);
215 BMediaInput
* input
= dynamic_cast<BMediaInput
*>(ourConnection
);
216 if (input
!= NULL
&& theirConnection
.IsOutput())
217 return _ConnectOutput(input
, theirConnection
);
224 BMediaClient::Connect(BMediaConnection
* connection
,
225 const media_client
& client
)
234 BMediaClient::Disconnect()
238 for (int32 i
= 0; i
< CountInputs(); i
++)
239 InputAt(i
)->Disconnect();
241 for (int32 i
= 0; i
< CountOutputs(); i
++)
242 OutputAt(i
)->Disconnect();
249 BMediaClient::CountInputs() const
253 return fInputs
.CountItems();
258 BMediaClient::CountOutputs() const
262 return fOutputs
.CountItems();
267 BMediaClient::InputAt(int32 index
) const
271 return fInputs
.ItemAt(index
)->Obj();
276 BMediaClient::OutputAt(int32 index
) const
280 return fOutputs
.ItemAt(index
)->Obj();
285 BMediaClient::FindInput(const media_connection
& input
) const
289 if (!input
.IsInput())
292 return _FindInput(input
._Destination());
297 BMediaClient::FindOutput(const media_connection
& output
) const
301 if (!output
.IsOutput())
304 return _FindOutput(output
._Source());
309 BMediaClient::IsRunning() const
318 BMediaClient::Start()
323 for (int32 i
= 0; i
< CountOutputs(); i
++) {
324 media_node remoteNode
= OutputAt(i
)->Connection()._RemoteNode();
325 if (remoteNode
.kind
& B_TIME_SOURCE
)
326 err
= BMediaRoster::CurrentRoster()->StartTimeSource(
327 remoteNode
, BTimeSource::RealTime());
329 err
= BMediaRoster::CurrentRoster()->StartNode(
330 remoteNode
, fNode
->TimeSource()->Now());
333 return BMediaRoster::CurrentRoster()->StartNode(
334 fNode
->Node(), fNode
->TimeSource()->Now());
343 return BMediaRoster::CurrentRoster()->StopNode(
344 fNode
->Node(), fNode
->TimeSource()->Now());
349 BMediaClient::Seek(bigtime_t mediaTime
,
350 bigtime_t performanceTime
)
354 return BMediaRoster::CurrentRoster()->SeekNode(fNode
->Node(),
355 mediaTime
, performanceTime
);
360 BMediaClient::Roll(bigtime_t start
, bigtime_t stop
, bigtime_t seek
)
364 return BMediaRoster::CurrentRoster()->RollNode(fNode
->Node(),
370 BMediaClient::Preroll()
374 return BMediaRoster::CurrentRoster()->PrerollNode(fNode
->Node());
379 BMediaClient::SyncTo(bigtime_t performanceTime
, bigtime_t timeout
)
383 return BMediaRoster::CurrentRoster()->SyncToNode(fNode
->Node(),
384 performanceTime
, timeout
);
389 BMediaClient::RunMode() const
393 return fNode
->RunMode();
398 BMediaClient::SetRunMode(BMediaNode::run_mode mode
)
402 return BMediaRoster::CurrentRoster()->SetRunModeNode(fNode
->Node(), mode
);
407 BMediaClient::CurrentTime() const
416 BMediaClient::AddOn(int32
* id
) const
425 BMediaClient::HandleStart(bigtime_t performanceTime
)
432 BMediaClient::HandleStop(bigtime_t performanceTime
)
439 BMediaClient::HandleSeek(bigtime_t mediaTime
, bigtime_t performanceTime
)
445 BMediaClient::FormatSuggestion(media_type type
, int32 quality
,
446 media_format
* format
)
453 BMediaClient::_Init()
457 BMediaRoster
* roster
= BMediaRoster::Roster(&fInitErr
);
458 if (fInitErr
== B_OK
&& roster
!= NULL
)
459 fInitErr
= roster
->RegisterNode(fNode
);
464 BMediaClient::_Deinit()
473 // This will release the connections too.
474 fInputs
.MakeEmpty(true);
475 fOutputs
.MakeEmpty(true);
482 BMediaClient::_AddInput(BMediaInput
* input
)
486 fInputs
.AddItem(new InputReleaser(input
));
491 BMediaClient::_AddOutput(BMediaOutput
* output
)
495 fOutputs
.AddItem(new OutputReleaser(output
));
500 BMediaClient::_FindInput(const media_destination
& dest
) const
504 for (int32 i
= 0; i
< CountInputs(); i
++) {
505 if (dest
.id
== InputAt(i
)->_Destination().id
)
513 BMediaClient::_FindOutput(const media_source
& source
) const
517 for (int32 i
= 0; i
< CountOutputs(); i
++) {
518 if (source
.id
== OutputAt(i
)->_Source().id
)
526 BMediaClient::_ConnectInput(BMediaOutput
* output
,
527 const media_connection
& input
)
531 if (input
._Destination() == media_destination::null
)
532 return B_MEDIA_BAD_DESTINATION
;
534 media_output ourOutput
= output
->Connection()._MediaOutput();
535 media_input theirInput
= input
._MediaInput();
536 media_format format
= output
->AcceptedFormat();
538 return BMediaRoster::CurrentRoster()->Connect(ourOutput
.source
,
539 theirInput
.destination
, &format
, &ourOutput
, &theirInput
,
540 BMediaRoster::B_CONNECT_MUTED
);
545 BMediaClient::_ConnectOutput(BMediaInput
* input
,
546 const media_connection
& output
)
550 if (output
._Source() == media_source::null
)
551 return B_MEDIA_BAD_SOURCE
;
553 media_input ourInput
= input
->Connection()._MediaInput();
554 media_output theirOutput
= output
._MediaOutput();
555 media_format format
= input
->AcceptedFormat();
557 return BMediaRoster::CurrentRoster()->Connect(theirOutput
.source
,
558 ourInput
.destination
, &format
, &theirOutput
, &ourInput
,
559 BMediaRoster::B_CONNECT_MUTED
);
564 BMediaClient::_DisconnectConnection(BMediaConnection
* conn
)
566 if (conn
->Client() != this)
569 const media_connection
& handle
= conn
->Connection();
570 if (handle
.IsInput()) {
571 return BMediaRoster::CurrentRoster()->Disconnect(
572 handle
._RemoteNode().node
, handle
._Source(),
573 handle
._Node().node
, handle
._Destination());
575 return BMediaRoster::CurrentRoster()->Disconnect(
576 handle
._Node().node
, handle
._Source(),
577 handle
._RemoteNode().node
, handle
._Destination());
585 BMediaClient::_ReleaseConnection(BMediaConnection
* conn
)
587 if (conn
->Client() != this)
590 if (conn
->Connection().IsInput()) {
591 InputReleaser obj
= InputReleaser(dynamic_cast<BMediaInput
*>(conn
));
592 fInputs
.RemoveItem(&obj
);
595 OutputReleaser obj
= OutputReleaser(dynamic_cast<BMediaOutput
*>(conn
));
596 fOutputs
.RemoveItem(&obj
);
604 void BMediaClient::_ReservedMediaClient0() {}
605 void BMediaClient::_ReservedMediaClient1() {}
606 void BMediaClient::_ReservedMediaClient2() {}
607 void BMediaClient::_ReservedMediaClient3() {}
608 void BMediaClient::_ReservedMediaClient4() {}
609 void BMediaClient::_ReservedMediaClient5() {}
610 void BMediaClient::_ReservedMediaClient6() {}
611 void BMediaClient::_ReservedMediaClient7() {}
612 void BMediaClient::_ReservedMediaClient8() {}
613 void BMediaClient::_ReservedMediaClient9() {}
614 void BMediaClient::_ReservedMediaClient10() {}