mmdevapi buffering
Joerg-Cyril.Hoehle at t-systems.com
Joerg-Cyril.Hoehle at t-systems.com
Wed Jun 1 07:33:40 CDT 2011
Hi,
I have one big concern about MSDN's "Rendering a stream" (shared mode)
example w.r.t wrap-around of buffer pointers and how Wine implements it.
The example is at
http://msdn.microsoft.com/en-us/library/dd316756(v=vs.85).aspx
Suppose the write pointer is near the end of the buffer and the app is
a little late, so the HW read pointer is not far away.
|---------------------------------------------------^read------^write-----|
What is GetCurrentPadding going to return?
- the tiny write-read portion, says MSDN AFAICT
- 0, because there's a new fresh buffer waiting to be filled?
MSDN's example then computes avail = GetBufferSize() - GetCurrentPadding();
What is GetBuffer(avail) going to return?!?
- If it's a pointer to the above buffer, it can only succeed if avail
is tiny, otherwise there's a buffer overflow.
However avail, as defined above and in MSDN's example, will be large.
Wine tricks around that by returning a dynamic local tmp buffer larger than GetBufferSize
(I wonder why a fixed one instead, twice GetBufferSize would not suffice?)
Does native behave like that?
- E_BUFFER_TOO_LARGE ? The MSDN example would exit.
- Could it be a pointer to the beginning of the buffer?
- Or it's a pointer to another buffer!
That's not compatible with Wine's current local_buffer implementation...
Isn't Wine's mmdevapi going to produces glitches?
The problematic situation is when avail is small, as the following sleep for half a
buffer size in MSDN's example will inevitably produce an xrun.
So what actually is the buffer size and how does GetCurrentPadding behave?
I don't expect MSDN's example to be fundamentally flawed. IMHO, they
designed their API such that it is the typical use case.
I believe that multiple buffers (of size GetBufferSize) are
involved (much like ALSA's periods) and that GetBuffer switches among
them -- exactly like they say about the exclusive mode ping pong.
I suppose native's mixer (in shared mode) would mix these possibly
incompletely filled buffers and everything is fine there.
No need to deal with wrap-around!
Why should Wine do something entirely different?
Regards,
Jörg Höhle
More information about the wine-devel
mailing list