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/sample-util.h>
36 #include <pulsecore/core-subscribe.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/play-memblockq.h>
39 #include <pulsecore/namereg.h>
40 #include <pulsecore/core-util.h>
42 #include "sink-input.h"
44 /* #define 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 static void sink_input_free(pa_object
*o
);
52 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
54 static int check_passthrough_connection(pa_bool_t passthrough
, pa_sink
*dest
) {
55 if (pa_sink_is_passthrough(dest
)) {
56 pa_log_warn("Sink is already connected to PASSTHROUGH input");
60 /* If current input(s) exist, check new input is not PASSTHROUGH */
61 if (pa_idxset_size(dest
->inputs
) > 0 && passthrough
) {
62 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
69 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
73 data
->resample_method
= PA_RESAMPLER_INVALID
;
74 data
->proplist
= pa_proplist_new();
75 data
->volume_writable
= TRUE
;
80 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
83 if ((data
->sample_spec_is_set
= !!spec
))
84 data
->sample_spec
= *spec
;
87 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
90 if ((data
->channel_map_is_set
= !!map
))
91 data
->channel_map
= *map
;
94 pa_bool_t
pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data
*data
) {
97 if (PA_LIKELY(data
->format
) && PA_UNLIKELY(!pa_format_info_is_pcm(data
->format
)))
100 if (PA_UNLIKELY(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
106 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
108 pa_assert(data
->volume_writable
);
110 if ((data
->volume_is_set
= !!volume
))
111 data
->volume
= *volume
;
114 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
116 pa_assert(volume_factor
);
118 if (data
->volume_factor_is_set
)
119 pa_sw_cvolume_multiply(&data
->volume_factor
, &data
->volume_factor
, volume_factor
);
121 data
->volume_factor_is_set
= TRUE
;
122 data
->volume_factor
= *volume_factor
;
126 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
128 pa_assert(volume_factor
);
130 if (data
->volume_factor_sink_is_set
)
131 pa_sw_cvolume_multiply(&data
->volume_factor_sink
, &data
->volume_factor_sink
, volume_factor
);
133 data
->volume_factor_sink_is_set
= TRUE
;
134 data
->volume_factor_sink
= *volume_factor
;
138 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
141 data
->muted_is_set
= TRUE
;
142 data
->muted
= !!mute
;
145 pa_bool_t
pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, pa_bool_t save
) {
146 pa_bool_t ret
= TRUE
;
147 pa_idxset
*formats
= NULL
;
152 if (!data
->req_formats
) {
153 /* We're not working with the extended API */
155 data
->save_sink
= save
;
157 /* Extended API: let's see if this sink supports the formats the client can provide */
158 formats
= pa_sink_check_formats(s
, data
->req_formats
);
160 if (formats
&& !pa_idxset_isempty(formats
)) {
161 /* Sink supports at least one of the requested formats */
163 data
->save_sink
= save
;
164 if (data
->nego_formats
)
165 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
166 data
->nego_formats
= formats
;
168 /* Sink doesn't support any of the formats requested by the client */
170 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
178 pa_bool_t
pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
182 if (data
->req_formats
)
183 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
185 data
->req_formats
= formats
;
188 /* Trigger format negotiation */
189 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
195 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
198 if (data
->req_formats
)
199 pa_idxset_free(data
->req_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
201 if (data
->nego_formats
)
202 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
205 pa_format_info_free(data
->format
);
207 pa_proplist_free(data
->proplist
);
210 /* Called from main context */
211 static void reset_callbacks(pa_sink_input
*i
) {
215 i
->process_rewind
= NULL
;
216 i
->update_max_rewind
= NULL
;
217 i
->update_max_request
= NULL
;
218 i
->update_sink_requested_latency
= NULL
;
219 i
->update_sink_latency_range
= NULL
;
220 i
->update_sink_fixed_latency
= NULL
;
224 i
->suspend_within_thread
= NULL
;
227 i
->get_latency
= NULL
;
228 i
->state_change
= NULL
;
229 i
->may_move_to
= NULL
;
230 i
->send_event
= NULL
;
231 i
->volume_changed
= NULL
;
232 i
->mute_changed
= NULL
;
235 /* Called from main context */
236 int pa_sink_input_new(
239 pa_sink_input_new_data
*data
) {
242 pa_resampler
*resampler
= NULL
;
243 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
244 pa_channel_map original_cm
;
247 char *memblockq_name
;
254 pa_assert_ctl_context();
257 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
259 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
260 data
->volume_writable
= FALSE
;
262 if (!data
->req_formats
) {
263 /* From this point on, we want to work only with formats, and get back
264 * to using the sample spec and channel map after all decisions w.r.t.
265 * routing are complete. */
266 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
267 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
,
268 data
->channel_map_is_set
? &data
->channel_map
: NULL
);
269 pa_idxset_put(tmp
, f
, NULL
);
270 pa_sink_input_new_data_set_formats(data
, tmp
);
273 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
276 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
279 pa_sink
*sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
280 pa_return_val_if_fail(sink
, -PA_ERR_NOENTITY
);
281 pa_sink_input_new_data_set_sink(data
, sink
, FALSE
);
283 /* Routing's done, we have a sink. Now let's fix the format and set up the
286 /* If something didn't pick a format for us, pick the top-most format since
287 * we assume this is sorted in priority order */
288 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
289 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
291 pa_return_val_if_fail(data
->format
, -PA_ERR_NOTSUPPORTED
);
293 /* Now populate the sample spec and format according to the final
294 * format that we've negotiated */
295 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
) == 0, -PA_ERR_INVALID
);
296 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
297 if (pa_format_info_is_pcm(data
->format
) && pa_channel_map_valid(&map
))
298 pa_sink_input_new_data_set_channel_map(data
, &map
);
300 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
301 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
);
303 r
= check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data
), data
->sink
);
307 if (!data
->sample_spec_is_set
)
308 data
->sample_spec
= data
->sink
->sample_spec
;
310 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
312 if (!data
->channel_map_is_set
) {
313 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
314 data
->channel_map
= data
->sink
->channel_map
;
316 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
319 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
321 /* Don't restore (or save) stream volume for passthrough streams and
322 * prevent attenuation/gain */
323 if (pa_sink_input_new_data_is_passthrough(data
)) {
324 data
->volume_is_set
= TRUE
;
325 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
326 data
->volume_is_absolute
= TRUE
;
327 data
->save_volume
= FALSE
;
330 if (!data
->volume_is_set
) {
331 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
332 data
->volume_is_absolute
= FALSE
;
333 data
->save_volume
= FALSE
;
336 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
338 if (!data
->volume_factor_is_set
)
339 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
341 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
343 if (!data
->volume_factor_sink_is_set
)
344 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
346 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
348 if (!data
->muted_is_set
)
351 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
352 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
354 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
355 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
357 original_cm
= data
->channel_map
;
359 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
360 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
361 data
->channel_map
= data
->sink
->channel_map
;
364 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
365 pa_assert(pa_channel_map_valid(&data
->channel_map
));
367 if (!(data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
368 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
)) {
369 /* try to change sink rate. This is done before the FIXATE hook since
370 module-suspend-on-idle can resume a sink */
372 pa_log_info("Trying to change sample rate");
373 if (pa_sink_update_rate(data
->sink
, data
->sample_spec
.rate
, pa_sink_input_new_data_is_passthrough(data
)) == TRUE
)
374 pa_log_info("Rate changed to %u Hz",
375 data
->sink
->sample_spec
.rate
);
377 pa_log_info("Resampling enabled to %u Hz", data
->sink
->sample_spec
.rate
);
380 /* Due to the fixing of the sample spec the volume might not match anymore */
381 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
383 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
384 data
->resample_method
= core
->resample_method
;
386 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
388 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
391 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
392 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
393 pa_log_warn("Failed to create sink input: sink is suspended.");
394 return -PA_ERR_BADSTATE
;
397 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
398 pa_log_warn("Failed to create sink input: too many inputs per sink.");
399 return -PA_ERR_TOOLARGE
;
402 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
403 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
404 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
406 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
407 if (!pa_sink_input_new_data_is_passthrough(data
)) /* no resampler for passthrough content */
408 if (!(resampler
= pa_resampler_new(
410 &data
->sample_spec
, &data
->channel_map
,
411 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
412 data
->resample_method
,
413 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
414 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
415 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
416 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
417 pa_log_warn("Unsupported resampling operation.");
418 return -PA_ERR_NOTSUPPORTED
;
422 i
= pa_msgobject_new(pa_sink_input
);
423 i
->parent
.parent
.free
= sink_input_free
;
424 i
->parent
.process_msg
= pa_sink_input_process_msg
;
427 i
->state
= PA_SINK_INPUT_INIT
;
428 i
->flags
= data
->flags
;
429 i
->proplist
= pa_proplist_copy(data
->proplist
);
430 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
431 i
->module
= data
->module
;
432 i
->sink
= data
->sink
;
433 i
->origin_sink
= data
->origin_sink
;
434 i
->client
= data
->client
;
436 i
->requested_resample_method
= data
->resample_method
;
437 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
438 i
->sample_spec
= data
->sample_spec
;
439 i
->channel_map
= data
->channel_map
;
440 i
->format
= pa_format_info_copy(data
->format
);
442 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
445 /* When the 'absolute' bool is not set then we'll treat the volume
446 * as relative to the sink volume even in flat volume mode */
447 remapped
= data
->sink
->reference_volume
;
448 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
449 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
451 i
->volume
= data
->volume
;
453 i
->volume_factor
= data
->volume_factor
;
454 i
->volume_factor_sink
= data
->volume_factor_sink
;
455 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
456 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
457 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
458 i
->volume_writable
= data
->volume_writable
;
459 i
->save_volume
= data
->save_volume
;
460 i
->save_sink
= data
->save_sink
;
461 i
->save_muted
= data
->save_muted
;
463 i
->muted
= data
->muted
;
465 if (data
->sync_base
) {
466 i
->sync_next
= data
->sync_base
->sync_next
;
467 i
->sync_prev
= data
->sync_base
;
469 if (data
->sync_base
->sync_next
)
470 data
->sync_base
->sync_next
->sync_prev
= i
;
471 data
->sync_base
->sync_next
= i
;
473 i
->sync_next
= i
->sync_prev
= NULL
;
475 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
480 i
->thread_info
.state
= i
->state
;
481 i
->thread_info
.attached
= FALSE
;
482 pa_atomic_store(&i
->thread_info
.drained
, 1);
483 i
->thread_info
.sample_spec
= i
->sample_spec
;
484 i
->thread_info
.resampler
= resampler
;
485 i
->thread_info
.soft_volume
= i
->soft_volume
;
486 i
->thread_info
.muted
= i
->muted
;
487 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
488 i
->thread_info
.rewrite_nbytes
= 0;
489 i
->thread_info
.rewrite_flush
= FALSE
;
490 i
->thread_info
.dont_rewind_render
= FALSE
;
491 i
->thread_info
.underrun_for
= (uint64_t) -1;
492 i
->thread_info
.playing_for
= 0;
493 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
495 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
496 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
499 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
501 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
502 i
->thread_info
.render_memblockq
= pa_memblockq_new(
507 &i
->sink
->sample_spec
,
512 pa_xfree(memblockq_name
);
514 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
515 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
517 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
519 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
520 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
524 /* Don't forget to call pa_sink_input_put! */
530 /* Called from main context */
531 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
533 pa_assert_ctl_context();
538 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
539 pa_assert_se(i
->sink
->n_corked
-- >= 1);
540 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
544 /* Called from main context */
545 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
546 pa_sink_input
*ssync
;
548 pa_assert_ctl_context();
550 if (state
== PA_SINK_INPUT_DRAINED
)
551 state
= PA_SINK_INPUT_RUNNING
;
553 if (i
->state
== state
)
556 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
&& pa_sink_used_by(i
->sink
) == 0) {
557 /* We were uncorked and the sink was not playing anything -- let's try
558 * to update the sample rate to avoid resampling */
559 pa_sink_update_rate(i
->sink
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
));
562 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);
564 update_n_corked(i
, state
);
567 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
568 update_n_corked(ssync
, state
);
569 ssync
->state
= state
;
571 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
572 update_n_corked(ssync
, state
);
573 ssync
->state
= state
;
576 if (state
!= PA_SINK_INPUT_UNLINKED
) {
577 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
579 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
580 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
582 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
583 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
585 if (PA_SINK_INPUT_IS_LINKED(state
))
586 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
589 pa_sink_update_status(i
->sink
);
592 /* Called from main context */
593 void pa_sink_input_unlink(pa_sink_input
*i
) {
595 pa_source_output
*o
, *p
= NULL
;
598 pa_assert_ctl_context();
600 /* See pa_sink_unlink() for a couple of comments how this function
603 pa_sink_input_ref(i
);
605 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
608 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
611 i
->sync_prev
->sync_next
= i
->sync_next
;
613 i
->sync_next
->sync_prev
= i
->sync_prev
;
615 i
->sync_prev
= i
->sync_next
= NULL
;
617 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
620 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
621 pa_sink_input_unref(i
);
624 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
626 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
628 pa_source_output_kill(o
);
632 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
633 i
->state
= PA_SINK_INPUT_UNLINKED
;
635 if (linked
&& i
->sink
) {
636 if (pa_sink_input_is_passthrough(i
))
637 pa_sink_leave_passthrough(i
->sink
);
639 /* We might need to update the sink's volume if we are in flat volume mode. */
640 if (pa_sink_flat_volume_enabled(i
->sink
))
641 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
643 if (i
->sink
->asyncmsgq
)
644 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
650 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
651 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
655 if (PA_SINK_IS_LINKED(pa_sink_get_state(i
->sink
)))
656 pa_sink_update_status(i
->sink
);
661 pa_core_maybe_vacuum(i
->core
);
663 pa_sink_input_unref(i
);
666 /* Called from main context */
667 static void sink_input_free(pa_object
*o
) {
668 pa_sink_input
* i
= PA_SINK_INPUT(o
);
671 pa_assert_ctl_context();
672 pa_assert(pa_sink_input_refcnt(i
) == 0);
674 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
675 pa_sink_input_unlink(i
);
677 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
679 /* Side note: this function must be able to destruct properly any
680 * kind of sink input in any state, even those which are
681 * "half-moved" or are connected to sinks that have no asyncmsgq
682 * and are hence half-destructed themselves! */
684 if (i
->thread_info
.render_memblockq
)
685 pa_memblockq_free(i
->thread_info
.render_memblockq
);
687 if (i
->thread_info
.resampler
)
688 pa_resampler_free(i
->thread_info
.resampler
);
691 pa_format_info_free(i
->format
);
694 pa_proplist_free(i
->proplist
);
696 if (i
->direct_outputs
)
697 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
699 if (i
->thread_info
.direct_outputs
)
700 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
706 /* Called from main context */
707 void pa_sink_input_put(pa_sink_input
*i
) {
708 pa_sink_input_state_t state
;
710 pa_sink_input_assert_ref(i
);
711 pa_assert_ctl_context();
713 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
715 /* The following fields must be initialized properly */
717 pa_assert(i
->process_rewind
);
720 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
722 update_n_corked(i
, state
);
725 /* We might need to update the sink's volume if we are in flat volume mode. */
726 if (pa_sink_flat_volume_enabled(i
->sink
))
727 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
729 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
730 pa_assert(pa_cvolume_is_norm(&i
->volume
));
731 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
734 set_real_ratio(i
, &i
->volume
);
737 if (pa_sink_input_is_passthrough(i
))
738 pa_sink_enter_passthrough(i
->sink
);
740 i
->thread_info
.soft_volume
= i
->soft_volume
;
741 i
->thread_info
.muted
= i
->muted
;
743 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
745 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
746 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
748 pa_sink_update_status(i
->sink
);
751 /* Called from main context */
752 void pa_sink_input_kill(pa_sink_input
*i
) {
753 pa_sink_input_assert_ref(i
);
754 pa_assert_ctl_context();
755 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
760 /* Called from main context */
761 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
762 pa_usec_t r
[2] = { 0, 0 };
764 pa_sink_input_assert_ref(i
);
765 pa_assert_ctl_context();
766 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
768 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
771 r
[0] += i
->get_latency(i
);
774 *sink_latency
= r
[1];
779 /* Called from thread context */
780 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
781 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
782 pa_bool_t volume_is_norm
;
783 size_t block_size_max_sink
, block_size_max_sink_input
;
786 pa_sink_input_assert_ref(i
);
787 pa_sink_input_assert_io_context(i
);
788 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
789 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
793 #ifdef SINK_INPUT_DEBUG
794 pa_log_debug("peek");
797 block_size_max_sink_input
= i
->thread_info
.resampler
?
798 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
799 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
801 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
803 /* Default buffer size */
805 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
807 if (slength
> block_size_max_sink
)
808 slength
= block_size_max_sink
;
810 if (i
->thread_info
.resampler
) {
811 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
814 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
818 if (ilength
> block_size_max_sink_input
)
819 ilength
= block_size_max_sink_input
;
821 /* If the channel maps of the sink and this stream differ, we need
822 * to adjust the volume *before* we resample. Otherwise we can do
823 * it after and leave it for the sink code */
825 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
826 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
827 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
829 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
832 /* There's nothing in our render queue. We need to fill it up
833 * with data from the implementor. */
835 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
836 i
->pop(i
, ilength
, &tchunk
) < 0) {
838 /* OK, we're corked or the implementor didn't give us any
839 * data, so let's just hand out silence */
840 pa_atomic_store(&i
->thread_info
.drained
, 1);
842 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
843 i
->thread_info
.playing_for
= 0;
844 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
845 i
->thread_info
.underrun_for
+= ilength
;
849 pa_atomic_store(&i
->thread_info
.drained
, 0);
851 pa_assert(tchunk
.length
> 0);
852 pa_assert(tchunk
.memblock
);
854 i
->thread_info
.underrun_for
= 0;
855 i
->thread_info
.playing_for
+= tchunk
.length
;
857 while (tchunk
.length
> 0) {
859 pa_bool_t nvfs
= need_volume_factor_sink
;
862 pa_memblock_ref(wchunk
.memblock
);
864 if (wchunk
.length
> block_size_max_sink_input
)
865 wchunk
.length
= block_size_max_sink_input
;
867 /* It might be necessary to adjust the volume here */
868 if (do_volume_adj_here
&& !volume_is_norm
) {
869 pa_memchunk_make_writable(&wchunk
, 0);
871 if (i
->thread_info
.muted
) {
872 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
875 } else if (!i
->thread_info
.resampler
&& nvfs
) {
878 /* If we don't need a resampler we can merge the
879 * post and the pre volume adjustment into one */
881 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
882 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
886 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
889 if (!i
->thread_info
.resampler
) {
892 pa_memchunk_make_writable(&wchunk
, 0);
893 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
896 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
899 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
901 #ifdef SINK_INPUT_DEBUG
902 pa_log_debug("pushing %lu", (unsigned long) rchunk
.length
);
905 if (rchunk
.memblock
) {
908 pa_memchunk_make_writable(&rchunk
, 0);
909 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
912 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
913 pa_memblock_unref(rchunk
.memblock
);
917 pa_memblock_unref(wchunk
.memblock
);
919 tchunk
.index
+= wchunk
.length
;
920 tchunk
.length
-= wchunk
.length
;
923 pa_memblock_unref(tchunk
.memblock
);
926 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
928 pa_assert(chunk
->length
> 0);
929 pa_assert(chunk
->memblock
);
931 #ifdef SINK_INPUT_DEBUG
932 pa_log_debug("peeking %lu", (unsigned long) chunk
->length
);
935 if (chunk
->length
> block_size_max_sink
)
936 chunk
->length
= block_size_max_sink
;
938 /* Let's see if we had to apply the volume adjustment ourselves,
939 * or if this can be done by the sink for us */
941 if (do_volume_adj_here
)
942 /* We had different channel maps, so we already did the adjustment */
943 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
944 else if (i
->thread_info
.muted
)
945 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
946 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
948 *volume
= i
->thread_info
.soft_volume
;
951 /* Called from thread context */
952 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
954 pa_sink_input_assert_ref(i
);
955 pa_sink_input_assert_io_context(i
);
956 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
957 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
958 pa_assert(nbytes
> 0);
960 #ifdef SINK_INPUT_DEBUG
961 pa_log_debug("dropping %lu", (unsigned long) nbytes
);
964 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
967 /* Called from thread context */
968 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
970 pa_bool_t called
= FALSE
;
972 pa_sink_input_assert_ref(i
);
973 pa_sink_input_assert_io_context(i
);
974 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
975 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
977 #ifdef SINK_INPUT_DEBUG
978 pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes
, (unsigned long) i
->thread_info
.rewrite_nbytes
);
981 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
983 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
984 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
985 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
988 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
990 /* We were asked to drop all buffered data, and rerequest new
991 * data from implementor the next time push() is called */
993 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, TRUE
);
995 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
996 size_t max_rewrite
, amount
;
998 /* Calculate how much make sense to rewrite at most */
999 max_rewrite
= nbytes
+ lbq
;
1001 /* Transform into local domain */
1002 if (i
->thread_info
.resampler
)
1003 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
1005 /* Calculate how much of the rewinded data should actually be rewritten */
1006 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
1009 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
1011 /* Tell the implementor */
1012 if (i
->process_rewind
)
1013 i
->process_rewind(i
, amount
);
1016 /* Convert back to to sink domain */
1017 if (i
->thread_info
.resampler
)
1018 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
1021 /* Ok, now update the write pointer */
1022 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
1024 if (i
->thread_info
.rewrite_flush
)
1025 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
1027 /* And reset the resampler */
1028 if (i
->thread_info
.resampler
)
1029 pa_resampler_reset(i
->thread_info
.resampler
);
1034 if (i
->process_rewind
)
1035 i
->process_rewind(i
, 0);
1037 i
->thread_info
.rewrite_nbytes
= 0;
1038 i
->thread_info
.rewrite_flush
= FALSE
;
1039 i
->thread_info
.dont_rewind_render
= FALSE
;
1042 /* Called from thread context */
1043 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
1044 pa_sink_input_assert_ref(i
);
1045 pa_sink_input_assert_io_context(i
);
1047 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1050 /* Called from thread context */
1051 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1052 pa_sink_input_assert_ref(i
);
1053 pa_sink_input_assert_io_context(i
);
1055 /* We're not verifying the status here, to allow this to be called
1056 * in the state change handler between _INIT and _RUNNING */
1058 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1061 /* Called from thread context */
1062 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1063 pa_sink_input_assert_ref(i
);
1064 pa_sink_input_assert_io_context(i
);
1065 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1066 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1068 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1070 if (i
->update_max_rewind
)
1071 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1074 /* Called from thread context */
1075 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1076 pa_sink_input_assert_ref(i
);
1077 pa_sink_input_assert_io_context(i
);
1078 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1079 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1081 if (i
->update_max_request
)
1082 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1085 /* Called from thread context */
1086 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1087 pa_sink_input_assert_ref(i
);
1088 pa_sink_input_assert_io_context(i
);
1090 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1091 usec
= i
->sink
->thread_info
.fixed_latency
;
1093 if (usec
!= (pa_usec_t
) -1)
1094 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1096 i
->thread_info
.requested_sink_latency
= usec
;
1097 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
1102 /* Called from main context */
1103 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1104 pa_sink_input_assert_ref(i
);
1105 pa_assert_ctl_context();
1107 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1108 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1112 /* If this sink input is not realized yet or we are being moved,
1113 * we have to touch the thread info data directly */
1116 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1117 usec
= pa_sink_get_fixed_latency(i
->sink
);
1119 if (usec
!= (pa_usec_t
) -1) {
1120 pa_usec_t min_latency
, max_latency
;
1121 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1122 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1126 i
->thread_info
.requested_sink_latency
= usec
;
1131 /* Called from main context */
1132 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1133 pa_sink_input_assert_ref(i
);
1134 pa_assert_ctl_context();
1136 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1138 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1142 /* If this sink input is not realized yet or we are being moved,
1143 * we have to touch the thread info data directly */
1145 return i
->thread_info
.requested_sink_latency
;
1148 /* Called from main context */
1149 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
1152 pa_sink_input_assert_ref(i
);
1153 pa_assert_ctl_context();
1154 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1156 pa_assert(pa_cvolume_valid(volume
));
1157 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1158 pa_assert(i
->volume_writable
);
1160 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1161 v
= i
->sink
->reference_volume
;
1162 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1164 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1165 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1167 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1169 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1171 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1175 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1176 i
->save_volume
= i
->save_volume
|| save
;
1180 i
->volume
= *volume
;
1181 i
->save_volume
= save
;
1183 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1184 /* We are in flat volume mode, so let's update all sink input
1185 * volumes and update the flat volume of the sink */
1187 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1190 /* OK, we are in normal volume mode. The volume only affects
1192 set_real_ratio(i
, volume
);
1194 /* Copy the new soft_volume to the thread_info struct */
1195 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1198 /* The volume changed, let's tell people so */
1199 if (i
->volume_changed
)
1200 i
->volume_changed(i
);
1202 /* The virtual volume changed, let's tell people so */
1203 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1206 /* Called from main context */
1207 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1208 pa_sink_input_assert_ref(i
);
1209 pa_assert_ctl_context();
1210 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1211 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1213 /* This basically calculates:
1215 * i->real_ratio := v
1216 * i->soft_volume := i->real_ratio * i->volume_factor */
1221 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1223 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1224 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1227 /* Called from main or I/O context */
1228 pa_bool_t
pa_sink_input_is_passthrough(pa_sink_input
*i
) {
1229 pa_sink_input_assert_ref(i
);
1231 if (PA_UNLIKELY(!pa_format_info_is_pcm(i
->format
)))
1234 if (PA_UNLIKELY(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
1240 /* Called from main context */
1241 pa_bool_t
pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1242 pa_sink_input_assert_ref(i
);
1243 pa_assert_ctl_context();
1245 return !pa_sink_input_is_passthrough(i
);
1248 /* Called from main context */
1249 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1250 pa_sink_input_assert_ref(i
);
1251 pa_assert_ctl_context();
1252 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1253 pa_assert(pa_sink_input_is_volume_readable(i
));
1255 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1256 *volume
= i
->volume
;
1258 *volume
= i
->reference_ratio
;
1263 /* Called from main context */
1264 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1265 pa_sink_input_assert_ref(i
);
1266 pa_assert_ctl_context();
1267 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1269 if (!i
->muted
== !mute
) {
1270 i
->save_muted
= i
->save_muted
|| mute
;
1275 i
->save_muted
= save
;
1277 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1279 /* The mute status changed, let's tell people so */
1280 if (i
->mute_changed
)
1283 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1286 /* Called from main context */
1287 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1288 pa_sink_input_assert_ref(i
);
1289 pa_assert_ctl_context();
1290 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1295 /* Called from main thread */
1296 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1297 pa_sink_input_assert_ref(i
);
1298 pa_assert_ctl_context();
1301 pa_proplist_update(i
->proplist
, mode
, p
);
1303 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1304 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1305 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1309 /* Called from main context */
1310 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1311 pa_sink_input_assert_ref(i
);
1312 pa_assert_ctl_context();
1313 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1315 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1318 /* Called from main context */
1319 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1320 pa_sink_input_assert_ref(i
);
1321 pa_assert_ctl_context();
1322 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1323 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1325 if (i
->sample_spec
.rate
== rate
)
1328 i
->sample_spec
.rate
= rate
;
1330 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1332 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1336 /* Called from main context */
1337 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1339 pa_sink_input_assert_ref(i
);
1340 pa_assert_ctl_context();
1342 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1345 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1347 if (old
&& name
&& pa_streq(old
, name
))
1351 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1353 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1355 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1356 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1357 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1361 /* Called from main context */
1362 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1363 pa_sink_input_assert_ref(i
);
1364 pa_assert_ctl_context();
1366 return i
->actual_resample_method
;
1369 /* Called from main context */
1370 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1371 pa_sink_input_assert_ref(i
);
1372 pa_assert_ctl_context();
1373 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1375 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1378 if (i
->sync_next
|| i
->sync_prev
) {
1379 pa_log_warn("Moving synchronized streams not supported.");
1386 /* Called from main context */
1387 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1388 pa_sink_input_assert_ref(i
);
1389 pa_assert_ctl_context();
1390 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1391 pa_sink_assert_ref(dest
);
1393 if (dest
== i
->sink
)
1396 if (!pa_sink_input_may_move(i
))
1399 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1400 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1404 if (check_passthrough_connection(pa_sink_input_is_passthrough(i
), dest
) < 0)
1408 if (!i
->may_move_to(i
, dest
))
1414 /* Called from main context */
1415 int pa_sink_input_start_move(pa_sink_input
*i
) {
1416 pa_source_output
*o
, *p
= NULL
;
1419 pa_sink_input_assert_ref(i
);
1420 pa_assert_ctl_context();
1421 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1424 if (!pa_sink_input_may_move(i
))
1425 return -PA_ERR_NOTSUPPORTED
;
1427 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1430 /* Kill directly connected outputs */
1431 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1433 pa_source_output_kill(o
);
1436 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1438 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1440 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1441 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1443 if (pa_sink_input_is_passthrough(i
))
1444 pa_sink_leave_passthrough(i
->sink
);
1446 if (pa_sink_flat_volume_enabled(i
->sink
))
1447 /* We might need to update the sink's volume if we are in flat
1449 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1451 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1453 pa_sink_update_status(i
->sink
);
1454 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1457 pa_sink_input_unref(i
);
1462 /* Called from main context. If i has an origin sink that uses volume sharing,
1463 * then also the origin sink and all streams connected to it need to update
1464 * their volume - this function does all that by using recursion. */
1465 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1466 pa_cvolume old_volume
;
1470 pa_assert(i
->sink
); /* The destination sink should already be set. */
1472 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1473 pa_sink
*root_sink
= pa_sink_get_master(i
->sink
);
1474 pa_sink_input
*origin_sink_input
;
1477 if (PA_UNLIKELY(!root_sink
))
1480 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1481 /* Ok, so the origin sink uses volume sharing, and flat volume is
1482 * enabled. The volume will have to be updated as follows:
1484 * i->volume := i->sink->real_volume
1485 * (handled later by pa_sink_set_volume)
1486 * i->reference_ratio := i->volume / i->sink->reference_volume
1487 * (handled later by pa_sink_set_volume)
1488 * i->real_ratio stays unchanged
1489 * (streams whose origin sink uses volume sharing should
1490 * always have real_ratio of 0 dB)
1491 * i->soft_volume stays unchanged
1492 * (streams whose origin sink uses volume sharing should
1493 * always have volume_factor as soft_volume, so no change
1494 * should be needed) */
1496 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1497 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1499 /* Notifications will be sent by pa_sink_set_volume(). */
1502 /* Ok, so the origin sink uses volume sharing, and flat volume is
1503 * disabled. The volume will have to be updated as follows:
1506 * i->reference_ratio := 0 dB
1507 * i->real_ratio stays unchanged
1508 * (streams whose origin sink uses volume sharing should
1509 * always have real_ratio of 0 dB)
1510 * i->soft_volume stays unchanged
1511 * (streams whose origin sink uses volume sharing should
1512 * always have volume_factor as soft_volume, so no change
1513 * should be needed) */
1515 old_volume
= i
->volume
;
1516 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1517 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1518 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1519 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1521 /* Notify others about the changed sink input volume. */
1522 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1523 if (i
->volume_changed
)
1524 i
->volume_changed(i
);
1526 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1530 /* Additionally, the origin sink volume needs updating:
1532 * i->origin_sink->reference_volume := root_sink->reference_volume
1533 * i->origin_sink->real_volume := root_sink->real_volume
1534 * i->origin_sink->soft_volume stays unchanged
1535 * (sinks that use volume sharing should always have
1536 * soft_volume of 0 dB) */
1538 old_volume
= i
->origin_sink
->reference_volume
;
1540 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1541 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1543 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1544 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1546 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1548 /* Notify others about the changed sink volume. If you wonder whether
1549 * i->origin_sink->set_volume() should be called somewhere, that's not
1550 * the case, because sinks that use volume sharing shouldn't have any
1551 * internal volume that set_volume() would update. If you wonder
1552 * whether the thread_info variables should be synced, yes, they
1553 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1555 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1556 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1558 /* Recursively update origin sink inputs. */
1559 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1560 update_volume_due_to_moving(origin_sink_input
, dest
);
1563 old_volume
= i
->volume
;
1565 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1566 /* Ok, so this is a regular stream, and flat volume is enabled. The
1567 * volume will have to be updated as follows:
1569 * i->volume := i->reference_ratio * i->sink->reference_volume
1570 * i->reference_ratio stays unchanged
1571 * i->real_ratio := i->volume / i->sink->real_volume
1572 * (handled later by pa_sink_set_volume)
1573 * i->soft_volume := i->real_ratio * i->volume_factor
1574 * (handled later by pa_sink_set_volume) */
1576 i
->volume
= i
->sink
->reference_volume
;
1577 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1578 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1581 /* Ok, so this is a regular stream, and flat volume is disabled.
1582 * The volume will have to be updated as follows:
1584 * i->volume := i->reference_ratio
1585 * i->reference_ratio stays unchanged
1586 * i->real_ratio := i->reference_ratio
1587 * i->soft_volume := i->real_ratio * i->volume_factor */
1589 i
->volume
= i
->reference_ratio
;
1590 i
->real_ratio
= i
->reference_ratio
;
1591 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1594 /* Notify others about the changed sink input volume. */
1595 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1596 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1597 * and soft_volume are not updated yet. Let's hope that the
1598 * callback implementation doesn't care about those variables... */
1599 if (i
->volume_changed
)
1600 i
->volume_changed(i
);
1602 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1606 /* If i->sink == dest, then recursion has finished, and we can finally call
1607 * pa_sink_set_volume(), which will do the rest of the updates. */
1608 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1609 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1612 /* Called from main context */
1613 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1614 pa_sink_input_assert_ref(i
);
1615 pa_assert_ctl_context();
1616 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1617 pa_assert(!i
->sink
);
1618 pa_sink_assert_ref(dest
);
1620 if (!pa_sink_input_may_move_to(i
, dest
))
1621 return -PA_ERR_NOTSUPPORTED
;
1623 if (pa_sink_input_is_passthrough(i
) && !pa_sink_check_format(dest
, i
->format
)) {
1624 pa_proplist
*p
= pa_proplist_new();
1625 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1626 /* Tell the client what device we want to be on if it is going to
1628 pa_proplist_sets(p
, "device", dest
->name
);
1629 pa_sink_input_send_event(i
, PA_STREAM_EVENT_FORMAT_LOST
, p
);
1630 pa_proplist_free(p
);
1631 return -PA_ERR_NOTSUPPORTED
;
1634 if (!(i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) &&
1635 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
)) {
1636 /* try to change dest sink rate if possible without glitches.
1637 module-suspend-on-idle resumes destination sink with
1638 SINK_INPUT_MOVE_FINISH hook */
1640 pa_log_info("Trying to change sample rate");
1641 if (pa_sink_update_rate(dest
, i
->sample_spec
.rate
, pa_sink_input_is_passthrough(i
)) == TRUE
)
1642 pa_log_info("Rate changed to %u Hz",
1643 dest
->sample_spec
.rate
);
1645 pa_log_info("Resampling enabled to %u Hz",
1646 dest
->sample_spec
.rate
);
1653 i
->save_sink
= save
;
1654 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1656 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1658 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1659 i
->sink
->n_corked
++;
1661 pa_sink_input_update_rate(i
);
1663 pa_sink_update_status(dest
);
1665 update_volume_due_to_moving(i
, dest
);
1667 if (pa_sink_input_is_passthrough(i
))
1668 pa_sink_enter_passthrough(i
->sink
);
1670 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1672 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1674 /* Notify everyone */
1675 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1676 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1681 /* Called from main context */
1682 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1684 pa_sink_input_assert_ref(i
);
1685 pa_assert_ctl_context();
1686 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1687 pa_assert(!i
->sink
);
1689 /* Check if someone wants this sink input? */
1690 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1696 pa_sink_input_kill(i
);
1699 /* Called from main context */
1700 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1703 pa_sink_input_assert_ref(i
);
1704 pa_assert_ctl_context();
1705 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1707 pa_sink_assert_ref(dest
);
1709 if (dest
== i
->sink
)
1712 if (!pa_sink_input_may_move_to(i
, dest
))
1713 return -PA_ERR_NOTSUPPORTED
;
1715 pa_sink_input_ref(i
);
1717 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1718 pa_sink_input_unref(i
);
1722 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1723 pa_sink_input_fail_move(i
);
1724 pa_sink_input_unref(i
);
1728 pa_sink_input_unref(i
);
1733 /* Called from IO thread context */
1734 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1735 pa_bool_t corking
, uncorking
;
1737 pa_sink_input_assert_ref(i
);
1738 pa_sink_input_assert_io_context(i
);
1740 if (state
== i
->thread_info
.state
)
1743 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1744 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1745 pa_atomic_store(&i
->thread_info
.drained
, 1);
1747 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1748 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1750 if (i
->state_change
)
1751 i
->state_change(i
, state
);
1755 pa_log_debug("Requesting rewind due to corking");
1757 /* This will tell the implementing sink input driver to rewind
1758 * so that the unplayed already mixed data is not lost */
1759 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1761 /* Set the corked state *after* requesting rewind */
1762 i
->thread_info
.state
= state
;
1764 } else if (uncorking
) {
1766 pa_log_debug("Requesting rewind due to uncorking");
1768 i
->thread_info
.underrun_for
= (uint64_t) -1;
1769 i
->thread_info
.playing_for
= 0;
1771 /* Set the uncorked state *before* requesting rewind */
1772 i
->thread_info
.state
= state
;
1774 /* OK, we're being uncorked. Make sure we're not rewound when
1775 * the hw buffer is remixed and request a remix. */
1776 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1778 /* We may not be corking or uncorking, but we still need to set the state. */
1779 i
->thread_info
.state
= state
;
1782 /* Called from thread context, except when it is not. */
1783 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1784 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1785 pa_sink_input_assert_ref(i
);
1789 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1790 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1791 i
->thread_info
.soft_volume
= i
->soft_volume
;
1792 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1796 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1797 if (i
->thread_info
.muted
!= i
->muted
) {
1798 i
->thread_info
.muted
= i
->muted
;
1799 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1803 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1804 pa_usec_t
*r
= userdata
;
1806 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1807 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1812 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1814 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1815 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1819 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1820 pa_sink_input
*ssync
;
1822 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1824 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1825 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1827 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1828 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1833 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1834 pa_usec_t
*usec
= userdata
;
1836 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1840 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1841 pa_usec_t
*r
= userdata
;
1843 *r
= i
->thread_info
.requested_sink_latency
;
1848 return -PA_ERR_NOTIMPLEMENTED
;
1851 /* Called from main thread */
1852 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1853 pa_sink_input_assert_ref(i
);
1854 pa_assert_ctl_context();
1856 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1857 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1862 /* Called from IO context */
1863 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1864 pa_sink_input_assert_ref(i
);
1865 pa_sink_input_assert_io_context(i
);
1867 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1868 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1873 /* Called from IO context */
1874 void pa_sink_input_request_rewind(
1876 size_t nbytes
/* in our sample spec */,
1879 pa_bool_t dont_rewind_render
) {
1883 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1884 * and possible and the exact value of this is passed back the
1885 * implementor via process_rewind(). If 'flush' is also TRUE all
1886 * already rendered data is also dropped.
1888 * If 'rewrite' is FALSE the sink is rewound as far as requested
1889 * and possible and the already rendered data is dropped so that
1890 * in the next iteration we read new data from the
1891 * implementor. This implies 'flush' is TRUE. If
1892 * dont_rewind_render is TRUE then the render memblockq is not
1895 /* nbytes = 0 means maximum rewind request */
1897 pa_sink_input_assert_ref(i
);
1898 pa_sink_input_assert_io_context(i
);
1899 pa_assert(rewrite
|| flush
);
1900 pa_assert(!dont_rewind_render
|| !rewrite
);
1902 /* We don't take rewind requests while we are corked */
1903 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1906 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1908 #ifdef SINK_INPUT_DEBUG
1909 pa_log_debug("request rewrite %zu", nbytes
);
1912 /* Calculate how much we can rewind locally without having to
1915 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1919 /* Check if rewinding for the maximum is requested, and if so, fix up */
1922 /* Calculate maximum number of bytes that could be rewound in theory */
1923 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1925 /* Transform from sink domain */
1926 if (i
->thread_info
.resampler
)
1927 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1930 /* Remember how much we actually want to rewrite */
1931 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1933 /* Make sure to not overwrite over underruns */
1934 if (nbytes
> i
->thread_info
.playing_for
)
1935 nbytes
= (size_t) i
->thread_info
.playing_for
;
1937 i
->thread_info
.rewrite_nbytes
= nbytes
;
1939 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1942 i
->thread_info
.rewrite_flush
=
1943 i
->thread_info
.rewrite_flush
||
1944 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1946 i
->thread_info
.dont_rewind_render
=
1947 i
->thread_info
.dont_rewind_render
||
1950 if (nbytes
!= (size_t) -1) {
1952 /* Transform to sink domain */
1953 if (i
->thread_info
.resampler
)
1954 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1957 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1959 /* This call will make sure process_rewind() is called later */
1960 pa_sink_request_rewind(i
->sink
, 0);
1964 /* Called from main context */
1965 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1966 pa_sink_input_assert_ref(i
);
1967 pa_assert_ctl_context();
1970 /* FIXME: Shouldn't access resampler object from main context! */
1972 pa_silence_memchunk_get(
1973 &i
->core
->silence_cache
,
1977 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1982 /* Called from main context */
1983 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1984 pa_proplist
*pl
= NULL
;
1985 pa_sink_input_send_event_hook_data hook_data
;
1987 pa_sink_input_assert_ref(i
);
1988 pa_assert_ctl_context();
1995 data
= pl
= pa_proplist_new();
1997 hook_data
.sink_input
= i
;
1998 hook_data
.data
= data
;
1999 hook_data
.event
= event
;
2001 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
2004 i
->send_event(i
, event
, data
);
2008 pa_proplist_free(pl
);
2011 /* Called from main context */
2012 /* Updates the sink input's resampler with whatever the current sink requires
2013 * -- useful when the underlying sink's rate might have changed */
2014 int pa_sink_input_update_rate(pa_sink_input
*i
) {
2015 pa_resampler
*new_resampler
;
2016 char *memblockq_name
;
2018 pa_sink_input_assert_ref(i
);
2019 pa_assert_ctl_context();
2021 if (i
->thread_info
.resampler
&&
2022 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &i
->sink
->sample_spec
) &&
2023 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &i
->sink
->channel_map
))
2025 new_resampler
= i
->thread_info
.resampler
;
2027 else if (!pa_sink_input_is_passthrough(i
) &&
2028 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
2029 !pa_sample_spec_equal(&i
->sample_spec
, &i
->sink
->sample_spec
) ||
2030 !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
))) {
2032 new_resampler
= pa_resampler_new(i
->core
->mempool
,
2033 &i
->sample_spec
, &i
->channel_map
,
2034 &i
->sink
->sample_spec
, &i
->sink
->channel_map
,
2035 i
->requested_resample_method
,
2036 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
2037 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
2038 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0));
2040 if (!new_resampler
) {
2041 pa_log_warn("Unsupported resampling operation.");
2042 return -PA_ERR_NOTSUPPORTED
;
2045 new_resampler
= NULL
;
2047 if (new_resampler
== i
->thread_info
.resampler
)
2050 if (i
->thread_info
.resampler
)
2051 pa_resampler_free(i
->thread_info
.resampler
);
2053 i
->thread_info
.resampler
= new_resampler
;
2055 pa_memblockq_free(i
->thread_info
.render_memblockq
);
2057 memblockq_name
= pa_sprintf_malloc("sink input render_memblockq [%u]", i
->index
);
2058 i
->thread_info
.render_memblockq
= pa_memblockq_new(
2061 MEMBLOCKQ_MAXLENGTH
,
2063 &i
->sink
->sample_spec
,
2068 pa_xfree(memblockq_name
);
2070 i
->actual_resample_method
= new_resampler
? pa_resampler_get_method(new_resampler
) : PA_RESAMPLER_INVALID
;
2072 pa_log_debug("Updated resampler for sink input %d", i
->index
);