qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

audio/dsound: fix invalid parameters error

Windows (unlike wine) bails out when IDirectSoundBuffer8::Lock is called
with zero length. Also, hw->pos_emul handling was incorrect when
calling this function for the first time.

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Reported-by: KJ Liew <liewkj@yahoo.com>
Tested-by: Howard Spoelstra <hsp.cat7@gmail.com>
Message-id: fe9744216d9d421a2dbb09bcf5fa0dbd18f77ac5.1580684275.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

authored by

Kővágó, Zoltán and committed by
Gerd Hoffmann
fb35c2ce 599eac4e

+26 -8
+2 -4
audio/audio.c
··· 1076 1076 while (live) { 1077 1077 size_t size, decr, proc; 1078 1078 void *buf = hw->pcm_ops->get_buffer_out(hw, &size); 1079 - if (!buf) { 1080 - /* retrying will likely won't help, drop everything. */ 1081 - hw->mix_buf->pos = (hw->mix_buf->pos + live) % hw->mix_buf->size; 1082 - return clipped + live; 1079 + if (!buf || size == 0) { 1080 + break; 1083 1081 } 1084 1082 1085 1083 decr = MIN(size / hw->info.bytes_per_frame, live);
+1
audio/dsound_template.h
··· 244 244 goto fail0; 245 245 } 246 246 247 + ds->first_time = true; 247 248 obt_as.endianness = 0; 248 249 audio_pcm_init_info (&hw->info, &obt_as); 249 250
+23 -4
audio/dsoundaudio.c
··· 53 53 typedef struct { 54 54 HWVoiceOut hw; 55 55 LPDIRECTSOUNDBUFFER dsound_buffer; 56 + bool first_time; 56 57 dsound *s; 57 58 } DSoundVoiceOut; 58 59 59 60 typedef struct { 60 61 HWVoiceIn hw; 61 62 LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer; 63 + bool first_time; 62 64 dsound *s; 63 65 } DSoundVoiceIn; 64 66 ··· 414 416 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; 415 417 LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; 416 418 HRESULT hr; 417 - DWORD ppos, act_size; 419 + DWORD ppos, wpos, act_size; 418 420 size_t req_size; 419 421 int err; 420 422 void *ret; 421 423 422 - hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL); 424 + hr = IDirectSoundBuffer_GetCurrentPosition( 425 + dsb, &ppos, ds->first_time ? &wpos : NULL); 423 426 if (FAILED(hr)) { 424 427 dsound_logerr(hr, "Could not get playback buffer position\n"); 425 428 *size = 0; 426 429 return NULL; 427 430 } 428 431 432 + if (ds->first_time) { 433 + hw->pos_emul = wpos; 434 + ds->first_time = false; 435 + } 436 + 429 437 req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul); 430 438 req_size = MIN(req_size, hw->size_emul - hw->pos_emul); 439 + 440 + if (req_size == 0) { 441 + *size = 0; 442 + return NULL; 443 + } 431 444 432 445 err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL, 433 446 &act_size, NULL, false, ds->s); ··· 508 521 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; 509 522 LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; 510 523 HRESULT hr; 511 - DWORD cpos, act_size; 524 + DWORD cpos, rpos, act_size; 512 525 size_t req_size; 513 526 int err; 514 527 void *ret; 515 528 516 - hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL); 529 + hr = IDirectSoundCaptureBuffer_GetCurrentPosition( 530 + dscb, &cpos, ds->first_time ? &rpos : NULL); 517 531 if (FAILED(hr)) { 518 532 dsound_logerr(hr, "Could not get capture buffer position\n"); 519 533 *size = 0; 520 534 return NULL; 535 + } 536 + 537 + if (ds->first_time) { 538 + hw->pos_emul = rpos; 539 + ds->first_time = false; 521 540 } 522 541 523 542 req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);