MediaClient: Introduce BMediaInput and BMediaOutput

This commit is contained in:
Dario Casalinuovo
2016-11-25 17:38:44 +01:00
parent eebedf8f1a
commit 6d0255216e
7 changed files with 154 additions and 99 deletions
+26 -21
View File
@@ -11,7 +11,6 @@
#include <MediaAddOn.h> #include <MediaAddOn.h>
#include <MediaClientDefs.h> #include <MediaClientDefs.h>
#include <MediaConnection.h>
#include <MediaDefs.h> #include <MediaDefs.h>
#include <MediaNode.h> #include <MediaNode.h>
@@ -21,6 +20,10 @@
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
class BMediaConnection;
class BMediaInput;
class BMediaOutput;
// 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
// different run modes, and allow to specify the different capabilities // different run modes, and allow to specify the different capabilities
@@ -75,18 +78,19 @@ public:
// You can pass the object returned by this function to another // You can pass the object returned by this function to another
// BMediaClient::BeginConnection() and then Connect(), so that it // BMediaClient::BeginConnection() and then Connect(), so that it
// will automatically connect to this node. // will automatically connect to this node.
virtual BMediaConnection* BeginConnection(media_connection_kind kind); virtual BMediaInput* BeginInput();
virtual BMediaOutput* BeginOutput();
// 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.
// Beware that the binding operation is valid only for local connections // Beware that the binding operation is valid only for local connections
// which belong to this node, otherwise return B_ERROR. // which belong to this node, otherwise return B_ERROR.
virtual status_t Bind(BMediaConnection* input, virtual status_t Bind(BMediaInput* input,
BMediaConnection* output); BMediaOutput* output);
virtual status_t Unbind(BMediaConnection* input, virtual status_t Unbind(BMediaInput* input,
BMediaConnection* output); BMediaOutput* output);
// If the user want a particular format for a connection it should // If the user want a particular format for a connection it should
// use BMediaConnection::SetAcceptedFormat(), if it's not specified // use BMediaConnection::SetAcceptedFormat(), if it's not specified
@@ -112,12 +116,12 @@ public:
int32 CountInputs() const; int32 CountInputs() const;
int32 CountOutputs() const; int32 CountOutputs() const;
BMediaConnection* InputAt(int32 index) const; BMediaInput* InputAt(int32 index) const;
BMediaConnection* OutputAt(int32 index) const; BMediaOutput* OutputAt(int32 index) const;
BMediaConnection* FindInput( BMediaInput* FindInput(
const media_connection& input) const; const media_connection& input) const;
BMediaConnection* FindOutput( BMediaOutput* FindOutput(
const media_connection& output) const; const media_connection& output) const;
bool IsRunning() const; bool IsRunning() const;
@@ -164,20 +168,21 @@ public:
void* cookie = NULL); void* cookie = NULL);
protected: protected:
virtual void BufferReceived(BBuffer* buffer,
BMediaInput* input);
// When a connection is not binded with another, it's your job to send // When a connection is not binded with another, it's your job to send
// the buffer to the connection you want. You might want // the buffer to the connection you want. You might want
// to ovverride it so that you can track something, in this case // to ovverride it so that you can track something, in this case
// be sure to call the base version. // be sure to call the base version.
virtual status_t SendBuffer(BBuffer* buffer, virtual status_t SendBuffer(BBuffer* buffer,
BMediaConnection* connection); BMediaOutput* output);
virtual void BufferReceived(BMediaConnection* connection,
BBuffer* buffer);
// This is used when the user want to override the BeginConnection // This is used when the user want to override the BeginConnection
// mechanism, for example to supply your BMediaConnection derived // mechanism, for example to supply your BMediaConnection derived
// class. Take ownership of the object. // class. Take ownership of the object.
virtual void AddConnection(BMediaConnection* connection); virtual void AddInput(BMediaInput* input);
virtual void AddOutput(BMediaOutput* output);
// Called from BMediaConnection // Called from BMediaConnection
status_t DisconnectConnection(BMediaConnection* conn); status_t DisconnectConnection(BMediaConnection* conn);
@@ -185,17 +190,17 @@ protected:
status_t ReleaseConnection(BMediaConnection* conn); status_t ReleaseConnection(BMediaConnection* conn);
private: private:
BMediaConnection* FindInput( BMediaInput* FindInput(
const media_destination& dest) const; const media_destination& dest) const;
BMediaConnection* FindOutput( BMediaOutput* FindOutput(
const media_source& source) const; const media_source& source) const;
void _Init(); void _Init();
void _Deinit(); void _Deinit();
status_t _ConnectInput(BMediaConnection* output, status_t _ConnectInput(BMediaOutput* output,
const media_connection& input); const media_connection& input);
status_t _ConnectOutput(BMediaConnection* input, status_t _ConnectOutput(BMediaInput* input,
const media_connection& output); const media_connection& output);
status_t fInitErr; status_t fInitErr;
@@ -215,8 +220,8 @@ private:
void* fNotifyCookie; void* fNotifyCookie;
BObjectList<BMediaConnection> fInputs; BObjectList<BMediaInput> fInputs;
BObjectList<BMediaConnection> fOutputs; BObjectList<BMediaOutput> fOutputs;
media_connection_id fLastID; media_connection_id fLastID;
+3 -1
View File
@@ -90,8 +90,10 @@ private:
uint32 padding[16]; uint32 padding[16];
friend class BMediaClient; friend class BMediaClient;
friend class BMediaConnection;
friend class BMediaClientNode; friend class BMediaClientNode;
friend class BMediaConnection;
friend class BMediaInput;
friend class BMediaOutput;
} media_connection; } media_connection;
+24 -3
View File
@@ -128,9 +128,6 @@ protected:
void DisconnectCallback(const media_destination& source); void DisconnectCallback(const media_destination& source);
private: private:
media_input MediaInput() const;
media_output MediaOutput() const;
const media_source& Source() const; const media_source& Source() const;
const media_destination& Destination() const; const media_destination& Destination() const;
@@ -175,6 +172,30 @@ private:
}; };
class BMediaInput : public BMediaConnection {
public:
BMediaInput(BMediaClient* owner,
media_connection_id id);
private:
media_input MediaInput() const;
friend class BMediaClientNode;
};
class BMediaOutput : public BMediaConnection {
public:
BMediaOutput(BMediaClient* owner,
media_connection_id id);
private:
media_output MediaOutput() const;
friend class BMediaClientNode;
};
} }
} }
+49 -36
View File
@@ -71,31 +71,40 @@ BMediaClient::MediaType() const
} }
BMediaConnection* BMediaInput*
BMediaClient::BeginConnection(media_connection_kind kind) BMediaClient::BeginInput()
{ {
CALLED(); CALLED();
BMediaConnection* conn = new BMediaConnection(this, kind, fLastID++); BMediaInput* input = new BMediaInput(this, fLastID++);
AddConnection(conn); AddInput(input);
return conn; return input;
}
BMediaOutput*
BMediaClient::BeginOutput()
{
CALLED();
BMediaOutput* output = new BMediaOutput(this, fLastID++);
AddOutput(output);
return output;
} }
status_t status_t
BMediaClient::Bind(BMediaConnection* input, BMediaConnection* output) BMediaClient::Bind(BMediaInput* input, BMediaOutput* output)
{ {
CALLED(); CALLED();
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
else if (!input->IsInput() || !output->IsOutput())
return B_ERROR;
if (input == NULL if (input == NULL
|| output == NULL) || output == NULL)
return B_ERROR; return B_ERROR;
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
// TODO: Implement binding one input to more outputs. // TODO: Implement binding one input to more outputs.
if (input->fBind != NULL if (input->fBind != NULL
|| output->fBind != NULL) || output->fBind != NULL)
@@ -108,19 +117,17 @@ BMediaClient::Bind(BMediaConnection* input, BMediaConnection* output)
status_t status_t
BMediaClient::Unbind(BMediaConnection* input, BMediaConnection* output) BMediaClient::Unbind(BMediaInput* input, BMediaOutput* output)
{ {
CALLED(); CALLED();
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
else if (!input->IsInput() || !output->IsOutput())
return B_ERROR;
if (input == NULL if (input == NULL
|| input == NULL) || input == NULL)
return B_ERROR; return B_ERROR;
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
input->fBind = NULL; input->fBind = NULL;
output->fBind = NULL; output->fBind = NULL;
return B_OK; return B_OK;
@@ -144,9 +151,9 @@ BMediaClient::Connect(BMediaConnection* ourConnection,
CALLED(); CALLED();
if (ourConnection->IsOutput() && theirConnection.IsInput()) if (ourConnection->IsOutput() && theirConnection.IsInput())
return _ConnectInput(ourConnection, theirConnection); return _ConnectInput((BMediaOutput*)ourConnection, theirConnection);
else if (ourConnection->IsInput() && theirConnection.IsOutput()) else if (ourConnection->IsInput() && theirConnection.IsOutput())
return _ConnectOutput(ourConnection, theirConnection); return _ConnectOutput((BMediaInput*)ourConnection, theirConnection);
return B_ERROR; return B_ERROR;
} }
@@ -224,7 +231,7 @@ BMediaClient::CountOutputs() const
} }
BMediaConnection* BMediaInput*
BMediaClient::InputAt(int32 index) const BMediaClient::InputAt(int32 index) const
{ {
CALLED(); CALLED();
@@ -233,7 +240,7 @@ BMediaClient::InputAt(int32 index) const
} }
BMediaConnection* BMediaOutput*
BMediaClient::OutputAt(int32 index) const BMediaClient::OutputAt(int32 index) const
{ {
CALLED(); CALLED();
@@ -242,7 +249,7 @@ BMediaClient::OutputAt(int32 index) const
} }
BMediaConnection* BMediaInput*
BMediaClient::FindInput(const media_connection& input) const BMediaClient::FindInput(const media_connection& input) const
{ {
CALLED(); CALLED();
@@ -254,7 +261,7 @@ BMediaClient::FindInput(const media_connection& input) const
} }
BMediaConnection* BMediaOutput*
BMediaClient::FindOutput(const media_connection& output) const BMediaClient::FindOutput(const media_connection& output) const
{ {
CALLED(); CALLED();
@@ -266,7 +273,7 @@ BMediaClient::FindOutput(const media_connection& output) const
} }
BMediaConnection* BMediaInput*
BMediaClient::FindInput(const media_destination& dest) const BMediaClient::FindInput(const media_destination& dest) const
{ {
CALLED(); CALLED();
@@ -279,7 +286,7 @@ BMediaClient::FindInput(const media_destination& dest) const
} }
BMediaConnection* BMediaOutput*
BMediaClient::FindOutput(const media_source& source) const BMediaClient::FindOutput(const media_source& source) const
{ {
CALLED(); CALLED();
@@ -453,29 +460,35 @@ BMediaClient::PerformanceTime() const
status_t status_t
BMediaClient::SendBuffer(BBuffer* buffer, BMediaConnection* connection) BMediaClient::SendBuffer(BBuffer* buffer, BMediaOutput* output)
{ {
CALLED(); CALLED();
return fNode->SendBuffer(buffer, connection); return fNode->SendBuffer(buffer, output);
} }
void void
BMediaClient::AddConnection(BMediaConnection* connection) BMediaClient::AddInput(BMediaInput* input)
{ {
CALLED(); CALLED();
if (connection->IsInput()) fInputs.AddItem(input);
fInputs.AddItem(connection);
else
fOutputs.AddItem(connection);
} }
void void
BMediaClient::BufferReceived(BMediaConnection* connection, BMediaClient::AddOutput(BMediaOutput* output)
BBuffer* buffer) {
CALLED();
fOutputs.AddItem(output);
}
void
BMediaClient::BufferReceived(BBuffer* buffer,
BMediaInput* connection)
{ {
CALLED(); CALLED();
@@ -532,7 +545,7 @@ BMediaClient::_Deinit()
status_t status_t
BMediaClient::_ConnectInput(BMediaConnection* output, BMediaClient::_ConnectInput(BMediaOutput* output,
const media_connection& input) const media_connection& input)
{ {
CALLED(); CALLED();
@@ -551,7 +564,7 @@ BMediaClient::_ConnectInput(BMediaConnection* output,
status_t status_t
BMediaClient::_ConnectOutput(BMediaConnection* input, BMediaClient::_ConnectOutput(BMediaInput* input,
const media_connection& output) const media_connection& output)
{ {
CALLED(); CALLED();
+15 -15
View File
@@ -147,7 +147,7 @@ BMediaClientNode::AcceptFormat(const media_destination& dest,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
@@ -173,7 +173,7 @@ BMediaClientNode::GetNextInput(int32* cookie,
*cookie = -1; *cookie = -1;
input = NULL; input = NULL;
} else { } else {
BMediaConnection* conn = fOwner->InputAt(*cookie); BMediaInput* conn = fOwner->InputAt(*cookie);
if (conn != NULL) { if (conn != NULL) {
*input = conn->MediaInput(); *input = conn->MediaInput();
*cookie += 1; *cookie += 1;
@@ -209,7 +209,7 @@ BMediaClientNode::GetLatencyFor(const media_destination& dest,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
@@ -226,7 +226,7 @@ BMediaClientNode::Connected(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
@@ -242,7 +242,7 @@ BMediaClientNode::Disconnected(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL) if (conn == NULL)
return; return;
@@ -257,7 +257,7 @@ BMediaClientNode::FormatChanged(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
@@ -303,7 +303,7 @@ BMediaClientNode::FormatProposal(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
@@ -349,7 +349,7 @@ BMediaClientNode::GetNextOutput(int32* cookie, media_output* output)
*cookie = -1; *cookie = -1;
output = NULL; output = NULL;
} else { } else {
BMediaConnection* conn = fOwner->OutputAt(*cookie); BMediaOutput* conn = fOwner->OutputAt(*cookie);
if (conn != NULL) { if (conn != NULL) {
*output = conn->MediaOutput(); *output = conn->MediaOutput();
*cookie += 1; *cookie += 1;
@@ -374,7 +374,7 @@ BMediaClientNode::SetBufferGroup(const media_source& source, BBufferGroup* group
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_SOURCE; return B_MEDIA_BAD_SOURCE;
@@ -410,7 +410,7 @@ BMediaClientNode::PrepareToConnect(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL) if (conn == NULL)
return B_MEDIA_BAD_SOURCE; return B_MEDIA_BAD_SOURCE;
@@ -437,7 +437,7 @@ BMediaClientNode::Connect(status_t status, const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL) if (conn == NULL)
return; return;
@@ -462,7 +462,7 @@ BMediaClientNode::Disconnect(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL) if (conn == NULL)
return; return;
@@ -479,7 +479,7 @@ BMediaClientNode::EnableOutput(const media_source& source,
{ {
CALLED(); CALLED();
BMediaConnection* conn = fOwner->FindOutput(source); BMediaOutput* conn = fOwner->FindOutput(source);
if (conn != NULL) { if (conn != NULL) {
conn->fOutputEnabled = enabled; conn->fOutputEnabled = enabled;
return; return;
@@ -569,10 +569,10 @@ BMediaClientNode::_HandleBuffer(BBuffer* buffer)
media_destination dest; media_destination dest;
dest.id = buffer->Header()->destination; dest.id = buffer->Header()->destination;
BMediaConnection* conn = fOwner->FindInput(dest); BMediaInput* conn = fOwner->FindInput(dest);
if (conn != NULL) if (conn != NULL)
fOwner->BufferReceived(conn, buffer); fOwner->BufferReceived(buffer, conn);
// TODO: this should be logged someway // TODO: this should be logged someway
} }
+28 -14
View File
@@ -259,20 +259,6 @@ BMediaConnection::_Init()
} }
media_input
BMediaConnection::MediaInput() const
{
return fConnection.MediaInput();
}
media_output
BMediaConnection::MediaOutput() const
{
return fConnection.MediaOutput();
}
const media_source& const media_source&
BMediaConnection::Source() const BMediaConnection::Source() const
{ {
@@ -298,3 +284,31 @@ void BMediaConnection::_ReservedMediaConnection7() {}
void BMediaConnection::_ReservedMediaConnection8() {} void BMediaConnection::_ReservedMediaConnection8() {}
void BMediaConnection::_ReservedMediaConnection9() {} void BMediaConnection::_ReservedMediaConnection9() {}
void BMediaConnection::_ReservedMediaConnection10() {} void BMediaConnection::_ReservedMediaConnection10() {}
BMediaInput::BMediaInput(BMediaClient* owner, media_connection_id id)
:
BMediaConnection(owner, B_MEDIA_INPUT, id)
{
}
media_input
BMediaInput::MediaInput() const
{
return Connection().MediaInput();
}
BMediaOutput::BMediaOutput(BMediaClient* owner, media_connection_id id)
:
BMediaConnection(owner, B_MEDIA_OUTPUT, id)
{
}
media_output
BMediaOutput::MediaOutput() const
{
return Connection().MediaOutput();
}
@@ -14,7 +14,7 @@
#ifdef DEBUG #ifdef DEBUG
#define DELAYED_MODE 1 #define DELAYED_MODE 1
#define SNOOZE_FOR 1000000 #define SNOOZE_FOR 10000000
#endif #endif
@@ -57,8 +57,8 @@ void _ConsumerProducerTest()
{ {
_InitClients(false); _InitClients(false);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT); BMediaOutput* output = sProducer->BeginOutput();
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT); BMediaInput* input = sConsumer->BeginInput();
output->SetAcceptedFormat(_BuildRawAudioFormat()); output->SetAcceptedFormat(_BuildRawAudioFormat());
input->SetAcceptedFormat(_BuildRawAudioFormat()); input->SetAcceptedFormat(_BuildRawAudioFormat());
@@ -79,8 +79,8 @@ void _ProducerConsumerTest()
{ {
_InitClients(false); _InitClients(false);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT); BMediaOutput* output = sProducer->BeginOutput();
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT); BMediaInput* input = sConsumer->BeginInput();
assert(sProducer->Connect(output, input) == B_OK); assert(sProducer->Connect(output, input) == B_OK);
@@ -98,11 +98,11 @@ void _ProducerFilterConsumerTest()
{ {
_InitClients(true); _InitClients(true);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT); BMediaOutput* output = sProducer->BeginOutput();
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT); BMediaInput* input = sConsumer->BeginInput();
BMediaConnection* filterInput = sFilter->BeginConnection(B_MEDIA_INPUT); BMediaInput* filterInput = sFilter->BeginInput();
BMediaConnection* filterOutput = sFilter->BeginConnection(B_MEDIA_OUTPUT); BMediaOutput* filterOutput = sFilter->BeginOutput();
assert(sFilter->Bind(filterInput, filterOutput) == B_OK); assert(sFilter->Bind(filterInput, filterOutput) == B_OK);