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_entry_free2(struct volume_factor_entry
*volume_entry
, void *userdarta
) {
78 volume_factor_entry_free(volume_entry
);
81 static void volume_factor_from_hashmap(pa_cvolume
*v
, pa_hashmap
*items
, uint8_t channels
) {
82 struct volume_factor_entry
*entry
;
85 pa_cvolume_reset(v
, channels
);
86 PA_HASHMAP_FOREACH(entry
, items
, state
)
87 pa_sw_cvolume_multiply(v
, v
, &entry
->volume
);
90 static void sink_input_free(pa_object
*o
);
91 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
93 static int check_passthrough_connection(pa_bool_t passthrough
, pa_sink
*dest
) {
94 if (pa_sink_is_passthrough(dest
)) {
95 pa_log_warn("Sink is already connected to PASSTHROUGH input");
99 /* If current input(s) exist, check new input is not PASSTHROUGH */
100 if (pa_idxset_size(dest
->inputs
) > 0 && passthrough
) {
101 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
108 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
112 data
->resample_method
= PA_RESAMPLER_INVALID
;
113 data
->proplist
= pa_proplist_new();
114 data
->volume_writable
= TRUE
;
116 data
->volume_factor_items
= pa_hashmap_new(pa_idxset_string_hash_func
, pa_idxset_string_compare_func
);
117 data
->volume_factor_sink_items
= pa_hashmap_new(pa_idxset_string_hash_func
, pa_idxset_string_compare_func
);
122 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
125 if ((data
->sample_spec_is_set
= !!spec
))
126 data
->sample_spec
= *spec
;
129 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
132 if ((data
->channel_map_is_set
= !!map
))
133 data
->channel_map
= *map
;
136 pa_bool_t
pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data
*data
) {
139 if (PA_LIKELY(data
->format
) && PA_UNLIKELY(!pa_format_info_is_pcm(data
->format
)))
142 if (PA_UNLIKELY(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
148 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
150 pa_assert(data
->volume_writable
);
152 if ((data
->volume_is_set
= !!volume
))
153 data
->volume
= *volume
;
156 void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data
*data
, const char *key
, const pa_cvolume
*volume_factor
) {
157 struct volume_factor_entry
*v
;
161 pa_assert(volume_factor
);
163 v
= volume_factor_entry_new(key
, volume_factor
);
164 pa_assert_se(pa_hashmap_put(data
->volume_factor_items
, v
->key
, v
) >= 0);
167 void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data
*data
, const char *key
, const pa_cvolume
*volume_factor
) {
168 struct volume_factor_entry
*v
;
172 pa_assert(volume_factor
);
174 v
= volume_factor_entry_new(key
, volume_factor
);
175 pa_assert_se(pa_hashmap_put(data
->volume_factor_sink_items
, v
->key
, v
) >= 0);
178 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
181 data
->muted_is_set
= TRUE
;
182 data
->muted
= !!mute
;
185 pa_bool_t
pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, pa_bool_t save
) {
186 pa_bool_t ret
= TRUE
;
187 pa_idxset
*formats
= NULL
;
192 if (!data
->req_formats
) {
193 /* We're not working with the extended API */
195 data
->save_sink
= save
;
197 /* Extended API: let's see if this sink supports the formats the client can provide */
198 formats
= pa_sink_check_formats(s
, data
->req_formats
);
200 if (formats
&& !pa_idxset_isempty(formats
)) {
201 /* Sink supports at least one of the requested formats */
203 data
->save_sink
= save
;
204 if (data
->nego_formats
)
205 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
206 data
->nego_formats
= formats
;
208 /* Sink doesn't support any of the formats requested by the client */
210 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
218 pa_bool_t
pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
222 if (data
->req_formats
)
223 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
225 data
->req_formats
= formats
;
228 /* Trigger format negotiation */
229 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
235 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
238 if (data
->req_formats
)
239 pa_idxset_free(data
->req_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
241 if (data
->nego_formats
)
242 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
245 pa_format_info_free(data
->format
);
247 if (data
->volume_factor_items
)
248 pa_hashmap_free(data
->volume_factor_items
, (pa_free2_cb_t
) volume_factor_entry_free2
, NULL
);
250 if (data
->volume_factor_sink_items
)
251 pa_hashmap_free(data
->volume_factor_sink_items
, (pa_free2_cb_t
) volume_factor_entry_free2
, NULL
);
253 pa_proplist_free(data
->proplist
);
256 /* Called from main context */
257 static void reset_callbacks(pa_sink_input
*i
) {
261 i
->process_rewind
= NULL
;
262 i
->update_max_rewind
= NULL
;
263 i
->update_max_request
= NULL
;
264 i
->update_sink_requested_latency
= NULL
;
265 i
->update_sink_latency_range
= NULL
;
266 i
->update_sink_fixed_latency
= NULL
;
270 i
->suspend_within_thread
= NULL
;
273 i
->get_latency
= NULL
;
274 i
->state_change
= NULL
;
275 i
->may_move_to
= NULL
;
276 i
->send_event
= NULL
;
277 i
->volume_changed
= NULL
;
278 i
->mute_changed
= NULL
;
281 /* Called from main context */
282 int pa_sink_input_new(
285 pa_sink_input_new_data
*data
) {
288 pa_resampler
*resampler
= NULL
;
289 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
290 pa_channel_map original_cm
;
293 char *memblockq_name
;
300 pa_assert_ctl_context();
303 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
305 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
306 data
->volume_writable
= FALSE
;
308 if (!data
->req_formats
) {
309 /* From this point on, we want to work only with formats, and get back
310 * to using the sample spec and channel map after all decisions w.r.t.
311 * routing are complete. */
312 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
313 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
,
314 data
->channel_map_is_set
? &data
->channel_map
: NULL
);
315 pa_idxset_put(tmp
, f
, NULL
);
316 pa_sink_input_new_data_set_formats(data
, tmp
);
319 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
322 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
325 pa_sink
*sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
326 pa_return_val_if_fail(sink
, -PA_ERR_NOENTITY
);
327 pa_sink_input_new_data_set_sink(data
, sink
, FALSE
);
329 /* Routing's done, we have a sink. Now let's fix the format and set up the
332 /* If something didn't pick a format for us, pick the top-most format since
333 * we assume this is sorted in priority order */
334 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
335 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
337 pa_return_val_if_fail(data
->format
, -PA_ERR_NOTSUPPORTED
);
339 /* Now populate the sample spec and format according to the final
340 * format that we've negotiated */
341 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
) == 0, -PA_ERR_INVALID
);
342 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
343 if (pa_format_info_is_pcm(data
->format
) && pa_channel_map_valid(&map
))
344 pa_sink_input_new_data_set_channel_map(data
, &map
);
346 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
347 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
);
349 r
= check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data
), data
->sink
);
353 if (!data
->sample_spec_is_set
)
354 data
->sample_spec
= data
->sink
->sample_spec
;
356 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
358 if (!data
->channel_map_is_set
) {
359 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
360 data
->channel_map
= data
->sink
->channel_map
;
362 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
365 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
367 /* Don't restore (or save) stream volume for passthrough streams and
368 * prevent attenuation/gain */
369 if (pa_sink_input_new_data_is_passthrough(data
)) {
370 data
->volume_is_set
= TRUE
;
371 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
372 data
->volume_is_absolute
= TRUE
;
373 data
->save_volume
= FALSE
;
376 if (!data
->volume_is_set
) {
377 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
378 data
->volume_is_absolute
= FALSE
;
379 data
->save_volume
= FALSE
;
382 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
384 if (!data
->muted_is_set
)
387 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
388 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
390 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
391 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
393 original_cm
= data
->channel_map
;
395 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
396 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
397 data
->channel_map
= data
->sink
->channel_map
;
400 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
401 pa_assert(pa_channel_map_valid(&data
->channel_map
));
403 if (!(data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
404 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
)) {
405 /* try to change sink rate. This is done before the FIXATE hook since
406 module-suspend-on-idle can resume a sink */
408 pa_log_info("Trying to change sample rate");
409 if (pa_sink_update_rate(data
->sink
, data
->sample_spec
.rate
, pa_sink_input_new_data_is_passthrough(data
)) == TRUE
)
410 pa_log_info("Rate changed to %u Hz", data
->sink
->sample_spec
.rate
);
413 if (pa_sink_input_new_data_is_passthrough(data
) &&
414 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
)) {
415 /* rate update failed, or other parts of sample spec didn't match */
417 pa_log_debug("Could not update sink sample spec to match passthrough stream");
418 return -PA_ERR_NOTSUPPORTED
;
421 /* Due to the fixing of the sample spec the volume might not match anymore */
422 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
424 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
425 data
->resample_method
= core
->resample_method
;
427 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
429 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
432 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
433 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
434 pa_log_warn("Failed to create sink input: sink is suspended.");
435 return -PA_ERR_BADSTATE
;
438 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
439 pa_log_warn("Failed to create sink input: too many inputs per sink.");
440 return -PA_ERR_TOOLARGE
;
443 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
444 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
445 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
447 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
448 if (!pa_sink_input_new_data_is_passthrough(data
)) /* no resampler for passthrough content */
449 if (!(resampler
= pa_resampler_new(
451 &data
->sample_spec
, &data
->channel_map
,
452 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
453 data
->resample_method
,
454 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
455 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
456 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
457 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
458 pa_log_warn("Unsupported resampling operation.");
459 return -PA_ERR_NOTSUPPORTED
;
463 i
= pa_msgobject_new(pa_sink_input
);
464 i
->parent
.parent
.free
= sink_input_free
;
465 i
->parent
.process_msg
= pa_sink_input_process_msg
;
468 i
->state
= PA_SINK_INPUT_INIT
;
469 i
->flags
= data
->flags
;
470 i
->proplist
= pa_proplist_copy(data
->proplist
);
471 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
472 i
->module
= data
->module
;
473 i
->sink
= data
->sink
;
474 i
->origin_sink
= data
->origin_sink
;
475 i
->client
= data
->client
;
477 i
->requested_resample_method
= data
->resample_method
;
478 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
479 i
->sample_spec
= data
->sample_spec
;
480 i
->channel_map
= data
->channel_map
;
481 i
->format
= pa_format_info_copy(data
->format
);
483 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
486 /* When the 'absolute' bool is not set then we'll treat the volume
487 * as relative to the sink volume even in flat volume mode */
488 remapped
= data
->sink
->reference_volume
;
489 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
490 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
492 i
->volume
= data
->volume
;
494 i
->volume_factor_items
= data
->volume_factor_items
;
495 data
->volume_factor_items
= NULL
;
496 volume_factor_from_hashmap(&i
->volume_factor
, i
->volume_factor_items
, i
->sample_spec
.channels
);
498 i
->volume_factor_sink_items
= data
->volume_factor_sink_items
;
499 data
->volume_factor_sink_items
= NULL
;
500 volume_factor_from_hashmap(&i
->volume_factor_sink
, i
->volume_factor_sink_items
, i
->sample_spec
.channels
);
502 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
503 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
504 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
505 i
->volume_writable
= data
->volume_writable
;
506 i
->save_volume
= data
->save_volume
;
507 i
->save_sink
= data
->save_sink
;
508 i
->save_muted
= data
->save_muted
;
510 i
->muted
= data
->muted
;
512 if (data
->sync_base
) {
513 i
->sync_next
= data
->sync_base
->sync_next
;
514 i
->sync_prev
= data
->sync_base
;
516 if (data
->sync_base
->sync_next
)
517 data
->sync_base
->sync_next
->sync_prev
= i
;
518 data
->sync_base
->sync_next
= i
;
520 i
->sync_next
= i
->sync_prev
= NULL
;
522 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
527 i
->thread_info
.state
= i
->state
;
528 i
->thread_info
.attached
= FALSE
;
529 pa_atomic_store(&i
->thread_info
.drained
, 1);
530 i
->thread_info
.sample_spec
= i
->sample_spec
;
531 i
->thread_info
.resampler
= resampler
;
532 i
->thread_info
.soft_volume
= i
->soft_volume
;
533 i
->thread_info
.muted
= i
->muted
;
534 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
535 i
->thread_info
.rewrite_nbytes
= 0;
536 i
->thread_info
.rewrite_flush
= FALSE
;
537 i
->thread_info
.dont_rewind_render
= FALSE
;
538 i
->thread_info
.underrun_for
= (uint64_t) -1;
539 i
->thread_info
.playing_for
= 0;
540 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
542 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
543 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
546 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
548 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
549 i
->thread_info
.render_memblockq
= pa_memblockq_new(
554 &i
->sink
->sample_spec
,
559 pa_xfree(memblockq_name
);
561 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
562 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
564 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
566 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
567 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
571 /* Don't forget to call pa_sink_input_put! */
577 /* Called from main context */
578 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
580 pa_assert_ctl_context();
585 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
586 pa_assert_se(i
->sink
->n_corked
-- >= 1);
587 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
591 /* Called from main context */
592 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
593 pa_sink_input
*ssync
;
595 pa_assert_ctl_context();
597 if (state
== PA_SINK_INPUT_DRAINED
)
598 state
= PA_SINK_INPUT_RUNNING
;
600 if (i
->state
== state
)
603 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
&& pa_sink_used_by(i
->sink
) == 0 &&
604 !pa_sample_spec_equal(&i
->sample_spec
, &i
->sink
->sample_spec
)) {
605 /* We were uncorked and the sink was not playing anything -- let's try
606 * to update the sample rate to avoid resampling */
607 pa_sink_update_rate(i
->sink
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
));
610 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);
612 update_n_corked(i
, state
);
615 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
616 update_n_corked(ssync
, state
);
617 ssync
->state
= state
;
619 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
620 update_n_corked(ssync
, state
);
621 ssync
->state
= state
;
624 if (state
!= PA_SINK_INPUT_UNLINKED
) {
625 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
627 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
628 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
630 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
631 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
633 if (PA_SINK_INPUT_IS_LINKED(state
))
634 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
637 pa_sink_update_status(i
->sink
);
640 /* Called from main context */
641 void pa_sink_input_unlink(pa_sink_input
*i
) {
643 pa_source_output
*o
, *p
= NULL
;
646 pa_assert_ctl_context();
648 /* See pa_sink_unlink() for a couple of comments how this function
651 pa_sink_input_ref(i
);
653 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
656 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
659 i
->sync_prev
->sync_next
= i
->sync_next
;
661 i
->sync_next
->sync_prev
= i
->sync_prev
;
663 i
->sync_prev
= i
->sync_next
= NULL
;
665 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
668 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
669 pa_sink_input_unref(i
);
672 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
674 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
676 pa_source_output_kill(o
);
680 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
681 i
->state
= PA_SINK_INPUT_UNLINKED
;
683 if (linked
&& i
->sink
) {
684 if (pa_sink_input_is_passthrough(i
))
685 pa_sink_leave_passthrough(i
->sink
);
687 /* We might need to update the sink's volume if we are in flat volume mode. */
688 if (pa_sink_flat_volume_enabled(i
->sink
))
689 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
691 if (i
->sink
->asyncmsgq
)
692 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
698 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
699 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
703 if (PA_SINK_IS_LINKED(pa_sink_get_state(i
->sink
)))
704 pa_sink_update_status(i
->sink
);
709 pa_core_maybe_vacuum(i
->core
);
711 pa_sink_input_unref(i
);
714 /* Called from main context */
715 static void sink_input_free(pa_object
*o
) {
716 pa_sink_input
* i
= PA_SINK_INPUT(o
);
719 pa_assert_ctl_context();
720 pa_assert(pa_sink_input_refcnt(i
) == 0);
722 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
723 pa_sink_input_unlink(i
);
725 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
727 /* Side note: this function must be able to destruct properly any
728 * kind of sink input in any state, even those which are
729 * "half-moved" or are connected to sinks that have no asyncmsgq
730 * and are hence half-destructed themselves! */
732 if (i
->thread_info
.render_memblockq
)
733 pa_memblockq_free(i
->thread_info
.render_memblockq
);
735 if (i
->thread_info
.resampler
)
736 pa_resampler_free(i
->thread_info
.resampler
);
739 pa_format_info_free(i
->format
);
742 pa_proplist_free(i
->proplist
);
744 if (i
->direct_outputs
)
745 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
747 if (i
->thread_info
.direct_outputs
)
748 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
750 if (i
->volume_factor_items
)
751 pa_hashmap_free(i
->volume_factor_items
, (pa_free2_cb_t
) volume_factor_entry_free2
, NULL
);
752 if (i
->volume_factor_sink_items
)
753 pa_hashmap_free(i
->volume_factor_sink_items
, (pa_free2_cb_t
) volume_factor_entry_free2
, NULL
);
759 /* Called from main context */
760 void pa_sink_input_put(pa_sink_input
*i
) {
761 pa_sink_input_state_t state
;
763 pa_sink_input_assert_ref(i
);
764 pa_assert_ctl_context();
766 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
768 /* The following fields must be initialized properly */
770 pa_assert(i
->process_rewind
);
773 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
775 update_n_corked(i
, state
);
778 /* We might need to update the sink's volume if we are in flat volume mode. */
779 if (pa_sink_flat_volume_enabled(i
->sink
))
780 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
782 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
783 pa_assert(pa_cvolume_is_norm(&i
->volume
));
784 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
787 set_real_ratio(i
, &i
->volume
);
790 if (pa_sink_input_is_passthrough(i
))
791 pa_sink_enter_passthrough(i
->sink
);
793 i
->thread_info
.soft_volume
= i
->soft_volume
;
794 i
->thread_info
.muted
= i
->muted
;
796 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
798 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
799 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
801 pa_sink_update_status(i
->sink
);
804 /* Called from main context */
805 void pa_sink_input_kill(pa_sink_input
*i
) {
806 pa_sink_input_assert_ref(i
);
807 pa_assert_ctl_context();
808 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
813 /* Called from main context */
814 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
815 pa_usec_t r
[2] = { 0, 0 };
817 pa_sink_input_assert_ref(i
);
818 pa_assert_ctl_context();
819 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
821 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
824 r
[0] += i
->get_latency(i
);
827 *sink_latency
= r
[1];
832 /* Called from thread context */
833 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
834 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
835 pa_bool_t volume_is_norm
;
836 size_t block_size_max_sink
, block_size_max_sink_input
;
840 pa_sink_input_assert_ref(i
);
841 pa_sink_input_assert_io_context(i
);
842 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
843 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
847 #ifdef SINK_INPUT_DEBUG
848 pa_log_debug("peek");
851 block_size_max_sink_input
= i
->thread_info
.resampler
?
852 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
853 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
855 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
857 /* Default buffer size */
859 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
861 if (slength
> block_size_max_sink
)
862 slength
= block_size_max_sink
;
864 if (i
->thread_info
.resampler
) {
865 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
868 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
872 /* Length corresponding to slength (without limiting to
873 * block_size_max_sink_input). */
874 ilength_full
= ilength
;
876 if (ilength
> block_size_max_sink_input
)
877 ilength
= block_size_max_sink_input
;
879 /* If the channel maps of the sink and this stream differ, we need
880 * to adjust the volume *before* we resample. Otherwise we can do
881 * it after and leave it for the sink code */
883 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
884 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
885 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
887 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
890 /* There's nothing in our render queue. We need to fill it up
891 * with data from the implementor. */
893 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
894 i
->pop(i
, ilength
, &tchunk
) < 0) {
896 /* OK, we're corked or the implementor didn't give us any
897 * data, so let's just hand out silence */
898 pa_atomic_store(&i
->thread_info
.drained
, 1);
900 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
901 i
->thread_info
.playing_for
= 0;
902 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
903 i
->thread_info
.underrun_for
+= ilength_full
;
907 pa_atomic_store(&i
->thread_info
.drained
, 0);
909 pa_assert(tchunk
.length
> 0);
910 pa_assert(tchunk
.memblock
);
912 i
->thread_info
.underrun_for
= 0;
913 i
->thread_info
.playing_for
+= tchunk
.length
;
915 while (tchunk
.length
> 0) {
917 pa_bool_t nvfs
= need_volume_factor_sink
;
920 pa_memblock_ref(wchunk
.memblock
);
922 if (wchunk
.length
> block_size_max_sink_input
)
923 wchunk
.length
= block_size_max_sink_input
;
925 /* It might be necessary to adjust the volume here */
926 if (do_volume_adj_here
&& !volume_is_norm
) {
927 pa_memchunk_make_writable(&wchunk
, 0);
929 if (i
->thread_info
.muted
) {
930 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
933 } else if (!i
->thread_info
.resampler
&& nvfs
) {
936 /* If we don't need a resampler we can merge the
937 * post and the pre volume adjustment into one */
939 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
940 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
944 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
947 if (!i
->thread_info
.resampler
) {
950 pa_memchunk_make_writable(&wchunk
, 0);
951 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
954 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
957 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
959 #ifdef SINK_INPUT_DEBUG
960 pa_log_debug("pushing %lu", (unsigned long) rchunk
.length
);
963 if (rchunk
.memblock
) {
966 pa_memchunk_make_writable(&rchunk
, 0);
967 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
970 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
971 pa_memblock_unref(rchunk
.memblock
);
975 pa_memblock_unref(wchunk
.memblock
);
977 tchunk
.index
+= wchunk
.length
;
978 tchunk
.length
-= wchunk
.length
;
981 pa_memblock_unref(tchunk
.memblock
);
984 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
986 pa_assert(chunk
->length
> 0);
987 pa_assert(chunk
->memblock
);
989 #ifdef SINK_INPUT_DEBUG
990 pa_log_debug("peeking %lu", (unsigned long) chunk
->length
);
993 if (chunk
->length
> block_size_max_sink
)
994 chunk
->length
= block_size_max_sink
;
996 /* Let's see if we had to apply the volume adjustment ourselves,
997 * or if this can be done by the sink for us */
999 if (do_volume_adj_here
)
1000 /* We had different channel maps, so we already did the adjustment */
1001 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
1002 else if (i
->thread_info
.muted
)
1003 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
1004 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
1006 *volume
= i
->thread_info
.soft_volume
;
1009 /* Called from thread context */
1010 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
1012 pa_sink_input_assert_ref(i
);
1013 pa_sink_input_assert_io_context(i
);
1014 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1015 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1016 pa_assert(nbytes
> 0);
1018 #ifdef SINK_INPUT_DEBUG
1019 pa_log_debug("dropping %lu", (unsigned long) nbytes
);
1022 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
1025 /* Called from thread context */
1026 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
1028 pa_bool_t called
= FALSE
;
1030 pa_sink_input_assert_ref(i
);
1031 pa_sink_input_assert_io_context(i
);
1032 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1033 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1035 #ifdef SINK_INPUT_DEBUG
1036 pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes
, (unsigned long) i
->thread_info
.rewrite_nbytes
);
1039 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1041 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
1042 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
1043 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
1046 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
1048 /* We were asked to drop all buffered data, and rerequest new
1049 * data from implementor the next time peek() is called */
1051 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, TRUE
);
1053 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
1054 size_t max_rewrite
, amount
;
1056 /* Calculate how much make sense to rewrite at most */
1057 max_rewrite
= nbytes
+ lbq
;
1059 /* Transform into local domain */
1060 if (i
->thread_info
.resampler
)
1061 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
1063 /* Calculate how much of the rewinded data should actually be rewritten */
1064 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
1067 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
1069 /* Tell the implementor */
1070 if (i
->process_rewind
)
1071 i
->process_rewind(i
, amount
);
1074 /* Convert back to to sink domain */
1075 if (i
->thread_info
.resampler
)
1076 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
1079 /* Ok, now update the write pointer */
1080 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
1082 if (i
->thread_info
.rewrite_flush
)
1083 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
1085 /* And reset the resampler */
1086 if (i
->thread_info
.resampler
)
1087 pa_resampler_reset(i
->thread_info
.resampler
);
1092 if (i
->process_rewind
)
1093 i
->process_rewind(i
, 0);
1095 i
->thread_info
.rewrite_nbytes
= 0;
1096 i
->thread_info
.rewrite_flush
= FALSE
;
1097 i
->thread_info
.dont_rewind_render
= FALSE
;
1100 /* Called from thread context */
1101 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
1102 pa_sink_input_assert_ref(i
);
1103 pa_sink_input_assert_io_context(i
);
1105 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1108 /* Called from thread context */
1109 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1110 pa_sink_input_assert_ref(i
);
1111 pa_sink_input_assert_io_context(i
);
1113 /* We're not verifying the status here, to allow this to be called
1114 * in the state change handler between _INIT and _RUNNING */
1116 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1119 /* Called from thread context */
1120 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1121 pa_sink_input_assert_ref(i
);
1122 pa_sink_input_assert_io_context(i
);
1123 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1124 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1126 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1128 if (i
->update_max_rewind
)
1129 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1132 /* Called from thread context */
1133 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1134 pa_sink_input_assert_ref(i
);
1135 pa_sink_input_assert_io_context(i
);
1136 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1137 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1139 if (i
->update_max_request
)
1140 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1143 /* Called from thread context */
1144 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1145 pa_sink_input_assert_ref(i
);
1146 pa_sink_input_assert_io_context(i
);
1148 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1149 usec
= i
->sink
->thread_info
.fixed_latency
;
1151 if (usec
!= (pa_usec_t
) -1)
1152 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1154 i
->thread_info
.requested_sink_latency
= usec
;
1155 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
1160 /* Called from main context */
1161 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1162 pa_sink_input_assert_ref(i
);
1163 pa_assert_ctl_context();
1165 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1166 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1170 /* If this sink input is not realized yet or we are being moved,
1171 * we have to touch the thread info data directly */
1174 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1175 usec
= pa_sink_get_fixed_latency(i
->sink
);
1177 if (usec
!= (pa_usec_t
) -1) {
1178 pa_usec_t min_latency
, max_latency
;
1179 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1180 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1184 i
->thread_info
.requested_sink_latency
= usec
;
1189 /* Called from main context */
1190 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1191 pa_sink_input_assert_ref(i
);
1192 pa_assert_ctl_context();
1194 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1196 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1200 /* If this sink input is not realized yet or we are being moved,
1201 * we have to touch the thread info data directly */
1203 return i
->thread_info
.requested_sink_latency
;
1206 /* Called from main context */
1207 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
1210 pa_sink_input_assert_ref(i
);
1211 pa_assert_ctl_context();
1212 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1214 pa_assert(pa_cvolume_valid(volume
));
1215 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1216 pa_assert(i
->volume_writable
);
1218 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1219 v
= i
->sink
->reference_volume
;
1220 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1222 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1223 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1225 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1227 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1229 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1233 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1234 i
->save_volume
= i
->save_volume
|| save
;
1238 i
->volume
= *volume
;
1239 i
->save_volume
= save
;
1241 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1242 /* We are in flat volume mode, so let's update all sink input
1243 * volumes and update the flat volume of the sink */
1245 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1248 /* OK, we are in normal volume mode. The volume only affects
1250 set_real_ratio(i
, volume
);
1252 /* Copy the new soft_volume to the thread_info struct */
1253 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1256 /* The volume changed, let's tell people so */
1257 if (i
->volume_changed
)
1258 i
->volume_changed(i
);
1260 /* The virtual volume changed, let's tell people so */
1261 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1264 void pa_sink_input_add_volume_factor(pa_sink_input
*i
, const char *key
, const pa_cvolume
*volume_factor
) {
1265 struct volume_factor_entry
*v
;
1267 pa_sink_input_assert_ref(i
);
1268 pa_assert_ctl_context();
1269 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1270 pa_assert(volume_factor
);
1272 pa_assert(pa_cvolume_valid(volume_factor
));
1273 pa_assert(volume_factor
->channels
== 1 || pa_cvolume_compatible(volume_factor
, &i
->sample_spec
));
1275 v
= volume_factor_entry_new(key
, volume_factor
);
1276 if (!pa_cvolume_compatible(volume_factor
, &i
->sample_spec
))
1277 pa_cvolume_set(&v
->volume
, i
->sample_spec
.channels
, volume_factor
->values
[0]);
1279 pa_assert_se(pa_hashmap_put(i
->volume_factor_items
, v
->key
, v
) >= 0);
1280 if (pa_hashmap_size(i
->volume_factor_items
) == 1)
1281 i
->volume_factor
= v
->volume
;
1283 pa_sw_cvolume_multiply(&i
->volume_factor
, &i
->volume_factor
, &v
->volume
);
1285 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1287 /* Copy the new soft_volume to the thread_info struct */
1288 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1291 void pa_sink_input_remove_volume_factor(pa_sink_input
*i
, const char *key
) {
1292 struct volume_factor_entry
*v
;
1294 pa_sink_input_assert_ref(i
);
1296 pa_assert_ctl_context();
1297 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1299 pa_assert_se(v
= pa_hashmap_remove(i
->volume_factor_items
, key
));
1300 volume_factor_entry_free(v
);
1302 switch (pa_hashmap_size(i
->volume_factor_items
)) {
1304 pa_cvolume_reset(&i
->volume_factor
, i
->sample_spec
.channels
);
1307 v
= pa_hashmap_first(i
->volume_factor_items
);
1308 i
->volume_factor
= v
->volume
;
1311 volume_factor_from_hashmap(&i
->volume_factor
, i
->volume_factor_items
, i
->volume_factor
.channels
);
1314 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1316 /* Copy the new soft_volume to the thread_info struct */
1317 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1320 /* Called from main context */
1321 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1322 pa_sink_input_assert_ref(i
);
1323 pa_assert_ctl_context();
1324 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1325 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1327 /* This basically calculates:
1329 * i->real_ratio := v
1330 * i->soft_volume := i->real_ratio * i->volume_factor */
1335 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1337 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1338 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1341 /* Called from main or I/O context */
1342 pa_bool_t
pa_sink_input_is_passthrough(pa_sink_input
*i
) {
1343 pa_sink_input_assert_ref(i
);
1345 if (PA_UNLIKELY(!pa_format_info_is_pcm(i
->format
)))
1348 if (PA_UNLIKELY(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
1354 /* Called from main context */
1355 pa_bool_t
pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1356 pa_sink_input_assert_ref(i
);
1357 pa_assert_ctl_context();
1359 return !pa_sink_input_is_passthrough(i
);
1362 /* Called from main context */
1363 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1364 pa_sink_input_assert_ref(i
);
1365 pa_assert_ctl_context();
1366 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1367 pa_assert(pa_sink_input_is_volume_readable(i
));
1369 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1370 *volume
= i
->volume
;
1372 *volume
= i
->reference_ratio
;
1377 /* Called from main context */
1378 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1379 pa_sink_input_assert_ref(i
);
1380 pa_assert_ctl_context();
1381 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1383 if (!i
->muted
== !mute
) {
1384 i
->save_muted
= i
->save_muted
|| mute
;
1389 i
->save_muted
= save
;
1391 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1393 /* The mute status changed, let's tell people so */
1394 if (i
->mute_changed
)
1397 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1400 /* Called from main context */
1401 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1402 pa_sink_input_assert_ref(i
);
1403 pa_assert_ctl_context();
1404 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1409 /* Called from main thread */
1410 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1411 pa_sink_input_assert_ref(i
);
1412 pa_assert_ctl_context();
1415 pa_proplist_update(i
->proplist
, mode
, p
);
1417 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1418 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1419 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1423 /* Called from main context */
1424 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1425 pa_sink_input_assert_ref(i
);
1426 pa_assert_ctl_context();
1427 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1429 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1432 /* Called from main context */
1433 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1434 pa_sink_input_assert_ref(i
);
1435 pa_assert_ctl_context();
1436 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1437 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1439 if (i
->sample_spec
.rate
== rate
)
1442 i
->sample_spec
.rate
= rate
;
1444 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1446 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1450 /* Called from main context */
1451 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1453 pa_sink_input_assert_ref(i
);
1454 pa_assert_ctl_context();
1456 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1459 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1461 if (old
&& name
&& pa_streq(old
, name
))
1465 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1467 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1469 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1470 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1471 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1475 /* Called from main context */
1476 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1477 pa_sink_input_assert_ref(i
);
1478 pa_assert_ctl_context();
1480 return i
->actual_resample_method
;
1483 /* Called from main context */
1484 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1485 pa_sink_input_assert_ref(i
);
1486 pa_assert_ctl_context();
1487 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1489 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1492 if (i
->sync_next
|| i
->sync_prev
) {
1493 pa_log_warn("Moving synchronized streams not supported.");
1500 static pa_bool_t
find_filter_sink_input(pa_sink_input
*target
, pa_sink
*s
) {
1502 while (s
&& s
->input_to_master
) {
1503 if (s
->input_to_master
== target
)
1505 s
= s
->input_to_master
->sink
;
1506 pa_assert(i
++ < 100);
1511 /* Called from main context */
1512 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1513 pa_sink_input_assert_ref(i
);
1514 pa_assert_ctl_context();
1515 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1516 pa_sink_assert_ref(dest
);
1518 if (dest
== i
->sink
)
1521 if (!pa_sink_input_may_move(i
))
1524 /* Make sure we're not creating a filter sink cycle */
1525 if (find_filter_sink_input(i
, dest
)) {
1526 pa_log_debug("Can't connect input to %s, as that would create a cycle.", dest
->name
);
1530 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1531 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1535 if (check_passthrough_connection(pa_sink_input_is_passthrough(i
), dest
) < 0)
1539 if (!i
->may_move_to(i
, dest
))
1545 /* Called from main context */
1546 int pa_sink_input_start_move(pa_sink_input
*i
) {
1547 pa_source_output
*o
, *p
= NULL
;
1548 struct volume_factor_entry
*v
;
1552 pa_sink_input_assert_ref(i
);
1553 pa_assert_ctl_context();
1554 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1557 if (!pa_sink_input_may_move(i
))
1558 return -PA_ERR_NOTSUPPORTED
;
1560 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1563 /* Kill directly connected outputs */
1564 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1566 pa_source_output_kill(o
);
1569 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1571 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1573 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1574 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1576 if (pa_sink_input_is_passthrough(i
))
1577 pa_sink_leave_passthrough(i
->sink
);
1579 if (pa_sink_flat_volume_enabled(i
->sink
))
1580 /* We might need to update the sink's volume if we are in flat
1582 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1584 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1586 pa_sink_update_status(i
->sink
);
1588 PA_HASHMAP_FOREACH(v
, i
->volume_factor_sink_items
, state
)
1589 pa_cvolume_remap(&v
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1591 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1595 pa_sink_input_unref(i
);
1600 /* Called from main context. If i has an origin sink that uses volume sharing,
1601 * then also the origin sink and all streams connected to it need to update
1602 * their volume - this function does all that by using recursion. */
1603 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1604 pa_cvolume old_volume
;
1608 pa_assert(i
->sink
); /* The destination sink should already be set. */
1610 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1611 pa_sink
*root_sink
= pa_sink_get_master(i
->sink
);
1612 pa_sink_input
*origin_sink_input
;
1615 if (PA_UNLIKELY(!root_sink
))
1618 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1619 /* Ok, so the origin sink uses volume sharing, and flat volume is
1620 * enabled. The volume will have to be updated as follows:
1622 * i->volume := i->sink->real_volume
1623 * (handled later by pa_sink_set_volume)
1624 * i->reference_ratio := i->volume / i->sink->reference_volume
1625 * (handled later by pa_sink_set_volume)
1626 * i->real_ratio stays unchanged
1627 * (streams whose origin sink uses volume sharing should
1628 * always have real_ratio of 0 dB)
1629 * i->soft_volume stays unchanged
1630 * (streams whose origin sink uses volume sharing should
1631 * always have volume_factor as soft_volume, so no change
1632 * should be needed) */
1634 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1635 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1637 /* Notifications will be sent by pa_sink_set_volume(). */
1640 /* Ok, so the origin sink uses volume sharing, and flat volume is
1641 * disabled. The volume will have to be updated as follows:
1644 * i->reference_ratio := 0 dB
1645 * i->real_ratio stays unchanged
1646 * (streams whose origin sink uses volume sharing should
1647 * always have real_ratio of 0 dB)
1648 * i->soft_volume stays unchanged
1649 * (streams whose origin sink uses volume sharing should
1650 * always have volume_factor as soft_volume, so no change
1651 * should be needed) */
1653 old_volume
= i
->volume
;
1654 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1655 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1656 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1657 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1659 /* Notify others about the changed sink input volume. */
1660 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1661 if (i
->volume_changed
)
1662 i
->volume_changed(i
);
1664 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1668 /* Additionally, the origin sink volume needs updating:
1670 * i->origin_sink->reference_volume := root_sink->reference_volume
1671 * i->origin_sink->real_volume := root_sink->real_volume
1672 * i->origin_sink->soft_volume stays unchanged
1673 * (sinks that use volume sharing should always have
1674 * soft_volume of 0 dB) */
1676 old_volume
= i
->origin_sink
->reference_volume
;
1678 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1679 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1681 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1682 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1684 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1686 /* Notify others about the changed sink volume. If you wonder whether
1687 * i->origin_sink->set_volume() should be called somewhere, that's not
1688 * the case, because sinks that use volume sharing shouldn't have any
1689 * internal volume that set_volume() would update. If you wonder
1690 * whether the thread_info variables should be synced, yes, they
1691 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1693 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1694 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1696 /* Recursively update origin sink inputs. */
1697 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1698 update_volume_due_to_moving(origin_sink_input
, dest
);
1701 old_volume
= i
->volume
;
1703 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1704 /* Ok, so this is a regular stream, and flat volume is enabled. The
1705 * volume will have to be updated as follows:
1707 * i->volume := i->reference_ratio * i->sink->reference_volume
1708 * i->reference_ratio stays unchanged
1709 * i->real_ratio := i->volume / i->sink->real_volume
1710 * (handled later by pa_sink_set_volume)
1711 * i->soft_volume := i->real_ratio * i->volume_factor
1712 * (handled later by pa_sink_set_volume) */
1714 i
->volume
= i
->sink
->reference_volume
;
1715 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1716 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1719 /* Ok, so this is a regular stream, and flat volume is disabled.
1720 * The volume will have to be updated as follows:
1722 * i->volume := i->reference_ratio
1723 * i->reference_ratio stays unchanged
1724 * i->real_ratio := i->reference_ratio
1725 * i->soft_volume := i->real_ratio * i->volume_factor */
1727 i
->volume
= i
->reference_ratio
;
1728 i
->real_ratio
= i
->reference_ratio
;
1729 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1732 /* Notify others about the changed sink input volume. */
1733 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1734 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1735 * and soft_volume are not updated yet. Let's hope that the
1736 * callback implementation doesn't care about those variables... */
1737 if (i
->volume_changed
)
1738 i
->volume_changed(i
);
1740 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1744 /* If i->sink == dest, then recursion has finished, and we can finally call
1745 * pa_sink_set_volume(), which will do the rest of the updates. */
1746 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1747 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1750 /* Called from main context */
1751 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1752 struct volume_factor_entry
*v
;
1755 pa_sink_input_assert_ref(i
);
1756 pa_assert_ctl_context();
1757 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1758 pa_assert(!i
->sink
);
1759 pa_sink_assert_ref(dest
);
1761 if (!pa_sink_input_may_move_to(i
, dest
))
1762 return -PA_ERR_NOTSUPPORTED
;
1764 if (pa_sink_input_is_passthrough(i
) && !pa_sink_check_format(dest
, i
->format
)) {
1765 pa_proplist
*p
= pa_proplist_new();
1766 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1767 /* Tell the client what device we want to be on if it is going to
1769 pa_proplist_sets(p
, "device", dest
->name
);
1770 pa_sink_input_send_event(i
, PA_STREAM_EVENT_FORMAT_LOST
, p
);
1771 pa_proplist_free(p
);
1772 return -PA_ERR_NOTSUPPORTED
;
1775 if (!(i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
1776 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
)) {
1777 /* try to change dest sink rate if possible without glitches.
1778 module-suspend-on-idle resumes destination sink with
1779 SINK_INPUT_MOVE_FINISH hook */
1781 pa_log_info("Trying to change sample rate");
1782 if (pa_sink_update_rate(dest
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
)) == TRUE
)
1783 pa_log_info("Rate changed to %u Hz", dest
->sample_spec
.rate
);
1790 i
->save_sink
= save
;
1791 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1793 PA_HASHMAP_FOREACH(v
, i
->volume_factor_sink_items
, state
)
1794 pa_cvolume_remap(&v
->volume
, &i
->channel_map
, &i
->sink
->channel_map
);
1796 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1798 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1799 i
->sink
->n_corked
++;
1801 pa_sink_input_update_rate(i
);
1803 pa_sink_update_status(dest
);
1805 update_volume_due_to_moving(i
, dest
);
1807 if (pa_sink_input_is_passthrough(i
))
1808 pa_sink_enter_passthrough(i
->sink
);
1810 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1812 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1814 /* Notify everyone */
1815 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1816 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1821 /* Called from main context */
1822 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1824 pa_sink_input_assert_ref(i
);
1825 pa_assert_ctl_context();
1826 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1827 pa_assert(!i
->sink
);
1829 /* Check if someone wants this sink input? */
1830 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1836 pa_sink_input_kill(i
);
1839 /* Called from main context */
1840 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1843 pa_sink_input_assert_ref(i
);
1844 pa_assert_ctl_context();
1845 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1847 pa_sink_assert_ref(dest
);
1849 if (dest
== i
->sink
)
1852 if (!pa_sink_input_may_move_to(i
, dest
))
1853 return -PA_ERR_NOTSUPPORTED
;
1855 pa_sink_input_ref(i
);
1857 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1858 pa_sink_input_unref(i
);
1862 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1863 pa_sink_input_fail_move(i
);
1864 pa_sink_input_unref(i
);
1868 pa_sink_input_unref(i
);
1873 /* Called from IO thread context */
1874 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1875 pa_bool_t corking
, uncorking
;
1877 pa_sink_input_assert_ref(i
);
1878 pa_sink_input_assert_io_context(i
);
1880 if (state
== i
->thread_info
.state
)
1883 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1884 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1885 pa_atomic_store(&i
->thread_info
.drained
, 1);
1887 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1888 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1890 if (i
->state_change
)
1891 i
->state_change(i
, state
);
1895 pa_log_debug("Requesting rewind due to corking");
1897 /* This will tell the implementing sink input driver to rewind
1898 * so that the unplayed already mixed data is not lost */
1899 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1901 /* Set the corked state *after* requesting rewind */
1902 i
->thread_info
.state
= state
;
1904 } else if (uncorking
) {
1906 pa_log_debug("Requesting rewind due to uncorking");
1908 i
->thread_info
.underrun_for
= (uint64_t) -1;
1909 i
->thread_info
.playing_for
= 0;
1911 /* Set the uncorked state *before* requesting rewind */
1912 i
->thread_info
.state
= state
;
1914 /* OK, we're being uncorked. Make sure we're not rewound when
1915 * the hw buffer is remixed and request a remix. */
1916 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1918 /* We may not be corking or uncorking, but we still need to set the state. */
1919 i
->thread_info
.state
= state
;
1922 /* Called from thread context, except when it is not. */
1923 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1924 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1925 pa_sink_input_assert_ref(i
);
1929 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1930 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1931 i
->thread_info
.soft_volume
= i
->soft_volume
;
1932 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1936 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1937 if (i
->thread_info
.muted
!= i
->muted
) {
1938 i
->thread_info
.muted
= i
->muted
;
1939 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1943 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1944 pa_usec_t
*r
= userdata
;
1946 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1947 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1952 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1954 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1955 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1959 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1960 pa_sink_input
*ssync
;
1962 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1964 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1965 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1967 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1968 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1973 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1974 pa_usec_t
*usec
= userdata
;
1976 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1980 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1981 pa_usec_t
*r
= userdata
;
1983 *r
= i
->thread_info
.requested_sink_latency
;
1988 return -PA_ERR_NOTIMPLEMENTED
;
1991 /* Called from main thread */
1992 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1993 pa_sink_input_assert_ref(i
);
1994 pa_assert_ctl_context();
1996 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1997 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
2002 /* Called from IO context */
2003 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
2004 pa_sink_input_assert_ref(i
);
2005 pa_sink_input_assert_io_context(i
);
2007 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
2008 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
2013 /* Called from IO context */
2014 void pa_sink_input_request_rewind(
2016 size_t nbytes
/* in our sample spec */,
2019 pa_bool_t dont_rewind_render
) {
2023 /* If 'rewrite' is TRUE the sink is rewound as far as requested
2024 * and possible and the exact value of this is passed back the
2025 * implementor via process_rewind(). If 'flush' is also TRUE all
2026 * already rendered data is also dropped.
2028 * If 'rewrite' is FALSE the sink is rewound as far as requested
2029 * and possible and the already rendered data is dropped so that
2030 * in the next iteration we read new data from the
2031 * implementor. This implies 'flush' is TRUE. If
2032 * dont_rewind_render is TRUE then the render memblockq is not
2035 /* nbytes = 0 means maximum rewind request */
2037 pa_sink_input_assert_ref(i
);
2038 pa_sink_input_assert_io_context(i
);
2039 pa_assert(rewrite
|| flush
);
2040 pa_assert(!dont_rewind_render
|| !rewrite
);
2042 /* We don't take rewind requests while we are corked */
2043 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
2046 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
2048 #ifdef SINK_INPUT_DEBUG
2049 pa_log_debug("request rewrite %zu", nbytes
);
2052 /* Calculate how much we can rewind locally without having to
2055 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
2059 /* Check if rewinding for the maximum is requested, and if so, fix up */
2062 /* Calculate maximum number of bytes that could be rewound in theory */
2063 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
2065 /* Transform from sink domain */
2066 if (i
->thread_info
.resampler
)
2067 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
2070 /* Remember how much we actually want to rewrite */
2071 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
2073 /* Make sure to not overwrite over underruns */
2074 if (nbytes
> i
->thread_info
.playing_for
)
2075 nbytes
= (size_t) i
->thread_info
.playing_for
;
2077 i
->thread_info
.rewrite_nbytes
= nbytes
;
2079 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
2082 i
->thread_info
.rewrite_flush
=
2083 i
->thread_info
.rewrite_flush
|| flush
;
2085 i
->thread_info
.dont_rewind_render
=
2086 i
->thread_info
.dont_rewind_render
||
2089 /* nbytes is -1 if some earlier rewind request had rewrite == false. */
2090 if (nbytes
!= (size_t) -1) {
2092 /* Transform to sink domain */
2093 if (i
->thread_info
.resampler
)
2094 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
2097 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
2099 /* This call will make sure process_rewind() is called later */
2100 pa_sink_request_rewind(i
->sink
, 0);
2104 /* Called from main context */
2105 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
2106 pa_sink_input_assert_ref(i
);
2107 pa_assert_ctl_context();
2110 /* FIXME: Shouldn't access resampler object from main context! */
2112 pa_silence_memchunk_get(
2113 &i
->core
->silence_cache
,
2117 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
2122 /* Called from main context */
2123 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
2124 pa_proplist
*pl
= NULL
;
2125 pa_sink_input_send_event_hook_data hook_data
;
2127 pa_sink_input_assert_ref(i
);
2128 pa_assert_ctl_context();
2135 data
= pl
= pa_proplist_new();
2137 hook_data
.sink_input
= i
;
2138 hook_data
.data
= data
;
2139 hook_data
.event
= event
;
2141 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
2144 i
->send_event(i
, event
, data
);
2148 pa_proplist_free(pl
);
2151 /* Called from main context */
2152 /* Updates the sink input's resampler with whatever the current sink requires
2153 * -- useful when the underlying sink's rate might have changed */
2154 int pa_sink_input_update_rate(pa_sink_input
*i
) {
2155 pa_resampler
*new_resampler
;
2156 char *memblockq_name
;
2158 pa_sink_input_assert_ref(i
);
2159 pa_assert_ctl_context();
2161 if (i
->thread_info
.resampler
&&
2162 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &i
->sink
->sample_spec
) &&
2163 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &i
->sink
->channel_map
))
2165 new_resampler
= i
->thread_info
.resampler
;
2167 else if (!pa_sink_input_is_passthrough(i
) &&
2168 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
2169 !pa_sample_spec_equal(&i
->sample_spec
, &i
->sink
->sample_spec
) ||
2170 !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
))) {
2172 new_resampler
= pa_resampler_new(i
->core
->mempool
,
2173 &i
->sample_spec
, &i
->channel_map
,
2174 &i
->sink
->sample_spec
, &i
->sink
->channel_map
,
2175 i
->requested_resample_method
,
2176 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
2177 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
2178 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0));
2180 if (!new_resampler
) {
2181 pa_log_warn("Unsupported resampling operation.");
2182 return -PA_ERR_NOTSUPPORTED
;
2185 new_resampler
= NULL
;
2187 if (new_resampler
== i
->thread_info
.resampler
)
2190 if (i
->thread_info
.resampler
)
2191 pa_resampler_free(i
->thread_info
.resampler
);
2193 i
->thread_info
.resampler
= new_resampler
;
2195 pa_memblockq_free(i
->thread_info
.render_memblockq
);
2197 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
2198 i
->thread_info
.render_memblockq
= pa_memblockq_new(
2201 MEMBLOCKQ_MAXLENGTH
,
2203 &i
->sink
->sample_spec
,
2208 pa_xfree(memblockq_name
);
2210 i
->actual_resample_method
= new_resampler
? pa_resampler_get_method(new_resampler
) : PA_RESAMPLER_INVALID
;
2212 pa_log_debug("Updated resampler for sink input %d", i
->index
);