[vlc-devel] [Patch] Windows WaveOut

Andre Weber WeberAndre at gmx.de
Mon Feb 25 19:44:23 CET 2008


through the weekend I played several DVD's and got no more errors (than expected;-) with my
changes to the waveout device - no crashs, no lockups. So I think its time to make it final
and apply it - to the trunk.

- what is changed you can read below -- I think with this patch the following tickets
are solved so far?
#897 - works currently only with wxWidgets, because the change of the device list is not
            recognized by the QT interface..
#492 -  nearly - see below - because its no a real issue of SPDIF on windows, its
an issue on the DVD-demux (dvdnav?) I think...


--- first mail ---

awaiting comments, and my be bug reports if my changes to this module, destroyed
it for some other cases -- I think it's still no finally finished, some issues are still not solved
with this. f.e. the one on my windows 2000 Workstations, with active Cool and Quite,
and changing CPU load, there it happens that aout gets empty, and the decoder is to slow
to push enough datapackets into the queue. (I don't if "slow" is the right description,
but the speed on which new packets then arrive in p_aout is slower, than regular playback
speed, so the playback eats up the pre buffer advantage... and then it audio beginns
to stop..)

What did I change? -- you see diff size is nearly complete size, this means I touched
a lot. ;-)

- first was to synchronize the thread which puts data into the waveout device
  with the playback, so implemented the method "Play" in the same way, like it
is done for alsa... on the first call to this method, I set the event (_p_aout->output.p_sys->event)
to wakeup the thread and go on, feeding the waveout. This removes / avoids the massive
starving messages on the beginning of the playback, which happen with current, waveout)

the seond event set there in the else case "_p_aout->output.p_sys->new_buffer_event"
is used to wait in some situation for the next buffer to arrive (will explain this later)

- close - method a little cleanup
mostly reordering of code, for logical reason,
fixed a memory leak, because the last queue buffers, before dying aout, wasn't released
properly, the caused me some trouble on windows 2000, because the driver was still
in the opinion he has allocated buffers, (with enough start / stop - playing I was able
to force a bsod... on windows:)

- now it works this way -
** first stop the thread who feeds the waveout driver
** then try the cancel all running playbacks
(for some drivers, this fails, in this case I decided to wait that
 playback is really done, and free the buffers than..)
** in the other case -- cleanup the buffers immediately

only added some debug messages, to know which parameter where passed to the driver
(may be interesting in case of not working, device. to help the user finding a solution, (or us))

Added a new Parameter uint32_t i_device_id  --> to control which Waveout device
should be used. (currently only the default is supported)

Added a new Parameter uint32_t i_device_id  --> to control which Waveout device
should be used. (currently only the default is supported)

new method extracted from the thread code, because the same logic is required also in close of the driver
normaly this method should only be called inside the thread, or when the thread is allready terminated
(to avoid, problems, with concurrent access)

got the most modifications - first he has to wait, until the first call to the method play before
he will start to feed data, into the waveout buffers.
(this logic is copied, from alsa.c)

Calculation of "next_date" changed, original code - was not very realiable, because in case of SPDIF
output I think that the buffers where marked done, earlier than the playback was done, I think the
WaveOutCallback - is called in this case, in the moment the buffer was copied to some DMA
transferbuffer inside the driver. (so the buffer was done from the point of the user, but not of the audience?)
-- this lead to a wrong assumption about the next_buffer - which was calculated on the base
of the current mdate() + number_of_queued_buffers * play_time_of_buffer --> this leads
to starvation messages...

so I went again to other code from alsa.c and oss.c ... where the next_date was calculated
on base of the start_time of the thread ... (this works for me...)

another thing was - the handling of the case if  "aout_OutputNextBuffer" doesn't return
a buffer to the waveout -- the original code, didn't checked the reason for this, and
only checked if there is something to play in  the buffers left - we can wait until the
driver has finished the next block, which is a bad idea -- because if only one block
is in our queue - and we wait for this block to be finished, as next time to put a new
blocks into the output  - we have lost... there is some latency between the event from
the driver "WaveOutCallback", which uses SetEvent to wakeup the thread - (:-
so there would be GAP in the audio stream.
Most of my tests and debugging showed me - if the queue gets empty as reason
for not getting another buffer, the buffer will arrive only some ms after the call
to aout_OutputNextBuffer -- instead of waiting for the playback, I wait for the
arrival of this buffer, to keep the output playing, using the "new_buffer_event"
which is set in the "play" method,   --> these tricks help mostly for AC3 and DTS.
so if the output is allready playing its last buffer - he feeds this buffer into the
waveout device, early enough to avoid - a playback gap...

In case of starvation -- which should only occur, if the previous output
stages throws some packets away? (is this right??), I decided to let output stop,
and wait for the next buffer in the future, with the same logic that is used to
initialize the output thread? - to come in sync again?

And last but not least -- I added a configuration option to select the waveout device..

Only one problem is left there -- on my german windows - my audiodriver has
a name with "umlaute" in it - which are not currently shown inside QT settings - any
idea ?

What shall you do with this patch? if you are building for windows, and useing
SPDIF output, feel free to try it - and report regressions to me ...  for committing
it into trunk -- I would like that meuuh and some other would look at this...


-------------- next part --------------
A non-text attachment was scrubbed...
Name: waveout.zip
Type: application/x-zip-compressed
Size: 7619 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20080225/b629a175/attachment.bin>

More information about the vlc-devel mailing list