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

paaudio: get/put_buffer functions



This lets us avoid some buffer copying when using mixeng.

Signed-off-by: default avatarKővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Message-id: d03d30138b9b5a9681cc90cbfbfec0a197cac88c.1570996490.git.DirtY.iCE.hu@gmail.com
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 1930616b
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
@@ -99,6 +99,59 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
        }                                                               \
    } while (0)

static void *qpa_get_buffer_in(HWVoiceIn *hw, size_t *size)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
    PAConnection *c = p->g->conn;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");

    if (!p->read_length) {
        r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
        CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
                           "pa_stream_peek failed\n");
    }

    *size = MIN(p->read_length, *size);

    pa_threaded_mainloop_unlock(c->mainloop);
    return (void *) p->read_data;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    *size = 0;
    return NULL;
}

static void qpa_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
    PAConnection *c = p->g->conn;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock,
                    "pa_threaded_mainloop_lock failed\n");

    assert(buf == p->read_data && size <= p->read_length);

    p->read_data += size;
    p->read_length -= size;

    if (size && !p->read_length) {
        r = pa_stream_drop(p->stream);
        CHECK_SUCCESS_GOTO(c, r == 0, unlock, "pa_stream_drop failed\n");
    }

unlock:
    pa_threaded_mainloop_unlock(c->mainloop);
}

static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
@@ -137,6 +190,32 @@ unlock_and_fail:
    return 0;
}

static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
{
    PAVoiceOut *p = (PAVoiceOut *) hw;
    PAConnection *c = p->g->conn;
    void *ret;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");

    *size = -1;
    r = pa_stream_begin_write(p->stream, &ret, size);
    CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail,
                       "pa_stream_begin_write failed\n");

    pa_threaded_mainloop_unlock(c->mainloop);
    return ret;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    *size = 0;
    return NULL;
}

static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length)
{
    PAVoiceOut *p = (PAVoiceOut *) hw;
@@ -701,11 +780,15 @@ static struct audio_pcm_ops qpa_pcm_ops = {
    .init_out = qpa_init_out,
    .fini_out = qpa_fini_out,
    .write    = qpa_write,
    .get_buffer_out = qpa_get_buffer_out,
    .put_buffer_out = qpa_write, /* pa handles it */
    .volume_out = qpa_volume_out,

    .init_in  = qpa_init_in,
    .fini_in  = qpa_fini_in,
    .read     = qpa_read,
    .get_buffer_in = qpa_get_buffer_in,
    .put_buffer_in = qpa_put_buffer_in,
    .volume_in = qpa_volume_in
};