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
30 #include <pulse/utf8.h>
31 #include <pulse/xmalloc.h>
32 #include <pulse/util.h>
33 #include <pulse/internal.h>
35 #include <pulsecore/mix.h>
36 #include <pulsecore/core-subscribe.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/play-memblockq.h>
39 #include <pulsecore/namereg.h>
40 #include <pulsecore/core-util.h>
42 #include "sink-input.h"
44 /* #define SINK_INPUT_DEBUG */
46 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
47 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
49 PA_DEFINE_PUBLIC_CLASS(pa_sink_input
, pa_msgobject
);
51 struct volume_factor_entry
{
56 static struct volume_factor_entry
*volume_factor_entry_new(const char *key
, const pa_cvolume
*volume
) {
57 struct volume_factor_entry
*entry
;
62 entry
= pa_xnew(struct volume_factor_entry
, 1);
63 entry
->key
= pa_xstrdup(key
);
65 entry
->volume
= *volume
;
70 static void volume_factor_entry_free(struct volume_factor_entry
*volume_entry
) {
71 pa_assert(volume_entry
);
73 pa_xfree(volume_entry
->key
);
74 pa_xfree(volume_entry
);
77 static void volume_factor_from_hashmap(pa_cvolume
*v
, pa_hashmap
*items
, uint8_t channels
) {
78 struct volume_factor_entry
*entry
;
81 pa_cvolume_reset(v
, channels
);
82 PA_HASHMAP_FOREACH(entry
, items
, state
)
83 pa_sw_cvolume_multiply(v
, v
, &entry
->volume
);
86 static void sink_input_free(pa_object
*o
);
87 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
89 static int check_passthrough_connection(bool passthrough
, pa_sink
*dest
) {
90 if (pa_sink_is_passthrough(dest
)) {
91 pa_log_warn("Sink is already connected to PASSTHROUGH input");
95 /* If current input(s) exist, check new input is not PASSTHROUGH */
96 if (pa_idxset_size(dest
->inputs
) > 0 && passthrough
) {
97 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
104 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
108 data
->resample_method
= PA_RESAMPLER_INVALID
;
109 data
->proplist
= pa_proplist_new();
110 data
->volume_writable
= true;
112 data
->volume_factor_items
= pa_hashmap_new(pa_idxset_string_hash_func
, pa_idxset_string_compare_func
);
113 data
->volume_factor_sink_items
= pa_hashmap_new(pa_idxset_string_hash_func
, pa_idxset_string_compare_func
);
118 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
121 if ((data
->sample_spec_is_set
= !!spec
))
122 data
->sample_spec
= *spec
;
125 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
128 if ((data
->channel_map_is_set
= !!map
))
129 data
->channel_map
= *map
;
132 bool pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data
*data
) {
135 if (PA_LIKELY(data
->format
) && PA_UNLIKELY(!pa_format_info_is_pcm(data
->format
)))
138 if (PA_UNLIKELY(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
144 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
146 pa_assert(data
->volume_writable
);
148 if ((data
->volume_is_set
= !!volume
))
149 data
->volume
= *volume
;
152 void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data
*data
, const char *key
, const pa_cvolume
*volume_factor
) {
153 struct volume_factor_entry
*v
;
157 pa_assert(volume_factor
);
159 v
= volume_factor_entry_new(key
, volume_factor
);
160 pa_assert_se(pa_hashmap_put(data
->volume_factor_items
, v
->key
, v
) >= 0);
163 void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data
*data
, const char *key
, const pa_cvolume
*volume_factor
) {
164 struct volume_factor_entry
*v
;
168 pa_assert(volume_factor
);
170 v
= volume_factor_entry_new(key
, volume_factor
);
171 pa_assert_se(pa_hashmap_put(data
->volume_factor_sink_items
, v
->key
, v
) >= 0);
174 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, bool mute
) {
177 data
->muted_is_set
= true;
178 data
->muted
= !!mute
;
181 bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, bool save
) {
183 pa_idxset
*formats
= NULL
;
188 if (!data
->req_formats
) {
189 /* We're not working with the extended API */
191 data
->save_sink
= save
;
193 /* Extended API: let's see if this sink supports the formats the client can provide */
194 formats
= pa_sink_check_formats(s
, data
->req_formats
);
196 if (formats
&& !pa_idxset_isempty(formats
)) {
197 /* Sink supports at least one of the requested formats */
199 data
->save_sink
= save
;
200 if (data
->nego_formats
)
201 pa_idxset_free(data
->nego_formats
, (pa_free_cb_t
) pa_format_info_free
);
202 data
->nego_formats
= formats
;
204 /* Sink doesn't support any of the formats requested by the client */
206 pa_idxset_free(formats
, (pa_free_cb_t
) pa_format_info_free
);
214 bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
218 if (data
->req_formats
)
219 pa_idxset_free(formats
, (pa_free_cb_t
) pa_format_info_free
);
221 data
->req_formats
= formats
;
224 /* Trigger format negotiation */
225 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
231 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
234 if (data
->req_formats
)
235 pa_idxset_free(data
->req_formats
, (pa_free_cb_t
) pa_format_info_free
);
237 if (data
->nego_formats
)
238 pa_idxset_free(data
->nego_formats
, (pa_free_cb_t
) pa_format_info_free
);
241 pa_format_info_free(data
->format
);
243 if (data
->volume_factor_items
)
244 pa_hashmap_free(data
->volume_factor_items
, (pa_free_cb_t
) volume_factor_entry_free
);
246 if (data
->volume_factor_sink_items
)
247 pa_hashmap_free(data
->volume_factor_sink_items
, (pa_free_cb_t
) volume_factor_entry_free
);
249 pa_proplist_free(data
->proplist
);
252 /* Called from main context */
253 static void reset_callbacks(pa_sink_input
*i
) {
257 i
->process_underrun
= NULL
;
258 i
->process_rewind
= NULL
;
259 i
->update_max_rewind
= NULL
;
260 i
->update_max_request
= NULL
;
261 i
->update_sink_requested_latency
= NULL
;
262 i
->update_sink_latency_range
= NULL
;
263 i
->update_sink_fixed_latency
= NULL
;
267 i
->suspend_within_thread
= NULL
;
270 i
->get_latency
= NULL
;
271 i
->state_change
= NULL
;
272 i
->may_move_to
= NULL
;
273 i
->send_event
= NULL
;
274 i
->volume_changed
= NULL
;
275 i
->mute_changed
= NULL
;
278 /* Called from main context */
279 int pa_sink_input_new(
282 pa_sink_input_new_data
*data
) {
285 pa_resampler
*resampler
= NULL
;
286 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
], fmt
[PA_FORMAT_INFO_SNPRINT_MAX
];
287 pa_channel_map original_cm
;
290 char *memblockq_name
;
297 pa_assert_ctl_context();
300 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
302 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
303 data
->volume_writable
= false;
305 if (!data
->req_formats
) {
306 /* From this point on, we want to work only with formats, and get back
307 * to using the sample spec and channel map after all decisions w.r.t.
308 * routing are complete. */
309 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
310 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
,
311 data
->channel_map_is_set
? &data
->channel_map
: NULL
);
312 pa_idxset_put(tmp
, f
, NULL
);
313 pa_sink_input_new_data_set_formats(data
, tmp
);
316 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
319 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
322 pa_sink
*sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
323 pa_return_val_if_fail(sink
, -PA_ERR_NOENTITY
);
324 pa_sink_input_new_data_set_sink(data
, sink
, false);
326 /* Routing's done, we have a sink. Now let's fix the format and set up the
329 /* If something didn't pick a format for us, pick the top-most format since
330 * we assume this is sorted in priority order */
331 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
332 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
334 if (PA_LIKELY(data
->format
)) {
335 pa_log_debug("Negotiated format: %s", pa_format_info_snprint(fmt
, sizeof(fmt
), data
->format
));
337 pa_format_info
*format
;
340 pa_log_info("Sink does not support any requested format:");
341 PA_IDXSET_FOREACH(format
, data
->req_formats
, idx
)
342 pa_log_info(" -- %s", pa_format_info_snprint(fmt
, sizeof(fmt
), format
));
344 return -PA_ERR_NOTSUPPORTED
;
347 /* Now populate the sample spec and format according to the final
348 * format that we've negotiated */
349 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
) == 0, -PA_ERR_INVALID
);
350 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
351 if (pa_format_info_is_pcm(data
->format
) && pa_channel_map_valid(&map
))
352 pa_sink_input_new_data_set_channel_map(data
, &map
);
354 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
355 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
);
357 r
= check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data
), data
->sink
);
361 if (!data
->sample_spec_is_set
)
362 data
->sample_spec
= data
->sink
->sample_spec
;
364 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
366 if (!data
->channel_map_is_set
) {
367 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
368 data
->channel_map
= data
->sink
->channel_map
;
370 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
373 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
375 /* Don't restore (or save) stream volume for passthrough streams and
376 * prevent attenuation/gain */
377 if (pa_sink_input_new_data_is_passthrough(data
)) {
378 data
->volume_is_set
= true;
379 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
380 data
->volume_is_absolute
= true;
381 data
->save_volume
= false;
384 if (!data
->volume_is_set
) {
385 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
386 data
->volume_is_absolute
= false;
387 data
->save_volume
= false;
390 if (!data
->volume_writable
)
391 data
->save_volume
= false;
393 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
395 if (!data
->muted_is_set
)
398 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
) {
399 pa_return_val_if_fail(pa_format_info_is_pcm(data
->format
), -PA_ERR_INVALID
);
400 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
401 pa_format_info_set_sample_format(data
->format
, data
->sample_spec
.format
);
404 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
) {
405 pa_return_val_if_fail(pa_format_info_is_pcm(data
->format
), -PA_ERR_INVALID
);
406 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
407 pa_format_info_set_rate(data
->format
, data
->sample_spec
.rate
);
410 original_cm
= data
->channel_map
;
412 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
413 pa_return_val_if_fail(pa_format_info_is_pcm(data
->format
), -PA_ERR_INVALID
);
414 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
415 data
->channel_map
= data
->sink
->channel_map
;
416 pa_format_info_set_channels(data
->format
, data
->sample_spec
.channels
);
417 pa_format_info_set_channel_map(data
->format
, &data
->channel_map
);
420 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
421 pa_assert(pa_channel_map_valid(&data
->channel_map
));
423 if (!(data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
424 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
)) {
425 /* try to change sink rate. This is done before the FIXATE hook since
426 module-suspend-on-idle can resume a sink */
428 pa_log_info("Trying to change sample rate");
429 if (pa_sink_update_rate(data
->sink
, data
->sample_spec
.rate
, pa_sink_input_new_data_is_passthrough(data
)) == true)
430 pa_log_info("Rate changed to %u Hz", data
->sink
->sample_spec
.rate
);
433 if (pa_sink_input_new_data_is_passthrough(data
) &&
434 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
)) {
435 /* rate update failed, or other parts of sample spec didn't match */
437 pa_log_debug("Could not update sink sample spec to match passthrough stream");
438 return -PA_ERR_NOTSUPPORTED
;
441 /* Due to the fixing of the sample spec the volume might not match anymore */
442 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
444 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
445 data
->resample_method
= core
->resample_method
;
447 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
449 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
452 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
453 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
454 pa_log_warn("Failed to create sink input: sink is suspended.");
455 return -PA_ERR_BADSTATE
;
458 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
459 pa_log_warn("Failed to create sink input: too many inputs per sink.");
460 return -PA_ERR_TOOLARGE
;
463 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
464 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
465 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
467 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
468 if (!pa_sink_input_new_data_is_passthrough(data
)) /* no resampler for passthrough content */
469 if (!(resampler
= pa_resampler_new(
471 &data
->sample_spec
, &data
->channel_map
,
472 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
473 data
->resample_method
,
474 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
475 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
476 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
477 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
478 pa_log_warn("Unsupported resampling operation.");
479 return -PA_ERR_NOTSUPPORTED
;
483 i
= pa_msgobject_new(pa_sink_input
);
484 i
->parent
.parent
.free
= sink_input_free
;
485 i
->parent
.process_msg
= pa_sink_input_process_msg
;
488 i
->state
= PA_SINK_INPUT_INIT
;
489 i
->flags
= data
->flags
;
490 i
->proplist
= pa_proplist_copy(data
->proplist
);
491 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
492 i
->module
= data
->module
;
493 i
->sink
= data
->sink
;
494 i
->origin_sink
= data
->origin_sink
;
495 i
->client
= data
->client
;
497 i
->requested_resample_method
= data
->resample_method
;
498 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
499 i
->sample_spec
= data
->sample_spec
;
500 i
->channel_map
= data
->channel_map
;
501 i
->format
= pa_format_info_copy(data
->format
);
503 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
506 /* When the 'absolute' bool is not set then we'll treat the volume
507 * as relative to the sink volume even in flat volume mode */
508 remapped
= data
->sink
->reference_volume
;
509 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
510 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
512 i
->volume
= data
->volume
;
514 i
->volume_factor_items
= data
->volume_factor_items
;
515 data
->volume_factor_items
= NULL
;
516 volume_factor_from_hashmap(&i
->volume_factor
, i
->volume_factor_items
, i
->sample_spec
.channels
);
518 i
->volume_factor_sink_items
= data
->volume_factor_sink_items
;
519 data
->volume_factor_sink_items
= NULL
;
520 volume_factor_from_hashmap(&i
->volume_factor_sink
, i
->volume_factor_sink_items
, i
->sample_spec
.channels
);
522 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
523 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
524 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
525 i
->volume_writable
= data
->volume_writable
;
526 i
->save_volume
= data
->save_volume
;
527 i
->save_sink
= data
->save_sink
;
528 i
->save_muted
= data
->save_muted
;
530 i
->muted
= data
->muted
;
532 if (data
->sync_base
) {
533 i
->sync_next
= data
->sync_base
->sync_next
;
534 i
->sync_prev
= data
->sync_base
;
536 if (data
->sync_base
->sync_next
)
537 data
->sync_base
->sync_next
->sync_prev
= i
;
538 data
->sync_base
->sync_next
= i
;
540 i
->sync_next
= i
->sync_prev
= NULL
;
542 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
547 i
->thread_info
.state
= i
->state
;
548 i
->thread_info
.attached
= false;
549 pa_atomic_store(&i
->thread_info
.drained
, 1);
550 i
->thread_info
.sample_spec
= i
->sample_spec
;
551 i
->thread_info
.resampler
= resampler
;
552 i
->thread_info
.soft_volume
= i
->soft_volume
;
553 i
->thread_info
.muted
= i
->muted
;
554 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
555 i
->thread_info
.rewrite_nbytes
= 0;
556 i
->thread_info
.rewrite_flush
= false;
557 i
->thread_info
.dont_rewind_render
= false;
558 i
->thread_info
.underrun_for
= (uint64_t) -1;
559 i
->thread_info
.underrun_for_sink
= 0;
560 i
->thread_info
.playing_for
= 0;
561 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
563 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
564 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
567 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
569 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
570 i
->thread_info
.render_memblockq
= pa_memblockq_new(
575 &i
->sink
->sample_spec
,
580 pa_xfree(memblockq_name
);
582 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
583 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
585 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
587 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
588 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
592 /* Don't forget to call pa_sink_input_put! */
598 /* Called from main context */
599 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
601 pa_assert_ctl_context();
606 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
607 pa_assert_se(i
->sink
->n_corked
-- >= 1);
608 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
612 /* Called from main context */
613 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
614 pa_sink_input
*ssync
;
616 pa_assert_ctl_context();
618 if (state
== PA_SINK_INPUT_DRAINED
)
619 state
= PA_SINK_INPUT_RUNNING
;
621 if (i
->state
== state
)
624 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
&& pa_sink_used_by(i
->sink
) == 0 &&
625 !pa_sample_spec_equal(&i
->sample_spec
, &i
->sink
->sample_spec
)) {
626 /* We were uncorked and the sink was not playing anything -- let's try
627 * to update the sample rate to avoid resampling */
628 pa_sink_update_rate(i
->sink
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
));
631 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);
633 update_n_corked(i
, state
);
636 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
637 update_n_corked(ssync
, state
);
638 ssync
->state
= state
;
640 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
641 update_n_corked(ssync
, state
);
642 ssync
->state
= state
;
645 if (state
!= PA_SINK_INPUT_UNLINKED
) {
646 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
648 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
649 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
651 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
652 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
654 if (PA_SINK_INPUT_IS_LINKED(state
))
655 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
658 pa_sink_update_status(i
->sink
);
661 /* Called from main context */
662 void pa_sink_input_unlink(pa_sink_input
*i
) {
664 pa_source_output
*o
, *p
= NULL
;
667 pa_assert_ctl_context();
669 /* See pa_sink_unlink() for a couple of comments how this function
672 pa_sink_input_ref(i
);
674 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
677 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
680 i
->sync_prev
->sync_next
= i
->sync_next
;
682 i
->sync_next
->sync_prev
= i
->sync_prev
;
684 i
->sync_prev
= i
->sync_next
= NULL
;
686 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
689 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
690 pa_sink_input_unref(i
);
693 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
695 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
697 pa_source_output_kill(o
);
701 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
702 i
->state
= PA_SINK_INPUT_UNLINKED
;
704 if (linked
&& i
->sink
) {
705 if (pa_sink_input_is_passthrough(i
))
706 pa_sink_leave_passthrough(i
->sink
);
708 /* We might need to update the sink's volume if we are in flat volume mode. */
709 if (pa_sink_flat_volume_enabled(i
->sink
))
710 pa_sink_set_volume(i
->sink
, NULL
, false, false);
712 if (i
->sink
->asyncmsgq
)
713 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
719 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
720 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
724 if (PA_SINK_IS_LINKED(pa_sink_get_state(i
->sink
)))
725 pa_sink_update_status(i
->sink
);
730 pa_core_maybe_vacuum(i
->core
);
732 pa_sink_input_unref(i
);
735 /* Called from main context */
736 static void sink_input_free(pa_object
*o
) {
737 pa_sink_input
* i
= PA_SINK_INPUT(o
);
740 pa_assert_ctl_context();
741 pa_assert(pa_sink_input_refcnt(i
) == 0);
743 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
744 pa_sink_input_unlink(i
);
746 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
748 /* Side note: this function must be able to destruct properly any
749 * kind of sink input in any state, even those which are
750 * "half-moved" or are connected to sinks that have no asyncmsgq
751 * and are hence half-destructed themselves! */
753 if (i
->thread_info
.render_memblockq
)
754 pa_memblockq_free(i
->thread_info
.render_memblockq
);
756 if (i
->thread_info
.resampler
)
757 pa_resampler_free(i
->thread_info
.resampler
);
760 pa_format_info_free(i
->format
);
763 pa_proplist_free(i
->proplist
);
765 if (i
->direct_outputs
)
766 pa_idxset_free(i
->direct_outputs
, NULL
);
768 if (i
->thread_info
.direct_outputs
)
769 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
);
771 if (i
->volume_factor_items
)
772 pa_hashmap_free(i
->volume_factor_items
, (pa_free_cb_t
) volume_factor_entry_free
);
774 if (i
->volume_factor_sink_items
)
775 pa_hashmap_free(i
->volume_factor_sink_items
, (pa_free_cb_t
) volume_factor_entry_free
);
781 /* Called from main context */
782 void pa_sink_input_put(pa_sink_input
*i
) {
783 pa_sink_input_state_t state
;
785 pa_sink_input_assert_ref(i
);
786 pa_assert_ctl_context();
788 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
790 /* The following fields must be initialized properly */
792 pa_assert(i
->process_rewind
);
795 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
797 update_n_corked(i
, state
);
800 /* We might need to update the sink's volume if we are in flat volume mode. */
801 if (pa_sink_flat_volume_enabled(i
->sink
))
802 pa_sink_set_volume(i
->sink
, NULL
, false, i
->save_volume
);
804 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
805 pa_assert(pa_cvolume_is_norm(&i
->volume
));
806 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
809 set_real_ratio(i
, &i
->volume
);
812 if (pa_sink_input_is_passthrough(i
))
813 pa_sink_enter_passthrough(i
->sink
);
815 i
->thread_info
.soft_volume
= i
->soft_volume
;
816 i
->thread_info
.muted
= i
->muted
;
818 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
820 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
821 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
823 pa_sink_update_status(i
->sink
);
826 /* Called from main context */
827 void pa_sink_input_kill(pa_sink_input
*i
) {
828 pa_sink_input_assert_ref(i
);
829 pa_assert_ctl_context();
830 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
835 /* Called from main context */
836 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
837 pa_usec_t r
[2] = { 0, 0 };
839 pa_sink_input_assert_ref(i
);
840 pa_assert_ctl_context();
841 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
843 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
846 r
[0] += i
->get_latency(i
);
849 *sink_latency
= r
[1];
854 /* Called from thread context */
855 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink bytes */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
856 bool do_volume_adj_here
, need_volume_factor_sink
;
858 size_t block_size_max_sink
, block_size_max_sink_input
;
862 pa_sink_input_assert_ref(i
);
863 pa_sink_input_assert_io_context(i
);
864 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
865 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
869 #ifdef SINK_INPUT_DEBUG
870 pa_log_debug("peek");
873 block_size_max_sink_input
= i
->thread_info
.resampler
?
874 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
875 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
877 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
879 /* Default buffer size */
881 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
883 if (slength
> block_size_max_sink
)
884 slength
= block_size_max_sink
;
886 if (i
->thread_info
.resampler
) {
887 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
890 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
894 /* Length corresponding to slength (without limiting to
895 * block_size_max_sink_input). */
896 ilength_full
= ilength
;
898 if (ilength
> block_size_max_sink_input
)
899 ilength
= block_size_max_sink_input
;
901 /* If the channel maps of the sink and this stream differ, we need
902 * to adjust the volume *before* we resample. Otherwise we can do
903 * it after and leave it for the sink code */
905 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
906 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
907 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
909 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
912 /* There's nothing in our render queue. We need to fill it up
913 * with data from the implementor. */
915 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
916 i
->pop(i
, ilength
, &tchunk
) < 0) {
918 /* OK, we're corked or the implementor didn't give us any
919 * data, so let's just hand out silence */
920 pa_atomic_store(&i
->thread_info
.drained
, 1);
922 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, true);
923 i
->thread_info
.playing_for
= 0;
924 if (i
->thread_info
.underrun_for
!= (uint64_t) -1) {
925 i
->thread_info
.underrun_for
+= ilength_full
;
926 i
->thread_info
.underrun_for_sink
+= slength
;
931 pa_atomic_store(&i
->thread_info
.drained
, 0);
933 pa_assert(tchunk
.length
> 0);
934 pa_assert(tchunk
.memblock
);
936 i
->thread_info
.underrun_for
= 0;
937 i
->thread_info
.underrun_for_sink
= 0;
938 i
->thread_info
.playing_for
+= tchunk
.length
;
940 while (tchunk
.length
> 0) {
942 bool nvfs
= need_volume_factor_sink
;
945 pa_memblock_ref(wchunk
.memblock
);
947 if (wchunk
.length
> block_size_max_sink_input
)
948 wchunk
.length
= block_size_max_sink_input
;
950 /* It might be necessary to adjust the volume here */
951 if (do_volume_adj_here
&& !volume_is_norm
) {
952 pa_memchunk_make_writable(&wchunk
, 0);
954 if (i
->thread_info
.muted
) {
955 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
958 } else if (!i
->thread_info
.resampler
&& nvfs
) {
961 /* If we don't need a resampler we can merge the
962 * post and the pre volume adjustment into one */
964 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
965 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
969 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
972 if (!i
->thread_info
.resampler
) {
975 pa_memchunk_make_writable(&wchunk
, 0);
976 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
979 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
982 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
984 #ifdef SINK_INPUT_DEBUG
985 pa_log_debug("pushing %lu", (unsigned long) rchunk
.length
);
988 if (rchunk
.memblock
) {
991 pa_memchunk_make_writable(&rchunk
, 0);
992 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
995 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
996 pa_memblock_unref(rchunk
.memblock
);
1000 pa_memblock_unref(wchunk
.memblock
);
1002 tchunk
.index
+= wchunk
.length
;
1003 tchunk
.length
-= wchunk
.length
;
1006 pa_memblock_unref(tchunk
.memblock
);
1009 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
1011 pa_assert(chunk
->length
> 0);
1012 pa_assert(chunk
->memblock
);
1014 #ifdef SINK_INPUT_DEBUG
1015 pa_log_debug("peeking %lu", (unsigned long) chunk
->length
);
1018 if (chunk
->length
> block_size_max_sink
)
1019 chunk
->length
= block_size_max_sink
;
1021 /* Let's see if we had to apply the volume adjustment ourselves,
1022 * or if this can be done by the sink for us */
1024 if (do_volume_adj_here
)
1025 /* We had different channel maps, so we already did the adjustment */
1026 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
1027 else if (i
->thread_info
.muted
)
1028 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
1029 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
1031 *volume
= i
->thread_info
.soft_volume
;
1034 /* Called from thread context */
1035 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
1037 pa_sink_input_assert_ref(i
);
1038 pa_sink_input_assert_io_context(i
);
1039 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1040 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1041 pa_assert(nbytes
> 0);
1043 #ifdef SINK_INPUT_DEBUG
1044 pa_log_debug("dropping %lu", (unsigned long) nbytes
);
1047 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
1050 /* Called from thread context */
1051 bool pa_sink_input_process_underrun(pa_sink_input
*i
) {
1052 pa_sink_input_assert_ref(i
);
1053 pa_sink_input_assert_io_context(i
);
1055 if (pa_memblockq_is_readable(i
->thread_info
.render_memblockq
))
1058 if (i
->process_underrun
&& i
->process_underrun(i
)) {
1059 /* All valid data has been played back, so we can empty this queue. */
1060 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
1066 /* Called from thread context */
1067 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
1069 bool called
= false;
1071 pa_sink_input_assert_ref(i
);
1072 pa_sink_input_assert_io_context(i
);
1073 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1074 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1076 #ifdef SINK_INPUT_DEBUG
1077 pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes
, (unsigned long) i
->thread_info
.rewrite_nbytes
);
1080 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1082 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
1083 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
1084 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
1087 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
1089 /* We were asked to drop all buffered data, and rerequest new
1090 * data from implementor the next time peek() is called */
1092 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, true);
1094 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
1095 size_t max_rewrite
, amount
;
1097 /* Calculate how much make sense to rewrite at most */
1098 max_rewrite
= nbytes
+ lbq
;
1100 /* Transform into local domain */
1101 if (i
->thread_info
.resampler
)
1102 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
1104 /* Calculate how much of the rewinded data should actually be rewritten */
1105 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
1108 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
1110 /* Tell the implementor */
1111 if (i
->process_rewind
)
1112 i
->process_rewind(i
, amount
);
1115 /* Convert back to to sink domain */
1116 if (i
->thread_info
.resampler
)
1117 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
1120 /* Ok, now update the write pointer */
1121 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, true);
1123 if (i
->thread_info
.rewrite_flush
)
1124 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
1126 /* And reset the resampler */
1127 if (i
->thread_info
.resampler
)
1128 pa_resampler_reset(i
->thread_info
.resampler
);
1133 if (i
->process_rewind
)
1134 i
->process_rewind(i
, 0);
1136 i
->thread_info
.rewrite_nbytes
= 0;
1137 i
->thread_info
.rewrite_flush
= false;
1138 i
->thread_info
.dont_rewind_render
= false;
1141 /* Called from thread context */
1142 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
1143 pa_sink_input_assert_ref(i
);
1144 pa_sink_input_assert_io_context(i
);
1146 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1149 /* Called from thread context */
1150 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1151 pa_sink_input_assert_ref(i
);
1152 pa_sink_input_assert_io_context(i
);
1154 /* We're not verifying the status here, to allow this to be called
1155 * in the state change handler between _INIT and _RUNNING */
1157 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1160 /* Called from thread context */
1161 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1162 pa_sink_input_assert_ref(i
);
1163 pa_sink_input_assert_io_context(i
);
1164 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1165 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1167 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1169 if (i
->update_max_rewind
)
1170 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1173 /* Called from thread context */
1174 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1175 pa_sink_input_assert_ref(i
);
1176 pa_sink_input_assert_io_context(i
);
1177 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1178 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1180 if (i
->update_max_request
)
1181 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1184 /* Called from thread context */
1185 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1186 pa_sink_input_assert_ref(i
);
1187 pa_sink_input_assert_io_context(i
);
1189 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1190 usec
= i
->sink
->thread_info
.fixed_latency
;
1192 if (usec
!= (pa_usec_t
) -1)
1193 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1195 i
->thread_info
.requested_sink_latency
= usec
;
1196 pa_sink_invalidate_requested_latency(i
->sink
, true);
1201 /* Called from main context */
1202 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1203 pa_sink_input_assert_ref(i
);
1204 pa_assert_ctl_context();
1206 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1207 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1211 /* If this sink input is not realized yet or we are being moved,
1212 * we have to touch the thread info data directly */
1215 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1216 usec
= pa_sink_get_fixed_latency(i
->sink
);
1218 if (usec
!= (pa_usec_t
) -1) {
1219 pa_usec_t min_latency
, max_latency
;
1220 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1221 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1225 i
->thread_info
.requested_sink_latency
= usec
;
1230 /* Called from main context */
1231 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1232 pa_sink_input_assert_ref(i
);
1233 pa_assert_ctl_context();
1235 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1237 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1241 /* If this sink input is not realized yet or we are being moved,
1242 * we have to touch the thread info data directly */
1244 return i
->thread_info
.requested_sink_latency
;
1247 /* Called from main context */
1248 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, bool save
, bool absolute
) {
1251 pa_sink_input_assert_ref(i
);
1252 pa_assert_ctl_context();
1253 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1255 pa_assert(pa_cvolume_valid(volume
));
1256 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1257 pa_assert(i
->volume_writable
);
1259 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1260 v
= i
->sink
->reference_volume
;
1261 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1263 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1264 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1266 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1268 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1270 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1274 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1275 i
->save_volume
= i
->save_volume
|| save
;
1279 i
->volume
= *volume
;
1280 i
->save_volume
= save
;
1282 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1283 /* We are in flat volume mode, so let's update all sink input
1284 * volumes and update the flat volume of the sink */
1286 pa_sink_set_volume(i
->sink
, NULL
, true, save
);
1289 /* OK, we are in normal volume mode. The volume only affects
1291 set_real_ratio(i
, volume
);
1293 /* Copy the new soft_volume to the thread_info struct */
1294 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1297 /* The volume changed, let's tell people so */
1298 if (i
->volume_changed
)
1299 i
->volume_changed(i
);
1301 /* The virtual volume changed, let's tell people so */
1302 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1305 void pa_sink_input_add_volume_factor(pa_sink_input
*i
, const char *key
, const pa_cvolume
*volume_factor
) {
1306 struct volume_factor_entry
*v
;
1308 pa_sink_input_assert_ref(i
);
1309 pa_assert_ctl_context();
1310 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1311 pa_assert(volume_factor
);
1313 pa_assert(pa_cvolume_valid(volume_factor
));
1314 pa_assert(volume_factor
->channels
== 1 || pa_cvolume_compatible(volume_factor
, &i
->sample_spec
));
1316 v
= volume_factor_entry_new(key
, volume_factor
);
1317 if (!pa_cvolume_compatible(volume_factor
, &i
->sample_spec
))
1318 pa_cvolume_set(&v
->volume
, i
->sample_spec
.channels
, volume_factor
->values
[0]);
1320 pa_assert_se(pa_hashmap_put(i
->volume_factor_items
, v
->key
, v
) >= 0);
1321 if (pa_hashmap_size(i
->volume_factor_items
) == 1)
1322 i
->volume_factor
= v
->volume
;
1324 pa_sw_cvolume_multiply(&i
->volume_factor
, &i
->volume_factor
, &v
->volume
);
1326 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1328 /* Copy the new soft_volume to the thread_info struct */
1329 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1332 void pa_sink_input_remove_volume_factor(pa_sink_input
*i
, const char *key
) {
1333 struct volume_factor_entry
*v
;
1335 pa_sink_input_assert_ref(i
);
1337 pa_assert_ctl_context();
1338 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1340 pa_assert_se(v
= pa_hashmap_remove(i
->volume_factor_items
, key
));
1341 volume_factor_entry_free(v
);
1343 switch (pa_hashmap_size(i
->volume_factor_items
)) {
1345 pa_cvolume_reset(&i
->volume_factor
, i
->sample_spec
.channels
);
1348 v
= pa_hashmap_first(i
->volume_factor_items
);
1349 i
->volume_factor
= v
->volume
;
1352 volume_factor_from_hashmap(&i
->volume_factor
, i
->volume_factor_items
, i
->volume_factor
.channels
);
1355 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1357 /* Copy the new soft_volume to the thread_info struct */
1358 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1361 /* Called from main context */
1362 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1363 pa_sink_input_assert_ref(i
);
1364 pa_assert_ctl_context();
1365 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1366 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1368 /* This basically calculates:
1370 * i->real_ratio := v
1371 * i->soft_volume := i->real_ratio * i->volume_factor */
1376 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1378 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1379 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1382 /* Called from main or I/O context */
1383 bool pa_sink_input_is_passthrough(pa_sink_input
*i
) {
1384 pa_sink_input_assert_ref(i
);
1386 if (PA_UNLIKELY(!pa_format_info_is_pcm(i
->format
)))
1389 if (PA_UNLIKELY(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
1395 /* Called from main context */
1396 bool pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1397 pa_sink_input_assert_ref(i
);
1398 pa_assert_ctl_context();
1400 return !pa_sink_input_is_passthrough(i
);
1403 /* Called from main context */
1404 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, bool absolute
) {
1405 pa_sink_input_assert_ref(i
);
1406 pa_assert_ctl_context();
1407 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1408 pa_assert(pa_sink_input_is_volume_readable(i
));
1410 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1411 *volume
= i
->volume
;
1413 *volume
= i
->reference_ratio
;
1418 /* Called from main context */
1419 void pa_sink_input_set_mute(pa_sink_input
*i
, bool mute
, bool save
) {
1420 pa_sink_input_assert_ref(i
);
1421 pa_assert_ctl_context();
1422 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1424 if (!i
->muted
== !mute
) {
1425 i
->save_muted
= i
->save_muted
|| mute
;
1430 i
->save_muted
= save
;
1432 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1434 /* The mute status changed, let's tell people so */
1435 if (i
->mute_changed
)
1438 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1441 /* Called from main context */
1442 bool pa_sink_input_get_mute(pa_sink_input
*i
) {
1443 pa_sink_input_assert_ref(i
);
1444 pa_assert_ctl_context();
1445 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1450 /* Called from main thread */
1451 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1452 pa_sink_input_assert_ref(i
);
1453 pa_assert_ctl_context();
1456 pa_proplist_update(i
->proplist
, mode
, p
);
1458 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1459 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1460 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1464 /* Called from main context */
1465 void pa_sink_input_cork(pa_sink_input
*i
, bool b
) {
1466 pa_sink_input_assert_ref(i
);
1467 pa_assert_ctl_context();
1468 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1470 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1473 /* Called from main context */
1474 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1475 pa_sink_input_assert_ref(i
);
1476 pa_assert_ctl_context();
1477 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1478 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1480 if (i
->sample_spec
.rate
== rate
)
1483 i
->sample_spec
.rate
= rate
;
1485 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1487 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1491 /* Called from main context */
1492 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1494 pa_sink_input_assert_ref(i
);
1495 pa_assert_ctl_context();
1497 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1500 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1502 if (old
&& name
&& pa_streq(old
, name
))
1506 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1508 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1510 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1511 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1512 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1516 /* Called from main context */
1517 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1518 pa_sink_input_assert_ref(i
);
1519 pa_assert_ctl_context();
1521 return i
->actual_resample_method
;
1524 /* Called from main context */
1525 bool pa_sink_input_may_move(pa_sink_input
*i
) {
1526 pa_sink_input_assert_ref(i
);
1527 pa_assert_ctl_context();
1528 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1530 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1533 if (i
->sync_next
|| i
->sync_prev
) {
1534 pa_log_warn("Moving synchronized streams not supported.");
1541 static bool find_filter_sink_input(pa_sink_input
*target
, pa_sink
*s
) {
1543 while (s
&& s
->input_to_master
) {
1544 if (s
->input_to_master
== target
)
1546 s
= s
->input_to_master
->sink
;
1547 pa_assert(i
++ < 100);
1552 /* Called from main context */
1553 bool pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1554 pa_sink_input_assert_ref(i
);
1555 pa_assert_ctl_context();
1556 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1557 pa_sink_assert_ref(dest
);
1559 if (dest
== i
->sink
)
1562 if (!pa_sink_input_may_move(i
))
1565 /* Make sure we're not creating a filter sink cycle */
1566 if (find_filter_sink_input(i
, dest
)) {
1567 pa_log_debug("Can't connect input to %s, as that would create a cycle.", dest
->name
);
1571 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1572 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1576 if (check_passthrough_connection(pa_sink_input_is_passthrough(i
), dest
) < 0)
1580 if (!i
->may_move_to(i
, dest
))
1586 /* Called from main context */
1587 int pa_sink_input_start_move(pa_sink_input
*i
) {
1588 pa_source_output
*o
, *p
= NULL
;
1589 struct volume_factor_entry
*v
;
1593 pa_sink_input_assert_ref(i
);
1594 pa_assert_ctl_context();
1595 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1598 if (!pa_sink_input_may_move(i
))
1599 return -PA_ERR_NOTSUPPORTED
;
1601 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1604 /* Kill directly connected outputs */
1605 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1607 pa_source_output_kill(o
);
1610 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1612 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1614 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1615 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1617 if (pa_sink_input_is_passthrough(i
))
1618 pa_sink_leave_passthrough(i
->sink
);
1620 if (pa_sink_flat_volume_enabled(i
->sink
))
1621 /* We might need to update the sink's volume if we are in flat
1623 pa_sink_set_volume(i
->sink
, NULL
, false, false);
1625 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1627 pa_sink_update_status(i
->sink
);
1629 PA_HASHMAP_FOREACH(v
, i
->volume_factor_sink_items
, state
)
1630 pa_cvolume_remap(&v
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1632 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1636 pa_sink_input_unref(i
);
1641 /* Called from main context. If i has an origin sink that uses volume sharing,
1642 * then also the origin sink and all streams connected to it need to update
1643 * their volume - this function does all that by using recursion. */
1644 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1645 pa_cvolume old_volume
;
1649 pa_assert(i
->sink
); /* The destination sink should already be set. */
1651 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1652 pa_sink
*root_sink
= pa_sink_get_master(i
->sink
);
1653 pa_sink_input
*origin_sink_input
;
1656 if (PA_UNLIKELY(!root_sink
))
1659 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1660 /* Ok, so the origin sink uses volume sharing, and flat volume is
1661 * enabled. The volume will have to be updated as follows:
1663 * i->volume := i->sink->real_volume
1664 * (handled later by pa_sink_set_volume)
1665 * i->reference_ratio := i->volume / i->sink->reference_volume
1666 * (handled later by pa_sink_set_volume)
1667 * i->real_ratio stays unchanged
1668 * (streams whose origin sink uses volume sharing should
1669 * always have real_ratio of 0 dB)
1670 * i->soft_volume stays unchanged
1671 * (streams whose origin sink uses volume sharing should
1672 * always have volume_factor as soft_volume, so no change
1673 * should be needed) */
1675 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1676 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1678 /* Notifications will be sent by pa_sink_set_volume(). */
1681 /* Ok, so the origin sink uses volume sharing, and flat volume is
1682 * disabled. The volume will have to be updated as follows:
1685 * i->reference_ratio := 0 dB
1686 * i->real_ratio stays unchanged
1687 * (streams whose origin sink uses volume sharing should
1688 * always have real_ratio of 0 dB)
1689 * i->soft_volume stays unchanged
1690 * (streams whose origin sink uses volume sharing should
1691 * always have volume_factor as soft_volume, so no change
1692 * should be needed) */
1694 old_volume
= i
->volume
;
1695 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1696 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1697 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1698 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1700 /* Notify others about the changed sink input volume. */
1701 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1702 if (i
->volume_changed
)
1703 i
->volume_changed(i
);
1705 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1709 /* Additionally, the origin sink volume needs updating:
1711 * i->origin_sink->reference_volume := root_sink->reference_volume
1712 * i->origin_sink->real_volume := root_sink->real_volume
1713 * i->origin_sink->soft_volume stays unchanged
1714 * (sinks that use volume sharing should always have
1715 * soft_volume of 0 dB) */
1717 old_volume
= i
->origin_sink
->reference_volume
;
1719 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1720 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1722 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1723 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1725 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1727 /* Notify others about the changed sink volume. If you wonder whether
1728 * i->origin_sink->set_volume() should be called somewhere, that's not
1729 * the case, because sinks that use volume sharing shouldn't have any
1730 * internal volume that set_volume() would update. If you wonder
1731 * whether the thread_info variables should be synced, yes, they
1732 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1734 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1735 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1737 /* Recursively update origin sink inputs. */
1738 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1739 update_volume_due_to_moving(origin_sink_input
, dest
);
1742 old_volume
= i
->volume
;
1744 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1745 /* Ok, so this is a regular stream, and flat volume is enabled. The
1746 * volume will have to be updated as follows:
1748 * i->volume := i->reference_ratio * i->sink->reference_volume
1749 * i->reference_ratio stays unchanged
1750 * i->real_ratio := i->volume / i->sink->real_volume
1751 * (handled later by pa_sink_set_volume)
1752 * i->soft_volume := i->real_ratio * i->volume_factor
1753 * (handled later by pa_sink_set_volume) */
1755 i
->volume
= i
->sink
->reference_volume
;
1756 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1757 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1760 /* Ok, so this is a regular stream, and flat volume is disabled.
1761 * The volume will have to be updated as follows:
1763 * i->volume := i->reference_ratio
1764 * i->reference_ratio stays unchanged
1765 * i->real_ratio := i->reference_ratio
1766 * i->soft_volume := i->real_ratio * i->volume_factor */
1768 i
->volume
= i
->reference_ratio
;
1769 i
->real_ratio
= i
->reference_ratio
;
1770 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1773 /* Notify others about the changed sink input volume. */
1774 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1775 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1776 * and soft_volume are not updated yet. Let's hope that the
1777 * callback implementation doesn't care about those variables... */
1778 if (i
->volume_changed
)
1779 i
->volume_changed(i
);
1781 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1785 /* If i->sink == dest, then recursion has finished, and we can finally call
1786 * pa_sink_set_volume(), which will do the rest of the updates. */
1787 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1788 pa_sink_set_volume(i
->sink
, NULL
, false, i
->save_volume
);
1791 /* Called from main context */
1792 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, bool save
) {
1793 struct volume_factor_entry
*v
;
1796 pa_sink_input_assert_ref(i
);
1797 pa_assert_ctl_context();
1798 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1799 pa_assert(!i
->sink
);
1800 pa_sink_assert_ref(dest
);
1802 if (!pa_sink_input_may_move_to(i
, dest
))
1803 return -PA_ERR_NOTSUPPORTED
;
1805 if (pa_sink_input_is_passthrough(i
) && !pa_sink_check_format(dest
, i
->format
)) {
1806 pa_proplist
*p
= pa_proplist_new();
1807 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1808 /* Tell the client what device we want to be on if it is going to
1810 pa_proplist_sets(p
, "device", dest
->name
);
1811 pa_sink_input_send_event(i
, PA_STREAM_EVENT_FORMAT_LOST
, p
);
1812 pa_proplist_free(p
);
1813 return -PA_ERR_NOTSUPPORTED
;
1816 if (!(i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
1817 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
)) {
1818 /* try to change dest sink rate if possible without glitches.
1819 module-suspend-on-idle resumes destination sink with
1820 SINK_INPUT_MOVE_FINISH hook */
1822 pa_log_info("Trying to change sample rate");
1823 if (pa_sink_update_rate(dest
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
)) == true)
1824 pa_log_info("Rate changed to %u Hz", dest
->sample_spec
.rate
);
1831 i
->save_sink
= save
;
1832 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1834 PA_HASHMAP_FOREACH(v
, i
->volume_factor_sink_items
, state
)
1835 pa_cvolume_remap(&v
->volume
, &i
->channel_map
, &i
->sink
->channel_map
);
1837 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1839 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1840 i
->sink
->n_corked
++;
1842 pa_sink_input_update_rate(i
);
1844 pa_sink_update_status(dest
);
1846 update_volume_due_to_moving(i
, dest
);
1848 if (pa_sink_input_is_passthrough(i
))
1849 pa_sink_enter_passthrough(i
->sink
);
1851 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1853 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1855 /* Notify everyone */
1856 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1857 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1862 /* Called from main context */
1863 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1865 pa_sink_input_assert_ref(i
);
1866 pa_assert_ctl_context();
1867 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1868 pa_assert(!i
->sink
);
1870 /* Check if someone wants this sink input? */
1871 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1877 pa_sink_input_kill(i
);
1880 /* Called from main context */
1881 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, bool save
) {
1884 pa_sink_input_assert_ref(i
);
1885 pa_assert_ctl_context();
1886 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1888 pa_sink_assert_ref(dest
);
1890 if (dest
== i
->sink
)
1893 if (!pa_sink_input_may_move_to(i
, dest
))
1894 return -PA_ERR_NOTSUPPORTED
;
1896 pa_sink_input_ref(i
);
1898 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1899 pa_sink_input_unref(i
);
1903 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1904 pa_sink_input_fail_move(i
);
1905 pa_sink_input_unref(i
);
1909 pa_sink_input_unref(i
);
1914 /* Called from IO thread context */
1915 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1916 bool corking
, uncorking
;
1918 pa_sink_input_assert_ref(i
);
1919 pa_sink_input_assert_io_context(i
);
1921 if (state
== i
->thread_info
.state
)
1924 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1925 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1926 pa_atomic_store(&i
->thread_info
.drained
, 1);
1928 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1929 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1931 if (i
->state_change
)
1932 i
->state_change(i
, state
);
1936 pa_log_debug("Requesting rewind due to corking");
1938 /* This will tell the implementing sink input driver to rewind
1939 * so that the unplayed already mixed data is not lost */
1940 pa_sink_input_request_rewind(i
, 0, true, true, false);
1942 /* Set the corked state *after* requesting rewind */
1943 i
->thread_info
.state
= state
;
1945 } else if (uncorking
) {
1947 pa_log_debug("Requesting rewind due to uncorking");
1949 i
->thread_info
.underrun_for
= (uint64_t) -1;
1950 i
->thread_info
.underrun_for_sink
= 0;
1951 i
->thread_info
.playing_for
= 0;
1953 /* Set the uncorked state *before* requesting rewind */
1954 i
->thread_info
.state
= state
;
1956 /* OK, we're being uncorked. Make sure we're not rewound when
1957 * the hw buffer is remixed and request a remix. */
1958 pa_sink_input_request_rewind(i
, 0, false, true, true);
1960 /* We may not be corking or uncorking, but we still need to set the state. */
1961 i
->thread_info
.state
= state
;
1964 /* Called from thread context, except when it is not. */
1965 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1966 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1967 pa_sink_input_assert_ref(i
);
1971 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1972 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1973 i
->thread_info
.soft_volume
= i
->soft_volume
;
1974 pa_sink_input_request_rewind(i
, 0, true, false, false);
1978 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1979 if (i
->thread_info
.muted
!= i
->muted
) {
1980 i
->thread_info
.muted
= i
->muted
;
1981 pa_sink_input_request_rewind(i
, 0, true, false, false);
1985 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1986 pa_usec_t
*r
= userdata
;
1988 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1989 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1994 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1996 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1997 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
2001 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
2002 pa_sink_input
*ssync
;
2004 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
2006 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
2007 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
2009 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
2010 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
2015 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
2016 pa_usec_t
*usec
= userdata
;
2018 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
2022 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
2023 pa_usec_t
*r
= userdata
;
2025 *r
= i
->thread_info
.requested_sink_latency
;
2030 return -PA_ERR_NOTIMPLEMENTED
;
2033 /* Called from main thread */
2034 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
2035 pa_sink_input_assert_ref(i
);
2036 pa_assert_ctl_context();
2038 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
2039 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
2044 /* Called from IO context */
2045 bool pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
2046 pa_sink_input_assert_ref(i
);
2047 pa_sink_input_assert_io_context(i
);
2049 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
2050 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
2055 /* Called from IO context */
2056 void pa_sink_input_request_rewind(
2058 size_t nbytes
/* in our sample spec */,
2061 bool dont_rewind_render
) {
2065 /* If 'rewrite' is true the sink is rewound as far as requested
2066 * and possible and the exact value of this is passed back the
2067 * implementor via process_rewind(). If 'flush' is also true all
2068 * already rendered data is also dropped.
2070 * If 'rewrite' is false the sink is rewound as far as requested
2071 * and possible and the already rendered data is dropped so that
2072 * in the next iteration we read new data from the
2073 * implementor. This implies 'flush' is true. If
2074 * dont_rewind_render is true then the render memblockq is not
2077 /* nbytes = 0 means maximum rewind request */
2079 pa_sink_input_assert_ref(i
);
2080 pa_sink_input_assert_io_context(i
);
2081 pa_assert(rewrite
|| flush
);
2082 pa_assert(!dont_rewind_render
|| !rewrite
);
2084 /* We don't take rewind requests while we are corked */
2085 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
2088 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
2090 #ifdef SINK_INPUT_DEBUG
2091 pa_log_debug("request rewrite %zu", nbytes
);
2094 /* Calculate how much we can rewind locally without having to
2097 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
2101 /* Check if rewinding for the maximum is requested, and if so, fix up */
2104 /* Calculate maximum number of bytes that could be rewound in theory */
2105 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
2107 /* Transform from sink domain */
2108 if (i
->thread_info
.resampler
)
2109 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
2112 /* Remember how much we actually want to rewrite */
2113 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
2115 /* Make sure to not overwrite over underruns */
2116 if (nbytes
> i
->thread_info
.playing_for
)
2117 nbytes
= (size_t) i
->thread_info
.playing_for
;
2119 i
->thread_info
.rewrite_nbytes
= nbytes
;
2121 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
2124 i
->thread_info
.rewrite_flush
=
2125 i
->thread_info
.rewrite_flush
|| flush
;
2127 i
->thread_info
.dont_rewind_render
=
2128 i
->thread_info
.dont_rewind_render
||
2131 /* nbytes is -1 if some earlier rewind request had rewrite == false. */
2132 if (nbytes
!= (size_t) -1) {
2134 /* Transform to sink domain */
2135 if (i
->thread_info
.resampler
)
2136 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
2139 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
2141 /* This call will make sure process_rewind() is called later */
2142 pa_sink_request_rewind(i
->sink
, 0);
2146 /* Called from main context */
2147 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
2148 pa_sink_input_assert_ref(i
);
2149 pa_assert_ctl_context();
2152 /* FIXME: Shouldn't access resampler object from main context! */
2154 pa_silence_memchunk_get(
2155 &i
->core
->silence_cache
,
2159 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
2164 /* Called from main context */
2165 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
2166 pa_proplist
*pl
= NULL
;
2167 pa_sink_input_send_event_hook_data hook_data
;
2169 pa_sink_input_assert_ref(i
);
2170 pa_assert_ctl_context();
2177 data
= pl
= pa_proplist_new();
2179 hook_data
.sink_input
= i
;
2180 hook_data
.data
= data
;
2181 hook_data
.event
= event
;
2183 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
2186 i
->send_event(i
, event
, data
);
2190 pa_proplist_free(pl
);
2193 /* Called from main context */
2194 /* Updates the sink input's resampler with whatever the current sink requires
2195 * -- useful when the underlying sink's rate might have changed */
2196 int pa_sink_input_update_rate(pa_sink_input
*i
) {
2197 pa_resampler
*new_resampler
;
2198 char *memblockq_name
;
2200 pa_sink_input_assert_ref(i
);
2201 pa_assert_ctl_context();
2203 if (i
->thread_info
.resampler
&&
2204 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &i
->sink
->sample_spec
) &&
2205 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &i
->sink
->channel_map
))
2207 new_resampler
= i
->thread_info
.resampler
;
2209 else if (!pa_sink_input_is_passthrough(i
) &&
2210 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
2211 !pa_sample_spec_equal(&i
->sample_spec
, &i
->sink
->sample_spec
) ||
2212 !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
))) {
2214 new_resampler
= pa_resampler_new(i
->core
->mempool
,
2215 &i
->sample_spec
, &i
->channel_map
,
2216 &i
->sink
->sample_spec
, &i
->sink
->channel_map
,
2217 i
->requested_resample_method
,
2218 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
2219 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
2220 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0));
2222 if (!new_resampler
) {
2223 pa_log_warn("Unsupported resampling operation.");
2224 return -PA_ERR_NOTSUPPORTED
;
2227 new_resampler
= NULL
;
2229 if (new_resampler
== i
->thread_info
.resampler
)
2232 if (i
->thread_info
.resampler
)
2233 pa_resampler_free(i
->thread_info
.resampler
);
2235 i
->thread_info
.resampler
= new_resampler
;
2237 pa_memblockq_free(i
->thread_info
.render_memblockq
);
2239 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
2240 i
->thread_info
.render_memblockq
= pa_memblockq_new(
2243 MEMBLOCKQ_MAXLENGTH
,
2245 &i
->sink
->sample_spec
,
2250 pa_xfree(memblockq_name
);
2252 i
->actual_resample_method
= new_resampler
? pa_resampler_get_method(new_resampler
) : PA_RESAMPLER_INVALID
;
2254 pa_log_debug("Updated resampler for sink input %d", i
->index
);