X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/4d623f0d4442148f20f2ffdc85cf95e54ef83721..d3f2bfa21bd1966f6d624dfbfc74f8913bb054a5:/src/pulsecore/play-memchunk.c diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 3ebbc14c..26a2bccd 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -1,13 +1,11 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. - Copyright 2004-2006 Lennart Poettering + Copyright 2004-2008 Lennart Poettering PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -27,168 +25,40 @@ #include #include -#include - -#include #include -#include -#include +#include #include "play-memchunk.h" -typedef struct memchunk_stream { - pa_msgobject parent; - pa_core *core; - pa_sink_input *sink_input; - pa_memchunk memchunk; -} memchunk_stream; - -enum { - MEMCHUNK_STREAM_MESSAGE_UNLINK, -}; - -PA_DECLARE_CLASS(memchunk_stream); -#define MEMCHUNK_STREAM(o) (memchunk_stream_cast(o)) -static PA_DEFINE_CHECK_TYPE(memchunk_stream, pa_msgobject); - -static void memchunk_stream_unlink(memchunk_stream *u) { - pa_assert(u); - - if (!u->sink_input) - return; - - pa_sink_input_unlink(u->sink_input); - - pa_sink_input_unref(u->sink_input); - u->sink_input = NULL; - - memchunk_stream_unref(u); -} - -static void memchunk_stream_free(pa_object *o) { - memchunk_stream *u = MEMCHUNK_STREAM(o); - pa_assert(u); - - memchunk_stream_unlink(u); - - if (u->memchunk.memblock) - pa_memblock_unref(u->memchunk.memblock); - - pa_xfree(u); -} - -static int memchunk_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { - memchunk_stream *u = MEMCHUNK_STREAM(o); - memchunk_stream_assert_ref(u); - - switch (code) { - case MEMCHUNK_STREAM_MESSAGE_UNLINK: - memchunk_stream_unlink(u); - break; - } - - return 0; -} - -static void sink_input_kill_cb(pa_sink_input *i) { - pa_sink_input_assert_ref(i); - - memchunk_stream_unlink(MEMCHUNK_STREAM(i->userdata)); -} - -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - memchunk_stream *u; - - pa_assert(i); - pa_assert(chunk); - u = MEMCHUNK_STREAM(i->userdata); - memchunk_stream_assert_ref(u); - - if (!u->memchunk.memblock) - return -1; - - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; - pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u), MEMCHUNK_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); - return -1; - } - - pa_assert(u->memchunk.memblock); - *chunk = u->memchunk; - pa_memblock_ref(chunk->memblock); - - return 0; -} - -static void sink_input_drop_cb(pa_sink_input *i, size_t length) { - memchunk_stream *u; - - pa_assert(i); - pa_assert(length > 0); - u = MEMCHUNK_STREAM(i->userdata); - memchunk_stream_assert_ref(u); - - if (length < u->memchunk.length) { - u->memchunk.length -= length; - u->memchunk.index += length; - } else - u->memchunk.length = 0; -} - int pa_play_memchunk( pa_sink *sink, - const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, - pa_cvolume *volume) { + pa_cvolume *volume, + pa_proplist *p, + pa_sink_input_flags_t flags, + uint32_t *sink_input_index) { - memchunk_stream *u = NULL; - pa_sink_input_new_data data; + pa_memblockq *q; + int r; + pa_memchunk silence; pa_assert(sink); pa_assert(ss); pa_assert(chunk); - if (volume && pa_cvolume_is_muted(volume)) - return 0; - - u = pa_msgobject_new(memchunk_stream); - u->parent.parent.free = memchunk_stream_free; - u->parent.process_msg = memchunk_stream_process_msg; - u->core = sink->core; - u->memchunk = *chunk; - pa_memblock_ref(u->memchunk.memblock); + pa_silence_memchunk_get(&sink->core->silence_cache, sink->core->mempool, &silence, ss, 0); + q = pa_memblockq_new("pa_play_memchunk() q", 0, chunk->length, 0, ss, 1, 1, 0, &silence); + pa_memblock_unref(silence.memblock); - pa_sink_input_new_data_init(&data); - data.sink = sink; - data.driver = __FILE__; - data.name = name; - pa_sink_input_new_data_set_sample_spec(&data, ss); - pa_sink_input_new_data_set_channel_map(&data, map); - pa_sink_input_new_data_set_volume(&data, volume); + pa_assert_se(pa_memblockq_push(q, chunk) >= 0); - if (!(u->sink_input = pa_sink_input_new(sink->core, &data, 0))) - goto fail; - - u->sink_input->peek = sink_input_peek_cb; - u->sink_input->drop = sink_input_drop_cb; - u->sink_input->kill = sink_input_kill_cb; - u->sink_input->userdata = u; - - pa_sink_input_put(u->sink_input); + if ((r = pa_play_memblockq(sink, ss, map, q, volume, p, flags, sink_input_index)) < 0) { + pa_memblockq_free(q); + return r; + } - /* The reference to u is dangling here, because we want to keep - * this stream around until it is fully played. */ - return 0; - -fail: - if (u) - memchunk_stream_unref(u); - - return -1; } -