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>
41 #include <pulse/timeval.h>
43 #include "sink-input.h"
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
48 static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject);
50 static void sink_input_free(pa_object *o);
51 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t);
52 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t);
53 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk);
54 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes);
55 static void sink_input_release_envelope(pa_sink_input *i);
57 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
60 memset(data, 0, sizeof(*data));
61 data->resample_method = PA_RESAMPLER_INVALID;
62 data->proplist = pa_proplist_new();
67 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
70 if ((data->sample_spec_is_set = !!spec))
71 data->sample_spec = *spec;
74 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
77 if ((data->channel_map_is_set = !!map))
78 data->channel_map = *map;
81 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
84 if ((data->volume_is_set = !!volume))
85 data->volume = *volume;
88 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
90 pa_assert(volume_factor);
92 if (data->volume_factor_is_set)
93 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
95 data->volume_factor_is_set = TRUE;
96 data->volume_factor = *volume_factor;
100 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
103 data->muted_is_set = TRUE;
104 data->muted = !!mute;
107 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
110 pa_proplist_free(data->proplist);
113 /* Called from main context */
114 static void reset_callbacks(pa_sink_input *i) {
118 i->process_rewind = NULL;
119 i->update_max_rewind = NULL;
120 i->update_max_request = NULL;
121 i->update_sink_requested_latency = NULL;
122 i->update_sink_latency_range = NULL;
126 i->suspend_within_thread = NULL;
129 i->get_latency = NULL;
130 i->state_change = NULL;
131 i->may_move_to = NULL;
132 i->send_event = NULL;
135 /* Called from main context */
136 int pa_sink_input_new(
139 pa_sink_input_new_data *data,
140 pa_sink_input_flags_t flags) {
143 pa_resampler *resampler = NULL;
144 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
145 pa_channel_map original_cm;
153 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
155 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
158 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
161 data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
162 data->save_sink = FALSE;
165 pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
166 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
167 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);
169 if (!data->sample_spec_is_set)
170 data->sample_spec = data->sink->sample_spec;
172 pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
174 if (!data->channel_map_is_set) {
175 if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
176 data->channel_map = data->sink->channel_map;
178 pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
181 pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
182 pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
184 if (!data->volume_is_set) {
185 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
186 data->volume_is_absolute = FALSE;
187 data->save_volume = FALSE;
190 pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
191 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
193 if (!data->volume_factor_is_set)
194 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
196 pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
197 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
199 if (!data->muted_is_set)
202 if (flags & PA_SINK_INPUT_FIX_FORMAT)
203 data->sample_spec.format = data->sink->sample_spec.format;
205 if (flags & PA_SINK_INPUT_FIX_RATE)
206 data->sample_spec.rate = data->sink->sample_spec.rate;
208 original_cm = data->channel_map;
210 if (flags & PA_SINK_INPUT_FIX_CHANNELS) {
211 data->sample_spec.channels = data->sink->sample_spec.channels;
212 data->channel_map = data->sink->channel_map;
215 pa_assert(pa_sample_spec_valid(&data->sample_spec));
216 pa_assert(pa_channel_map_valid(&data->channel_map));
218 /* Due to the fixing of the sample spec the volume might not match anymore */
219 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
221 if (data->resample_method == PA_RESAMPLER_INVALID)
222 data->resample_method = core->resample_method;
224 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
226 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
229 if ((flags & PA_SINK_INPUT_FAIL_ON_SUSPEND) &&
230 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
231 pa_log_warn("Failed to create sink input: sink is suspended.");
232 return -PA_ERR_BADSTATE;
235 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
236 pa_log_warn("Failed to create sink input: too many inputs per sink.");
237 return -PA_ERR_TOOLARGE;
240 if ((flags & PA_SINK_INPUT_VARIABLE_RATE) ||
241 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
242 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
244 if (!(resampler = pa_resampler_new(
246 &data->sample_spec, &data->channel_map,
247 &data->sink->sample_spec, &data->sink->channel_map,
248 data->resample_method,
249 ((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
250 ((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
251 (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
252 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
253 pa_log_warn("Unsupported resampling operation.");
254 return -PA_ERR_NOTSUPPORTED;
258 i = pa_msgobject_new(pa_sink_input);
259 i->parent.parent.free = sink_input_free;
260 i->parent.process_msg = pa_sink_input_process_msg;
263 i->state = PA_SINK_INPUT_INIT;
265 i->proplist = pa_proplist_copy(data->proplist);
266 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
267 i->module = data->module;
268 i->sink = data->sink;
269 i->client = data->client;
271 i->requested_resample_method = data->resample_method;
272 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
273 i->sample_spec = data->sample_spec;
274 i->channel_map = data->channel_map;
276 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
277 /* When the 'absolute' bool is not set then we'll treat the volume
278 * as relative to the sink volume even in flat volume mode */
280 pa_cvolume v = data->sink->reference_volume;
281 pa_cvolume_remap(&v, &data->sink->channel_map, &data->channel_map);
282 pa_sw_cvolume_multiply(&i->virtual_volume, &data->volume, &v);
284 i->virtual_volume = data->volume;
286 i->volume_factor = data->volume_factor;
287 pa_cvolume_init(&i->soft_volume);
288 memset(i->relative_volume, 0, sizeof(i->relative_volume));
289 i->save_volume = data->save_volume;
290 i->save_sink = data->save_sink;
291 i->save_muted = data->save_muted;
293 i->muted = data->muted;
295 if (data->sync_base) {
296 i->sync_next = data->sync_base->sync_next;
297 i->sync_prev = data->sync_base;
299 if (data->sync_base->sync_next)
300 data->sync_base->sync_next->sync_prev = i;
301 data->sync_base->sync_next = i;
303 i->sync_next = i->sync_prev = NULL;
305 i->direct_outputs = pa_idxset_new(NULL, NULL);
310 /* Set Ramping info */
311 i->thread_info.ramp_info.is_ramping = FALSE;
312 i->thread_info.ramp_info.envelope_dead = TRUE;
313 i->thread_info.ramp_info.envelope = NULL;
314 i->thread_info.ramp_info.item = NULL;
315 i->thread_info.ramp_info.envelope_dying = 0;
317 pa_atomic_store(&i->before_ramping_v, 0);
318 pa_atomic_store(&i->before_ramping_m, 0);
320 i->thread_info.state = i->state;
321 i->thread_info.attached = FALSE;
322 pa_atomic_store(&i->thread_info.drained, 1);
323 i->thread_info.sample_spec = i->sample_spec;
324 i->thread_info.resampler = resampler;
325 i->thread_info.soft_volume = i->soft_volume;
326 i->thread_info.muted = i->muted;
327 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
328 i->thread_info.rewrite_nbytes = 0;
329 i->thread_info.rewrite_flush = FALSE;
330 i->thread_info.dont_rewind_render = FALSE;
331 i->thread_info.underrun_for = (uint64_t) -1;
332 i->thread_info.playing_for = 0;
333 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
335 i->thread_info.render_memblockq = pa_memblockq_new(
339 pa_frame_size(&i->sink->sample_spec),
345 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
346 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
349 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
351 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s",
353 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
355 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
356 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map));
358 /* Don't forget to call pa_sink_input_put! */
364 /* Called from main context */
365 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
371 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
372 pa_assert_se(i->sink->n_corked -- >= 1);
373 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
377 /* Called from main context */
378 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
379 pa_sink_input *ssync;
382 if (state == PA_SINK_INPUT_DRAINED)
383 state = PA_SINK_INPUT_RUNNING;
385 if (i->state == state)
388 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);
390 update_n_corked(i, state);
393 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
394 update_n_corked(ssync, state);
395 ssync->state = state;
397 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
398 update_n_corked(ssync, state);
399 ssync->state = state;
402 if (state != PA_SINK_INPUT_UNLINKED) {
403 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
405 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
406 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
408 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
409 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
412 pa_sink_update_status(i->sink);
415 /* Called from main context */
416 void pa_sink_input_unlink(pa_sink_input *i) {
418 pa_source_output *o, *p = NULL;
421 /* See pa_sink_unlink() for a couple of comments how this function
424 pa_sink_input_ref(i);
426 linked = PA_SINK_INPUT_IS_LINKED(i->state);
429 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
432 i->sync_prev->sync_next = i->sync_next;
434 i->sync_next->sync_prev = i->sync_prev;
436 i->sync_prev = i->sync_next = NULL;
438 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
441 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
442 pa_sink_input_unref(i);
445 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
447 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
449 pa_source_output_kill(o);
453 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
454 i->state = PA_SINK_INPUT_UNLINKED;
456 if (linked && i->sink) {
457 /* We might need to update the sink's volume if we are in flat volume mode. */
458 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
459 pa_cvolume new_volume;
460 pa_sink_update_flat_volume(i->sink, &new_volume);
461 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
464 if (i->sink->asyncmsgq)
465 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
471 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
472 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
476 pa_sink_update_status(i->sink);
480 pa_core_maybe_vacuum(i->core);
482 pa_sink_input_unref(i);
485 /* Called from main context */
486 static void sink_input_free(pa_object *o) {
487 pa_sink_input* i = PA_SINK_INPUT(o);
490 pa_assert(pa_sink_input_refcnt(i) == 0);
492 if (PA_SINK_INPUT_IS_LINKED(i->state))
493 pa_sink_input_unlink(i);
495 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
497 pa_assert(!i->thread_info.attached);
499 if (i->thread_info.ramp_info.envelope) {
500 pa_log_debug ("Freeing envelope\n");
501 pa_envelope_free(i->thread_info.ramp_info.envelope);
502 i->thread_info.ramp_info.envelope = NULL;
505 if (i->thread_info.render_memblockq)
506 pa_memblockq_free(i->thread_info.render_memblockq);
508 if (i->thread_info.resampler)
509 pa_resampler_free(i->thread_info.resampler);
512 pa_proplist_free(i->proplist);
514 if (i->direct_outputs)
515 pa_idxset_free(i->direct_outputs, NULL, NULL);
517 if (i->thread_info.direct_outputs)
518 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
524 /* Called from main context */
525 void pa_sink_input_put(pa_sink_input *i) {
526 pa_sink_input_state_t state;
527 pa_sink_input_assert_ref(i);
529 pa_assert(i->state == PA_SINK_INPUT_INIT);
531 /* The following fields must be initialized properly */
533 pa_assert(i->process_rewind);
536 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
538 update_n_corked(i, state);
541 /* We might need to update the sink's volume if we are in flat volume mode. */
542 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
543 pa_cvolume new_volume;
544 pa_sink_update_flat_volume(i->sink, &new_volume);
545 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
547 pa_sink_input_set_relative_volume(i, &i->virtual_volume);
549 i->thread_info.soft_volume = i->soft_volume;
550 i->thread_info.muted = i->muted;
552 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
554 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
555 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
557 pa_sink_update_status(i->sink);
560 /* Called from main context */
561 void pa_sink_input_kill(pa_sink_input*i) {
562 pa_sink_input_assert_ref(i);
563 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
568 /* Called from main context */
569 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
570 pa_usec_t r[2] = { 0, 0 };
572 pa_sink_input_assert_ref(i);
573 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
575 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
578 r[0] += i->get_latency(i);
581 *sink_latency = r[1];
586 /* Called from thread context */
587 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
588 pa_bool_t do_volume_adj_here;
589 pa_bool_t volume_is_norm;
591 size_t block_size_max_sink, block_size_max_sink_input;
594 pa_sink_input_assert_ref(i);
595 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
596 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
600 /* pa_log_debug("peek"); */
602 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
603 i->thread_info.state == PA_SINK_INPUT_CORKED ||
604 i->thread_info.state == PA_SINK_INPUT_DRAINED);
606 block_size_max_sink_input = i->thread_info.resampler ?
607 pa_resampler_max_block_size(i->thread_info.resampler) :
608 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
610 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
612 /* Default buffer size */
614 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
616 if (slength > block_size_max_sink)
617 slength = block_size_max_sink;
619 if (i->thread_info.resampler) {
620 ilength = pa_resampler_request(i->thread_info.resampler, slength);
623 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
627 if (ilength > block_size_max_sink_input)
628 ilength = block_size_max_sink_input;
630 /* If the channel maps of the sink and this stream differ, we need
631 * to adjust the volume *before* we resample. Otherwise we can do
632 * it after and leave it for the sink code */
634 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map) || i->thread_info.ramp_info.is_ramping;
635 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
637 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
640 /* There's nothing in our render queue. We need to fill it up
641 * with data from the implementor. */
643 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
644 i->pop(i, ilength, &tchunk) < 0) {
646 /* OK, we're corked or the implementor didn't give us any
647 * data, so let's just hand out silence */
648 pa_atomic_store(&i->thread_info.drained, 1);
650 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
651 i->thread_info.playing_for = 0;
652 if (i->thread_info.underrun_for != (uint64_t) -1)
653 i->thread_info.underrun_for += ilength;
657 pa_atomic_store(&i->thread_info.drained, 0);
659 pa_assert(tchunk.length > 0);
660 pa_assert(tchunk.memblock);
662 i->thread_info.underrun_for = 0;
663 i->thread_info.playing_for += tchunk.length;
665 while (tchunk.length > 0) {
669 pa_memblock_ref(wchunk.memblock);
671 if (wchunk.length > block_size_max_sink_input)
672 wchunk.length = block_size_max_sink_input;
674 /* It might be necessary to adjust the volume here */
675 if (do_volume_adj_here && !volume_is_norm && !i->thread_info.ramp_info.is_ramping) {
676 pa_memchunk_make_writable(&wchunk, 0);
678 if (i->thread_info.muted)
679 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
681 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
684 if (!i->thread_info.resampler)
685 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
688 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
690 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
692 if (rchunk.memblock) {
693 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
694 pa_memblock_unref(rchunk.memblock);
698 pa_memblock_unref(wchunk.memblock);
700 tchunk.index += wchunk.length;
701 tchunk.length -= wchunk.length;
704 pa_memblock_unref(tchunk.memblock);
707 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
709 pa_assert(chunk->length > 0);
710 pa_assert(chunk->memblock);
712 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
714 if (chunk->length > block_size_max_sink)
715 chunk->length = block_size_max_sink;
717 ramping = i->thread_info.ramp_info.is_ramping;
719 sink_input_volume_ramping(i, chunk);
721 if (!i->thread_info.ramp_info.envelope_dead) {
722 i->thread_info.ramp_info.envelope_dying += chunk->length;
723 pa_log_debug("Envelope dying is %d, chunk length is %d, dead thresholder is %d\n", i->thread_info.ramp_info.envelope_dying,
725 i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope));
727 if (i->thread_info.ramp_info.envelope_dying >= (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) {
728 pa_log_debug("RELEASE Envelop");
729 i->thread_info.ramp_info.envelope_dead = TRUE;
730 sink_input_release_envelope(i);
734 /* Let's see if we had to apply the volume adjustment ourselves,
735 * or if this can be done by the sink for us */
737 if (do_volume_adj_here)
738 /* We had different channel maps, so we already did the adjustment */
739 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
740 else if (i->thread_info.muted)
741 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
742 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
744 *volume = i->thread_info.soft_volume;
747 /* Called from thread context */
748 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
749 pa_sink_input_assert_ref(i);
751 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
752 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
753 pa_assert(nbytes > 0);
755 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
757 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
760 /* Called from thread context */
761 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
763 pa_bool_t called = FALSE;
764 pa_sink_input_assert_ref(i);
766 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
767 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
769 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
771 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
773 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
774 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
775 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
776 sink_input_rewind_ramp_info(i, nbytes);
779 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
781 /* We were asked to drop all buffered data, and rerequest new
782 * data from implementor the next time push() is called */
784 pa_memblockq_flush_write(i->thread_info.render_memblockq);
786 } else if (i->thread_info.rewrite_nbytes > 0) {
787 size_t max_rewrite, amount;
789 /* Calculate how much make sense to rewrite at most */
790 max_rewrite = nbytes + lbq;
792 /* Transform into local domain */
793 if (i->thread_info.resampler)
794 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
796 /* Calculate how much of the rewinded data should actually be rewritten */
797 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
800 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
802 /* Tell the implementor */
803 if (i->process_rewind)
804 i->process_rewind(i, amount);
807 /* Convert back to to sink domain */
808 if (i->thread_info.resampler)
809 amount = pa_resampler_result(i->thread_info.resampler, amount);
812 /* Ok, now update the write pointer */
813 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
815 if (i->thread_info.rewrite_flush)
816 pa_memblockq_silence(i->thread_info.render_memblockq);
818 /* And reset the resampler */
819 if (i->thread_info.resampler)
820 pa_resampler_reset(i->thread_info.resampler);
825 if (i->process_rewind)
826 i->process_rewind(i, 0);
828 i->thread_info.rewrite_nbytes = 0;
829 i->thread_info.rewrite_flush = FALSE;
830 i->thread_info.dont_rewind_render = FALSE;
833 /* Called from thread context */
834 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
835 pa_sink_input_assert_ref(i);
836 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
837 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
839 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
841 if (i->update_max_rewind)
842 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
845 /* Called from thread context */
846 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
847 pa_sink_input_assert_ref(i);
848 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
849 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
851 if (i->update_max_request)
852 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
855 /* Called from thread context */
856 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
857 pa_sink_input_assert_ref(i);
859 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
860 usec = i->sink->fixed_latency;
862 if (usec != (pa_usec_t) -1)
863 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
865 i->thread_info.requested_sink_latency = usec;
866 pa_sink_invalidate_requested_latency(i->sink);
871 /* Called from main context */
872 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
873 pa_sink_input_assert_ref(i);
875 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
876 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
880 /* If this sink input is not realized yet or we are being moved,
881 * we have to touch the thread info data directly */
884 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
885 usec = i->sink->fixed_latency;
887 if (usec != (pa_usec_t) -1) {
888 pa_usec_t min_latency, max_latency;
889 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
890 usec = PA_CLAMP(usec, min_latency, max_latency);
894 i->thread_info.requested_sink_latency = usec;
899 /* Called from main context */
900 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
901 pa_sink_input_assert_ref(i);
903 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
905 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
909 /* If this sink input is not realized yet or we are being moved,
910 * we have to touch the thread info data directly */
912 return i->thread_info.requested_sink_latency;
915 /* Called from main context */
916 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
917 /* test ramping -> return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 2000 * PA_USEC_PER_MSEC); */
918 return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 0);
921 /* Called from main context */
922 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
923 pa_sink_input_assert_ref(i);
924 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
926 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
927 pa_cvolume v = i->sink->reference_volume;
928 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
929 pa_sw_cvolume_divide(volume, &i->virtual_volume, &v);
931 *volume = i->virtual_volume;
936 /* Called from main context */
937 pa_cvolume *pa_sink_input_get_relative_volume(pa_sink_input *i, pa_cvolume *v) {
940 pa_sink_input_assert_ref(i);
942 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
944 /* This always returns the relative volume. Converts the float
945 * version into a pa_cvolume */
947 v->channels = i->sample_spec.channels;
949 for (c = 0; c < v->channels; c++)
950 v->values[c] = pa_sw_volume_from_linear(i->relative_volume[c]);
955 /* Called from main context */
956 void pa_sink_input_set_relative_volume(pa_sink_input *i, const pa_cvolume *v) {
960 pa_sink_input_assert_ref(i);
961 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
962 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
965 v = pa_cvolume_reset(&_v, i->sample_spec.channels);
967 /* This basically calculates:
969 * i->relative_volume := v
970 * i->soft_volume := i->relative_volume * i->volume_factor */
972 i->soft_volume.channels = i->sample_spec.channels;
974 for (c = 0; c < i->sample_spec.channels; c++) {
975 i->relative_volume[c] = pa_sw_volume_to_linear(v->values[c]);
977 i->soft_volume.values[c] = pa_sw_volume_from_linear(
978 i->relative_volume[c] *
979 pa_sw_volume_to_linear(i->volume_factor.values[c]));
982 /* We don't copy the data to the thread_info data. That's left for someone else to do */
985 /* Called from main context */
986 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
987 /* test ramping -> return pa_sink_input_set_mute_with_ramping(i, mute, save, 2000 * PA_USEC_PER_MSEC); */
988 return pa_sink_input_set_mute_with_ramping(i, mute, save, 0);
991 /* Called from main context */
992 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
993 pa_sink_input_assert_ref(i);
994 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
999 /* Called from main thread */
1000 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1001 pa_sink_input_assert_ref(i);
1004 pa_proplist_update(i->proplist, mode, p);
1006 if (PA_SINK_IS_LINKED(i->state)) {
1007 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1008 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1012 /* Called from main context */
1013 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1014 pa_sink_input_assert_ref(i);
1015 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1017 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1020 /* Called from main context */
1021 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1022 pa_sink_input_assert_ref(i);
1023 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1024 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1026 if (i->sample_spec.rate == rate)
1029 i->sample_spec.rate = rate;
1031 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1033 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1037 /* Called from main context */
1038 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1040 pa_sink_input_assert_ref(i);
1042 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1045 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1047 if (old && name && !strcmp(old, name))
1051 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1053 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1055 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1056 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1057 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1061 /* Called from main context */
1062 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1063 pa_sink_input_assert_ref(i);
1065 return i->actual_resample_method;
1068 /* Called from main context */
1069 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1070 pa_sink_input_assert_ref(i);
1071 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1073 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1076 if (i->sync_next || i->sync_prev) {
1077 pa_log_warn("Moving synchronised streams not supported.");
1084 /* Called from main context */
1085 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1086 pa_sink_input_assert_ref(i);
1087 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1088 pa_sink_assert_ref(dest);
1090 if (dest == i->sink)
1093 if (!pa_sink_input_may_move(i))
1096 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1097 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1102 if (!i->may_move_to(i, dest))
1108 /* Called from main context */
1109 int pa_sink_input_start_move(pa_sink_input *i) {
1110 pa_source_output *o, *p = NULL;
1114 pa_sink_input_assert_ref(i);
1115 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1118 if (!pa_sink_input_may_move(i))
1119 return -PA_ERR_NOTSUPPORTED;
1121 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1126 /* Kill directly connected outputs */
1127 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1129 pa_source_output_kill(o);
1132 pa_assert(pa_idxset_isempty(i->direct_outputs));
1134 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1136 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1137 pa_assert_se(i->sink->n_corked-- >= 1);
1139 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1140 pa_cvolume new_volume;
1142 /* Make the virtual volume relative */
1143 pa_sink_input_get_relative_volume(i, &i->virtual_volume);
1145 /* And reset the the relative volume */
1146 pa_sink_input_set_relative_volume(i, NULL);
1148 /* We might need to update the sink's volume if we are in flat
1150 pa_sink_update_flat_volume(i->sink, &new_volume);
1151 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
1154 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1156 pa_sink_update_status(i->sink);
1159 pa_sink_input_unref(i);
1164 /* Called from main context */
1165 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1166 pa_resampler *new_resampler;
1168 pa_sink_input_assert_ref(i);
1169 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1170 pa_assert(!i->sink);
1171 pa_sink_assert_ref(dest);
1173 if (!pa_sink_input_may_move_to(i, dest))
1174 return -PA_ERR_NOTSUPPORTED;
1176 if (i->thread_info.resampler &&
1177 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1178 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1180 /* Try to reuse the old resampler if possible */
1181 new_resampler = i->thread_info.resampler;
1183 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1184 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1185 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1187 /* Okey, we need a new resampler for the new sink */
1189 if (!(new_resampler = pa_resampler_new(
1191 &i->sample_spec, &i->channel_map,
1192 &dest->sample_spec, &dest->channel_map,
1193 i->requested_resample_method,
1194 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1195 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1196 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1197 pa_log_warn("Unsupported resampling operation.");
1198 return -PA_ERR_NOTSUPPORTED;
1201 new_resampler = NULL;
1207 i->save_sink = save;
1208 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1210 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1211 i->sink->n_corked++;
1213 /* Replace resampler and render queue */
1214 if (new_resampler != i->thread_info.resampler) {
1216 if (i->thread_info.resampler)
1217 pa_resampler_free(i->thread_info.resampler);
1218 i->thread_info.resampler = new_resampler;
1220 pa_memblockq_free(i->thread_info.render_memblockq);
1222 i->thread_info.render_memblockq = pa_memblockq_new(
1224 MEMBLOCKQ_MAXLENGTH,
1226 pa_frame_size(&i->sink->sample_spec),
1232 pa_sink_update_status(dest);
1234 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1235 pa_cvolume new_volume;
1237 /* Make relative volume absolute again */
1238 pa_cvolume t = dest->reference_volume;
1239 pa_cvolume_remap(&t, &dest->channel_map, &i->channel_map);
1240 pa_sw_cvolume_multiply(&i->virtual_volume, &i->virtual_volume, &t);
1242 /* We might need to update the sink's volume if we are in flat volume mode. */
1243 pa_sink_update_flat_volume(i->sink, &new_volume);
1244 pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE, FALSE, FALSE);
1247 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1249 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1251 /* Notify everyone */
1252 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1253 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1258 /* Called from main context */
1259 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1262 pa_sink_input_assert_ref(i);
1263 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1265 pa_sink_assert_ref(dest);
1267 if (dest == i->sink)
1270 if (!pa_sink_input_may_move_to(i, dest))
1271 return -PA_ERR_NOTSUPPORTED;
1273 pa_sink_input_ref(i);
1275 if ((r = pa_sink_input_start_move(i)) < 0) {
1276 pa_sink_input_unref(i);
1280 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1281 pa_sink_input_unref(i);
1285 pa_sink_input_unref(i);
1290 /* Called from IO thread context */
1291 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1292 pa_bool_t corking, uncorking;
1293 pa_sink_input_assert_ref(i);
1295 if (state == i->thread_info.state)
1298 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1299 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1300 pa_atomic_store(&i->thread_info.drained, 1);
1302 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1303 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1305 if (i->state_change)
1306 i->state_change(i, state);
1308 i->thread_info.state = state;
1312 pa_log_debug("Requesting rewind due to corking");
1314 /* This will tell the implementing sink input driver to rewind
1315 * so that the unplayed already mixed data is not lost */
1316 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1318 } else if (uncorking) {
1320 i->thread_info.underrun_for = (uint64_t) -1;
1321 i->thread_info.playing_for = 0;
1323 pa_log_debug("Requesting rewind due to uncorking");
1325 /* OK, we're being uncorked. Make sure we're not rewound when
1326 * the hw buffer is remixed and request a remix. */
1327 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1331 /* Called from thread context, except when it is not. */
1332 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1333 pa_sink_input *i = PA_SINK_INPUT(o);
1334 pa_sink_input_assert_ref(i);
1338 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1339 if (pa_atomic_load(&i->before_ramping_v))
1340 i->thread_info.future_soft_volume = i->soft_volume;
1342 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1343 if (!pa_atomic_load(&i->before_ramping_v))
1344 i->thread_info.soft_volume = i->soft_volume;
1345 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1349 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1350 if (pa_atomic_load(&i->before_ramping_m))
1351 i->thread_info.future_muted = i->muted;
1353 if (i->thread_info.muted != i->muted) {
1354 if (!pa_atomic_load(&i->before_ramping_m))
1355 i->thread_info.muted = i->muted;
1356 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1360 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1361 pa_usec_t *r = userdata;
1363 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1364 r[1] += pa_sink_get_latency_within_thread(i->sink);
1369 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1371 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1372 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1376 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1377 pa_sink_input *ssync;
1379 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1381 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1382 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1384 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1385 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1390 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1391 pa_usec_t *usec = userdata;
1393 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1397 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1398 pa_usec_t *r = userdata;
1400 *r = i->thread_info.requested_sink_latency;
1404 case PA_SINK_INPUT_MESSAGE_SET_ENVELOPE: {
1405 if (!i->thread_info.ramp_info.envelope)
1406 i->thread_info.ramp_info.envelope = pa_envelope_new(&i->sink->sample_spec);
1408 if (i->thread_info.ramp_info.envelope && i->thread_info.ramp_info.item) {
1409 pa_envelope_remove(i->thread_info.ramp_info.envelope, i->thread_info.ramp_info.item);
1410 i->thread_info.ramp_info.item = NULL;
1413 i->thread_info.ramp_info.item = pa_envelope_add(i->thread_info.ramp_info.envelope, &i->using_def);
1414 i->thread_info.ramp_info.is_ramping = TRUE;
1415 i->thread_info.ramp_info.envelope_dead = FALSE;
1416 i->thread_info.ramp_info.envelope_dying = 0;
1418 if (i->thread_info.ramp_info.envelope)
1419 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1425 return -PA_ERR_NOTIMPLEMENTED;
1428 /* Called from main thread */
1429 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1430 pa_sink_input_assert_ref(i);
1432 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1433 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1438 /* Called from IO context */
1439 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1440 pa_sink_input_assert_ref(i);
1442 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1443 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1448 /* Called from IO context */
1449 void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sample spec */, pa_bool_t rewrite, pa_bool_t flush, pa_bool_t dont_rewind_render) {
1452 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1453 * and possible and the exact value of this is passed back the
1454 * implementor via process_rewind(). If 'flush' is also TRUE all
1455 * already rendered data is also dropped.
1457 * If 'rewrite' is FALSE the sink is rewound as far as requested
1458 * and possible and the already rendered data is dropped so that
1459 * in the next iteration we read new data from the
1460 * implementor. This implies 'flush' is TRUE. If
1461 * dont_rewind_render is TRUE then the render memblockq is not
1464 pa_sink_input_assert_ref(i);
1466 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1468 /* pa_log_debug("request rewrite %lu", (unsigned long) nbytes); */
1470 /* We don't take rewind requests while we are corked */
1471 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1474 pa_assert(rewrite || flush);
1475 pa_assert(!dont_rewind_render || !rewrite);
1477 /* Calculate how much we can rewind locally without having to
1480 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1484 /* Check if rewinding for the maximum is requested, and if so, fix up */
1487 /* Calculate maximum number of bytes that could be rewound in theory */
1488 nbytes = i->sink->thread_info.max_rewind + lbq;
1490 /* Transform from sink domain */
1491 if (i->thread_info.resampler)
1492 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1495 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1497 /* Make sure to not overwrite over underruns */
1498 if (nbytes > i->thread_info.playing_for)
1499 nbytes = (size_t) i->thread_info.playing_for;
1501 i->thread_info.rewrite_nbytes = nbytes;
1503 i->thread_info.rewrite_nbytes = (size_t) -1;
1506 i->thread_info.rewrite_flush =
1507 i->thread_info.rewrite_flush ||
1508 (flush && i->thread_info.rewrite_nbytes != 0);
1510 i->thread_info.dont_rewind_render =
1511 i->thread_info.dont_rewind_render ||
1514 if (nbytes != (size_t) -1) {
1516 /* Transform to sink domain */
1517 if (i->thread_info.resampler)
1518 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1521 pa_sink_request_rewind(i->sink, nbytes - lbq);
1523 /* This call will make sure process_rewind() is called later */
1524 pa_sink_request_rewind(i->sink, 0);
1528 /* Called from main context */
1529 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1530 pa_sink_input_assert_ref(i);
1533 pa_silence_memchunk_get(
1534 &i->core->silence_cache,
1538 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1543 /* Called from main context */
1544 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1545 pa_proplist *pl = NULL;
1546 pa_sink_input_send_event_hook_data hook_data;
1548 pa_sink_input_assert_ref(i);
1555 data = pl = pa_proplist_new();
1557 hook_data.sink_input = i;
1558 hook_data.data = data;
1559 hook_data.event = event;
1561 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1564 i->send_event(i, event, data);
1568 pa_proplist_free(pl);
1571 /* Called from IO context */
1572 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk) {
1575 pa_assert(chunk->memblock);
1576 pa_assert(i->thread_info.ramp_info.is_ramping);
1578 /* Volume is adjusted with ramping effect here */
1579 pa_envelope_apply(i->thread_info.ramp_info.envelope, chunk);
1581 if (pa_envelope_is_finished(i->thread_info.ramp_info.envelope)) {
1582 i->thread_info.ramp_info.is_ramping = FALSE;
1583 if (pa_atomic_load(&i->before_ramping_v)) {
1584 i->thread_info.soft_volume = i->thread_info.future_soft_volume;
1585 pa_atomic_store(&i->before_ramping_v, 0);
1587 else if (pa_atomic_load(&i->before_ramping_m)) {
1588 i->thread_info.muted = i->thread_info.future_muted;
1589 pa_atomic_store(&i->before_ramping_m, 0);
1595 * Called from main context
1596 * This function should be called inside pa_sink_input_set_volume_with_ramping
1597 * should be called after soft_volume of sink_input and sink are all adjusted
1599 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t) {
1601 int32_t target_abs_vol, target_apply_vol, pre_apply_vol;
1604 pa_log_debug("Sink input's soft volume is %d= %f ", pa_cvolume_avg(&i->soft_volume), pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)));
1606 /* Calculation formula are target_abs_vol := i->soft_volume
1607 * target_apply_vol := lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000)
1608 * pre_apply_vol := ( previous_virtual_volume / target_virtual_volume ) * target_apply_vol
1610 * Will do volume adjustment inside pa_sink_input_peek
1612 target_abs_vol = pa_cvolume_avg(&i->soft_volume);
1613 target_apply_vol = (int32_t) lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000);
1614 pre_apply_vol = (int32_t) ((pa_sw_volume_to_linear(pre_virtual_volume) / pa_sw_volume_to_linear(target_virtual_volume)) * target_apply_vol);
1616 i->using_def.n_points = 2;
1617 i->using_def.points_x[0] = 0;
1618 i->using_def.points_x[1] = t;
1619 i->using_def.points_y.i[0] = pre_apply_vol;
1620 i->using_def.points_y.i[1] = target_apply_vol;
1621 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1622 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1624 pa_log_debug("Volume Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1625 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1627 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1630 /* Called from main context */
1631 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t) {
1636 i->using_def.n_points = 2;
1637 i->using_def.points_x[0] = 0;
1638 i->using_def.points_x[1] = t;
1639 cur_vol = (int32_t) lrint( pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)) * 0x10000);
1642 i->using_def.points_y.i[0] = cur_vol;
1643 i->using_def.points_y.i[1] = 0;
1645 i->using_def.points_y.i[0] = 0;
1646 i->using_def.points_y.i[1] = cur_vol;
1649 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1650 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1652 pa_log_debug("Mute Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1653 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1655 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1658 /* Called from IO context */
1659 static void sink_input_release_envelope(pa_sink_input *i) {
1661 pa_assert(!i->thread_info.ramp_info.is_ramping);
1662 pa_assert(i->thread_info.ramp_info.envelope_dead);
1664 pa_envelope_free(i->thread_info.ramp_info.envelope);
1665 i->thread_info.ramp_info.envelope = NULL;
1666 i->thread_info.ramp_info.item = NULL;
1669 /* Called from IO context */
1670 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) {
1673 if (!i->thread_info.ramp_info.envelope_dead) {
1674 pa_assert(i->thread_info.ramp_info.envelope);
1676 int32_t envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope);
1678 if (i->thread_info.ramp_info.envelope_dying > envelope_length) {
1679 if ((i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) {
1680 pa_log_debug("Envelope Become Alive");
1681 pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes));
1682 i->thread_info.ramp_info.is_ramping = TRUE;
1684 } else if (i->thread_info.ramp_info.envelope_dying < envelope_length) {
1685 if ((i->thread_info.ramp_info.envelope_dying - nbytes) <= 0) {
1686 pa_log_debug("Envelope Restart");
1687 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1690 pa_log_debug("Envelope Simple Rewind");
1691 pa_envelope_rewind(i->thread_info.ramp_info.envelope, nbytes);
1695 i->thread_info.ramp_info.envelope_dying -= nbytes;
1696 if (i->thread_info.ramp_info.envelope_dying <= 0)
1697 i->thread_info.ramp_info.envelope_dying = 0;
1701 void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t t){
1703 pa_volume_t previous_virtual_volume, target_virtual_volume;
1704 pa_sink_input_assert_ref(i);
1706 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1708 pa_assert(pa_cvolume_valid(volume));
1709 pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
1711 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
1712 v = i->sink->reference_volume;
1713 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1714 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1717 if (pa_cvolume_equal(volume, &i->virtual_volume))
1720 previous_virtual_volume = pa_cvolume_avg(&i->virtual_volume);
1721 target_virtual_volume = pa_cvolume_avg(volume);
1722 if (t > 0 && target_virtual_volume > 0)
1723 pa_log_debug("SetVolumeWithRamping: Virtual Volume From %u=%f to %u=%f\n", previous_virtual_volume, pa_sw_volume_to_linear(previous_virtual_volume),
1724 target_virtual_volume, pa_sw_volume_to_linear(target_virtual_volume));
1726 i->virtual_volume = *volume;
1727 i->save_volume = save;
1729 /* Set this flag before the following code modify i->thread_info.soft_volume */
1730 if (t > 0 && target_virtual_volume > 0)
1731 pa_atomic_store(&i->before_ramping_v, 1);
1733 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1734 pa_cvolume new_volume;
1736 /* We are in flat volume mode, so let's update all sink input
1737 * volumes and update the flat volume of the sink */
1739 pa_sink_update_flat_volume(i->sink, &new_volume);
1740 pa_sink_set_volume(i->sink, &new_volume, FALSE, TRUE, FALSE, FALSE);
1744 /* OK, we are in normal volume mode. The volume only affects
1746 pa_sink_input_set_relative_volume(i, volume);
1748 /* Hooks have the ability to play games with i->soft_volume */
1749 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
1751 /* Copy the new soft_volume to the thread_info struct */
1752 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1755 if (t > 0 && target_virtual_volume > 0)
1756 sink_input_set_ramping_info(i, previous_virtual_volume, target_virtual_volume, t);
1758 /* The virtual volume changed, let's tell people so */
1759 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1762 void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){
1765 pa_sink_input_assert_ref(i);
1766 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1768 if (!i->muted == !mute)
1772 i->save_muted = save;
1773 /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */
1775 pa_atomic_store(&i->before_ramping_m, 1);
1777 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1780 sink_input_set_ramping_info_for_mute(i, mute, t);
1782 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);