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
);
720 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
722 if (rchunk
.memblock
) {
725 pa_memchunk_make_writable(&rchunk
, 0);
726 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
729 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
730 pa_memblock_unref(rchunk
.memblock
);
734 pa_memblock_unref(wchunk
.memblock
);
736 tchunk
.index
+= wchunk
.length
;
737 tchunk
.length
-= wchunk
.length
;
740 pa_memblock_unref(tchunk
.memblock
);
743 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
745 pa_assert(chunk
->length
> 0);
746 pa_assert(chunk
->memblock
);
748 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
750 if (chunk
->length
> block_size_max_sink
)
751 chunk
->length
= block_size_max_sink
;
753 /* Let's see if we had to apply the volume adjustment ourselves,
754 * or if this can be done by the sink for us */
756 if (do_volume_adj_here
)
757 /* We had different channel maps, so we already did the adjustment */
758 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
759 else if (i
->thread_info
.muted
)
760 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
761 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
763 *volume
= i
->thread_info
.soft_volume
;
766 /* Called from thread context */
767 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
769 pa_sink_input_assert_ref(i
);
770 pa_sink_input_assert_io_context(i
);
771 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
772 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
773 pa_assert(nbytes
> 0);
775 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
777 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
780 /* Called from thread context */
781 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
783 pa_bool_t called
= FALSE
;
785 pa_sink_input_assert_ref(i
);
786 pa_sink_input_assert_io_context(i
);
787 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
788 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
790 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
792 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
794 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
795 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
796 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
799 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
801 /* We were asked to drop all buffered data, and rerequest new
802 * data from implementor the next time push() is called */
804 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
);
806 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
807 size_t max_rewrite
, amount
;
809 /* Calculate how much make sense to rewrite at most */
810 max_rewrite
= nbytes
+ lbq
;
812 /* Transform into local domain */
813 if (i
->thread_info
.resampler
)
814 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
816 /* Calculate how much of the rewinded data should actually be rewritten */
817 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
820 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
822 /* Tell the implementor */
823 if (i
->process_rewind
)
824 i
->process_rewind(i
, amount
);
827 /* Convert back to to sink domain */
828 if (i
->thread_info
.resampler
)
829 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
832 /* Ok, now update the write pointer */
833 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
835 if (i
->thread_info
.rewrite_flush
)
836 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
838 /* And reset the resampler */
839 if (i
->thread_info
.resampler
)
840 pa_resampler_reset(i
->thread_info
.resampler
);
845 if (i
->process_rewind
)
846 i
->process_rewind(i
, 0);
848 i
->thread_info
.rewrite_nbytes
= 0;
849 i
->thread_info
.rewrite_flush
= FALSE
;
850 i
->thread_info
.dont_rewind_render
= FALSE
;
853 /* Called from thread context */
854 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
855 pa_sink_input_assert_ref(i
);
856 pa_sink_input_assert_io_context(i
);
858 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
861 /* Called from thread context */
862 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
863 pa_sink_input_assert_ref(i
);
864 pa_sink_input_assert_io_context(i
);
866 /* We're not verifying the status here, to allow this to be called
867 * in the state change handler between _INIT and _RUNNING */
869 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
872 /* Called from thread context */
873 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
874 pa_sink_input_assert_ref(i
);
875 pa_sink_input_assert_io_context(i
);
876 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
877 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
879 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
881 if (i
->update_max_rewind
)
882 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
885 /* Called from thread context */
886 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
887 pa_sink_input_assert_ref(i
);
888 pa_sink_input_assert_io_context(i
);
889 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
890 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
892 if (i
->update_max_request
)
893 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
896 /* Called from thread context */
897 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
898 pa_sink_input_assert_ref(i
);
899 pa_sink_input_assert_io_context(i
);
901 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
902 usec
= i
->sink
->thread_info
.fixed_latency
;
904 if (usec
!= (pa_usec_t
) -1)
905 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
907 i
->thread_info
.requested_sink_latency
= usec
;
908 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
913 /* Called from main context */
914 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
915 pa_sink_input_assert_ref(i
);
916 pa_assert_ctl_context();
918 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
919 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
923 /* If this sink input is not realized yet or we are being moved,
924 * we have to touch the thread info data directly */
927 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
928 usec
= pa_sink_get_fixed_latency(i
->sink
);
930 if (usec
!= (pa_usec_t
) -1) {
931 pa_usec_t min_latency
, max_latency
;
932 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
933 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
937 i
->thread_info
.requested_sink_latency
= usec
;
942 /* Called from main context */
943 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
944 pa_sink_input_assert_ref(i
);
945 pa_assert_ctl_context();
947 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
949 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
953 /* If this sink input is not realized yet or we are being moved,
954 * we have to touch the thread info data directly */
956 return i
->thread_info
.requested_sink_latency
;
959 /* Called from main context */
960 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
961 pa_sink_input_assert_ref(i
);
962 pa_assert_ctl_context();
963 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
964 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
966 /* This basically calculates:
969 * i->soft_volume := i->real_ratio * i->volume_factor */
974 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
976 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
977 /* We don't copy the data to the thread_info data. That's left for someone else to do */
980 /* Called from main context */
981 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
984 pa_sink_input_assert_ref(i
);
985 pa_assert_ctl_context();
986 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
988 pa_assert(pa_cvolume_valid(volume
));
989 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
991 if ((i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) && !absolute
) {
992 v
= i
->sink
->reference_volume
;
993 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
995 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
996 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
998 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1001 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1003 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1007 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1008 i
->save_volume
= i
->save_volume
|| save
;
1012 i
->volume
= *volume
;
1013 i
->save_volume
= save
;
1015 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1016 /* We are in flat volume mode, so let's update all sink input
1017 * volumes and update the flat volume of the sink */
1019 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1022 /* OK, we are in normal volume mode. The volume only affects
1024 set_real_ratio(i
, volume
);
1026 /* Copy the new soft_volume to the thread_info struct */
1027 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1030 /* The volume changed, let's tell people so */
1031 if (i
->volume_changed
)
1032 i
->volume_changed(i
);
1034 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1037 /* Called from main context */
1038 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1039 pa_sink_input_assert_ref(i
);
1040 pa_assert_ctl_context();
1041 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1043 if (absolute
|| !(i
->sink
->flags
& PA_SINK_FLAT_VOLUME
))
1044 *volume
= i
->volume
;
1046 *volume
= i
->reference_ratio
;
1051 /* Called from main context */
1052 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1053 pa_sink_input_assert_ref(i
);
1054 pa_assert_ctl_context();
1055 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1057 if (!i
->muted
== !mute
)
1061 i
->save_muted
= save
;
1063 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1065 /* The mute status changed, let's tell people so */
1066 if (i
->mute_changed
)
1069 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1072 /* Called from main context */
1073 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1074 pa_sink_input_assert_ref(i
);
1075 pa_assert_ctl_context();
1076 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1081 /* Called from main thread */
1082 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1083 pa_sink_input_assert_ref(i
);
1084 pa_assert_ctl_context();
1087 pa_proplist_update(i
->proplist
, mode
, p
);
1089 if (PA_SINK_IS_LINKED(i
->state
)) {
1090 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1091 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1095 /* Called from main context */
1096 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1097 pa_sink_input_assert_ref(i
);
1098 pa_assert_ctl_context();
1099 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1101 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1104 /* Called from main context */
1105 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1106 pa_sink_input_assert_ref(i
);
1107 pa_assert_ctl_context();
1108 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1109 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1111 if (i
->sample_spec
.rate
== rate
)
1114 i
->sample_spec
.rate
= rate
;
1116 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1118 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1122 /* Called from main context */
1123 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1125 pa_sink_input_assert_ref(i
);
1126 pa_assert_ctl_context();
1128 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1131 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1133 if (old
&& name
&& pa_streq(old
, name
))
1137 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1139 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1141 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1142 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1143 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1147 /* Called from main context */
1148 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1149 pa_sink_input_assert_ref(i
);
1150 pa_assert_ctl_context();
1152 return i
->actual_resample_method
;
1155 /* Called from main context */
1156 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1157 pa_sink_input_assert_ref(i
);
1158 pa_assert_ctl_context();
1159 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1161 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1164 if (i
->sync_next
|| i
->sync_prev
) {
1165 pa_log_warn("Moving synchronised streams not supported.");
1172 /* Called from main context */
1173 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1174 pa_sink_input_assert_ref(i
);
1175 pa_assert_ctl_context();
1176 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1177 pa_sink_assert_ref(dest
);
1179 if (dest
== i
->sink
)
1182 if (!pa_sink_input_may_move(i
))
1185 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1186 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1191 if (!i
->may_move_to(i
, dest
))
1197 /* Called from main context */
1198 int pa_sink_input_start_move(pa_sink_input
*i
) {
1199 pa_source_output
*o
, *p
= NULL
;
1202 pa_sink_input_assert_ref(i
);
1203 pa_assert_ctl_context();
1204 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1207 if (!pa_sink_input_may_move(i
))
1208 return -PA_ERR_NOTSUPPORTED
;
1210 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1213 /* Kill directly connected outputs */
1214 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1216 pa_source_output_kill(o
);
1219 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1221 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1223 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1224 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1226 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
)
1227 /* We might need to update the sink's volume if we are in flat
1229 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1231 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1233 pa_sink_update_status(i
->sink
);
1234 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1237 pa_sink_input_unref(i
);
1242 /* Called from main context */
1243 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1244 pa_resampler
*new_resampler
;
1246 pa_sink_input_assert_ref(i
);
1247 pa_assert_ctl_context();
1248 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1249 pa_assert(!i
->sink
);
1250 pa_sink_assert_ref(dest
);
1252 if (!pa_sink_input_may_move_to(i
, dest
))
1253 return -PA_ERR_NOTSUPPORTED
;
1255 if (i
->thread_info
.resampler
&&
1256 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1257 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1259 /* Try to reuse the old resampler if possible */
1260 new_resampler
= i
->thread_info
.resampler
;
1262 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1263 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1264 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1266 /* Okey, we need a new resampler for the new sink */
1268 if (!(new_resampler
= pa_resampler_new(
1270 &i
->sample_spec
, &i
->channel_map
,
1271 &dest
->sample_spec
, &dest
->channel_map
,
1272 i
->requested_resample_method
,
1273 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1274 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1275 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1276 pa_log_warn("Unsupported resampling operation.");
1277 return -PA_ERR_NOTSUPPORTED
;
1280 new_resampler
= NULL
;
1286 i
->save_sink
= save
;
1287 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1289 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1291 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1292 i
->sink
->n_corked
++;
1294 /* Replace resampler and render queue */
1295 if (new_resampler
!= i
->thread_info
.resampler
) {
1297 if (i
->thread_info
.resampler
)
1298 pa_resampler_free(i
->thread_info
.resampler
);
1299 i
->thread_info
.resampler
= new_resampler
;
1301 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1303 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1305 MEMBLOCKQ_MAXLENGTH
,
1307 pa_frame_size(&i
->sink
->sample_spec
),
1313 pa_sink_update_status(dest
);
1315 if (i
->sink
->flags
& PA_SINK_FLAT_VOLUME
) {
1316 pa_cvolume remapped
;
1318 /* Make relative volumes absolute */
1319 remapped
= dest
->reference_volume
;
1320 pa_cvolume_remap(&remapped
, &dest
->channel_map
, &i
->channel_map
);
1321 pa_sw_cvolume_multiply(&i
->volume
, &i
->reference_ratio
, &remapped
);
1323 /* We might need to update the sink's volume if we are in flat volume mode. */
1324 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1327 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1329 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1331 /* Notify everyone */
1332 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1334 if (i
->volume_changed
)
1335 i
->volume_changed(i
);
1337 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1342 /* Called from main context */
1343 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1345 pa_sink_input_assert_ref(i
);
1346 pa_assert_ctl_context();
1347 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1348 pa_assert(!i
->sink
);
1350 /* Check if someone wants this sink input? */
1351 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1357 pa_sink_input_kill(i
);
1360 /* Called from main context */
1361 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1364 pa_sink_input_assert_ref(i
);
1365 pa_assert_ctl_context();
1366 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1368 pa_sink_assert_ref(dest
);
1370 if (dest
== i
->sink
)
1373 if (!pa_sink_input_may_move_to(i
, dest
))
1374 return -PA_ERR_NOTSUPPORTED
;
1376 pa_sink_input_ref(i
);
1378 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1379 pa_sink_input_unref(i
);
1383 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1384 pa_sink_input_fail_move(i
);
1385 pa_sink_input_unref(i
);
1389 pa_sink_input_unref(i
);
1394 /* Called from IO thread context */
1395 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1396 pa_bool_t corking
, uncorking
;
1398 pa_sink_input_assert_ref(i
);
1399 pa_sink_input_assert_io_context(i
);
1401 if (state
== i
->thread_info
.state
)
1404 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1405 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1406 pa_atomic_store(&i
->thread_info
.drained
, 1);
1408 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1409 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1411 if (i
->state_change
)
1412 i
->state_change(i
, state
);
1414 i
->thread_info
.state
= state
;
1418 pa_log_debug("Requesting rewind due to corking");
1420 /* This will tell the implementing sink input driver to rewind
1421 * so that the unplayed already mixed data is not lost */
1422 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1424 } else if (uncorking
) {
1426 i
->thread_info
.underrun_for
= (uint64_t) -1;
1427 i
->thread_info
.playing_for
= 0;
1429 pa_log_debug("Requesting rewind due to uncorking");
1431 /* OK, we're being uncorked. Make sure we're not rewound when
1432 * the hw buffer is remixed and request a remix. */
1433 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1437 /* Called from thread context, except when it is not. */
1438 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1439 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1440 pa_sink_input_assert_ref(i
);
1444 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1445 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1446 i
->thread_info
.soft_volume
= i
->soft_volume
;
1447 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1451 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1452 if (i
->thread_info
.muted
!= i
->muted
) {
1453 i
->thread_info
.muted
= i
->muted
;
1454 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1458 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1459 pa_usec_t
*r
= userdata
;
1461 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1462 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1467 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1469 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1470 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1474 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1475 pa_sink_input
*ssync
;
1477 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1479 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1480 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1482 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1483 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1488 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1489 pa_usec_t
*usec
= userdata
;
1491 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1495 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1496 pa_usec_t
*r
= userdata
;
1498 *r
= i
->thread_info
.requested_sink_latency
;
1503 return -PA_ERR_NOTIMPLEMENTED
;
1506 /* Called from main thread */
1507 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1508 pa_sink_input_assert_ref(i
);
1509 pa_assert_ctl_context();
1511 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1512 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1517 /* Called from IO context */
1518 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1519 pa_sink_input_assert_ref(i
);
1520 pa_sink_input_assert_io_context(i
);
1522 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1523 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1528 /* Called from IO context */
1529 void pa_sink_input_request_rewind(
1531 size_t nbytes
/* in our sample spec */,
1534 pa_bool_t dont_rewind_render
) {
1538 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1539 * and possible and the exact value of this is passed back the
1540 * implementor via process_rewind(). If 'flush' is also TRUE all
1541 * already rendered data is also dropped.
1543 * If 'rewrite' is FALSE the sink is rewound as far as requested
1544 * and possible and the already rendered data is dropped so that
1545 * in the next iteration we read new data from the
1546 * implementor. This implies 'flush' is TRUE. If
1547 * dont_rewind_render is TRUE then the render memblockq is not
1550 /* nbytes = 0 means maximum rewind request */
1552 pa_sink_input_assert_ref(i
);
1553 pa_sink_input_assert_io_context(i
);
1554 pa_assert(rewrite
|| flush
);
1555 pa_assert(!dont_rewind_render
|| !rewrite
);
1557 /* We don't take rewind requests while we are corked */
1558 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1561 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1563 /* pa_log_debug("request rewrite %zu", nbytes); */
1565 /* Calculate how much we can rewind locally without having to
1568 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1572 /* Check if rewinding for the maximum is requested, and if so, fix up */
1575 /* Calculate maximum number of bytes that could be rewound in theory */
1576 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1578 /* Transform from sink domain */
1579 if (i
->thread_info
.resampler
)
1580 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1583 /* Remember how much we actually want to rewrite */
1584 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1586 /* Make sure to not overwrite over underruns */
1587 if (nbytes
> i
->thread_info
.playing_for
)
1588 nbytes
= (size_t) i
->thread_info
.playing_for
;
1590 i
->thread_info
.rewrite_nbytes
= nbytes
;
1592 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1595 i
->thread_info
.rewrite_flush
=
1596 i
->thread_info
.rewrite_flush
||
1597 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1599 i
->thread_info
.dont_rewind_render
=
1600 i
->thread_info
.dont_rewind_render
||
1603 if (nbytes
!= (size_t) -1) {
1605 /* Transform to sink domain */
1606 if (i
->thread_info
.resampler
)
1607 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1610 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1612 /* This call will make sure process_rewind() is called later */
1613 pa_sink_request_rewind(i
->sink
, 0);
1617 /* Called from main context */
1618 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1619 pa_sink_input_assert_ref(i
);
1620 pa_assert_ctl_context();
1623 /* FIXME: Shouldn't access resampler object from main context! */
1625 pa_silence_memchunk_get(
1626 &i
->core
->silence_cache
,
1630 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1635 /* Called from main context */
1636 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1637 pa_proplist
*pl
= NULL
;
1638 pa_sink_input_send_event_hook_data hook_data
;
1640 pa_sink_input_assert_ref(i
);
1641 pa_assert_ctl_context();
1648 data
= pl
= pa_proplist_new();
1650 hook_data
.sink_input
= i
;
1651 hook_data
.data
= data
;
1652 hook_data
.event
= event
;
1654 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
1657 i
->send_event(i
, event
, data
);
1661 pa_proplist_free(pl
);