hrev50076 adds 2 changesets to branch 'master'
old head: 801b3e3bf487edd9de0c68bdf44f749370849e38
new head: 7b83e044e7b0115b8e2a6e483efb3720b6d4fc4c
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=7b83e044e7b0+%5E801b3e3bf487
----------------------------------------------------------------------------
2a2e352a4a58: 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.
7b83e044e7b0: SoundRecorder: Fix connection and disconnection from Cortex
* SoundRecorder can now be connected and disconnected safely,
due to some unknown reason, probably format negotiation problems,
ATM we need a system mixer between.
* The normal behavior is unchanged, when the record button is pressed
it will record from the preferred audio interface and disconnect on
stop. But when the connection is made manually it will stay connected
until the user explictly disconnect it.
* To make it work, instantiate a system mixer, connect the output to
SoundRecorder, instantiate a node like the ToneProducer, and connect
it's output to the mixer input. Press the record button and check
the Mixer has started from the Cortex transport, if not, start it.
[ Dario Casalinuovo <b.vitruvio@xxxxxxxxx> ]
----------------------------------------------------------------------------
6 files changed, 147 insertions(+), 120 deletions(-)
headers/private/media/MediaRecorder.h | 15 ++--
headers/private/media/MediaRecorderNode.h | 103 +++++++++++++-------------
src/apps/soundrecorder/RecorderWindow.cpp | 32 ++++----
src/apps/soundrecorder/RecorderWindow.h | 1 +
src/kits/media/MediaRecorder.cpp | 86 ++++++++++-----------
src/kits/media/MediaRecorderNode.cpp | 30 ++++++--
############################################################################
Commit: 2a2e352a4a58214b162ed9dac27d898f1dc910ef
URL: http://cgit.haiku-os.org/haiku/commit/?id=2a2e352a4a58
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Tue Feb 9 12:33:09 2016 UTC
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.
----------------------------------------------------------------------------
diff --git a/headers/private/media/MediaRecorder.h
b/headers/private/media/MediaRecorder.h
index 417be03..eeb64f0 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 8a4f2fe..746e5ac 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 d2d6be4..5738e93 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;
-
- 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;
+ fNode->GetInput(&ourInput);
- // 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 bb6d5be..87ef527 100644
--- a/src/kits/media/MediaRecorderNode.cpp
+++ b/src/kits/media/MediaRecorderNode.cpp
@@ -10,6 +10,8 @@
#include <Buffer.h>
#include <scheduler.h>
+#include <MediaRoster.h>
+#include <MediaRosterEx.h>
#include <TimedEventQueue.h>
#include <TimeSource.h>
@@ -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;
}
############################################################################
Revision: hrev50076
Commit: 7b83e044e7b0115b8e2a6e483efb3720b6d4fc4c
URL: http://cgit.haiku-os.org/haiku/commit/?id=7b83e044e7b0
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Tue Feb 9 12:23:14 2016 UTC
SoundRecorder: Fix connection and disconnection from Cortex
* SoundRecorder can now be connected and disconnected safely,
due to some unknown reason, probably format negotiation problems,
ATM we need a system mixer between.
* The normal behavior is unchanged, when the record button is pressed
it will record from the preferred audio interface and disconnect on
stop. But when the connection is made manually it will stay connected
until the user explictly disconnect it.
* To make it work, instantiate a system mixer, connect the output to
SoundRecorder, instantiate a node like the ToneProducer, and connect
it's output to the mixer input. Press the record button and check
the Mixer has started from the Cortex transport, if not, start it.
----------------------------------------------------------------------------
diff --git a/src/apps/soundrecorder/RecorderWindow.cpp
b/src/apps/soundrecorder/RecorderWindow.cpp
index aebfc7f..06bcdc6 100644
--- a/src/apps/soundrecorder/RecorderWindow.cpp
+++ b/src/apps/soundrecorder/RecorderWindow.cpp
@@ -125,6 +125,7 @@ RecorderWindow::RecorderWindow()
fInputField = NULL;
fRecorder = NULL;
fRecording = false;
+ fExternalConnection = false;
fTempCount = -1;
fButtonState = btnPaused;
@@ -693,7 +694,7 @@ RecorderWindow::Record(BMessage * message)
fRecFile.Seek(sizeof(struct wave_struct), SEEK_SET);
- // Hook up input
+ // Hook up input
err = MakeRecordConnection(fAudioInputNode);
if (err < B_OK) {
ErrorAlert(B_TRANSLATE("Cannot connect to the selected sound
input"),
@@ -702,7 +703,6 @@ RecorderWindow::Record(BMessage * message)
fRecEntry.Unset();
return;
}
-
fRecorder->Start();
}
@@ -892,15 +892,14 @@ RecorderWindow::MakeRecordConnection(const media_node &
input)
return B_BUSY;
}
+ // Get a format, any format.
+ fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
+ fExternalConnection = false;
} else {
- CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
- " audio input node already connected\n"));
-
- return B_BUSY;
+ fRecordFormat.u.raw_audio =
fRecorder->AcceptedFormat().u.raw_audio;
+ fExternalConnection = true;
}
- // Get a format, any format.
- fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
fRecordFormat.type = B_MEDIA_RAW_AUDIO;
// Tell the consumer where we want data to go.
@@ -932,12 +931,6 @@ RecorderWindow::MakeRecordConnection(const media_node &
input)
status_t
RecorderWindow::BreakRecordConnection()
{
- status_t err = B_OK;
-
- err = fRecorder->Stop(true);
- if (err < B_OK)
- return err;
-
return fRecorder->Disconnect();
}
@@ -949,7 +942,16 @@ RecorderWindow::StopRecording()
return B_OK;
fRecording = false;
- BreakRecordConnection();
+ status_t err = B_OK;
+ err = fRecorder->Stop(true);
+ if (err < B_OK)
+ return err;
+
+ // We maintain the connection active
+ // if the user connected us from Cortex.
+ if (!fExternalConnection) {
+ BreakRecordConnection();
+ }
fRecorder->SetHooks(NULL, NULL, NULL);
diff --git a/src/apps/soundrecorder/RecorderWindow.h
b/src/apps/soundrecorder/RecorderWindow.h
index d0c405e..9cf0893 100644
--- a/src/apps/soundrecorder/RecorderWindow.h
+++ b/src/apps/soundrecorder/RecorderWindow.h
@@ -96,6 +96,7 @@ private:
BMediaRecorder * fRecorder;
BSoundPlayer * fPlayer;
bool fRecording;
+ bool fExternalConnection;
SoundListView * fSoundList;
BDirectory fTempDir;
int fTempCount;