[haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency
- From: "bonefish" <trac@xxxxxxxxxxxx>
- Date: Wed, 04 May 2011 12:07:20 -0000
#7285: BSoundPlayer sends buffers late, with ever-increasing latency
------------------------------+-----------------------
Reporter: Pete | Owner: axeld
Type: bug | Status: new
Priority: normal | Milestone: R1
Component: Kits/Media Kit | Version: R1/alpha2
Resolution: | Keywords:
Blocked By: | Blocking:
Has a Patch: 1 | Platform: All
------------------------------+-----------------------
Comment (by bonefish):
Replying to [comment:13 Pete]:
> Replying to [comment:12 bonefish]:
> > Replying to [comment:11 Pete]:
> > > (The actual calculation of "lateness" was at one point moved to that
point at the beginning of the loop, but it seems better that the true
lateness when the buffer is returned from the loop be provided, so this
check is still done after wakeup, as it was originally.)
> >
> > Due to the violation of the seamless latency computation it is still
incorrect, though. If the behavior is worse with the correct
implementation, there's obviously something else wrong. Since after with
your changes the mixer completely ignores the value computed here, the
issue is probably in a different node up- or downstream.
> It was not "worse" -- just ineffective. My thesis is that there is ''no
possible'' "correct implementation" of lateness calculation in
ControlLoop()!
[...]
> Now let's suppose a blackout occurs, resulting in a late wakeup. Then
using a lateness calculated after the wakeup to affect upstream latency is
obviously wrong, because the delay in the loop gets reported as if it was
upstream. However, the other setup is no better, because if buffer
duration is short there will be other buffers in the queue; a late wakeup
will mean that -- though the first buffer will not be "late" because its
lateness was determined before the wait -- the next buffer is ''looked
at'' late when the loop returns to the top after the wait, so computing
lateness at that point has just the same result: again "lateness" will be
detected and the cause will erroneously be attributed to the producer.
(If buffer duration is longer than the latency, the early test does work,
because the loop goes into infinite timeout after passing on a buffer, and
is woken by the next one's arrival.)
Agreed.
> > > '''AudioMixer''':[[BR]]
> > > Checking the lateness of incoming buffers -- and notifying the
producer -- is now done in BufferReceived, rather than when the buffer is
returned from the loop in HandleInputBuffer.
> >
> > Well, that is a work-around for the incorrect lateness computation in
`BMediaEventLooper::ControlLoop()`.
> See above... (:-)) Why do you think this is the wrong place to do the
check? Upstream latency should only be changed when the producer is late
(and blackouts do also happen in the producer's looper). So testing when
the buffer actually arrives at the mixer seems the obvious (and correct!)
place to do the check.
I think any place outside libbe is suboptimal for the lateness
computation. BMediaEventLooper already provides a lateness value. To let
that be computed incorrectly and have the API user compute it themselves
is not a solution.
I have nothing against basing the lateness computation on a time stamp
from the receiving thread. Unfortunately the event doesn't go through the
`BMediaEventLooper`, but is added directly to the event queue. A
reasonable solution would be to add a `queued_time` field to
`media_timed_event`, filled in when the event is added. That means
`BTimedEventQueue` would need to allow for optionally specifying a
`BTimeSource`. The actual lateness computation would still happen in
`BMediaEventLooper::ControlLoop()`, just based on the event's
`queued_time`.
> > > There is a new test in the latter for actual lateness ( wrt
downstream latency -- ''not'' the total event latency) which will adjust
the Mixer's internal latency.
> >
> > While it doesn't harm, I don't think this is necessary either. I would
rather see the lateness be computed correctly in `BMediaEventLooper` and
handled here instead of in `BufferReceived()`.
> Again, see above...
You too. :-)
> In fact, I think this would properly be dealt with by
LateNoticeReceived, but as I say I didn't seem to be seeing any activity
there. I felt a "belt and braces" approach was safer for the moment.
We don't want something that works just because we have added enough work-
arounds. We want it to work because it is correct. In fact adding work-
arounds usually makes it more complicated to find the actual problems.
> As you say, it does no harm (and works in practice...).
No-ops don't harm either. Still we don't want them in the code.
> > That only leaves the wait itself, which should be covered by the
scheduling latency. Though I wouldn't bother adjusting it, but rather let
the internal latency compensate. The internal latency could be checked
after the mixing has happened (i.e. whether the lateness after mixing is
greater than the greatest lateness of the processed input buffers (using
the lateness value computed by `BMediaEventLooper`)).
> Not sure exactly what you're suggesting here.
I'm suggesting that, for the time being, all that is needed is the
lateness handling in `HandleInputBuffer()`. If you or anyone else feels
motivated, one could add comparisons of the actual buffer processing times
with the internal latency and increase the latter, if necessary. Due to
the mixer's nature of having multiple inputs with possibly different
formats and buffer durations, this might turn out to be a bit complicated.
I'm also not sure whether this would actually improve things in practice.
> Note, though, that using the looper's lateness to calculate internal
latency is no use either, because the looper only knows about (total)
event latency (and scheduling latency). If you adjust internal latency
and thus event latency, all calculations come out just as before (it will
compute both sleep time and lateness based on the event latency, so short
buffers especially can still generate spurious lateness). So each blackout
will incur another bump.
I don't follow. "All calculations" certainly don't come out the same: The
wakeup time will be earlier, which is the whole point of increasing the
internal latency. The lateness has nothing to do with our internal latency
(other than shifting the requested buffer arrival times), so, of course,
it shouldn't be affected. Regarding the blackout, I thought we agreed on
that: As long as the latency/lateness computation is done seamlessly
without attributing wait times (be it actual wait times or times where the
thread is busy with another event) to the upstream latency the blackout
time will increase the right latencies until they completely compensate
for blackouts. And computing the lateness as suggested (based on a time
stamp in `BTimedEventQueue::AddEvent()`), that will be the case:
- A blackout anytime before getting the time stamp in
`BTimedEventQueue::AddEvent()` will increase the lateness and will cause
the upstream node's latency to be increased until buffers arrive up to a
full blackout time early. Another blackout will simply result in 0
lateness.
- A blackout anytime after getting the time stamp -- be it even before
actually queuing the event or anywhere in the looper thread -- will not
affect the computed lateness and will thus not increase the upstream
node's latency. The buffer will be processed and sent downstream where it
will possibly arrive late, which will cause a late notice and an increase
of the internal latency. Eventually the internal latency will have been
increased by a full blackout time. Hence the looper will schedule the
wakeup time a full blackout time earlier. Thereafter:
- A blackout before starting to wait will simply cause the event to be
pulled out of the queue without wait at wakeup time + blackout time. Since
the internal latency includes a full blackout time, there's still enough
time to process and send the buffer so that it arrives in time.
- A blackout while or immediately after waiting will cause the event to
be pulled out of the queue at the latest at wakeup time + blackout time,
so, again, in time for the downstream node.
- In case of a later blackout the event will be pulled out of the queue
at wakeup time, so there's a full additional blackout time left for
processing and sending the buffer, which compensates for the blackout.
So in neither case latencies will be increased unboundedly.
> > > LateNoticeReceived will also adjust internal latency, but as far as
I can tell is never invoked!
> > That's bad and should be fixed.
> I'm not exactly sure of the flow sequence here. I think MixerInput is
the next in line?
No, that's just part of the mixer. The whole mixer is a single node. Next
upstream you usually already have the audio producer.
> I presume MultiAudio gets the actual mixer output, but that's probably
too far down the line.
Nope, that's usually already the next one downstream. Just check with
Cortex.
> > > In all cases, lateness is only acted upon if it is an ''initial''
report, as multiple buffers following in the queue will also be flagged
late. The fLastNotification variable has been redirected for this
purpose, as its original use in LateNoticeReceived seemed to be pointless.
> >
> > The purpose of `fLastLateNotification` is to prevent a reaction to a
late notice before the latency adjustment caused by the previous late
notice could have taken effect. Looking at the code I'd say the value it
is currently set to (`TimeSource()->Now()`) should be increased by the
downstream and internal latency, since any buffer that already has been or
is currently being processed won't benefit from the latency change. So in
that your change is correct, but the respective change in
`HandleInputBuffer()` seems superfluous at best.
> ("Now"+downstream+internal) should be approximately the same as the
buffer start time by my calculation, so I chose that for convenience.
> The `HandleInputBuffer()` code section is intended to compensate for
queued buffers all being affected by a single blackout,
To clarify what I mean: This code is insufficient, because only the late
notice receiver can really decide whether an internal latency change due
to a previous late notice happened before or after processing the buffer
causing the current late notice. And since the late notice receiver has to
do that anyway (haven't checked whether it actually does in this case),
the code in `HandleInputBuffer()` is superfluous.
Apropos, latency change: I noticed that
`BMediaEventLooper::SetEventLatency()` does not wake up the looper thread,
which means that the event currently waited on will not be affected by the
latency change.
--
Ticket URL: <http://dev.haiku-os.org/ticket/7285#comment:15>
Haiku <http://dev.haiku-os.org>
Haiku - the operating system.
Other related posts:
- » [haiku-bugs] [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - bonefish
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Disreali
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - marcusoverhagen
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - luroh
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - luroh
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - ttcoder
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - Pete
- » [haiku-bugs] Re: [Haiku] #7285: BSoundPlayer sends buffers late, with ever-increasing latency - pulkomandy