BMediaRecorder: Rework to allow external connections
* This required to review various parts of the code, and isn't probably still perfect. The main problem was an attributes hell where redondance created a lot of problems, all this data is now controlled mostly by the node. * Header indentation changes needed too.
This commit is contained in:
@@ -46,6 +46,7 @@ public:
|
|||||||
|
|
||||||
void SetAcceptedFormat(
|
void SetAcceptedFormat(
|
||||||
const media_format& format);
|
const media_format& format);
|
||||||
|
const media_format& AcceptedFormat() const;
|
||||||
|
|
||||||
virtual status_t Start(bool force = false);
|
virtual status_t Start(bool force = false);
|
||||||
virtual status_t Stop(bool force = false);
|
virtual status_t Stop(bool force = false);
|
||||||
@@ -66,13 +67,18 @@ public:
|
|||||||
|
|
||||||
const media_format& Format() const;
|
const media_format& Format() const;
|
||||||
|
|
||||||
const media_output& MediaOutput() const;
|
|
||||||
const media_input& MediaInput() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Get the producer node source
|
||||||
|
const media_source& MediaSource() const;
|
||||||
|
// This is the our own input
|
||||||
|
const media_input& MediaInput() const;
|
||||||
|
|
||||||
virtual void BufferReceived(void* buffer, size_t size,
|
virtual void BufferReceived(void* buffer, size_t size,
|
||||||
const media_header& header);
|
const media_header& header);
|
||||||
|
|
||||||
|
status_t SetUpConnection(media_input ourInput,
|
||||||
|
media_source outputSource);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
status_t _Connect(const media_node& mediaNode,
|
status_t _Connect(const media_node& mediaNode,
|
||||||
@@ -98,10 +104,9 @@ private:
|
|||||||
NotifyFunc fNotifyHook;
|
NotifyFunc fNotifyHook;
|
||||||
|
|
||||||
media_node fOutputNode;
|
media_node fOutputNode;
|
||||||
media_output fOutput;
|
media_source fOutputSource;
|
||||||
|
|
||||||
BMediaRecorderNode* fNode;
|
BMediaRecorderNode* fNode;
|
||||||
media_input fInput;
|
|
||||||
|
|
||||||
void* fBufferCookie;
|
void* fBufferCookie;
|
||||||
uint32 fPadding[32];
|
uint32 fPadding[32];
|
||||||
|
|||||||
@@ -20,44 +20,45 @@ class BMediaRecorder;
|
|||||||
class BMediaRecorderNode : public BMediaEventLooper,
|
class BMediaRecorderNode : public BMediaEventLooper,
|
||||||
public BBufferConsumer {
|
public BBufferConsumer {
|
||||||
public:
|
public:
|
||||||
BMediaRecorderNode(const char* name,
|
BMediaRecorderNode(const char* name,
|
||||||
BMediaRecorder* recorder,
|
BMediaRecorder* recorder,
|
||||||
media_type type
|
media_type type
|
||||||
= B_MEDIA_UNKNOWN_TYPE);
|
= B_MEDIA_UNKNOWN_TYPE);
|
||||||
|
|
||||||
// TODO these are not thread safe; we should fix that...
|
// TODO these are not thread safe; we should fix that...
|
||||||
void SetAcceptedFormat(const media_format& format);
|
void SetAcceptedFormat(const media_format& format);
|
||||||
|
const media_format& AcceptedFormat() const;
|
||||||
|
|
||||||
status_t GetInput(media_input* outInput);
|
void GetInput(media_input* input);
|
||||||
|
|
||||||
void SetDataEnabled(bool enabled);
|
void SetDataEnabled(bool enabled);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual BMediaAddOn* AddOn(int32* id) const;
|
virtual BMediaAddOn* AddOn(int32* id) const;
|
||||||
|
|
||||||
virtual void NodeRegistered();
|
virtual void NodeRegistered();
|
||||||
|
|
||||||
virtual void SetRunMode(run_mode mode);
|
virtual void SetRunMode(run_mode mode);
|
||||||
|
|
||||||
virtual void HandleEvent(const media_timed_event* event,
|
virtual void HandleEvent(const media_timed_event* event,
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent);
|
bool realTimeEvent);
|
||||||
|
|
||||||
virtual void Start(bigtime_t performanceTime);
|
virtual void Start(bigtime_t performanceTime);
|
||||||
|
|
||||||
virtual void Stop(bigtime_t performanceTime,
|
virtual void Stop(bigtime_t performanceTime,
|
||||||
bool immediate);
|
bool immediate);
|
||||||
|
|
||||||
virtual void Seek(bigtime_t mediaTime,
|
virtual void Seek(bigtime_t mediaTime,
|
||||||
bigtime_t performanceTime);
|
bigtime_t performanceTime);
|
||||||
|
|
||||||
virtual void TimeWarp(bigtime_t realTime,
|
virtual void TimeWarp(bigtime_t realTime,
|
||||||
bigtime_t performanceTime);
|
bigtime_t performanceTime);
|
||||||
|
|
||||||
virtual status_t HandleMessage(int32 message,
|
virtual status_t HandleMessage(int32 message,
|
||||||
const void* data,
|
const void* data,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
// Someone, probably the producer, is asking you about
|
// Someone, probably the producer, is asking you about
|
||||||
// this format. Give your honest opinion, possibly
|
// this format. Give your honest opinion, possibly
|
||||||
@@ -65,46 +66,46 @@ protected:
|
|||||||
// the format, since he's synchronously waiting for your
|
// the format, since he's synchronously waiting for your
|
||||||
// reply.
|
// reply.
|
||||||
|
|
||||||
virtual status_t AcceptFormat(const media_destination& dest,
|
virtual status_t AcceptFormat(const media_destination& dest,
|
||||||
media_format* format);
|
media_format* format);
|
||||||
|
|
||||||
virtual status_t GetNextInput(int32* cookie,
|
virtual status_t GetNextInput(int32* cookie,
|
||||||
media_input* outInput);
|
media_input* outInput);
|
||||||
|
|
||||||
virtual void DisposeInputCookie(int32 cookie);
|
virtual void DisposeInputCookie(int32 cookie);
|
||||||
|
|
||||||
virtual void BufferReceived(BBuffer* buffer);
|
virtual void BufferReceived(BBuffer* buffer);
|
||||||
|
|
||||||
virtual void ProducerDataStatus(
|
virtual void ProducerDataStatus(
|
||||||
const media_destination& destination,
|
const media_destination& destination,
|
||||||
int32 status,
|
int32 status,
|
||||||
bigtime_t performanceTime);
|
bigtime_t performanceTime);
|
||||||
|
|
||||||
virtual status_t GetLatencyFor(const media_destination& destination,
|
virtual status_t GetLatencyFor(const media_destination& destination,
|
||||||
bigtime_t* outLatency,
|
bigtime_t* outLatency,
|
||||||
media_node_id* outTimesource);
|
media_node_id* outTimesource);
|
||||||
|
|
||||||
virtual status_t Connected(const media_source& producer,
|
virtual status_t Connected(const media_source& producer,
|
||||||
const media_destination& where,
|
const media_destination& where,
|
||||||
const media_format& format,
|
const media_format& format,
|
||||||
media_input* outInput);
|
media_input* outInput);
|
||||||
|
|
||||||
virtual void Disconnected(const media_source& producer,
|
virtual void Disconnected(const media_source& producer,
|
||||||
const media_destination& where);
|
const media_destination& where);
|
||||||
|
|
||||||
virtual status_t FormatChanged(const media_source& producer,
|
virtual status_t FormatChanged(const media_source& producer,
|
||||||
const media_destination& consumer,
|
const media_destination& consumer,
|
||||||
int32 tag,
|
int32 tag,
|
||||||
const media_format& format);
|
const media_format& format);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ~BMediaRecorderNode();
|
virtual ~BMediaRecorderNode();
|
||||||
|
|
||||||
BMediaRecorder* fRecorder;
|
BMediaRecorder* fRecorder;
|
||||||
media_format fOKFormat;
|
media_format fOKFormat;
|
||||||
media_input fInput;
|
media_input fInput;
|
||||||
BString fName;
|
BString fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,15 @@ BMediaRecorder::SetAcceptedFormat(const media_format& format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const media_format&
|
||||||
|
BMediaRecorder::AcceptedFormat() const
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
return fNode->AcceptedFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaRecorder::SetHooks(ProcessFunc recordFunc, NotifyFunc notifyFunc,
|
BMediaRecorder::SetHooks(ProcessFunc recordFunc, NotifyFunc notifyFunc,
|
||||||
void* cookie)
|
void* cookie)
|
||||||
@@ -216,10 +225,13 @@ BMediaRecorder::Disconnect()
|
|||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
media_input ourInput;
|
||||||
|
fNode->GetInput(&ourInput);
|
||||||
|
|
||||||
// do the disconnect
|
// do the disconnect
|
||||||
err = BMediaRoster::CurrentRoster()->Disconnect(
|
err = BMediaRoster::CurrentRoster()->Disconnect(
|
||||||
fOutputNode.node, fOutput.source,
|
fOutputNode.node, fOutputSource,
|
||||||
fNode->Node().node, fInput.destination);
|
fNode->Node().node, ourInput.destination);
|
||||||
|
|
||||||
if (fReleaseOutputNode) {
|
if (fReleaseOutputNode) {
|
||||||
BMediaRoster::Roster()->ReleaseNode(fOutputNode);
|
BMediaRoster::Roster()->ReleaseNode(fOutputNode);
|
||||||
@@ -312,12 +324,12 @@ BMediaRecorder::IsConnected() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const media_output&
|
const media_source&
|
||||||
BMediaRecorder::MediaOutput() const
|
BMediaRecorder::MediaSource() const
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fOutput;
|
return fOutputSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -326,7 +338,9 @@ BMediaRecorder::MediaInput() const
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fInput;
|
media_input* input = NULL;
|
||||||
|
fNode->GetInput(input);
|
||||||
|
return *input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -335,7 +349,25 @@ BMediaRecorder::Format() const
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return fOutput.format;
|
return fNode->AcceptedFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BMediaRecorder::SetUpConnection(media_input ourInput, media_source outputSource)
|
||||||
|
{
|
||||||
|
fOutputSource = outputSource;
|
||||||
|
|
||||||
|
// Perform the connection
|
||||||
|
media_node timeSource;
|
||||||
|
if ((fOutputNode.kind & B_TIME_SOURCE) != 0)
|
||||||
|
timeSource = fOutputNode;
|
||||||
|
else
|
||||||
|
BMediaRoster::Roster()->GetTimeSource(&timeSource);
|
||||||
|
|
||||||
|
// Set time source
|
||||||
|
return BMediaRoster::Roster()->SetTimeSourceFor(fNode->Node().node,
|
||||||
|
timeSource.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -381,45 +413,15 @@ BMediaRecorder::_Connect(const media_node& node,
|
|||||||
if (ourOutput.source == media_source::null)
|
if (ourOutput.source == media_source::null)
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
|
|
||||||
|
fOutputSource = ourOutput.source;
|
||||||
|
|
||||||
// find our Node's free input
|
// find our Node's free input
|
||||||
media_input ourInput;
|
media_input ourInput;
|
||||||
err = fNode->GetInput(&ourInput);
|
fNode->GetInput(&ourInput);
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
media_node timeSource;
|
return BMediaRoster::CurrentRoster()->Connect(fOutputSource,
|
||||||
if ((node.kind & B_TIME_SOURCE) != 0)
|
ourInput.destination, &ourFormat, &ourOutput, &ourInput,
|
||||||
timeSource = node;
|
|
||||||
else
|
|
||||||
BMediaRoster::Roster()->GetTimeSource(&timeSource);
|
|
||||||
|
|
||||||
// set time source
|
|
||||||
err = BMediaRoster::Roster()->SetTimeSourceFor(fNode->Node().node,
|
|
||||||
timeSource.node);
|
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
// start the recorder node (it's always running)
|
|
||||||
err = BMediaRoster::CurrentRoster()->StartNode(fOutputNode,
|
|
||||||
fNode->TimeSource()->Now());
|
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
// perform the connection
|
|
||||||
fOutput = ourOutput;
|
|
||||||
fInput = ourInput;
|
|
||||||
|
|
||||||
err = BMediaRoster::CurrentRoster()->Connect(fOutput.source,
|
|
||||||
fInput.destination, &ourFormat, &fOutput, &fInput,
|
|
||||||
BMediaRoster::B_CONNECT_MUTED);
|
BMediaRoster::B_CONNECT_MUTED);
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
fConnected = true;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <Buffer.h>
|
#include <Buffer.h>
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
|
#include <MediaRoster.h>
|
||||||
|
#include <MediaRosterEx.h>
|
||||||
#include <TimedEventQueue.h>
|
#include <TimedEventQueue.h>
|
||||||
#include <TimeSource.h>
|
#include <TimeSource.h>
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ BMediaRecorderNode::BMediaRecorderNode(const char* name,
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
|
fInput.node = Node();
|
||||||
fInput.destination.id = 1;
|
fInput.destination.id = 1;
|
||||||
fInput.destination.port = ControlPort();
|
fInput.destination.port = ControlPort();
|
||||||
|
|
||||||
@@ -105,15 +108,22 @@ BMediaRecorderNode::SetAcceptedFormat(const media_format& format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
const media_format&
|
||||||
|
BMediaRecorderNode::AcceptedFormat() const
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
return fOKFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
BMediaRecorderNode::GetInput(media_input* outInput)
|
BMediaRecorderNode::GetInput(media_input* outInput)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
fInput.node = Node();
|
fInput.node = Node();
|
||||||
*outInput = fInput;
|
*outInput = fInput;
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,8 +297,16 @@ BMediaRecorderNode::Connected(const media_source &producer,
|
|||||||
fInput.format = withFormat;
|
fInput.format = withFormat;
|
||||||
*outInput = fInput;
|
*outInput = fInput;
|
||||||
|
|
||||||
|
// This is a workaround needed for us to get the node
|
||||||
|
// so that our owner class can do it's operations.
|
||||||
|
media_node node;
|
||||||
|
BMediaRosterEx* roster = MediaRosterEx(BMediaRoster::CurrentRoster());
|
||||||
|
roster->GetNodeFor(roster->NodeIDFor(producer.port), &node);
|
||||||
|
fRecorder->fOutputNode = node;
|
||||||
|
fRecorder->fReleaseOutputNode = true;
|
||||||
|
|
||||||
|
fRecorder->SetUpConnection(fInput, producer);
|
||||||
fRecorder->fConnected = true;
|
fRecorder->fConnected = true;
|
||||||
fRecorder->fInput = fInput;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -301,10 +319,8 @@ BMediaRecorderNode::Disconnected(const media_source& producer,
|
|||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
fInput.source = media_source::null;
|
fInput.source = media_source::null;
|
||||||
|
|
||||||
fRecorder->fConnected = false;
|
fRecorder->fConnected = false;
|
||||||
|
fInput.format = fOKFormat;
|
||||||
fRecorder->fInput.format = fOKFormat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user