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 <MediaClientDefs.h>
#include <MediaConnection.h>
#include <MediaDefs.h>
#include <MediaNode.h>
@@ -21,6 +20,10 @@
namespace BPrivate { namespace media {
class BMediaConnection;
class BMediaInput;
class BMediaOutput;
// BMediaClient is a general purpose class allowing to create any kind
// of media_node. It automatically manage the expected behavior under
// 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
// BMediaClient::BeginConnection() and then Connect(), so that it
// 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
// input will be automatically forwarded to the output just after the
// ProcessFunc is called. The buffer is automatically recycled too.
// Beware that the binding operation is valid only for local connections
// which belong to this node, otherwise return B_ERROR.
virtual status_t Bind(BMediaConnection* input,
BMediaConnection* output);
virtual status_t Bind(BMediaInput* input,
BMediaOutput* output);
virtual status_t Unbind(BMediaConnection* input,
BMediaConnection* output);
virtual status_t Unbind(BMediaInput* input,
BMediaOutput* output);
// If the user want a particular format for a connection it should
// use BMediaConnection::SetAcceptedFormat(), if it's not specified
@@ -112,12 +116,12 @@ public:
int32 CountInputs() const;
int32 CountOutputs() const;
BMediaConnection* InputAt(int32 index) const;
BMediaConnection* OutputAt(int32 index) const;
BMediaInput* InputAt(int32 index) const;
BMediaOutput* OutputAt(int32 index) const;
BMediaConnection* FindInput(
BMediaInput* FindInput(
const media_connection& input) const;
BMediaConnection* FindOutput(
BMediaOutput* FindOutput(
const media_connection& output) const;
bool IsRunning() const;
@@ -164,20 +168,21 @@ public:
void* cookie = NULL);
protected:
virtual void BufferReceived(BBuffer* buffer,
BMediaInput* input);
// 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);
BMediaOutput* output);
// This is used when the user want to override the BeginConnection
// mechanism, for example to supply your BMediaConnection derived
// class. Take ownership of the object.
virtual void AddConnection(BMediaConnection* connection);
virtual void AddInput(BMediaInput* input);
virtual void AddOutput(BMediaOutput* output);
// Called from BMediaConnection
status_t DisconnectConnection(BMediaConnection* conn);
@@ -185,17 +190,17 @@ protected:
status_t ReleaseConnection(BMediaConnection* conn);
private:
BMediaConnection* FindInput(
BMediaInput* FindInput(
const media_destination& dest) const;
BMediaConnection* FindOutput(
BMediaOutput* FindOutput(
const media_source& source) const;
void _Init();
void _Deinit();
status_t _ConnectInput(BMediaConnection* output,
status_t _ConnectInput(BMediaOutput* output,
const media_connection& input);
status_t _ConnectOutput(BMediaConnection* input,
status_t _ConnectOutput(BMediaInput* input,
const media_connection& output);
status_t fInitErr;
@@ -215,8 +220,8 @@ private:
void* fNotifyCookie;
BObjectList<BMediaConnection> fInputs;
BObjectList<BMediaConnection> fOutputs;
BObjectList<BMediaInput> fInputs;
BObjectList<BMediaOutput> fOutputs;
media_connection_id fLastID;
+3 -1
View File
@@ -90,8 +90,10 @@ private:
uint32 padding[16];
friend class BMediaClient;
friend class BMediaConnection;
friend class BMediaClientNode;
friend class BMediaConnection;
friend class BMediaInput;
friend class BMediaOutput;
} media_connection;
+24 -3
View File
@@ -128,9 +128,6 @@ protected:
void DisconnectCallback(const media_destination& source);
private:
media_input MediaInput() const;
media_output MediaOutput() const;
const media_source& Source() 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*
BMediaClient::BeginConnection(media_connection_kind kind)
BMediaInput*
BMediaClient::BeginInput()
{
CALLED();
BMediaConnection* conn = new BMediaConnection(this, kind, fLastID++);
AddConnection(conn);
return conn;
BMediaInput* input = new BMediaInput(this, fLastID++);
AddInput(input);
return input;
}
BMediaOutput*
BMediaClient::BeginOutput()
{
CALLED();
BMediaOutput* output = new BMediaOutput(this, fLastID++);
AddOutput(output);
return output;
}
status_t
BMediaClient::Bind(BMediaConnection* input, BMediaConnection* output)
BMediaClient::Bind(BMediaInput* input, BMediaOutput* output)
{
CALLED();
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
else if (!input->IsInput() || !output->IsOutput())
return B_ERROR;
if (input == NULL
|| output == NULL)
return B_ERROR;
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
// TODO: Implement binding one input to more outputs.
if (input->fBind != NULL
|| output->fBind != NULL)
@@ -108,19 +117,17 @@ BMediaClient::Bind(BMediaConnection* input, BMediaConnection* output)
status_t
BMediaClient::Unbind(BMediaConnection* input, BMediaConnection* output)
BMediaClient::Unbind(BMediaInput* input, BMediaOutput* output)
{
CALLED();
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
else if (!input->IsInput() || !output->IsOutput())
return B_ERROR;
if (input == NULL
|| input == NULL)
return B_ERROR;
if (input->fOwner != this || output->fOwner != this)
return B_ERROR;
input->fBind = NULL;
output->fBind = NULL;
return B_OK;
@@ -144,9 +151,9 @@ BMediaClient::Connect(BMediaConnection* ourConnection,
CALLED();
if (ourConnection->IsOutput() && theirConnection.IsInput())
return _ConnectInput(ourConnection, theirConnection);
return _ConnectInput((BMediaOutput*)ourConnection, theirConnection);
else if (ourConnection->IsInput() && theirConnection.IsOutput())
return _ConnectOutput(ourConnection, theirConnection);
return _ConnectOutput((BMediaInput*)ourConnection, theirConnection);
return B_ERROR;
}
@@ -224,7 +231,7 @@ BMediaClient::CountOutputs() const
}
BMediaConnection*
BMediaInput*
BMediaClient::InputAt(int32 index) const
{
CALLED();
@@ -233,7 +240,7 @@ BMediaClient::InputAt(int32 index) const
}
BMediaConnection*
BMediaOutput*
BMediaClient::OutputAt(int32 index) const
{
CALLED();
@@ -242,7 +249,7 @@ BMediaClient::OutputAt(int32 index) const
}
BMediaConnection*
BMediaInput*
BMediaClient::FindInput(const media_connection& input) const
{
CALLED();
@@ -254,7 +261,7 @@ BMediaClient::FindInput(const media_connection& input) const
}
BMediaConnection*
BMediaOutput*
BMediaClient::FindOutput(const media_connection& output) const
{
CALLED();
@@ -266,7 +273,7 @@ BMediaClient::FindOutput(const media_connection& output) const
}
BMediaConnection*
BMediaInput*
BMediaClient::FindInput(const media_destination& dest) const
{
CALLED();
@@ -279,7 +286,7 @@ BMediaClient::FindInput(const media_destination& dest) const
}
BMediaConnection*
BMediaOutput*
BMediaClient::FindOutput(const media_source& source) const
{
CALLED();
@@ -453,29 +460,35 @@ BMediaClient::PerformanceTime() const
status_t
BMediaClient::SendBuffer(BBuffer* buffer, BMediaConnection* connection)
BMediaClient::SendBuffer(BBuffer* buffer, BMediaOutput* output)
{
CALLED();
return fNode->SendBuffer(buffer, connection);
return fNode->SendBuffer(buffer, output);
}
void
BMediaClient::AddConnection(BMediaConnection* connection)
BMediaClient::AddInput(BMediaInput* input)
{
CALLED();
if (connection->IsInput())
fInputs.AddItem(connection);
else
fOutputs.AddItem(connection);
fInputs.AddItem(input);
}
void
BMediaClient::BufferReceived(BMediaConnection* connection,
BBuffer* buffer)
BMediaClient::AddOutput(BMediaOutput* output)
{
CALLED();
fOutputs.AddItem(output);
}
void
BMediaClient::BufferReceived(BBuffer* buffer,
BMediaInput* connection)
{
CALLED();
@@ -532,7 +545,7 @@ BMediaClient::_Deinit()
status_t
BMediaClient::_ConnectInput(BMediaConnection* output,
BMediaClient::_ConnectInput(BMediaOutput* output,
const media_connection& input)
{
CALLED();
@@ -551,7 +564,7 @@ BMediaClient::_ConnectInput(BMediaConnection* output,
status_t
BMediaClient::_ConnectOutput(BMediaConnection* input,
BMediaClient::_ConnectOutput(BMediaInput* input,
const media_connection& output)
{
CALLED();
+15 -15
View File
@@ -147,7 +147,7 @@ BMediaClientNode::AcceptFormat(const media_destination& dest,
{
CALLED();
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL)
return B_MEDIA_BAD_DESTINATION;
@@ -173,7 +173,7 @@ BMediaClientNode::GetNextInput(int32* cookie,
*cookie = -1;
input = NULL;
} else {
BMediaConnection* conn = fOwner->InputAt(*cookie);
BMediaInput* conn = fOwner->InputAt(*cookie);
if (conn != NULL) {
*input = conn->MediaInput();
*cookie += 1;
@@ -209,7 +209,7 @@ BMediaClientNode::GetLatencyFor(const media_destination& dest,
{
CALLED();
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL)
return B_MEDIA_BAD_DESTINATION;
@@ -226,7 +226,7 @@ BMediaClientNode::Connected(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL)
return B_MEDIA_BAD_DESTINATION;
@@ -242,7 +242,7 @@ BMediaClientNode::Disconnected(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL)
return;
@@ -257,7 +257,7 @@ BMediaClientNode::FormatChanged(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn == NULL)
return B_MEDIA_BAD_DESTINATION;
@@ -303,7 +303,7 @@ BMediaClientNode::FormatProposal(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL)
return B_MEDIA_BAD_DESTINATION;
@@ -349,7 +349,7 @@ BMediaClientNode::GetNextOutput(int32* cookie, media_output* output)
*cookie = -1;
output = NULL;
} else {
BMediaConnection* conn = fOwner->OutputAt(*cookie);
BMediaOutput* conn = fOwner->OutputAt(*cookie);
if (conn != NULL) {
*output = conn->MediaOutput();
*cookie += 1;
@@ -374,7 +374,7 @@ BMediaClientNode::SetBufferGroup(const media_source& source, BBufferGroup* group
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL)
return B_MEDIA_BAD_SOURCE;
@@ -410,7 +410,7 @@ BMediaClientNode::PrepareToConnect(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL)
return B_MEDIA_BAD_SOURCE;
@@ -437,7 +437,7 @@ BMediaClientNode::Connect(status_t status, const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL)
return;
@@ -462,7 +462,7 @@ BMediaClientNode::Disconnect(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn == NULL)
return;
@@ -479,7 +479,7 @@ BMediaClientNode::EnableOutput(const media_source& source,
{
CALLED();
BMediaConnection* conn = fOwner->FindOutput(source);
BMediaOutput* conn = fOwner->FindOutput(source);
if (conn != NULL) {
conn->fOutputEnabled = enabled;
return;
@@ -569,10 +569,10 @@ BMediaClientNode::_HandleBuffer(BBuffer* buffer)
media_destination dest;
dest.id = buffer->Header()->destination;
BMediaConnection* conn = fOwner->FindInput(dest);
BMediaInput* conn = fOwner->FindInput(dest);
if (conn != NULL)
fOwner->BufferReceived(conn, buffer);
fOwner->BufferReceived(buffer, conn);
// 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&
BMediaConnection::Source() const
{
@@ -298,3 +284,31 @@ void BMediaConnection::_ReservedMediaConnection7() {}
void BMediaConnection::_ReservedMediaConnection8() {}
void BMediaConnection::_ReservedMediaConnection9() {}
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
#define DELAYED_MODE 1
#define SNOOZE_FOR 1000000
#define SNOOZE_FOR 10000000
#endif
@@ -57,8 +57,8 @@ void _ConsumerProducerTest()
{
_InitClients(false);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT);
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT);
BMediaOutput* output = sProducer->BeginOutput();
BMediaInput* input = sConsumer->BeginInput();
output->SetAcceptedFormat(_BuildRawAudioFormat());
input->SetAcceptedFormat(_BuildRawAudioFormat());
@@ -79,8 +79,8 @@ void _ProducerConsumerTest()
{
_InitClients(false);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT);
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT);
BMediaOutput* output = sProducer->BeginOutput();
BMediaInput* input = sConsumer->BeginInput();
assert(sProducer->Connect(output, input) == B_OK);
@@ -98,11 +98,11 @@ void _ProducerFilterConsumerTest()
{
_InitClients(true);
BMediaConnection* output = sProducer->BeginConnection(B_MEDIA_OUTPUT);
BMediaConnection* input = sConsumer->BeginConnection(B_MEDIA_INPUT);
BMediaOutput* output = sProducer->BeginOutput();
BMediaInput* input = sConsumer->BeginInput();
BMediaConnection* filterInput = sFilter->BeginConnection(B_MEDIA_INPUT);
BMediaConnection* filterOutput = sFilter->BeginConnection(B_MEDIA_OUTPUT);
BMediaInput* filterInput = sFilter->BeginInput();
BMediaOutput* filterOutput = sFilter->BeginOutput();
assert(sFilter->Bind(filterInput, filterOutput) == B_OK);