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 MEMBLOCKQ_MAXLENGTH (32*1024*1024)
45 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
47 PA_DEFINE_PUBLIC_CLASS(pa_sink_input
, pa_msgobject
);
49 static void sink_input_free(pa_object
*o
);
50 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
52 static int check_passthrough_connection(pa_bool_t passthrough
, pa_sink
*dest
) {
53 if (pa_sink_is_passthrough(dest
)) {
54 pa_log_warn("Sink is already connected to PASSTHROUGH input");
58 /* If current input(s) exist, check new input is not PASSTHROUGH */
59 if (pa_idxset_size(dest
->inputs
) > 0 && passthrough
) {
60 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
67 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
71 data
->resample_method
= PA_RESAMPLER_INVALID
;
72 data
->proplist
= pa_proplist_new();
73 data
->volume_writable
= TRUE
;
78 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
81 if ((data
->sample_spec_is_set
= !!spec
))
82 data
->sample_spec
= *spec
;
85 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
88 if ((data
->channel_map_is_set
= !!map
))
89 data
->channel_map
= *map
;
92 pa_bool_t
pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data
*data
) {
95 if (PA_LIKELY(data
->format
) && PA_UNLIKELY(!pa_format_info_is_pcm(data
->format
)))
98 if (PA_UNLIKELY(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
104 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
106 pa_assert(data
->volume_writable
);
108 if ((data
->volume_is_set
= !!volume
))
109 data
->volume
= *volume
;
112 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
114 pa_assert(volume_factor
);
116 if (data
->volume_factor_is_set
)
117 pa_sw_cvolume_multiply(&data
->volume_factor
, &data
->volume_factor
, volume_factor
);
119 data
->volume_factor_is_set
= TRUE
;
120 data
->volume_factor
= *volume_factor
;
124 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
126 pa_assert(volume_factor
);
128 if (data
->volume_factor_sink_is_set
)
129 pa_sw_cvolume_multiply(&data
->volume_factor_sink
, &data
->volume_factor_sink
, volume_factor
);
131 data
->volume_factor_sink_is_set
= TRUE
;
132 data
->volume_factor_sink
= *volume_factor
;
136 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
139 data
->muted_is_set
= TRUE
;
140 data
->muted
= !!mute
;
143 pa_bool_t
pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, pa_bool_t save
) {
144 pa_bool_t ret
= TRUE
;
145 pa_idxset
*formats
= NULL
;
150 if (!data
->req_formats
) {
151 /* We're not working with the extended API */
153 data
->save_sink
= save
;
155 /* Extended API: let's see if this sink supports the formats the client can provide */
156 formats
= pa_sink_check_formats(s
, data
->req_formats
);
158 if (formats
&& !pa_idxset_isempty(formats
)) {
159 /* Sink supports at least one of the requested formats */
161 data
->save_sink
= save
;
162 if (data
->nego_formats
)
163 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
164 data
->nego_formats
= formats
;
166 /* Sink doesn't support any of the formats requested by the client */
168 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
176 pa_bool_t
pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
180 if (data
->req_formats
)
181 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
183 data
->req_formats
= formats
;
186 /* Trigger format negotiation */
187 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
193 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
196 if (data
->req_formats
)
197 pa_idxset_free(data
->req_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
199 if (data
->nego_formats
)
200 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
203 pa_format_info_free(data
->format
);
205 pa_proplist_free(data
->proplist
);
208 /* Called from main context */
209 static void reset_callbacks(pa_sink_input
*i
) {
213 i
->process_rewind
= NULL
;
214 i
->update_max_rewind
= NULL
;
215 i
->update_max_request
= NULL
;
216 i
->update_sink_requested_latency
= NULL
;
217 i
->update_sink_latency_range
= NULL
;
218 i
->update_sink_fixed_latency
= NULL
;
222 i
->suspend_within_thread
= NULL
;
225 i
->get_latency
= NULL
;
226 i
->state_change
= NULL
;
227 i
->may_move_to
= NULL
;
228 i
->send_event
= NULL
;
229 i
->volume_changed
= NULL
;
230 i
->mute_changed
= NULL
;
233 /* Called from main context */
234 int pa_sink_input_new(
237 pa_sink_input_new_data
*data
) {
240 pa_resampler
*resampler
= NULL
;
241 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
242 pa_channel_map original_cm
;
251 pa_assert_ctl_context();
254 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
256 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
257 data
->volume_writable
= FALSE
;
259 if (!data
->req_formats
) {
260 /* From this point on, we want to work only with formats, and get back
261 * to using the sample spec and channel map after all decisions w.r.t.
262 * routing are complete. */
263 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
264 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
,
265 data
->channel_map_is_set
? &data
->channel_map
: NULL
);
266 pa_idxset_put(tmp
, f
, NULL
);
267 pa_sink_input_new_data_set_formats(data
, tmp
);
270 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
273 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
276 pa_sink
*sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
277 pa_return_val_if_fail(sink
, -PA_ERR_NOENTITY
);
278 pa_sink_input_new_data_set_sink(data
, sink
, FALSE
);
280 /* Routing's done, we have a sink. Now let's fix the format and set up the
283 /* If something didn't pick a format for us, pick the top-most format since
284 * we assume this is sorted in priority order */
285 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
286 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
288 pa_return_val_if_fail(data
->format
, -PA_ERR_NOTSUPPORTED
);
290 /* Now populate the sample spec and format according to the final
291 * format that we've negotiated */
292 if (PA_LIKELY(data
->format
->encoding
== PA_ENCODING_PCM
)) {
293 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
), -PA_ERR_INVALID
);
294 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
295 if (pa_channel_map_valid(&map
))
296 pa_sink_input_new_data_set_channel_map(data
, &map
);
298 pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data
->format
, &ss
), -PA_ERR_INVALID
);
299 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
302 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
303 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
);
305 r
= check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data
), data
->sink
);
309 if (!data
->sample_spec_is_set
)
310 data
->sample_spec
= data
->sink
->sample_spec
;
312 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
314 if (!data
->channel_map_is_set
) {
315 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
316 data
->channel_map
= data
->sink
->channel_map
;
318 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
321 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
323 /* Don't restore (or save) stream volume for passthrough streams */
324 if (!pa_format_info_is_pcm(data
->format
)) {
325 data
->volume_is_set
= FALSE
;
326 data
->volume_factor_is_set
= FALSE
;
329 if (!data
->volume_is_set
) {
330 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
331 data
->volume_is_absolute
= FALSE
;
332 data
->save_volume
= FALSE
;
335 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
337 if (!data
->volume_factor_is_set
)
338 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
340 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
342 if (!data
->volume_factor_sink_is_set
)
343 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
345 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
347 if (!data
->muted_is_set
)
350 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
351 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
353 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
354 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
356 original_cm
= data
->channel_map
;
358 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
359 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
360 data
->channel_map
= data
->sink
->channel_map
;
363 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
364 pa_assert(pa_channel_map_valid(&data
->channel_map
));
366 /* Due to the fixing of the sample spec the volume might not match anymore */
367 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
369 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
370 data
->resample_method
= core
->resample_method
;
372 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
374 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
377 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
378 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
379 pa_log_warn("Failed to create sink input: sink is suspended.");
380 return -PA_ERR_BADSTATE
;
383 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
384 pa_log_warn("Failed to create sink input: too many inputs per sink.");
385 return -PA_ERR_TOOLARGE
;
388 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
389 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
390 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
392 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
393 if (!pa_sink_input_new_data_is_passthrough(data
)) /* no resampler for passthrough content */
394 if (!(resampler
= pa_resampler_new(
396 &data
->sample_spec
, &data
->channel_map
,
397 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
398 data
->resample_method
,
399 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
400 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
401 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
402 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
403 pa_log_warn("Unsupported resampling operation.");
404 return -PA_ERR_NOTSUPPORTED
;
408 i
= pa_msgobject_new(pa_sink_input
);
409 i
->parent
.parent
.free
= sink_input_free
;
410 i
->parent
.process_msg
= pa_sink_input_process_msg
;
413 i
->state
= PA_SINK_INPUT_INIT
;
414 i
->flags
= data
->flags
;
415 i
->proplist
= pa_proplist_copy(data
->proplist
);
416 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
417 i
->module
= data
->module
;
418 i
->sink
= data
->sink
;
419 i
->origin_sink
= data
->origin_sink
;
420 i
->client
= data
->client
;
422 i
->requested_resample_method
= data
->resample_method
;
423 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
424 i
->sample_spec
= data
->sample_spec
;
425 i
->channel_map
= data
->channel_map
;
426 i
->format
= pa_format_info_copy(data
->format
);
428 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
431 /* When the 'absolute' bool is not set then we'll treat the volume
432 * as relative to the sink volume even in flat volume mode */
433 remapped
= data
->sink
->reference_volume
;
434 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
435 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
437 i
->volume
= data
->volume
;
439 i
->volume_factor
= data
->volume_factor
;
440 i
->volume_factor_sink
= data
->volume_factor_sink
;
441 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
442 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
443 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
444 i
->volume_writable
= data
->volume_writable
;
445 i
->save_volume
= data
->save_volume
;
446 i
->save_sink
= data
->save_sink
;
447 i
->save_muted
= data
->save_muted
;
449 i
->muted
= data
->muted
;
451 if (data
->sync_base
) {
452 i
->sync_next
= data
->sync_base
->sync_next
;
453 i
->sync_prev
= data
->sync_base
;
455 if (data
->sync_base
->sync_next
)
456 data
->sync_base
->sync_next
->sync_prev
= i
;
457 data
->sync_base
->sync_next
= i
;
459 i
->sync_next
= i
->sync_prev
= NULL
;
461 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
466 i
->thread_info
.state
= i
->state
;
467 i
->thread_info
.attached
= FALSE
;
468 pa_atomic_store(&i
->thread_info
.drained
, 1);
469 i
->thread_info
.sample_spec
= i
->sample_spec
;
470 i
->thread_info
.resampler
= resampler
;
471 i
->thread_info
.soft_volume
= i
->soft_volume
;
472 i
->thread_info
.muted
= i
->muted
;
473 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
474 i
->thread_info
.rewrite_nbytes
= 0;
475 i
->thread_info
.rewrite_flush
= FALSE
;
476 i
->thread_info
.dont_rewind_render
= FALSE
;
477 i
->thread_info
.underrun_for
= (uint64_t) -1;
478 i
->thread_info
.playing_for
= 0;
479 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
481 i
->thread_info
.render_memblockq
= pa_memblockq_new(
485 pa_frame_size(&i
->sink
->sample_spec
),
491 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
492 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
495 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
497 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
498 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
500 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
502 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
503 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
507 /* Don't forget to call pa_sink_input_put! */
513 /* Called from main context */
514 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
516 pa_assert_ctl_context();
521 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
522 pa_assert_se(i
->sink
->n_corked
-- >= 1);
523 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
527 /* Called from main context */
528 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
529 pa_sink_input
*ssync
;
531 pa_assert_ctl_context();
533 if (state
== PA_SINK_INPUT_DRAINED
)
534 state
= PA_SINK_INPUT_RUNNING
;
536 if (i
->state
== state
)
539 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);
541 update_n_corked(i
, state
);
544 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
545 update_n_corked(ssync
, state
);
546 ssync
->state
= state
;
548 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
549 update_n_corked(ssync
, state
);
550 ssync
->state
= state
;
553 if (state
!= PA_SINK_INPUT_UNLINKED
) {
554 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
556 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
557 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
559 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
560 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
562 if (PA_SINK_INPUT_IS_LINKED(state
))
563 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
566 pa_sink_update_status(i
->sink
);
569 /* Called from main context */
570 void pa_sink_input_unlink(pa_sink_input
*i
) {
572 pa_source_output
*o
, *p
= NULL
;
575 pa_assert_ctl_context();
577 /* See pa_sink_unlink() for a couple of comments how this function
580 pa_sink_input_ref(i
);
582 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
585 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
588 i
->sync_prev
->sync_next
= i
->sync_next
;
590 i
->sync_next
->sync_prev
= i
->sync_prev
;
592 i
->sync_prev
= i
->sync_next
= NULL
;
594 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
597 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
598 pa_sink_input_unref(i
);
601 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
603 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
605 pa_source_output_kill(o
);
609 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
610 i
->state
= PA_SINK_INPUT_UNLINKED
;
612 if (linked
&& i
->sink
) {
613 /* We might need to update the sink's volume if we are in flat volume mode. */
614 if (pa_sink_flat_volume_enabled(i
->sink
))
615 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
617 if (i
->sink
->asyncmsgq
)
618 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
620 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
621 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
622 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
628 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
629 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
633 pa_sink_update_status(i
->sink
);
637 pa_core_maybe_vacuum(i
->core
);
639 pa_sink_input_unref(i
);
642 /* Called from main context */
643 static void sink_input_free(pa_object
*o
) {
644 pa_sink_input
* i
= PA_SINK_INPUT(o
);
647 pa_assert_ctl_context();
648 pa_assert(pa_sink_input_refcnt(i
) == 0);
650 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
651 pa_sink_input_unlink(i
);
653 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
655 /* Side note: this function must be able to destruct properly any
656 * kind of sink input in any state, even those which are
657 * "half-moved" or are connected to sinks that have no asyncmsgq
658 * and are hence half-destructed themselves! */
660 if (i
->thread_info
.render_memblockq
)
661 pa_memblockq_free(i
->thread_info
.render_memblockq
);
663 if (i
->thread_info
.resampler
)
664 pa_resampler_free(i
->thread_info
.resampler
);
667 pa_format_info_free(i
->format
);
670 pa_proplist_free(i
->proplist
);
672 if (i
->direct_outputs
)
673 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
675 if (i
->thread_info
.direct_outputs
)
676 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
682 /* Called from main context */
683 void pa_sink_input_put(pa_sink_input
*i
) {
684 pa_sink_input_state_t state
;
686 pa_sink_input_assert_ref(i
);
687 pa_assert_ctl_context();
689 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
691 /* The following fields must be initialized properly */
693 pa_assert(i
->process_rewind
);
696 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
698 update_n_corked(i
, state
);
701 /* We might need to update the sink's volume if we are in flat volume mode. */
702 if (pa_sink_flat_volume_enabled(i
->sink
))
703 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
705 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
706 pa_assert(pa_cvolume_is_norm(&i
->volume
));
707 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
710 set_real_ratio(i
, &i
->volume
);
713 /* If we're entering passthrough mode, disable the monitor */
714 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
715 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
717 i
->thread_info
.soft_volume
= i
->soft_volume
;
718 i
->thread_info
.muted
= i
->muted
;
720 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
722 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
723 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
725 pa_sink_update_status(i
->sink
);
728 /* Called from main context */
729 void pa_sink_input_kill(pa_sink_input
*i
) {
730 pa_sink_input_assert_ref(i
);
731 pa_assert_ctl_context();
732 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
737 /* Called from main context */
738 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
739 pa_usec_t r
[2] = { 0, 0 };
741 pa_sink_input_assert_ref(i
);
742 pa_assert_ctl_context();
743 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
745 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
748 r
[0] += i
->get_latency(i
);
751 *sink_latency
= r
[1];
756 /* Called from thread context */
757 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
758 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
759 pa_bool_t volume_is_norm
;
760 size_t block_size_max_sink
, block_size_max_sink_input
;
763 pa_sink_input_assert_ref(i
);
764 pa_sink_input_assert_io_context(i
);
765 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
766 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
770 /* pa_log_debug("peek"); */
772 pa_assert(i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
||
773 i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
774 i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
);
776 block_size_max_sink_input
= i
->thread_info
.resampler
?
777 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
778 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
780 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
782 /* Default buffer size */
784 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
786 if (slength
> block_size_max_sink
)
787 slength
= block_size_max_sink
;
789 if (i
->thread_info
.resampler
) {
790 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
793 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
797 if (ilength
> block_size_max_sink_input
)
798 ilength
= block_size_max_sink_input
;
800 /* If the channel maps of the sink and this stream differ, we need
801 * to adjust the volume *before* we resample. Otherwise we can do
802 * it after and leave it for the sink code */
804 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
805 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
806 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
808 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
811 /* There's nothing in our render queue. We need to fill it up
812 * with data from the implementor. */
814 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
815 i
->pop(i
, ilength
, &tchunk
) < 0) {
817 /* OK, we're corked or the implementor didn't give us any
818 * data, so let's just hand out silence */
819 pa_atomic_store(&i
->thread_info
.drained
, 1);
821 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
822 i
->thread_info
.playing_for
= 0;
823 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
824 i
->thread_info
.underrun_for
+= ilength
;
828 pa_atomic_store(&i
->thread_info
.drained
, 0);
830 pa_assert(tchunk
.length
> 0);
831 pa_assert(tchunk
.memblock
);
833 i
->thread_info
.underrun_for
= 0;
834 i
->thread_info
.playing_for
+= tchunk
.length
;
836 while (tchunk
.length
> 0) {
838 pa_bool_t nvfs
= need_volume_factor_sink
;
841 pa_memblock_ref(wchunk
.memblock
);
843 if (wchunk
.length
> block_size_max_sink_input
)
844 wchunk
.length
= block_size_max_sink_input
;
846 /* It might be necessary to adjust the volume here */
847 if (do_volume_adj_here
&& !volume_is_norm
) {
848 pa_memchunk_make_writable(&wchunk
, 0);
850 if (i
->thread_info
.muted
) {
851 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
854 } else if (!i
->thread_info
.resampler
&& nvfs
) {
857 /* If we don't need a resampler we can merge the
858 * post and the pre volume adjustment into one */
860 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
861 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
865 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
868 if (!i
->thread_info
.resampler
) {
871 pa_memchunk_make_writable(&wchunk
, 0);
872 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
875 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
878 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
880 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
882 if (rchunk
.memblock
) {
885 pa_memchunk_make_writable(&rchunk
, 0);
886 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
889 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
890 pa_memblock_unref(rchunk
.memblock
);
894 pa_memblock_unref(wchunk
.memblock
);
896 tchunk
.index
+= wchunk
.length
;
897 tchunk
.length
-= wchunk
.length
;
900 pa_memblock_unref(tchunk
.memblock
);
903 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
905 pa_assert(chunk
->length
> 0);
906 pa_assert(chunk
->memblock
);
908 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
910 if (chunk
->length
> block_size_max_sink
)
911 chunk
->length
= block_size_max_sink
;
913 /* Let's see if we had to apply the volume adjustment ourselves,
914 * or if this can be done by the sink for us */
916 if (do_volume_adj_here
)
917 /* We had different channel maps, so we already did the adjustment */
918 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
919 else if (i
->thread_info
.muted
)
920 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
921 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
923 *volume
= i
->thread_info
.soft_volume
;
926 /* Called from thread context */
927 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
929 pa_sink_input_assert_ref(i
);
930 pa_sink_input_assert_io_context(i
);
931 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
932 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
933 pa_assert(nbytes
> 0);
935 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
937 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
940 /* Called from thread context */
941 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
943 pa_bool_t called
= FALSE
;
945 pa_sink_input_assert_ref(i
);
946 pa_sink_input_assert_io_context(i
);
947 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
948 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
950 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
952 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
954 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
955 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
956 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
959 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
961 /* We were asked to drop all buffered data, and rerequest new
962 * data from implementor the next time push() is called */
964 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, TRUE
);
966 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
967 size_t max_rewrite
, amount
;
969 /* Calculate how much make sense to rewrite at most */
970 max_rewrite
= nbytes
+ lbq
;
972 /* Transform into local domain */
973 if (i
->thread_info
.resampler
)
974 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
976 /* Calculate how much of the rewinded data should actually be rewritten */
977 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
980 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
982 /* Tell the implementor */
983 if (i
->process_rewind
)
984 i
->process_rewind(i
, amount
);
987 /* Convert back to to sink domain */
988 if (i
->thread_info
.resampler
)
989 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
992 /* Ok, now update the write pointer */
993 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
995 if (i
->thread_info
.rewrite_flush
)
996 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
998 /* And reset the resampler */
999 if (i
->thread_info
.resampler
)
1000 pa_resampler_reset(i
->thread_info
.resampler
);
1005 if (i
->process_rewind
)
1006 i
->process_rewind(i
, 0);
1008 i
->thread_info
.rewrite_nbytes
= 0;
1009 i
->thread_info
.rewrite_flush
= FALSE
;
1010 i
->thread_info
.dont_rewind_render
= FALSE
;
1013 /* Called from thread context */
1014 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
1015 pa_sink_input_assert_ref(i
);
1016 pa_sink_input_assert_io_context(i
);
1018 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1021 /* Called from thread context */
1022 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1023 pa_sink_input_assert_ref(i
);
1024 pa_sink_input_assert_io_context(i
);
1026 /* We're not verifying the status here, to allow this to be called
1027 * in the state change handler between _INIT and _RUNNING */
1029 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1032 /* Called from thread context */
1033 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1034 pa_sink_input_assert_ref(i
);
1035 pa_sink_input_assert_io_context(i
);
1036 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1037 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1039 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1041 if (i
->update_max_rewind
)
1042 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1045 /* Called from thread context */
1046 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1047 pa_sink_input_assert_ref(i
);
1048 pa_sink_input_assert_io_context(i
);
1049 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1050 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1052 if (i
->update_max_request
)
1053 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1056 /* Called from thread context */
1057 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1058 pa_sink_input_assert_ref(i
);
1059 pa_sink_input_assert_io_context(i
);
1061 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1062 usec
= i
->sink
->thread_info
.fixed_latency
;
1064 if (usec
!= (pa_usec_t
) -1)
1065 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1067 i
->thread_info
.requested_sink_latency
= usec
;
1068 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
1073 /* Called from main context */
1074 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1075 pa_sink_input_assert_ref(i
);
1076 pa_assert_ctl_context();
1078 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1079 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1083 /* If this sink input is not realized yet or we are being moved,
1084 * we have to touch the thread info data directly */
1087 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1088 usec
= pa_sink_get_fixed_latency(i
->sink
);
1090 if (usec
!= (pa_usec_t
) -1) {
1091 pa_usec_t min_latency
, max_latency
;
1092 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1093 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1097 i
->thread_info
.requested_sink_latency
= usec
;
1102 /* Called from main context */
1103 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1104 pa_sink_input_assert_ref(i
);
1105 pa_assert_ctl_context();
1107 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1109 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1113 /* If this sink input is not realized yet or we are being moved,
1114 * we have to touch the thread info data directly */
1116 return i
->thread_info
.requested_sink_latency
;
1119 /* Called from main context */
1120 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
1123 pa_sink_input_assert_ref(i
);
1124 pa_assert_ctl_context();
1125 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1127 pa_assert(pa_cvolume_valid(volume
));
1128 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1129 pa_assert(i
->volume_writable
);
1131 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1132 v
= i
->sink
->reference_volume
;
1133 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1135 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1136 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1138 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1140 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1142 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1146 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1147 i
->save_volume
= i
->save_volume
|| save
;
1151 i
->volume
= *volume
;
1152 i
->save_volume
= save
;
1154 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1155 /* We are in flat volume mode, so let's update all sink input
1156 * volumes and update the flat volume of the sink */
1158 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1161 /* OK, we are in normal volume mode. The volume only affects
1163 set_real_ratio(i
, volume
);
1165 /* Copy the new soft_volume to the thread_info struct */
1166 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1169 /* The volume changed, let's tell people so */
1170 if (i
->volume_changed
)
1171 i
->volume_changed(i
);
1173 /* The virtual volume changed, let's tell people so */
1174 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1177 /* Called from main context */
1178 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1179 pa_sink_input_assert_ref(i
);
1180 pa_assert_ctl_context();
1181 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1182 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1184 /* This basically calculates:
1186 * i->real_ratio := v
1187 * i->soft_volume := i->real_ratio * i->volume_factor */
1192 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1194 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1195 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1198 /* Called from main or I/O context */
1199 pa_bool_t
pa_sink_input_is_passthrough(pa_sink_input
*i
) {
1200 pa_sink_input_assert_ref(i
);
1202 if (PA_UNLIKELY(!pa_format_info_is_pcm(i
->format
)))
1205 if (PA_UNLIKELY(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
1211 /* Called from main context */
1212 pa_bool_t
pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1213 pa_sink_input_assert_ref(i
);
1214 pa_assert_ctl_context();
1216 return !pa_sink_input_is_passthrough(i
);
1219 /* Called from main context */
1220 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1221 pa_sink_input_assert_ref(i
);
1222 pa_assert_ctl_context();
1223 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1224 pa_assert(pa_sink_input_is_volume_readable(i
));
1226 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1227 *volume
= i
->volume
;
1229 *volume
= i
->reference_ratio
;
1234 /* Called from main context */
1235 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1236 pa_sink_input_assert_ref(i
);
1237 pa_assert_ctl_context();
1238 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1240 if (!i
->muted
== !mute
) {
1241 i
->save_muted
= i
->save_muted
|| mute
;
1246 i
->save_muted
= save
;
1248 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1250 /* The mute status changed, let's tell people so */
1251 if (i
->mute_changed
)
1254 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1257 /* Called from main context */
1258 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1259 pa_sink_input_assert_ref(i
);
1260 pa_assert_ctl_context();
1261 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1266 /* Called from main thread */
1267 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1268 pa_sink_input_assert_ref(i
);
1269 pa_assert_ctl_context();
1272 pa_proplist_update(i
->proplist
, mode
, p
);
1274 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1275 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1276 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1280 /* Called from main context */
1281 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1282 pa_sink_input_assert_ref(i
);
1283 pa_assert_ctl_context();
1284 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1286 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1289 /* Called from main context */
1290 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1291 pa_sink_input_assert_ref(i
);
1292 pa_assert_ctl_context();
1293 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1294 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1296 if (i
->sample_spec
.rate
== rate
)
1299 i
->sample_spec
.rate
= rate
;
1301 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1303 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1307 /* Called from main context */
1308 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1310 pa_sink_input_assert_ref(i
);
1311 pa_assert_ctl_context();
1313 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1316 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1318 if (old
&& name
&& pa_streq(old
, name
))
1322 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1324 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1326 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1327 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1328 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1332 /* Called from main context */
1333 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1334 pa_sink_input_assert_ref(i
);
1335 pa_assert_ctl_context();
1337 return i
->actual_resample_method
;
1340 /* Called from main context */
1341 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1342 pa_sink_input_assert_ref(i
);
1343 pa_assert_ctl_context();
1344 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1346 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1349 if (i
->sync_next
|| i
->sync_prev
) {
1350 pa_log_warn("Moving synchronized streams not supported.");
1357 /* Called from main context */
1358 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1359 pa_sink_input_assert_ref(i
);
1360 pa_assert_ctl_context();
1361 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1362 pa_sink_assert_ref(dest
);
1364 if (dest
== i
->sink
)
1367 if (!pa_sink_input_may_move(i
))
1370 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1371 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1375 if (check_passthrough_connection(pa_sink_input_is_passthrough(i
), dest
) < 0)
1379 if (!i
->may_move_to(i
, dest
))
1385 /* Called from main context */
1386 int pa_sink_input_start_move(pa_sink_input
*i
) {
1387 pa_source_output
*o
, *p
= NULL
;
1390 pa_sink_input_assert_ref(i
);
1391 pa_assert_ctl_context();
1392 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1395 if (!pa_sink_input_may_move(i
))
1396 return -PA_ERR_NOTSUPPORTED
;
1398 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1401 /* Kill directly connected outputs */
1402 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1404 pa_source_output_kill(o
);
1407 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1409 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1411 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1412 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1414 if (pa_sink_flat_volume_enabled(i
->sink
))
1415 /* We might need to update the sink's volume if we are in flat
1417 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1419 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1421 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
1422 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
1423 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
1425 pa_sink_update_status(i
->sink
);
1426 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1429 pa_sink_input_unref(i
);
1434 /* Called from main context. If i has an origin sink that uses volume sharing,
1435 * then also the origin sink and all streams connected to it need to update
1436 * their volume - this function does all that by using recursion. */
1437 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1438 pa_cvolume old_volume
;
1442 pa_assert(i
->sink
); /* The destination sink should already be set. */
1444 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1445 pa_sink
*root_sink
= i
->sink
;
1446 pa_sink_input
*origin_sink_input
;
1449 while (root_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)
1450 root_sink
= root_sink
->input_to_master
->sink
;
1452 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1453 /* Ok, so the origin sink uses volume sharing, and flat volume is
1454 * enabled. The volume will have to be updated as follows:
1456 * i->volume := i->sink->real_volume
1457 * (handled later by pa_sink_set_volume)
1458 * i->reference_ratio := i->volume / i->sink->reference_volume
1459 * (handled later by pa_sink_set_volume)
1460 * i->real_ratio stays unchanged
1461 * (streams whose origin sink uses volume sharing should
1462 * always have real_ratio of 0 dB)
1463 * i->soft_volume stays unchanged
1464 * (streams whose origin sink uses volume sharing should
1465 * always have volume_factor as soft_volume, so no change
1466 * should be needed) */
1468 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1469 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1471 /* Notifications will be sent by pa_sink_set_volume(). */
1474 /* Ok, so the origin sink uses volume sharing, and flat volume is
1475 * disabled. The volume will have to be updated as follows:
1478 * i->reference_ratio := 0 dB
1479 * i->real_ratio stays unchanged
1480 * (streams whose origin sink uses volume sharing should
1481 * always have real_ratio of 0 dB)
1482 * i->soft_volume stays unchanged
1483 * (streams whose origin sink uses volume sharing should
1484 * always have volume_factor as soft_volume, so no change
1485 * should be needed) */
1487 old_volume
= i
->volume
;
1488 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1489 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1490 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1491 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1493 /* Notify others about the changed sink input volume. */
1494 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1495 if (i
->volume_changed
)
1496 i
->volume_changed(i
);
1498 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1502 /* Additionally, the origin sink volume needs updating:
1504 * i->origin_sink->reference_volume := root_sink->reference_volume
1505 * i->origin_sink->real_volume := root_sink->real_volume
1506 * i->origin_sink->soft_volume stays unchanged
1507 * (sinks that use volume sharing should always have
1508 * soft_volume of 0 dB) */
1510 old_volume
= i
->origin_sink
->reference_volume
;
1512 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1513 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1515 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1516 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1518 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1520 /* Notify others about the changed sink volume. If you wonder whether
1521 * i->origin_sink->set_volume() should be called somewhere, that's not
1522 * the case, because sinks that use volume sharing shouldn't have any
1523 * internal volume that set_volume() would update. If you wonder
1524 * whether the thread_info variables should be synced, yes, they
1525 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1527 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1528 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1530 /* Recursively update origin sink inputs. */
1531 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1532 update_volume_due_to_moving(origin_sink_input
, dest
);
1535 old_volume
= i
->volume
;
1537 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1538 /* Ok, so this is a regular stream, and flat volume is enabled. The
1539 * volume will have to be updated as follows:
1541 * i->volume := i->reference_ratio * i->sink->reference_volume
1542 * i->reference_ratio stays unchanged
1543 * i->real_ratio := i->volume / i->sink->real_volume
1544 * (handled later by pa_sink_set_volume)
1545 * i->soft_volume := i->real_ratio * i->volume_factor
1546 * (handled later by pa_sink_set_volume) */
1548 i
->volume
= i
->sink
->reference_volume
;
1549 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1550 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1553 /* Ok, so this is a regular stream, and flat volume is disabled.
1554 * The volume will have to be updated as follows:
1556 * i->volume := i->reference_ratio
1557 * i->reference_ratio stays unchanged
1558 * i->real_ratio := i->reference_ratio
1559 * i->soft_volume := i->real_ratio * i->volume_factor */
1561 i
->volume
= i
->reference_ratio
;
1562 i
->real_ratio
= i
->reference_ratio
;
1563 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1566 /* Notify others about the changed sink input volume. */
1567 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1568 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1569 * and soft_volume are not updated yet. Let's hope that the
1570 * callback implementation doesn't care about those variables... */
1571 if (i
->volume_changed
)
1572 i
->volume_changed(i
);
1574 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1578 /* If i->sink == dest, then recursion has finished, and we can finally call
1579 * pa_sink_set_volume(), which will do the rest of the updates. */
1580 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1581 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1584 /* Called from main context */
1585 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1586 pa_resampler
*new_resampler
;
1588 pa_sink_input_assert_ref(i
);
1589 pa_assert_ctl_context();
1590 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1591 pa_assert(!i
->sink
);
1592 pa_sink_assert_ref(dest
);
1594 if (!pa_sink_input_may_move_to(i
, dest
))
1595 return -PA_ERR_NOTSUPPORTED
;
1597 if (pa_sink_input_is_passthrough(i
) && !pa_sink_check_format(dest
, i
->format
)) {
1598 pa_proplist
*p
= pa_proplist_new();
1599 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1600 /* Tell the client what device we want to be on if it is going to
1602 pa_proplist_sets(p
, "device", dest
->name
);
1603 pa_sink_input_send_event(i
, PA_STREAM_EVENT_FORMAT_LOST
, p
);
1604 pa_proplist_free(p
);
1605 return -PA_ERR_NOTSUPPORTED
;
1608 if (i
->thread_info
.resampler
&&
1609 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1610 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1612 /* Try to reuse the old resampler if possible */
1613 new_resampler
= i
->thread_info
.resampler
;
1615 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1616 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1617 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1619 /* Okay, we need a new resampler for the new sink */
1621 if (!(new_resampler
= pa_resampler_new(
1623 &i
->sample_spec
, &i
->channel_map
,
1624 &dest
->sample_spec
, &dest
->channel_map
,
1625 i
->requested_resample_method
,
1626 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1627 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1628 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1629 pa_log_warn("Unsupported resampling operation.");
1630 return -PA_ERR_NOTSUPPORTED
;
1633 new_resampler
= NULL
;
1639 i
->save_sink
= save
;
1640 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1642 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1644 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1645 i
->sink
->n_corked
++;
1647 /* Replace resampler and render queue */
1648 if (new_resampler
!= i
->thread_info
.resampler
) {
1650 if (i
->thread_info
.resampler
)
1651 pa_resampler_free(i
->thread_info
.resampler
);
1652 i
->thread_info
.resampler
= new_resampler
;
1654 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1656 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1658 MEMBLOCKQ_MAXLENGTH
,
1660 pa_frame_size(&i
->sink
->sample_spec
),
1665 i
->actual_resample_method
= new_resampler
? pa_resampler_get_method(new_resampler
) : PA_RESAMPLER_INVALID
;
1668 pa_sink_update_status(dest
);
1670 update_volume_due_to_moving(i
, dest
);
1672 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1674 /* If we're entering passthrough mode, disable the monitor */
1675 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
1676 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
1678 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1680 /* Notify everyone */
1681 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1682 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1687 /* Called from main context */
1688 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1690 pa_sink_input_assert_ref(i
);
1691 pa_assert_ctl_context();
1692 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1693 pa_assert(!i
->sink
);
1695 /* Check if someone wants this sink input? */
1696 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1702 pa_sink_input_kill(i
);
1705 /* Called from main context */
1706 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1709 pa_sink_input_assert_ref(i
);
1710 pa_assert_ctl_context();
1711 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1713 pa_sink_assert_ref(dest
);
1715 if (dest
== i
->sink
)
1718 if (!pa_sink_input_may_move_to(i
, dest
))
1719 return -PA_ERR_NOTSUPPORTED
;
1721 pa_sink_input_ref(i
);
1723 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1724 pa_sink_input_unref(i
);
1728 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1729 pa_sink_input_fail_move(i
);
1730 pa_sink_input_unref(i
);
1734 pa_sink_input_unref(i
);
1739 /* Called from IO thread context */
1740 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1741 pa_bool_t corking
, uncorking
;
1743 pa_sink_input_assert_ref(i
);
1744 pa_sink_input_assert_io_context(i
);
1746 if (state
== i
->thread_info
.state
)
1749 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1750 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1751 pa_atomic_store(&i
->thread_info
.drained
, 1);
1753 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1754 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1756 if (i
->state_change
)
1757 i
->state_change(i
, state
);
1759 i
->thread_info
.state
= state
;
1763 pa_log_debug("Requesting rewind due to corking");
1765 /* This will tell the implementing sink input driver to rewind
1766 * so that the unplayed already mixed data is not lost */
1767 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1769 } else if (uncorking
) {
1771 i
->thread_info
.underrun_for
= (uint64_t) -1;
1772 i
->thread_info
.playing_for
= 0;
1774 pa_log_debug("Requesting rewind due to uncorking");
1776 /* OK, we're being uncorked. Make sure we're not rewound when
1777 * the hw buffer is remixed and request a remix. */
1778 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
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 /* pa_log_debug("request rewrite %zu", nbytes); */
1910 /* Calculate how much we can rewind locally without having to
1913 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1917 /* Check if rewinding for the maximum is requested, and if so, fix up */
1920 /* Calculate maximum number of bytes that could be rewound in theory */
1921 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1923 /* Transform from sink domain */
1924 if (i
->thread_info
.resampler
)
1925 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1928 /* Remember how much we actually want to rewrite */
1929 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1931 /* Make sure to not overwrite over underruns */
1932 if (nbytes
> i
->thread_info
.playing_for
)
1933 nbytes
= (size_t) i
->thread_info
.playing_for
;
1935 i
->thread_info
.rewrite_nbytes
= nbytes
;
1937 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1940 i
->thread_info
.rewrite_flush
=
1941 i
->thread_info
.rewrite_flush
||
1942 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1944 i
->thread_info
.dont_rewind_render
=
1945 i
->thread_info
.dont_rewind_render
||
1948 if (nbytes
!= (size_t) -1) {
1950 /* Transform to sink domain */
1951 if (i
->thread_info
.resampler
)
1952 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1955 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1957 /* This call will make sure process_rewind() is called later */
1958 pa_sink_request_rewind(i
->sink
, 0);
1962 /* Called from main context */
1963 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1964 pa_sink_input_assert_ref(i
);
1965 pa_assert_ctl_context();
1968 /* FIXME: Shouldn't access resampler object from main context! */
1970 pa_silence_memchunk_get(
1971 &i
->core
->silence_cache
,
1975 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1980 /* Called from main context */
1981 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1982 pa_proplist
*pl
= NULL
;
1983 pa_sink_input_send_event_hook_data hook_data
;
1985 pa_sink_input_assert_ref(i
);
1986 pa_assert_ctl_context();
1993 data
= pl
= pa_proplist_new();
1995 hook_data
.sink_input
= i
;
1996 hook_data
.data
= data
;
1997 hook_data
.event
= event
;
1999 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
2002 i
->send_event(i
, event
, data
);
2006 pa_proplist_free(pl
);