[haiku-commits] haiku: hrev50071 - src/kits/media headers/os/media

  • From: b.vitruvio@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 3 Feb 2016 13:32:10 +0100 (CET)

hrev50071 adds 3 changesets to branch 'master'
old head: 4e7b05cca20d88909030317ce6aac83c71490d9c
new head: 138a802617a45b58aa3f778b6f061b68d6341c48
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=138a802617a4+%5E4e7b05cca20d

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

ffeb987dc475: BMediaEventLooper: Make lateness calculus in real time
  
  * After having this patch applied locally for some time,
  I'm going to be sure that we have to deal only with real_time values.
  * Since RealTime() is just a system_time() wrapper, the code
  will be slightly improved in performances too.
  * Additionally it performs very well when the thread is
  externally stopped (such as debugging it), so that the audio
  recover almost immediately.

bb1f15aadee6: BMediaEventLooper: Better solution for negative timestamp
  
  * This problem happens only at the startup, so that it's
  preferred that we deal with it in the BMediaEventLooper side.
  * This solve some audio stability problems I had with slow systems.

138a802617a4: BMediaEventLooper: Use enqueue_time in a different shape
  
  * This is the only solution that allowed to use the best
  of both ways to do this calculus. I've also tested it
  with a modified sound player that snoozed every time
  the buffer should be handled, and found that neither
  of the lateness calculus I tested (including enqueue_time)
  really solve all problems. That's why I've tried to find
  an average solution. There's still room for improvements
  eventually.

                                [ Dario Casalinuovo <b.vitruvio@xxxxxxxxx> ]

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

4 files changed, 33 insertions(+), 13 deletions(-)
headers/os/media/TimedEventQueue.h        |  3 ++-
src/kits/media/MediaEventLooper.cpp       | 34 ++++++++++++++++++++++-----
src/kits/media/MediaNode.cpp              |  6 -----
src/kits/media/TimedEventQueuePrivate.cpp |  3 +++

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

Commit:      ffeb987dc475fb6a84f5c00a42c9b0ac86718d29
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ffeb987dc475
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Sun Jan 31 11:54:12 2016 UTC

BMediaEventLooper: Make lateness calculus in real time

* After having this patch applied locally for some time,
I'm going to be sure that we have to deal only with real_time values.
* Since RealTime() is just a system_time() wrapper, the code
will be slightly improved in performances too.
* Additionally it performs very well when the thread is
externally stopped (such as debugging it), so that the audio
recover almost immediately.

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

diff --git a/src/kits/media/MediaEventLooper.cpp 
b/src/kits/media/MediaEventLooper.cpp
index 5110b24..8cb3f22 100644
--- a/src/kits/media/MediaEventLooper.cpp
+++ b/src/kits/media/MediaEventLooper.cpp
@@ -241,12 +241,11 @@ BMediaEventLooper::ControlLoop()
                                err = fRealTimeQueue.RemoveFirstEvent(&event);
 
                        if (err == B_OK) {
-                               // We are going to do this calculus in 
performance time
+                               // We are going to do this calculus in real time
                                // because otherwise we could get erroneous 
values.
                                // This calculus allow us to detect both early 
and late
                                // buffers, this is the meaning of the lateness 
concept.
-                               bigtime_t lateness = event.event_time - 
fEventLatency
-                                       - fSchedulingLatency - 
TimeSource()->Now();
+                               bigtime_t lateness = waitUntil - 
TimeSource()->RealTime();
                                DispatchEvent(&event, -lateness, hasRealtime);
                        }
                } else if (err != B_OK)

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

Commit:      bb1f15aadee6533de6ddcb511d04d84b2c22029a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=bb1f15aadee6
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Feb  2 00:10:15 2016 UTC

BMediaEventLooper: Better solution for negative timestamp

* This problem happens only at the startup, so that it's
preferred that we deal with it in the BMediaEventLooper side.
* This solve some audio stability problems I had with slow systems.

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

diff --git a/src/kits/media/MediaEventLooper.cpp 
b/src/kits/media/MediaEventLooper.cpp
index 8cb3f22..85af33a 100644
--- a/src/kits/media/MediaEventLooper.cpp
+++ b/src/kits/media/MediaEventLooper.cpp
@@ -217,6 +217,7 @@ BMediaEventLooper::ControlLoop()
        bigtime_t waitUntil = B_INFINITE_TIMEOUT;
        bool hasRealtime = false;
        bool hasEvent = false;
+       bool hasBooted = false;
 
        // While there are no events or it is not time for the earliest event,
        // process messages using WaitForMessages. Whenever this funtion times 
out,
@@ -262,6 +263,15 @@ BMediaEventLooper::ControlLoop()
                        waitUntil = TimeSource()->RealTimeFor(
                                fEventQueue.FirstEventTime(),
                                fEventLatency + fSchedulingLatency);
+
+                       // The first event we handle will have
+                       // a negative startup wait. In this case
+                       // we just check the port and let the
+                       // first event to be executed just now.
+                       if (!hasBooted && waitUntil < 0) {
+                               waitUntil = 0;
+                               hasBooted = true;
+                       }
                } else if (!hasRealtime) {
                        waitUntil = B_INFINITE_TIMEOUT;
                        continue;
diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp
index 5f2ab4f..362c3f3 100644
--- a/src/kits/media/MediaNode.cpp
+++ b/src/kits/media/MediaNode.cpp
@@ -362,12 +362,6 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, uint32 
flags,
        int32 message;
        ssize_t size;
 
-       // TODO: Investigate on this issue
-       if (waitUntil < 0) {
-               TRACE("BMediaNode::WaitForMessage: Negative timeout!\n");
-               waitUntil = 0;
-       }
-
        while (true) {
                size = read_port_etc(ControlPort(), &message, data,
                        sizeof(data), B_ABSOLUTE_TIMEOUT, waitUntil);

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

Revision:    hrev50071
Commit:      138a802617a45b58aa3f778b6f061b68d6341c48
URL:         http://cgit.haiku-os.org/haiku/commit/?id=138a802617a4
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Feb  2 21:57:27 2016 UTC

BMediaEventLooper: Use enqueue_time in a different shape

* This is the only solution that allowed to use the best
of both ways to do this calculus. I've also tested it
with a modified sound player that snoozed every time
the buffer should be handled, and found that neither
of the lateness calculus I tested (including enqueue_time)
really solve all problems. That's why I've tried to find
an average solution. There's still room for improvements
eventually.

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

diff --git a/headers/os/media/TimedEventQueue.h 
b/headers/os/media/TimedEventQueue.h
index 732fd17..ce00b5b 100644
--- a/headers/os/media/TimedEventQueue.h
+++ b/headers/os/media/TimedEventQueue.h
@@ -38,8 +38,9 @@ struct media_timed_event {
                        int32                           data;
                        int64                           bigdata;
                        char                            user_data[64];
+                       bigtime_t                       enqueue_time;
 
-                       uint32                          
_reserved_media_timed_event_[8];
+                       uint32                          
_reserved_media_timed_event_[6];
 };
 
 
diff --git a/src/kits/media/MediaEventLooper.cpp 
b/src/kits/media/MediaEventLooper.cpp
index 85af33a..3eae844 100644
--- a/src/kits/media/MediaEventLooper.cpp
+++ b/src/kits/media/MediaEventLooper.cpp
@@ -242,11 +242,24 @@ BMediaEventLooper::ControlLoop()
                                err = fRealTimeQueue.RemoveFirstEvent(&event);
 
                        if (err == B_OK) {
-                               // We are going to do this calculus in real time
-                               // because otherwise we could get erroneous 
values.
-                               // This calculus allow us to detect both early 
and late
-                               // buffers, this is the meaning of the lateness 
concept.
-                               bigtime_t lateness = waitUntil - 
TimeSource()->RealTime();
+                               // The general idea of lateness is to allow
+                               // the client code to detect when the buffer
+                               // is handled late or early. What we add is
+                               // that the code log the time at which the
+                               // current event is added to the queue. This
+                               // allow us to detect cyclic/stagnant latency
+                               // in the meantime, so that the client can
+                               // notify to the producer only the portion
+                               // that might be attributable.
+                               bigtime_t lateness = 0;
+                               if (waitUntil > 0) {
+                                       lateness = waitUntil - 
TimeSource()->RealTime();
+                                       if (lateness > 0) {
+                                               bigtime_t enqueueLatency = 
event.enqueue_time - waitUntil;
+                                               if (enqueueLatency > 0)
+                                                       lateness += 
enqueueLatency;
+                                       }
+                               }
                                DispatchEvent(&event, -lateness, hasRealtime);
                        }
                } else if (err != B_OK)
diff --git a/src/kits/media/TimedEventQueuePrivate.cpp 
b/src/kits/media/TimedEventQueuePrivate.cpp
index 6b5be4d..4e39b83 100644
--- a/src/kits/media/TimedEventQueuePrivate.cpp
+++ b/src/kits/media/TimedEventQueuePrivate.cpp
@@ -78,6 +78,9 @@ _event_queue_imp::AddEvent(const media_timed_event &event)
                 return B_BAD_VALUE;
        }
 
+       const_cast<media_timed_event&>(event).enqueue_time =
+               BTimeSource::RealTime();
+
        //create a new queue
        if (fFirstEntry == NULL) {
                ASSERT(fEventCount == 0);


Other related posts: