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
;
161 pa_assert_ctl_context();
164 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
166 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
169 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
172 data
->sink
= pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
);
173 data
->save_sink
= FALSE
;
176 pa_return_val_if_fail(data
->sink
, -PA_ERR_NOENTITY
);
177 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
178 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
);
180 if (!data
->sample_spec_is_set
)
181 data
->sample_spec
= data
->sink
->sample_spec
;
183 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
185 if (!data
->channel_map_is_set
) {
186 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
187 data
->channel_map
= data
->sink
->channel_map
;
189 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
192 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
194 if (!data
->volume_is_set
) {
195 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
196 data
->volume_is_absolute
= FALSE
;
197 data
->save_volume
= FALSE
;
200 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
202 if (!data
->volume_factor_is_set
)
203 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
205 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
207 if (!data
->volume_factor_sink_is_set
)
208 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
210 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
212 if (!data
->muted_is_set
)
215 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
216 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
218 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
219 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
221 original_cm
= data
->channel_map
;
223 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
224 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
225 data
->channel_map
= data
->sink
->channel_map
;
228 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
229 pa_assert(pa_channel_map_valid(&data
->channel_map
));
231 /* Due to the fixing of the sample spec the volume might not match anymore */
232 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
234 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
235 data
->resample_method
= core
->resample_method
;
237 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
239 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
242 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
243 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
244 pa_log_warn("Failed to create sink input: sink is suspended.");
245 return -PA_ERR_BADSTATE
;
248 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
249 pa_log_warn("Failed to create sink input: too many inputs per sink.");
250 return -PA_ERR_TOOLARGE
;
253 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
254 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
255 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
257 if (!(resampler
= pa_resampler_new(
259 &data
->sample_spec
, &data
->channel_map
,
260 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
261 data
->resample_method
,
262 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
263 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
264 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
265 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
266 pa_log_warn("Unsupported resampling operation.");
267 return -PA_ERR_NOTSUPPORTED
;
271 i
= pa_msgobject_new(pa_sink_input
);
272 i
->parent
.parent
.free
= sink_input_free
;
273 i
->parent
.process_msg
= pa_sink_input_process_msg
;
276 i
->state
= PA_SINK_INPUT_INIT
;
277 i
->flags
= data
->flags
;
278 i
->proplist
= pa_proplist_copy(data
->proplist
);
279 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
280 i
->module
= data
->module
;
281 i
->sink
= data
->sink
;
282 i
->client
= data
->client
;
284 i
->requested_resample_method
= data
->resample_method
;
285 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
286 i
->sample_spec
= data
->sample_spec
;
287 i
->channel_map
= data
->channel_map
;
289 if ((i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) && !data
->volume_is_absolute
) {
292 /* When the 'absolute' bool is not set then we'll treat the volume
293 * as relative to the sink volume even in flat volume mode */
294 remapped
= data
->sink
->reference_volume
;
295 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
296 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
298 i
->volume
= data
->volume
;
300 i
->volume_factor
= data
->volume_factor
;
301 i
->volume_factor_sink
= data
->volume_factor_sink
;
302 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
303 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
304 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
305 i
->save_volume
= data
->save_volume
;
306 i
->save_sink
= data
->save_sink
;
307 i
->save_muted
= data
->save_muted
;
309 i
->muted
= data
->muted
;
311 if (data
->sync_base
) {
312 i
->sync_next
= data
->sync_base
->sync_next
;
313 i
->sync_prev
= data
->sync_base
;
315 if (data
->sync_base
->sync_next
)
316 data
->sync_base
->sync_next
->sync_prev
= i
;
317 data
->sync_base
->sync_next
= i
;
319 i
->sync_next
= i
->sync_prev
= NULL
;
321 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
326 i
->thread_info
.state
= i
->state
;
327 i
->thread_info
.attached
= FALSE
;
328 pa_atomic_store(&i
->thread_info
.drained
, 1);
329 i
->thread_info
.sample_spec
= i
->sample_spec
;
330 i
->thread_info
.resampler
= resampler
;
331 i
->thread_info
.soft_volume
= i
->soft_volume
;
332 i
->thread_info
.muted
= i
->muted
;
333 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
334 i
->thread_info
.rewrite_nbytes
= 0;
335 i
->thread_info
.rewrite_flush
= FALSE
;
336 i
->thread_info
.dont_rewind_render
= FALSE
;
337 i
->thread_info
.underrun_for
= (uint64_t) -1;
338 i
->thread_info
.playing_for
= 0;
339 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
341 i
->thread_info
.render_memblockq
= pa_memblockq_new(
345 pa_frame_size(&i
->sink
->sample_spec
),
351 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
352 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
355 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
357 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
358 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
360 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
362 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
363 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
367 /* Don't forget to call pa_sink_input_put! */
373 /* Called from main context */
374 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
376 pa_assert_ctl_context();
381 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
382 pa_assert_se(i
->sink
->n_corked
-- >= 1);
383 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
387 /* Called from main context */
388 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
389 pa_sink_input
*ssync
;
391 pa_assert_ctl_context();
393 if (state
== PA_SINK_INPUT_DRAINED
)
394 state
= PA_SINK_INPUT_RUNNING
;
396 if (i
->state
== state
)
399 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);
401 update_n_corked(i
, state
);
404 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
405 update_n_corked(ssync
, state
);
406 ssync
->state
= state
;
408 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
409 update_n_corked(ssync
, state
);
410 ssync
->state
= state
;
413 if (state
!= PA_SINK_INPUT_UNLINKED
) {
414 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
416 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
417 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
419 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
420 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
423 pa_sink_update_status(i
->sink
);
426 /* Called from main context */
427 void pa_sink_input_unlink(pa_sink_input
*i
) {
429 pa_source_output
*o
, *p
= NULL
;
432 pa_assert_ctl_context();
434 /* See pa_sink_unlink() for a couple of comments how this function
437 pa_sink_input_ref(i
);
439 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
442 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
445 i
->sync_prev
->sync_next
= i
->sync_next
;
447 i
->sync_next
->sync_prev
= i
->sync_prev
;
449 i
->sync_prev
= i
->sync_next
= NULL
;
451 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
454 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
455 pa_sink_input_unref(i
);
458 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
460 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
462 pa_source_output_kill(o
);
466 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
467 i
->state
= PA_SINK_INPUT_UNLINKED
;
469 if (linked
&& i
->sink
) {
470 /* We might need to update the sink's volume if we are in flat volume mode. */
471 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
472 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
474 if (i
->sink
->asyncmsgq
)
475 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
481 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
482 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
486 pa_sink_update_status(i
->sink
);
490 pa_core_maybe_vacuum(i
->core
);
492 pa_sink_input_unref(i
);
495 /* Called from main context */
496 static void sink_input_free(pa_object
*o
) {
497 pa_sink_input
* i
= PA_SINK_INPUT(o
);
500 pa_assert_ctl_context();
501 pa_assert(pa_sink_input_refcnt(i
) == 0);
503 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
504 pa_sink_input_unlink(i
);
506 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
508 /* Side note: this function must be able to destruct properly any
509 * kind of sink input in any state, even those which are
510 * "half-moved" or are connected to sinks that have no asyncmsgq
511 * and are hence half-destructed themselves! */
513 if (i
->thread_info
.render_memblockq
)
514 pa_memblockq_free(i
->thread_info
.render_memblockq
);
516 if (i
->thread_info
.resampler
)
517 pa_resampler_free(i
->thread_info
.resampler
);
520 pa_proplist_free(i
->proplist
);
522 if (i
->direct_outputs
)
523 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
525 if (i
->thread_info
.direct_outputs
)
526 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
532 /* Called from main context */
533 void pa_sink_input_put(pa_sink_input
*i
) {
534 pa_sink_input_state_t state
;
536 pa_sink_input_assert_ref(i
);
537 pa_assert_ctl_context();
539 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
541 /* The following fields must be initialized properly */
543 pa_assert(i
->process_rewind
);
546 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
548 update_n_corked(i
, state
);
551 /* We might need to update the sink's volume if we are in flat volume mode. */
552 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
553 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
555 set_real_ratio(i
, &i
->volume
);
557 i
->thread_info
.soft_volume
= i
->soft_volume
;
558 i
->thread_info
.muted
= i
->muted
;
560 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
562 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
563 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
565 pa_sink_update_status(i
->sink
);
568 /* Called from main context */
569 void pa_sink_input_kill(pa_sink_input
*i
) {
570 pa_sink_input_assert_ref(i
);
571 pa_assert_ctl_context();
572 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
577 /* Called from main context */
578 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
579 pa_usec_t r
[2] = { 0, 0 };
581 pa_sink_input_assert_ref(i
);
582 pa_assert_ctl_context();
583 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
585 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
588 r
[0] += i
->get_latency(i
);
591 *sink_latency
= r
[1];
596 /* Called from thread context */
597 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
598 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
599 pa_bool_t volume_is_norm
;
600 size_t block_size_max_sink
, block_size_max_sink_input
;
603 pa_sink_input_assert_ref(i
);
604 pa_sink_input_assert_io_context(i
);
605 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
606 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
610 /* pa_log_debug("peek"); */
612 pa_assert(i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
||
613 i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
614 i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
);
616 block_size_max_sink_input
= i
->thread_info
.resampler
?
617 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
618 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
620 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
622 /* Default buffer size */
624 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
626 if (slength
> block_size_max_sink
)
627 slength
= block_size_max_sink
;
629 if (i
->thread_info
.resampler
) {
630 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
633 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
637 if (ilength
> block_size_max_sink_input
)
638 ilength
= block_size_max_sink_input
;
640 /* If the channel maps of the sink and this stream differ, we need
641 * to adjust the volume *before* we resample. Otherwise we can do
642 * it after and leave it for the sink code */
644 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
645 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
646 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
648 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
651 /* There's nothing in our render queue. We need to fill it up
652 * with data from the implementor. */
654 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
655 i
->pop(i
, ilength
, &tchunk
) < 0) {
657 /* OK, we're corked or the implementor didn't give us any
658 * data, so let's just hand out silence */
659 pa_atomic_store(&i
->thread_info
.drained
, 1);
661 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
662 i
->thread_info
.playing_for
= 0;
663 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
664 i
->thread_info
.underrun_for
+= ilength
;
668 pa_atomic_store(&i
->thread_info
.drained
, 0);
670 pa_assert(tchunk
.length
> 0);
671 pa_assert(tchunk
.memblock
);
673 i
->thread_info
.underrun_for
= 0;
674 i
->thread_info
.playing_for
+= tchunk
.length
;
676 while (tchunk
.length
> 0) {
678 pa_bool_t nvfs
= need_volume_factor_sink
;
681 pa_memblock_ref(wchunk
.memblock
);
683 if (wchunk
.length
> block_size_max_sink_input
)
684 wchunk
.length
= block_size_max_sink_input
;
686 /* It might be necessary to adjust the volume here */
687 if (do_volume_adj_here
&& !volume_is_norm
) {
688 pa_memchunk_make_writable(&wchunk
, 0);
690 if (i
->thread_info
.muted
) {
691 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
694 } else if (!i
->thread_info
.resampler
&& nvfs
) {
697 /* If we don't need a resampler we can merge the
698 * post and the pre volume adjustment into one */
700 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
701 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
705 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
708 if (!i
->thread_info
.resampler
) {
711 pa_memchunk_make_writable(&wchunk
, 0);
712 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
715 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
718 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
721 pa_memchunk_make_writable(&rchunk
, 0);
722 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
725 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
727 if (rchunk
.memblock
) {
728 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
729 pa_memblock_unref(rchunk
.memblock
);
733 pa_memblock_unref(wchunk
.memblock
);
735 tchunk
.index
+= wchunk
.length
;
736 tchunk
.length
-= wchunk
.length
;
739 pa_memblock_unref(tchunk
.memblock
);
742 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
744 pa_assert(chunk
->length
> 0);
745 pa_assert(chunk
->memblock
);
747 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
749 if (chunk
->length
> block_size_max_sink
)
750 chunk
->length
= block_size_max_sink
;
752 /* Let's see if we had to apply the volume adjustment ourselves,
753 * or if this can be done by the sink for us */
755 if (do_volume_adj_here
)
756 /* We had different channel maps, so we already did the adjustment */
757 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
758 else if (i
->thread_info
.muted
)
759 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
760 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
762 *volume
= i
->thread_info
.soft_volume
;
765 /* Called from thread context */
766 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
768 pa_sink_input_assert_ref(i
);
769 pa_sink_input_assert_io_context(i
);
770 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
771 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
772 pa_assert(nbytes
> 0);
774 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
776 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
779 /* Called from thread context */
780 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
782 pa_bool_t called
= FALSE
;
784 pa_sink_input_assert_ref(i
);
785 pa_sink_input_assert_io_context(i
);
786 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
787 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
789 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
791 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
793 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
794 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
795 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
798 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
800 /* We were asked to drop all buffered data, and rerequest new
801 * data from implementor the next time push() is called */
803 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
);
805 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
806 size_t max_rewrite
, amount
;
808 /* Calculate how much make sense to rewrite at most */
809 max_rewrite
= nbytes
+ lbq
;
811 /* Transform into local domain */
812 if (i
->thread_info
.resampler
)
813 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
815 /* Calculate how much of the rewinded data should actually be rewritten */
816 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
819 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
821 /* Tell the implementor */
822 if (i
->process_rewind
)
823 i
->process_rewind(i
, amount
);
826 /* Convert back to to sink domain */
827 if (i
->thread_info
.resampler
)
828 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
831 /* Ok, now update the write pointer */
832 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
834 if (i
->thread_info
.rewrite_flush
)
835 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
837 /* And reset the resampler */
838 if (i
->thread_info
.resampler
)
839 pa_resampler_reset(i
->thread_info
.resampler
);
844 if (i
->process_rewind
)
845 i
->process_rewind(i
, 0);
847 i
->thread_info
.rewrite_nbytes
= 0;
848 i
->thread_info
.rewrite_flush
= FALSE
;
849 i
->thread_info
.dont_rewind_render
= FALSE
;
852 /* Called from thread context */
853 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
854 pa_sink_input_assert_ref(i
);
855 pa_sink_input_assert_io_context(i
);
857 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
860 /* Called from thread context */
861 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
862 pa_sink_input_assert_ref(i
);
863 pa_sink_input_assert_io_context(i
);
865 /* We're not verifying the status here, to allow this to be called
866 * in the state change handler between _INIT and _RUNNING */
868 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
871 /* Called from thread context */
872 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
873 pa_sink_input_assert_ref(i
);
874 pa_sink_input_assert_io_context(i
);
875 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
876 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
878 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
880 if (i
->update_max_rewind
)
881 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
884 /* Called from thread context */
885 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
886 pa_sink_input_assert_ref(i
);
887 pa_sink_input_assert_io_context(i
);
888 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
889 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
891 if (i
->update_max_request
)
892 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
895 /* Called from thread context */
896 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
897 pa_sink_input_assert_ref(i
);
898 pa_sink_input_assert_io_context(i
);
900 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
901 usec
= i
->sink
->thread_info
.fixed_latency
;
903 if (usec
!= (pa_usec_t
) -1)
904 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
906 i
->thread_info
.requested_sink_latency
= usec
;
907 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
912 /* Called from main context */
913 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
914 pa_sink_input_assert_ref(i
);
915 pa_assert_ctl_context();
917 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
918 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
922 /* If this sink input is not realized yet or we are being moved,
923 * we have to touch the thread info data directly */
926 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
927 usec
= pa_sink_get_fixed_latency(i
->sink
);
929 if (usec
!= (pa_usec_t
) -1) {
930 pa_usec_t min_latency
, max_latency
;
931 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
932 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
936 i
->thread_info
.requested_sink_latency
= usec
;
941 /* Called from main context */
942 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
943 pa_sink_input_assert_ref(i
);
944 pa_assert_ctl_context();
946 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
948 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
952 /* If this sink input is not realized yet or we are being moved,
953 * we have to touch the thread info data directly */
955 return i
->thread_info
.requested_sink_latency
;
958 /* Called from main context */
959 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
960 pa_sink_input_assert_ref(i
);
961 pa_assert_ctl_context();
962 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
963 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
965 /* This basically calculates:
968 * i->soft_volume := i->real_ratio * i->volume_factor */
973 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
975 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
976 /* We don't copy the data to the thread_info data. That's left for someone else to do */
979 /* Called from main context */
980 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
983 pa_sink_input_assert_ref(i
);
984 pa_assert_ctl_context();
985 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
987 pa_assert(pa_cvolume_valid(volume
));
988 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
990 if ((i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) && !absolute
) {
991 v
= i
->sink
->reference_volume
;
992 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
994 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
995 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
997 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1000 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1002 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1006 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1007 i
->save_volume
= i
->save_volume
|| save
;
1011 i
->volume
= *volume
;
1012 i
->save_volume
= save
;
1014 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1015 /* We are in flat volume mode, so let's update all sink input
1016 * volumes and update the flat volume of the sink */
1018 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1021 /* OK, we are in normal volume mode. The volume only affects
1023 set_real_ratio(i
, volume
);
1025 /* Copy the new soft_volume to the thread_info struct */
1026 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1029 /* The volume changed, let's tell people so */
1030 if (i
->volume_changed
)
1031 i
->volume_changed(i
);
1033 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1036 /* Called from main context */
1037 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1038 pa_sink_input_assert_ref(i
);
1039 pa_assert_ctl_context();
1040 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1042 if (absolute
|| !(i
->sink
->flags
& PA_SINK_FLAT_VOLUME
))
1043 *volume
= i
->volume
;
1045 *volume
= i
->reference_ratio
;
1050 /* Called from main context */
1051 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1052 pa_sink_input_assert_ref(i
);
1053 pa_assert_ctl_context();
1054 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1056 if (!i
->muted
== !mute
)
1060 i
->save_muted
= save
;
1062 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1064 /* The mute status changed, let's tell people so */
1065 if (i
->mute_changed
)
1068 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1071 /* Called from main context */
1072 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1073 pa_sink_input_assert_ref(i
);
1074 pa_assert_ctl_context();
1075 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1080 /* Called from main thread */
1081 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1082 pa_sink_input_assert_ref(i
);
1083 pa_assert_ctl_context();
1086 pa_proplist_update(i
->proplist
, mode
, p
);
1088 if (PA_SINK_IS_LINKED(i
->state
)) {
1089 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1090 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1094 /* Called from main context */
1095 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1096 pa_sink_input_assert_ref(i
);
1097 pa_assert_ctl_context();
1098 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1100 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1103 /* Called from main context */
1104 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1105 pa_sink_input_assert_ref(i
);
1106 pa_assert_ctl_context();
1107 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1108 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1110 if (i
->sample_spec
.rate
== rate
)
1113 i
->sample_spec
.rate
= rate
;
1115 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1117 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1121 /* Called from main context */
1122 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1124 pa_sink_input_assert_ref(i
);
1125 pa_assert_ctl_context();
1127 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1130 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1132 if (old
&& name
&& pa_streq(old
, name
))
1136 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1138 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1140 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1141 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1142 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1146 /* Called from main context */
1147 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1148 pa_sink_input_assert_ref(i
);
1149 pa_assert_ctl_context();
1151 return i
->actual_resample_method
;
1154 /* Called from main context */
1155 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1156 pa_sink_input_assert_ref(i
);
1157 pa_assert_ctl_context();
1158 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1160 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1163 if (i
->sync_next
|| i
->sync_prev
) {
1164 pa_log_warn("Moving synchronised streams not supported.");
1171 /* Called from main context */
1172 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1173 pa_sink_input_assert_ref(i
);
1174 pa_assert_ctl_context();
1175 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1176 pa_sink_assert_ref(dest
);
1178 if (dest
== i
->sink
)
1181 if (!pa_sink_input_may_move(i
))
1184 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1185 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1190 if (!i
->may_move_to(i
, dest
))
1196 /* Called from main context */
1197 int pa_sink_input_start_move(pa_sink_input
*i
) {
1198 pa_source_output
*o
, *p
= NULL
;
1201 pa_sink_input_assert_ref(i
);
1202 pa_assert_ctl_context();
1203 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1206 if (!pa_sink_input_may_move(i
))
1207 return -PA_ERR_NOTSUPPORTED
;
1209 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1212 /* Kill directly connected outputs */
1213 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1215 pa_source_output_kill(o
);
1218 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1220 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1222 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1223 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1225 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1226 /* We might need to update the sink's volume if we are in flat
1228 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1230 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1232 pa_sink_update_status(i
->sink
);
1233 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1236 pa_sink_input_unref(i
);
1241 /* Called from main context */
1242 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1243 pa_resampler
*new_resampler
;
1245 pa_sink_input_assert_ref(i
);
1246 pa_assert_ctl_context();
1247 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1248 pa_assert(!i
->sink
);
1249 pa_sink_assert_ref(dest
);
1251 if (!pa_sink_input_may_move_to(i
, dest
))
1252 return -PA_ERR_NOTSUPPORTED
;
1254 if (i
->thread_info
.resampler
&&
1255 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1256 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1258 /* Try to reuse the old resampler if possible */
1259 new_resampler
= i
->thread_info
.resampler
;
1261 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1262 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1263 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1265 /* Okey, we need a new resampler for the new sink */
1267 if (!(new_resampler
= pa_resampler_new(
1269 &i
->sample_spec
, &i
->channel_map
,
1270 &dest
->sample_spec
, &dest
->channel_map
,
1271 i
->requested_resample_method
,
1272 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1273 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1274 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1275 pa_log_warn("Unsupported resampling operation.");
1276 return -PA_ERR_NOTSUPPORTED
;
1279 new_resampler
= NULL
;
1285 i
->save_sink
= save
;
1286 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1288 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1290 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1291 i
->sink
->n_corked
++;
1293 /* Replace resampler and render queue */
1294 if (new_resampler
!= i
->thread_info
.resampler
) {
1296 if (i
->thread_info
.resampler
)
1297 pa_resampler_free(i
->thread_info
.resampler
);
1298 i
->thread_info
.resampler
= new_resampler
;
1300 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1302 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1304 MEMBLOCKQ_MAXLENGTH
,
1306 pa_frame_size(&i
->sink
->sample_spec
),
1312 pa_sink_update_status(dest
);
1314 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) {
1315 pa_cvolume remapped
;
1317 /* Make relative volumes absolute */
1318 remapped
= dest
->reference_volume
;
1319 pa_cvolume_remap(&remapped
, &dest
->channel_map
, &i
->channel_map
);
1320 pa_sw_cvolume_multiply(&i
->volume
, &i
->reference_ratio
, &remapped
);
1322 /* We might need to update the sink's volume if we are in flat volume mode. */
1323 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1326 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1328 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1330 /* Notify everyone */
1331 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1333 if (i
->volume_changed
)
1334 i
->volume_changed(i
);
1336 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1341 /* Called from main context */
1342 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1344 pa_sink_input_assert_ref(i
);
1345 pa_assert_ctl_context();
1346 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1347 pa_assert(!i
->sink
);
1349 /* Check if someone wants this sink input? */
1350 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1356 pa_sink_input_kill(i
);
1359 /* Called from main context */
1360 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1363 pa_sink_input_assert_ref(i
);
1364 pa_assert_ctl_context();
1365 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1367 pa_sink_assert_ref(dest
);
1369 if (dest
== i
->sink
)
1372 if (!pa_sink_input_may_move_to(i
, dest
))
1373 return -PA_ERR_NOTSUPPORTED
;
1375 pa_sink_input_ref(i
);
1377 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1378 pa_sink_input_unref(i
);
1382 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1383 pa_sink_input_fail_move(i
);
1384 pa_sink_input_unref(i
);
1388 pa_sink_input_unref(i
);
1393 /* Called from IO thread context */
1394 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1395 pa_bool_t corking
, uncorking
;
1397 pa_sink_input_assert_ref(i
);
1398 pa_sink_input_assert_io_context(i
);
1400 if (state
== i
->thread_info
.state
)
1403 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1404 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1405 pa_atomic_store(&i
->thread_info
.drained
, 1);
1407 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1408 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1410 if (i
->state_change
)
1411 i
->state_change(i
, state
);
1413 i
->thread_info
.state
= state
;
1417 pa_log_debug("Requesting rewind due to corking");
1419 /* This will tell the implementing sink input driver to rewind
1420 * so that the unplayed already mixed data is not lost */
1421 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1423 } else if (uncorking
) {
1425 i
->thread_info
.underrun_for
= (uint64_t) -1;
1426 i
->thread_info
.playing_for
= 0;
1428 pa_log_debug("Requesting rewind due to uncorking");
1430 /* OK, we're being uncorked. Make sure we're not rewound when
1431 * the hw buffer is remixed and request a remix. */
1432 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1436 /* Called from thread context, except when it is not. */
1437 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1438 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1439 pa_sink_input_assert_ref(i
);
1443 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1444 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1445 i
->thread_info
.soft_volume
= i
->soft_volume
;
1446 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1450 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1451 if (i
->thread_info
.muted
!= i
->muted
) {
1452 i
->thread_info
.muted
= i
->muted
;
1453 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1457 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1458 pa_usec_t
*r
= userdata
;
1460 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1461 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1466 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1468 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1469 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1473 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1474 pa_sink_input
*ssync
;
1476 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1478 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1479 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1481 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1482 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1487 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1488 pa_usec_t
*usec
= userdata
;
1490 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1494 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1495 pa_usec_t
*r
= userdata
;
1497 *r
= i
->thread_info
.requested_sink_latency
;
1502 return -PA_ERR_NOTIMPLEMENTED
;
1505 /* Called from main thread */
1506 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1507 pa_sink_input_assert_ref(i
);
1508 pa_assert_ctl_context();
1510 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1511 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1516 /* Called from IO context */
1517 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1518 pa_sink_input_assert_ref(i
);
1519 pa_sink_input_assert_io_context(i
);
1521 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1522 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1527 /* Called from IO context */
1528 void pa_sink_input_request_rewind(
1530 size_t nbytes
/* in our sample spec */,
1533 pa_bool_t dont_rewind_render
) {
1537 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1538 * and possible and the exact value of this is passed back the
1539 * implementor via process_rewind(). If 'flush' is also TRUE all
1540 * already rendered data is also dropped.
1542 * If 'rewrite' is FALSE the sink is rewound as far as requested
1543 * and possible and the already rendered data is dropped so that
1544 * in the next iteration we read new data from the
1545 * implementor. This implies 'flush' is TRUE. If
1546 * dont_rewind_render is TRUE then the render memblockq is not
1549 /* nbytes = 0 means maximum rewind request */
1551 pa_sink_input_assert_ref(i
);
1552 pa_sink_input_assert_io_context(i
);
1553 pa_assert(rewrite
|| flush
);
1554 pa_assert(!dont_rewind_render
|| !rewrite
);
1556 /* We don't take rewind requests while we are corked */
1557 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1560 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1562 /* pa_log_debug("request rewrite %zu", nbytes); */
1564 /* Calculate how much we can rewind locally without having to
1567 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1571 /* Check if rewinding for the maximum is requested, and if so, fix up */
1574 /* Calculate maximum number of bytes that could be rewound in theory */
1575 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1577 /* Transform from sink domain */
1578 if (i
->thread_info
.resampler
)
1579 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1582 /* Remember how much we actually want to rewrite */
1583 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1585 /* Make sure to not overwrite over underruns */
1586 if (nbytes
> i
->thread_info
.playing_for
)
1587 nbytes
= (size_t) i
->thread_info
.playing_for
;
1589 i
->thread_info
.rewrite_nbytes
= nbytes
;
1591 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1594 i
->thread_info
.rewrite_flush
=
1595 i
->thread_info
.rewrite_flush
||
1596 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1598 i
->thread_info
.dont_rewind_render
=
1599 i
->thread_info
.dont_rewind_render
||
1602 if (nbytes
!= (size_t) -1) {
1604 /* Transform to sink domain */
1605 if (i
->thread_info
.resampler
)
1606 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1609 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1611 /* This call will make sure process_rewind() is called later */
1612 pa_sink_request_rewind(i
->sink
, 0);
1616 /* Called from main context */
1617 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1618 pa_sink_input_assert_ref(i
);
1619 pa_assert_ctl_context();
1622 /* FIXME: Shouldn't access resampler object from main context! */
1624 pa_silence_memchunk_get(
1625 &i
->core
->silence_cache
,
1629 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1634 /* Called from main context */
1635 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1636 pa_proplist
*pl
= NULL
;
1637 pa_sink_input_send_event_hook_data hook_data
;
1639 pa_sink_input_assert_ref(i
);
1640 pa_assert_ctl_context();
1647 data
= pl
= pa_proplist_new();
1649 hook_data
.sink_input
= i
;
1650 hook_data
.data
= data
;
1651 hook_data
.event
= event
;
1653 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
1656 i
->send_event(i
, event
, data
);
1660 pa_proplist_free(pl
);