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 <MediaAddOn.h>
|
||||
#include <MediaClientDefs.h>
|
||||
#include <MediaConnection.h>
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaNode.h>
|
||||
@@ -19,19 +20,6 @@
|
||||
|
||||
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
|
||||
// of media_node. It automatically manage the expected behavior under
|
||||
@@ -56,20 +44,25 @@ public:
|
||||
...);
|
||||
|
||||
// TODO: Should allow BControllable capabilities
|
||||
// TODO: Add file interface
|
||||
// TODO: Offline mode is still missing
|
||||
|
||||
BMediaClient(const char* name,
|
||||
media_type type
|
||||
= B_MEDIA_UNKNOWN_TYPE,
|
||||
media_client_kind
|
||||
capabilities = B_MEDIA_PLAYER
|
||||
kind = B_MEDIA_PLAYER
|
||||
& B_MEDIA_RECORDER);
|
||||
|
||||
virtual ~BMediaClient();
|
||||
|
||||
status_t InitCheck() const;
|
||||
const media_client& Client() const;
|
||||
|
||||
// Return the capabilities of this BMediaClient instance.
|
||||
media_client_kind Capabilities() const;
|
||||
media_type Type() const;
|
||||
media_client_kind Kind() const;
|
||||
media_type MediaType() const;
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
// To connect pass the BMediaConnection to this class or to another BMediaClient,
|
||||
// also in another team the connection object will be valid.
|
||||
@@ -84,11 +77,6 @@ public:
|
||||
// will automatically connect to this node.
|
||||
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
|
||||
// input will be automatically forwarded to the output just after the
|
||||
// ProcessFunc is called. The buffer is automatically recycled too.
|
||||
@@ -110,18 +98,20 @@ public:
|
||||
BMediaConnection* theirConnection);
|
||||
|
||||
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,
|
||||
const media_node& node);
|
||||
const media_client& client);
|
||||
|
||||
// Disconnect any connection belonging to this object, to disconnect
|
||||
// a single connection use BMediaConnection::Disconnect().
|
||||
virtual status_t Disconnect();
|
||||
|
||||
int32 CountConnections() const;
|
||||
int32 CountInputs() const;
|
||||
int32 CountOutputs() const;
|
||||
|
||||
BMediaConnection* InputAt(int32 index) const;
|
||||
BMediaConnection* OutputAt(int32 index) const;
|
||||
|
||||
@@ -164,14 +154,6 @@ public:
|
||||
// when run_mode != B_OFFLINE.
|
||||
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.
|
||||
// Default version just return NULL.
|
||||
virtual BMediaAddOn* AddOn(int32* id) const;
|
||||
@@ -180,6 +162,13 @@ public:
|
||||
void* cookie = NULL);
|
||||
|
||||
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,
|
||||
BBuffer* buffer);
|
||||
|
||||
@@ -192,24 +181,20 @@ protected:
|
||||
status_t DisconnectConnection(BMediaConnection* conn);
|
||||
status_t ResetConnection(BMediaConnection* conn);
|
||||
status_t ReleaseConnection(BMediaConnection* conn);
|
||||
|
||||
private:
|
||||
|
||||
void _Init();
|
||||
void _Deinit();
|
||||
|
||||
status_t _TranslateConnection(BMediaConnection* dest,
|
||||
BMediaConnection* source);
|
||||
|
||||
status_t _Connect(BMediaConnection* conn,
|
||||
media_node node);
|
||||
status_t _ConnectInput(BMediaConnection* output,
|
||||
BMediaConnection* input);
|
||||
const media_connection& input);
|
||||
status_t _ConnectOutput(BMediaConnection* input,
|
||||
BMediaConnection* output);
|
||||
const media_connection& output);
|
||||
|
||||
status_t fInitErr;
|
||||
|
||||
media_client_kind fCapabilities;
|
||||
media_client fClient;
|
||||
|
||||
bool fRunning;
|
||||
BMediaClientNode* fNode;
|
||||
@@ -227,6 +212,9 @@ private:
|
||||
BObjectList<BMediaConnection> fInputs;
|
||||
BObjectList<BMediaConnection> fOutputs;
|
||||
|
||||
int32 fLastInputID;
|
||||
int32 fLastOutputID;
|
||||
|
||||
virtual void _ReservedMediaClient0();
|
||||
virtual void _ReservedMediaClient1();
|
||||
virtual void _ReservedMediaClient2();
|
||||
|
||||
@@ -9,20 +9,15 @@
|
||||
#include <BufferGroup.h>
|
||||
#include <MediaDefs.h>
|
||||
|
||||
#include <MediaClient.h>
|
||||
#include <MediaClientDefs.h>
|
||||
|
||||
#include "MediaClientNode.h"
|
||||
|
||||
|
||||
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.
|
||||
// It represents a connection between two nodes and allow to create complex
|
||||
// nodes without dealing with the unneeded complexity. Two local connections,
|
||||
@@ -51,7 +46,8 @@ public:
|
||||
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,
|
||||
BBuffer* buffer);
|
||||
|
||||
@@ -63,15 +59,16 @@ public:
|
||||
|
||||
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
|
||||
// it would be worthwile to have a private implementation
|
||||
// so that we can better model the differences and avoid
|
||||
// problems.
|
||||
bool IsOutput() const;
|
||||
bool IsInput() const;
|
||||
|
||||
const media_destination& Destination() const;
|
||||
const media_source& Source() const;
|
||||
bool IsOutput() const;
|
||||
|
||||
bool HasBinding() const;
|
||||
BMediaConnection* Binding() const;
|
||||
@@ -119,11 +116,8 @@ public:
|
||||
|
||||
protected:
|
||||
BMediaConnection(BMediaClient* owner,
|
||||
media_connection_kind kind);
|
||||
BMediaConnection(BMediaClient* owner,
|
||||
const media_output& output);
|
||||
BMediaConnection(BMediaClient* owner,
|
||||
const media_input& input);
|
||||
media_connection_kind kind,
|
||||
media_connection_id id);
|
||||
|
||||
// TODO: All notifications should be done into private callbacks like this.
|
||||
void ConnectedCallback(const media_source& source,
|
||||
@@ -134,18 +128,17 @@ protected:
|
||||
void DisconnectCallback(const media_destination& source);
|
||||
|
||||
private:
|
||||
void BuildMediaOutput(media_output* output) const;
|
||||
void BuildMediaInput(media_input* output) const;
|
||||
media_input MediaInput() const;
|
||||
media_output MediaOutput() const;
|
||||
|
||||
const media_source& Source() const;
|
||||
const media_destination& Destination() const;
|
||||
|
||||
void _Init();
|
||||
|
||||
bool fConnected;
|
||||
bool fOutputEnabled;
|
||||
media_connection fConnection;
|
||||
|
||||
media_connection_kind fKind;
|
||||
BMediaClient* fOwner;
|
||||
media_node fOwnerNode;
|
||||
team_id fOwnerTeam;
|
||||
|
||||
// A connection might be binded so that it will automatically
|
||||
// forward or receive the data from/to a local BMediaConnection,
|
||||
@@ -156,18 +149,14 @@ private:
|
||||
notify_hook fNotifyHook;
|
||||
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;
|
||||
bigtime_t fBufferDuration;
|
||||
|
||||
BBufferGroup* fBufferGroup;
|
||||
|
||||
bool fConnected;
|
||||
bool fOutputEnabled;
|
||||
|
||||
virtual void _ReservedMediaConnection0();
|
||||
virtual void _ReservedMediaConnection1();
|
||||
virtual void _ReservedMediaConnection2();
|
||||
|
||||
Reference in New Issue
Block a user