2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
34 #include <pulse/internal.h>
36 #include <pulsecore/sample-util.h>
37 #include <pulsecore/core-subscribe.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/play-memblockq.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-util.h>
43 #include "sink-input.h"
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input
, pa_msgobject
);
50 static void sink_input_free(pa_object
*o
);
51 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
53 static int check_passthrough_connection(pa_format_info
*format
, 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 && !pa_format_info_is_pcm(format
)) {
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 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
96 pa_assert(data
->volume_writable
);
98 if ((data
->volume_is_set
= !!volume
))
99 data
->volume
= *volume
;
102 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
104 pa_assert(volume_factor
);
106 if (data
->volume_factor_is_set
)
107 pa_sw_cvolume_multiply(&data
->volume_factor
, &data
->volume_factor
, volume_factor
);
109 data
->volume_factor_is_set
= TRUE
;
110 data
->volume_factor
= *volume_factor
;
114 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
116 pa_assert(volume_factor
);
118 if (data
->volume_factor_sink_is_set
)
119 pa_sw_cvolume_multiply(&data
->volume_factor_sink
, &data
->volume_factor_sink
, volume_factor
);
121 data
->volume_factor_sink_is_set
= TRUE
;
122 data
->volume_factor_sink
= *volume_factor
;
126 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
129 data
->muted_is_set
= TRUE
;
130 data
->muted
= !!mute
;
133 pa_bool_t
pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, pa_bool_t save
) {
134 pa_bool_t ret
= TRUE
;
135 pa_idxset
*formats
= NULL
;
140 if (!data
->req_formats
) {
141 /* We're not working with the extended API */
143 data
->save_sink
= save
;
145 /* Extended API: let's see if this sink supports the formats the client can provide */
146 formats
= pa_sink_check_formats(s
, data
->req_formats
);
148 if (formats
&& !pa_idxset_isempty(formats
)) {
149 /* Sink supports at least one of the requested formats */
151 data
->save_sink
= save
;
152 if (data
->nego_formats
)
153 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
154 data
->nego_formats
= formats
;
156 /* Sink doesn't support any of the formats requested by the client */
158 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
166 pa_bool_t
pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
170 if (data
->req_formats
)
171 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
173 data
->req_formats
= formats
;
176 /* Trigger format negotiation */
177 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
183 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
186 if (data
->req_formats
)
187 pa_idxset_free(data
->req_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
189 if (data
->nego_formats
)
190 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
193 pa_format_info_free(data
->format
);
195 pa_proplist_free(data
->proplist
);
198 /* Called from main context */
199 static void reset_callbacks(pa_sink_input
*i
) {
203 i
->process_rewind
= NULL
;
204 i
->update_max_rewind
= NULL
;
205 i
->update_max_request
= NULL
;
206 i
->update_sink_requested_latency
= NULL
;
207 i
->update_sink_latency_range
= NULL
;
208 i
->update_sink_fixed_latency
= NULL
;
212 i
->suspend_within_thread
= NULL
;
215 i
->get_latency
= NULL
;
216 i
->state_change
= NULL
;
217 i
->may_move_to
= NULL
;
218 i
->send_event
= NULL
;
219 i
->volume_changed
= NULL
;
220 i
->mute_changed
= NULL
;
223 /* Called from main context */
224 int pa_sink_input_new(
227 pa_sink_input_new_data
*data
) {
230 pa_resampler
*resampler
= NULL
;
231 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
232 pa_channel_map original_cm
;
241 pa_assert_ctl_context();
244 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
246 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
247 data
->volume_writable
= FALSE
;
249 if (!data
->req_formats
) {
250 /* From this point on, we want to work only with formats, and get back
251 * to using the sample spec and channel map after all decisions w.r.t.
252 * routing are complete. */
253 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
254 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
, &data
->channel_map
);
255 pa_idxset_put(tmp
, f
, NULL
);
256 pa_sink_input_new_data_set_formats(data
, tmp
);
259 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
262 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
265 pa_sink_input_new_data_set_sink(data
, pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
), FALSE
);
267 /* Routing's done, we have a sink. Now let's fix the format and set up the
270 /* If something didn't pick a format for us, pick the top-most format since
271 * we assume this is sorted in priority order */
272 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
273 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
275 pa_return_val_if_fail(data
->format
, -PA_ERR_NOTSUPPORTED
);
277 /* Now populate the sample spec and format according to the final
278 * format that we've negotiated */
279 if (PA_LIKELY(data
->format
->encoding
== PA_ENCODING_PCM
)) {
280 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
), -PA_ERR_INVALID
);
281 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
282 if (pa_channel_map_valid(&map
))
283 pa_sink_input_new_data_set_channel_map(data
, &map
);
285 pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data
->format
, &ss
), -PA_ERR_INVALID
);
286 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
287 /* XXX: this is redundant - we can just check the encoding */
288 data
->flags
|= PA_SINK_INPUT_PASSTHROUGH
;
291 pa_return_val_if_fail(data
->sink
, -PA_ERR_NOENTITY
);
292 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
293 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
);
295 r
= check_passthrough_connection(data
->format
, data
->sink
);
296 pa_return_val_if_fail(r
== PA_OK
, r
);
298 if (!data
->sample_spec_is_set
)
299 data
->sample_spec
= data
->sink
->sample_spec
;
301 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
303 if (!data
->channel_map_is_set
) {
304 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
305 data
->channel_map
= data
->sink
->channel_map
;
307 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
310 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
312 if (!data
->volume_is_set
) {
313 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
314 data
->volume_is_absolute
= FALSE
;
315 data
->save_volume
= FALSE
;
318 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
320 if (!data
->volume_factor_is_set
)
321 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
323 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
325 if (!data
->volume_factor_sink_is_set
)
326 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
328 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
330 if (!data
->muted_is_set
)
333 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
334 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
336 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
337 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
339 original_cm
= data
->channel_map
;
341 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
342 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
343 data
->channel_map
= data
->sink
->channel_map
;
346 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
347 pa_assert(pa_channel_map_valid(&data
->channel_map
));
349 /* Due to the fixing of the sample spec the volume might not match anymore */
350 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
352 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
353 data
->resample_method
= core
->resample_method
;
355 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
357 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
360 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
361 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
362 pa_log_warn("Failed to create sink input: sink is suspended.");
363 return -PA_ERR_BADSTATE
;
366 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
367 pa_log_warn("Failed to create sink input: too many inputs per sink.");
368 return -PA_ERR_TOOLARGE
;
371 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
372 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
373 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
375 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
376 if (!(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
)) /* no resampler for passthrough content */
377 if (!(resampler
= pa_resampler_new(
379 &data
->sample_spec
, &data
->channel_map
,
380 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
381 data
->resample_method
,
382 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
383 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
384 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
385 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
386 pa_log_warn("Unsupported resampling operation.");
387 return -PA_ERR_NOTSUPPORTED
;
391 i
= pa_msgobject_new(pa_sink_input
);
392 i
->parent
.parent
.free
= sink_input_free
;
393 i
->parent
.process_msg
= pa_sink_input_process_msg
;
396 i
->state
= PA_SINK_INPUT_INIT
;
397 i
->flags
= data
->flags
;
398 i
->proplist
= pa_proplist_copy(data
->proplist
);
399 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
400 i
->module
= data
->module
;
401 i
->sink
= data
->sink
;
402 i
->origin_sink
= data
->origin_sink
;
403 i
->client
= data
->client
;
405 i
->requested_resample_method
= data
->resample_method
;
406 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
407 i
->sample_spec
= data
->sample_spec
;
408 i
->channel_map
= data
->channel_map
;
409 i
->format
= pa_format_info_copy(data
->format
);
411 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
414 /* When the 'absolute' bool is not set then we'll treat the volume
415 * as relative to the sink volume even in flat volume mode */
416 remapped
= data
->sink
->reference_volume
;
417 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
418 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
420 i
->volume
= data
->volume
;
422 i
->volume_factor
= data
->volume_factor
;
423 i
->volume_factor_sink
= data
->volume_factor_sink
;
424 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
425 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
426 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
427 i
->volume_writable
= data
->volume_writable
;
428 i
->save_volume
= data
->save_volume
;
429 i
->save_sink
= data
->save_sink
;
430 i
->save_muted
= data
->save_muted
;
432 i
->muted
= data
->muted
;
434 if (data
->sync_base
) {
435 i
->sync_next
= data
->sync_base
->sync_next
;
436 i
->sync_prev
= data
->sync_base
;
438 if (data
->sync_base
->sync_next
)
439 data
->sync_base
->sync_next
->sync_prev
= i
;
440 data
->sync_base
->sync_next
= i
;
442 i
->sync_next
= i
->sync_prev
= NULL
;
444 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
449 i
->thread_info
.state
= i
->state
;
450 i
->thread_info
.attached
= FALSE
;
451 pa_atomic_store(&i
->thread_info
.drained
, 1);
452 i
->thread_info
.sample_spec
= i
->sample_spec
;
453 i
->thread_info
.resampler
= resampler
;
454 i
->thread_info
.soft_volume
= i
->soft_volume
;
455 i
->thread_info
.muted
= i
->muted
;
456 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
457 i
->thread_info
.rewrite_nbytes
= 0;
458 i
->thread_info
.rewrite_flush
= FALSE
;
459 i
->thread_info
.dont_rewind_render
= FALSE
;
460 i
->thread_info
.underrun_for
= (uint64_t) -1;
461 i
->thread_info
.playing_for
= 0;
462 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
464 i
->thread_info
.render_memblockq
= pa_memblockq_new(
468 pa_frame_size(&i
->sink
->sample_spec
),
474 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
475 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
478 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
480 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
481 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
483 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
485 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
486 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
490 /* Don't forget to call pa_sink_input_put! */
496 /* Called from main context */
497 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
499 pa_assert_ctl_context();
504 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
505 pa_assert_se(i
->sink
->n_corked
-- >= 1);
506 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
510 /* Called from main context */
511 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
512 pa_sink_input
*ssync
;
514 pa_assert_ctl_context();
516 if (state
== PA_SINK_INPUT_DRAINED
)
517 state
= PA_SINK_INPUT_RUNNING
;
519 if (i
->state
== state
)
522 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);
524 update_n_corked(i
, state
);
527 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
528 update_n_corked(ssync
, state
);
529 ssync
->state
= state
;
531 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
532 update_n_corked(ssync
, state
);
533 ssync
->state
= state
;
536 if (state
!= PA_SINK_INPUT_UNLINKED
) {
537 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
539 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
540 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
542 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
543 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
545 if (PA_SINK_INPUT_IS_LINKED(state
))
546 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
549 pa_sink_update_status(i
->sink
);
552 /* Called from main context */
553 void pa_sink_input_unlink(pa_sink_input
*i
) {
555 pa_source_output
*o
, *p
= NULL
;
558 pa_assert_ctl_context();
560 /* See pa_sink_unlink() for a couple of comments how this function
563 pa_sink_input_ref(i
);
565 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
568 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
571 i
->sync_prev
->sync_next
= i
->sync_next
;
573 i
->sync_next
->sync_prev
= i
->sync_prev
;
575 i
->sync_prev
= i
->sync_next
= NULL
;
577 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
580 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
581 pa_sink_input_unref(i
);
584 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
586 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
588 pa_source_output_kill(o
);
592 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
593 i
->state
= PA_SINK_INPUT_UNLINKED
;
595 if (linked
&& i
->sink
) {
596 /* We might need to update the sink's volume if we are in flat volume mode. */
597 if (pa_sink_flat_volume_enabled(i
->sink
))
598 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
600 if (i
->sink
->asyncmsgq
)
601 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
603 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
604 if (!pa_format_info_is_pcm(i
->format
) && i
->sink
->monitor_source
)
605 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
611 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
612 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
616 pa_sink_update_status(i
->sink
);
620 pa_core_maybe_vacuum(i
->core
);
622 pa_sink_input_unref(i
);
625 /* Called from main context */
626 static void sink_input_free(pa_object
*o
) {
627 pa_sink_input
* i
= PA_SINK_INPUT(o
);
630 pa_assert_ctl_context();
631 pa_assert(pa_sink_input_refcnt(i
) == 0);
633 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
634 pa_sink_input_unlink(i
);
636 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
638 /* Side note: this function must be able to destruct properly any
639 * kind of sink input in any state, even those which are
640 * "half-moved" or are connected to sinks that have no asyncmsgq
641 * and are hence half-destructed themselves! */
643 if (i
->thread_info
.render_memblockq
)
644 pa_memblockq_free(i
->thread_info
.render_memblockq
);
646 if (i
->thread_info
.resampler
)
647 pa_resampler_free(i
->thread_info
.resampler
);
650 pa_format_info_free(i
->format
);
653 pa_proplist_free(i
->proplist
);
655 if (i
->direct_outputs
)
656 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
658 if (i
->thread_info
.direct_outputs
)
659 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
665 /* Called from main context */
666 void pa_sink_input_put(pa_sink_input
*i
) {
667 pa_sink_input_state_t state
;
669 pa_sink_input_assert_ref(i
);
670 pa_assert_ctl_context();
672 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
674 /* The following fields must be initialized properly */
676 pa_assert(i
->process_rewind
);
679 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
681 update_n_corked(i
, state
);
684 /* We might need to update the sink's volume if we are in flat volume mode. */
685 if (pa_sink_flat_volume_enabled(i
->sink
))
686 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
688 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
689 pa_assert(pa_cvolume_is_norm(&i
->volume
));
690 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
693 set_real_ratio(i
, &i
->volume
);
696 /* If we're entering passthrough mode, disable the monitor */
697 if (!pa_format_info_is_pcm(i
->format
) && i
->sink
->monitor_source
)
698 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
700 i
->thread_info
.soft_volume
= i
->soft_volume
;
701 i
->thread_info
.muted
= i
->muted
;
703 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
705 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
706 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
708 pa_sink_update_status(i
->sink
);
711 /* Called from main context */
712 void pa_sink_input_kill(pa_sink_input
*i
) {
713 pa_sink_input_assert_ref(i
);
714 pa_assert_ctl_context();
715 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
720 /* Called from main context */
721 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
722 pa_usec_t r
[2] = { 0, 0 };
724 pa_sink_input_assert_ref(i
);
725 pa_assert_ctl_context();
726 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
728 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
731 r
[0] += i
->get_latency(i
);
734 *sink_latency
= r
[1];
739 /* Called from thread context */
740 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
741 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
742 pa_bool_t volume_is_norm
;
743 size_t block_size_max_sink
, block_size_max_sink_input
;
746 pa_sink_input_assert_ref(i
);
747 pa_sink_input_assert_io_context(i
);
748 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
749 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
753 /* pa_log_debug("peek"); */
755 pa_assert(i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
||
756 i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
757 i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
);
759 block_size_max_sink_input
= i
->thread_info
.resampler
?
760 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
761 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
763 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
765 /* Default buffer size */
767 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
769 if (slength
> block_size_max_sink
)
770 slength
= block_size_max_sink
;
772 if (i
->thread_info
.resampler
) {
773 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
776 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
780 if (ilength
> block_size_max_sink_input
)
781 ilength
= block_size_max_sink_input
;
783 /* If the channel maps of the sink and this stream differ, we need
784 * to adjust the volume *before* we resample. Otherwise we can do
785 * it after and leave it for the sink code */
787 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
788 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
789 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
791 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
794 /* There's nothing in our render queue. We need to fill it up
795 * with data from the implementor. */
797 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
798 i
->pop(i
, ilength
, &tchunk
) < 0) {
800 /* OK, we're corked or the implementor didn't give us any
801 * data, so let's just hand out silence */
802 pa_atomic_store(&i
->thread_info
.drained
, 1);
804 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
805 i
->thread_info
.playing_for
= 0;
806 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
807 i
->thread_info
.underrun_for
+= ilength
;
811 pa_atomic_store(&i
->thread_info
.drained
, 0);
813 pa_assert(tchunk
.length
> 0);
814 pa_assert(tchunk
.memblock
);
816 i
->thread_info
.underrun_for
= 0;
817 i
->thread_info
.playing_for
+= tchunk
.length
;
819 while (tchunk
.length
> 0) {
821 pa_bool_t nvfs
= need_volume_factor_sink
;
824 pa_memblock_ref(wchunk
.memblock
);
826 if (wchunk
.length
> block_size_max_sink_input
)
827 wchunk
.length
= block_size_max_sink_input
;
829 /* It might be necessary to adjust the volume here */
830 if (do_volume_adj_here
&& !volume_is_norm
) {
831 pa_memchunk_make_writable(&wchunk
, 0);
833 if (i
->thread_info
.muted
) {
834 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
837 } else if (!i
->thread_info
.resampler
&& nvfs
) {
840 /* If we don't need a resampler we can merge the
841 * post and the pre volume adjustment into one */
843 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
844 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
848 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
851 if (!i
->thread_info
.resampler
) {
854 pa_memchunk_make_writable(&wchunk
, 0);
855 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
858 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
861 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
863 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
865 if (rchunk
.memblock
) {
868 pa_memchunk_make_writable(&rchunk
, 0);
869 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
872 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
873 pa_memblock_unref(rchunk
.memblock
);
877 pa_memblock_unref(wchunk
.memblock
);
879 tchunk
.index
+= wchunk
.length
;
880 tchunk
.length
-= wchunk
.length
;
883 pa_memblock_unref(tchunk
.memblock
);
886 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
888 pa_assert(chunk
->length
> 0);
889 pa_assert(chunk
->memblock
);
891 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
893 if (chunk
->length
> block_size_max_sink
)
894 chunk
->length
= block_size_max_sink
;
896 /* Let's see if we had to apply the volume adjustment ourselves,
897 * or if this can be done by the sink for us */
899 if (do_volume_adj_here
)
900 /* We had different channel maps, so we already did the adjustment */
901 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
902 else if (i
->thread_info
.muted
)
903 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
904 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
906 *volume
= i
->thread_info
.soft_volume
;
909 /* Called from thread context */
910 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
912 pa_sink_input_assert_ref(i
);
913 pa_sink_input_assert_io_context(i
);
914 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
915 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
916 pa_assert(nbytes
> 0);
918 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
920 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
923 /* Called from thread context */
924 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
926 pa_bool_t called
= FALSE
;
928 pa_sink_input_assert_ref(i
);
929 pa_sink_input_assert_io_context(i
);
930 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
931 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
933 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
935 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
937 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
938 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
939 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
942 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
944 /* We were asked to drop all buffered data, and rerequest new
945 * data from implementor the next time push() is called */
947 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, TRUE
);
949 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
950 size_t max_rewrite
, amount
;
952 /* Calculate how much make sense to rewrite at most */
953 max_rewrite
= nbytes
+ lbq
;
955 /* Transform into local domain */
956 if (i
->thread_info
.resampler
)
957 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
959 /* Calculate how much of the rewinded data should actually be rewritten */
960 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
963 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
965 /* Tell the implementor */
966 if (i
->process_rewind
)
967 i
->process_rewind(i
, amount
);
970 /* Convert back to to sink domain */
971 if (i
->thread_info
.resampler
)
972 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
975 /* Ok, now update the write pointer */
976 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
978 if (i
->thread_info
.rewrite_flush
)
979 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
981 /* And reset the resampler */
982 if (i
->thread_info
.resampler
)
983 pa_resampler_reset(i
->thread_info
.resampler
);
988 if (i
->process_rewind
)
989 i
->process_rewind(i
, 0);
991 i
->thread_info
.rewrite_nbytes
= 0;
992 i
->thread_info
.rewrite_flush
= FALSE
;
993 i
->thread_info
.dont_rewind_render
= FALSE
;
996 /* Called from thread context */
997 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
998 pa_sink_input_assert_ref(i
);
999 pa_sink_input_assert_io_context(i
);
1001 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1004 /* Called from thread context */
1005 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1006 pa_sink_input_assert_ref(i
);
1007 pa_sink_input_assert_io_context(i
);
1009 /* We're not verifying the status here, to allow this to be called
1010 * in the state change handler between _INIT and _RUNNING */
1012 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1015 /* Called from thread context */
1016 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1017 pa_sink_input_assert_ref(i
);
1018 pa_sink_input_assert_io_context(i
);
1019 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1020 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1022 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1024 if (i
->update_max_rewind
)
1025 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1028 /* Called from thread context */
1029 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
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 if (i
->update_max_request
)
1036 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1039 /* Called from thread context */
1040 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1041 pa_sink_input_assert_ref(i
);
1042 pa_sink_input_assert_io_context(i
);
1044 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1045 usec
= i
->sink
->thread_info
.fixed_latency
;
1047 if (usec
!= (pa_usec_t
) -1)
1048 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1050 i
->thread_info
.requested_sink_latency
= usec
;
1051 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
1056 /* Called from main context */
1057 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1058 pa_sink_input_assert_ref(i
);
1059 pa_assert_ctl_context();
1061 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1062 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1066 /* If this sink input is not realized yet or we are being moved,
1067 * we have to touch the thread info data directly */
1070 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1071 usec
= pa_sink_get_fixed_latency(i
->sink
);
1073 if (usec
!= (pa_usec_t
) -1) {
1074 pa_usec_t min_latency
, max_latency
;
1075 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1076 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1080 i
->thread_info
.requested_sink_latency
= usec
;
1085 /* Called from main context */
1086 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1087 pa_sink_input_assert_ref(i
);
1088 pa_assert_ctl_context();
1090 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1092 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1096 /* If this sink input is not realized yet or we are being moved,
1097 * we have to touch the thread info data directly */
1099 return i
->thread_info
.requested_sink_latency
;
1102 /* Called from main context */
1103 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
1106 pa_sink_input_assert_ref(i
);
1107 pa_assert_ctl_context();
1108 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1110 pa_assert(pa_cvolume_valid(volume
));
1111 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1112 pa_assert(i
->volume_writable
);
1114 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1115 v
= i
->sink
->reference_volume
;
1116 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1118 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1119 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1121 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1123 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1125 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1129 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1130 i
->save_volume
= i
->save_volume
|| save
;
1134 i
->volume
= *volume
;
1135 i
->save_volume
= save
;
1137 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1138 /* We are in flat volume mode, so let's update all sink input
1139 * volumes and update the flat volume of the sink */
1141 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1144 /* OK, we are in normal volume mode. The volume only affects
1146 set_real_ratio(i
, volume
);
1148 /* Copy the new soft_volume to the thread_info struct */
1149 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1152 /* The volume changed, let's tell people so */
1153 if (i
->volume_changed
)
1154 i
->volume_changed(i
);
1156 /* The virtual volume changed, let's tell people so */
1157 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1160 /* Called from main context */
1161 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1162 pa_sink_input_assert_ref(i
);
1163 pa_assert_ctl_context();
1164 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1165 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1167 /* This basically calculates:
1169 * i->real_ratio := v
1170 * i->soft_volume := i->real_ratio * i->volume_factor */
1175 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1177 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1178 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1181 /* Called from main context */
1182 pa_bool_t
pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1183 pa_sink_input_assert_ref(i
);
1184 pa_assert_ctl_context();
1186 return !(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
);
1189 /* Called from main context */
1190 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1191 pa_sink_input_assert_ref(i
);
1192 pa_assert_ctl_context();
1193 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1194 pa_assert(pa_sink_input_is_volume_readable(i
));
1196 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1197 *volume
= i
->volume
;
1199 *volume
= i
->reference_ratio
;
1204 /* Called from main context */
1205 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1206 pa_sink_input_assert_ref(i
);
1207 pa_assert_ctl_context();
1208 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1210 if (!i
->muted
== !mute
) {
1211 i
->save_muted
= i
->save_muted
|| mute
;
1216 i
->save_muted
= save
;
1218 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1220 /* The mute status changed, let's tell people so */
1221 if (i
->mute_changed
)
1224 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1227 /* Called from main context */
1228 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1229 pa_sink_input_assert_ref(i
);
1230 pa_assert_ctl_context();
1231 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1236 /* Called from main thread */
1237 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1238 pa_sink_input_assert_ref(i
);
1239 pa_assert_ctl_context();
1242 pa_proplist_update(i
->proplist
, mode
, p
);
1244 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1245 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1246 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1250 /* Called from main context */
1251 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1252 pa_sink_input_assert_ref(i
);
1253 pa_assert_ctl_context();
1254 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1256 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1259 /* Called from main context */
1260 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1261 pa_sink_input_assert_ref(i
);
1262 pa_assert_ctl_context();
1263 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1264 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1266 if (i
->sample_spec
.rate
== rate
)
1269 i
->sample_spec
.rate
= rate
;
1271 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1273 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1277 /* Called from main context */
1278 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1280 pa_sink_input_assert_ref(i
);
1281 pa_assert_ctl_context();
1283 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1286 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1288 if (old
&& name
&& pa_streq(old
, name
))
1292 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1294 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1296 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1297 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1298 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1302 /* Called from main context */
1303 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1304 pa_sink_input_assert_ref(i
);
1305 pa_assert_ctl_context();
1307 return i
->actual_resample_method
;
1310 /* Called from main context */
1311 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1312 pa_sink_input_assert_ref(i
);
1313 pa_assert_ctl_context();
1314 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1316 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1319 if (i
->sync_next
|| i
->sync_prev
) {
1320 pa_log_warn("Moving synchronized streams not supported.");
1327 /* Called from main context */
1328 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1329 pa_sink_input_assert_ref(i
);
1330 pa_assert_ctl_context();
1331 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1332 pa_sink_assert_ref(dest
);
1334 if (dest
== i
->sink
)
1337 if (!pa_sink_input_may_move(i
))
1340 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1341 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1345 if (check_passthrough_connection(i
->format
, dest
) < 0)
1349 if (!i
->may_move_to(i
, dest
))
1355 /* Called from main context */
1356 int pa_sink_input_start_move(pa_sink_input
*i
) {
1357 pa_source_output
*o
, *p
= NULL
;
1360 pa_sink_input_assert_ref(i
);
1361 pa_assert_ctl_context();
1362 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1365 if (!pa_sink_input_may_move(i
))
1366 return -PA_ERR_NOTSUPPORTED
;
1368 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1371 /* Kill directly connected outputs */
1372 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1374 pa_source_output_kill(o
);
1377 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1379 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1381 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1382 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1384 if (pa_sink_flat_volume_enabled(i
->sink
))
1385 /* We might need to update the sink's volume if we are in flat
1387 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1389 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1391 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
1392 if (!pa_format_info_is_pcm(i
->format
) && i
->sink
->monitor_source
)
1393 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
1395 pa_sink_update_status(i
->sink
);
1396 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1399 pa_sink_input_unref(i
);
1404 /* Called from main context. If i has an origin sink that uses volume sharing,
1405 * then also the origin sink and all streams connected to it need to update
1406 * their volume - this function does all that by using recursion. */
1407 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1408 pa_cvolume old_volume
;
1412 pa_assert(i
->sink
); /* The destination sink should already be set. */
1414 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1415 pa_sink
*root_sink
= i
->sink
;
1416 pa_sink_input
*origin_sink_input
;
1419 while (root_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)
1420 root_sink
= root_sink
->input_to_master
->sink
;
1422 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1423 /* Ok, so the origin sink uses volume sharing, and flat volume is
1424 * enabled. The volume will have to be updated as follows:
1426 * i->volume := i->sink->real_volume
1427 * (handled later by pa_sink_set_volume)
1428 * i->reference_ratio := i->volume / i->sink->reference_volume
1429 * (handled later by pa_sink_set_volume)
1430 * i->real_ratio stays unchanged
1431 * (streams whose origin sink uses volume sharing should
1432 * always have real_ratio of 0 dB)
1433 * i->soft_volume stays unchanged
1434 * (streams whose origin sink uses volume sharing should
1435 * always have volume_factor as soft_volume, so no change
1436 * should be needed) */
1438 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1439 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1441 /* Notifications will be sent by pa_sink_set_volume(). */
1444 /* Ok, so the origin sink uses volume sharing, and flat volume is
1445 * disabled. The volume will have to be updated as follows:
1448 * i->reference_ratio := 0 dB
1449 * i->real_ratio stays unchanged
1450 * (streams whose origin sink uses volume sharing should
1451 * always have real_ratio of 0 dB)
1452 * i->soft_volume stays unchanged
1453 * (streams whose origin sink uses volume sharing should
1454 * always have volume_factor as soft_volume, so no change
1455 * should be needed) */
1457 old_volume
= i
->volume
;
1458 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1459 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1460 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1461 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1463 /* Notify others about the changed sink input volume. */
1464 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1465 if (i
->volume_changed
)
1466 i
->volume_changed(i
);
1468 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1472 /* Additionally, the origin sink volume needs updating:
1474 * i->origin_sink->reference_volume := root_sink->reference_volume
1475 * i->origin_sink->real_volume := root_sink->real_volume
1476 * i->origin_sink->soft_volume stays unchanged
1477 * (sinks that use volume sharing should always have
1478 * soft_volume of 0 dB) */
1480 old_volume
= i
->origin_sink
->reference_volume
;
1482 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1483 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1485 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1486 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1488 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1490 /* Notify others about the changed sink volume. If you wonder whether
1491 * i->origin_sink->set_volume() should be called somewhere, that's not
1492 * the case, because sinks that use volume sharing shouldn't have any
1493 * internal volume that set_volume() would update. If you wonder
1494 * whether the thread_info variables should be synced, yes, they
1495 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1497 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1498 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1500 /* Recursively update origin sink inputs. */
1501 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1502 update_volume_due_to_moving(origin_sink_input
, dest
);
1505 old_volume
= i
->volume
;
1507 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1508 /* Ok, so this is a regular stream, and flat volume is enabled. The
1509 * volume will have to be updated as follows:
1511 * i->volume := i->reference_ratio * i->sink->reference_volume
1512 * i->reference_ratio stays unchanged
1513 * i->real_ratio := i->volume / i->sink->real_volume
1514 * (handled later by pa_sink_set_volume)
1515 * i->soft_volume := i->real_ratio * i->volume_factor
1516 * (handled later by pa_sink_set_volume) */
1518 i
->volume
= i
->sink
->reference_volume
;
1519 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1520 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1523 /* Ok, so this is a regular stream, and flat volume is disabled.
1524 * The volume will have to be updated as follows:
1526 * i->volume := i->reference_ratio
1527 * i->reference_ratio stays unchanged
1528 * i->real_ratio := i->reference_ratio
1529 * i->soft_volume := i->real_ratio * i->volume_factor */
1531 i
->volume
= i
->reference_ratio
;
1532 i
->real_ratio
= i
->reference_ratio
;
1533 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1536 /* Notify others about the changed sink input volume. */
1537 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1538 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1539 * and soft_volume are not updated yet. Let's hope that the
1540 * callback implementation doesn't care about those variables... */
1541 if (i
->volume_changed
)
1542 i
->volume_changed(i
);
1544 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1548 /* If i->sink == dest, then recursion has finished, and we can finally call
1549 * pa_sink_set_volume(), which will do the rest of the updates. */
1550 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1551 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1554 /* Called from main context */
1555 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1556 pa_resampler
*new_resampler
;
1558 pa_sink_input_assert_ref(i
);
1559 pa_assert_ctl_context();
1560 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1561 pa_assert(!i
->sink
);
1562 pa_sink_assert_ref(dest
);
1564 if (!pa_sink_input_may_move_to(i
, dest
))
1565 return -PA_ERR_NOTSUPPORTED
;
1567 if (!pa_format_info_is_pcm(i
->format
) && !pa_sink_check_format(dest
, i
->format
)) {
1568 /* FIXME: Fire a message here so the client can renegotiate */
1569 return -PA_ERR_NOTSUPPORTED
;
1572 if (i
->thread_info
.resampler
&&
1573 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1574 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1576 /* Try to reuse the old resampler if possible */
1577 new_resampler
= i
->thread_info
.resampler
;
1579 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1580 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1581 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1583 /* Okey, we need a new resampler for the new sink */
1585 if (!(new_resampler
= pa_resampler_new(
1587 &i
->sample_spec
, &i
->channel_map
,
1588 &dest
->sample_spec
, &dest
->channel_map
,
1589 i
->requested_resample_method
,
1590 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1591 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1592 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1593 pa_log_warn("Unsupported resampling operation.");
1594 return -PA_ERR_NOTSUPPORTED
;
1597 new_resampler
= NULL
;
1603 i
->save_sink
= save
;
1604 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1606 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1608 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1609 i
->sink
->n_corked
++;
1611 /* Replace resampler and render queue */
1612 if (new_resampler
!= i
->thread_info
.resampler
) {
1614 if (i
->thread_info
.resampler
)
1615 pa_resampler_free(i
->thread_info
.resampler
);
1616 i
->thread_info
.resampler
= new_resampler
;
1618 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1620 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1622 MEMBLOCKQ_MAXLENGTH
,
1624 pa_frame_size(&i
->sink
->sample_spec
),
1630 pa_sink_update_status(dest
);
1632 update_volume_due_to_moving(i
, dest
);
1634 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1636 /* If we're entering passthrough mode, disable the monitor */
1637 if (!pa_format_info_is_pcm(i
->format
) && i
->sink
->monitor_source
)
1638 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
1640 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1642 /* Notify everyone */
1643 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1645 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1650 /* Called from main context */
1651 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1653 pa_sink_input_assert_ref(i
);
1654 pa_assert_ctl_context();
1655 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1656 pa_assert(!i
->sink
);
1658 /* Check if someone wants this sink input? */
1659 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1665 pa_sink_input_kill(i
);
1668 /* Called from main context */
1669 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1672 pa_sink_input_assert_ref(i
);
1673 pa_assert_ctl_context();
1674 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1676 pa_sink_assert_ref(dest
);
1678 if (dest
== i
->sink
)
1681 if (!pa_sink_input_may_move_to(i
, dest
))
1682 return -PA_ERR_NOTSUPPORTED
;
1684 pa_sink_input_ref(i
);
1686 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1687 pa_sink_input_unref(i
);
1691 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1692 pa_sink_input_fail_move(i
);
1693 pa_sink_input_unref(i
);
1697 pa_sink_input_unref(i
);
1702 /* Called from IO thread context */
1703 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1704 pa_bool_t corking
, uncorking
;
1706 pa_sink_input_assert_ref(i
);
1707 pa_sink_input_assert_io_context(i
);
1709 if (state
== i
->thread_info
.state
)
1712 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1713 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1714 pa_atomic_store(&i
->thread_info
.drained
, 1);
1716 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1717 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1719 if (i
->state_change
)
1720 i
->state_change(i
, state
);
1722 i
->thread_info
.state
= state
;
1726 pa_log_debug("Requesting rewind due to corking");
1728 /* This will tell the implementing sink input driver to rewind
1729 * so that the unplayed already mixed data is not lost */
1730 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1732 } else if (uncorking
) {
1734 i
->thread_info
.underrun_for
= (uint64_t) -1;
1735 i
->thread_info
.playing_for
= 0;
1737 pa_log_debug("Requesting rewind due to uncorking");
1739 /* OK, we're being uncorked. Make sure we're not rewound when
1740 * the hw buffer is remixed and request a remix. */
1741 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1745 /* Called from thread context, except when it is not. */
1746 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1747 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1748 pa_sink_input_assert_ref(i
);
1752 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1753 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1754 i
->thread_info
.soft_volume
= i
->soft_volume
;
1755 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1759 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1760 if (i
->thread_info
.muted
!= i
->muted
) {
1761 i
->thread_info
.muted
= i
->muted
;
1762 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1766 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1767 pa_usec_t
*r
= userdata
;
1769 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1770 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1775 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1777 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1778 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1782 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1783 pa_sink_input
*ssync
;
1785 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1787 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1788 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1790 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1791 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1796 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1797 pa_usec_t
*usec
= userdata
;
1799 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1803 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1804 pa_usec_t
*r
= userdata
;
1806 *r
= i
->thread_info
.requested_sink_latency
;
1811 return -PA_ERR_NOTIMPLEMENTED
;
1814 /* Called from main thread */
1815 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1816 pa_sink_input_assert_ref(i
);
1817 pa_assert_ctl_context();
1819 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1820 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1825 /* Called from IO context */
1826 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1827 pa_sink_input_assert_ref(i
);
1828 pa_sink_input_assert_io_context(i
);
1830 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1831 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1836 /* Called from IO context */
1837 void pa_sink_input_request_rewind(
1839 size_t nbytes
/* in our sample spec */,
1842 pa_bool_t dont_rewind_render
) {
1846 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1847 * and possible and the exact value of this is passed back the
1848 * implementor via process_rewind(). If 'flush' is also TRUE all
1849 * already rendered data is also dropped.
1851 * If 'rewrite' is FALSE the sink is rewound as far as requested
1852 * and possible and the already rendered data is dropped so that
1853 * in the next iteration we read new data from the
1854 * implementor. This implies 'flush' is TRUE. If
1855 * dont_rewind_render is TRUE then the render memblockq is not
1858 /* nbytes = 0 means maximum rewind request */
1860 pa_sink_input_assert_ref(i
);
1861 pa_sink_input_assert_io_context(i
);
1862 pa_assert(rewrite
|| flush
);
1863 pa_assert(!dont_rewind_render
|| !rewrite
);
1865 /* We don't take rewind requests while we are corked */
1866 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1869 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1871 /* pa_log_debug("request rewrite %zu", nbytes); */
1873 /* Calculate how much we can rewind locally without having to
1876 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1880 /* Check if rewinding for the maximum is requested, and if so, fix up */
1883 /* Calculate maximum number of bytes that could be rewound in theory */
1884 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1886 /* Transform from sink domain */
1887 if (i
->thread_info
.resampler
)
1888 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1891 /* Remember how much we actually want to rewrite */
1892 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1894 /* Make sure to not overwrite over underruns */
1895 if (nbytes
> i
->thread_info
.playing_for
)
1896 nbytes
= (size_t) i
->thread_info
.playing_for
;
1898 i
->thread_info
.rewrite_nbytes
= nbytes
;
1900 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1903 i
->thread_info
.rewrite_flush
=
1904 i
->thread_info
.rewrite_flush
||
1905 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1907 i
->thread_info
.dont_rewind_render
=
1908 i
->thread_info
.dont_rewind_render
||
1911 if (nbytes
!= (size_t) -1) {
1913 /* Transform to sink domain */
1914 if (i
->thread_info
.resampler
)
1915 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1918 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1920 /* This call will make sure process_rewind() is called later */
1921 pa_sink_request_rewind(i
->sink
, 0);
1925 /* Called from main context */
1926 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1927 pa_sink_input_assert_ref(i
);
1928 pa_assert_ctl_context();
1931 /* FIXME: Shouldn't access resampler object from main context! */
1933 pa_silence_memchunk_get(
1934 &i
->core
->silence_cache
,
1938 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1943 /* Called from main context */
1944 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1945 pa_proplist
*pl
= NULL
;
1946 pa_sink_input_send_event_hook_data hook_data
;
1948 pa_sink_input_assert_ref(i
);
1949 pa_assert_ctl_context();
1956 data
= pl
= pa_proplist_new();
1958 hook_data
.sink_input
= i
;
1959 hook_data
.data
= data
;
1960 hook_data
.event
= event
;
1962 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
1965 i
->send_event(i
, event
, data
);
1969 pa_proplist_free(pl
);