[MPlayer-dev-eng] [PATCH] Fix ao_dsound looping tail audio when shorter than video

David Bolen db3l.net at gmail.com
Sat Mar 7 01:08:16 CET 2009


Reimar Döffinger <Reimar.Doeffinger at gmx.de> writes:

> On Fri, Mar 06, 2009 at 04:49:35PM -0500, David Bolen wrote:
>> The attached proposed patch corrects this.  The basic flaw appears to
>> be that ao_dsound sets up the play buffer in looping mode.  I don't
>> understand why (it's not a requirement for a secondary DirectSound
>> buffer), but since I definitely get some audio glitches if it isn't
>> set, for the moment I'm willing to go with "because it works" as the
>> reason it was done this way originally.
>
> You misunderstood how this works, contrary to ao_win32 there is only one
> buffer, and that one is read and written like a ring buffer, i.e.
> MPlayer would write some data at the start, dsound would start playing
> from the start, then later MPlayer writes another bit of data right
> after the data it wrote previously while dsound continues playing the
> buffer. If one of them reach the end they will just continue from the
> front again.

Crud, ok yeah, I clearly misunderstood DSBPLAY_LOOPING then.  I knew
the secondary buffer was used as a ring buffer, but thought
DSBPLAY_LOOPING referred to repeating the entire ring, and not the
actual looping intrinsic to it acting as a ring buffer.  The
distortion I got when I removed it makes more sense now.

Just for clarity, by primary/secondary I meant in DirectSound terms,
since there does seem to be both a primary (hdspribuf) and secondary
(hdsbuf) buffer.

> Which also means your change is wrong, if e.g. MPlayer writes that final
> chunk to the front of the buffer but dsound still plays somewhere in the
> middle, disabling looping will cause that final part not to be played at
> all (in so far even the current code is wrong).

Makes sense - I probably just didn't hit that case.

I am a little confused as to why my fix worked at all for my stuff (it
does), since even if my final audio chunk was showing up without
requiring a loop, presumably it wasn't filling in the whole buffer, so
there still should have been garbage in the buffer from the end of the
final chunk to the end of the buffer.  I'd think that would play even
without looping enabled, but maybe without looping DirectSound also
stops when it reaches the end of the last updated portion (since the
lock/append/unlock process does tell DirectSound how much was added).

> dsound should have some overrun detection stuff that maybe would allow
> you to make it stop at the right place. As an alternative, you could
> overwrite as much as possible with zeros (i.e. everything that has
> already been played).

I briefly thought maybe it could be approached more like ao_win32 with
a series of secondary buffers that didn't require looping operation
(that would also fix the minimum 1s playing granularity), but there
doesn't appear to be a way to queue up secondary buffers, so they'd
probably all play on top of each other.

Filling any remaining portion of the buffer at audio end would at
least avoid repeated audio (though still the 1s granularity), but I'm
not sure of a practical way to accomplish it, since I'd sort of have
to chase the currently playing position to ensure everything up through
the end of the buffer was zeroed.

If I get the audio end and knew that no loop was required to play it,
I could just fill to end of the buffer and clear looping.  But if a
loop will be required, I'd somehow have to fill in "behind" the
playing portion or else there will still be non-zero data in the
buffer following the final data at the front.

I guess as you suggest the most plausible approach is to try to stop
it when it hits the logical end of the buffer - there's a notification
mechanism, but it uses a windows event object, so without a native
event loop I'd have to poll that, which would increase the latency of
a response, perhaps still glitching the audio.  I'm not even sure
there's an appropriate point to poll, since the most logical (play)
wouldn't even be getting called when I most cared, which was after the
final audio chunk.  It would be nice to have an audio check_events()
sort of like video.

What a pain.  Ok, clearly more complicated (so I'm glad win32 is
working for me at the moment).  Sorry for the bogus patch ... I'll try
to revisit it when I have a moment, since there are some attractive
aspects of dsound (such as independent volume) that I might prefer
over win32 if I can get this working.

-- David




More information about the MPlayer-dev-eng mailing list