BMediaEventLooper: Finally fix some lateness problems

* For the moment i still remain with the classic lateness calculus.
My code wasn't perfect, but this commit fix the remaining
problems from my perspective.
* The first reason is that if we have a patologic latency
such as adding for experimental reasons a snooze() before a SendBuffer or
in the BufferReceived callback, we still can't do anything about it.
If we use enqueue_time and don't send a LateProducer notice, this latency
will never be detected by the API client. We can't do anything about it,
and it's even better that systems with such problems are recognized as
soon as possible IMO.
* The second reason is that the lateness calculus described in the BeBook
is done this way because the media_kit want us to adjust our timing in both
early and late situations.
* Realtime expect that things are always delivered under a certain time
limit, if the software at the bottom doesn't meet with this requirement,
it's just not realtime and things can't work in realtime.
* enqueue_time has nothing to do with the performance_time. But we can
still add this to the media_timed_event struct so that applications can
make use of it.
* Lateness was probably not used a lot in BeOS programs as it looks like
a relatively new feature but i have the concern to complete our API
implementation to be close to what i see was reasonably the designers aim.
This commit is contained in:
Dario Casalinuovo 2015-09-21 14:50:50 +02:00
parent 8bffda1633
commit 5e726ed442

View File

@ -230,6 +230,10 @@ BMediaEventLooper::ControlLoop()
err = WaitForMessage(waitUntil);
if (err == B_TIMED_OUT
|| err == B_WOULD_BLOCK) {
// NOTE: The reference for doing the lateness calculus this way can
// be found in the BeBook article "A BMediaEventLooper Example".
// The value which we are going to calculate, is referred there as
// 'lateness'.
media_timed_event event;
if (hasEvent)
err = fEventQueue.RemoveFirstEvent(&event);
@ -237,11 +241,13 @@ BMediaEventLooper::ControlLoop()
err = fRealTimeQueue.RemoveFirstEvent(&event);
if (err == B_OK) {
bigtime_t lateness = waitUntil - TimeSource()->RealTime();
if (lateness < 0)
lateness = 0;
DispatchEvent(&event, lateness, hasRealtime);
// We are going to do this calculus in performance 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();
DispatchEvent(&event, -lateness, hasRealtime);
}
} else if (err != B_OK)
return;