[haiku-commits] BRANCH haiku.master [598880fc3005] in src: add-ons/media/media-add-ons/mixer servers/media

  • From: haiku.master <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 12 Apr 2016 03:45:47 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/haiku/master'
old head: 59d2bf34cea1fcf7c63ed14ec1cea64037945802
new head: 598880fc300517d70466d3d1693d630bfd8d5744

----------------------------------------------------------------------------

9074223db038: media_server: Print unknown messages notice only when debugging
  
  * Remove unneeded noise caused by progress notifications.
  * Don't print the message to screen.

ec2c5619c1c4: AVFormatWriter: Add more error checking
  
  * Check before to write chunks if the header was correctly
  written, the same happens for track infos, even if the code
  doesn't support it.

b0dd37b7a03c: AudioMixer: Review and rework synchronization
  
  * The event time is managed through the main node control
  loop.
  * Make the mix thread to activate only when needed.
  * Make the locking more simple and remove a race condition,
  this will make the thread to be more silent too.

598880fc3005: MixerCore: Remove wrong flag

                                [ Dario Casalinuovo <b.vitruvio@xxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 89 insertions(+), 42 deletions(-)
.../media/media-add-ons/mixer/AudioMixer.cpp     | 12 ++++
.../media/media-add-ons/mixer/MixerCore.cpp      | 63 ++++++++++++--------
.../media/media-add-ons/mixer/MixerCore.h        | 47 ++++++++++-----
.../media/plugins/ffmpeg/AVFormatWriter.cpp      |  6 ++
src/servers/media/media_server.cpp               |  3 +-

############################################################################

Commit:      9074223db03899c62df9e793d0af73d8afd3c2c7
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Fri Apr  8 18:11:32 2016 UTC

media_server: Print unknown messages notice only when debugging

* Remove unneeded noise caused by progress notifications.
* Don't print the message to screen.

----------------------------------------------------------------------------

diff --git a/src/servers/media/media_server.cpp 
b/src/servers/media/media_server.cpp
index 2450edf..96157d9 100644
--- a/src/servers/media/media_server.cpp
+++ b/src/servers/media/media_server.cpp
@@ -966,8 +966,7 @@ ServerApp::MessageReceived(BMessage* msg)
 
                default:
                        BApplication::MessageReceived(msg);
-                       printf("\nmedia_server: unknown message received:\n");
-                       msg->PrintToStream();
+                       TRACE("\nmedia_server: unknown message received!\n");
                        break;
        }
        TRACE("ServerApp::MessageReceived %lx leave\n", msg->what);

############################################################################

Commit:      ec2c5619c1c402639dc80f9191f6031822344558
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Mon Apr 11 10:56:48 2016 UTC

AVFormatWriter: Add more error checking

* Check before to write chunks if the header was correctly
written, the same happens for track infos, even if the code
doesn't support it.

----------------------------------------------------------------------------

diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
index f4804c8..017fde4 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
@@ -601,6 +601,9 @@ AVFormatWriter::AddTrackInfo(void* _cookie, uint32 code,
        TRACE("AVFormatWriter::AddTrackInfo(%lu, %p, %ld, %lu)\n",
                code, data, size, flags);
 
+       if (fHeaderError != 0)
+               return B_ERROR;
+
        StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie);
        return cookie->AddTrackInfo(code, data, size, flags);
 }
@@ -613,6 +616,9 @@ AVFormatWriter::WriteChunk(void* _cookie, const void* 
chunkBuffer,
        TRACE_PACKET("AVFormatWriter::WriteChunk(%p, %ld, %p)\n", chunkBuffer,
                chunkSize, encodeInfo);
 
+       if (fHeaderError != 0)
+               return B_ERROR;
+
        StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie);
        return cookie->WriteChunk(chunkBuffer, chunkSize, encodeInfo);
 }

############################################################################

Commit:      b0dd37b7a03cc0a6c6dedfe0938397f453e461f0
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Apr 12 00:32:01 2016 UTC

AudioMixer: Review and rework synchronization

* The event time is managed through the main node control
loop.
* Make the mix thread to activate only when needed.
* Make the locking more simple and remove a race condition,
this will make the thread to be more silent too.

----------------------------------------------------------------------------

diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp 
b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp
index 1af6a4d..4bf0978 100644
--- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp
@@ -212,6 +212,14 @@ status_t
 AudioMixer::HandleMessage(int32 message, const void *data, size_t size)
 {
        // since we're using a mediaeventlooper, there shouldn't be any messages
+       // except the message we are using to schedule output events for the
+       // process thread.
+
+       if (message == MIXER_SCHEDULE_EVENT) {
+               RealTimeQueue()->AddEvent(*(const media_timed_event*)data);
+               return B_OK;
+       }
+
        return B_ERROR;
 }
 
@@ -1131,6 +1139,10 @@ AudioMixer::HandleEvent(const media_timed_event *event, 
bigtime_t lateness,
                        break;
                }
 
+               case MIXER_PROCESS_EVENT:
+                       fCore->Process();
+               break;
+
                default:
                        break;
        }
diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp 
b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
index 5af27a6..a6dd37d 100644
--- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
@@ -1,9 +1,10 @@
 /*
- * Copyright 2003-2010 Haiku Inc. All rights reserved.
+ * Copyright 2003-2016 Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             Marcus Overhagen
+ *     Dario Casalinuovo
  */
 
 
@@ -83,6 +84,7 @@ MixerCore::MixerCore(AudioMixer *node)
        fTimeSource(0),
        fMixThread(-1),
        fMixThreadWaitSem(-1),
+       fHasEvent(false),
        fOutputGain(1.0)
 {
 }
@@ -377,13 +379,13 @@ MixerCore::StopMixThread()
        ASSERT(fMixThread > 0);
        ASSERT(fMixThreadWaitSem > 0);
 
+       fRunning = false;
        status_t unused;
        delete_sem(fMixThreadWaitSem);
        wait_for_thread(fMixThread, &unused);
 
        fMixThread = -1;
        fMixThreadWaitSem = -1;
-       fRunning = false;
 }
 
 
@@ -477,7 +479,7 @@ MixerCore::_MixThread()
        // The broken BeOS R5 multiaudio node starts with time 0,
        // then publishes negative times for about 50ms, publishes 0
        // again until it finally reaches time values > 0
-       if (!LockFromMixThread())
+       if (!Lock())
                return;
        bigtime_t start = fTimeSource->Now();
        Unlock();
@@ -485,15 +487,13 @@ MixerCore::_MixThread()
                TRACE("MixerCore: delaying _MixThread start, timesource is at 
%Ld\n",
                        start);
                snooze(5000);
-               if (!LockFromMixThread())
+               if (!Lock())
                        return;
                start = fTimeSource->Now();
                Unlock();
        }
 
-       if (!LockFromMixThread())
-               return;
-       bigtime_t latency = max((bigtime_t)3600, bigtime_t(0.4 * 
buffer_duration(
+       fEventLatency = max((bigtime_t)3600, bigtime_t(0.4 * buffer_duration(
                fOutput->MediaOutput().format.u.raw_audio)));
 
        // TODO: when the format changes while running, everything is wrong!
@@ -510,7 +510,6 @@ MixerCore::_MixThread()
        int64 frameBase = ((temp / fMixBufferFrameCount) + 1)
                * fMixBufferFrameCount;
        bigtime_t timeBase = duration_for_frames(fMixBufferFrameRate, 
frameBase);
-       Unlock();
 
        TRACE("MixerCore: starting _MixThread, start %Ld, timeBase %Ld, "
                "frameBase %Ld\n", start, timeBase, frameBase);
@@ -526,21 +525,23 @@ MixerCore::_MixThread()
        BStackOrHeapArray<chan_info_list, 16> 
mixChanInfos(fMixBufferChannelCount);
                // TODO: this does not support changing output channel count
 
-       bigtime_t eventTime = timeBase;
+       fEventTime = timeBase;
        int64 framePos = 0;
-       for (;;) {
-               if (!LockFromMixThread())
-                       return;
-               bigtime_t waitUntil = fTimeSource->RealTimeFor(eventTime, 0)
-                       - latency - fDownstreamLatency;
-               Unlock();
-               status_t rv = acquire_sem_etc(fMixThreadWaitSem, 1, 
B_ABSOLUTE_TIMEOUT,
-                       waitUntil);
-               if (rv == B_INTERRUPTED)
+       status_t ret = B_ERROR;
+
+       while(fRunning == true) {
+               if (fHasEvent == false)
+                       goto schedule_next_event;
+
+               ret = acquire_sem_etc(fMixThreadWaitSem, 1,
+                       B_RELATIVE_TIMEOUT | B_DO_NOT_RESCHEDULE, 100000);
+               if (ret == B_TIMED_OUT)
                        continue;
-               if (rv != B_TIMED_OUT && rv < B_OK)
+               else if (ret != B_OK)
                        return;
 
+               fHasEvent = false;
+
                if (!LockWithTimeout(10000)) {
                        ERROR("MixerCore: LockWithTimeout failed\n");
                        continue;
@@ -559,7 +560,7 @@ MixerCore::_MixThread()
                                hdr->type = B_MEDIA_RAW_AUDIO;
                                hdr->size_used = size;
                                hdr->time_source = fTimeSource->ID();
-                               hdr->start_time = eventTime;
+                               hdr->start_time = fEventTime;
                                if (fNode->SendBuffer(buffer, fOutput) != B_OK) 
{
 #if DEBUG
                                        ERROR("MixerCore: SendBuffer failed for 
buffer %Ld\n",
@@ -587,7 +588,7 @@ MixerCore::_MixThread()
                ASSERT(currentFramePos % fMixBufferFrameCount == 0);
 
                PRINT(4, "create new buffer event at %Ld, reading input frames 
at "
-                       "%Ld\n", eventTime, currentFramePos);
+                       "%Ld\n", fEventTime, currentFramePos);
 
                // Init the channel information for each MixerInput.
                for (int i = 0; MixerInput* input = Input(i); i++) {
@@ -598,7 +599,7 @@ MixerCore::_MixThread()
                                uint32 sampleOffset;
                                float gain;
                                if (!input->GetMixerChannelInfo(channel, 
currentFramePos,
-                                               eventTime, &base, 
&sampleOffset, &type, &gain)) {
+                                               fEventTime, &base, 
&sampleOffset, &type, &gain)) {
                                        continue;
                                }
                                if (type < 0 || type >= MAX_CHANNEL_TYPES)
@@ -689,7 +690,7 @@ MixerCore::_MixThread()
                        hdr->size_used
                                = 
fOutput->MediaOutput().format.u.raw_audio.buffer_size;
                        hdr->time_source = fTimeSource->ID();
-                       hdr->start_time = eventTime;
+                       hdr->start_time = fEventTime;
 
                        // swap byte order if necessary
                        fOutput->AdjustByteOrder(buffer);
@@ -721,11 +722,23 @@ MixerCore::_MixThread()
                        mixChanInfos[i].MakeEmpty();
 
 schedule_next_event:
+               Unlock();
+
                // schedule next event
                framePos += fMixBufferFrameCount;
-               eventTime = timeBase + bigtime_t((1000000LL * framePos)
+               fEventTime = timeBase + bigtime_t((1000000LL * framePos)
                        / fMixBufferFrameRate);
-               Unlock();
+
+               media_timed_event mixerEvent(PickEvent(),
+                       MIXER_PROCESS_EVENT, 0, BTimedEventQueue::B_NO_CLEANUP);
+
+               ret = write_port(fNode->ControlPort(), MIXER_SCHEDULE_EVENT,
+                       &mixerEvent, sizeof(mixerEvent));
+               if (ret != B_OK)
+                       TRACE("MixerCore::_MixThread: can't write to owner 
port\n");
+
+               fHasEvent = true;
+
 #if DEBUG
                bufferIndex++;
 #endif
diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.h 
b/src/add-ons/media/media-add-ons/mixer/MixerCore.h
index 5a5c7e2..eb16127 100644
--- a/src/add-ons/media/media-add-ons/mixer/MixerCore.h
+++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.h
@@ -30,6 +30,10 @@ class Resampler;
 //     but for now we redefine type 12
 #define B_CHANNEL_MONO         B_CHANNEL_TOP_CENTER
 
+#define MIXER_PROCESS_EVENT BTimedEventQueue::B_USER_EVENT+10
+#define MIXER_SCHEDULE_EVENT BTimedEventQueue::B_USER_EVENT+11
+
+
 class MixerCore {
 public:
                                                                
MixerCore(AudioMixer* node);
@@ -53,11 +57,14 @@ public:
                        MixerInput*                     Input(int index);
                        MixerOutput*            Output();
 
-                       void                            Lock();
+                       bool                            Lock();
                        bool                            
LockWithTimeout(bigtime_t timeout);
-                       bool                            LockFromMixThread();
+                       bool                            IsLocked() const;
                        void                            Unlock();
 
+                       void                            Process();
+                       bigtime_t                       PickEvent();
+
                        void                            BufferReceived(BBuffer* 
buffer,
                                                                        
bigtime_t lateness);
 
@@ -114,6 +121,9 @@ private:
                        BTimeSource*            fTimeSource;
                        thread_id                       fMixThread;
                        sem_id                          fMixThreadWaitSem;
+                       bool                            fHasEvent;
+                       bigtime_t                       fEventTime;
+                       bigtime_t                       fEventLatency;
                        float                           fOutputGain;
 
        friend class MixerInput;
@@ -121,10 +131,10 @@ private:
 };
 
 
-inline void
+inline bool
 MixerCore::Lock()
 {
-       fLocker->Lock();
+       return fLocker->Lock();
 }
 
 
@@ -135,6 +145,13 @@ MixerCore::LockWithTimeout(bigtime_t timeout)
 }
 
 
+inline bool
+MixerCore::IsLocked() const
+{
+       return fLocker->IsLocked();
+}
+
+
 inline void
 MixerCore::Unlock()
 {
@@ -142,18 +159,18 @@ MixerCore::Unlock()
 }
 
 
-inline bool
-MixerCore::LockFromMixThread()
+inline void
+MixerCore::Process()
+{
+       release_sem(fMixThreadWaitSem);
+}
+
+
+inline bigtime_t
+MixerCore::PickEvent()
 {
-       for (;;) {
-               if (LockWithTimeout(10000))
-                       return true;
-               // XXX accessing fMixThreadWaitSem is still a race condition :(
-               if (acquire_sem_etc(fMixThreadWaitSem, 1, B_RELATIVE_TIMEOUT, 0)
-                               != B_WOULD_BLOCK) {
-                       return false;
-               }
-       }
+       return fTimeSource->RealTimeFor(fEventTime, 0)
+               - fEventLatency - fDownstreamLatency;
 }
 
 

############################################################################

Commit:      598880fc300517d70466d3d1693d630bfd8d5744
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Apr 12 00:54:09 2016 UTC

MixerCore: Remove wrong flag

----------------------------------------------------------------------------

diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp 
b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
index a6dd37d..aa501e5 100644
--- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
+++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
@@ -534,7 +534,7 @@ MixerCore::_MixThread()
                        goto schedule_next_event;
 
                ret = acquire_sem_etc(fMixThreadWaitSem, 1,
-                       B_RELATIVE_TIMEOUT | B_DO_NOT_RESCHEDULE, 100000);
+                       B_RELATIVE_TIMEOUT, 100000);
                if (ret == B_TIMED_OUT)
                        continue;
                else if (ret != B_OK)


Other related posts:

  • » [haiku-commits] BRANCH haiku.master [598880fc3005] in src: add-ons/media/media-add-ons/mixer servers/media - haiku . master