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>
34 #include <pulse/internal.h>
36 #include <pulsecore/sample-util.h>
37 #include <pulsecore/core-subscribe.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/play-memblockq.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-util.h>
43 #include "sink-input.h"
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
50 static void sink_input_free(pa_object *o);
51 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
53 static int check_passthrough_connection(pa_bool_t passthrough, pa_sink *dest) {
54 if (pa_sink_is_passthrough(dest)) {
55 pa_log_warn("Sink is already connected to PASSTHROUGH input");
59 /* If current input(s) exist, check new input is not PASSTHROUGH */
60 if (pa_idxset_size(dest->inputs) > 0 && passthrough) {
61 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
68 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
72 data->resample_method = PA_RESAMPLER_INVALID;
73 data->proplist = pa_proplist_new();
74 data->volume_writable = TRUE;
79 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
82 if ((data->sample_spec_is_set = !!spec))
83 data->sample_spec = *spec;
86 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
89 if ((data->channel_map_is_set = !!map))
90 data->channel_map = *map;
93 pa_bool_t pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data) {
96 if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format)))
99 if (PA_UNLIKELY(data->flags & PA_SINK_INPUT_PASSTHROUGH))
105 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
107 pa_assert(data->volume_writable);
109 if ((data->volume_is_set = !!volume))
110 data->volume = *volume;
113 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
115 pa_assert(volume_factor);
117 if (data->volume_factor_is_set)
118 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
120 data->volume_factor_is_set = TRUE;
121 data->volume_factor = *volume_factor;
125 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
127 pa_assert(volume_factor);
129 if (data->volume_factor_sink_is_set)
130 pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
132 data->volume_factor_sink_is_set = TRUE;
133 data->volume_factor_sink = *volume_factor;
137 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
140 data->muted_is_set = TRUE;
141 data->muted = !!mute;
144 pa_bool_t pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, pa_bool_t save) {
145 pa_bool_t ret = TRUE;
146 pa_idxset *formats = NULL;
151 if (!data->req_formats) {
152 /* We're not working with the extended API */
154 data->save_sink = save;
156 /* Extended API: let's see if this sink supports the formats the client can provide */
157 formats = pa_sink_check_formats(s, data->req_formats);
159 if (formats && !pa_idxset_isempty(formats)) {
160 /* Sink supports at least one of the requested formats */
162 data->save_sink = save;
163 if (data->nego_formats)
164 pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
165 data->nego_formats = formats;
167 /* Sink doesn't support any of the formats requested by the client */
169 pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
177 pa_bool_t pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset *formats) {
181 if (data->req_formats)
182 pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
184 data->req_formats = formats;
187 /* Trigger format negotiation */
188 return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink);
194 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
197 if (data->req_formats)
198 pa_idxset_free(data->req_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
200 if (data->nego_formats)
201 pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
204 pa_format_info_free(data->format);
206 pa_proplist_free(data->proplist);
209 /* Called from main context */
210 static void reset_callbacks(pa_sink_input *i) {
214 i->process_rewind = NULL;
215 i->update_max_rewind = NULL;
216 i->update_max_request = NULL;
217 i->update_sink_requested_latency = NULL;
218 i->update_sink_latency_range = NULL;
219 i->update_sink_fixed_latency = NULL;
223 i->suspend_within_thread = NULL;
226 i->get_latency = NULL;
227 i->state_change = NULL;
228 i->may_move_to = NULL;
229 i->send_event = NULL;
230 i->volume_changed = NULL;
231 i->mute_changed = NULL;
234 /* Called from main context */
235 int pa_sink_input_new(
238 pa_sink_input_new_data *data) {
241 pa_resampler *resampler = NULL;
242 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
243 pa_channel_map original_cm;
252 pa_assert_ctl_context();
255 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
257 if (data->origin_sink && (data->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
258 data->volume_writable = FALSE;
260 if (!data->req_formats) {
261 /* From this point on, we want to work only with formats, and get back
262 * to using the sample spec and channel map after all decisions w.r.t.
263 * routing are complete. */
264 pa_idxset *tmp = pa_idxset_new(NULL, NULL);
265 pa_format_info *f = pa_format_info_from_sample_spec(&data->sample_spec, &data->channel_map);
266 pa_idxset_put(tmp, f, NULL);
267 pa_sink_input_new_data_set_formats(data, tmp);
270 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
273 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
276 pa_sink_input_new_data_set_sink(data, pa_namereg_get(core, NULL, PA_NAMEREG_SINK), FALSE);
278 /* Routing's done, we have a sink. Now let's fix the format and set up the
281 /* If something didn't pick a format for us, pick the top-most format since
282 * we assume this is sorted in priority order */
283 if (!data->format && data->nego_formats && !pa_idxset_isempty(data->nego_formats))
284 data->format = pa_format_info_copy(pa_idxset_first(data->nego_formats, NULL));
286 pa_return_val_if_fail(data->format, -PA_ERR_NOTSUPPORTED);
288 /* Now populate the sample spec and format according to the final
289 * format that we've negotiated */
290 if (PA_LIKELY(data->format->encoding == PA_ENCODING_PCM)) {
291 pa_return_val_if_fail(pa_format_info_to_sample_spec(data->format, &ss, &map), -PA_ERR_INVALID);
292 pa_sink_input_new_data_set_sample_spec(data, &ss);
293 if (pa_channel_map_valid(&map))
294 pa_sink_input_new_data_set_channel_map(data, &map);
296 pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data->format, &ss), -PA_ERR_INVALID);
297 pa_sink_input_new_data_set_sample_spec(data, &ss);
300 pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
301 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
302 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);
304 r = check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data), data->sink);
308 if (!data->sample_spec_is_set)
309 data->sample_spec = data->sink->sample_spec;
311 pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
313 if (!data->channel_map_is_set) {
314 if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
315 data->channel_map = data->sink->channel_map;
317 pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
320 pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
322 if (!data->volume_is_set) {
323 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
324 data->volume_is_absolute = FALSE;
325 data->save_volume = FALSE;
328 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
330 if (!data->volume_factor_is_set)
331 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
333 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
335 if (!data->volume_factor_sink_is_set)
336 pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
338 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
340 if (!data->muted_is_set)
343 if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
344 data->sample_spec.format = data->sink->sample_spec.format;
346 if (data->flags & PA_SINK_INPUT_FIX_RATE)
347 data->sample_spec.rate = data->sink->sample_spec.rate;
349 original_cm = data->channel_map;
351 if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
352 data->sample_spec.channels = data->sink->sample_spec.channels;
353 data->channel_map = data->sink->channel_map;
356 pa_assert(pa_sample_spec_valid(&data->sample_spec));
357 pa_assert(pa_channel_map_valid(&data->channel_map));
359 /* Due to the fixing of the sample spec the volume might not match anymore */
360 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
362 if (data->resample_method == PA_RESAMPLER_INVALID)
363 data->resample_method = core->resample_method;
365 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
367 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
370 if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
371 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
372 pa_log_warn("Failed to create sink input: sink is suspended.");
373 return -PA_ERR_BADSTATE;
376 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
377 pa_log_warn("Failed to create sink input: too many inputs per sink.");
378 return -PA_ERR_TOOLARGE;
381 if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
382 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
383 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
385 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
386 if (!pa_sink_input_new_data_is_passthrough(data)) /* no resampler for passthrough content */
387 if (!(resampler = pa_resampler_new(
389 &data->sample_spec, &data->channel_map,
390 &data->sink->sample_spec, &data->sink->channel_map,
391 data->resample_method,
392 ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
393 ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
394 (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
395 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
396 pa_log_warn("Unsupported resampling operation.");
397 return -PA_ERR_NOTSUPPORTED;
401 i = pa_msgobject_new(pa_sink_input);
402 i->parent.parent.free = sink_input_free;
403 i->parent.process_msg = pa_sink_input_process_msg;
406 i->state = PA_SINK_INPUT_INIT;
407 i->flags = data->flags;
408 i->proplist = pa_proplist_copy(data->proplist);
409 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
410 i->module = data->module;
411 i->sink = data->sink;
412 i->origin_sink = data->origin_sink;
413 i->client = data->client;
415 i->requested_resample_method = data->resample_method;
416 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
417 i->sample_spec = data->sample_spec;
418 i->channel_map = data->channel_map;
419 i->format = pa_format_info_copy(data->format);
421 if (!data->volume_is_absolute && pa_sink_flat_volume_enabled(i->sink)) {
424 /* When the 'absolute' bool is not set then we'll treat the volume
425 * as relative to the sink volume even in flat volume mode */
426 remapped = data->sink->reference_volume;
427 pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
428 pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
430 i->volume = data->volume;
432 i->volume_factor = data->volume_factor;
433 i->volume_factor_sink = data->volume_factor_sink;
434 i->real_ratio = i->reference_ratio = data->volume;
435 pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
436 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
437 i->volume_writable = data->volume_writable;
438 i->save_volume = data->save_volume;
439 i->save_sink = data->save_sink;
440 i->save_muted = data->save_muted;
442 i->muted = data->muted;
444 if (data->sync_base) {
445 i->sync_next = data->sync_base->sync_next;
446 i->sync_prev = data->sync_base;
448 if (data->sync_base->sync_next)
449 data->sync_base->sync_next->sync_prev = i;
450 data->sync_base->sync_next = i;
452 i->sync_next = i->sync_prev = NULL;
454 i->direct_outputs = pa_idxset_new(NULL, NULL);
459 i->thread_info.state = i->state;
460 i->thread_info.attached = FALSE;
461 pa_atomic_store(&i->thread_info.drained, 1);
462 i->thread_info.sample_spec = i->sample_spec;
463 i->thread_info.resampler = resampler;
464 i->thread_info.soft_volume = i->soft_volume;
465 i->thread_info.muted = i->muted;
466 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
467 i->thread_info.rewrite_nbytes = 0;
468 i->thread_info.rewrite_flush = FALSE;
469 i->thread_info.dont_rewind_render = FALSE;
470 i->thread_info.underrun_for = (uint64_t) -1;
471 i->thread_info.playing_for = 0;
472 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
474 i->thread_info.render_memblockq = pa_memblockq_new(
478 pa_frame_size(&i->sink->sample_spec),
484 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
485 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
488 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
490 pt = pa_proplist_to_string_sep(i->proplist, "\n ");
491 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
493 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
495 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
496 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
500 /* Don't forget to call pa_sink_input_put! */
506 /* Called from main context */
507 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
509 pa_assert_ctl_context();
514 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
515 pa_assert_se(i->sink->n_corked -- >= 1);
516 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
520 /* Called from main context */
521 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
522 pa_sink_input *ssync;
524 pa_assert_ctl_context();
526 if (state == PA_SINK_INPUT_DRAINED)
527 state = PA_SINK_INPUT_RUNNING;
529 if (i->state == state)
532 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);
534 update_n_corked(i, state);
537 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
538 update_n_corked(ssync, state);
539 ssync->state = state;
541 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
542 update_n_corked(ssync, state);
543 ssync->state = state;
546 if (state != PA_SINK_INPUT_UNLINKED) {
547 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
549 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
550 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
552 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
553 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
555 if (PA_SINK_INPUT_IS_LINKED(state))
556 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
559 pa_sink_update_status(i->sink);
562 /* Called from main context */
563 void pa_sink_input_unlink(pa_sink_input *i) {
565 pa_source_output *o, *p = NULL;
568 pa_assert_ctl_context();
570 /* See pa_sink_unlink() for a couple of comments how this function
573 pa_sink_input_ref(i);
575 linked = PA_SINK_INPUT_IS_LINKED(i->state);
578 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
581 i->sync_prev->sync_next = i->sync_next;
583 i->sync_next->sync_prev = i->sync_prev;
585 i->sync_prev = i->sync_next = NULL;
587 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
590 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
591 pa_sink_input_unref(i);
594 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
596 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
598 pa_source_output_kill(o);
602 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
603 i->state = PA_SINK_INPUT_UNLINKED;
605 if (linked && i->sink) {
606 /* We might need to update the sink's volume if we are in flat volume mode. */
607 if (pa_sink_flat_volume_enabled(i->sink))
608 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
610 if (i->sink->asyncmsgq)
611 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
613 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
614 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
615 pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
621 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
622 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
626 pa_sink_update_status(i->sink);
630 pa_core_maybe_vacuum(i->core);
632 pa_sink_input_unref(i);
635 /* Called from main context */
636 static void sink_input_free(pa_object *o) {
637 pa_sink_input* i = PA_SINK_INPUT(o);
640 pa_assert_ctl_context();
641 pa_assert(pa_sink_input_refcnt(i) == 0);
643 if (PA_SINK_INPUT_IS_LINKED(i->state))
644 pa_sink_input_unlink(i);
646 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
648 /* Side note: this function must be able to destruct properly any
649 * kind of sink input in any state, even those which are
650 * "half-moved" or are connected to sinks that have no asyncmsgq
651 * and are hence half-destructed themselves! */
653 if (i->thread_info.render_memblockq)
654 pa_memblockq_free(i->thread_info.render_memblockq);
656 if (i->thread_info.resampler)
657 pa_resampler_free(i->thread_info.resampler);
660 pa_format_info_free(i->format);
663 pa_proplist_free(i->proplist);
665 if (i->direct_outputs)
666 pa_idxset_free(i->direct_outputs, NULL, NULL);
668 if (i->thread_info.direct_outputs)
669 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
675 /* Called from main context */
676 void pa_sink_input_put(pa_sink_input *i) {
677 pa_sink_input_state_t state;
679 pa_sink_input_assert_ref(i);
680 pa_assert_ctl_context();
682 pa_assert(i->state == PA_SINK_INPUT_INIT);
684 /* The following fields must be initialized properly */
686 pa_assert(i->process_rewind);
689 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
691 update_n_corked(i, state);
694 /* We might need to update the sink's volume if we are in flat volume mode. */
695 if (pa_sink_flat_volume_enabled(i->sink))
696 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
698 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
699 pa_assert(pa_cvolume_is_norm(&i->volume));
700 pa_assert(pa_cvolume_is_norm(&i->reference_ratio));
703 set_real_ratio(i, &i->volume);
706 /* If we're entering passthrough mode, disable the monitor */
707 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
708 pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
710 i->thread_info.soft_volume = i->soft_volume;
711 i->thread_info.muted = i->muted;
713 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
715 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
716 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
718 pa_sink_update_status(i->sink);
721 /* Called from main context */
722 void pa_sink_input_kill(pa_sink_input*i) {
723 pa_sink_input_assert_ref(i);
724 pa_assert_ctl_context();
725 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
730 /* Called from main context */
731 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
732 pa_usec_t r[2] = { 0, 0 };
734 pa_sink_input_assert_ref(i);
735 pa_assert_ctl_context();
736 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
738 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
741 r[0] += i->get_latency(i);
744 *sink_latency = r[1];
749 /* Called from thread context */
750 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
751 pa_bool_t do_volume_adj_here, need_volume_factor_sink;
752 pa_bool_t volume_is_norm;
753 size_t block_size_max_sink, block_size_max_sink_input;
756 pa_sink_input_assert_ref(i);
757 pa_sink_input_assert_io_context(i);
758 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
759 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
763 /* pa_log_debug("peek"); */
765 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
766 i->thread_info.state == PA_SINK_INPUT_CORKED ||
767 i->thread_info.state == PA_SINK_INPUT_DRAINED);
769 block_size_max_sink_input = i->thread_info.resampler ?
770 pa_resampler_max_block_size(i->thread_info.resampler) :
771 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
773 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
775 /* Default buffer size */
777 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
779 if (slength > block_size_max_sink)
780 slength = block_size_max_sink;
782 if (i->thread_info.resampler) {
783 ilength = pa_resampler_request(i->thread_info.resampler, slength);
786 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
790 if (ilength > block_size_max_sink_input)
791 ilength = block_size_max_sink_input;
793 /* If the channel maps of the sink and this stream differ, we need
794 * to adjust the volume *before* we resample. Otherwise we can do
795 * it after and leave it for the sink code */
797 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
798 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
799 need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
801 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
804 /* There's nothing in our render queue. We need to fill it up
805 * with data from the implementor. */
807 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
808 i->pop(i, ilength, &tchunk) < 0) {
810 /* OK, we're corked or the implementor didn't give us any
811 * data, so let's just hand out silence */
812 pa_atomic_store(&i->thread_info.drained, 1);
814 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
815 i->thread_info.playing_for = 0;
816 if (i->thread_info.underrun_for != (uint64_t) -1)
817 i->thread_info.underrun_for += ilength;
821 pa_atomic_store(&i->thread_info.drained, 0);
823 pa_assert(tchunk.length > 0);
824 pa_assert(tchunk.memblock);
826 i->thread_info.underrun_for = 0;
827 i->thread_info.playing_for += tchunk.length;
829 while (tchunk.length > 0) {
831 pa_bool_t nvfs = need_volume_factor_sink;
834 pa_memblock_ref(wchunk.memblock);
836 if (wchunk.length > block_size_max_sink_input)
837 wchunk.length = block_size_max_sink_input;
839 /* It might be necessary to adjust the volume here */
840 if (do_volume_adj_here && !volume_is_norm) {
841 pa_memchunk_make_writable(&wchunk, 0);
843 if (i->thread_info.muted) {
844 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
847 } else if (!i->thread_info.resampler && nvfs) {
850 /* If we don't need a resampler we can merge the
851 * post and the pre volume adjustment into one */
853 pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
854 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
858 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
861 if (!i->thread_info.resampler) {
864 pa_memchunk_make_writable(&wchunk, 0);
865 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
868 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
871 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
873 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
875 if (rchunk.memblock) {
878 pa_memchunk_make_writable(&rchunk, 0);
879 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
882 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
883 pa_memblock_unref(rchunk.memblock);
887 pa_memblock_unref(wchunk.memblock);
889 tchunk.index += wchunk.length;
890 tchunk.length -= wchunk.length;
893 pa_memblock_unref(tchunk.memblock);
896 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
898 pa_assert(chunk->length > 0);
899 pa_assert(chunk->memblock);
901 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
903 if (chunk->length > block_size_max_sink)
904 chunk->length = block_size_max_sink;
906 /* Let's see if we had to apply the volume adjustment ourselves,
907 * or if this can be done by the sink for us */
909 if (do_volume_adj_here)
910 /* We had different channel maps, so we already did the adjustment */
911 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
912 else if (i->thread_info.muted)
913 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
914 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
916 *volume = i->thread_info.soft_volume;
919 /* Called from thread context */
920 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
922 pa_sink_input_assert_ref(i);
923 pa_sink_input_assert_io_context(i);
924 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
925 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
926 pa_assert(nbytes > 0);
928 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
930 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
933 /* Called from thread context */
934 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
936 pa_bool_t called = FALSE;
938 pa_sink_input_assert_ref(i);
939 pa_sink_input_assert_io_context(i);
940 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
941 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
943 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
945 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
947 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
948 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
949 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
952 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
954 /* We were asked to drop all buffered data, and rerequest new
955 * data from implementor the next time push() is called */
957 pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
959 } else if (i->thread_info.rewrite_nbytes > 0) {
960 size_t max_rewrite, amount;
962 /* Calculate how much make sense to rewrite at most */
963 max_rewrite = nbytes + lbq;
965 /* Transform into local domain */
966 if (i->thread_info.resampler)
967 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
969 /* Calculate how much of the rewinded data should actually be rewritten */
970 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
973 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
975 /* Tell the implementor */
976 if (i->process_rewind)
977 i->process_rewind(i, amount);
980 /* Convert back to to sink domain */
981 if (i->thread_info.resampler)
982 amount = pa_resampler_result(i->thread_info.resampler, amount);
985 /* Ok, now update the write pointer */
986 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
988 if (i->thread_info.rewrite_flush)
989 pa_memblockq_silence(i->thread_info.render_memblockq);
991 /* And reset the resampler */
992 if (i->thread_info.resampler)
993 pa_resampler_reset(i->thread_info.resampler);
998 if (i->process_rewind)
999 i->process_rewind(i, 0);
1001 i->thread_info.rewrite_nbytes = 0;
1002 i->thread_info.rewrite_flush = FALSE;
1003 i->thread_info.dont_rewind_render = FALSE;
1006 /* Called from thread context */
1007 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
1008 pa_sink_input_assert_ref(i);
1009 pa_sink_input_assert_io_context(i);
1011 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
1014 /* Called from thread context */
1015 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
1016 pa_sink_input_assert_ref(i);
1017 pa_sink_input_assert_io_context(i);
1019 /* We're not verifying the status here, to allow this to be called
1020 * in the state change handler between _INIT and _RUNNING */
1022 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
1025 /* Called from thread context */
1026 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1027 pa_sink_input_assert_ref(i);
1028 pa_sink_input_assert_io_context(i);
1029 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1030 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1032 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
1034 if (i->update_max_rewind)
1035 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1038 /* Called from thread context */
1039 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1040 pa_sink_input_assert_ref(i);
1041 pa_sink_input_assert_io_context(i);
1042 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1043 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1045 if (i->update_max_request)
1046 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1049 /* Called from thread context */
1050 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
1051 pa_sink_input_assert_ref(i);
1052 pa_sink_input_assert_io_context(i);
1054 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1055 usec = i->sink->thread_info.fixed_latency;
1057 if (usec != (pa_usec_t) -1)
1058 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1060 i->thread_info.requested_sink_latency = usec;
1061 pa_sink_invalidate_requested_latency(i->sink, TRUE);
1066 /* Called from main context */
1067 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
1068 pa_sink_input_assert_ref(i);
1069 pa_assert_ctl_context();
1071 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1072 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1076 /* If this sink input is not realized yet or we are being moved,
1077 * we have to touch the thread info data directly */
1080 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1081 usec = pa_sink_get_fixed_latency(i->sink);
1083 if (usec != (pa_usec_t) -1) {
1084 pa_usec_t min_latency, max_latency;
1085 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
1086 usec = PA_CLAMP(usec, min_latency, max_latency);
1090 i->thread_info.requested_sink_latency = usec;
1095 /* Called from main context */
1096 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
1097 pa_sink_input_assert_ref(i);
1098 pa_assert_ctl_context();
1100 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1102 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1106 /* If this sink input is not realized yet or we are being moved,
1107 * we have to touch the thread info data directly */
1109 return i->thread_info.requested_sink_latency;
1112 /* Called from main context */
1113 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
1116 pa_sink_input_assert_ref(i);
1117 pa_assert_ctl_context();
1118 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1120 pa_assert(pa_cvolume_valid(volume));
1121 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1122 pa_assert(i->volume_writable);
1124 if (!absolute && pa_sink_flat_volume_enabled(i->sink)) {
1125 v = i->sink->reference_volume;
1126 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1128 if (pa_cvolume_compatible(volume, &i->sample_spec))
1129 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1131 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1133 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1135 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1139 if (pa_cvolume_equal(volume, &i->volume)) {
1140 i->save_volume = i->save_volume || save;
1144 i->volume = *volume;
1145 i->save_volume = save;
1147 if (pa_sink_flat_volume_enabled(i->sink)) {
1148 /* We are in flat volume mode, so let's update all sink input
1149 * volumes and update the flat volume of the sink */
1151 pa_sink_set_volume(i->sink, NULL, TRUE, save);
1154 /* OK, we are in normal volume mode. The volume only affects
1156 set_real_ratio(i, volume);
1158 /* Copy the new soft_volume to the thread_info struct */
1159 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1162 /* The volume changed, let's tell people so */
1163 if (i->volume_changed)
1164 i->volume_changed(i);
1166 /* The virtual volume changed, let's tell people so */
1167 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1170 /* Called from main context */
1171 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1172 pa_sink_input_assert_ref(i);
1173 pa_assert_ctl_context();
1174 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1175 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1177 /* This basically calculates:
1179 * i->real_ratio := v
1180 * i->soft_volume := i->real_ratio * i->volume_factor */
1185 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1187 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1188 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1191 /* Called from main or I/O context */
1192 pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i) {
1193 pa_sink_input_assert_ref(i);
1195 if (PA_UNLIKELY(!pa_format_info_is_pcm(i->format)))
1198 if (PA_UNLIKELY(i->flags & PA_SINK_INPUT_PASSTHROUGH))
1204 /* Called from main context */
1205 pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i) {
1206 pa_sink_input_assert_ref(i);
1207 pa_assert_ctl_context();
1209 return !pa_sink_input_is_passthrough(i);
1212 /* Called from main context */
1213 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1214 pa_sink_input_assert_ref(i);
1215 pa_assert_ctl_context();
1216 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1217 pa_assert(pa_sink_input_is_volume_readable(i));
1219 if (absolute || !pa_sink_flat_volume_enabled(i->sink))
1220 *volume = i->volume;
1222 *volume = i->reference_ratio;
1227 /* Called from main context */
1228 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1229 pa_sink_input_assert_ref(i);
1230 pa_assert_ctl_context();
1231 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1233 if (!i->muted == !mute) {
1234 i->save_muted = i->save_muted || mute;
1239 i->save_muted = save;
1241 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1243 /* The mute status changed, let's tell people so */
1244 if (i->mute_changed)
1247 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1250 /* Called from main context */
1251 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1252 pa_sink_input_assert_ref(i);
1253 pa_assert_ctl_context();
1254 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1259 /* Called from main thread */
1260 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1261 pa_sink_input_assert_ref(i);
1262 pa_assert_ctl_context();
1265 pa_proplist_update(i->proplist, mode, p);
1267 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1268 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1269 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1273 /* Called from main context */
1274 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1275 pa_sink_input_assert_ref(i);
1276 pa_assert_ctl_context();
1277 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1279 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1282 /* Called from main context */
1283 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1284 pa_sink_input_assert_ref(i);
1285 pa_assert_ctl_context();
1286 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1287 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1289 if (i->sample_spec.rate == rate)
1292 i->sample_spec.rate = rate;
1294 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1296 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1300 /* Called from main context */
1301 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1303 pa_sink_input_assert_ref(i);
1304 pa_assert_ctl_context();
1306 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1309 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1311 if (old && name && pa_streq(old, name))
1315 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1317 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1319 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1320 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1321 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1325 /* Called from main context */
1326 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1327 pa_sink_input_assert_ref(i);
1328 pa_assert_ctl_context();
1330 return i->actual_resample_method;
1333 /* Called from main context */
1334 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1335 pa_sink_input_assert_ref(i);
1336 pa_assert_ctl_context();
1337 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1339 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1342 if (i->sync_next || i->sync_prev) {
1343 pa_log_warn("Moving synchronized streams not supported.");
1350 /* Called from main context */
1351 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1352 pa_sink_input_assert_ref(i);
1353 pa_assert_ctl_context();
1354 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1355 pa_sink_assert_ref(dest);
1357 if (dest == i->sink)
1360 if (!pa_sink_input_may_move(i))
1363 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1364 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1368 if (check_passthrough_connection(pa_sink_input_is_passthrough(i), dest) < 0)
1372 if (!i->may_move_to(i, dest))
1378 /* Called from main context */
1379 int pa_sink_input_start_move(pa_sink_input *i) {
1380 pa_source_output *o, *p = NULL;
1383 pa_sink_input_assert_ref(i);
1384 pa_assert_ctl_context();
1385 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1388 if (!pa_sink_input_may_move(i))
1389 return -PA_ERR_NOTSUPPORTED;
1391 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1394 /* Kill directly connected outputs */
1395 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1397 pa_source_output_kill(o);
1400 pa_assert(pa_idxset_isempty(i->direct_outputs));
1402 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1404 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1405 pa_assert_se(i->sink->n_corked-- >= 1);
1407 if (pa_sink_flat_volume_enabled(i->sink))
1408 /* We might need to update the sink's volume if we are in flat
1410 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1412 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1414 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
1415 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
1416 pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
1418 pa_sink_update_status(i->sink);
1419 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1422 pa_sink_input_unref(i);
1427 /* Called from main context. If i has an origin sink that uses volume sharing,
1428 * then also the origin sink and all streams connected to it need to update
1429 * their volume - this function does all that by using recursion. */
1430 static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
1431 pa_cvolume old_volume;
1435 pa_assert(i->sink); /* The destination sink should already be set. */
1437 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1438 pa_sink *root_sink = i->sink;
1439 pa_sink_input *origin_sink_input;
1442 while (root_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
1443 root_sink = root_sink->input_to_master->sink;
1445 if (pa_sink_flat_volume_enabled(i->sink)) {
1446 /* Ok, so the origin sink uses volume sharing, and flat volume is
1447 * enabled. The volume will have to be updated as follows:
1449 * i->volume := i->sink->real_volume
1450 * (handled later by pa_sink_set_volume)
1451 * i->reference_ratio := i->volume / i->sink->reference_volume
1452 * (handled later by pa_sink_set_volume)
1453 * i->real_ratio stays unchanged
1454 * (streams whose origin sink uses volume sharing should
1455 * always have real_ratio of 0 dB)
1456 * i->soft_volume stays unchanged
1457 * (streams whose origin sink uses volume sharing should
1458 * always have volume_factor as soft_volume, so no change
1459 * should be needed) */
1461 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1462 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1464 /* Notifications will be sent by pa_sink_set_volume(). */
1467 /* Ok, so the origin sink uses volume sharing, and flat volume is
1468 * disabled. The volume will have to be updated as follows:
1471 * i->reference_ratio := 0 dB
1472 * i->real_ratio stays unchanged
1473 * (streams whose origin sink uses volume sharing should
1474 * always have real_ratio of 0 dB)
1475 * i->soft_volume stays unchanged
1476 * (streams whose origin sink uses volume sharing should
1477 * always have volume_factor as soft_volume, so no change
1478 * should be needed) */
1480 old_volume = i->volume;
1481 pa_cvolume_reset(&i->volume, i->volume.channels);
1482 pa_cvolume_reset(&i->reference_ratio, i->reference_ratio.channels);
1483 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1484 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1486 /* Notify others about the changed sink input volume. */
1487 if (!pa_cvolume_equal(&i->volume, &old_volume)) {
1488 if (i->volume_changed)
1489 i->volume_changed(i);
1491 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1495 /* Additionally, the origin sink volume needs updating:
1497 * i->origin_sink->reference_volume := root_sink->reference_volume
1498 * i->origin_sink->real_volume := root_sink->real_volume
1499 * i->origin_sink->soft_volume stays unchanged
1500 * (sinks that use volume sharing should always have
1501 * soft_volume of 0 dB) */
1503 old_volume = i->origin_sink->reference_volume;
1505 i->origin_sink->reference_volume = root_sink->reference_volume;
1506 pa_cvolume_remap(&i->origin_sink->reference_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1508 i->origin_sink->real_volume = root_sink->real_volume;
1509 pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1511 pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
1513 /* Notify others about the changed sink volume. If you wonder whether
1514 * i->origin_sink->set_volume() should be called somewhere, that's not
1515 * the case, because sinks that use volume sharing shouldn't have any
1516 * internal volume that set_volume() would update. If you wonder
1517 * whether the thread_info variables should be synced, yes, they
1518 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1520 if (!pa_cvolume_equal(&i->origin_sink->reference_volume, &old_volume))
1521 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, i->origin_sink->index);
1523 /* Recursively update origin sink inputs. */
1524 PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
1525 update_volume_due_to_moving(origin_sink_input, dest);
1528 old_volume = i->volume;
1530 if (pa_sink_flat_volume_enabled(i->sink)) {
1531 /* Ok, so this is a regular stream, and flat volume is enabled. The
1532 * volume will have to be updated as follows:
1534 * i->volume := i->reference_ratio * i->sink->reference_volume
1535 * i->reference_ratio stays unchanged
1536 * i->real_ratio := i->volume / i->sink->real_volume
1537 * (handled later by pa_sink_set_volume)
1538 * i->soft_volume := i->real_ratio * i->volume_factor
1539 * (handled later by pa_sink_set_volume) */
1541 i->volume = i->sink->reference_volume;
1542 pa_cvolume_remap(&i->volume, &i->sink->channel_map, &i->channel_map);
1543 pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
1546 /* Ok, so this is a regular stream, and flat volume is disabled.
1547 * The volume will have to be updated as follows:
1549 * i->volume := i->reference_ratio
1550 * i->reference_ratio stays unchanged
1551 * i->real_ratio := i->reference_ratio
1552 * i->soft_volume := i->real_ratio * i->volume_factor */
1554 i->volume = i->reference_ratio;
1555 i->real_ratio = i->reference_ratio;
1556 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1559 /* Notify others about the changed sink input volume. */
1560 if (!pa_cvolume_equal(&i->volume, &old_volume)) {
1561 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1562 * and soft_volume are not updated yet. Let's hope that the
1563 * callback implementation doesn't care about those variables... */
1564 if (i->volume_changed)
1565 i->volume_changed(i);
1567 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1571 /* If i->sink == dest, then recursion has finished, and we can finally call
1572 * pa_sink_set_volume(), which will do the rest of the updates. */
1573 if ((i->sink == dest) && pa_sink_flat_volume_enabled(i->sink))
1574 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1577 /* Called from main context */
1578 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1579 pa_resampler *new_resampler;
1581 pa_sink_input_assert_ref(i);
1582 pa_assert_ctl_context();
1583 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1584 pa_assert(!i->sink);
1585 pa_sink_assert_ref(dest);
1587 if (!pa_sink_input_may_move_to(i, dest))
1588 return -PA_ERR_NOTSUPPORTED;
1590 if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
1591 /* FIXME: Fire a message here so the client can renegotiate */
1592 return -PA_ERR_NOTSUPPORTED;
1595 if (i->thread_info.resampler &&
1596 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1597 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1599 /* Try to reuse the old resampler if possible */
1600 new_resampler = i->thread_info.resampler;
1602 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1603 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1604 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1606 /* Okey, we need a new resampler for the new sink */
1608 if (!(new_resampler = pa_resampler_new(
1610 &i->sample_spec, &i->channel_map,
1611 &dest->sample_spec, &dest->channel_map,
1612 i->requested_resample_method,
1613 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1614 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1615 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1616 pa_log_warn("Unsupported resampling operation.");
1617 return -PA_ERR_NOTSUPPORTED;
1620 new_resampler = NULL;
1626 i->save_sink = save;
1627 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1629 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1631 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1632 i->sink->n_corked++;
1634 /* Replace resampler and render queue */
1635 if (new_resampler != i->thread_info.resampler) {
1637 if (i->thread_info.resampler)
1638 pa_resampler_free(i->thread_info.resampler);
1639 i->thread_info.resampler = new_resampler;
1641 pa_memblockq_free(i->thread_info.render_memblockq);
1643 i->thread_info.render_memblockq = pa_memblockq_new(
1645 MEMBLOCKQ_MAXLENGTH,
1647 pa_frame_size(&i->sink->sample_spec),
1653 pa_sink_update_status(dest);
1655 update_volume_due_to_moving(i, dest);
1657 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1659 /* If we're entering passthrough mode, disable the monitor */
1660 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
1661 pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
1663 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1665 /* Notify everyone */
1666 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1668 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1673 /* Called from main context */
1674 void pa_sink_input_fail_move(pa_sink_input *i) {
1676 pa_sink_input_assert_ref(i);
1677 pa_assert_ctl_context();
1678 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1679 pa_assert(!i->sink);
1681 /* Check if someone wants this sink input? */
1682 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1688 pa_sink_input_kill(i);
1691 /* Called from main context */
1692 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1695 pa_sink_input_assert_ref(i);
1696 pa_assert_ctl_context();
1697 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1699 pa_sink_assert_ref(dest);
1701 if (dest == i->sink)
1704 if (!pa_sink_input_may_move_to(i, dest))
1705 return -PA_ERR_NOTSUPPORTED;
1707 pa_sink_input_ref(i);
1709 if ((r = pa_sink_input_start_move(i)) < 0) {
1710 pa_sink_input_unref(i);
1714 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1715 pa_sink_input_fail_move(i);
1716 pa_sink_input_unref(i);
1720 pa_sink_input_unref(i);
1725 /* Called from IO thread context */
1726 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1727 pa_bool_t corking, uncorking;
1729 pa_sink_input_assert_ref(i);
1730 pa_sink_input_assert_io_context(i);
1732 if (state == i->thread_info.state)
1735 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1736 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1737 pa_atomic_store(&i->thread_info.drained, 1);
1739 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1740 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1742 if (i->state_change)
1743 i->state_change(i, state);
1745 i->thread_info.state = state;
1749 pa_log_debug("Requesting rewind due to corking");
1751 /* This will tell the implementing sink input driver to rewind
1752 * so that the unplayed already mixed data is not lost */
1753 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1755 } else if (uncorking) {
1757 i->thread_info.underrun_for = (uint64_t) -1;
1758 i->thread_info.playing_for = 0;
1760 pa_log_debug("Requesting rewind due to uncorking");
1762 /* OK, we're being uncorked. Make sure we're not rewound when
1763 * the hw buffer is remixed and request a remix. */
1764 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1768 /* Called from thread context, except when it is not. */
1769 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1770 pa_sink_input *i = PA_SINK_INPUT(o);
1771 pa_sink_input_assert_ref(i);
1775 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1776 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1777 i->thread_info.soft_volume = i->soft_volume;
1778 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1782 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1783 if (i->thread_info.muted != i->muted) {
1784 i->thread_info.muted = i->muted;
1785 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1789 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1790 pa_usec_t *r = userdata;
1792 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1793 r[1] += pa_sink_get_latency_within_thread(i->sink);
1798 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1800 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1801 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1805 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1806 pa_sink_input *ssync;
1808 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1810 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1811 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1813 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1814 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1819 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1820 pa_usec_t *usec = userdata;
1822 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1826 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1827 pa_usec_t *r = userdata;
1829 *r = i->thread_info.requested_sink_latency;
1834 return -PA_ERR_NOTIMPLEMENTED;
1837 /* Called from main thread */
1838 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1839 pa_sink_input_assert_ref(i);
1840 pa_assert_ctl_context();
1842 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1843 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1848 /* Called from IO context */
1849 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1850 pa_sink_input_assert_ref(i);
1851 pa_sink_input_assert_io_context(i);
1853 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1854 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1859 /* Called from IO context */
1860 void pa_sink_input_request_rewind(
1862 size_t nbytes /* in our sample spec */,
1865 pa_bool_t dont_rewind_render) {
1869 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1870 * and possible and the exact value of this is passed back the
1871 * implementor via process_rewind(). If 'flush' is also TRUE all
1872 * already rendered data is also dropped.
1874 * If 'rewrite' is FALSE the sink is rewound as far as requested
1875 * and possible and the already rendered data is dropped so that
1876 * in the next iteration we read new data from the
1877 * implementor. This implies 'flush' is TRUE. If
1878 * dont_rewind_render is TRUE then the render memblockq is not
1881 /* nbytes = 0 means maximum rewind request */
1883 pa_sink_input_assert_ref(i);
1884 pa_sink_input_assert_io_context(i);
1885 pa_assert(rewrite || flush);
1886 pa_assert(!dont_rewind_render || !rewrite);
1888 /* We don't take rewind requests while we are corked */
1889 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1892 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1894 /* pa_log_debug("request rewrite %zu", nbytes); */
1896 /* Calculate how much we can rewind locally without having to
1899 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1903 /* Check if rewinding for the maximum is requested, and if so, fix up */
1906 /* Calculate maximum number of bytes that could be rewound in theory */
1907 nbytes = i->sink->thread_info.max_rewind + lbq;
1909 /* Transform from sink domain */
1910 if (i->thread_info.resampler)
1911 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1914 /* Remember how much we actually want to rewrite */
1915 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1917 /* Make sure to not overwrite over underruns */
1918 if (nbytes > i->thread_info.playing_for)
1919 nbytes = (size_t) i->thread_info.playing_for;
1921 i->thread_info.rewrite_nbytes = nbytes;
1923 i->thread_info.rewrite_nbytes = (size_t) -1;
1926 i->thread_info.rewrite_flush =
1927 i->thread_info.rewrite_flush ||
1928 (flush && i->thread_info.rewrite_nbytes != 0);
1930 i->thread_info.dont_rewind_render =
1931 i->thread_info.dont_rewind_render ||
1934 if (nbytes != (size_t) -1) {
1936 /* Transform to sink domain */
1937 if (i->thread_info.resampler)
1938 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1941 pa_sink_request_rewind(i->sink, nbytes - lbq);
1943 /* This call will make sure process_rewind() is called later */
1944 pa_sink_request_rewind(i->sink, 0);
1948 /* Called from main context */
1949 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1950 pa_sink_input_assert_ref(i);
1951 pa_assert_ctl_context();
1954 /* FIXME: Shouldn't access resampler object from main context! */
1956 pa_silence_memchunk_get(
1957 &i->core->silence_cache,
1961 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1966 /* Called from main context */
1967 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1968 pa_proplist *pl = NULL;
1969 pa_sink_input_send_event_hook_data hook_data;
1971 pa_sink_input_assert_ref(i);
1972 pa_assert_ctl_context();
1979 data = pl = pa_proplist_new();
1981 hook_data.sink_input = i;
1982 hook_data.data = data;
1983 hook_data.event = event;
1985 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1988 i->send_event(i, event, data);
1992 pa_proplist_free(pl);