summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/sink.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-08-11 23:46:51 +0000
committerLennart Poettering <lennart@poettering.net>2007-08-11 23:46:51 +0000
commit1cecd46d9573d7bbe1a4e53b469b232a86e47b2a (patch)
treec7d43ae719c6591a9b032ef152bbcb51955f19cd /src/pulsecore/sink.c
parent79a586db1775bdadc5f1716f3e398c6c45237af1 (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.c67
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;