diff options
author | Lennart Poettering <lennart@poettering.net> | 2007-08-11 23:46:51 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2007-08-11 23:46:51 +0000 |
commit | 1cecd46d9573d7bbe1a4e53b469b232a86e47b2a (patch) | |
tree | c7d43ae719c6591a9b032ef152bbcb51955f19cd /src/pulsecore/sink.c | |
parent | 79a586db1775bdadc5f1716f3e398c6c45237af1 (diff) |
Resurrect ability to move streams between sinks
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1649 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/pulsecore/sink.c')
-rw-r--r-- | src/pulsecore/sink.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 929542cc..df08ff6e 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -42,6 +42,7 @@ #include <pulsecore/core-subscribe.h> #include <pulsecore/log.h> #include <pulsecore/macro.h> +#include <pulsecore/play-memblockq.h> #include "sink.h" @@ -721,6 +722,72 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return 0; } + case PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER: { + pa_sink_input_move_info *info = userdata; + int volume_is_norm; + + /* We don't support moving synchronized streams. */ + pa_assert(!info->sink_input->sync_prev); + pa_assert(!info->sink_input->sync_next); + pa_assert(!info->sink_input->thread_info.sync_next); + pa_assert(!info->sink_input->thread_info.sync_prev); + + if (info->ghost_sink_input) { + pa_assert(info->buffer_bytes > 0); + pa_assert(info->buffer); + + volume_is_norm = pa_cvolume_is_norm(&info->sink_input->thread_info.volume); + + pa_log_debug("Buffering %u bytes ...", info->buffer_bytes); + + while (info->buffer_bytes > 0) { + pa_memchunk memchunk; + pa_cvolume volume; + size_t n; + + if (pa_sink_input_peek(info->sink_input, &memchunk, &volume) < 0) + break; + + n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length; + pa_sink_input_drop(info->sink_input, n); + memchunk.length = n; + + if (!volume_is_norm) { + pa_memchunk_make_writable(&memchunk, 0); + pa_volume_memchunk(&memchunk, &s->sample_spec, &volume); + } + + if (pa_memblockq_push(info->buffer, &memchunk) < 0) { + pa_memblock_unref(memchunk.memblock); + break; + } + + pa_memblock_unref(memchunk.memblock); + info->buffer_bytes -= n; + } + + /* Add the remaining already resampled chunk to the buffer */ + if (info->sink_input->thread_info.resampled_chunk.memblock) + pa_memblockq_push(info->buffer, &info->sink_input->thread_info.resampled_chunk); + + pa_memblockq_sink_input_set_queue(info->ghost_sink_input, info->buffer); + + pa_log_debug("Buffered %u bytes ...", pa_memblockq_get_length(info->buffer)); + } + + /* Let's remove the sink input ...*/ + if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(info->sink_input->index))) + pa_sink_input_unref(info->sink_input); + + /* .. and add the ghost sink input instead */ + if (info->ghost_sink_input) { + pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(info->ghost_sink_input->index), pa_sink_input_ref(info->ghost_sink_input)); + info->ghost_sink_input->thread_info.sync_prev = info->ghost_sink_input->thread_info.sync_next = NULL; + } + + return 0; + } + case PA_SINK_MESSAGE_SET_VOLUME: s->thread_info.soft_volume = *((pa_cvolume*) userdata); return 0; |