Commit fb35c2ce authored by Kővágó, Zoltán's avatar Kővágó, Zoltán Committed by Gerd Hoffmann
Browse files

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: default avatarKővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Reported-by: default avatarKJ Liew <liewkj@yahoo.com>
Tested-by: default avatarHoward Spoelstra <hsp.cat7@gmail.com>
Message-id: fe9744216d9d421a2dbb09bcf5fa0dbd18f77ac5.1580684275.git.DirtY.iCE.hu@gmail.com
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 599eac4e
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -1076,10 +1076,8 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
    while (live) {
        size_t size, decr, proc;
        void *buf = hw->pcm_ops->get_buffer_out(hw, &size);
        if (!buf) {
            /* retrying will likely won't help, drop everything. */
            hw->mix_buf->pos = (hw->mix_buf->pos + live) % hw->mix_buf->size;
            return clipped + live;
        if (!buf || size == 0) {
            break;
        }

        decr = MIN(size / hw->info.bytes_per_frame, live);
+1 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
        goto fail0;
    }

    ds->first_time = true;
    obt_as.endianness = 0;
    audio_pcm_init_info (&hw->info, &obt_as);

+23 −4
Original line number Diff line number Diff line
@@ -53,12 +53,14 @@ typedef struct {
typedef struct {
    HWVoiceOut hw;
    LPDIRECTSOUNDBUFFER dsound_buffer;
    bool first_time;
    dsound *s;
} DSoundVoiceOut;

typedef struct {
    HWVoiceIn hw;
    LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
    bool first_time;
    dsound *s;
} DSoundVoiceIn;

@@ -414,21 +416,32 @@ static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
    LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
    HRESULT hr;
    DWORD ppos, act_size;
    DWORD ppos, wpos, act_size;
    size_t req_size;
    int err;
    void *ret;

    hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL);
    hr = IDirectSoundBuffer_GetCurrentPosition(
        dsb, &ppos, ds->first_time ? &wpos : NULL);
    if (FAILED(hr)) {
        dsound_logerr(hr, "Could not get playback buffer position\n");
        *size = 0;
        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 = 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,
                          &act_size, NULL, false, ds->s);
    if (err) {
@@ -508,18 +521,24 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
    LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
    HRESULT hr;
    DWORD cpos, act_size;
    DWORD cpos, rpos, act_size;
    size_t req_size;
    int err;
    void *ret;

    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL);
    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(
        dscb, &cpos, ds->first_time ? &rpos : NULL);
    if (FAILED(hr)) {
        dsound_logerr(hr, "Could not get capture buffer position\n");
        *size = 0;
        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 = MIN(req_size, hw->size_emul - hw->pos_emul);