Resurrect ability to move streams between sinks

git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1649 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
Lennart Poettering 2007-08-11 23:46:51 +00:00
parent 79a586db17
commit 1cecd46d95
4 changed files with 236 additions and 169 deletions

View file

@ -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;