2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
34 #include <pulse/internal.h>
36 #include <pulsecore/sample-util.h>
37 #include <pulsecore/core-subscribe.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/play-memblockq.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-util.h>
43 #include "sink-input.h"
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input
, pa_msgobject
);
50 static void sink_input_free(pa_object
*o
);
51 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
);
53 static int check_passthrough_connection(pa_bool_t passthrough
, pa_sink
*dest
) {
54 if (pa_sink_is_passthrough(dest
)) {
55 pa_log_warn("Sink is already connected to PASSTHROUGH input");
59 /* If current input(s) exist, check new input is not PASSTHROUGH */
60 if (pa_idxset_size(dest
->inputs
) > 0 && passthrough
) {
61 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
68 pa_sink_input_new_data
* pa_sink_input_new_data_init(pa_sink_input_new_data
*data
) {
72 data
->resample_method
= PA_RESAMPLER_INVALID
;
73 data
->proplist
= pa_proplist_new();
74 data
->volume_writable
= TRUE
;
79 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data
*data
, const pa_sample_spec
*spec
) {
82 if ((data
->sample_spec_is_set
= !!spec
))
83 data
->sample_spec
= *spec
;
86 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data
*data
, const pa_channel_map
*map
) {
89 if ((data
->channel_map_is_set
= !!map
))
90 data
->channel_map
= *map
;
93 pa_bool_t
pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data
*data
) {
96 if (PA_LIKELY(data
->format
) && PA_UNLIKELY(!pa_format_info_is_pcm(data
->format
)))
99 if (PA_UNLIKELY(data
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
105 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data
*data
, const pa_cvolume
*volume
) {
107 pa_assert(data
->volume_writable
);
109 if ((data
->volume_is_set
= !!volume
))
110 data
->volume
= *volume
;
113 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
115 pa_assert(volume_factor
);
117 if (data
->volume_factor_is_set
)
118 pa_sw_cvolume_multiply(&data
->volume_factor
, &data
->volume_factor
, volume_factor
);
120 data
->volume_factor_is_set
= TRUE
;
121 data
->volume_factor
= *volume_factor
;
125 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data
*data
, const pa_cvolume
*volume_factor
) {
127 pa_assert(volume_factor
);
129 if (data
->volume_factor_sink_is_set
)
130 pa_sw_cvolume_multiply(&data
->volume_factor_sink
, &data
->volume_factor_sink
, volume_factor
);
132 data
->volume_factor_sink_is_set
= TRUE
;
133 data
->volume_factor_sink
= *volume_factor
;
137 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data
*data
, pa_bool_t mute
) {
140 data
->muted_is_set
= TRUE
;
141 data
->muted
= !!mute
;
144 pa_bool_t
pa_sink_input_new_data_set_sink(pa_sink_input_new_data
*data
, pa_sink
*s
, pa_bool_t save
) {
145 pa_bool_t ret
= TRUE
;
146 pa_idxset
*formats
= NULL
;
151 if (!data
->req_formats
) {
152 /* We're not working with the extended API */
154 data
->save_sink
= save
;
156 /* Extended API: let's see if this sink supports the formats the client can provide */
157 formats
= pa_sink_check_formats(s
, data
->req_formats
);
159 if (formats
&& !pa_idxset_isempty(formats
)) {
160 /* Sink supports at least one of the requested formats */
162 data
->save_sink
= save
;
163 if (data
->nego_formats
)
164 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
165 data
->nego_formats
= formats
;
167 /* Sink doesn't support any of the formats requested by the client */
169 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
177 pa_bool_t
pa_sink_input_new_data_set_formats(pa_sink_input_new_data
*data
, pa_idxset
*formats
) {
181 if (data
->req_formats
)
182 pa_idxset_free(formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
184 data
->req_formats
= formats
;
187 /* Trigger format negotiation */
188 return pa_sink_input_new_data_set_sink(data
, data
->sink
, data
->save_sink
);
194 void pa_sink_input_new_data_done(pa_sink_input_new_data
*data
) {
197 if (data
->req_formats
)
198 pa_idxset_free(data
->req_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
200 if (data
->nego_formats
)
201 pa_idxset_free(data
->nego_formats
, (pa_free2_cb_t
) pa_format_info_free2
, NULL
);
204 pa_format_info_free(data
->format
);
206 pa_proplist_free(data
->proplist
);
209 /* Called from main context */
210 static void reset_callbacks(pa_sink_input
*i
) {
214 i
->process_rewind
= NULL
;
215 i
->update_max_rewind
= NULL
;
216 i
->update_max_request
= NULL
;
217 i
->update_sink_requested_latency
= NULL
;
218 i
->update_sink_latency_range
= NULL
;
219 i
->update_sink_fixed_latency
= NULL
;
223 i
->suspend_within_thread
= NULL
;
226 i
->get_latency
= NULL
;
227 i
->state_change
= NULL
;
228 i
->may_move_to
= NULL
;
229 i
->send_event
= NULL
;
230 i
->volume_changed
= NULL
;
231 i
->mute_changed
= NULL
;
234 /* Called from main context */
235 int pa_sink_input_new(
238 pa_sink_input_new_data
*data
) {
241 pa_resampler
*resampler
= NULL
;
242 char st
[PA_SAMPLE_SPEC_SNPRINT_MAX
], cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
243 pa_channel_map original_cm
;
252 pa_assert_ctl_context();
255 pa_proplist_update(data
->proplist
, PA_UPDATE_MERGE
, data
->client
->proplist
);
257 if (data
->origin_sink
&& (data
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
))
258 data
->volume_writable
= FALSE
;
260 if (!data
->req_formats
) {
261 /* From this point on, we want to work only with formats, and get back
262 * to using the sample spec and channel map after all decisions w.r.t.
263 * routing are complete. */
264 pa_idxset
*tmp
= pa_idxset_new(NULL
, NULL
);
265 pa_format_info
*f
= pa_format_info_from_sample_spec(&data
->sample_spec
, &data
->channel_map
);
266 pa_idxset_put(tmp
, f
, NULL
);
267 pa_sink_input_new_data_set_formats(data
, tmp
);
270 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_NEW
], data
)) < 0)
273 pa_return_val_if_fail(!data
->driver
|| pa_utf8_valid(data
->driver
), -PA_ERR_INVALID
);
276 pa_sink_input_new_data_set_sink(data
, pa_namereg_get(core
, NULL
, PA_NAMEREG_SINK
), FALSE
);
278 /* Routing's done, we have a sink. Now let's fix the format and set up the
281 /* If something didn't pick a format for us, pick the top-most format since
282 * we assume this is sorted in priority order */
283 if (!data
->format
&& data
->nego_formats
&& !pa_idxset_isempty(data
->nego_formats
))
284 data
->format
= pa_format_info_copy(pa_idxset_first(data
->nego_formats
, NULL
));
286 pa_return_val_if_fail(data
->format
, -PA_ERR_NOTSUPPORTED
);
288 /* Now populate the sample spec and format according to the final
289 * format that we've negotiated */
290 if (PA_LIKELY(data
->format
->encoding
== PA_ENCODING_PCM
)) {
291 pa_return_val_if_fail(pa_format_info_to_sample_spec(data
->format
, &ss
, &map
), -PA_ERR_INVALID
);
292 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
293 if (pa_channel_map_valid(&map
))
294 pa_sink_input_new_data_set_channel_map(data
, &map
);
296 pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data
->format
, &ss
), -PA_ERR_INVALID
);
297 pa_sink_input_new_data_set_sample_spec(data
, &ss
);
300 pa_return_val_if_fail(data
->sink
, -PA_ERR_NOENTITY
);
301 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data
->sink
)), -PA_ERR_BADSTATE
);
302 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
);
304 r
= check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data
), data
->sink
);
305 pa_return_val_if_fail(r
== PA_OK
, r
);
307 if (!data
->sample_spec_is_set
)
308 data
->sample_spec
= data
->sink
->sample_spec
;
310 pa_return_val_if_fail(pa_sample_spec_valid(&data
->sample_spec
), -PA_ERR_INVALID
);
312 if (!data
->channel_map_is_set
) {
313 if (pa_channel_map_compatible(&data
->sink
->channel_map
, &data
->sample_spec
))
314 data
->channel_map
= data
->sink
->channel_map
;
316 pa_channel_map_init_extend(&data
->channel_map
, data
->sample_spec
.channels
, PA_CHANNEL_MAP_DEFAULT
);
319 pa_return_val_if_fail(pa_channel_map_compatible(&data
->channel_map
, &data
->sample_spec
), -PA_ERR_INVALID
);
321 if (!data
->volume_is_set
) {
322 pa_cvolume_reset(&data
->volume
, data
->sample_spec
.channels
);
323 data
->volume_is_absolute
= FALSE
;
324 data
->save_volume
= FALSE
;
327 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume
, &data
->sample_spec
), -PA_ERR_INVALID
);
329 if (!data
->volume_factor_is_set
)
330 pa_cvolume_reset(&data
->volume_factor
, data
->sample_spec
.channels
);
332 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor
, &data
->sample_spec
), -PA_ERR_INVALID
);
334 if (!data
->volume_factor_sink_is_set
)
335 pa_cvolume_reset(&data
->volume_factor_sink
, data
->sink
->sample_spec
.channels
);
337 pa_return_val_if_fail(pa_cvolume_compatible(&data
->volume_factor_sink
, &data
->sink
->sample_spec
), -PA_ERR_INVALID
);
339 if (!data
->muted_is_set
)
342 if (data
->flags
& PA_SINK_INPUT_FIX_FORMAT
)
343 data
->sample_spec
.format
= data
->sink
->sample_spec
.format
;
345 if (data
->flags
& PA_SINK_INPUT_FIX_RATE
)
346 data
->sample_spec
.rate
= data
->sink
->sample_spec
.rate
;
348 original_cm
= data
->channel_map
;
350 if (data
->flags
& PA_SINK_INPUT_FIX_CHANNELS
) {
351 data
->sample_spec
.channels
= data
->sink
->sample_spec
.channels
;
352 data
->channel_map
= data
->sink
->channel_map
;
355 pa_assert(pa_sample_spec_valid(&data
->sample_spec
));
356 pa_assert(pa_channel_map_valid(&data
->channel_map
));
358 /* Due to the fixing of the sample spec the volume might not match anymore */
359 pa_cvolume_remap(&data
->volume
, &original_cm
, &data
->channel_map
);
361 if (data
->resample_method
== PA_RESAMPLER_INVALID
)
362 data
->resample_method
= core
->resample_method
;
364 pa_return_val_if_fail(data
->resample_method
< PA_RESAMPLER_MAX
, -PA_ERR_INVALID
);
366 if ((r
= pa_hook_fire(&core
->hooks
[PA_CORE_HOOK_SINK_INPUT_FIXATE
], data
)) < 0)
369 if ((data
->flags
& PA_SINK_INPUT_NO_CREATE_ON_SUSPEND
) &&
370 pa_sink_get_state(data
->sink
) == PA_SINK_SUSPENDED
) {
371 pa_log_warn("Failed to create sink input: sink is suspended.");
372 return -PA_ERR_BADSTATE
;
375 if (pa_idxset_size(data
->sink
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
376 pa_log_warn("Failed to create sink input: too many inputs per sink.");
377 return -PA_ERR_TOOLARGE
;
380 if ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
381 !pa_sample_spec_equal(&data
->sample_spec
, &data
->sink
->sample_spec
) ||
382 !pa_channel_map_equal(&data
->channel_map
, &data
->sink
->channel_map
)) {
384 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
385 if (!pa_sink_input_new_data_is_passthrough(data
)) /* no resampler for passthrough content */
386 if (!(resampler
= pa_resampler_new(
388 &data
->sample_spec
, &data
->channel_map
,
389 &data
->sink
->sample_spec
, &data
->sink
->channel_map
,
390 data
->resample_method
,
391 ((data
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
392 ((data
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
393 (core
->disable_remixing
|| (data
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0) |
394 (core
->disable_lfe_remixing
? PA_RESAMPLER_NO_LFE
: 0)))) {
395 pa_log_warn("Unsupported resampling operation.");
396 return -PA_ERR_NOTSUPPORTED
;
400 i
= pa_msgobject_new(pa_sink_input
);
401 i
->parent
.parent
.free
= sink_input_free
;
402 i
->parent
.process_msg
= pa_sink_input_process_msg
;
405 i
->state
= PA_SINK_INPUT_INIT
;
406 i
->flags
= data
->flags
;
407 i
->proplist
= pa_proplist_copy(data
->proplist
);
408 i
->driver
= pa_xstrdup(pa_path_get_filename(data
->driver
));
409 i
->module
= data
->module
;
410 i
->sink
= data
->sink
;
411 i
->origin_sink
= data
->origin_sink
;
412 i
->client
= data
->client
;
414 i
->requested_resample_method
= data
->resample_method
;
415 i
->actual_resample_method
= resampler
? pa_resampler_get_method(resampler
) : PA_RESAMPLER_INVALID
;
416 i
->sample_spec
= data
->sample_spec
;
417 i
->channel_map
= data
->channel_map
;
418 i
->format
= pa_format_info_copy(data
->format
);
420 if (!data
->volume_is_absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
423 /* When the 'absolute' bool is not set then we'll treat the volume
424 * as relative to the sink volume even in flat volume mode */
425 remapped
= data
->sink
->reference_volume
;
426 pa_cvolume_remap(&remapped
, &data
->sink
->channel_map
, &data
->channel_map
);
427 pa_sw_cvolume_multiply(&i
->volume
, &data
->volume
, &remapped
);
429 i
->volume
= data
->volume
;
431 i
->volume_factor
= data
->volume_factor
;
432 i
->volume_factor_sink
= data
->volume_factor_sink
;
433 i
->real_ratio
= i
->reference_ratio
= data
->volume
;
434 pa_cvolume_reset(&i
->soft_volume
, i
->sample_spec
.channels
);
435 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
436 i
->volume_writable
= data
->volume_writable
;
437 i
->save_volume
= data
->save_volume
;
438 i
->save_sink
= data
->save_sink
;
439 i
->save_muted
= data
->save_muted
;
441 i
->muted
= data
->muted
;
443 if (data
->sync_base
) {
444 i
->sync_next
= data
->sync_base
->sync_next
;
445 i
->sync_prev
= data
->sync_base
;
447 if (data
->sync_base
->sync_next
)
448 data
->sync_base
->sync_next
->sync_prev
= i
;
449 data
->sync_base
->sync_next
= i
;
451 i
->sync_next
= i
->sync_prev
= NULL
;
453 i
->direct_outputs
= pa_idxset_new(NULL
, NULL
);
458 i
->thread_info
.state
= i
->state
;
459 i
->thread_info
.attached
= FALSE
;
460 pa_atomic_store(&i
->thread_info
.drained
, 1);
461 i
->thread_info
.sample_spec
= i
->sample_spec
;
462 i
->thread_info
.resampler
= resampler
;
463 i
->thread_info
.soft_volume
= i
->soft_volume
;
464 i
->thread_info
.muted
= i
->muted
;
465 i
->thread_info
.requested_sink_latency
= (pa_usec_t
) -1;
466 i
->thread_info
.rewrite_nbytes
= 0;
467 i
->thread_info
.rewrite_flush
= FALSE
;
468 i
->thread_info
.dont_rewind_render
= FALSE
;
469 i
->thread_info
.underrun_for
= (uint64_t) -1;
470 i
->thread_info
.playing_for
= 0;
471 i
->thread_info
.direct_outputs
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
473 i
->thread_info
.render_memblockq
= pa_memblockq_new(
477 pa_frame_size(&i
->sink
->sample_spec
),
483 pa_assert_se(pa_idxset_put(core
->sink_inputs
, i
, &i
->index
) == 0);
484 pa_assert_se(pa_idxset_put(i
->sink
->inputs
, pa_sink_input_ref(i
), NULL
) == 0);
487 pa_assert_se(pa_idxset_put(i
->client
->sink_inputs
, i
, NULL
) >= 0);
489 pt
= pa_proplist_to_string_sep(i
->proplist
, "\n ");
490 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
492 pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)),
494 pa_sample_spec_snprint(st
, sizeof(st
), &i
->sample_spec
),
495 pa_channel_map_snprint(cm
, sizeof(cm
), &i
->channel_map
),
499 /* Don't forget to call pa_sink_input_put! */
505 /* Called from main context */
506 static void update_n_corked(pa_sink_input
*i
, pa_sink_input_state_t state
) {
508 pa_assert_ctl_context();
513 if (i
->state
== PA_SINK_INPUT_CORKED
&& state
!= PA_SINK_INPUT_CORKED
)
514 pa_assert_se(i
->sink
->n_corked
-- >= 1);
515 else if (i
->state
!= PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_CORKED
)
519 /* Called from main context */
520 static void sink_input_set_state(pa_sink_input
*i
, pa_sink_input_state_t state
) {
521 pa_sink_input
*ssync
;
523 pa_assert_ctl_context();
525 if (state
== PA_SINK_INPUT_DRAINED
)
526 state
= PA_SINK_INPUT_RUNNING
;
528 if (i
->state
== state
)
531 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);
533 update_n_corked(i
, state
);
536 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
) {
537 update_n_corked(ssync
, state
);
538 ssync
->state
= state
;
540 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
) {
541 update_n_corked(ssync
, state
);
542 ssync
->state
= state
;
545 if (state
!= PA_SINK_INPUT_UNLINKED
) {
546 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], i
);
548 for (ssync
= i
->sync_prev
; ssync
; ssync
= ssync
->sync_prev
)
549 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
551 for (ssync
= i
->sync_next
; ssync
; ssync
= ssync
->sync_next
)
552 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED
], ssync
);
554 if (PA_SINK_INPUT_IS_LINKED(state
))
555 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
558 pa_sink_update_status(i
->sink
);
561 /* Called from main context */
562 void pa_sink_input_unlink(pa_sink_input
*i
) {
564 pa_source_output
*o
, *p
= NULL
;
567 pa_assert_ctl_context();
569 /* See pa_sink_unlink() for a couple of comments how this function
572 pa_sink_input_ref(i
);
574 linked
= PA_SINK_INPUT_IS_LINKED(i
->state
);
577 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK
], i
);
580 i
->sync_prev
->sync_next
= i
->sync_next
;
582 i
->sync_next
->sync_prev
= i
->sync_prev
;
584 i
->sync_prev
= i
->sync_next
= NULL
;
586 pa_idxset_remove_by_data(i
->core
->sink_inputs
, i
, NULL
);
589 if (pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
))
590 pa_sink_input_unref(i
);
593 pa_idxset_remove_by_data(i
->client
->sink_inputs
, i
, NULL
);
595 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
597 pa_source_output_kill(o
);
601 update_n_corked(i
, PA_SINK_INPUT_UNLINKED
);
602 i
->state
= PA_SINK_INPUT_UNLINKED
;
604 if (linked
&& i
->sink
) {
605 /* We might need to update the sink's volume if we are in flat volume mode. */
606 if (pa_sink_flat_volume_enabled(i
->sink
))
607 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
609 if (i
->sink
->asyncmsgq
)
610 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_REMOVE_INPUT
, i
, 0, NULL
) == 0);
612 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
613 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
614 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
620 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_REMOVE
, i
->index
);
621 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST
], i
);
625 pa_sink_update_status(i
->sink
);
629 pa_core_maybe_vacuum(i
->core
);
631 pa_sink_input_unref(i
);
634 /* Called from main context */
635 static void sink_input_free(pa_object
*o
) {
636 pa_sink_input
* i
= PA_SINK_INPUT(o
);
639 pa_assert_ctl_context();
640 pa_assert(pa_sink_input_refcnt(i
) == 0);
642 if (PA_SINK_INPUT_IS_LINKED(i
->state
))
643 pa_sink_input_unlink(i
);
645 pa_log_info("Freeing input %u \"%s\"", i
->index
, pa_strnull(pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
)));
647 /* Side note: this function must be able to destruct properly any
648 * kind of sink input in any state, even those which are
649 * "half-moved" or are connected to sinks that have no asyncmsgq
650 * and are hence half-destructed themselves! */
652 if (i
->thread_info
.render_memblockq
)
653 pa_memblockq_free(i
->thread_info
.render_memblockq
);
655 if (i
->thread_info
.resampler
)
656 pa_resampler_free(i
->thread_info
.resampler
);
659 pa_format_info_free(i
->format
);
662 pa_proplist_free(i
->proplist
);
664 if (i
->direct_outputs
)
665 pa_idxset_free(i
->direct_outputs
, NULL
, NULL
);
667 if (i
->thread_info
.direct_outputs
)
668 pa_hashmap_free(i
->thread_info
.direct_outputs
, NULL
, NULL
);
674 /* Called from main context */
675 void pa_sink_input_put(pa_sink_input
*i
) {
676 pa_sink_input_state_t state
;
678 pa_sink_input_assert_ref(i
);
679 pa_assert_ctl_context();
681 pa_assert(i
->state
== PA_SINK_INPUT_INIT
);
683 /* The following fields must be initialized properly */
685 pa_assert(i
->process_rewind
);
688 state
= i
->flags
& PA_SINK_INPUT_START_CORKED
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
;
690 update_n_corked(i
, state
);
693 /* We might need to update the sink's volume if we are in flat volume mode. */
694 if (pa_sink_flat_volume_enabled(i
->sink
))
695 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
697 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
698 pa_assert(pa_cvolume_is_norm(&i
->volume
));
699 pa_assert(pa_cvolume_is_norm(&i
->reference_ratio
));
702 set_real_ratio(i
, &i
->volume
);
705 /* If we're entering passthrough mode, disable the monitor */
706 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
707 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
709 i
->thread_info
.soft_volume
= i
->soft_volume
;
710 i
->thread_info
.muted
= i
->muted
;
712 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_ADD_INPUT
, i
, 0, NULL
) == 0);
714 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_NEW
, i
->index
);
715 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PUT
], i
);
717 pa_sink_update_status(i
->sink
);
720 /* Called from main context */
721 void pa_sink_input_kill(pa_sink_input
*i
) {
722 pa_sink_input_assert_ref(i
);
723 pa_assert_ctl_context();
724 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
729 /* Called from main context */
730 pa_usec_t
pa_sink_input_get_latency(pa_sink_input
*i
, pa_usec_t
*sink_latency
) {
731 pa_usec_t r
[2] = { 0, 0 };
733 pa_sink_input_assert_ref(i
);
734 pa_assert_ctl_context();
735 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
737 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_LATENCY
, r
, 0, NULL
) == 0);
740 r
[0] += i
->get_latency(i
);
743 *sink_latency
= r
[1];
748 /* Called from thread context */
749 void pa_sink_input_peek(pa_sink_input
*i
, size_t slength
/* in sink frames */, pa_memchunk
*chunk
, pa_cvolume
*volume
) {
750 pa_bool_t do_volume_adj_here
, need_volume_factor_sink
;
751 pa_bool_t volume_is_norm
;
752 size_t block_size_max_sink
, block_size_max_sink_input
;
755 pa_sink_input_assert_ref(i
);
756 pa_sink_input_assert_io_context(i
);
757 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
758 pa_assert(pa_frame_aligned(slength
, &i
->sink
->sample_spec
));
762 /* pa_log_debug("peek"); */
764 pa_assert(i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
||
765 i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
766 i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
);
768 block_size_max_sink_input
= i
->thread_info
.resampler
?
769 pa_resampler_max_block_size(i
->thread_info
.resampler
) :
770 pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sample_spec
);
772 block_size_max_sink
= pa_frame_align(pa_mempool_block_size_max(i
->core
->mempool
), &i
->sink
->sample_spec
);
774 /* Default buffer size */
776 slength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sink
->sample_spec
);
778 if (slength
> block_size_max_sink
)
779 slength
= block_size_max_sink
;
781 if (i
->thread_info
.resampler
) {
782 ilength
= pa_resampler_request(i
->thread_info
.resampler
, slength
);
785 ilength
= pa_frame_align(CONVERT_BUFFER_LENGTH
, &i
->sample_spec
);
789 if (ilength
> block_size_max_sink_input
)
790 ilength
= block_size_max_sink_input
;
792 /* If the channel maps of the sink and this stream differ, we need
793 * to adjust the volume *before* we resample. Otherwise we can do
794 * it after and leave it for the sink code */
796 do_volume_adj_here
= !pa_channel_map_equal(&i
->channel_map
, &i
->sink
->channel_map
);
797 volume_is_norm
= pa_cvolume_is_norm(&i
->thread_info
.soft_volume
) && !i
->thread_info
.muted
;
798 need_volume_factor_sink
= !pa_cvolume_is_norm(&i
->volume_factor_sink
);
800 while (!pa_memblockq_is_readable(i
->thread_info
.render_memblockq
)) {
803 /* There's nothing in our render queue. We need to fill it up
804 * with data from the implementor. */
806 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
||
807 i
->pop(i
, ilength
, &tchunk
) < 0) {
809 /* OK, we're corked or the implementor didn't give us any
810 * data, so let's just hand out silence */
811 pa_atomic_store(&i
->thread_info
.drained
, 1);
813 pa_memblockq_seek(i
->thread_info
.render_memblockq
, (int64_t) slength
, PA_SEEK_RELATIVE
, TRUE
);
814 i
->thread_info
.playing_for
= 0;
815 if (i
->thread_info
.underrun_for
!= (uint64_t) -1)
816 i
->thread_info
.underrun_for
+= ilength
;
820 pa_atomic_store(&i
->thread_info
.drained
, 0);
822 pa_assert(tchunk
.length
> 0);
823 pa_assert(tchunk
.memblock
);
825 i
->thread_info
.underrun_for
= 0;
826 i
->thread_info
.playing_for
+= tchunk
.length
;
828 while (tchunk
.length
> 0) {
830 pa_bool_t nvfs
= need_volume_factor_sink
;
833 pa_memblock_ref(wchunk
.memblock
);
835 if (wchunk
.length
> block_size_max_sink_input
)
836 wchunk
.length
= block_size_max_sink_input
;
838 /* It might be necessary to adjust the volume here */
839 if (do_volume_adj_here
&& !volume_is_norm
) {
840 pa_memchunk_make_writable(&wchunk
, 0);
842 if (i
->thread_info
.muted
) {
843 pa_silence_memchunk(&wchunk
, &i
->thread_info
.sample_spec
);
846 } else if (!i
->thread_info
.resampler
&& nvfs
) {
849 /* If we don't need a resampler we can merge the
850 * post and the pre volume adjustment into one */
852 pa_sw_cvolume_multiply(&v
, &i
->thread_info
.soft_volume
, &i
->volume_factor_sink
);
853 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &v
);
857 pa_volume_memchunk(&wchunk
, &i
->thread_info
.sample_spec
, &i
->thread_info
.soft_volume
);
860 if (!i
->thread_info
.resampler
) {
863 pa_memchunk_make_writable(&wchunk
, 0);
864 pa_volume_memchunk(&wchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
867 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &wchunk
);
870 pa_resampler_run(i
->thread_info
.resampler
, &wchunk
, &rchunk
);
872 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
874 if (rchunk
.memblock
) {
877 pa_memchunk_make_writable(&rchunk
, 0);
878 pa_volume_memchunk(&rchunk
, &i
->sink
->sample_spec
, &i
->volume_factor_sink
);
881 pa_memblockq_push_align(i
->thread_info
.render_memblockq
, &rchunk
);
882 pa_memblock_unref(rchunk
.memblock
);
886 pa_memblock_unref(wchunk
.memblock
);
888 tchunk
.index
+= wchunk
.length
;
889 tchunk
.length
-= wchunk
.length
;
892 pa_memblock_unref(tchunk
.memblock
);
895 pa_assert_se(pa_memblockq_peek(i
->thread_info
.render_memblockq
, chunk
) >= 0);
897 pa_assert(chunk
->length
> 0);
898 pa_assert(chunk
->memblock
);
900 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
902 if (chunk
->length
> block_size_max_sink
)
903 chunk
->length
= block_size_max_sink
;
905 /* Let's see if we had to apply the volume adjustment ourselves,
906 * or if this can be done by the sink for us */
908 if (do_volume_adj_here
)
909 /* We had different channel maps, so we already did the adjustment */
910 pa_cvolume_reset(volume
, i
->sink
->sample_spec
.channels
);
911 else if (i
->thread_info
.muted
)
912 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
913 pa_cvolume_mute(volume
, i
->sink
->sample_spec
.channels
);
915 *volume
= i
->thread_info
.soft_volume
;
918 /* Called from thread context */
919 void pa_sink_input_drop(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
921 pa_sink_input_assert_ref(i
);
922 pa_sink_input_assert_io_context(i
);
923 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
924 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
925 pa_assert(nbytes
> 0);
927 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
929 pa_memblockq_drop(i
->thread_info
.render_memblockq
, nbytes
);
932 /* Called from thread context */
933 void pa_sink_input_process_rewind(pa_sink_input
*i
, size_t nbytes
/* in sink sample spec */) {
935 pa_bool_t called
= FALSE
;
937 pa_sink_input_assert_ref(i
);
938 pa_sink_input_assert_io_context(i
);
939 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
940 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
942 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
944 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
946 if (nbytes
> 0 && !i
->thread_info
.dont_rewind_render
) {
947 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes
);
948 pa_memblockq_rewind(i
->thread_info
.render_memblockq
, nbytes
);
951 if (i
->thread_info
.rewrite_nbytes
== (size_t) -1) {
953 /* We were asked to drop all buffered data, and rerequest new
954 * data from implementor the next time push() is called */
956 pa_memblockq_flush_write(i
->thread_info
.render_memblockq
, TRUE
);
958 } else if (i
->thread_info
.rewrite_nbytes
> 0) {
959 size_t max_rewrite
, amount
;
961 /* Calculate how much make sense to rewrite at most */
962 max_rewrite
= nbytes
+ lbq
;
964 /* Transform into local domain */
965 if (i
->thread_info
.resampler
)
966 max_rewrite
= pa_resampler_request(i
->thread_info
.resampler
, max_rewrite
);
968 /* Calculate how much of the rewinded data should actually be rewritten */
969 amount
= PA_MIN(i
->thread_info
.rewrite_nbytes
, max_rewrite
);
972 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount
);
974 /* Tell the implementor */
975 if (i
->process_rewind
)
976 i
->process_rewind(i
, amount
);
979 /* Convert back to to sink domain */
980 if (i
->thread_info
.resampler
)
981 amount
= pa_resampler_result(i
->thread_info
.resampler
, amount
);
984 /* Ok, now update the write pointer */
985 pa_memblockq_seek(i
->thread_info
.render_memblockq
, - ((int64_t) amount
), PA_SEEK_RELATIVE
, TRUE
);
987 if (i
->thread_info
.rewrite_flush
)
988 pa_memblockq_silence(i
->thread_info
.render_memblockq
);
990 /* And reset the resampler */
991 if (i
->thread_info
.resampler
)
992 pa_resampler_reset(i
->thread_info
.resampler
);
997 if (i
->process_rewind
)
998 i
->process_rewind(i
, 0);
1000 i
->thread_info
.rewrite_nbytes
= 0;
1001 i
->thread_info
.rewrite_flush
= FALSE
;
1002 i
->thread_info
.dont_rewind_render
= FALSE
;
1005 /* Called from thread context */
1006 size_t pa_sink_input_get_max_rewind(pa_sink_input
*i
) {
1007 pa_sink_input_assert_ref(i
);
1008 pa_sink_input_assert_io_context(i
);
1010 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_rewind
) : i
->sink
->thread_info
.max_rewind
;
1013 /* Called from thread context */
1014 size_t pa_sink_input_get_max_request(pa_sink_input
*i
) {
1015 pa_sink_input_assert_ref(i
);
1016 pa_sink_input_assert_io_context(i
);
1018 /* We're not verifying the status here, to allow this to be called
1019 * in the state change handler between _INIT and _RUNNING */
1021 return i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, i
->sink
->thread_info
.max_request
) : i
->sink
->thread_info
.max_request
;
1024 /* Called from thread context */
1025 void pa_sink_input_update_max_rewind(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1026 pa_sink_input_assert_ref(i
);
1027 pa_sink_input_assert_io_context(i
);
1028 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1029 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1031 pa_memblockq_set_maxrewind(i
->thread_info
.render_memblockq
, nbytes
);
1033 if (i
->update_max_rewind
)
1034 i
->update_max_rewind(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1037 /* Called from thread context */
1038 void pa_sink_input_update_max_request(pa_sink_input
*i
, size_t nbytes
/* in the sink's sample spec */) {
1039 pa_sink_input_assert_ref(i
);
1040 pa_sink_input_assert_io_context(i
);
1041 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
));
1042 pa_assert(pa_frame_aligned(nbytes
, &i
->sink
->sample_spec
));
1044 if (i
->update_max_request
)
1045 i
->update_max_request(i
, i
->thread_info
.resampler
? pa_resampler_request(i
->thread_info
.resampler
, nbytes
) : nbytes
);
1048 /* Called from thread context */
1049 pa_usec_t
pa_sink_input_set_requested_latency_within_thread(pa_sink_input
*i
, pa_usec_t usec
) {
1050 pa_sink_input_assert_ref(i
);
1051 pa_sink_input_assert_io_context(i
);
1053 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1054 usec
= i
->sink
->thread_info
.fixed_latency
;
1056 if (usec
!= (pa_usec_t
) -1)
1057 usec
= PA_CLAMP(usec
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
1059 i
->thread_info
.requested_sink_latency
= usec
;
1060 pa_sink_invalidate_requested_latency(i
->sink
, TRUE
);
1065 /* Called from main context */
1066 pa_usec_t
pa_sink_input_set_requested_latency(pa_sink_input
*i
, pa_usec_t usec
) {
1067 pa_sink_input_assert_ref(i
);
1068 pa_assert_ctl_context();
1070 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1071 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1075 /* If this sink input is not realized yet or we are being moved,
1076 * we have to touch the thread info data directly */
1079 if (!(i
->sink
->flags
& PA_SINK_DYNAMIC_LATENCY
))
1080 usec
= pa_sink_get_fixed_latency(i
->sink
);
1082 if (usec
!= (pa_usec_t
) -1) {
1083 pa_usec_t min_latency
, max_latency
;
1084 pa_sink_get_latency_range(i
->sink
, &min_latency
, &max_latency
);
1085 usec
= PA_CLAMP(usec
, min_latency
, max_latency
);
1089 i
->thread_info
.requested_sink_latency
= usec
;
1094 /* Called from main context */
1095 pa_usec_t
pa_sink_input_get_requested_latency(pa_sink_input
*i
) {
1096 pa_sink_input_assert_ref(i
);
1097 pa_assert_ctl_context();
1099 if (PA_SINK_INPUT_IS_LINKED(i
->state
) && i
->sink
) {
1101 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
, &usec
, 0, NULL
) == 0);
1105 /* If this sink input is not realized yet or we are being moved,
1106 * we have to touch the thread info data directly */
1108 return i
->thread_info
.requested_sink_latency
;
1111 /* Called from main context */
1112 void pa_sink_input_set_volume(pa_sink_input
*i
, const pa_cvolume
*volume
, pa_bool_t save
, pa_bool_t absolute
) {
1115 pa_sink_input_assert_ref(i
);
1116 pa_assert_ctl_context();
1117 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1119 pa_assert(pa_cvolume_valid(volume
));
1120 pa_assert(volume
->channels
== 1 || pa_cvolume_compatible(volume
, &i
->sample_spec
));
1121 pa_assert(i
->volume_writable
);
1123 if (!absolute
&& pa_sink_flat_volume_enabled(i
->sink
)) {
1124 v
= i
->sink
->reference_volume
;
1125 pa_cvolume_remap(&v
, &i
->sink
->channel_map
, &i
->channel_map
);
1127 if (pa_cvolume_compatible(volume
, &i
->sample_spec
))
1128 volume
= pa_sw_cvolume_multiply(&v
, &v
, volume
);
1130 volume
= pa_sw_cvolume_multiply_scalar(&v
, &v
, pa_cvolume_max(volume
));
1132 if (!pa_cvolume_compatible(volume
, &i
->sample_spec
)) {
1134 volume
= pa_cvolume_scale(&v
, pa_cvolume_max(volume
));
1138 if (pa_cvolume_equal(volume
, &i
->volume
)) {
1139 i
->save_volume
= i
->save_volume
|| save
;
1143 i
->volume
= *volume
;
1144 i
->save_volume
= save
;
1146 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1147 /* We are in flat volume mode, so let's update all sink input
1148 * volumes and update the flat volume of the sink */
1150 pa_sink_set_volume(i
->sink
, NULL
, TRUE
, save
);
1153 /* OK, we are in normal volume mode. The volume only affects
1155 set_real_ratio(i
, volume
);
1157 /* Copy the new soft_volume to the thread_info struct */
1158 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
, NULL
, 0, NULL
) == 0);
1161 /* The volume changed, let's tell people so */
1162 if (i
->volume_changed
)
1163 i
->volume_changed(i
);
1165 /* The virtual volume changed, let's tell people so */
1166 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1169 /* Called from main context */
1170 static void set_real_ratio(pa_sink_input
*i
, const pa_cvolume
*v
) {
1171 pa_sink_input_assert_ref(i
);
1172 pa_assert_ctl_context();
1173 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1174 pa_assert(!v
|| pa_cvolume_compatible(v
, &i
->sample_spec
));
1176 /* This basically calculates:
1178 * i->real_ratio := v
1179 * i->soft_volume := i->real_ratio * i->volume_factor */
1184 pa_cvolume_reset(&i
->real_ratio
, i
->sample_spec
.channels
);
1186 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1187 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1190 /* Called from main or I/O context */
1191 pa_bool_t
pa_sink_input_is_passthrough(pa_sink_input
*i
) {
1192 pa_sink_input_assert_ref(i
);
1194 if (PA_UNLIKELY(!pa_format_info_is_pcm(i
->format
)))
1197 if (PA_UNLIKELY(i
->flags
& PA_SINK_INPUT_PASSTHROUGH
))
1203 /* Called from main context */
1204 pa_bool_t
pa_sink_input_is_volume_readable(pa_sink_input
*i
) {
1205 pa_sink_input_assert_ref(i
);
1206 pa_assert_ctl_context();
1208 return !pa_sink_input_is_passthrough(i
);
1211 /* Called from main context */
1212 pa_cvolume
*pa_sink_input_get_volume(pa_sink_input
*i
, pa_cvolume
*volume
, pa_bool_t absolute
) {
1213 pa_sink_input_assert_ref(i
);
1214 pa_assert_ctl_context();
1215 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1216 pa_assert(pa_sink_input_is_volume_readable(i
));
1218 if (absolute
|| !pa_sink_flat_volume_enabled(i
->sink
))
1219 *volume
= i
->volume
;
1221 *volume
= i
->reference_ratio
;
1226 /* Called from main context */
1227 void pa_sink_input_set_mute(pa_sink_input
*i
, pa_bool_t mute
, pa_bool_t save
) {
1228 pa_sink_input_assert_ref(i
);
1229 pa_assert_ctl_context();
1230 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1232 if (!i
->muted
== !mute
) {
1233 i
->save_muted
= i
->save_muted
|| mute
;
1238 i
->save_muted
= save
;
1240 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
, NULL
, 0, NULL
) == 0);
1242 /* The mute status changed, let's tell people so */
1243 if (i
->mute_changed
)
1246 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1249 /* Called from main context */
1250 pa_bool_t
pa_sink_input_get_mute(pa_sink_input
*i
) {
1251 pa_sink_input_assert_ref(i
);
1252 pa_assert_ctl_context();
1253 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1258 /* Called from main thread */
1259 void pa_sink_input_update_proplist(pa_sink_input
*i
, pa_update_mode_t mode
, pa_proplist
*p
) {
1260 pa_sink_input_assert_ref(i
);
1261 pa_assert_ctl_context();
1264 pa_proplist_update(i
->proplist
, mode
, p
);
1266 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1267 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1268 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1272 /* Called from main context */
1273 void pa_sink_input_cork(pa_sink_input
*i
, pa_bool_t b
) {
1274 pa_sink_input_assert_ref(i
);
1275 pa_assert_ctl_context();
1276 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1278 sink_input_set_state(i
, b
? PA_SINK_INPUT_CORKED
: PA_SINK_INPUT_RUNNING
);
1281 /* Called from main context */
1282 int pa_sink_input_set_rate(pa_sink_input
*i
, uint32_t rate
) {
1283 pa_sink_input_assert_ref(i
);
1284 pa_assert_ctl_context();
1285 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1286 pa_return_val_if_fail(i
->thread_info
.resampler
, -PA_ERR_BADSTATE
);
1288 if (i
->sample_spec
.rate
== rate
)
1291 i
->sample_spec
.rate
= rate
;
1293 pa_asyncmsgq_post(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
), PA_SINK_INPUT_MESSAGE_SET_RATE
, PA_UINT_TO_PTR(rate
), 0, NULL
, NULL
);
1295 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1299 /* Called from main context */
1300 void pa_sink_input_set_name(pa_sink_input
*i
, const char *name
) {
1302 pa_sink_input_assert_ref(i
);
1303 pa_assert_ctl_context();
1305 if (!name
&& !pa_proplist_contains(i
->proplist
, PA_PROP_MEDIA_NAME
))
1308 old
= pa_proplist_gets(i
->proplist
, PA_PROP_MEDIA_NAME
);
1310 if (old
&& name
&& pa_streq(old
, name
))
1314 pa_proplist_sets(i
->proplist
, PA_PROP_MEDIA_NAME
, name
);
1316 pa_proplist_unset(i
->proplist
, PA_PROP_MEDIA_NAME
);
1318 if (PA_SINK_INPUT_IS_LINKED(i
->state
)) {
1319 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED
], i
);
1320 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1324 /* Called from main context */
1325 pa_resample_method_t
pa_sink_input_get_resample_method(pa_sink_input
*i
) {
1326 pa_sink_input_assert_ref(i
);
1327 pa_assert_ctl_context();
1329 return i
->actual_resample_method
;
1332 /* Called from main context */
1333 pa_bool_t
pa_sink_input_may_move(pa_sink_input
*i
) {
1334 pa_sink_input_assert_ref(i
);
1335 pa_assert_ctl_context();
1336 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1338 if (i
->flags
& PA_SINK_INPUT_DONT_MOVE
)
1341 if (i
->sync_next
|| i
->sync_prev
) {
1342 pa_log_warn("Moving synchronized streams not supported.");
1349 /* Called from main context */
1350 pa_bool_t
pa_sink_input_may_move_to(pa_sink_input
*i
, pa_sink
*dest
) {
1351 pa_sink_input_assert_ref(i
);
1352 pa_assert_ctl_context();
1353 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1354 pa_sink_assert_ref(dest
);
1356 if (dest
== i
->sink
)
1359 if (!pa_sink_input_may_move(i
))
1362 if (pa_idxset_size(dest
->inputs
) >= PA_MAX_INPUTS_PER_SINK
) {
1363 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1367 if (check_passthrough_connection(pa_sink_input_is_passthrough(i
), dest
) < 0)
1371 if (!i
->may_move_to(i
, dest
))
1377 /* Called from main context */
1378 int pa_sink_input_start_move(pa_sink_input
*i
) {
1379 pa_source_output
*o
, *p
= NULL
;
1382 pa_sink_input_assert_ref(i
);
1383 pa_assert_ctl_context();
1384 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1387 if (!pa_sink_input_may_move(i
))
1388 return -PA_ERR_NOTSUPPORTED
;
1390 if ((r
= pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_START
], i
)) < 0)
1393 /* Kill directly connected outputs */
1394 while ((o
= pa_idxset_first(i
->direct_outputs
, NULL
))) {
1396 pa_source_output_kill(o
);
1399 pa_assert(pa_idxset_isempty(i
->direct_outputs
));
1401 pa_idxset_remove_by_data(i
->sink
->inputs
, i
, NULL
);
1403 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1404 pa_assert_se(i
->sink
->n_corked
-- >= 1);
1406 if (pa_sink_flat_volume_enabled(i
->sink
))
1407 /* We might need to update the sink's volume if we are in flat
1409 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, FALSE
);
1411 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_START_MOVE
, i
, 0, NULL
) == 0);
1413 /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
1414 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
1415 pa_source_suspend(i
->sink
->monitor_source
, FALSE
, PA_SUSPEND_PASSTHROUGH
);
1417 pa_sink_update_status(i
->sink
);
1418 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->sink
->channel_map
, &i
->channel_map
);
1421 pa_sink_input_unref(i
);
1426 /* Called from main context. If i has an origin sink that uses volume sharing,
1427 * then also the origin sink and all streams connected to it need to update
1428 * their volume - this function does all that by using recursion. */
1429 static void update_volume_due_to_moving(pa_sink_input
*i
, pa_sink
*dest
) {
1430 pa_cvolume old_volume
;
1434 pa_assert(i
->sink
); /* The destination sink should already be set. */
1436 if (i
->origin_sink
&& (i
->origin_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)) {
1437 pa_sink
*root_sink
= i
->sink
;
1438 pa_sink_input
*origin_sink_input
;
1441 while (root_sink
->flags
& PA_SINK_SHARE_VOLUME_WITH_MASTER
)
1442 root_sink
= root_sink
->input_to_master
->sink
;
1444 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1445 /* Ok, so the origin sink uses volume sharing, and flat volume is
1446 * enabled. The volume will have to be updated as follows:
1448 * i->volume := i->sink->real_volume
1449 * (handled later by pa_sink_set_volume)
1450 * i->reference_ratio := i->volume / i->sink->reference_volume
1451 * (handled later by pa_sink_set_volume)
1452 * i->real_ratio stays unchanged
1453 * (streams whose origin sink uses volume sharing should
1454 * always have real_ratio of 0 dB)
1455 * i->soft_volume stays unchanged
1456 * (streams whose origin sink uses volume sharing should
1457 * always have volume_factor as soft_volume, so no change
1458 * should be needed) */
1460 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1461 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1463 /* Notifications will be sent by pa_sink_set_volume(). */
1466 /* Ok, so the origin sink uses volume sharing, and flat volume is
1467 * disabled. The volume will have to be updated as follows:
1470 * i->reference_ratio := 0 dB
1471 * i->real_ratio stays unchanged
1472 * (streams whose origin sink uses volume sharing should
1473 * always have real_ratio of 0 dB)
1474 * i->soft_volume stays unchanged
1475 * (streams whose origin sink uses volume sharing should
1476 * always have volume_factor as soft_volume, so no change
1477 * should be needed) */
1479 old_volume
= i
->volume
;
1480 pa_cvolume_reset(&i
->volume
, i
->volume
.channels
);
1481 pa_cvolume_reset(&i
->reference_ratio
, i
->reference_ratio
.channels
);
1482 pa_assert(pa_cvolume_is_norm(&i
->real_ratio
));
1483 pa_assert(pa_cvolume_equal(&i
->soft_volume
, &i
->volume_factor
));
1485 /* Notify others about the changed sink input volume. */
1486 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1487 if (i
->volume_changed
)
1488 i
->volume_changed(i
);
1490 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1494 /* Additionally, the origin sink volume needs updating:
1496 * i->origin_sink->reference_volume := root_sink->reference_volume
1497 * i->origin_sink->real_volume := root_sink->real_volume
1498 * i->origin_sink->soft_volume stays unchanged
1499 * (sinks that use volume sharing should always have
1500 * soft_volume of 0 dB) */
1502 old_volume
= i
->origin_sink
->reference_volume
;
1504 i
->origin_sink
->reference_volume
= root_sink
->reference_volume
;
1505 pa_cvolume_remap(&i
->origin_sink
->reference_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1507 i
->origin_sink
->real_volume
= root_sink
->real_volume
;
1508 pa_cvolume_remap(&i
->origin_sink
->real_volume
, &root_sink
->channel_map
, &i
->origin_sink
->channel_map
);
1510 pa_assert(pa_cvolume_is_norm(&i
->origin_sink
->soft_volume
));
1512 /* Notify others about the changed sink volume. If you wonder whether
1513 * i->origin_sink->set_volume() should be called somewhere, that's not
1514 * the case, because sinks that use volume sharing shouldn't have any
1515 * internal volume that set_volume() would update. If you wonder
1516 * whether the thread_info variables should be synced, yes, they
1517 * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
1519 if (!pa_cvolume_equal(&i
->origin_sink
->reference_volume
, &old_volume
))
1520 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->origin_sink
->index
);
1522 /* Recursively update origin sink inputs. */
1523 PA_IDXSET_FOREACH(origin_sink_input
, i
->origin_sink
->inputs
, idx
)
1524 update_volume_due_to_moving(origin_sink_input
, dest
);
1527 old_volume
= i
->volume
;
1529 if (pa_sink_flat_volume_enabled(i
->sink
)) {
1530 /* Ok, so this is a regular stream, and flat volume is enabled. The
1531 * volume will have to be updated as follows:
1533 * i->volume := i->reference_ratio * i->sink->reference_volume
1534 * i->reference_ratio stays unchanged
1535 * i->real_ratio := i->volume / i->sink->real_volume
1536 * (handled later by pa_sink_set_volume)
1537 * i->soft_volume := i->real_ratio * i->volume_factor
1538 * (handled later by pa_sink_set_volume) */
1540 i
->volume
= i
->sink
->reference_volume
;
1541 pa_cvolume_remap(&i
->volume
, &i
->sink
->channel_map
, &i
->channel_map
);
1542 pa_sw_cvolume_multiply(&i
->volume
, &i
->volume
, &i
->reference_ratio
);
1545 /* Ok, so this is a regular stream, and flat volume is disabled.
1546 * The volume will have to be updated as follows:
1548 * i->volume := i->reference_ratio
1549 * i->reference_ratio stays unchanged
1550 * i->real_ratio := i->reference_ratio
1551 * i->soft_volume := i->real_ratio * i->volume_factor */
1553 i
->volume
= i
->reference_ratio
;
1554 i
->real_ratio
= i
->reference_ratio
;
1555 pa_sw_cvolume_multiply(&i
->soft_volume
, &i
->real_ratio
, &i
->volume_factor
);
1558 /* Notify others about the changed sink input volume. */
1559 if (!pa_cvolume_equal(&i
->volume
, &old_volume
)) {
1560 /* XXX: In case i->sink has flat volume enabled, then real_ratio
1561 * and soft_volume are not updated yet. Let's hope that the
1562 * callback implementation doesn't care about those variables... */
1563 if (i
->volume_changed
)
1564 i
->volume_changed(i
);
1566 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1570 /* If i->sink == dest, then recursion has finished, and we can finally call
1571 * pa_sink_set_volume(), which will do the rest of the updates. */
1572 if ((i
->sink
== dest
) && pa_sink_flat_volume_enabled(i
->sink
))
1573 pa_sink_set_volume(i
->sink
, NULL
, FALSE
, i
->save_volume
);
1576 /* Called from main context */
1577 int pa_sink_input_finish_move(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1578 pa_resampler
*new_resampler
;
1580 pa_sink_input_assert_ref(i
);
1581 pa_assert_ctl_context();
1582 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1583 pa_assert(!i
->sink
);
1584 pa_sink_assert_ref(dest
);
1586 if (!pa_sink_input_may_move_to(i
, dest
))
1587 return -PA_ERR_NOTSUPPORTED
;
1589 if (pa_sink_input_is_passthrough(i
) && !pa_sink_check_format(dest
, i
->format
)) {
1590 /* FIXME: Fire a message here so the client can renegotiate */
1591 return -PA_ERR_NOTSUPPORTED
;
1594 if (i
->thread_info
.resampler
&&
1595 pa_sample_spec_equal(pa_resampler_output_sample_spec(i
->thread_info
.resampler
), &dest
->sample_spec
) &&
1596 pa_channel_map_equal(pa_resampler_output_channel_map(i
->thread_info
.resampler
), &dest
->channel_map
))
1598 /* Try to reuse the old resampler if possible */
1599 new_resampler
= i
->thread_info
.resampler
;
1601 else if ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ||
1602 !pa_sample_spec_equal(&i
->sample_spec
, &dest
->sample_spec
) ||
1603 !pa_channel_map_equal(&i
->channel_map
, &dest
->channel_map
)) {
1605 /* Okey, we need a new resampler for the new sink */
1607 if (!(new_resampler
= pa_resampler_new(
1609 &i
->sample_spec
, &i
->channel_map
,
1610 &dest
->sample_spec
, &dest
->channel_map
,
1611 i
->requested_resample_method
,
1612 ((i
->flags
& PA_SINK_INPUT_VARIABLE_RATE
) ? PA_RESAMPLER_VARIABLE_RATE
: 0) |
1613 ((i
->flags
& PA_SINK_INPUT_NO_REMAP
) ? PA_RESAMPLER_NO_REMAP
: 0) |
1614 (i
->core
->disable_remixing
|| (i
->flags
& PA_SINK_INPUT_NO_REMIX
) ? PA_RESAMPLER_NO_REMIX
: 0)))) {
1615 pa_log_warn("Unsupported resampling operation.");
1616 return -PA_ERR_NOTSUPPORTED
;
1619 new_resampler
= NULL
;
1625 i
->save_sink
= save
;
1626 pa_idxset_put(dest
->inputs
, pa_sink_input_ref(i
), NULL
);
1628 pa_cvolume_remap(&i
->volume_factor_sink
, &i
->channel_map
, &i
->sink
->channel_map
);
1630 if (pa_sink_input_get_state(i
) == PA_SINK_INPUT_CORKED
)
1631 i
->sink
->n_corked
++;
1633 /* Replace resampler and render queue */
1634 if (new_resampler
!= i
->thread_info
.resampler
) {
1636 if (i
->thread_info
.resampler
)
1637 pa_resampler_free(i
->thread_info
.resampler
);
1638 i
->thread_info
.resampler
= new_resampler
;
1640 pa_memblockq_free(i
->thread_info
.render_memblockq
);
1642 i
->thread_info
.render_memblockq
= pa_memblockq_new(
1644 MEMBLOCKQ_MAXLENGTH
,
1646 pa_frame_size(&i
->sink
->sample_spec
),
1652 pa_sink_update_status(dest
);
1654 update_volume_due_to_moving(i
, dest
);
1656 pa_assert_se(pa_asyncmsgq_send(i
->sink
->asyncmsgq
, PA_MSGOBJECT(i
->sink
), PA_SINK_MESSAGE_FINISH_MOVE
, i
, 0, NULL
) == 0);
1658 /* If we're entering passthrough mode, disable the monitor */
1659 if (pa_sink_input_is_passthrough(i
) && i
->sink
->monitor_source
)
1660 pa_source_suspend(i
->sink
->monitor_source
, TRUE
, PA_SUSPEND_PASSTHROUGH
);
1662 pa_log_debug("Successfully moved sink input %i to %s.", i
->index
, dest
->name
);
1664 /* Notify everyone */
1665 pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH
], i
);
1667 pa_subscription_post(i
->core
, PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
, i
->index
);
1672 /* Called from main context */
1673 void pa_sink_input_fail_move(pa_sink_input
*i
) {
1675 pa_sink_input_assert_ref(i
);
1676 pa_assert_ctl_context();
1677 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1678 pa_assert(!i
->sink
);
1680 /* Check if someone wants this sink input? */
1681 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL
], i
) == PA_HOOK_STOP
)
1687 pa_sink_input_kill(i
);
1690 /* Called from main context */
1691 int pa_sink_input_move_to(pa_sink_input
*i
, pa_sink
*dest
, pa_bool_t save
) {
1694 pa_sink_input_assert_ref(i
);
1695 pa_assert_ctl_context();
1696 pa_assert(PA_SINK_INPUT_IS_LINKED(i
->state
));
1698 pa_sink_assert_ref(dest
);
1700 if (dest
== i
->sink
)
1703 if (!pa_sink_input_may_move_to(i
, dest
))
1704 return -PA_ERR_NOTSUPPORTED
;
1706 pa_sink_input_ref(i
);
1708 if ((r
= pa_sink_input_start_move(i
)) < 0) {
1709 pa_sink_input_unref(i
);
1713 if ((r
= pa_sink_input_finish_move(i
, dest
, save
)) < 0) {
1714 pa_sink_input_fail_move(i
);
1715 pa_sink_input_unref(i
);
1719 pa_sink_input_unref(i
);
1724 /* Called from IO thread context */
1725 void pa_sink_input_set_state_within_thread(pa_sink_input
*i
, pa_sink_input_state_t state
) {
1726 pa_bool_t corking
, uncorking
;
1728 pa_sink_input_assert_ref(i
);
1729 pa_sink_input_assert_io_context(i
);
1731 if (state
== i
->thread_info
.state
)
1734 if ((state
== PA_SINK_INPUT_DRAINED
|| state
== PA_SINK_INPUT_RUNNING
) &&
1735 !(i
->thread_info
.state
== PA_SINK_INPUT_DRAINED
|| i
->thread_info
.state
!= PA_SINK_INPUT_RUNNING
))
1736 pa_atomic_store(&i
->thread_info
.drained
, 1);
1738 corking
= state
== PA_SINK_INPUT_CORKED
&& i
->thread_info
.state
== PA_SINK_INPUT_RUNNING
;
1739 uncorking
= i
->thread_info
.state
== PA_SINK_INPUT_CORKED
&& state
== PA_SINK_INPUT_RUNNING
;
1741 if (i
->state_change
)
1742 i
->state_change(i
, state
);
1744 i
->thread_info
.state
= state
;
1748 pa_log_debug("Requesting rewind due to corking");
1750 /* This will tell the implementing sink input driver to rewind
1751 * so that the unplayed already mixed data is not lost */
1752 pa_sink_input_request_rewind(i
, 0, TRUE
, TRUE
, FALSE
);
1754 } else if (uncorking
) {
1756 i
->thread_info
.underrun_for
= (uint64_t) -1;
1757 i
->thread_info
.playing_for
= 0;
1759 pa_log_debug("Requesting rewind due to uncorking");
1761 /* OK, we're being uncorked. Make sure we're not rewound when
1762 * the hw buffer is remixed and request a remix. */
1763 pa_sink_input_request_rewind(i
, 0, FALSE
, TRUE
, TRUE
);
1767 /* Called from thread context, except when it is not. */
1768 int pa_sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1769 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1770 pa_sink_input_assert_ref(i
);
1774 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME
:
1775 if (!pa_cvolume_equal(&i
->thread_info
.soft_volume
, &i
->soft_volume
)) {
1776 i
->thread_info
.soft_volume
= i
->soft_volume
;
1777 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1781 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE
:
1782 if (i
->thread_info
.muted
!= i
->muted
) {
1783 i
->thread_info
.muted
= i
->muted
;
1784 pa_sink_input_request_rewind(i
, 0, TRUE
, FALSE
, FALSE
);
1788 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1789 pa_usec_t
*r
= userdata
;
1791 r
[0] += pa_bytes_to_usec(pa_memblockq_get_length(i
->thread_info
.render_memblockq
), &i
->sink
->sample_spec
);
1792 r
[1] += pa_sink_get_latency_within_thread(i
->sink
);
1797 case PA_SINK_INPUT_MESSAGE_SET_RATE
:
1799 i
->thread_info
.sample_spec
.rate
= PA_PTR_TO_UINT(userdata
);
1800 pa_resampler_set_input_rate(i
->thread_info
.resampler
, PA_PTR_TO_UINT(userdata
));
1804 case PA_SINK_INPUT_MESSAGE_SET_STATE
: {
1805 pa_sink_input
*ssync
;
1807 pa_sink_input_set_state_within_thread(i
, PA_PTR_TO_UINT(userdata
));
1809 for (ssync
= i
->thread_info
.sync_prev
; ssync
; ssync
= ssync
->thread_info
.sync_prev
)
1810 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1812 for (ssync
= i
->thread_info
.sync_next
; ssync
; ssync
= ssync
->thread_info
.sync_next
)
1813 pa_sink_input_set_state_within_thread(ssync
, PA_PTR_TO_UINT(userdata
));
1818 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY
: {
1819 pa_usec_t
*usec
= userdata
;
1821 *usec
= pa_sink_input_set_requested_latency_within_thread(i
, *usec
);
1825 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY
: {
1826 pa_usec_t
*r
= userdata
;
1828 *r
= i
->thread_info
.requested_sink_latency
;
1833 return -PA_ERR_NOTIMPLEMENTED
;
1836 /* Called from main thread */
1837 pa_sink_input_state_t
pa_sink_input_get_state(pa_sink_input
*i
) {
1838 pa_sink_input_assert_ref(i
);
1839 pa_assert_ctl_context();
1841 if (i
->state
== PA_SINK_INPUT_RUNNING
|| i
->state
== PA_SINK_INPUT_DRAINED
)
1842 return pa_atomic_load(&i
->thread_info
.drained
) ? PA_SINK_INPUT_DRAINED
: PA_SINK_INPUT_RUNNING
;
1847 /* Called from IO context */
1848 pa_bool_t
pa_sink_input_safe_to_remove(pa_sink_input
*i
) {
1849 pa_sink_input_assert_ref(i
);
1850 pa_sink_input_assert_io_context(i
);
1852 if (PA_SINK_INPUT_IS_LINKED(i
->thread_info
.state
))
1853 return pa_memblockq_is_empty(i
->thread_info
.render_memblockq
);
1858 /* Called from IO context */
1859 void pa_sink_input_request_rewind(
1861 size_t nbytes
/* in our sample spec */,
1864 pa_bool_t dont_rewind_render
) {
1868 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1869 * and possible and the exact value of this is passed back the
1870 * implementor via process_rewind(). If 'flush' is also TRUE all
1871 * already rendered data is also dropped.
1873 * If 'rewrite' is FALSE the sink is rewound as far as requested
1874 * and possible and the already rendered data is dropped so that
1875 * in the next iteration we read new data from the
1876 * implementor. This implies 'flush' is TRUE. If
1877 * dont_rewind_render is TRUE then the render memblockq is not
1880 /* nbytes = 0 means maximum rewind request */
1882 pa_sink_input_assert_ref(i
);
1883 pa_sink_input_assert_io_context(i
);
1884 pa_assert(rewrite
|| flush
);
1885 pa_assert(!dont_rewind_render
|| !rewrite
);
1887 /* We don't take rewind requests while we are corked */
1888 if (i
->thread_info
.state
== PA_SINK_INPUT_CORKED
)
1891 nbytes
= PA_MAX(i
->thread_info
.rewrite_nbytes
, nbytes
);
1893 /* pa_log_debug("request rewrite %zu", nbytes); */
1895 /* Calculate how much we can rewind locally without having to
1898 lbq
= pa_memblockq_get_length(i
->thread_info
.render_memblockq
);
1902 /* Check if rewinding for the maximum is requested, and if so, fix up */
1905 /* Calculate maximum number of bytes that could be rewound in theory */
1906 nbytes
= i
->sink
->thread_info
.max_rewind
+ lbq
;
1908 /* Transform from sink domain */
1909 if (i
->thread_info
.resampler
)
1910 nbytes
= pa_resampler_request(i
->thread_info
.resampler
, nbytes
);
1913 /* Remember how much we actually want to rewrite */
1914 if (i
->thread_info
.rewrite_nbytes
!= (size_t) -1) {
1916 /* Make sure to not overwrite over underruns */
1917 if (nbytes
> i
->thread_info
.playing_for
)
1918 nbytes
= (size_t) i
->thread_info
.playing_for
;
1920 i
->thread_info
.rewrite_nbytes
= nbytes
;
1922 i
->thread_info
.rewrite_nbytes
= (size_t) -1;
1925 i
->thread_info
.rewrite_flush
=
1926 i
->thread_info
.rewrite_flush
||
1927 (flush
&& i
->thread_info
.rewrite_nbytes
!= 0);
1929 i
->thread_info
.dont_rewind_render
=
1930 i
->thread_info
.dont_rewind_render
||
1933 if (nbytes
!= (size_t) -1) {
1935 /* Transform to sink domain */
1936 if (i
->thread_info
.resampler
)
1937 nbytes
= pa_resampler_result(i
->thread_info
.resampler
, nbytes
);
1940 pa_sink_request_rewind(i
->sink
, nbytes
- lbq
);
1942 /* This call will make sure process_rewind() is called later */
1943 pa_sink_request_rewind(i
->sink
, 0);
1947 /* Called from main context */
1948 pa_memchunk
* pa_sink_input_get_silence(pa_sink_input
*i
, pa_memchunk
*ret
) {
1949 pa_sink_input_assert_ref(i
);
1950 pa_assert_ctl_context();
1953 /* FIXME: Shouldn't access resampler object from main context! */
1955 pa_silence_memchunk_get(
1956 &i
->core
->silence_cache
,
1960 i
->thread_info
.resampler
? pa_resampler_max_block_size(i
->thread_info
.resampler
) : 0);
1965 /* Called from main context */
1966 void pa_sink_input_send_event(pa_sink_input
*i
, const char *event
, pa_proplist
*data
) {
1967 pa_proplist
*pl
= NULL
;
1968 pa_sink_input_send_event_hook_data hook_data
;
1970 pa_sink_input_assert_ref(i
);
1971 pa_assert_ctl_context();
1978 data
= pl
= pa_proplist_new();
1980 hook_data
.sink_input
= i
;
1981 hook_data
.data
= data
;
1982 hook_data
.event
= event
;
1984 if (pa_hook_fire(&i
->core
->hooks
[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT
], &hook_data
) < 0)
1987 i
->send_event(i
, event
, data
);
1991 pa_proplist_free(pl
);