2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
35 #include <pulsecore/sample-util.h>
36 #include <pulsecore/core-subscribe.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/play-memblockq.h>
39 #include <pulsecore/namereg.h>
40 #include <pulsecore/core-util.h>
42 #include "sink-input.h"
44 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
45 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
47 static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject);
49 static void sink_input_free(pa_object *o);
51 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
55 data->resample_method = PA_RESAMPLER_INVALID;
56 data->proplist = pa_proplist_new();
61 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
64 if ((data->sample_spec_is_set = !!spec))
65 data->sample_spec = *spec;
68 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
71 if ((data->channel_map_is_set = !!map))
72 data->channel_map = *map;
75 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
78 if ((data->volume_is_set = !!volume))
79 data->volume = *volume;
82 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
84 pa_assert(volume_factor);
86 if (data->volume_factor_is_set)
87 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
89 data->volume_factor_is_set = TRUE;
90 data->volume_factor = *volume_factor;
94 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
97 data->muted_is_set = TRUE;
101 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
104 pa_proplist_free(data->proplist);
107 /* Called from main context */
108 static void reset_callbacks(pa_sink_input *i) {
112 i->process_rewind = NULL;
113 i->update_max_rewind = NULL;
114 i->update_max_request = NULL;
115 i->update_sink_requested_latency = NULL;
116 i->update_sink_latency_range = NULL;
120 i->suspend_within_thread = NULL;
123 i->get_latency = NULL;
124 i->state_change = NULL;
125 i->may_move_to = NULL;
126 i->send_event = NULL;
129 /* Called from main context */
130 int pa_sink_input_new(
133 pa_sink_input_new_data *data,
134 pa_sink_input_flags_t flags) {
137 pa_resampler *resampler = NULL;
138 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
139 pa_channel_map original_cm;
145 pa_assert_ctl_context();
148 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
150 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
153 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
156 data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
157 data->save_sink = FALSE;
160 pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
161 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
162 pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
164 if (!data->sample_spec_is_set)
165 data->sample_spec = data->sink->sample_spec;
167 pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
169 if (!data->channel_map_is_set) {
170 if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
171 data->channel_map = data->sink->channel_map;
173 pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
176 pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
177 pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
179 if (!data->volume_is_set) {
180 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
181 data->volume_is_absolute = FALSE;
182 data->save_volume = FALSE;
185 pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
186 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
188 if (!data->volume_factor_is_set)
189 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
191 pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
192 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
194 if (!data->muted_is_set)
197 if (flags & PA_SINK_INPUT_FIX_FORMAT)
198 data->sample_spec.format = data->sink->sample_spec.format;
200 if (flags & PA_SINK_INPUT_FIX_RATE)
201 data->sample_spec.rate = data->sink->sample_spec.rate;
203 original_cm = data->channel_map;
205 if (flags & PA_SINK_INPUT_FIX_CHANNELS) {
206 data->sample_spec.channels = data->sink->sample_spec.channels;
207 data->channel_map = data->sink->channel_map;
210 pa_assert(pa_sample_spec_valid(&data->sample_spec));
211 pa_assert(pa_channel_map_valid(&data->channel_map));
213 /* Due to the fixing of the sample spec the volume might not match anymore */
214 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
216 if (data->resample_method == PA_RESAMPLER_INVALID)
217 data->resample_method = core->resample_method;
219 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
221 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
224 if ((flags & PA_SINK_INPUT_FAIL_ON_SUSPEND) &&
225 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
226 pa_log_warn("Failed to create sink input: sink is suspended.");
227 return -PA_ERR_BADSTATE;
230 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
231 pa_log_warn("Failed to create sink input: too many inputs per sink.");
232 return -PA_ERR_TOOLARGE;
235 if ((flags & PA_SINK_INPUT_VARIABLE_RATE) ||
236 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
237 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
239 if (!(resampler = pa_resampler_new(
241 &data->sample_spec, &data->channel_map,
242 &data->sink->sample_spec, &data->sink->channel_map,
243 data->resample_method,
244 ((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
245 ((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
246 (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
247 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
248 pa_log_warn("Unsupported resampling operation.");
249 return -PA_ERR_NOTSUPPORTED;
253 i = pa_msgobject_new(pa_sink_input);
254 i->parent.parent.free = sink_input_free;
255 i->parent.process_msg = pa_sink_input_process_msg;
258 i->state = PA_SINK_INPUT_INIT;
260 i->proplist = pa_proplist_copy(data->proplist);
261 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
262 i->module = data->module;
263 i->sink = data->sink;
264 i->client = data->client;
266 i->requested_resample_method = data->resample_method;
267 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
268 i->sample_spec = data->sample_spec;
269 i->channel_map = data->channel_map;
271 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
272 /* When the 'absolute' bool is not set then we'll treat the volume
273 * as relative to the sink volume even in flat volume mode */
275 pa_cvolume v = data->sink->reference_volume;
276 pa_cvolume_remap(&v, &data->sink->channel_map, &data->channel_map);
277 pa_sw_cvolume_multiply(&i->virtual_volume, &data->volume, &v);
279 i->virtual_volume = data->volume;
281 i->volume_factor = data->volume_factor;
282 pa_cvolume_init(&i->soft_volume);
283 memset(i->relative_volume, 0, sizeof(i->relative_volume));
284 i->save_volume = data->save_volume;
285 i->save_sink = data->save_sink;
286 i->save_muted = data->save_muted;
288 i->muted = data->muted;
290 if (data->sync_base) {
291 i->sync_next = data->sync_base->sync_next;
292 i->sync_prev = data->sync_base;
294 if (data->sync_base->sync_next)
295 data->sync_base->sync_next->sync_prev = i;
296 data->sync_base->sync_next = i;
298 i->sync_next = i->sync_prev = NULL;
300 i->direct_outputs = pa_idxset_new(NULL, NULL);
305 i->thread_info.state = i->state;
306 i->thread_info.attached = FALSE;
307 pa_atomic_store(&i->thread_info.drained, 1);
308 i->thread_info.sample_spec = i->sample_spec;
309 i->thread_info.resampler = resampler;
310 i->thread_info.soft_volume = i->soft_volume;
311 i->thread_info.muted = i->muted;
312 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
313 i->thread_info.rewrite_nbytes = 0;
314 i->thread_info.rewrite_flush = FALSE;
315 i->thread_info.dont_rewind_render = FALSE;
316 i->thread_info.underrun_for = (uint64_t) -1;
317 i->thread_info.playing_for = 0;
318 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
320 i->thread_info.render_memblockq = pa_memblockq_new(
324 pa_frame_size(&i->sink->sample_spec),
330 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
331 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
334 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
336 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s",
338 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
340 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
341 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map));
343 /* Don't forget to call pa_sink_input_put! */
349 /* Called from main context */
350 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
352 pa_assert_ctl_context();
357 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
358 pa_assert_se(i->sink->n_corked -- >= 1);
359 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
363 /* Called from main context */
364 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
365 pa_sink_input *ssync;
367 pa_assert_ctl_context();
369 if (state == PA_SINK_INPUT_DRAINED)
370 state = PA_SINK_INPUT_RUNNING;
372 if (i->state == state)
375 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
377 update_n_corked(i, state);
380 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
381 update_n_corked(ssync, state);
382 ssync->state = state;
384 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
385 update_n_corked(ssync, state);
386 ssync->state = state;
389 if (state != PA_SINK_INPUT_UNLINKED) {
390 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
392 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
393 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
395 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
396 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
399 pa_sink_update_status(i->sink);
402 /* Called from main context */
403 void pa_sink_input_unlink(pa_sink_input *i) {
405 pa_source_output *o, *p = NULL;
408 pa_assert_ctl_context();
410 /* See pa_sink_unlink() for a couple of comments how this function
413 pa_sink_input_ref(i);
415 linked = PA_SINK_INPUT_IS_LINKED(i->state);
418 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
421 i->sync_prev->sync_next = i->sync_next;
423 i->sync_next->sync_prev = i->sync_prev;
425 i->sync_prev = i->sync_next = NULL;
427 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
430 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
431 pa_sink_input_unref(i);
434 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
436 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
438 pa_source_output_kill(o);
442 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
443 i->state = PA_SINK_INPUT_UNLINKED;
445 if (linked && i->sink) {
446 /* We might need to update the sink's volume if we are in flat volume mode. */
447 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
448 pa_cvolume new_volume;
449 pa_sink_update_flat_volume(i->sink, &new_volume);
450 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
453 if (i->sink->asyncmsgq)
454 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
460 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
461 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
465 pa_sink_update_status(i->sink);
469 pa_core_maybe_vacuum(i->core);
471 pa_sink_input_unref(i);
474 /* Called from main context */
475 static void sink_input_free(pa_object *o) {
476 pa_sink_input* i = PA_SINK_INPUT(o);
479 pa_assert_ctl_context();
480 pa_assert(pa_sink_input_refcnt(i) == 0);
482 if (PA_SINK_INPUT_IS_LINKED(i->state))
483 pa_sink_input_unlink(i);
485 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
487 pa_assert(!i->thread_info.attached);
489 if (i->thread_info.render_memblockq)
490 pa_memblockq_free(i->thread_info.render_memblockq);
492 if (i->thread_info.resampler)
493 pa_resampler_free(i->thread_info.resampler);
496 pa_proplist_free(i->proplist);
498 if (i->direct_outputs)
499 pa_idxset_free(i->direct_outputs, NULL, NULL);
501 if (i->thread_info.direct_outputs)
502 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
508 /* Called from main context */
509 void pa_sink_input_put(pa_sink_input *i) {
510 pa_sink_input_state_t state;
512 pa_sink_input_assert_ref(i);
513 pa_assert_ctl_context();
515 pa_assert(i->state == PA_SINK_INPUT_INIT);
517 /* The following fields must be initialized properly */
519 pa_assert(i->process_rewind);
522 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
524 update_n_corked(i, state);
527 /* We might need to update the sink's volume if we are in flat volume mode. */
528 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
529 pa_cvolume new_volume;
530 pa_sink_update_flat_volume(i->sink, &new_volume);
531 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
533 pa_sink_input_set_relative_volume(i, &i->virtual_volume);
535 i->thread_info.soft_volume = i->soft_volume;
536 i->thread_info.muted = i->muted;
538 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
540 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
541 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
543 pa_sink_update_status(i->sink);
546 /* Called from main context */
547 void pa_sink_input_kill(pa_sink_input*i) {
548 pa_sink_input_assert_ref(i);
549 pa_assert_ctl_context();
550 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
555 /* Called from main context */
556 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
557 pa_usec_t r[2] = { 0, 0 };
559 pa_sink_input_assert_ref(i);
560 pa_assert_ctl_context();
561 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
563 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
566 r[0] += i->get_latency(i);
569 *sink_latency = r[1];
574 /* Called from thread context */
575 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
576 pa_bool_t do_volume_adj_here;
577 pa_bool_t volume_is_norm;
578 size_t block_size_max_sink, block_size_max_sink_input;
581 pa_sink_input_assert_ref(i);
582 pa_sink_input_assert_io_context(i);
583 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
584 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
588 /* pa_log_debug("peek"); */
590 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
591 i->thread_info.state == PA_SINK_INPUT_CORKED ||
592 i->thread_info.state == PA_SINK_INPUT_DRAINED);
594 block_size_max_sink_input = i->thread_info.resampler ?
595 pa_resampler_max_block_size(i->thread_info.resampler) :
596 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
598 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
600 /* Default buffer size */
602 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
604 if (slength > block_size_max_sink)
605 slength = block_size_max_sink;
607 if (i->thread_info.resampler) {
608 ilength = pa_resampler_request(i->thread_info.resampler, slength);
611 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
615 if (ilength > block_size_max_sink_input)
616 ilength = block_size_max_sink_input;
618 /* If the channel maps of the sink and this stream differ, we need
619 * to adjust the volume *before* we resample. Otherwise we can do
620 * it after and leave it for the sink code */
622 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
623 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
625 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
628 /* There's nothing in our render queue. We need to fill it up
629 * with data from the implementor. */
631 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
632 i->pop(i, ilength, &tchunk) < 0) {
634 /* OK, we're corked or the implementor didn't give us any
635 * data, so let's just hand out silence */
636 pa_atomic_store(&i->thread_info.drained, 1);
638 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
639 i->thread_info.playing_for = 0;
640 if (i->thread_info.underrun_for != (uint64_t) -1)
641 i->thread_info.underrun_for += ilength;
645 pa_atomic_store(&i->thread_info.drained, 0);
647 pa_assert(tchunk.length > 0);
648 pa_assert(tchunk.memblock);
650 i->thread_info.underrun_for = 0;
651 i->thread_info.playing_for += tchunk.length;
653 while (tchunk.length > 0) {
657 pa_memblock_ref(wchunk.memblock);
659 if (wchunk.length > block_size_max_sink_input)
660 wchunk.length = block_size_max_sink_input;
662 /* It might be necessary to adjust the volume here */
663 if (do_volume_adj_here && !volume_is_norm) {
664 pa_memchunk_make_writable(&wchunk, 0);
666 if (i->thread_info.muted)
667 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
669 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
672 if (!i->thread_info.resampler)
673 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
676 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
678 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
680 if (rchunk.memblock) {
681 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
682 pa_memblock_unref(rchunk.memblock);
686 pa_memblock_unref(wchunk.memblock);
688 tchunk.index += wchunk.length;
689 tchunk.length -= wchunk.length;
692 pa_memblock_unref(tchunk.memblock);
695 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
697 pa_assert(chunk->length > 0);
698 pa_assert(chunk->memblock);
700 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
702 if (chunk->length > block_size_max_sink)
703 chunk->length = block_size_max_sink;
705 /* Let's see if we had to apply the volume adjustment ourselves,
706 * or if this can be done by the sink for us */
708 if (do_volume_adj_here)
709 /* We had different channel maps, so we already did the adjustment */
710 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
711 else if (i->thread_info.muted)
712 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
713 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
715 *volume = i->thread_info.soft_volume;
718 /* Called from thread context */
719 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
721 pa_sink_input_assert_ref(i);
722 pa_sink_input_assert_io_context(i);
723 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
724 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
725 pa_assert(nbytes > 0);
727 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
729 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
732 /* Called from thread context */
733 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
735 pa_bool_t called = FALSE;
737 pa_sink_input_assert_ref(i);
738 pa_sink_input_assert_io_context(i);
739 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
740 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
742 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
744 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
746 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
747 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
748 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
751 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
753 /* We were asked to drop all buffered data, and rerequest new
754 * data from implementor the next time push() is called */
756 pa_memblockq_flush_write(i->thread_info.render_memblockq);
758 } else if (i->thread_info.rewrite_nbytes > 0) {
759 size_t max_rewrite, amount;
761 /* Calculate how much make sense to rewrite at most */
762 max_rewrite = nbytes + lbq;
764 /* Transform into local domain */
765 if (i->thread_info.resampler)
766 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
768 /* Calculate how much of the rewinded data should actually be rewritten */
769 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
772 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
774 /* Tell the implementor */
775 if (i->process_rewind)
776 i->process_rewind(i, amount);
779 /* Convert back to to sink domain */
780 if (i->thread_info.resampler)
781 amount = pa_resampler_result(i->thread_info.resampler, amount);
784 /* Ok, now update the write pointer */
785 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
787 if (i->thread_info.rewrite_flush)
788 pa_memblockq_silence(i->thread_info.render_memblockq);
790 /* And reset the resampler */
791 if (i->thread_info.resampler)
792 pa_resampler_reset(i->thread_info.resampler);
797 if (i->process_rewind)
798 i->process_rewind(i, 0);
800 i->thread_info.rewrite_nbytes = 0;
801 i->thread_info.rewrite_flush = FALSE;
802 i->thread_info.dont_rewind_render = FALSE;
805 /* Called from thread context */
806 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
807 pa_sink_input_assert_ref(i);
808 pa_sink_input_assert_io_context(i);
810 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
813 /* Called from thread context */
814 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
815 pa_sink_input_assert_ref(i);
816 pa_sink_input_assert_io_context(i);
818 /* We're not verifying the status here, to allow this to be called
819 * in the state change handler between _INIT and _RUNNING */
821 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
824 /* Called from thread context */
825 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
826 pa_sink_input_assert_ref(i);
827 pa_sink_input_assert_io_context(i);
828 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
829 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
831 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
833 if (i->update_max_rewind)
834 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
837 /* Called from thread context */
838 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
839 pa_sink_input_assert_ref(i);
840 pa_sink_input_assert_io_context(i);
841 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
842 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
844 if (i->update_max_request)
845 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
848 /* Called from thread context */
849 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
850 pa_sink_input_assert_ref(i);
851 pa_sink_input_assert_io_context(i);
853 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
854 usec = i->sink->fixed_latency;
856 if (usec != (pa_usec_t) -1)
857 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
859 i->thread_info.requested_sink_latency = usec;
860 pa_sink_invalidate_requested_latency(i->sink);
865 /* Called from main context */
866 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
867 pa_sink_input_assert_ref(i);
868 pa_assert_ctl_context();
870 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
871 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
875 /* If this sink input is not realized yet or we are being moved,
876 * we have to touch the thread info data directly */
879 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
880 usec = i->sink->fixed_latency;
882 if (usec != (pa_usec_t) -1) {
883 pa_usec_t min_latency, max_latency;
884 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
885 usec = PA_CLAMP(usec, min_latency, max_latency);
889 i->thread_info.requested_sink_latency = usec;
894 /* Called from main context */
895 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
896 pa_sink_input_assert_ref(i);
897 pa_assert_ctl_context();
899 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
901 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
905 /* If this sink input is not realized yet or we are being moved,
906 * we have to touch the thread info data directly */
908 return i->thread_info.requested_sink_latency;
911 /* Called from main context */
912 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
915 pa_sink_input_assert_ref(i);
916 pa_assert_ctl_context();
917 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
919 pa_assert(pa_cvolume_valid(volume));
920 pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
922 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
923 v = i->sink->reference_volume;
924 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
925 volume = pa_sw_cvolume_multiply(&v, &v, volume);
928 if (pa_cvolume_equal(volume, &i->virtual_volume))
931 i->virtual_volume = *volume;
932 i->save_volume = save;
934 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
935 pa_cvolume new_volume;
937 /* We are in flat volume mode, so let's update all sink input
938 * volumes and update the flat volume of the sink */
940 pa_sink_update_flat_volume(i->sink, &new_volume);
941 pa_sink_set_volume(i->sink, &new_volume, FALSE, TRUE, FALSE, FALSE);
945 /* OK, we are in normal volume mode. The volume only affects
947 pa_sink_input_set_relative_volume(i, volume);
949 /* Hooks have the ability to play games with i->soft_volume */
950 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
952 /* Copy the new soft_volume to the thread_info struct */
953 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
956 /* The virtual volume changed, let's tell people so */
957 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
960 /* Called from main context */
961 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
962 pa_sink_input_assert_ref(i);
963 pa_assert_ctl_context();
964 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
966 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
967 pa_cvolume v = i->sink->reference_volume;
968 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
969 pa_sw_cvolume_divide(volume, &i->virtual_volume, &v);
971 *volume = i->virtual_volume;
976 /* Called from main context */
977 pa_cvolume *pa_sink_input_get_relative_volume(pa_sink_input *i, pa_cvolume *v) {
980 pa_sink_input_assert_ref(i);
981 pa_assert_ctl_context();
983 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
985 /* This always returns the relative volume. Converts the float
986 * version into a pa_cvolume */
988 v->channels = i->sample_spec.channels;
990 for (c = 0; c < v->channels; c++)
991 v->values[c] = pa_sw_volume_from_linear(i->relative_volume[c]);
996 /* Called from main context */
997 void pa_sink_input_set_relative_volume(pa_sink_input *i, const pa_cvolume *v) {
1001 pa_sink_input_assert_ref(i);
1002 pa_assert_ctl_context();
1003 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1004 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1007 v = pa_cvolume_reset(&_v, i->sample_spec.channels);
1009 /* This basically calculates:
1011 * i->relative_volume := v
1012 * i->soft_volume := i->relative_volume * i->volume_factor */
1014 i->soft_volume.channels = i->sample_spec.channels;
1016 for (c = 0; c < i->sample_spec.channels; c++) {
1017 i->relative_volume[c] = pa_sw_volume_to_linear(v->values[c]);
1019 i->soft_volume.values[c] = pa_sw_volume_from_linear(
1020 i->relative_volume[c] *
1021 pa_sw_volume_to_linear(i->volume_factor.values[c]));
1024 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1027 /* Called from main context */
1028 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1029 pa_sink_input_assert_ref(i);
1030 pa_assert_ctl_context();
1031 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1033 if (!i->muted == !mute)
1037 i->save_muted = save;
1039 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1040 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1043 /* Called from main context */
1044 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1045 pa_sink_input_assert_ref(i);
1046 pa_assert_ctl_context();
1047 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1052 /* Called from main thread */
1053 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1054 pa_sink_input_assert_ref(i);
1055 pa_assert_ctl_context();
1058 pa_proplist_update(i->proplist, mode, p);
1060 if (PA_SINK_IS_LINKED(i->state)) {
1061 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1062 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1066 /* Called from main context */
1067 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1068 pa_sink_input_assert_ref(i);
1069 pa_assert_ctl_context();
1070 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1072 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1075 /* Called from main context */
1076 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1077 pa_sink_input_assert_ref(i);
1078 pa_assert_ctl_context();
1079 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1080 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1082 if (i->sample_spec.rate == rate)
1085 i->sample_spec.rate = rate;
1087 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1089 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1093 /* Called from main context */
1094 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1096 pa_sink_input_assert_ref(i);
1097 pa_assert_ctl_context();
1099 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1102 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1104 if (old && name && pa_streq(old, name))
1108 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1110 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1112 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1113 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1114 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1118 /* Called from main context */
1119 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1120 pa_sink_input_assert_ref(i);
1121 pa_assert_ctl_context();
1123 return i->actual_resample_method;
1126 /* Called from main context */
1127 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1128 pa_sink_input_assert_ref(i);
1129 pa_assert_ctl_context();
1130 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1132 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1135 if (i->sync_next || i->sync_prev) {
1136 pa_log_warn("Moving synchronised streams not supported.");
1143 /* Called from main context */
1144 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1145 pa_sink_input_assert_ref(i);
1146 pa_assert_ctl_context();
1147 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1148 pa_sink_assert_ref(dest);
1150 if (dest == i->sink)
1153 if (!pa_sink_input_may_move(i))
1156 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1157 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1162 if (!i->may_move_to(i, dest))
1168 /* Called from main context */
1169 int pa_sink_input_start_move(pa_sink_input *i) {
1170 pa_source_output *o, *p = NULL;
1174 pa_sink_input_assert_ref(i);
1175 pa_assert_ctl_context();
1176 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1179 if (!pa_sink_input_may_move(i))
1180 return -PA_ERR_NOTSUPPORTED;
1182 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1187 /* Kill directly connected outputs */
1188 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1190 pa_source_output_kill(o);
1193 pa_assert(pa_idxset_isempty(i->direct_outputs));
1195 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1197 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1198 pa_assert_se(i->sink->n_corked-- >= 1);
1200 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1201 pa_cvolume new_volume;
1203 /* Make the virtual volume relative */
1204 pa_sink_input_get_relative_volume(i, &i->virtual_volume);
1206 /* And reset the the relative volume */
1207 pa_sink_input_set_relative_volume(i, NULL);
1209 /* We might need to update the sink's volume if we are in flat
1211 pa_sink_update_flat_volume(i->sink, &new_volume);
1212 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
1215 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1217 pa_sink_update_status(i->sink);
1220 pa_sink_input_unref(i);
1225 /* Called from main context */
1226 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1227 pa_resampler *new_resampler;
1229 pa_sink_input_assert_ref(i);
1230 pa_assert_ctl_context();
1231 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1232 pa_assert(!i->sink);
1233 pa_sink_assert_ref(dest);
1235 if (!pa_sink_input_may_move_to(i, dest))
1236 return -PA_ERR_NOTSUPPORTED;
1238 if (i->thread_info.resampler &&
1239 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1240 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1242 /* Try to reuse the old resampler if possible */
1243 new_resampler = i->thread_info.resampler;
1245 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1246 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1247 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1249 /* Okey, we need a new resampler for the new sink */
1251 if (!(new_resampler = pa_resampler_new(
1253 &i->sample_spec, &i->channel_map,
1254 &dest->sample_spec, &dest->channel_map,
1255 i->requested_resample_method,
1256 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1257 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1258 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1259 pa_log_warn("Unsupported resampling operation.");
1260 return -PA_ERR_NOTSUPPORTED;
1263 new_resampler = NULL;
1269 i->save_sink = save;
1270 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1272 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1273 i->sink->n_corked++;
1275 /* Replace resampler and render queue */
1276 if (new_resampler != i->thread_info.resampler) {
1278 if (i->thread_info.resampler)
1279 pa_resampler_free(i->thread_info.resampler);
1280 i->thread_info.resampler = new_resampler;
1282 pa_memblockq_free(i->thread_info.render_memblockq);
1284 i->thread_info.render_memblockq = pa_memblockq_new(
1286 MEMBLOCKQ_MAXLENGTH,
1288 pa_frame_size(&i->sink->sample_spec),
1294 pa_sink_update_status(dest);
1296 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1297 pa_cvolume new_volume;
1299 /* Make relative volume absolute again */
1300 pa_cvolume t = dest->reference_volume;
1301 pa_cvolume_remap(&t, &dest->channel_map, &i->channel_map);
1302 pa_sw_cvolume_multiply(&i->virtual_volume, &i->virtual_volume, &t);
1304 /* We might need to update the sink's volume if we are in flat volume mode. */
1305 pa_sink_update_flat_volume(i->sink, &new_volume);
1306 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
1309 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1311 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1313 /* Notify everyone */
1314 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1315 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1320 /* Called from main context */
1321 void pa_sink_input_fail_move(pa_sink_input *i) {
1323 pa_sink_input_assert_ref(i);
1324 pa_assert_ctl_context();
1325 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1326 pa_assert(!i->sink);
1328 /* Check if someone wants this sink input? */
1329 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1335 pa_sink_input_kill(i);
1338 /* Called from main context */
1339 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1342 pa_sink_input_assert_ref(i);
1343 pa_assert_ctl_context();
1344 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1346 pa_sink_assert_ref(dest);
1348 if (dest == i->sink)
1351 if (!pa_sink_input_may_move_to(i, dest))
1352 return -PA_ERR_NOTSUPPORTED;
1354 pa_sink_input_ref(i);
1356 if ((r = pa_sink_input_start_move(i)) < 0) {
1357 pa_sink_input_unref(i);
1361 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1362 pa_sink_input_fail_move(i);
1363 pa_sink_input_unref(i);
1367 pa_sink_input_unref(i);
1372 /* Called from IO thread context */
1373 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1374 pa_bool_t corking, uncorking;
1376 pa_sink_input_assert_ref(i);
1377 pa_sink_input_assert_io_context(i);
1379 if (state == i->thread_info.state)
1382 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1383 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1384 pa_atomic_store(&i->thread_info.drained, 1);
1386 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1387 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1389 if (i->state_change)
1390 i->state_change(i, state);
1392 i->thread_info.state = state;
1396 pa_log_debug("Requesting rewind due to corking");
1398 /* This will tell the implementing sink input driver to rewind
1399 * so that the unplayed already mixed data is not lost */
1400 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1402 } else if (uncorking) {
1404 i->thread_info.underrun_for = (uint64_t) -1;
1405 i->thread_info.playing_for = 0;
1407 pa_log_debug("Requesting rewind due to uncorking");
1409 /* OK, we're being uncorked. Make sure we're not rewound when
1410 * the hw buffer is remixed and request a remix. */
1411 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1415 /* Called from thread context, except when it is not. */
1416 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1417 pa_sink_input *i = PA_SINK_INPUT(o);
1418 pa_sink_input_assert_ref(i);
1422 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1423 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1424 i->thread_info.soft_volume = i->soft_volume;
1425 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1429 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1430 if (i->thread_info.muted != i->muted) {
1431 i->thread_info.muted = i->muted;
1432 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1436 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1437 pa_usec_t *r = userdata;
1439 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1440 r[1] += pa_sink_get_latency_within_thread(i->sink);
1445 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1447 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1448 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1452 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1453 pa_sink_input *ssync;
1455 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1457 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1458 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1460 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1461 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1466 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1467 pa_usec_t *usec = userdata;
1469 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1473 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1474 pa_usec_t *r = userdata;
1476 *r = i->thread_info.requested_sink_latency;
1481 return -PA_ERR_NOTIMPLEMENTED;
1484 /* Called from main thread */
1485 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1486 pa_sink_input_assert_ref(i);
1487 pa_assert_ctl_context();
1489 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1490 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1495 /* Called from IO context */
1496 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1497 pa_sink_input_assert_ref(i);
1498 pa_sink_input_assert_io_context(i);
1500 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1501 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1506 /* Called from IO context */
1507 void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sample spec */, pa_bool_t rewrite, pa_bool_t flush, pa_bool_t dont_rewind_render) {
1510 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1511 * and possible and the exact value of this is passed back the
1512 * implementor via process_rewind(). If 'flush' is also TRUE all
1513 * already rendered data is also dropped.
1515 * If 'rewrite' is FALSE the sink is rewound as far as requested
1516 * and possible and the already rendered data is dropped so that
1517 * in the next iteration we read new data from the
1518 * implementor. This implies 'flush' is TRUE. If
1519 * dont_rewind_render is TRUE then the render memblockq is not
1522 pa_sink_input_assert_ref(i);
1523 pa_sink_input_assert_io_context(i);
1525 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1527 /* pa_log_debug("request rewrite %lu", (unsigned long) nbytes); */
1529 /* We don't take rewind requests while we are corked */
1530 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1533 pa_assert(rewrite || flush);
1534 pa_assert(!dont_rewind_render || !rewrite);
1536 /* Calculate how much we can rewind locally without having to
1539 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1543 /* Check if rewinding for the maximum is requested, and if so, fix up */
1546 /* Calculate maximum number of bytes that could be rewound in theory */
1547 nbytes = i->sink->thread_info.max_rewind + lbq;
1549 /* Transform from sink domain */
1550 if (i->thread_info.resampler)
1551 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1554 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1556 /* Make sure to not overwrite over underruns */
1557 if (nbytes > i->thread_info.playing_for)
1558 nbytes = (size_t) i->thread_info.playing_for;
1560 i->thread_info.rewrite_nbytes = nbytes;
1562 i->thread_info.rewrite_nbytes = (size_t) -1;
1565 i->thread_info.rewrite_flush =
1566 i->thread_info.rewrite_flush ||
1567 (flush && i->thread_info.rewrite_nbytes != 0);
1569 i->thread_info.dont_rewind_render =
1570 i->thread_info.dont_rewind_render ||
1573 if (nbytes != (size_t) -1) {
1575 /* Transform to sink domain */
1576 if (i->thread_info.resampler)
1577 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1580 pa_sink_request_rewind(i->sink, nbytes - lbq);
1582 /* This call will make sure process_rewind() is called later */
1583 pa_sink_request_rewind(i->sink, 0);
1587 /* Called from main context */
1588 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1589 pa_sink_input_assert_ref(i);
1590 pa_assert_ctl_context();
1593 /* FIXME: Shouldn't access resampler object from main context! */
1595 pa_silence_memchunk_get(
1596 &i->core->silence_cache,
1600 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1605 /* Called from main context */
1606 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1607 pa_proplist *pl = NULL;
1608 pa_sink_input_send_event_hook_data hook_data;
1610 pa_sink_input_assert_ref(i);
1611 pa_assert_ctl_context();
1618 data = pl = pa_proplist_new();
1620 hook_data.sink_input = i;
1621 hook_data.data = data;
1622 hook_data.event = event;
1624 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1627 i->send_event(i, event, data);
1631 pa_proplist_free(pl);