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);