forked from mia/Aegisub
Re-integrate r3740 from the 2.1.8 branch to fix the DirectSoundPlayer2 buffer locking bug.
Updates #1028. Originally committed to SVN as r3751.
This commit is contained in:
parent
afd9133fc0
commit
d2834dca45
1 changed files with 51 additions and 34 deletions
|
@ -157,36 +157,35 @@ class DirectSoundPlayer2Thread {
|
||||||
// Used to signal state-changes to thread
|
// Used to signal state-changes to thread
|
||||||
HANDLE
|
HANDLE
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
event_start_playback,
|
event_start_playback,
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
event_stop_playback,
|
event_stop_playback,
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
event_update_end_time,
|
event_update_end_time,
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
event_set_volume,
|
event_set_volume,
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
event_kill_self;
|
event_kill_self;
|
||||||
|
|
||||||
// Thread communicating back
|
// Thread communicating back
|
||||||
HANDLE
|
HANDLE
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
thread_running,
|
thread_running,
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
is_playing,
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
error_happened;
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
wxChar *error_message;
|
is_playing,
|
||||||
|
|
||||||
|
/// DOCME
|
||||||
|
error_happened;
|
||||||
|
|
||||||
|
/// DOCME
|
||||||
|
const wxChar *error_message;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
double volume;
|
double volume;
|
||||||
|
@ -470,28 +469,46 @@ do_fill_buffer:
|
||||||
int bytes_needed = (int)play_cursor - (int)buffer_offset;
|
int bytes_needed = (int)play_cursor - (int)buffer_offset;
|
||||||
if (bytes_needed < 0) bytes_needed += (int)bufSize;
|
if (bytes_needed < 0) bytes_needed += (int)bufSize;
|
||||||
|
|
||||||
|
// Requesting zero buffer makes Windows cry, and zero buffer seemed to be
|
||||||
|
// a common request on Windows 7. (Maybe related to the new timer coalescing?)
|
||||||
|
// We'll probably get non-zero bytes requested on the next iteration.
|
||||||
|
if (bytes_needed == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
DWORD buf1sz, buf2sz;
|
DWORD buf1sz, buf2sz;
|
||||||
void *buf1, *buf2;
|
void *buf1, *buf2;
|
||||||
|
|
||||||
|
assert(buffer_offset < bufSize);
|
||||||
|
assert(bytes_needed <= bufSize);
|
||||||
|
|
||||||
HRESULT res = bfr->Lock(buffer_offset, bytes_needed, &buf1, &buf1sz, &buf2, &buf2sz, 0);
|
HRESULT res = bfr->Lock(buffer_offset, bytes_needed, &buf1, &buf1sz, &buf2, &buf2sz, 0);
|
||||||
while (FAILED(res)) // yes, while, so I can break out of it without a goto!
|
switch (res)
|
||||||
{
|
{
|
||||||
if (res == DSERR_BUFFERLOST)
|
case DSERR_BUFFERLOST:
|
||||||
|
// Try to regain the buffer
|
||||||
|
// When the buffer was lost the entire contents was lost too, so we have to start over
|
||||||
|
if (SUCCEEDED(bfr->Restore()) &&
|
||||||
|
SUCCEEDED(bfr->Lock(0, bufSize, &buf1, &buf1sz, &buf2, &buf2sz, 0)) &&
|
||||||
|
SUCCEEDED(bfr->Play(0, 0, DSBPLAY_LOOPING)))
|
||||||
{
|
{
|
||||||
// Try to regain the buffer
|
wxLogDebug(_T("DirectSoundPlayer2: Lost and restored buffer"));
|
||||||
// When the buffer was lost the entire contents was lost too, so we have to start over
|
break;
|
||||||
if (SUCCEEDED(bfr->Restore()) &&
|
|
||||||
SUCCEEDED(bfr->Lock(0, bufSize, &buf1, &buf1sz, &buf2, &buf2sz, 0)) &&
|
|
||||||
SUCCEEDED(bfr->Play(0, 0, DSBPLAY_LOOPING)))
|
|
||||||
{
|
|
||||||
wxLogDebug(_T("DirectSoundPlayer2: Lost and restored buffer"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
REPORT_ERROR("Lost buffer and could not restore it.")
|
|
||||||
}
|
}
|
||||||
|
REPORT_ERROR("Lost buffer and could not restore it.")
|
||||||
|
|
||||||
REPORT_ERROR("Could not lock buffer for filling.")
|
case DSERR_INVALIDPARAM:
|
||||||
|
REPORT_ERROR("Invalid parameters to IDirectSoundBuffer8::Lock().")
|
||||||
|
|
||||||
|
case DSERR_INVALIDCALL:
|
||||||
|
REPORT_ERROR("Invalid call to IDirectSoundBuffer8::Lock().")
|
||||||
|
|
||||||
|
case DSERR_PRIOLEVELNEEDED:
|
||||||
|
REPORT_ERROR("Incorrect priority level set on DirectSoundBuffer8 object.")
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (FAILED(res))
|
||||||
|
REPORT_ERROR("Could not lock audio buffer, unknown error.")
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD bytes_filled = FillAndUnlockBuffers(buf1, buf1sz, buf2, buf2sz, next_input_frame, bfr.obj);
|
DWORD bytes_filled = FillAndUnlockBuffers(buf1, buf1sz, buf2, buf2sz, next_input_frame, bfr.obj);
|
||||||
|
|
Loading…
Reference in a new issue