MediaClient: Improve internals and API
* Capabilities() become Kind() * Use media_client and media_connection to better model the different situations of the API. Reduce code duplication and move media_kit structs/methods into private. * Various API and beauty improvements. * Introduce id management for media_connections. * Fix different issues preventing to correctly begin a connection.
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include <Buffer.h>
|
#include <Buffer.h>
|
||||||
|
|
||||||
#include <MediaAddOn.h>
|
#include <MediaAddOn.h>
|
||||||
|
#include <MediaClientDefs.h>
|
||||||
#include <MediaConnection.h>
|
#include <MediaConnection.h>
|
||||||
#include <MediaDefs.h>
|
#include <MediaDefs.h>
|
||||||
#include <MediaNode.h>
|
#include <MediaNode.h>
|
||||||
@@ -19,19 +20,6 @@
|
|||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
|
|
||||||
typedef int32 media_client_kind;
|
|
||||||
|
|
||||||
enum media_client_kinds {
|
|
||||||
// The node can receive media data.
|
|
||||||
B_MEDIA_RECORDER = 0x000000001,
|
|
||||||
// The node can send media data to another node.
|
|
||||||
B_MEDIA_PLAYER = 0x000000002,
|
|
||||||
// The node specify a control GUI which can be used to configure it.
|
|
||||||
B_MEDIA_CONTROLLABLE = 0x000000004
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Add file interface
|
|
||||||
// TODO: Offline mode is still missing
|
|
||||||
|
|
||||||
// BMediaClient is a general purpose class allowing to create any kind
|
// BMediaClient is a general purpose class allowing to create any kind
|
||||||
// of media_node. It automatically manage the expected behavior under
|
// of media_node. It automatically manage the expected behavior under
|
||||||
@@ -56,20 +44,25 @@ public:
|
|||||||
...);
|
...);
|
||||||
|
|
||||||
// TODO: Should allow BControllable capabilities
|
// TODO: Should allow BControllable capabilities
|
||||||
|
// TODO: Add file interface
|
||||||
|
// TODO: Offline mode is still missing
|
||||||
|
|
||||||
BMediaClient(const char* name,
|
BMediaClient(const char* name,
|
||||||
media_type type
|
media_type type
|
||||||
= B_MEDIA_UNKNOWN_TYPE,
|
= B_MEDIA_UNKNOWN_TYPE,
|
||||||
media_client_kind
|
media_client_kind
|
||||||
capabilities = B_MEDIA_PLAYER
|
kind = B_MEDIA_PLAYER
|
||||||
& B_MEDIA_RECORDER);
|
& B_MEDIA_RECORDER);
|
||||||
|
|
||||||
virtual ~BMediaClient();
|
virtual ~BMediaClient();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
const media_client& Client() const;
|
||||||
|
|
||||||
// Return the capabilities of this BMediaClient instance.
|
// Return the capabilities of this BMediaClient instance.
|
||||||
media_client_kind Capabilities() const;
|
media_client_kind Kind() const;
|
||||||
media_type Type() const;
|
media_type MediaType() const;
|
||||||
|
|
||||||
|
status_t InitCheck() const;
|
||||||
|
|
||||||
// To connect pass the BMediaConnection to this class or to another BMediaClient,
|
// To connect pass the BMediaConnection to this class or to another BMediaClient,
|
||||||
// also in another team the connection object will be valid.
|
// also in another team the connection object will be valid.
|
||||||
@@ -84,11 +77,6 @@ public:
|
|||||||
// will automatically connect to this node.
|
// will automatically connect to this node.
|
||||||
virtual BMediaConnection* BeginConnection(media_connection_kind kind);
|
virtual BMediaConnection* BeginConnection(media_connection_kind kind);
|
||||||
|
|
||||||
// Those are used if you want to connect to a precise input/output of
|
|
||||||
// another node, the connection returned represents a remote input/output.
|
|
||||||
virtual BMediaConnection* BeginConnection(const media_input& input);
|
|
||||||
virtual BMediaConnection* BeginConnection(const media_output& output);
|
|
||||||
|
|
||||||
// Bind internally two connections of the same BMediaClient, so that the
|
// Bind internally two connections of the same BMediaClient, so that the
|
||||||
// input will be automatically forwarded to the output just after the
|
// input will be automatically forwarded to the output just after the
|
||||||
// ProcessFunc is called. The buffer is automatically recycled too.
|
// ProcessFunc is called. The buffer is automatically recycled too.
|
||||||
@@ -110,18 +98,20 @@ public:
|
|||||||
BMediaConnection* theirConnection);
|
BMediaConnection* theirConnection);
|
||||||
|
|
||||||
virtual status_t Connect(BMediaConnection* ourConnection,
|
virtual status_t Connect(BMediaConnection* ourConnection,
|
||||||
const dormant_node_info& dormantInfo);
|
const media_connection& theirConnection);
|
||||||
|
|
||||||
|
// Find a free input/output and try to connect to the media_client,
|
||||||
|
// return meaningful error otherwise.
|
||||||
virtual status_t Connect(BMediaConnection* ourConnection,
|
virtual status_t Connect(BMediaConnection* ourConnection,
|
||||||
const media_node& node);
|
const media_client& client);
|
||||||
|
|
||||||
// Disconnect any connection belonging to this object, to disconnect
|
// Disconnect any connection belonging to this object, to disconnect
|
||||||
// a single connection use BMediaConnection::Disconnect().
|
// a single connection use BMediaConnection::Disconnect().
|
||||||
virtual status_t Disconnect();
|
virtual status_t Disconnect();
|
||||||
|
|
||||||
int32 CountConnections() const;
|
|
||||||
int32 CountInputs() const;
|
int32 CountInputs() const;
|
||||||
int32 CountOutputs() const;
|
int32 CountOutputs() const;
|
||||||
|
|
||||||
BMediaConnection* InputAt(int32 index) const;
|
BMediaConnection* InputAt(int32 index) const;
|
||||||
BMediaConnection* OutputAt(int32 index) const;
|
BMediaConnection* OutputAt(int32 index) const;
|
||||||
|
|
||||||
@@ -164,14 +154,6 @@ public:
|
|||||||
// when run_mode != B_OFFLINE.
|
// when run_mode != B_OFFLINE.
|
||||||
bigtime_t PerformanceTime() const;
|
bigtime_t PerformanceTime() const;
|
||||||
|
|
||||||
// When a connection is not binded with another, it's your job to send
|
|
||||||
// the buffer to the connection you want. You might want
|
|
||||||
// to ovverride it so that you can track something, in this case
|
|
||||||
// be sure to call the base version.
|
|
||||||
// Automatically recycle the BBuffer.
|
|
||||||
virtual status_t SendBuffer(BBuffer* buffer,
|
|
||||||
BMediaConnection* connection);
|
|
||||||
|
|
||||||
// This is supplied to support using this class in a BMediaAddOn.
|
// This is supplied to support using this class in a BMediaAddOn.
|
||||||
// Default version just return NULL.
|
// Default version just return NULL.
|
||||||
virtual BMediaAddOn* AddOn(int32* id) const;
|
virtual BMediaAddOn* AddOn(int32* id) const;
|
||||||
@@ -180,6 +162,13 @@ public:
|
|||||||
void* cookie = NULL);
|
void* cookie = NULL);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// When a connection is not binded with another, it's your job to send
|
||||||
|
// the buffer to the connection you want. You might want
|
||||||
|
// to ovverride it so that you can track something, in this case
|
||||||
|
// be sure to call the base version.
|
||||||
|
virtual status_t SendBuffer(BBuffer* buffer,
|
||||||
|
BMediaConnection* connection);
|
||||||
|
|
||||||
virtual void BufferReceived(BMediaConnection* connection,
|
virtual void BufferReceived(BMediaConnection* connection,
|
||||||
BBuffer* buffer);
|
BBuffer* buffer);
|
||||||
|
|
||||||
@@ -192,24 +181,20 @@ protected:
|
|||||||
status_t DisconnectConnection(BMediaConnection* conn);
|
status_t DisconnectConnection(BMediaConnection* conn);
|
||||||
status_t ResetConnection(BMediaConnection* conn);
|
status_t ResetConnection(BMediaConnection* conn);
|
||||||
status_t ReleaseConnection(BMediaConnection* conn);
|
status_t ReleaseConnection(BMediaConnection* conn);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void _Init();
|
void _Init();
|
||||||
void _Deinit();
|
void _Deinit();
|
||||||
|
|
||||||
status_t _TranslateConnection(BMediaConnection* dest,
|
|
||||||
BMediaConnection* source);
|
|
||||||
|
|
||||||
status_t _Connect(BMediaConnection* conn,
|
|
||||||
media_node node);
|
|
||||||
status_t _ConnectInput(BMediaConnection* output,
|
status_t _ConnectInput(BMediaConnection* output,
|
||||||
BMediaConnection* input);
|
const media_connection& input);
|
||||||
status_t _ConnectOutput(BMediaConnection* input,
|
status_t _ConnectOutput(BMediaConnection* input,
|
||||||
BMediaConnection* output);
|
const media_connection& output);
|
||||||
|
|
||||||
status_t fInitErr;
|
status_t fInitErr;
|
||||||
|
|
||||||
media_client_kind fCapabilities;
|
media_client fClient;
|
||||||
|
|
||||||
bool fRunning;
|
bool fRunning;
|
||||||
BMediaClientNode* fNode;
|
BMediaClientNode* fNode;
|
||||||
@@ -227,6 +212,9 @@ private:
|
|||||||
BObjectList<BMediaConnection> fInputs;
|
BObjectList<BMediaConnection> fInputs;
|
||||||
BObjectList<BMediaConnection> fOutputs;
|
BObjectList<BMediaConnection> fOutputs;
|
||||||
|
|
||||||
|
int32 fLastInputID;
|
||||||
|
int32 fLastOutputID;
|
||||||
|
|
||||||
virtual void _ReservedMediaClient0();
|
virtual void _ReservedMediaClient0();
|
||||||
virtual void _ReservedMediaClient1();
|
virtual void _ReservedMediaClient1();
|
||||||
virtual void _ReservedMediaClient2();
|
virtual void _ReservedMediaClient2();
|
||||||
|
|||||||
@@ -9,20 +9,15 @@
|
|||||||
#include <BufferGroup.h>
|
#include <BufferGroup.h>
|
||||||
#include <MediaDefs.h>
|
#include <MediaDefs.h>
|
||||||
|
|
||||||
|
#include <MediaClient.h>
|
||||||
|
#include <MediaClientDefs.h>
|
||||||
|
|
||||||
#include "MediaClientNode.h"
|
#include "MediaClientNode.h"
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
|
|
||||||
|
|
||||||
enum media_connection_kind {
|
|
||||||
B_MEDIA_INPUT = 0,
|
|
||||||
B_MEDIA_OUTPUT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class BMediaClient;
|
|
||||||
|
|
||||||
// The BMediaConnection class is the swiss knife of BMediaClient.
|
// The BMediaConnection class is the swiss knife of BMediaClient.
|
||||||
// It represents a connection between two nodes and allow to create complex
|
// It represents a connection between two nodes and allow to create complex
|
||||||
// nodes without dealing with the unneeded complexity. Two local connections,
|
// nodes without dealing with the unneeded complexity. Two local connections,
|
||||||
@@ -51,7 +46,8 @@ public:
|
|||||||
B_ASK_TIMER
|
B_ASK_TIMER
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function is called when it has come the moment to handle a buffer.
|
|
||||||
|
// This function is called when it is the moment to handle a buffer.
|
||||||
typedef void (*process_hook)(BMediaConnection* connection,
|
typedef void (*process_hook)(BMediaConnection* connection,
|
||||||
BBuffer* buffer);
|
BBuffer* buffer);
|
||||||
|
|
||||||
@@ -63,15 +59,16 @@ public:
|
|||||||
|
|
||||||
virtual ~BMediaConnection();
|
virtual ~BMediaConnection();
|
||||||
|
|
||||||
|
const media_connection& Connection() const;
|
||||||
|
media_connection_id Id() const;
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
// TODO: while most of the objects for both kinds are common
|
// TODO: while most of the objects for both kinds are common
|
||||||
// it would be worthwile to have a private implementation
|
// it would be worthwile to have a private implementation
|
||||||
// so that we can better model the differences and avoid
|
// so that we can better model the differences and avoid
|
||||||
// problems.
|
// problems.
|
||||||
bool IsOutput() const;
|
|
||||||
bool IsInput() const;
|
bool IsInput() const;
|
||||||
|
bool IsOutput() const;
|
||||||
const media_destination& Destination() const;
|
|
||||||
const media_source& Source() const;
|
|
||||||
|
|
||||||
bool HasBinding() const;
|
bool HasBinding() const;
|
||||||
BMediaConnection* Binding() const;
|
BMediaConnection* Binding() const;
|
||||||
@@ -119,11 +116,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
BMediaConnection(BMediaClient* owner,
|
BMediaConnection(BMediaClient* owner,
|
||||||
media_connection_kind kind);
|
media_connection_kind kind,
|
||||||
BMediaConnection(BMediaClient* owner,
|
media_connection_id id);
|
||||||
const media_output& output);
|
|
||||||
BMediaConnection(BMediaClient* owner,
|
|
||||||
const media_input& input);
|
|
||||||
|
|
||||||
// TODO: All notifications should be done into private callbacks like this.
|
// TODO: All notifications should be done into private callbacks like this.
|
||||||
void ConnectedCallback(const media_source& source,
|
void ConnectedCallback(const media_source& source,
|
||||||
@@ -134,18 +128,17 @@ protected:
|
|||||||
void DisconnectCallback(const media_destination& source);
|
void DisconnectCallback(const media_destination& source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BuildMediaOutput(media_output* output) const;
|
media_input MediaInput() const;
|
||||||
void BuildMediaInput(media_input* output) const;
|
media_output MediaOutput() const;
|
||||||
|
|
||||||
|
const media_source& Source() const;
|
||||||
|
const media_destination& Destination() const;
|
||||||
|
|
||||||
void _Init();
|
void _Init();
|
||||||
|
|
||||||
bool fConnected;
|
media_connection fConnection;
|
||||||
bool fOutputEnabled;
|
|
||||||
|
|
||||||
media_connection_kind fKind;
|
|
||||||
BMediaClient* fOwner;
|
BMediaClient* fOwner;
|
||||||
media_node fOwnerNode;
|
|
||||||
team_id fOwnerTeam;
|
|
||||||
|
|
||||||
// A connection might be binded so that it will automatically
|
// A connection might be binded so that it will automatically
|
||||||
// forward or receive the data from/to a local BMediaConnection,
|
// forward or receive the data from/to a local BMediaConnection,
|
||||||
@@ -156,18 +149,14 @@ private:
|
|||||||
notify_hook fNotifyHook;
|
notify_hook fNotifyHook;
|
||||||
void* fBufferCookie;
|
void* fBufferCookie;
|
||||||
|
|
||||||
media_source fSource;
|
|
||||||
media_destination fDestination;
|
|
||||||
|
|
||||||
// This represents the node at other end of connection.
|
|
||||||
media_node fRemoteNode;
|
|
||||||
|
|
||||||
media_format fFormat;
|
|
||||||
size_t fBufferSize;
|
size_t fBufferSize;
|
||||||
bigtime_t fBufferDuration;
|
bigtime_t fBufferDuration;
|
||||||
|
|
||||||
BBufferGroup* fBufferGroup;
|
BBufferGroup* fBufferGroup;
|
||||||
|
|
||||||
|
bool fConnected;
|
||||||
|
bool fOutputEnabled;
|
||||||
|
|
||||||
virtual void _ReservedMediaConnection0();
|
virtual void _ReservedMediaConnection0();
|
||||||
virtual void _ReservedMediaConnection1();
|
virtual void _ReservedMediaConnection1();
|
||||||
virtual void _ReservedMediaConnection2();
|
virtual void _ReservedMediaConnection2();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
AdapterIO.cpp
|
AdapterIO.cpp
|
||||||
MediaIO.cpp
|
MediaIO.cpp
|
||||||
MediaClient.cpp
|
MediaClient.cpp
|
||||||
|
MediaClientDefs.cpp
|
||||||
MediaConnection.cpp
|
MediaConnection.cpp
|
||||||
MediaRecorder.cpp
|
MediaRecorder.cpp
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "MediaClient.h"
|
#include "MediaClient.h"
|
||||||
|
|
||||||
|
#include <MediaConnection.h>
|
||||||
|
|
||||||
#include <MediaRoster.h>
|
#include <MediaRoster.h>
|
||||||
#include <TimeSource.h>
|
#include <TimeSource.h>
|
||||||
|
|
||||||
@@ -12,14 +14,18 @@
|
|||||||
|
|
||||||
|
|
||||||
BMediaClient::BMediaClient(const char* name,
|
BMediaClient::BMediaClient(const char* name,
|
||||||
media_type type, media_client_kind capabilities)
|
media_type type, media_client_kind kind)
|
||||||
:
|
:
|
||||||
fCapabilities(capabilities)
|
fLastInputID(0),
|
||||||
|
fLastOutputID(0)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
fNode = new BMediaClientNode(name, this, type);
|
fNode = new BMediaClientNode(name, this, type);
|
||||||
_Init();
|
_Init();
|
||||||
|
|
||||||
|
fClient.node = fNode->Node();
|
||||||
|
fClient.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -31,6 +37,13 @@ BMediaClient::~BMediaClient()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const media_client&
|
||||||
|
BMediaClient::Client() const
|
||||||
|
{
|
||||||
|
return fClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaClient::InitCheck() const
|
BMediaClient::InitCheck() const
|
||||||
{
|
{
|
||||||
@@ -41,16 +54,16 @@ BMediaClient::InitCheck() const
|
|||||||
|
|
||||||
|
|
||||||
media_client_kind
|
media_client_kind
|
||||||
BMediaClient::Capabilities() const
|
BMediaClient::Kind() const
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fCapabilities;
|
return fClient.kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
media_type
|
media_type
|
||||||
BMediaClient::Type() const
|
BMediaClient::MediaType() const
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
@@ -64,29 +77,13 @@ BMediaClient::BeginConnection(media_connection_kind kind)
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
BMediaConnection* conn = new BMediaConnection(this, kind);
|
media_connection_id id;
|
||||||
AddConnection(conn);
|
if (kind == B_MEDIA_INPUT)
|
||||||
return conn;
|
id = fLastInputID++;
|
||||||
}
|
else
|
||||||
|
id = fLastOutputID++;
|
||||||
|
|
||||||
|
BMediaConnection* conn = new BMediaConnection(this, kind, id);
|
||||||
BMediaConnection*
|
|
||||||
BMediaClient::BeginConnection(const media_input& input)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
BMediaConnection* conn = new BMediaConnection(this, input);
|
|
||||||
AddConnection(conn);
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BMediaConnection*
|
|
||||||
BMediaClient::BeginConnection(const media_output& output)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
BMediaConnection* conn = new BMediaConnection(this, output);
|
|
||||||
AddConnection(conn);
|
AddConnection(conn);
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
@@ -143,9 +140,19 @@ BMediaClient::Connect(BMediaConnection* ourConnection,
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (ourConnection->IsOutput() && theirConnection->IsInput())
|
return Connect(ourConnection, theirConnection->Connection());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BMediaClient::Connect(BMediaConnection* ourConnection,
|
||||||
|
const media_connection& theirConnection)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
if (ourConnection->IsOutput() && theirConnection.IsInput())
|
||||||
return _ConnectInput(ourConnection, theirConnection);
|
return _ConnectInput(ourConnection, theirConnection);
|
||||||
else if (ourConnection->IsInput() && theirConnection->IsOutput())
|
else if (ourConnection->IsInput() && theirConnection.IsOutput())
|
||||||
return _ConnectOutput(ourConnection, theirConnection);
|
return _ConnectOutput(ourConnection, theirConnection);
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -154,24 +161,7 @@ BMediaClient::Connect(BMediaConnection* ourConnection,
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaClient::Connect(BMediaConnection* connection,
|
BMediaClient::Connect(BMediaConnection* connection,
|
||||||
const dormant_node_info& dormantInfo)
|
const media_client& client)
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
media_node node;
|
|
||||||
status_t err = BMediaRoster::CurrentRoster()->InstantiateDormantNode(
|
|
||||||
dormantInfo, &node, B_FLAVOR_IS_GLOBAL);
|
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return Connect(connection, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BMediaClient::Connect(BMediaConnection* connection,
|
|
||||||
const media_node& node)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
@@ -223,15 +213,6 @@ BMediaClient::ReleaseConnection(BMediaConnection* conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
BMediaClient::CountConnections() const
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
return fOutputs.CountItems()+fInputs.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
BMediaClient::CountInputs() const
|
BMediaClient::CountInputs() const
|
||||||
{
|
{
|
||||||
@@ -310,7 +291,7 @@ BMediaClient::Start(bool force)
|
|||||||
|
|
||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
for (int32 i = 0; i < CountOutputs(); i++) {
|
for (int32 i = 0; i < CountOutputs(); i++) {
|
||||||
media_node remoteNode = OutputAt(i)->fRemoteNode;
|
media_node remoteNode = OutputAt(i)->Connection().RemoteNode();
|
||||||
if (remoteNode.kind & B_TIME_SOURCE)
|
if (remoteNode.kind & B_TIME_SOURCE)
|
||||||
err = BMediaRoster::CurrentRoster()->StartTimeSource(
|
err = BMediaRoster::CurrentRoster()->StartTimeSource(
|
||||||
remoteNode, BTimeSource::RealTime());
|
remoteNode, BTimeSource::RealTime());
|
||||||
@@ -533,52 +514,38 @@ BMediaClient::_Deinit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BMediaClient::_TranslateConnection(BMediaConnection* dest,
|
|
||||||
BMediaConnection* source)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BMediaClient::_Connect(BMediaConnection* connection,
|
|
||||||
media_node node)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaClient::_ConnectInput(BMediaConnection* output,
|
BMediaClient::_ConnectInput(BMediaConnection* output,
|
||||||
BMediaConnection* input)
|
const media_connection& input)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return B_ERROR;
|
if (input.Destination() == media_destination::null)
|
||||||
|
return B_MEDIA_BAD_DESTINATION;
|
||||||
|
|
||||||
|
media_output ourOutput = output->Connection().MediaOutput();
|
||||||
|
media_input theirInput = input.MediaInput();
|
||||||
|
media_format format = output->AcceptedFormat();
|
||||||
|
|
||||||
|
return BMediaRoster::CurrentRoster()->Connect(ourOutput.source,
|
||||||
|
theirInput.destination, &format, &ourOutput, &theirInput,
|
||||||
|
BMediaRoster::B_CONNECT_MUTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaClient::_ConnectOutput(BMediaConnection* input,
|
BMediaClient::_ConnectOutput(BMediaConnection* input,
|
||||||
BMediaConnection* output)
|
const media_connection& output)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (output->Source() == media_source::null)
|
if (output.Source() == media_source::null)
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
|
|
||||||
media_input ourInput;
|
media_input ourInput = input->Connection().MediaInput();
|
||||||
media_output theirOutput;
|
media_output theirOutput = output.MediaOutput();
|
||||||
media_format format = input->AcceptedFormat();
|
media_format format = input->AcceptedFormat();
|
||||||
|
|
||||||
input->BuildMediaInput(&ourInput);
|
|
||||||
output->BuildMediaOutput(&theirOutput);
|
|
||||||
|
|
||||||
// TODO manage the node problems
|
// TODO manage the node problems
|
||||||
//fNode->ActivateInternalConnect(false);
|
//fNode->ActivateInternalConnect(false);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "MediaClientNode.h"
|
#include "MediaClientNode.h"
|
||||||
|
|
||||||
#include <MediaClient.h>
|
#include <MediaClient.h>
|
||||||
|
#include <MediaConnection.h>
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
#include <TimeSource.h>
|
#include <TimeSource.h>
|
||||||
|
|
||||||
@@ -28,11 +29,11 @@ BMediaClientNode::BMediaClientNode(const char* name,
|
|||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// Configure the node to do the requested jobs
|
// Configure the node to do the requested jobs
|
||||||
if (fOwner->Capabilities() & B_MEDIA_PLAYER)
|
if (fOwner->Kind() & B_MEDIA_PLAYER)
|
||||||
AddNodeKind(B_BUFFER_PRODUCER);
|
AddNodeKind(B_BUFFER_PRODUCER);
|
||||||
if (fOwner->Capabilities() & B_MEDIA_RECORDER)
|
if (fOwner->Kind() & B_MEDIA_RECORDER)
|
||||||
AddNodeKind(B_BUFFER_CONSUMER);
|
AddNodeKind(B_BUFFER_CONSUMER);
|
||||||
if (fOwner->Capabilities() & B_MEDIA_CONTROLLABLE)
|
if (fOwner->Kind() & B_MEDIA_CONTROLLABLE)
|
||||||
AddNodeKind(B_CONTROLLABLE);
|
AddNodeKind(B_CONTROLLABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +175,7 @@ BMediaClientNode::GetNextInput(int32* cookie,
|
|||||||
} else {
|
} else {
|
||||||
BMediaConnection* conn = fOwner->InputAt(*cookie);
|
BMediaConnection* conn = fOwner->InputAt(*cookie);
|
||||||
if (conn != NULL) {
|
if (conn != NULL) {
|
||||||
conn->BuildMediaInput(input);
|
*input = conn->MediaInput();
|
||||||
*cookie += 1;
|
*cookie += 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -230,7 +231,7 @@ BMediaClientNode::Connected(const media_source& source,
|
|||||||
return B_MEDIA_BAD_DESTINATION;
|
return B_MEDIA_BAD_DESTINATION;
|
||||||
|
|
||||||
conn->ConnectedCallback(source, format);
|
conn->ConnectedCallback(source, format);
|
||||||
conn->BuildMediaInput(outInput);
|
*outInput = conn->MediaInput();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +290,7 @@ BMediaClientNode::FormatSuggestionRequested(media_type type,
|
|||||||
} else {
|
} else {
|
||||||
// In that case we return just a very generic format.
|
// In that case we return just a very generic format.
|
||||||
media_format outFormat;
|
media_format outFormat;
|
||||||
outFormat.type = fOwner->Type();
|
outFormat.type = fOwner->MediaType();
|
||||||
*format = outFormat;
|
*format = outFormat;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -350,7 +351,7 @@ BMediaClientNode::GetNextOutput(int32* cookie, media_output* output)
|
|||||||
} else {
|
} else {
|
||||||
BMediaConnection* conn = fOwner->OutputAt(*cookie);
|
BMediaConnection* conn = fOwner->OutputAt(*cookie);
|
||||||
if (conn != NULL) {
|
if (conn != NULL) {
|
||||||
conn->BuildMediaOutput(output);
|
*output = conn->MediaOutput();
|
||||||
*cookie += 1;
|
*cookie += 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -413,15 +414,15 @@ BMediaClientNode::PrepareToConnect(const media_source& source,
|
|||||||
if (conn == NULL)
|
if (conn == NULL)
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
|
|
||||||
if (conn->fDestination != media_destination::null)
|
if (conn->Destination() != media_destination::null)
|
||||||
return B_MEDIA_ALREADY_CONNECTED;
|
return B_MEDIA_ALREADY_CONNECTED;
|
||||||
|
|
||||||
if (format->type != fOwner->Type())
|
if (format->type != fOwner->MediaType())
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
|
|
||||||
conn->fDestination = dest;
|
conn->fConnection.destination = dest;
|
||||||
conn->SetAcceptedFormat(*format);
|
conn->SetAcceptedFormat(*format);
|
||||||
*out_source = conn->fSource;
|
*out_source = conn->Source();
|
||||||
strcpy(name, Name());
|
strcpy(name, Name());
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -473,7 +474,7 @@ BMediaClientNode::Disconnect(const media_source& source,
|
|||||||
if (conn == NULL)
|
if (conn == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (source == conn->fSource && dest == conn->fDestination)
|
if (source == conn->Source() && dest == conn->Destination())
|
||||||
conn->Reset();
|
conn->Reset();
|
||||||
|
|
||||||
conn->DisconnectCallback(dest);
|
conn->DisconnectCallback(dest);
|
||||||
|
|||||||
@@ -5,17 +5,59 @@
|
|||||||
|
|
||||||
#include <MediaConnection.h>
|
#include <MediaConnection.h>
|
||||||
|
|
||||||
#include <MediaClient.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
BMediaConnection::BMediaConnection(BMediaClient* owner,
|
||||||
|
media_connection_kind kind,
|
||||||
|
media_connection_id id)
|
||||||
|
:
|
||||||
|
fOwner(owner),
|
||||||
|
fBind(NULL)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
_Init();
|
||||||
|
|
||||||
|
fConnection.kind = kind;
|
||||||
|
fConnection.id = id;
|
||||||
|
fConnection.client = fOwner->Client();
|
||||||
|
|
||||||
|
if (IsOutput()) {
|
||||||
|
fConnection.source.port = fOwner->fNode->ControlPort();
|
||||||
|
fConnection.source.id = fConnection.id;
|
||||||
|
|
||||||
|
fConnection.destination = media_destination::null;
|
||||||
|
} else {
|
||||||
|
// IsInput()
|
||||||
|
fConnection.destination.port = fOwner->fNode->ControlPort();
|
||||||
|
fConnection.destination.id = fConnection.id;
|
||||||
|
|
||||||
|
fConnection.source = media_source::null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMediaConnection::~BMediaConnection()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const media_connection&
|
||||||
|
BMediaConnection::Connection() const
|
||||||
|
{
|
||||||
|
return fConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BMediaConnection::IsOutput() const
|
BMediaConnection::IsOutput() const
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fKind == B_MEDIA_OUTPUT;
|
return fConnection.IsOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -24,49 +66,7 @@ BMediaConnection::IsInput() const
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fKind == B_MEDIA_INPUT;
|
return fConnection.IsInput();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BMediaConnection::BuildMediaOutput(media_output* output) const
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
output->format = AcceptedFormat();
|
|
||||||
output->node = fOwner->fNode->Node();
|
|
||||||
output->source = fSource;
|
|
||||||
output->source.port = fOwner->fNode->ControlPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BMediaConnection::BuildMediaInput(media_input* input) const
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
input->format = AcceptedFormat();
|
|
||||||
input->node = fOwner->fNode->Node();
|
|
||||||
input->destination = fDestination;
|
|
||||||
input->destination.port = fOwner->fNode->ControlPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const media_destination&
|
|
||||||
BMediaConnection::Destination() const
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
return fDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const media_source&
|
|
||||||
BMediaConnection::Source() const
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
return fSource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ BMediaConnection::SetAcceptedFormat(const media_format& format)
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
fFormat = format;
|
fConnection.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ BMediaConnection::AcceptedFormat() const
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fFormat;
|
return fConnection.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,11 +147,6 @@ BMediaConnection::Reset()
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (IsOutput())
|
|
||||||
fDestination = media_destination::null;
|
|
||||||
else
|
|
||||||
fSource = media_source::null;
|
|
||||||
|
|
||||||
delete fBufferGroup;
|
delete fBufferGroup;
|
||||||
fBufferGroup = NULL;
|
fBufferGroup = NULL;
|
||||||
|
|
||||||
@@ -180,52 +175,6 @@ BMediaConnection::SetHooks(process_hook processHook,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BMediaConnection::BMediaConnection(BMediaClient* owner,
|
|
||||||
media_connection_kind kind)
|
|
||||||
:
|
|
||||||
fKind(kind),
|
|
||||||
fOwner(owner),
|
|
||||||
fBind(NULL)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BMediaConnection::BMediaConnection(BMediaClient* owner,
|
|
||||||
const media_output& output)
|
|
||||||
:
|
|
||||||
fKind(B_MEDIA_OUTPUT),
|
|
||||||
fOwner(owner),
|
|
||||||
fBind(NULL)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BMediaConnection::BMediaConnection(BMediaClient* owner,
|
|
||||||
const media_input& input)
|
|
||||||
:
|
|
||||||
fKind(B_MEDIA_INPUT),
|
|
||||||
fOwner(owner),
|
|
||||||
fBind(NULL)
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BMediaConnection::~BMediaConnection()
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMediaConnection::SetBufferSize(size_t size)
|
BMediaConnection::SetBufferSize(size_t size)
|
||||||
{
|
{
|
||||||
@@ -266,7 +215,7 @@ void
|
|||||||
BMediaConnection::ConnectedCallback(const media_source& source,
|
BMediaConnection::ConnectedCallback(const media_source& source,
|
||||||
const media_format& format)
|
const media_format& format)
|
||||||
{
|
{
|
||||||
fSource = source;
|
fConnection.source = source;
|
||||||
SetAcceptedFormat(format);
|
SetAcceptedFormat(format);
|
||||||
|
|
||||||
if (fNotifyHook != NULL)
|
if (fNotifyHook != NULL)
|
||||||
@@ -279,8 +228,6 @@ BMediaConnection::ConnectedCallback(const media_source& source,
|
|||||||
void
|
void
|
||||||
BMediaConnection::DisconnectedCallback(const media_source& source)
|
BMediaConnection::DisconnectedCallback(const media_source& source)
|
||||||
{
|
{
|
||||||
fSource = media_source::null;
|
|
||||||
|
|
||||||
if (fNotifyHook != NULL)
|
if (fNotifyHook != NULL)
|
||||||
(*fNotifyHook)(B_DISCONNECTED, this);
|
(*fNotifyHook)(B_DISCONNECTED, this);
|
||||||
|
|
||||||
@@ -291,14 +238,13 @@ BMediaConnection::DisconnectedCallback(const media_source& source)
|
|||||||
void
|
void
|
||||||
BMediaConnection::ConnectCallback(const media_destination& destination)
|
BMediaConnection::ConnectCallback(const media_destination& destination)
|
||||||
{
|
{
|
||||||
fDestination = destination;
|
fConnection.destination = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMediaConnection::DisconnectCallback(const media_destination& destination)
|
BMediaConnection::DisconnectCallback(const media_destination& destination)
|
||||||
{
|
{
|
||||||
fDestination = destination;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -310,9 +256,34 @@ BMediaConnection::_Init()
|
|||||||
fBufferGroup = NULL;
|
fBufferGroup = NULL;
|
||||||
fNotifyHook = NULL;
|
fNotifyHook = NULL;
|
||||||
fProcessHook = NULL;
|
fProcessHook = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fSource = media_source::null;
|
|
||||||
fDestination = media_destination::null;
|
media_input
|
||||||
|
BMediaConnection::MediaInput() const
|
||||||
|
{
|
||||||
|
return fConnection.MediaInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
media_output
|
||||||
|
BMediaConnection::MediaOutput() const
|
||||||
|
{
|
||||||
|
return fConnection.MediaOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const media_source&
|
||||||
|
BMediaConnection::Source() const
|
||||||
|
{
|
||||||
|
return fConnection.Source();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const media_destination&
|
||||||
|
BMediaConnection::Destination() const
|
||||||
|
{
|
||||||
|
return fConnection.Destination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user