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 /* Don't restore (or save) stream volume for passthrough streams */
323 if (!pa_format_info_is_pcm(data->format)) {
324 data->volume_is_set = FALSE;
325 data->volume_factor_is_set = FALSE;
328 if (!data->volume_is_set) {
329 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
330 data->volume_is_absolute = FALSE;
331 data->save_volume = FALSE;
334 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
336 if (!data->volume_factor_is_set)
337 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
339 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
341 if (!data->volume_factor_sink_is_set)
342 pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
344 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
346 if (!data->muted_is_set)
349 if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
350 data->sample_spec.format = data->sink->sample_spec.format;
352 if (data->flags & PA_SINK_INPUT_FIX_RATE)
353 data->sample_spec.rate = data->sink->sample_spec.rate;
355 original_cm = data->channel_map;
357 if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
358 data->sample_spec.channels = data->sink->sample_spec.channels;
359 data->channel_map = data->sink->channel_map;
362 pa_assert(pa_sample_spec_valid(&data->sample_spec));
363 pa_assert(pa_channel_map_valid(&data->channel_map));
365 /* Due to the fixing of the sample spec the volume might not match anymore */
366 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
368 if (data->resample_method == PA_RESAMPLER_INVALID)
369 data->resample_method = core->resample_method;
371 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
373 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
376 if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
377 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
378 pa_log_warn("Failed to create sink input: sink is suspended.");
379 return -PA_ERR_BADSTATE;
382 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
383 pa_log_warn("Failed to create sink input: too many inputs per sink.");
384 return -PA_ERR_TOOLARGE;
387 if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
388 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
389 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
391 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
392 if (!pa_sink_input_new_data_is_passthrough(data)) /* no resampler for passthrough content */
393 if (!(resampler = pa_resampler_new(
395 &data->sample_spec, &data->channel_map,
396 &data->sink->sample_spec, &data->sink->channel_map,
397 data->resample_method,
398 ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
399 ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
400 (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
401 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
402 pa_log_warn("Unsupported resampling operation.");
403 return -PA_ERR_NOTSUPPORTED;
407 i = pa_msgobject_new(pa_sink_input);
408 i->parent.parent.free = sink_input_free;
409 i->parent.process_msg = pa_sink_input_process_msg;
412 i->state = PA_SINK_INPUT_INIT;
413 i->flags = data->flags;
414 i->proplist = pa_proplist_copy(data->proplist);
415 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
416 i->module = data->module;
417 i->sink = data->sink;
418 i->origin_sink = data->origin_sink;
419 i->client = data->client;
421 i->requested_resample_method = data->resample_method;
422 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
423 i->sample_spec = data->sample_spec;
424 i->channel_map = data->channel_map;
425 i->format = pa_format_info_copy(data->format);
427 if (!data->volume_is_absolute && pa_sink_flat_volume_enabled(i->sink)) {
430 /* When the 'absolute' bool is not set then we'll treat the volume
431 * as relative to the sink volume even in flat volume mode */
432 remapped = data->sink->reference_volume;
433 pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
434 pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
436 i->volume = data->volume;
438 i->volume_factor = data->volume_factor;
439 i->volume_factor_sink = data->volume_factor_sink;
440 i->real_ratio = i->reference_ratio = data->volume;
441 pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
442 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
443 i->volume_writable = data->volume_writable;
444 i->save_volume = data->save_volume;
445 i->save_sink = data->save_sink;
446 i->save_muted = data->save_muted;
448 i->muted = data->muted;
450 if (data->sync_base) {
451 i->sync_next = data->sync_base->sync_next;
452 i->sync_prev = data->sync_base;
454 if (data->sync_base->sync_next)
455 data->sync_base->sync_next->sync_prev = i;
456 data->sync_base->sync_next = i;
458 i->sync_next = i->sync_prev = NULL;
460 i->direct_outputs = pa_idxset_new(NULL, NULL);
465 i->thread_info.state = i->state;
466 i->thread_info.attached = FALSE;
467 pa_atomic_store(&i->thread_info.drained, 1);
468 i->thread_info.sample_spec = i->sample_spec;
469 i->thread_info.resampler = resampler;
470 i->thread_info.soft_volume = i->soft_volume;
471 i->thread_info.muted = i->muted;
472 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
473 i->thread_info.rewrite_nbytes = 0;
474 i->thread_info.rewrite_flush = FALSE;
475 i->thread_info.dont_rewind_render = FALSE;
476 i->thread_info.underrun_for = (uint64_t) -1;
477 i->thread_info.playing_for = 0;
478 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
480 i->thread_info.render_memblockq = pa_memblockq_new(
484 pa_frame_size(&i->sink->sample_spec),
490 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
491 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
494 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
496 pt = pa_proplist_to_string_sep(i->proplist, "\n ");
497 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
499 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
501 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
502 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
506 /* Don't forget to call pa_sink_input_put! */
512 /* Called from main context */
513 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
515 pa_assert_ctl_context();
520 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
521 pa_assert_se(i->sink->n_corked -- >= 1);
522 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
526 /* Called from main context */
527 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
528 pa_sink_input *ssync;
530 pa_assert_ctl_context();
532 if (state == PA_SINK_INPUT_DRAINED)
533 state = PA_SINK_INPUT_RUNNING;
535 if (i->state == state)
538 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);
540 update_n_corked(i, state);
543 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
544 update_n_corked(ssync, state);
545 ssync->state = state;
547 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
548 update_n_corked(ssync, state);
549 ssync->state = state;
552 if (state != PA_SINK_INPUT_UNLINKED) {
553 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
555 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
556 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
558 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
559 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
561 if (PA_SINK_INPUT_IS_LINKED(state))
562 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
565 pa_sink_update_status(i->sink);
568 /* Called from main context */
569 void pa_sink_input_unlink(pa_sink_input *i) {
571 pa_source_output *o, *p = NULL;
574 pa_assert_ctl_context();
576 /* See pa_sink_unlink() for a couple of comments how this function
579 pa_sink_input_ref(i);
581 linked = PA_SINK_INPUT_IS_LINKED(i->state);
584 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
587 i->sync_prev->sync_next = i->sync_next;
589 i->sync_next->sync_prev = i->sync_prev;
591 i->sync_prev = i->sync_next = NULL;
593 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
596 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
597 pa_sink_input_unref(i);
600 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
602 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
604 pa_source_output_kill(o);
608 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
609 i->state = PA_SINK_INPUT_UNLINKED;
611 if (linked && i->sink) {
612 /* We might need to update the sink's volume if we are in flat volume mode. */
613 if (pa_sink_flat_volume_enabled(i->sink))
614 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
616 if (i->sink->asyncmsgq)
617 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
619 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
620 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
621 pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
627 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
628 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
632 pa_sink_update_status(i->sink);
636 pa_core_maybe_vacuum(i->core);
638 pa_sink_input_unref(i);
641 /* Called from main context */
642 static void sink_input_free(pa_object *o) {
643 pa_sink_input* i = PA_SINK_INPUT(o);
646 pa_assert_ctl_context();
647 pa_assert(pa_sink_input_refcnt(i) == 0);
649 if (PA_SINK_INPUT_IS_LINKED(i->state))
650 pa_sink_input_unlink(i);
652 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
654 /* Side note: this function must be able to destruct properly any
655 * kind of sink input in any state, even those which are
656 * "half-moved" or are connected to sinks that have no asyncmsgq
657 * and are hence half-destructed themselves! */
659 if (i->thread_info.render_memblockq)
660 pa_memblockq_free(i->thread_info.render_memblockq);
662 if (i->thread_info.resampler)
663 pa_resampler_free(i->thread_info.resampler);
666 pa_format_info_free(i->format);
669 pa_proplist_free(i->proplist);
671 if (i->direct_outputs)
672 pa_idxset_free(i->direct_outputs, NULL, NULL);
674 if (i->thread_info.direct_outputs)
675 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
681 /* Called from main context */
682 void pa_sink_input_put(pa_sink_input *i) {
683 pa_sink_input_state_t state;
685 pa_sink_input_assert_ref(i);
686 pa_assert_ctl_context();
688 pa_assert(i->state == PA_SINK_INPUT_INIT);
690 /* The following fields must be initialized properly */
692 pa_assert(i->process_rewind);
695 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
697 update_n_corked(i, state);
700 /* We might need to update the sink's volume if we are in flat volume mode. */
701 if (pa_sink_flat_volume_enabled(i->sink))
702 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
704 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
705 pa_assert(pa_cvolume_is_norm(&i->volume));
706 pa_assert(pa_cvolume_is_norm(&i->reference_ratio));
709 set_real_ratio(i, &i->volume);
712 /* If we're entering passthrough mode, disable the monitor */
713 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
714 pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
716 i->thread_info.soft_volume = i->soft_volume;
717 i->thread_info.muted = i->muted;
719 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
721 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
722 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
724 pa_sink_update_status(i->sink);
727 /* Called from main context */
728 void pa_sink_input_kill(pa_sink_input*i) {
729 pa_sink_input_assert_ref(i);
730 pa_assert_ctl_context();
731 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
736 /* Called from main context */
737 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
738 pa_usec_t r[2] = { 0, 0 };
740 pa_sink_input_assert_ref(i);
741 pa_assert_ctl_context();
742 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
744 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
747 r[0] += i->get_latency(i);
750 *sink_latency = r[1];
755 /* Called from thread context */
756 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
757 pa_bool_t do_volume_adj_here, need_volume_factor_sink;
758 pa_bool_t volume_is_norm;
759 size_t block_size_max_sink, block_size_max_sink_input;
762 pa_sink_input_assert_ref(i);
763 pa_sink_input_assert_io_context(i);
764 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
765 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
769 /* pa_log_debug("peek"); */
771 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
772 i->thread_info.state == PA_SINK_INPUT_CORKED ||
773 i->thread_info.state == PA_SINK_INPUT_DRAINED);
775 block_size_max_sink_input = i->thread_info.resampler ?
776 pa_resampler_max_block_size(i->thread_info.resampler) :
777 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
779 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
781 /* Default buffer size */
783 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
785 if (slength > block_size_max_sink)
786 slength = block_size_max_sink;
788 if (i->thread_info.resampler) {
789 ilength = pa_resampler_request(i->thread_info.resampler, slength);
792 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
796 if (ilength > block_size_max_sink_input)
797 ilength = block_size_max_sink_input;
799 /* If the channel maps of the sink and this stream differ, we need
800 * to adjust the volume *before* we resample. Otherwise we can do
801 * it after and leave it for the sink code */
803 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
804 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
805 need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
807 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
810 /* There's nothing in our render queue. We need to fill it up
811 * with data from the implementor. */
813 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
814 i->pop(i, ilength, &tchunk) < 0) {
816 /* OK, we're corked or the implementor didn't give us any
817 * data, so let's just hand out silence */
818 pa_atomic_store(&i->thread_info.drained, 1);
820 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
821 i->thread_info.playing_for = 0;
822 if (i->thread_info.underrun_for != (uint64_t) -1)
823 i->thread_info.underrun_for += ilength;
827 pa_atomic_store(&i->thread_info.drained, 0);
829 pa_assert(tchunk.length > 0);
830 pa_assert(tchunk.memblock);
832 i->thread_info.underrun_for = 0;
833 i->thread_info.playing_for += tchunk.length;
835 while (tchunk.length > 0) {
837 pa_bool_t nvfs = need_volume_factor_sink;
840 pa_memblock_ref(wchunk.memblock);
842 if (wchunk.length > block_size_max_sink_input)
843 wchunk.length = block_size_max_sink_input;
845 /* It might be necessary to adjust the volume here */
846 if (do_volume_adj_here && !volume_is_norm) {
847 pa_memchunk_make_writable(&wchunk, 0);
849 if (i->thread_info.muted) {
850 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
853 } else if (!i->thread_info.resampler && nvfs) {
856 /* If we don't need a resampler we can merge the
857 * post and the pre volume adjustment into one */
859 pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
860 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
864 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
867 if (!i->thread_info.resampler) {
870 pa_memchunk_make_writable(&wchunk, 0);
871 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
874 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
877 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
879 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
881 if (rchunk.memblock) {
884 pa_memchunk_make_writable(&rchunk, 0);
885 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
888 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
889 pa_memblock_unref(rchunk.memblock);
893 pa_memblock_unref(wchunk.memblock);
895 tchunk.index += wchunk.length;
896 tchunk.length -= wchunk.length;
899 pa_memblock_unref(tchunk.memblock);
902 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
904 pa_assert(chunk->length > 0);
905 pa_assert(chunk->memblock);
907 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
909 if (chunk->length > block_size_max_sink)
910 chunk->length = block_size_max_sink;
912 /* Let's see if we had to apply the volume adjustment ourselves,
913 * or if this can be done by the sink for us */
915 if (do_volume_adj_here)
916 /* We had different channel maps, so we already did the adjustment */
917 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
918 else if (i->thread_info.muted)
919 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
920 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
922 *volume = i->thread_info.soft_volume;
925 /* Called from thread context */
926 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
928 pa_sink_input_assert_ref(i);
929 pa_sink_input_assert_io_context(i);
930 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
931 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
932 pa_assert(nbytes > 0);
934 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
936 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
939 /* Called from thread context */
940 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
942 pa_bool_t called = FALSE;
944 pa_sink_input_assert_ref(i);
945 pa_sink_input_assert_io_context(i);
946 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
947 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
949 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
951 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
953 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
954 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
955 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
958 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
960 /* We were asked to drop all buffered data, and rerequest new
961 * data from implementor the next time push() is called */
963 pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
965 } else if (i->thread_info.rewrite_nbytes > 0) {
966 size_t max_rewrite, amount;
968 /* Calculate how much make sense to rewrite at most */
969 max_rewrite = nbytes + lbq;
971 /* Transform into local domain */
972 if (i->thread_info.resampler)
973 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
975 /* Calculate how much of the rewinded data should actually be rewritten */
976 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
979 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
981 /* Tell the implementor */
982 if (i->process_rewind)
983 i->process_rewind(i, amount);
986 /* Convert back to to sink domain */
987 if (i->thread_info.resampler)
988 amount = pa_resampler_result(i->thread_info.resampler, amount);
991 /* Ok, now update the write pointer */
992 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
994 if (i->thread_info.rewrite_flush)
995 pa_memblockq_silence(i->thread_info.render_memblockq);
997 /* And reset the resampler */
998 if (i->thread_info.resampler)
999 pa_resampler_reset(i->thread_info.resampler);
1004 if (i->process_rewind)
1005 i->process_rewind(i, 0);
1007 i->thread_info.rewrite_nbytes = 0;
1008 i->thread_info.rewrite_flush = FALSE;
1009 i->thread_info.dont_rewind_render = FALSE;
1012 /* Called from thread context */
1013 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
1014 pa_sink_input_assert_ref(i);
1015 pa_sink_input_assert_io_context(i);
1017 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
1020 /* Called from thread context */
1021 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
1022 pa_sink_input_assert_ref(i);
1023 pa_sink_input_assert_io_context(i);
1025 /* We're not verifying the status here, to allow this to be called
1026 * in the state change handler between _INIT and _RUNNING */
1028 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
1031 /* Called from thread context */
1032 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1033 pa_sink_input_assert_ref(i);
1034 pa_sink_input_assert_io_context(i);
1035 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1036 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1038 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
1040 if (i->update_max_rewind)
1041 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1044 /* Called from thread context */
1045 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1046 pa_sink_input_assert_ref(i);
1047 pa_sink_input_assert_io_context(i);
1048 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1049 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1051 if (i->update_max_request)
1052 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1055 /* Called from thread context */
1056 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
1057 pa_sink_input_assert_ref(i);
1058 pa_sink_input_assert_io_context(i);
1060 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1061 usec = i->sink->thread_info.fixed_latency;
1063 if (usec != (pa_usec_t) -1)
1064 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1066 i->thread_info.requested_sink_latency = usec;
1067 pa_sink_invalidate_requested_latency(i->sink, TRUE);
1072 /* Called from main context */
1073 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
1074 pa_sink_input_assert_ref(i);
1075 pa_assert_ctl_context();
1077 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1078 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1082 /* If this sink input is not realized yet or we are being moved,
1083 * we have to touch the thread info data directly */
1086 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1087 usec = pa_sink_get_fixed_latency(i->sink);
1089 if (usec != (pa_usec_t) -1) {
1090 pa_usec_t min_latency, max_latency;
1091 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
1092 usec = PA_CLAMP(usec, min_latency, max_latency);
1096 i->thread_info.requested_sink_latency = usec;
1101 /* Called from main context */
1102 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
1103 pa_sink_input_assert_ref(i);
1104 pa_assert_ctl_context();
1106 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1108 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1112 /* If this sink input is not realized yet or we are being moved,
1113 * we have to touch the thread info data directly */
1115 return i->thread_info.requested_sink_latency;
1118 /* Called from main context */
1119 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
1122 pa_sink_input_assert_ref(i);
1123 pa_assert_ctl_context();
1124 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1126 pa_assert(pa_cvolume_valid(volume));
1127 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1128 pa_assert(i->volume_writable);
1130 if (!absolute && pa_sink_flat_volume_enabled(i->sink)) {
1131 v = i->sink->reference_volume;
1132 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1134 if (pa_cvolume_compatible(volume, &i->sample_spec))
1135 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1137 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1139 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1141 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1145 if (pa_cvolume_equal(volume, &i->volume)) {
1146 i->save_volume = i->save_volume || save;
1150 i->volume = *volume;
1151 i->save_volume = save;
1153 if (pa_sink_flat_volume_enabled(i->sink)) {
1154 /* We are in flat volume mode, so let's update all sink input
1155 * volumes and update the flat volume of the sink */
1157 pa_sink_set_volume(i->sink, NULL, TRUE, save);
1160 /* OK, we are in normal volume mode. The volume only affects
1162 set_real_ratio(i, volume);
1164 /* Copy the new soft_volume to the thread_info struct */
1165 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1168 /* The volume changed, let's tell people so */
1169 if (i->volume_changed)
1170 i->volume_changed(i);
1172 /* The virtual volume changed, let's tell people so */
1173 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1176 /* Called from main context */
1177 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1178 pa_sink_input_assert_ref(i);
1179 pa_assert_ctl_context();
1180 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1181 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1183 /* This basically calculates:
1185 * i->real_ratio := v
1186 * i->soft_volume := i->real_ratio * i->volume_factor */
1191 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1193 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1194 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1197 /* Called from main or I/O context */
1198 pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i) {
1199 pa_sink_input_assert_ref(i);
1201 if (PA_UNLIKELY(!pa_format_info_is_pcm(i->format)))
1204 if (PA_UNLIKELY(i->flags & PA_SINK_INPUT_PASSTHROUGH))
1210 /* Called from main context */
1211 pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i) {
1212 pa_sink_input_assert_ref(i);
1213 pa_assert_ctl_context();
1215 return !pa_sink_input_is_passthrough(i);
1218 /* Called from main context */
1219 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1220 pa_sink_input_assert_ref(i);
1221 pa_assert_ctl_context();
1222 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1223 pa_assert(pa_sink_input_is_volume_readable(i));
1225 if (absolute || !pa_sink_flat_volume_enabled(i->sink))
1226 *volume = i->volume;
1228 *volume = i->reference_ratio;
1233 /* Called from main context */
1234 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1235 pa_sink_input_assert_ref(i);
1236 pa_assert_ctl_context();
1237 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1239 if (!i->muted == !mute) {
1240 i->save_muted = i->save_muted || mute;
1245 i->save_muted = save;
1247 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1249 /* The mute status changed, let's tell people so */
1250 if (i->mute_changed)
1253 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1256 /* Called from main context */
1257 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1258 pa_sink_input_assert_ref(i);
1259 pa_assert_ctl_context();
1260 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1265 /* Called from main thread */
1266 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1267 pa_sink_input_assert_ref(i);
1268 pa_assert_ctl_context();
1271 pa_proplist_update(i->proplist, mode, p);
1273 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1274 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1275 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1279 /* Called from main context */
1280 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1281 pa_sink_input_assert_ref(i);
1282 pa_assert_ctl_context();
1283 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1285 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1288 /* Called from main context */
1289 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1290 pa_sink_input_assert_ref(i);
1291 pa_assert_ctl_context();
1292 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1293 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1295 if (i->sample_spec.rate == rate)
1298 i->sample_spec.rate = rate;
1300 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1302 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1306 /* Called from main context */
1307 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1309 pa_sink_input_assert_ref(i);
1310 pa_assert_ctl_context();
1312 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1315 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1317 if (old && name && pa_streq(old, name))
1321 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1323 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1325 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1326 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1327 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1331 /* Called from main context */
1332 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1333 pa_sink_input_assert_ref(i);
1334 pa_assert_ctl_context();
1336 return i->actual_resample_method;
1339 /* Called from main context */
1340 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1341 pa_sink_input_assert_ref(i);
1342 pa_assert_ctl_context();
1343 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1345 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1348 if (i->sync_next || i->sync_prev) {
1349 pa_log_warn("Moving synchronized streams not supported.");
1356 /* Called from main context */
1357 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1358 pa_sink_input_assert_ref(i);
1359 pa_assert_ctl_context();
1360 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1361 pa_sink_assert_ref(dest);
1363 if (dest == i->sink)
1366 if (!pa_sink_input_may_move(i))
1369 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1370 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1374 if (check_passthrough_connection(pa_sink_input_is_passthrough(i), dest) < 0)
1378 if (!i->may_move_to(i, dest))
1384 /* Called from main context */
1385 int pa_sink_input_start_move(pa_sink_input *i) {
1386 pa_source_output *o, *p = NULL;
1389 pa_sink_input_assert_ref(i);
1390 pa_assert_ctl_context();
1391 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1394 if (!pa_sink_input_may_move(i))
1395 return -PA_ERR_NOTSUPPORTED;
1397 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1400 /* Kill directly connected outputs */
1401 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1403 pa_source_output_kill(o);
1406 pa_assert(pa_idxset_isempty(i->direct_outputs));
1408 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1410 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1411 pa_assert_se(i->sink->n_corked-- >= 1);
1413 if (pa_sink_flat_volume_enabled(i->sink))
1414 /* We might need to update the sink's volume if we are in flat
1416 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1418 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1420 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
1421 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
1422 pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
1424 pa_sink_update_status(i->sink);
1425 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1428 pa_sink_input_unref(i);
1433 /* Called from main context. If i has an origin sink that uses volume sharing,
1434 * then also the origin sink and all streams connected to it need to update
1435 * their volume - this function does all that by using recursion. */
1436 static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
1437 pa_cvolume old_volume;
1441 pa_assert(i->sink); /* The destination sink should already be set. */
1443 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1444 pa_sink *root_sink = i->sink;
1445 pa_sink_input *origin_sink_input;
1448 while (root_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
1449 root_sink = root_sink->input_to_master->sink;
1451 if (pa_sink_flat_volume_enabled(i->sink)) {
1452 /* Ok, so the origin sink uses volume sharing, and flat volume is
1453 * enabled. The volume will have to be updated as follows:
1455 * i->volume := i->sink->real_volume
1456 * (handled later by pa_sink_set_volume)
1457 * i->reference_ratio := i->volume / i->sink->reference_volume
1458 * (handled later by pa_sink_set_volume)
1459 * i->real_ratio stays unchanged
1460 * (streams whose origin sink uses volume sharing should
1461 * always have real_ratio of 0 dB)
1462 * i->soft_volume stays unchanged
1463 * (streams whose origin sink uses volume sharing should
1464 * always have volume_factor as soft_volume, so no change
1465 * should be needed) */
1467 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1468 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1470 /* Notifications will be sent by pa_sink_set_volume(). */
1473 /* Ok, so the origin sink uses volume sharing, and flat volume is
1474 * disabled. The volume will have to be updated as follows:
1477 * i->reference_ratio := 0 dB
1478 * i->real_ratio stays unchanged
1479 * (streams whose origin sink uses volume sharing should
1480 * always have real_ratio of 0 dB)
1481 * i->soft_volume stays unchanged
1482 * (streams whose origin sink uses volume sharing should
1483 * always have volume_factor as soft_volume, so no change
1484 * should be needed) */
1486 old_volume = i->volume;
1487 pa_cvolume_reset(&i->volume, i->volume.channels);
1488 pa_cvolume_reset(&i->reference_ratio, i->reference_ratio.channels);
1489 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1490 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1492 /* Notify others about the changed sink input volume. */
1493 if (!pa_cvolume_equal(&i->volume, &old_volume)) {
1494 if (i->volume_changed)
1495 i->volume_changed(i);
1497 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1501 /* Additionally, the origin sink volume needs updating:
1503 * i->origin_sink->reference_volume := root_sink->reference_volume
1504 * i->origin_sink->real_volume := root_sink->real_volume
1505 * i->origin_sink->soft_volume stays unchanged
1506 * (sinks that use volume sharing should always have
1507 * soft_volume of 0 dB) */
1509 old_volume = i->origin_sink->reference_volume;
1511 i->origin_sink->reference_volume = root_sink->reference_volume;
1512 pa_cvolume_remap(&i->origin_sink->reference_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1514 i->origin_sink->real_volume = root_sink->real_volume;
1515 pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1517 pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
1519 /* Notify others about the changed sink volume. If you wonder whether
1520 * i->origin_sink->set_volume() should be called somewhere, that's not
1521 * the case, because sinks that use volume sharing shouldn't have any
1522 * internal volume that set_volume() would update. If you wonder
1523 * whether the thread_info variables should be synced, yes, they
1524 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1526 if (!pa_cvolume_equal(&i->origin_sink->reference_volume, &old_volume))
1527 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, i->origin_sink->index);
1529 /* Recursively update origin sink inputs. */
1530 PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
1531 update_volume_due_to_moving(origin_sink_input, dest);
1534 old_volume = i->volume;
1536 if (pa_sink_flat_volume_enabled(i->sink)) {
1537 /* Ok, so this is a regular stream, and flat volume is enabled. The
1538 * volume will have to be updated as follows:
1540 * i->volume := i->reference_ratio * i->sink->reference_volume
1541 * i->reference_ratio stays unchanged
1542 * i->real_ratio := i->volume / i->sink->real_volume
1543 * (handled later by pa_sink_set_volume)
1544 * i->soft_volume := i->real_ratio * i->volume_factor
1545 * (handled later by pa_sink_set_volume) */
1547 i->volume = i->sink->reference_volume;
1548 pa_cvolume_remap(&i->volume, &i->sink->channel_map, &i->channel_map);
1549 pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
1552 /* Ok, so this is a regular stream, and flat volume is disabled.
1553 * The volume will have to be updated as follows:
1555 * i->volume := i->reference_ratio
1556 * i->reference_ratio stays unchanged
1557 * i->real_ratio := i->reference_ratio
1558 * i->soft_volume := i->real_ratio * i->volume_factor */
1560 i->volume = i->reference_ratio;
1561 i->real_ratio = i->reference_ratio;
1562 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1565 /* Notify others about the changed sink input volume. */
1566 if (!pa_cvolume_equal(&i->volume, &old_volume)) {
1567 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1568 * and soft_volume are not updated yet. Let's hope that the
1569 * callback implementation doesn't care about those variables... */
1570 if (i->volume_changed)
1571 i->volume_changed(i);
1573 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1577 /* If i->sink == dest, then recursion has finished, and we can finally call
1578 * pa_sink_set_volume(), which will do the rest of the updates. */
1579 if ((i->sink == dest) && pa_sink_flat_volume_enabled(i->sink))
1580 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1583 /* Called from main context */
1584 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1585 pa_resampler *new_resampler;
1587 pa_sink_input_assert_ref(i);
1588 pa_assert_ctl_context();
1589 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1590 pa_assert(!i->sink);
1591 pa_sink_assert_ref(dest);
1593 if (!pa_sink_input_may_move_to(i, dest))
1594 return -PA_ERR_NOTSUPPORTED;
1596 if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
1597 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1598 pa_sink_input_send_event(i, PA_STREAM_EVENT_FORMAT_LOST, NULL);
1599 return -PA_ERR_NOTSUPPORTED;
1602 if (i->thread_info.resampler &&
1603 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1604 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1606 /* Try to reuse the old resampler if possible */
1607 new_resampler = i->thread_info.resampler;
1609 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1610 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1611 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1613 /* Okey, we need a new resampler for the new sink */
1615 if (!(new_resampler = pa_resampler_new(
1617 &i->sample_spec, &i->channel_map,
1618 &dest->sample_spec, &dest->channel_map,
1619 i->requested_resample_method,
1620 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1621 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1622 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1623 pa_log_warn("Unsupported resampling operation.");
1624 return -PA_ERR_NOTSUPPORTED;
1627 new_resampler = NULL;
1633 i->save_sink = save;
1634 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1636 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1638 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1639 i->sink->n_corked++;
1641 /* Replace resampler and render queue */
1642 if (new_resampler != i->thread_info.resampler) {
1644 if (i->thread_info.resampler)
1645 pa_resampler_free(i->thread_info.resampler);
1646 i->thread_info.resampler = new_resampler;
1648 pa_memblockq_free(i->thread_info.render_memblockq);
1650 i->thread_info.render_memblockq = pa_memblockq_new(
1652 MEMBLOCKQ_MAXLENGTH,
1654 pa_frame_size(&i->sink->sample_spec),
1660 pa_sink_update_status(dest);
1662 update_volume_due_to_moving(i, dest);
1664 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1666 /* If we're entering passthrough mode, disable the monitor */
1667 if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
1668 pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
1670 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1672 /* Notify everyone */
1673 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1675 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1680 /* Called from main context */
1681 void pa_sink_input_fail_move(pa_sink_input *i) {
1683 pa_sink_input_assert_ref(i);
1684 pa_assert_ctl_context();
1685 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1686 pa_assert(!i->sink);
1688 /* Check if someone wants this sink input? */
1689 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1695 pa_sink_input_kill(i);
1698 /* Called from main context */
1699 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1702 pa_sink_input_assert_ref(i);
1703 pa_assert_ctl_context();
1704 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1706 pa_sink_assert_ref(dest);
1708 if (dest == i->sink)
1711 if (!pa_sink_input_may_move_to(i, dest))
1712 return -PA_ERR_NOTSUPPORTED;
1714 pa_sink_input_ref(i);
1716 if ((r = pa_sink_input_start_move(i)) < 0) {
1717 pa_sink_input_unref(i);
1721 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1722 pa_sink_input_fail_move(i);
1723 pa_sink_input_unref(i);
1727 pa_sink_input_unref(i);
1732 /* Called from IO thread context */
1733 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1734 pa_bool_t corking, uncorking;
1736 pa_sink_input_assert_ref(i);
1737 pa_sink_input_assert_io_context(i);
1739 if (state == i->thread_info.state)
1742 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1743 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1744 pa_atomic_store(&i->thread_info.drained, 1);
1746 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1747 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1749 if (i->state_change)
1750 i->state_change(i, state);
1752 i->thread_info.state = state;
1756 pa_log_debug("Requesting rewind due to corking");
1758 /* This will tell the implementing sink input driver to rewind
1759 * so that the unplayed already mixed data is not lost */
1760 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1762 } else if (uncorking) {
1764 i->thread_info.underrun_for = (uint64_t) -1;
1765 i->thread_info.playing_for = 0;
1767 pa_log_debug("Requesting rewind due to uncorking");
1769 /* OK, we're being uncorked. Make sure we're not rewound when
1770 * the hw buffer is remixed and request a remix. */
1771 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1775 /* Called from thread context, except when it is not. */
1776 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1777 pa_sink_input *i = PA_SINK_INPUT(o);
1778 pa_sink_input_assert_ref(i);
1782 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1783 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1784 i->thread_info.soft_volume = i->soft_volume;
1785 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1789 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1790 if (i->thread_info.muted != i->muted) {
1791 i->thread_info.muted = i->muted;
1792 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1796 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1797 pa_usec_t *r = userdata;
1799 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1800 r[1] += pa_sink_get_latency_within_thread(i->sink);
1805 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1807 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1808 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1812 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1813 pa_sink_input *ssync;
1815 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1817 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1818 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1820 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1821 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1826 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1827 pa_usec_t *usec = userdata;
1829 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1833 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1834 pa_usec_t *r = userdata;
1836 *r = i->thread_info.requested_sink_latency;
1841 return -PA_ERR_NOTIMPLEMENTED;
1844 /* Called from main thread */
1845 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1846 pa_sink_input_assert_ref(i);
1847 pa_assert_ctl_context();
1849 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1850 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1855 /* Called from IO context */
1856 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1857 pa_sink_input_assert_ref(i);
1858 pa_sink_input_assert_io_context(i);
1860 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1861 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1866 /* Called from IO context */
1867 void pa_sink_input_request_rewind(
1869 size_t nbytes /* in our sample spec */,
1872 pa_bool_t dont_rewind_render) {
1876 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1877 * and possible and the exact value of this is passed back the
1878 * implementor via process_rewind(). If 'flush' is also TRUE all
1879 * already rendered data is also dropped.
1881 * If 'rewrite' is FALSE the sink is rewound as far as requested
1882 * and possible and the already rendered data is dropped so that
1883 * in the next iteration we read new data from the
1884 * implementor. This implies 'flush' is TRUE. If
1885 * dont_rewind_render is TRUE then the render memblockq is not
1888 /* nbytes = 0 means maximum rewind request */
1890 pa_sink_input_assert_ref(i);
1891 pa_sink_input_assert_io_context(i);
1892 pa_assert(rewrite || flush);
1893 pa_assert(!dont_rewind_render || !rewrite);
1895 /* We don't take rewind requests while we are corked */
1896 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1899 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1901 /* pa_log_debug("request rewrite %zu", nbytes); */
1903 /* Calculate how much we can rewind locally without having to
1906 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1910 /* Check if rewinding for the maximum is requested, and if so, fix up */
1913 /* Calculate maximum number of bytes that could be rewound in theory */
1914 nbytes = i->sink->thread_info.max_rewind + lbq;
1916 /* Transform from sink domain */
1917 if (i->thread_info.resampler)
1918 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1921 /* Remember how much we actually want to rewrite */
1922 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1924 /* Make sure to not overwrite over underruns */
1925 if (nbytes > i->thread_info.playing_for)
1926 nbytes = (size_t) i->thread_info.playing_for;
1928 i->thread_info.rewrite_nbytes = nbytes;
1930 i->thread_info.rewrite_nbytes = (size_t) -1;
1933 i->thread_info.rewrite_flush =
1934 i->thread_info.rewrite_flush ||
1935 (flush && i->thread_info.rewrite_nbytes != 0);
1937 i->thread_info.dont_rewind_render =
1938 i->thread_info.dont_rewind_render ||
1941 if (nbytes != (size_t) -1) {
1943 /* Transform to sink domain */
1944 if (i->thread_info.resampler)
1945 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1948 pa_sink_request_rewind(i->sink, nbytes - lbq);
1950 /* This call will make sure process_rewind() is called later */
1951 pa_sink_request_rewind(i->sink, 0);
1955 /* Called from main context */
1956 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1957 pa_sink_input_assert_ref(i);
1958 pa_assert_ctl_context();
1961 /* FIXME: Shouldn't access resampler object from main context! */
1963 pa_silence_memchunk_get(
1964 &i->core->silence_cache,
1968 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1973 /* Called from main context */
1974 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1975 pa_proplist *pl = NULL;
1976 pa_sink_input_send_event_hook_data hook_data;
1978 pa_sink_input_assert_ref(i);
1979 pa_assert_ctl_context();
1986 data = pl = pa_proplist_new();
1988 hook_data.sink_input = i;
1989 hook_data.data = data;
1990 hook_data.event = event;
1992 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1995 i->send_event(i, event, data);
1999 pa_proplist_free(pl);