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>
This commit is contained in:
parent
599eac4e5a
commit
fb35c2cec5
@ -1076,10 +1076,8 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
|
|||||||
while (live) {
|
while (live) {
|
||||||
size_t size, decr, proc;
|
size_t size, decr, proc;
|
||||||
void *buf = hw->pcm_ops->get_buffer_out(hw, &size);
|
void *buf = hw->pcm_ops->get_buffer_out(hw, &size);
|
||||||
if (!buf) {
|
if (!buf || size == 0) {
|
||||||
/* retrying will likely won't help, drop everything. */
|
break;
|
||||||
hw->mix_buf->pos = (hw->mix_buf->pos + live) % hw->mix_buf->size;
|
|
||||||
return clipped + live;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
decr = MIN(size / hw->info.bytes_per_frame, live);
|
decr = MIN(size / hw->info.bytes_per_frame, live);
|
||||||
|
@ -244,6 +244,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
|
|||||||
goto fail0;
|
goto fail0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds->first_time = true;
|
||||||
obt_as.endianness = 0;
|
obt_as.endianness = 0;
|
||||||
audio_pcm_init_info (&hw->info, &obt_as);
|
audio_pcm_init_info (&hw->info, &obt_as);
|
||||||
|
|
||||||
|
@ -53,12 +53,14 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
HWVoiceOut hw;
|
HWVoiceOut hw;
|
||||||
LPDIRECTSOUNDBUFFER dsound_buffer;
|
LPDIRECTSOUNDBUFFER dsound_buffer;
|
||||||
|
bool first_time;
|
||||||
dsound *s;
|
dsound *s;
|
||||||
} DSoundVoiceOut;
|
} DSoundVoiceOut;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HWVoiceIn hw;
|
HWVoiceIn hw;
|
||||||
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
|
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
|
||||||
|
bool first_time;
|
||||||
dsound *s;
|
dsound *s;
|
||||||
} DSoundVoiceIn;
|
} DSoundVoiceIn;
|
||||||
|
|
||||||
@ -414,21 +416,32 @@ static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
|||||||
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
||||||
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
|
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWORD ppos, act_size;
|
DWORD ppos, wpos, act_size;
|
||||||
size_t req_size;
|
size_t req_size;
|
||||||
int err;
|
int err;
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL);
|
hr = IDirectSoundBuffer_GetCurrentPosition(
|
||||||
|
dsb, &ppos, ds->first_time ? &wpos : NULL);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dsound_logerr(hr, "Could not get playback buffer position\n");
|
dsound_logerr(hr, "Could not get playback buffer position\n");
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ds->first_time) {
|
||||||
|
hw->pos_emul = wpos;
|
||||||
|
ds->first_time = false;
|
||||||
|
}
|
||||||
|
|
||||||
req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
|
req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
|
||||||
req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
|
req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
|
||||||
|
|
||||||
|
if (req_size == 0) {
|
||||||
|
*size = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
|
err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
|
||||||
&act_size, NULL, false, ds->s);
|
&act_size, NULL, false, ds->s);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -508,18 +521,24 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
|
|||||||
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
||||||
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
|
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWORD cpos, act_size;
|
DWORD cpos, rpos, act_size;
|
||||||
size_t req_size;
|
size_t req_size;
|
||||||
int err;
|
int err;
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL);
|
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(
|
||||||
|
dscb, &cpos, ds->first_time ? &rpos : NULL);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dsound_logerr(hr, "Could not get capture buffer position\n");
|
dsound_logerr(hr, "Could not get capture buffer position\n");
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ds->first_time) {
|
||||||
|
hw->pos_emul = rpos;
|
||||||
|
ds->first_time = false;
|
||||||
|
}
|
||||||
|
|
||||||
req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
|
req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
|
||||||
req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
|
req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user