From 2a2e352a4a58214b162ed9dac27d898f1dc910ef Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Tue, 9 Feb 2016 13:33:09 +0100 Subject: [PATCH] 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. --- headers/private/media/MediaRecorder.h | 15 ++-- headers/private/media/MediaRecorderNode.h | 103 +++++++++++----------- src/kits/media/MediaRecorder.cpp | 86 +++++++++--------- src/kits/media/MediaRecorderNode.cpp | 30 +++++-- 4 files changed, 129 insertions(+), 105 deletions(-) diff --git a/headers/private/media/MediaRecorder.h b/headers/private/media/MediaRecorder.h index 417be03f1d..eeb64f0dc8 100644 --- a/headers/private/media/MediaRecorder.h +++ b/headers/private/media/MediaRecorder.h @@ -46,6 +46,7 @@ public: void SetAcceptedFormat( const media_format& format); + const media_format& AcceptedFormat() const; virtual status_t Start(bool force = false); virtual status_t Stop(bool force = false); @@ -66,13 +67,18 @@ public: const media_format& Format() const; - const media_output& MediaOutput() const; - const media_input& MediaInput() const; - 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, const media_header& header); + + status_t SetUpConnection(media_input ourInput, + media_source outputSource); + private: status_t _Connect(const media_node& mediaNode, @@ -98,10 +104,9 @@ private: NotifyFunc fNotifyHook; media_node fOutputNode; - media_output fOutput; + media_source fOutputSource; BMediaRecorderNode* fNode; - media_input fInput; void* fBufferCookie; uint32 fPadding[32]; diff --git a/headers/private/media/MediaRecorderNode.h b/headers/private/media/MediaRecorderNode.h index 8a4f2fedfd..746e5ace46 100644 --- a/headers/private/media/MediaRecorderNode.h +++ b/headers/private/media/MediaRecorderNode.h @@ -20,44 +20,45 @@ class BMediaRecorder; class BMediaRecorderNode : public BMediaEventLooper, public BBufferConsumer { public: - BMediaRecorderNode(const char* name, - BMediaRecorder* recorder, - media_type type - = B_MEDIA_UNKNOWN_TYPE); + BMediaRecorderNode(const char* name, + BMediaRecorder* recorder, + media_type type + = B_MEDIA_UNKNOWN_TYPE); // 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: - 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, - bigtime_t lateness, - bool realTimeEvent); + virtual void HandleEvent(const media_timed_event* event, + bigtime_t lateness, + bool realTimeEvent); - virtual void Start(bigtime_t performanceTime); + virtual void Start(bigtime_t performanceTime); - virtual void Stop(bigtime_t performanceTime, - bool immediate); + virtual void Stop(bigtime_t performanceTime, + bool immediate); - virtual void Seek(bigtime_t mediaTime, - bigtime_t performanceTime); + virtual void Seek(bigtime_t mediaTime, + bigtime_t performanceTime); - virtual void TimeWarp(bigtime_t realTime, - bigtime_t performanceTime); + virtual void TimeWarp(bigtime_t realTime, + bigtime_t performanceTime); - virtual status_t HandleMessage(int32 message, - const void* data, - size_t size); + virtual status_t HandleMessage(int32 message, + const void* data, + size_t size); // Someone, probably the producer, is asking you about // this format. Give your honest opinion, possibly @@ -65,46 +66,46 @@ protected: // the format, since he's synchronously waiting for your // reply. - virtual status_t AcceptFormat(const media_destination& dest, - media_format* format); + virtual status_t AcceptFormat(const media_destination& dest, + media_format* format); - virtual status_t GetNextInput(int32* cookie, - media_input* outInput); + virtual status_t GetNextInput(int32* cookie, + 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( - const media_destination& destination, - int32 status, - bigtime_t performanceTime); + virtual void ProducerDataStatus( + const media_destination& destination, + int32 status, + bigtime_t performanceTime); - virtual status_t GetLatencyFor(const media_destination& destination, - bigtime_t* outLatency, - media_node_id* outTimesource); + virtual status_t GetLatencyFor(const media_destination& destination, + bigtime_t* outLatency, + media_node_id* outTimesource); - virtual status_t Connected(const media_source& producer, - const media_destination& where, - const media_format& format, - media_input* outInput); + virtual status_t Connected(const media_source& producer, + const media_destination& where, + const media_format& format, + media_input* outInput); - virtual void Disconnected(const media_source& producer, - const media_destination& where); + virtual void Disconnected(const media_source& producer, + const media_destination& where); - virtual status_t FormatChanged(const media_source& producer, - const media_destination& consumer, - int32 tag, - const media_format& format); + virtual status_t FormatChanged(const media_source& producer, + const media_destination& consumer, + int32 tag, + const media_format& format); protected: - virtual ~BMediaRecorderNode(); + virtual ~BMediaRecorderNode(); - BMediaRecorder* fRecorder; - media_format fOKFormat; - media_input fInput; - BString fName; + BMediaRecorder* fRecorder; + media_format fOKFormat; + media_input fInput; + BString fName; }; } diff --git a/src/kits/media/MediaRecorder.cpp b/src/kits/media/MediaRecorder.cpp index d2d6be449e..5738e936e3 100644 --- a/src/kits/media/MediaRecorder.cpp +++ b/src/kits/media/MediaRecorder.cpp @@ -72,6 +72,15 @@ BMediaRecorder::SetAcceptedFormat(const media_format& format) } +const media_format& +BMediaRecorder::AcceptedFormat() const +{ + CALLED(); + + return fNode->AcceptedFormat(); +} + + status_t BMediaRecorder::SetHooks(ProcessFunc recordFunc, NotifyFunc notifyFunc, void* cookie) @@ -216,10 +225,13 @@ BMediaRecorder::Disconnect() if (err != B_OK) return err; + media_input ourInput; + fNode->GetInput(&ourInput); + // do the disconnect err = BMediaRoster::CurrentRoster()->Disconnect( - fOutputNode.node, fOutput.source, - fNode->Node().node, fInput.destination); + fOutputNode.node, fOutputSource, + fNode->Node().node, ourInput.destination); if (fReleaseOutputNode) { BMediaRoster::Roster()->ReleaseNode(fOutputNode); @@ -312,12 +324,12 @@ BMediaRecorder::IsConnected() const } -const media_output& -BMediaRecorder::MediaOutput() const +const media_source& +BMediaRecorder::MediaSource() const { CALLED(); - return fOutput; + return fOutputSource; } @@ -326,7 +338,9 @@ BMediaRecorder::MediaInput() const { CALLED(); - return fInput; + media_input* input = NULL; + fNode->GetInput(input); + return *input; } @@ -335,7 +349,25 @@ BMediaRecorder::Format() const { 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) return B_MEDIA_BAD_SOURCE; + fOutputSource = ourOutput.source; + // find our Node's free input media_input ourInput; - err = fNode->GetInput(&ourInput); - if (err != B_OK) - return err; + fNode->GetInput(&ourInput); - media_node timeSource; - if ((node.kind & B_TIME_SOURCE) != 0) - 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, + return BMediaRoster::CurrentRoster()->Connect(fOutputSource, + ourInput.destination, &ourFormat, &ourOutput, &ourInput, BMediaRoster::B_CONNECT_MUTED); - - if (err != B_OK) - return err; - - fConnected = true; - return B_OK; } diff --git a/src/kits/media/MediaRecorderNode.cpp b/src/kits/media/MediaRecorderNode.cpp index bb6d5beff7..87ef5278f2 100644 --- a/src/kits/media/MediaRecorderNode.cpp +++ b/src/kits/media/MediaRecorderNode.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include @@ -27,6 +29,7 @@ BMediaRecorderNode::BMediaRecorderNode(const char* name, { CALLED(); + fInput.node = Node(); fInput.destination.id = 1; 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) { CALLED(); fInput.node = Node(); *outInput = fInput; - - return B_OK; } @@ -287,8 +297,16 @@ BMediaRecorderNode::Connected(const media_source &producer, fInput.format = withFormat; *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->fInput = fInput; return B_OK; } @@ -301,10 +319,8 @@ BMediaRecorderNode::Disconnected(const media_source& producer, CALLED(); fInput.source = media_source::null; - fRecorder->fConnected = false; - - fRecorder->fInput.format = fOKFormat; + fInput.format = fOKFormat; }