From 138a802617a45b58aa3f778b6f061b68d6341c48 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Tue, 2 Feb 2016 22:57:27 +0100 Subject: [PATCH] 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. --- headers/os/media/TimedEventQueue.h | 3 ++- src/kits/media/MediaEventLooper.cpp | 23 ++++++++++++++++++----- src/kits/media/TimedEventQueuePrivate.cpp | 3 +++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/headers/os/media/TimedEventQueue.h b/headers/os/media/TimedEventQueue.h index 732fd1727b..ce00b5b6ed 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 85af33acc6..3eae84481a 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 6b5be4d988..4e39b83f50 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(event).enqueue_time = + BTimeSource::RealTime(); + //create a new queue if (fFirstEntry == NULL) { ASSERT(fEventCount == 0);