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>
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 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
56 data
->resample_method
= PA_RESAMPLER_INVALID
;
57 data
->proplist
= pa_proplist_new();
62 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
65 if ((data
->sample_spec_is_set
= !!spec
))
66 data
->sample_spec
= *spec
;
69 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
72 if ((data
->channel_map_is_set
= !!map
))
73 data
->channel_map
= *map
;
76 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
79 if ((data
->volume_is_set
= !!volume
))
80 data
->volume
= *volume
;
83 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
85 pa_assert(volume_factor
);
87 if (data
->volume_factor_is_set
)
88 pa_sw_cvolume_multiply(&data
->volume_factor
, &data
->volume_factor
, volume_factor
);
90 data
->volume_factor_is_set
= TRUE
;
91 data
->volume_factor
= *volume_factor
;
95 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
97 pa_assert(volume_factor
);
99 if (data
->volume_factor_sink_is_set
)
100 pa_sw_cvolume_multiply(&data
->volume_factor_sink
, &data
->volume_factor_sink
, volume_factor
);
102 data
->volume_factor_sink_is_set
= TRUE
;
103 data
->volume_factor_sink
= *volume_factor
;
107 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
110 data
->muted_is_set
= TRUE
;
111 data
->muted
= !!mute
;
114 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
117 pa_proplist_free(data
->proplist
);
120 /* Called from main context */
121 static void reset_callbacks(pa_sink_input
*i
) {
125 i
->process_rewind
= NULL
;
126 i
->update_max_rewind
= NULL
;
127 i
->update_max_request
= NULL
;
128 i
->update_sink_requested_latency
= NULL
;
129 i
->update_sink_latency_range
= NULL
;
130 i
->update_sink_fixed_latency
= NULL
;
134 i
->suspend_within_thread
= NULL
;
137 i
->get_latency
= NULL
;
138 i
->state_change
= NULL
;
139 i
->may_move_to
= NULL
;
140 i
->send_event
= NULL
;
141 i
->volume_changed
= NULL
;
142 i
->mute_changed
= NULL
;
145 /* Called from main context */
146 int pa_sink_input_new(
149 pa_sink_input_new_data
*data
) {
152 pa_resampler
*resampler
= NULL
;
153 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
154 pa_channel_map original_cm
;
160 pa_assert_ctl_context();
163 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
165 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
168 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
171 data
->sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
172 data
->save_sink
= FALSE
;
175 pa_return_val_if_fail(data
->sink
, -PA_ERR_NOENTITY
);
176 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
177 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
);
179 if (!data
->sample_spec_is_set
)
180 data
->sample_spec
= data
->sink
->sample_spec
;
182 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
184 if (!data
->channel_map_is_set
) {
185 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
186 data
->channel_map
= data
->sink
->channel_map
;
188 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
191 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
193 if (!data
->volume_is_set
) {
194 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
195 data
->volume_is_absolute
= FALSE
;
196 data
->save_volume
= FALSE
;
199 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
201 if (!data
->volume_factor_is_set
)
202 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
204 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
206 if (!data
->volume_factor_sink_is_set
)
207 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
209 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
211 if (!data
->muted_is_set
)
214 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
215 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
217 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
218 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
220 original_cm
= data
->channel_map
;
222 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
223 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
224 data
->channel_map
= data
->sink
->channel_map
;
227 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
228 pa_assert(pa_channel_map_valid(&data
->channel_map
));
230 /* Due to the fixing of the sample spec the volume might not match anymore */
231 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
233 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
234 data
->resample_method
= core
->resample_method
;
236 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
238 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
241 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
242 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
243 pa_log_warn("Failed to create sink input: sink is suspended.");
244 return -PA_ERR_BADSTATE
;
247 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
248 pa_log_warn("Failed to create sink input: too many inputs per sink.");
249 return -PA_ERR_TOOLARGE
;
252 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
253 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
254 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
256 if (!(resampler
= pa_resampler_new(
258 &data
->sample_spec
, &data
->channel_map
,
259 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
260 data
->resample_method
,
261 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
262 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
263 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
264 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
265 pa_log_warn("Unsupported resampling operation.");
266 return -PA_ERR_NOTSUPPORTED
;
270 i
= pa_msgobject_new(pa_sink_input
);
271 i
->parent
.parent
.free
= sink_input_free
;
272 i
->parent
.process_msg
= pa_sink_input_process_msg
;
275 i
->state
= PA_SINK_INPUT_INIT
;
276 i
->flags
= data
->flags
;
277 i
->proplist
= pa_proplist_copy(data
->proplist
);
278 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
279 i
->module
= data
->module
;
280 i
->sink
= data
->sink
;
281 i
->client
= data
->client
;
283 i
->requested_resample_method
= data
->resample_method
;
284 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
285 i
->sample_spec
= data
->sample_spec
;
286 i
->channel_map
= data
->channel_map
;
288 if ((i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) && !data
->volume_is_absolute
) {
291 /* When the 'absolute' bool is not set then we'll treat the volume
292 * as relative to the sink volume even in flat volume mode */
293 remapped
= data
->sink
->reference_volume
;
294 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
295 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
297 i
->volume
= data
->volume
;
299 i
->volume_factor
= data
->volume_factor
;
300 i
->volume_factor_sink
= data
->volume_factor_sink
;
301 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
302 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
303 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
304 i
->save_volume
= data
->save_volume
;
305 i
->save_sink
= data
->save_sink
;
306 i
->save_muted
= data
->save_muted
;
308 i
->muted
= data
->muted
;
310 if (data
->sync_base
) {
311 i
->sync_next
= data
->sync_base
->sync_next
;
312 i
->sync_prev
= data
->sync_base
;
314 if (data
->sync_base
->sync_next
)
315 data
->sync_base
->sync_next
->sync_prev
= i
;
316 data
->sync_base
->sync_next
= i
;
318 i
->sync_next
= i
->sync_prev
= NULL
;
320 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
325 i
->thread_info
.state
= i
->state
;
326 i
->thread_info
.attached
= FALSE
;
327 pa_atomic_store(&i
->thread_info
.drained
, 1);
328 i
->thread_info
.sample_spec
= i
->sample_spec
;
329 i
->thread_info
.resampler
= resampler
;
330 i
->thread_info
.soft_volume
= i
->soft_volume
;
331 i
->thread_info
.muted
= i
->muted
;
332 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
333 i
->thread_info
.rewrite_nbytes
= 0;
334 i
->thread_info
.rewrite_flush
= FALSE
;
335 i
->thread_info
.dont_rewind_render
= FALSE
;
336 i
->thread_info
.underrun_for
= (uint64_t) -1;
337 i
->thread_info
.playing_for
= 0;
338 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
340 i
->thread_info
.render_memblockq
= pa_memblockq_new(
344 pa_frame_size(&i
->sink
->sample_spec
),
350 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
351 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
354 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
356 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s",
358 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
360 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
361 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
));
363 /* Don't forget to call pa_sink_input_put! */
369 /* Called from main context */
370 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
372 pa_assert_ctl_context();
377 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
378 pa_assert_se(i
->sink
->n_corked
-- >= 1);
379 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
383 /* Called from main context */
384 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
385 pa_sink_input
*ssync
;
387 pa_assert_ctl_context();
389 if (state
== PA_SINK_INPUT_DRAINED
)
390 state
= PA_SINK_INPUT_RUNNING
;
392 if (i
->state
== state
)
395 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);
397 update_n_corked(i
, state
);
400 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
401 update_n_corked(ssync
, state
);
402 ssync
->state
= state
;
404 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
405 update_n_corked(ssync
, state
);
406 ssync
->state
= state
;
409 if (state
!= PA_SINK_INPUT_UNLINKED
) {
410 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
412 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
413 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
415 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
416 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
419 pa_sink_update_status(i
->sink
);
422 /* Called from main context */
423 void pa_sink_input_unlink(pa_sink_input
*i
) {
425 pa_source_output
*o
, *p
= NULL
;
428 pa_assert_ctl_context();
430 /* See pa_sink_unlink() for a couple of comments how this function
433 pa_sink_input_ref(i
);
435 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
438 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
441 i
->sync_prev
->sync_next
= i
->sync_next
;
443 i
->sync_next
->sync_prev
= i
->sync_prev
;
445 i
->sync_prev
= i
->sync_next
= NULL
;
447 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
450 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
451 pa_sink_input_unref(i
);
454 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
456 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
458 pa_source_output_kill(o
);
462 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
463 i
->state
= PA_SINK_INPUT_UNLINKED
;
465 if (linked
&& i
->sink
) {
466 /* We might need to update the sink's volume if we are in flat volume mode. */
467 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
468 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
470 if (i
->sink
->asyncmsgq
)
471 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
477 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
478 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
482 pa_sink_update_status(i
->sink
);
486 pa_core_maybe_vacuum(i
->core
);
488 pa_sink_input_unref(i
);
491 /* Called from main context */
492 static void sink_input_free(pa_object
*o
) {
493 pa_sink_input
* i
= PA_SINK_INPUT(o
);
496 pa_assert_ctl_context();
497 pa_assert(pa_sink_input_refcnt(i
) == 0);
499 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
500 pa_sink_input_unlink(i
);
502 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
504 /* Side note: this function must be able to destruct properly any
505 * kind of sink input in any state, even those which are
506 * "half-moved" or are connected to sinks that have no asyncmsgq
507 * and are hence half-destructed themselves! */
509 if (i
->thread_info
.render_memblockq
)
510 pa_memblockq_free(i
->thread_info
.render_memblockq
);
512 if (i
->thread_info
.resampler
)
513 pa_resampler_free(i
->thread_info
.resampler
);
516 pa_proplist_free(i
->proplist
);
518 if (i
->direct_outputs
)
519 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
521 if (i
->thread_info
.direct_outputs
)
522 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
528 /* Called from main context */
529 void pa_sink_input_put(pa_sink_input
*i
) {
530 pa_sink_input_state_t state
;
532 pa_sink_input_assert_ref(i
);
533 pa_assert_ctl_context();
535 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
537 /* The following fields must be initialized properly */
539 pa_assert(i
->process_rewind
);
542 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
544 update_n_corked(i
, state
);
547 /* We might need to update the sink's volume if we are in flat volume mode. */
548 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
549 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
551 set_real_ratio(i
, &i
->volume
);
553 i
->thread_info
.soft_volume
= i
->soft_volume
;
554 i
->thread_info
.muted
= i
->muted
;
556 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
558 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
559 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
561 pa_sink_update_status(i
->sink
);
564 /* Called from main context */
565 void pa_sink_input_kill(pa_sink_input
*i
) {
566 pa_sink_input_assert_ref(i
);
567 pa_assert_ctl_context();
568 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
573 /* Called from main context */
574 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
575 pa_usec_t r
[2] = { 0, 0 };
577 pa_sink_input_assert_ref(i
);
578 pa_assert_ctl_context();
579 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
581 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
584 r
[0] += i
->get_latency(i
);
587 *sink_latency
= r
[1];
592 /* Called from thread context */
593 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
594 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
595 pa_bool_t volume_is_norm
;
596 size_t block_size_max_sink
, block_size_max_sink_input
;
599 pa_sink_input_assert_ref(i
);
600 pa_sink_input_assert_io_context(i
);
601 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
602 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
606 /* pa_log_debug("peek"); */
608 pa_assert(i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
||
609 i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
610 i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
);
612 block_size_max_sink_input
= i
->thread_info
.resampler
?
613 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
614 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
616 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
618 /* Default buffer size */
620 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
622 if (slength
> block_size_max_sink
)
623 slength
= block_size_max_sink
;
625 if (i
->thread_info
.resampler
) {
626 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
629 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
633 if (ilength
> block_size_max_sink_input
)
634 ilength
= block_size_max_sink_input
;
636 /* If the channel maps of the sink and this stream differ, we need
637 * to adjust the volume *before* we resample. Otherwise we can do
638 * it after and leave it for the sink code */
640 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
641 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
642 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
644 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
647 /* There's nothing in our render queue. We need to fill it up
648 * with data from the implementor. */
650 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
651 i
->pop(i
, ilength
, &tchunk
) < 0) {
653 /* OK, we're corked or the implementor didn't give us any
654 * data, so let's just hand out silence */
655 pa_atomic_store(&i
->thread_info
.drained
, 1);
657 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
658 i
->thread_info
.playing_for
= 0;
659 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
660 i
->thread_info
.underrun_for
+= ilength
;
664 pa_atomic_store(&i
->thread_info
.drained
, 0);
666 pa_assert(tchunk
.length
> 0);
667 pa_assert(tchunk
.memblock
);
669 i
->thread_info
.underrun_for
= 0;
670 i
->thread_info
.playing_for
+= tchunk
.length
;
672 while (tchunk
.length
> 0) {
674 pa_bool_t nvfs
= need_volume_factor_sink
;
677 pa_memblock_ref(wchunk
.memblock
);
679 if (wchunk
.length
> block_size_max_sink_input
)
680 wchunk
.length
= block_size_max_sink_input
;
682 /* It might be necessary to adjust the volume here */
683 if (do_volume_adj_here
&& !volume_is_norm
) {
684 pa_memchunk_make_writable(&wchunk
, 0);
686 if (i
->thread_info
.muted
) {
687 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
690 } else if (!i
->thread_info
.resampler
&& nvfs
) {
693 /* If we don't need a resampler we can merge the
694 * post and the pre volume adjustment into one */
696 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
697 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
701 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
704 if (!i
->thread_info
.resampler
) {
707 pa_memchunk_make_writable(&wchunk
, 0);
708 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
711 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
714 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
717 pa_memchunk_make_writable(&rchunk
, 0);
718 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
721 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
723 if (rchunk
.memblock
) {
724 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
725 pa_memblock_unref(rchunk
.memblock
);
729 pa_memblock_unref(wchunk
.memblock
);
731 tchunk
.index
+= wchunk
.length
;
732 tchunk
.length
-= wchunk
.length
;
735 pa_memblock_unref(tchunk
.memblock
);
738 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
740 pa_assert(chunk
->length
> 0);
741 pa_assert(chunk
->memblock
);
743 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
745 if (chunk
->length
> block_size_max_sink
)
746 chunk
->length
= block_size_max_sink
;
748 /* Let's see if we had to apply the volume adjustment ourselves,
749 * or if this can be done by the sink for us */
751 if (do_volume_adj_here
)
752 /* We had different channel maps, so we already did the adjustment */
753 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
754 else if (i
->thread_info
.muted
)
755 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
756 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
758 *volume
= i
->thread_info
.soft_volume
;
761 /* Called from thread context */
762 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
764 pa_sink_input_assert_ref(i
);
765 pa_sink_input_assert_io_context(i
);
766 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
767 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
768 pa_assert(nbytes
> 0);
770 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
772 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
775 /* Called from thread context */
776 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
778 pa_bool_t called
= FALSE
;
780 pa_sink_input_assert_ref(i
);
781 pa_sink_input_assert_io_context(i
);
782 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
783 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
785 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
787 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
789 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
790 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
791 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
794 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
796 /* We were asked to drop all buffered data, and rerequest new
797 * data from implementor the next time push() is called */
799 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
);
801 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
802 size_t max_rewrite
, amount
;
804 /* Calculate how much make sense to rewrite at most */
805 max_rewrite
= nbytes
+ lbq
;
807 /* Transform into local domain */
808 if (i
->thread_info
.resampler
)
809 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
811 /* Calculate how much of the rewinded data should actually be rewritten */
812 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
815 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
817 /* Tell the implementor */
818 if (i
->process_rewind
)
819 i
->process_rewind(i
, amount
);
822 /* Convert back to to sink domain */
823 if (i
->thread_info
.resampler
)
824 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
827 /* Ok, now update the write pointer */
828 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
830 if (i
->thread_info
.rewrite_flush
)
831 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
833 /* And reset the resampler */
834 if (i
->thread_info
.resampler
)
835 pa_resampler_reset(i
->thread_info
.resampler
);
840 if (i
->process_rewind
)
841 i
->process_rewind(i
, 0);
843 i
->thread_info
.rewrite_nbytes
= 0;
844 i
->thread_info
.rewrite_flush
= FALSE
;
845 i
->thread_info
.dont_rewind_render
= FALSE
;
848 /* Called from thread context */
849 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
850 pa_sink_input_assert_ref(i
);
851 pa_sink_input_assert_io_context(i
);
853 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
856 /* Called from thread context */
857 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
858 pa_sink_input_assert_ref(i
);
859 pa_sink_input_assert_io_context(i
);
861 /* We're not verifying the status here, to allow this to be called
862 * in the state change handler between _INIT and _RUNNING */
864 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
867 /* Called from thread context */
868 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
869 pa_sink_input_assert_ref(i
);
870 pa_sink_input_assert_io_context(i
);
871 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
872 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
874 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
876 if (i
->update_max_rewind
)
877 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
880 /* Called from thread context */
881 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
882 pa_sink_input_assert_ref(i
);
883 pa_sink_input_assert_io_context(i
);
884 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
885 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
887 if (i
->update_max_request
)
888 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
891 /* Called from thread context */
892 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
893 pa_sink_input_assert_ref(i
);
894 pa_sink_input_assert_io_context(i
);
896 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
897 usec
= i
->sink
->thread_info
.fixed_latency
;
899 if (usec
!= (pa_usec_t
) -1)
900 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
902 i
->thread_info
.requested_sink_latency
= usec
;
903 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
908 /* Called from main context */
909 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
910 pa_sink_input_assert_ref(i
);
911 pa_assert_ctl_context();
913 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
914 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
918 /* If this sink input is not realized yet or we are being moved,
919 * we have to touch the thread info data directly */
922 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
923 usec
= pa_sink_get_fixed_latency(i
->sink
);
925 if (usec
!= (pa_usec_t
) -1) {
926 pa_usec_t min_latency
, max_latency
;
927 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
928 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
932 i
->thread_info
.requested_sink_latency
= usec
;
937 /* Called from main context */
938 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
939 pa_sink_input_assert_ref(i
);
940 pa_assert_ctl_context();
942 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
944 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
948 /* If this sink input is not realized yet or we are being moved,
949 * we have to touch the thread info data directly */
951 return i
->thread_info
.requested_sink_latency
;
954 /* Called from main context */
955 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
956 pa_sink_input_assert_ref(i
);
957 pa_assert_ctl_context();
958 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
959 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
961 /* This basically calculates:
964 * i->soft_volume := i->real_ratio * i->volume_factor */
969 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
971 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
972 /* We don't copy the data to the thread_info data. That's left for someone else to do */
975 /* Called from main context */
976 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
979 pa_sink_input_assert_ref(i
);
980 pa_assert_ctl_context();
981 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
983 pa_assert(pa_cvolume_valid(volume
));
984 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
986 if ((i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) && !absolute
) {
987 v
= i
->sink
->reference_volume
;
988 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
990 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
991 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
993 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
996 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
998 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1002 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1003 i
->save_volume
= i
->save_volume
|| save
;
1007 i
->volume
= *volume
;
1008 i
->save_volume
= save
;
1010 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1011 /* We are in flat volume mode, so let's update all sink input
1012 * volumes and update the flat volume of the sink */
1014 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1017 /* OK, we are in normal volume mode. The volume only affects
1019 set_real_ratio(i
, volume
);
1021 /* Copy the new soft_volume to the thread_info struct */
1022 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1025 /* The volume changed, let's tell people so */
1026 if (i
->volume_changed
)
1027 i
->volume_changed(i
);
1029 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1032 /* Called from main context */
1033 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1034 pa_sink_input_assert_ref(i
);
1035 pa_assert_ctl_context();
1036 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1038 if (absolute
|| !(i
->sink
->flags
& PA_SINK_FLAT_VOLUME
))
1039 *volume
= i
->volume
;
1041 *volume
= i
->reference_ratio
;
1046 /* Called from main context */
1047 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1048 pa_sink_input_assert_ref(i
);
1049 pa_assert_ctl_context();
1050 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1052 if (!i
->muted
== !mute
)
1056 i
->save_muted
= save
;
1058 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1060 /* The mute status changed, let's tell people so */
1061 if (i
->mute_changed
)
1064 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1067 /* Called from main context */
1068 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1069 pa_sink_input_assert_ref(i
);
1070 pa_assert_ctl_context();
1071 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1076 /* Called from main thread */
1077 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1078 pa_sink_input_assert_ref(i
);
1079 pa_assert_ctl_context();
1082 pa_proplist_update(i
->proplist
, mode
, p
);
1084 if (PA_SINK_IS_LINKED(i
->state
)) {
1085 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1086 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1090 /* Called from main context */
1091 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1092 pa_sink_input_assert_ref(i
);
1093 pa_assert_ctl_context();
1094 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1096 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1099 /* Called from main context */
1100 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1101 pa_sink_input_assert_ref(i
);
1102 pa_assert_ctl_context();
1103 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1104 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1106 if (i
->sample_spec
.rate
== rate
)
1109 i
->sample_spec
.rate
= rate
;
1111 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1113 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1117 /* Called from main context */
1118 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1120 pa_sink_input_assert_ref(i
);
1121 pa_assert_ctl_context();
1123 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1126 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1128 if (old
&& name
&& pa_streq(old
, name
))
1132 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1134 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1136 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1137 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1138 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1142 /* Called from main context */
1143 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1144 pa_sink_input_assert_ref(i
);
1145 pa_assert_ctl_context();
1147 return i
->actual_resample_method
;
1150 /* Called from main context */
1151 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1152 pa_sink_input_assert_ref(i
);
1153 pa_assert_ctl_context();
1154 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1156 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1159 if (i
->sync_next
|| i
->sync_prev
) {
1160 pa_log_warn("Moving synchronised streams not supported.");
1167 /* Called from main context */
1168 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1169 pa_sink_input_assert_ref(i
);
1170 pa_assert_ctl_context();
1171 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1172 pa_sink_assert_ref(dest
);
1174 if (dest
== i
->sink
)
1177 if (!pa_sink_input_may_move(i
))
1180 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1181 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1186 if (!i
->may_move_to(i
, dest
))
1192 /* Called from main context */
1193 int pa_sink_input_start_move(pa_sink_input
*i
) {
1194 pa_source_output
*o
, *p
= NULL
;
1197 pa_sink_input_assert_ref(i
);
1198 pa_assert_ctl_context();
1199 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1202 if (!pa_sink_input_may_move(i
))
1203 return -PA_ERR_NOTSUPPORTED
;
1205 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1208 /* Kill directly connected outputs */
1209 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1211 pa_source_output_kill(o
);
1214 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1216 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1218 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1219 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1221 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1222 /* We might need to update the sink's volume if we are in flat
1224 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1226 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1228 pa_sink_update_status(i
->sink
);
1229 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1232 pa_sink_input_unref(i
);
1237 /* Called from main context */
1238 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1239 pa_resampler
*new_resampler
;
1241 pa_sink_input_assert_ref(i
);
1242 pa_assert_ctl_context();
1243 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1244 pa_assert(!i
->sink
);
1245 pa_sink_assert_ref(dest
);
1247 if (!pa_sink_input_may_move_to(i
, dest
))
1248 return -PA_ERR_NOTSUPPORTED
;
1250 if (i
->thread_info
.resampler
&&
1251 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1252 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1254 /* Try to reuse the old resampler if possible */
1255 new_resampler
= i
->thread_info
.resampler
;
1257 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1258 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1259 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1261 /* Okey, we need a new resampler for the new sink */
1263 if (!(new_resampler
= pa_resampler_new(
1265 &i
->sample_spec
, &i
->channel_map
,
1266 &dest
->sample_spec
, &dest
->channel_map
,
1267 i
->requested_resample_method
,
1268 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1269 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1270 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1271 pa_log_warn("Unsupported resampling operation.");
1272 return -PA_ERR_NOTSUPPORTED
;
1275 new_resampler
= NULL
;
1281 i
->save_sink
= save
;
1282 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1284 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1286 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1287 i
->sink
->n_corked
++;
1289 /* Replace resampler and render queue */
1290 if (new_resampler
!= i
->thread_info
.resampler
) {
1292 if (i
->thread_info
.resampler
)
1293 pa_resampler_free(i
->thread_info
.resampler
);
1294 i
->thread_info
.resampler
= new_resampler
;
1296 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1298 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1300 MEMBLOCKQ_MAXLENGTH
,
1302 pa_frame_size(&i
->sink
->sample_spec
),
1308 pa_sink_update_status(dest
);
1310 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) {
1311 pa_cvolume remapped
;
1313 /* Make relative volumes absolute */
1314 remapped
= dest
->reference_volume
;
1315 pa_cvolume_remap(&remapped
, &dest
->channel_map
, &i
->channel_map
);
1316 pa_sw_cvolume_multiply(&i
->volume
, &i
->reference_ratio
, &remapped
);
1318 /* We might need to update the sink's volume if we are in flat volume mode. */
1319 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1322 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1324 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1326 /* Notify everyone */
1327 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1329 if (i
->volume_changed
)
1330 i
->volume_changed(i
);
1332 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1337 /* Called from main context */
1338 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1340 pa_sink_input_assert_ref(i
);
1341 pa_assert_ctl_context();
1342 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1343 pa_assert(!i
->sink
);
1345 /* Check if someone wants this sink input? */
1346 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1352 pa_sink_input_kill(i
);
1355 /* Called from main context */
1356 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1359 pa_sink_input_assert_ref(i
);
1360 pa_assert_ctl_context();
1361 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1363 pa_sink_assert_ref(dest
);
1365 if (dest
== i
->sink
)
1368 if (!pa_sink_input_may_move_to(i
, dest
))
1369 return -PA_ERR_NOTSUPPORTED
;
1371 pa_sink_input_ref(i
);
1373 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1374 pa_sink_input_unref(i
);
1378 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1379 pa_sink_input_fail_move(i
);
1380 pa_sink_input_unref(i
);
1384 pa_sink_input_unref(i
);
1389 /* Called from IO thread context */
1390 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1391 pa_bool_t corking
, uncorking
;
1393 pa_sink_input_assert_ref(i
);
1394 pa_sink_input_assert_io_context(i
);
1396 if (state
== i
->thread_info
.state
)
1399 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1400 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1401 pa_atomic_store(&i
->thread_info
.drained
, 1);
1403 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1404 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1406 if (i
->state_change
)
1407 i
->state_change(i
, state
);
1409 i
->thread_info
.state
= state
;
1413 pa_log_debug("Requesting rewind due to corking");
1415 /* This will tell the implementing sink input driver to rewind
1416 * so that the unplayed already mixed data is not lost */
1417 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1419 } else if (uncorking
) {
1421 i
->thread_info
.underrun_for
= (uint64_t) -1;
1422 i
->thread_info
.playing_for
= 0;
1424 pa_log_debug("Requesting rewind due to uncorking");
1426 /* OK, we're being uncorked. Make sure we're not rewound when
1427 * the hw buffer is remixed and request a remix. */
1428 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1432 /* Called from thread context, except when it is not. */
1433 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1434 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1435 pa_sink_input_assert_ref(i
);
1439 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1440 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1441 i
->thread_info
.soft_volume
= i
->soft_volume
;
1442 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1446 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1447 if (i
->thread_info
.muted
!= i
->muted
) {
1448 i
->thread_info
.muted
= i
->muted
;
1449 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1453 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1454 pa_usec_t
*r
= userdata
;
1456 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1457 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1462 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1464 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1465 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1469 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1470 pa_sink_input
*ssync
;
1472 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1474 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1475 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1477 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1478 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1483 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1484 pa_usec_t
*usec
= userdata
;
1486 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1490 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1491 pa_usec_t
*r
= userdata
;
1493 *r
= i
->thread_info
.requested_sink_latency
;
1498 return -PA_ERR_NOTIMPLEMENTED
;
1501 /* Called from main thread */
1502 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1503 pa_sink_input_assert_ref(i
);
1504 pa_assert_ctl_context();
1506 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1507 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1512 /* Called from IO context */
1513 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1514 pa_sink_input_assert_ref(i
);
1515 pa_sink_input_assert_io_context(i
);
1517 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1518 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1523 /* Called from IO context */
1524 void pa_sink_input_request_rewind(
1526 size_t nbytes
/* in our sample spec */,
1529 pa_bool_t dont_rewind_render
) {
1533 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1534 * and possible and the exact value of this is passed back the
1535 * implementor via process_rewind(). If 'flush' is also TRUE all
1536 * already rendered data is also dropped.
1538 * If 'rewrite' is FALSE the sink is rewound as far as requested
1539 * and possible and the already rendered data is dropped so that
1540 * in the next iteration we read new data from the
1541 * implementor. This implies 'flush' is TRUE. If
1542 * dont_rewind_render is TRUE then the render memblockq is not
1545 /* nbytes = 0 means maximum rewind request */
1547 pa_sink_input_assert_ref(i
);
1548 pa_sink_input_assert_io_context(i
);
1549 pa_assert(rewrite
|| flush
);
1550 pa_assert(!dont_rewind_render
|| !rewrite
);
1552 /* We don't take rewind requests while we are corked */
1553 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1556 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1558 /* pa_log_debug("request rewrite %zu", nbytes); */
1560 /* Calculate how much we can rewind locally without having to
1563 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1567 /* Check if rewinding for the maximum is requested, and if so, fix up */
1570 /* Calculate maximum number of bytes that could be rewound in theory */
1571 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1573 /* Transform from sink domain */
1574 if (i
->thread_info
.resampler
)
1575 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1578 /* Remember how much we actually want to rewrite */
1579 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1581 /* Make sure to not overwrite over underruns */
1582 if (nbytes
> i
->thread_info
.playing_for
)
1583 nbytes
= (size_t) i
->thread_info
.playing_for
;
1585 i
->thread_info
.rewrite_nbytes
= nbytes
;
1587 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1590 i
->thread_info
.rewrite_flush
=
1591 i
->thread_info
.rewrite_flush
||
1592 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1594 i
->thread_info
.dont_rewind_render
=
1595 i
->thread_info
.dont_rewind_render
||
1598 if (nbytes
!= (size_t) -1) {
1600 /* Transform to sink domain */
1601 if (i
->thread_info
.resampler
)
1602 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1605 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1607 /* This call will make sure process_rewind() is called later */
1608 pa_sink_request_rewind(i
->sink
, 0);
1612 /* Called from main context */
1613 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1614 pa_sink_input_assert_ref(i
);
1615 pa_assert_ctl_context();
1618 /* FIXME: Shouldn't access resampler object from main context! */
1620 pa_silence_memchunk_get(
1621 &i
->core
->silence_cache
,
1625 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1630 /* Called from main context */
1631 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1632 pa_proplist
*pl
= NULL
;
1633 pa_sink_input_send_event_hook_data hook_data
;
1635 pa_sink_input_assert_ref(i
);
1636 pa_assert_ctl_context();
1643 data
= pl
= pa_proplist_new();
1645 hook_data
.sink_input
= i
;
1646 hook_data
.data
= data
;
1647 hook_data
.event
= event
;
1649 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
1652 i
->send_event(i
, event
, data
);
1656 pa_proplist_free(pl
);