]> code.delx.au - pulseaudio/blob - src/pulsecore/sink-input.c
core: Link virtual sinks and sources to their streams.
[pulseaudio] / src / pulsecore / sink-input.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
34
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>
42
43 #include "sink-input.h"
44
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
47
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
49
50 static void sink_input_free(pa_object *o);
51 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
52 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);
53 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t);
54 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk);
55 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes);
56 static void sink_input_release_envelope(pa_sink_input *i);
57
58 static int check_passthrough_connection(pa_sink_input_flags_t flags, pa_sink *dest) {
59
60 if (dest->flags & PA_SINK_PASSTHROUGH) {
61
62 if (pa_idxset_size(dest->inputs) > 0) {
63
64 pa_sink_input *alt_i;
65 uint32_t idx;
66
67 alt_i = pa_idxset_first(dest->inputs, &idx);
68
69 /* only need to check the first input is not PASSTHROUGH */
70 if (alt_i->flags & PA_SINK_INPUT_PASSTHROUGH) {
71 pa_log_warn("Sink is already connected to PASSTHROUGH input");
72 return -PA_ERR_BUSY;
73 }
74
75 /* Current inputs are PCM, check new input is not PASSTHROUGH */
76 if (flags & PA_SINK_INPUT_PASSTHROUGH) {
77 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
78 return -PA_ERR_BUSY;
79 }
80 }
81
82 } else {
83 if (flags & PA_SINK_INPUT_PASSTHROUGH) {
84 pa_log_warn("Cannot connect PASSTHROUGH sink input to sink without PASSTHROUGH capabilities");
85 return -PA_ERR_INVALID;
86 }
87 }
88 return PA_OK;
89 }
90
91 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
92 pa_assert(data);
93
94 pa_zero(*data);
95 data->resample_method = PA_RESAMPLER_INVALID;
96 data->proplist = pa_proplist_new();
97
98 return data;
99 }
100
101 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
102 pa_assert(data);
103
104 if ((data->sample_spec_is_set = !!spec))
105 data->sample_spec = *spec;
106 }
107
108 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
109 pa_assert(data);
110
111 if ((data->channel_map_is_set = !!map))
112 data->channel_map = *map;
113 }
114
115 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
116 pa_assert(data);
117
118 if ((data->volume_is_set = !!volume))
119 data->volume = *volume;
120 }
121
122 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
123 pa_assert(data);
124 pa_assert(volume_factor);
125
126 if (data->volume_factor_is_set)
127 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
128 else {
129 data->volume_factor_is_set = TRUE;
130 data->volume_factor = *volume_factor;
131 }
132 }
133
134 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
135 pa_assert(data);
136 pa_assert(volume_factor);
137
138 if (data->volume_factor_sink_is_set)
139 pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
140 else {
141 data->volume_factor_sink_is_set = TRUE;
142 data->volume_factor_sink = *volume_factor;
143 }
144 }
145
146 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
147 pa_assert(data);
148
149 data->muted_is_set = TRUE;
150 data->muted = !!mute;
151 }
152
153 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
154 pa_assert(data);
155
156 pa_proplist_free(data->proplist);
157 }
158
159 /* Called from main context */
160 static void reset_callbacks(pa_sink_input *i) {
161 pa_assert(i);
162
163 i->pop = NULL;
164 i->process_rewind = NULL;
165 i->update_max_rewind = NULL;
166 i->update_max_request = NULL;
167 i->update_sink_requested_latency = NULL;
168 i->update_sink_latency_range = NULL;
169 i->update_sink_fixed_latency = NULL;
170 i->attach = NULL;
171 i->detach = NULL;
172 i->suspend = NULL;
173 i->suspend_within_thread = NULL;
174 i->moving = NULL;
175 i->kill = NULL;
176 i->get_latency = NULL;
177 i->state_change = NULL;
178 i->may_move_to = NULL;
179 i->send_event = NULL;
180 i->volume_changed = NULL;
181 i->mute_changed = NULL;
182 }
183
184 /* Called from main context */
185 int pa_sink_input_new(
186 pa_sink_input **_i,
187 pa_core *core,
188 pa_sink_input_new_data *data) {
189
190 pa_sink_input *i;
191 pa_resampler *resampler = NULL;
192 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
193 pa_channel_map original_cm;
194 int r;
195 char *pt;
196
197 pa_assert(_i);
198 pa_assert(core);
199 pa_assert(data);
200 pa_assert_ctl_context();
201
202 if (data->client)
203 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
204
205 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
206 return r;
207
208 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
209
210 if (!data->sink) {
211 data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
212 data->save_sink = FALSE;
213 }
214
215 pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
216 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
217 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);
218
219 r = check_passthrough_connection(data->flags, data->sink);
220 pa_return_val_if_fail(r == PA_OK, r);
221
222 if (!data->sample_spec_is_set)
223 data->sample_spec = data->sink->sample_spec;
224
225 pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
226
227 if (!data->channel_map_is_set) {
228 if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
229 data->channel_map = data->sink->channel_map;
230 else
231 pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
232 }
233
234 pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
235
236 if (!data->volume_is_set) {
237 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
238 data->volume_is_absolute = FALSE;
239 data->save_volume = FALSE;
240 }
241
242 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
243
244 if (!data->volume_factor_is_set)
245 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
246
247 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
248
249 if (!data->volume_factor_sink_is_set)
250 pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
251
252 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
253
254 if (!data->muted_is_set)
255 data->muted = FALSE;
256
257 if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
258 data->sample_spec.format = data->sink->sample_spec.format;
259
260 if (data->flags & PA_SINK_INPUT_FIX_RATE)
261 data->sample_spec.rate = data->sink->sample_spec.rate;
262
263 original_cm = data->channel_map;
264
265 if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
266 data->sample_spec.channels = data->sink->sample_spec.channels;
267 data->channel_map = data->sink->channel_map;
268 }
269
270 pa_assert(pa_sample_spec_valid(&data->sample_spec));
271 pa_assert(pa_channel_map_valid(&data->channel_map));
272
273 /* Due to the fixing of the sample spec the volume might not match anymore */
274 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
275
276 if (data->resample_method == PA_RESAMPLER_INVALID)
277 data->resample_method = core->resample_method;
278
279 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
280
281 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
282 return r;
283
284 if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
285 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
286 pa_log_warn("Failed to create sink input: sink is suspended.");
287 return -PA_ERR_BADSTATE;
288 }
289
290 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
291 pa_log_warn("Failed to create sink input: too many inputs per sink.");
292 return -PA_ERR_TOOLARGE;
293 }
294
295 if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
296 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
297 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
298
299 if (!(resampler = pa_resampler_new(
300 core->mempool,
301 &data->sample_spec, &data->channel_map,
302 &data->sink->sample_spec, &data->sink->channel_map,
303 data->resample_method,
304 ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
305 ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
306 (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
307 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
308 pa_log_warn("Unsupported resampling operation.");
309 return -PA_ERR_NOTSUPPORTED;
310 }
311 }
312
313 i = pa_msgobject_new(pa_sink_input);
314 i->parent.parent.free = sink_input_free;
315 i->parent.process_msg = pa_sink_input_process_msg;
316
317 i->core = core;
318 i->state = PA_SINK_INPUT_INIT;
319 i->flags = data->flags;
320 i->proplist = pa_proplist_copy(data->proplist);
321 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
322 i->module = data->module;
323 i->sink = data->sink;
324 i->origin_sink = data->origin_sink;
325 i->client = data->client;
326
327 i->requested_resample_method = data->resample_method;
328 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
329 i->sample_spec = data->sample_spec;
330 i->channel_map = data->channel_map;
331
332 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
333 pa_cvolume remapped;
334
335 /* When the 'absolute' bool is not set then we'll treat the volume
336 * as relative to the sink volume even in flat volume mode */
337 remapped = data->sink->reference_volume;
338 pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
339 pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
340 } else
341 i->volume = data->volume;
342
343 i->volume_factor = data->volume_factor;
344 i->volume_factor_sink = data->volume_factor_sink;
345 i->real_ratio = i->reference_ratio = data->volume;
346 pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
347 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
348 i->save_volume = data->save_volume;
349 i->save_sink = data->save_sink;
350 i->save_muted = data->save_muted;
351
352 i->muted = data->muted;
353
354 if (data->sync_base) {
355 i->sync_next = data->sync_base->sync_next;
356 i->sync_prev = data->sync_base;
357
358 if (data->sync_base->sync_next)
359 data->sync_base->sync_next->sync_prev = i;
360 data->sync_base->sync_next = i;
361 } else
362 i->sync_next = i->sync_prev = NULL;
363
364 i->direct_outputs = pa_idxset_new(NULL, NULL);
365
366 reset_callbacks(i);
367 i->userdata = NULL;
368
369 /* Set Ramping info */
370 i->thread_info.ramp_info.is_ramping = FALSE;
371 i->thread_info.ramp_info.envelope_dead = TRUE;
372 i->thread_info.ramp_info.envelope = NULL;
373 i->thread_info.ramp_info.item = NULL;
374 i->thread_info.ramp_info.envelope_dying = 0;
375
376 pa_atomic_store(&i->before_ramping_v, 0);
377 pa_atomic_store(&i->before_ramping_m, 0);
378
379 i->thread_info.state = i->state;
380 i->thread_info.attached = FALSE;
381 pa_atomic_store(&i->thread_info.drained, 1);
382 i->thread_info.sample_spec = i->sample_spec;
383 i->thread_info.resampler = resampler;
384 i->thread_info.soft_volume = i->soft_volume;
385 i->thread_info.muted = i->muted;
386 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
387 i->thread_info.rewrite_nbytes = 0;
388 i->thread_info.rewrite_flush = FALSE;
389 i->thread_info.dont_rewind_render = FALSE;
390 i->thread_info.underrun_for = (uint64_t) -1;
391 i->thread_info.playing_for = 0;
392 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
393
394 i->thread_info.render_memblockq = pa_memblockq_new(
395 0,
396 MEMBLOCKQ_MAXLENGTH,
397 0,
398 pa_frame_size(&i->sink->sample_spec),
399 0,
400 1,
401 0,
402 &i->sink->silence);
403
404 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
405 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
406
407 if (i->client)
408 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
409
410 pt = pa_proplist_to_string_sep(i->proplist, "\n ");
411 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
412 i->index,
413 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
414 i->sink->name,
415 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
416 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
417 pt);
418 pa_xfree(pt);
419
420 /* Don't forget to call pa_sink_input_put! */
421
422 *_i = i;
423 return 0;
424 }
425
426 /* Called from main context */
427 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
428 pa_assert(i);
429 pa_assert_ctl_context();
430
431 if (!i->sink)
432 return;
433
434 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
435 pa_assert_se(i->sink->n_corked -- >= 1);
436 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
437 i->sink->n_corked++;
438 }
439
440 /* Called from main context */
441 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
442 pa_sink_input *ssync;
443 pa_assert(i);
444 pa_assert_ctl_context();
445
446 if (state == PA_SINK_INPUT_DRAINED)
447 state = PA_SINK_INPUT_RUNNING;
448
449 if (i->state == state)
450 return;
451
452 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);
453
454 update_n_corked(i, state);
455 i->state = state;
456
457 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
458 update_n_corked(ssync, state);
459 ssync->state = state;
460 }
461 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
462 update_n_corked(ssync, state);
463 ssync->state = state;
464 }
465
466 if (state != PA_SINK_INPUT_UNLINKED) {
467 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
468
469 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
470 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
471
472 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
473 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
474
475 if (PA_SINK_INPUT_IS_LINKED(state))
476 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
477 }
478
479 pa_sink_update_status(i->sink);
480 }
481
482 /* Called from main context */
483 void pa_sink_input_unlink(pa_sink_input *i) {
484 pa_bool_t linked;
485 pa_source_output *o, *p = NULL;
486
487 pa_assert(i);
488 pa_assert_ctl_context();
489
490 /* See pa_sink_unlink() for a couple of comments how this function
491 * works */
492
493 pa_sink_input_ref(i);
494
495 linked = PA_SINK_INPUT_IS_LINKED(i->state);
496
497 if (linked)
498 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
499
500 if (i->sync_prev)
501 i->sync_prev->sync_next = i->sync_next;
502 if (i->sync_next)
503 i->sync_next->sync_prev = i->sync_prev;
504
505 i->sync_prev = i->sync_next = NULL;
506
507 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
508
509 if (i->sink)
510 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
511 pa_sink_input_unref(i);
512
513 if (i->client)
514 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
515
516 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
517 pa_assert(o != p);
518 pa_source_output_kill(o);
519 p = o;
520 }
521
522 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
523 i->state = PA_SINK_INPUT_UNLINKED;
524
525 if (linked && i->sink) {
526 /* We might need to update the sink's volume if we are in flat volume mode. */
527 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
528 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
529
530 if (i->sink->asyncmsgq)
531 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
532 }
533
534 reset_callbacks(i);
535
536 if (linked) {
537 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
538 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
539 }
540
541 if (i->sink) {
542 pa_sink_update_status(i->sink);
543 i->sink = NULL;
544 }
545
546 pa_core_maybe_vacuum(i->core);
547
548 pa_sink_input_unref(i);
549 }
550
551 /* Called from main context */
552 static void sink_input_free(pa_object *o) {
553 pa_sink_input* i = PA_SINK_INPUT(o);
554
555 pa_assert(i);
556 pa_assert_ctl_context();
557 pa_assert(pa_sink_input_refcnt(i) == 0);
558
559 if (PA_SINK_INPUT_IS_LINKED(i->state))
560 pa_sink_input_unlink(i);
561
562 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
563
564 /* Side note: this function must be able to destruct properly any
565 * kind of sink input in any state, even those which are
566 * "half-moved" or are connected to sinks that have no asyncmsgq
567 * and are hence half-destructed themselves! */
568
569 if (i->thread_info.ramp_info.envelope) {
570 pa_log_debug ("Freeing envelope\n");
571 pa_envelope_free(i->thread_info.ramp_info.envelope);
572 i->thread_info.ramp_info.envelope = NULL;
573 }
574
575 if (i->thread_info.render_memblockq)
576 pa_memblockq_free(i->thread_info.render_memblockq);
577
578 if (i->thread_info.resampler)
579 pa_resampler_free(i->thread_info.resampler);
580
581 if (i->proplist)
582 pa_proplist_free(i->proplist);
583
584 if (i->direct_outputs)
585 pa_idxset_free(i->direct_outputs, NULL, NULL);
586
587 if (i->thread_info.direct_outputs)
588 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
589
590 pa_xfree(i->driver);
591 pa_xfree(i);
592 }
593
594 /* Called from main context */
595 void pa_sink_input_put(pa_sink_input *i) {
596 pa_sink_input_state_t state;
597
598 pa_sink_input_assert_ref(i);
599 pa_assert_ctl_context();
600
601 pa_assert(i->state == PA_SINK_INPUT_INIT);
602
603 /* The following fields must be initialized properly */
604 pa_assert(i->pop);
605 pa_assert(i->process_rewind);
606 pa_assert(i->kill);
607
608 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
609
610 update_n_corked(i, state);
611 i->state = state;
612
613 /* We might need to update the sink's volume if we are in flat volume mode. */
614 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
615 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
616 else
617 set_real_ratio(i, &i->volume);
618
619 i->thread_info.soft_volume = i->soft_volume;
620 i->thread_info.muted = i->muted;
621
622 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
623
624 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
625 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
626
627 pa_sink_update_status(i->sink);
628 }
629
630 /* Called from main context */
631 void pa_sink_input_kill(pa_sink_input*i) {
632 pa_sink_input_assert_ref(i);
633 pa_assert_ctl_context();
634 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
635
636 i->kill(i);
637 }
638
639 /* Called from main context */
640 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
641 pa_usec_t r[2] = { 0, 0 };
642
643 pa_sink_input_assert_ref(i);
644 pa_assert_ctl_context();
645 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
646
647 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
648
649 if (i->get_latency)
650 r[0] += i->get_latency(i);
651
652 if (sink_latency)
653 *sink_latency = r[1];
654
655 return r[0];
656 }
657
658 /* Called from thread context */
659 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
660 pa_bool_t do_volume_adj_here, need_volume_factor_sink;
661 pa_bool_t volume_is_norm;
662 pa_bool_t ramping;
663 size_t block_size_max_sink, block_size_max_sink_input;
664 size_t ilength;
665
666 pa_sink_input_assert_ref(i);
667 pa_sink_input_assert_io_context(i);
668 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
669 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
670 pa_assert(chunk);
671 pa_assert(volume);
672
673 /* pa_log_debug("peek"); */
674
675 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
676 i->thread_info.state == PA_SINK_INPUT_CORKED ||
677 i->thread_info.state == PA_SINK_INPUT_DRAINED);
678
679 block_size_max_sink_input = i->thread_info.resampler ?
680 pa_resampler_max_block_size(i->thread_info.resampler) :
681 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
682
683 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
684
685 /* Default buffer size */
686 if (slength <= 0)
687 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
688
689 if (slength > block_size_max_sink)
690 slength = block_size_max_sink;
691
692 if (i->thread_info.resampler) {
693 ilength = pa_resampler_request(i->thread_info.resampler, slength);
694
695 if (ilength <= 0)
696 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
697 } else
698 ilength = slength;
699
700 if (ilength > block_size_max_sink_input)
701 ilength = block_size_max_sink_input;
702
703 /* If the channel maps of the sink and this stream differ, we need
704 * to adjust the volume *before* we resample. Otherwise we can do
705 * it after and leave it for the sink code */
706
707 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map) || i->thread_info.ramp_info.is_ramping;
708 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
709 need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
710
711 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
712 pa_memchunk tchunk;
713
714 /* There's nothing in our render queue. We need to fill it up
715 * with data from the implementor. */
716
717 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
718 i->pop(i, ilength, &tchunk) < 0) {
719
720 /* OK, we're corked or the implementor didn't give us any
721 * data, so let's just hand out silence */
722 pa_atomic_store(&i->thread_info.drained, 1);
723
724 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
725 i->thread_info.playing_for = 0;
726 if (i->thread_info.underrun_for != (uint64_t) -1)
727 i->thread_info.underrun_for += ilength;
728 break;
729 }
730
731 pa_atomic_store(&i->thread_info.drained, 0);
732
733 pa_assert(tchunk.length > 0);
734 pa_assert(tchunk.memblock);
735
736 i->thread_info.underrun_for = 0;
737 i->thread_info.playing_for += tchunk.length;
738
739 while (tchunk.length > 0) {
740 pa_memchunk wchunk;
741 pa_bool_t nvfs = need_volume_factor_sink;
742
743 wchunk = tchunk;
744 pa_memblock_ref(wchunk.memblock);
745
746 if (wchunk.length > block_size_max_sink_input)
747 wchunk.length = block_size_max_sink_input;
748
749 /* It might be necessary to adjust the volume here */
750 if (do_volume_adj_here && !volume_is_norm && !i->thread_info.ramp_info.is_ramping) {
751 pa_memchunk_make_writable(&wchunk, 0);
752
753 if (i->thread_info.muted) {
754 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
755 nvfs = FALSE;
756
757 } else if (!i->thread_info.resampler && nvfs) {
758 pa_cvolume v;
759
760 /* If we don't need a resampler we can merge the
761 * post and the pre volume adjustment into one */
762
763 pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
764 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
765 nvfs = FALSE;
766
767 } else
768 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
769 }
770
771 if (!i->thread_info.resampler) {
772
773 if (nvfs) {
774 pa_memchunk_make_writable(&wchunk, 0);
775 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
776 }
777
778 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
779 } else {
780 pa_memchunk rchunk;
781 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
782
783 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
784
785 if (rchunk.memblock) {
786
787 if (nvfs) {
788 pa_memchunk_make_writable(&rchunk, 0);
789 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
790 }
791
792 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
793 pa_memblock_unref(rchunk.memblock);
794 }
795 }
796
797 pa_memblock_unref(wchunk.memblock);
798
799 tchunk.index += wchunk.length;
800 tchunk.length -= wchunk.length;
801 }
802
803 pa_memblock_unref(tchunk.memblock);
804 }
805
806 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
807
808 pa_assert(chunk->length > 0);
809 pa_assert(chunk->memblock);
810
811 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
812
813 if (chunk->length > block_size_max_sink)
814 chunk->length = block_size_max_sink;
815
816 ramping = i->thread_info.ramp_info.is_ramping;
817 if (ramping)
818 sink_input_volume_ramping(i, chunk);
819
820 if (!i->thread_info.ramp_info.envelope_dead) {
821 i->thread_info.ramp_info.envelope_dying += chunk->length;
822 pa_log_debug("Envelope dying is %d, chunk length is %zu, dead thresholder is %lu\n", i->thread_info.ramp_info.envelope_dying,
823 chunk->length,
824 i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope));
825
826 if (i->thread_info.ramp_info.envelope_dying >= (int32_t) (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) {
827 pa_log_debug("RELEASE Envelop");
828 i->thread_info.ramp_info.envelope_dead = TRUE;
829 sink_input_release_envelope(i);
830 }
831 }
832
833 /* Let's see if we had to apply the volume adjustment ourselves,
834 * or if this can be done by the sink for us */
835
836 if (do_volume_adj_here)
837 /* We had different channel maps, so we already did the adjustment */
838 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
839 else if (i->thread_info.muted)
840 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
841 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
842 else
843 *volume = i->thread_info.soft_volume;
844 }
845
846 /* Called from thread context */
847 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
848
849 pa_sink_input_assert_ref(i);
850 pa_sink_input_assert_io_context(i);
851 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
852 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
853 pa_assert(nbytes > 0);
854
855 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
856
857 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
858 }
859
860 /* Called from thread context */
861 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
862 size_t lbq;
863 pa_bool_t called = FALSE;
864
865 pa_sink_input_assert_ref(i);
866 pa_sink_input_assert_io_context(i);
867 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
868 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
869
870 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
871
872 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
873
874 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
875 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
876 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
877 sink_input_rewind_ramp_info(i, nbytes);
878 }
879
880 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
881
882 /* We were asked to drop all buffered data, and rerequest new
883 * data from implementor the next time push() is called */
884
885 pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
886
887 } else if (i->thread_info.rewrite_nbytes > 0) {
888 size_t max_rewrite, amount;
889
890 /* Calculate how much make sense to rewrite at most */
891 max_rewrite = nbytes + lbq;
892
893 /* Transform into local domain */
894 if (i->thread_info.resampler)
895 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
896
897 /* Calculate how much of the rewinded data should actually be rewritten */
898 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
899
900 if (amount > 0) {
901 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
902
903 /* Tell the implementor */
904 if (i->process_rewind)
905 i->process_rewind(i, amount);
906 called = TRUE;
907
908 /* Convert back to to sink domain */
909 if (i->thread_info.resampler)
910 amount = pa_resampler_result(i->thread_info.resampler, amount);
911
912 if (amount > 0)
913 /* Ok, now update the write pointer */
914 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
915
916 if (i->thread_info.rewrite_flush)
917 pa_memblockq_silence(i->thread_info.render_memblockq);
918
919 /* And reset the resampler */
920 if (i->thread_info.resampler)
921 pa_resampler_reset(i->thread_info.resampler);
922 }
923 }
924
925 if (!called)
926 if (i->process_rewind)
927 i->process_rewind(i, 0);
928
929 i->thread_info.rewrite_nbytes = 0;
930 i->thread_info.rewrite_flush = FALSE;
931 i->thread_info.dont_rewind_render = FALSE;
932 }
933
934 /* Called from thread context */
935 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
936 pa_sink_input_assert_ref(i);
937 pa_sink_input_assert_io_context(i);
938
939 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
940 }
941
942 /* Called from thread context */
943 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
944 pa_sink_input_assert_ref(i);
945 pa_sink_input_assert_io_context(i);
946
947 /* We're not verifying the status here, to allow this to be called
948 * in the state change handler between _INIT and _RUNNING */
949
950 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
951 }
952
953 /* Called from thread context */
954 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
955 pa_sink_input_assert_ref(i);
956 pa_sink_input_assert_io_context(i);
957 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
958 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
959
960 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
961
962 if (i->update_max_rewind)
963 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
964 }
965
966 /* Called from thread context */
967 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
968 pa_sink_input_assert_ref(i);
969 pa_sink_input_assert_io_context(i);
970 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
971 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
972
973 if (i->update_max_request)
974 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
975 }
976
977 /* Called from thread context */
978 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
979 pa_sink_input_assert_ref(i);
980 pa_sink_input_assert_io_context(i);
981
982 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
983 usec = i->sink->thread_info.fixed_latency;
984
985 if (usec != (pa_usec_t) -1)
986 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
987
988 i->thread_info.requested_sink_latency = usec;
989 pa_sink_invalidate_requested_latency(i->sink, TRUE);
990
991 return usec;
992 }
993
994 /* Called from main context */
995 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
996 pa_sink_input_assert_ref(i);
997 pa_assert_ctl_context();
998
999 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1000 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1001 return usec;
1002 }
1003
1004 /* If this sink input is not realized yet or we are being moved,
1005 * we have to touch the thread info data directly */
1006
1007 if (i->sink) {
1008 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1009 usec = pa_sink_get_fixed_latency(i->sink);
1010
1011 if (usec != (pa_usec_t) -1) {
1012 pa_usec_t min_latency, max_latency;
1013 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
1014 usec = PA_CLAMP(usec, min_latency, max_latency);
1015 }
1016 }
1017
1018 i->thread_info.requested_sink_latency = usec;
1019
1020 return usec;
1021 }
1022
1023 /* Called from main context */
1024 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
1025 pa_sink_input_assert_ref(i);
1026 pa_assert_ctl_context();
1027
1028 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1029 pa_usec_t usec = 0;
1030 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1031 return usec;
1032 }
1033
1034 /* If this sink input is not realized yet or we are being moved,
1035 * we have to touch the thread info data directly */
1036
1037 return i->thread_info.requested_sink_latency;
1038 }
1039
1040 /* Called from main context */
1041 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1042 pa_sink_input_assert_ref(i);
1043 pa_assert_ctl_context();
1044 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1045 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1046
1047 /* This basically calculates:
1048 *
1049 * i->real_ratio := v
1050 * i->soft_volume := i->real_ratio * i->volume_factor */
1051
1052 if (v)
1053 i->real_ratio = *v;
1054 else
1055 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1056
1057 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1058 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1059 }
1060
1061 /* Called from main context */
1062 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
1063
1064 /* Do not allow for volume changes for non-audio types */
1065 if (i->flags & PA_SINK_INPUT_PASSTHROUGH)
1066 return;
1067
1068 /* test ramping -> return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 2000 * PA_USEC_PER_MSEC); */
1069 return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 0);
1070 }
1071
1072 /* Called from main context */
1073 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1074 pa_sink_input_assert_ref(i);
1075 pa_assert_ctl_context();
1076 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1077
1078 if (absolute || !(i->sink->flags & PA_SINK_FLAT_VOLUME))
1079 *volume = i->volume;
1080 else
1081 *volume = i->reference_ratio;
1082
1083 return volume;
1084 }
1085
1086 /* Called from main context */
1087 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1088 /* test ramping -> return pa_sink_input_set_mute_with_ramping(i, mute, save, 2000 * PA_USEC_PER_MSEC); */
1089 return pa_sink_input_set_mute_with_ramping(i, mute, save, 0);
1090 }
1091
1092 /* Called from main context */
1093 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1094 pa_sink_input_assert_ref(i);
1095 pa_assert_ctl_context();
1096 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1097
1098 return i->muted;
1099 }
1100
1101 /* Called from main thread */
1102 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1103 pa_sink_input_assert_ref(i);
1104 pa_assert_ctl_context();
1105
1106 if (p)
1107 pa_proplist_update(i->proplist, mode, p);
1108
1109 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1110 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1111 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1112 }
1113 }
1114
1115 /* Called from main context */
1116 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1117 pa_sink_input_assert_ref(i);
1118 pa_assert_ctl_context();
1119 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1120
1121 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1122 }
1123
1124 /* Called from main context */
1125 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1126 pa_sink_input_assert_ref(i);
1127 pa_assert_ctl_context();
1128 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1129 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1130
1131 if (i->sample_spec.rate == rate)
1132 return 0;
1133
1134 i->sample_spec.rate = rate;
1135
1136 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1137
1138 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1139 return 0;
1140 }
1141
1142 /* Called from main context */
1143 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1144 const char *old;
1145 pa_sink_input_assert_ref(i);
1146 pa_assert_ctl_context();
1147
1148 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1149 return;
1150
1151 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1152
1153 if (old && name && pa_streq(old, name))
1154 return;
1155
1156 if (name)
1157 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1158 else
1159 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1160
1161 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1162 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1163 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1164 }
1165 }
1166
1167 /* Called from main context */
1168 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1169 pa_sink_input_assert_ref(i);
1170 pa_assert_ctl_context();
1171
1172 return i->actual_resample_method;
1173 }
1174
1175 /* Called from main context */
1176 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1177 pa_sink_input_assert_ref(i);
1178 pa_assert_ctl_context();
1179 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1180
1181 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1182 return FALSE;
1183
1184 if (i->sync_next || i->sync_prev) {
1185 pa_log_warn("Moving synchronized streams not supported.");
1186 return FALSE;
1187 }
1188
1189 return TRUE;
1190 }
1191
1192 /* Called from main context */
1193 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1194 pa_sink_input_assert_ref(i);
1195 pa_assert_ctl_context();
1196 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1197 pa_sink_assert_ref(dest);
1198
1199 if (dest == i->sink)
1200 return TRUE;
1201
1202 if (!pa_sink_input_may_move(i))
1203 return FALSE;
1204
1205 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1206 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1207 return FALSE;
1208 }
1209
1210 if (check_passthrough_connection(i->flags, dest) < 0)
1211 return FALSE;
1212
1213 if (i->may_move_to)
1214 if (!i->may_move_to(i, dest))
1215 return FALSE;
1216
1217 return TRUE;
1218 }
1219
1220 /* Called from main context */
1221 int pa_sink_input_start_move(pa_sink_input *i) {
1222 pa_source_output *o, *p = NULL;
1223 int r;
1224
1225 pa_sink_input_assert_ref(i);
1226 pa_assert_ctl_context();
1227 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1228 pa_assert(i->sink);
1229
1230 if (!pa_sink_input_may_move(i))
1231 return -PA_ERR_NOTSUPPORTED;
1232
1233 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1234 return r;
1235
1236 /* Kill directly connected outputs */
1237 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1238 pa_assert(o != p);
1239 pa_source_output_kill(o);
1240 p = o;
1241 }
1242 pa_assert(pa_idxset_isempty(i->direct_outputs));
1243
1244 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1245
1246 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1247 pa_assert_se(i->sink->n_corked-- >= 1);
1248
1249 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
1250 /* We might need to update the sink's volume if we are in flat
1251 * volume mode. */
1252 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1253
1254 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1255
1256 pa_sink_update_status(i->sink);
1257 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1258 i->sink = NULL;
1259
1260 pa_sink_input_unref(i);
1261
1262 return 0;
1263 }
1264
1265 /* Called from main context */
1266 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1267 pa_resampler *new_resampler;
1268
1269 pa_sink_input_assert_ref(i);
1270 pa_assert_ctl_context();
1271 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1272 pa_assert(!i->sink);
1273 pa_sink_assert_ref(dest);
1274
1275 if (!pa_sink_input_may_move_to(i, dest))
1276 return -PA_ERR_NOTSUPPORTED;
1277
1278 if (i->thread_info.resampler &&
1279 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1280 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1281
1282 /* Try to reuse the old resampler if possible */
1283 new_resampler = i->thread_info.resampler;
1284
1285 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1286 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1287 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1288
1289 /* Okey, we need a new resampler for the new sink */
1290
1291 if (!(new_resampler = pa_resampler_new(
1292 i->core->mempool,
1293 &i->sample_spec, &i->channel_map,
1294 &dest->sample_spec, &dest->channel_map,
1295 i->requested_resample_method,
1296 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1297 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1298 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1299 pa_log_warn("Unsupported resampling operation.");
1300 return -PA_ERR_NOTSUPPORTED;
1301 }
1302 } else
1303 new_resampler = NULL;
1304
1305 if (i->moving)
1306 i->moving(i, dest);
1307
1308 i->sink = dest;
1309 i->save_sink = save;
1310 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1311
1312 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1313
1314 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1315 i->sink->n_corked++;
1316
1317 /* Replace resampler and render queue */
1318 if (new_resampler != i->thread_info.resampler) {
1319
1320 if (i->thread_info.resampler)
1321 pa_resampler_free(i->thread_info.resampler);
1322 i->thread_info.resampler = new_resampler;
1323
1324 pa_memblockq_free(i->thread_info.render_memblockq);
1325
1326 i->thread_info.render_memblockq = pa_memblockq_new(
1327 0,
1328 MEMBLOCKQ_MAXLENGTH,
1329 0,
1330 pa_frame_size(&i->sink->sample_spec),
1331 0,
1332 1,
1333 0,
1334 &i->sink->silence);
1335 }
1336 pa_sink_update_status(dest);
1337
1338 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1339 pa_cvolume remapped;
1340
1341 /* Make relative volumes absolute */
1342 remapped = dest->reference_volume;
1343 pa_cvolume_remap(&remapped, &dest->channel_map, &i->channel_map);
1344 pa_sw_cvolume_multiply(&i->volume, &i->reference_ratio, &remapped);
1345
1346 /* We might need to update the sink's volume if we are in flat volume mode. */
1347 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1348 }
1349
1350 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1351
1352 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1353
1354 /* Notify everyone */
1355 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1356
1357 if (i->volume_changed)
1358 i->volume_changed(i);
1359
1360 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1361
1362 return 0;
1363 }
1364
1365 /* Called from main context */
1366 void pa_sink_input_fail_move(pa_sink_input *i) {
1367
1368 pa_sink_input_assert_ref(i);
1369 pa_assert_ctl_context();
1370 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1371 pa_assert(!i->sink);
1372
1373 /* Check if someone wants this sink input? */
1374 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1375 return;
1376
1377 if (i->moving)
1378 i->moving(i, NULL);
1379
1380 pa_sink_input_kill(i);
1381 }
1382
1383 /* Called from main context */
1384 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1385 int r;
1386
1387 pa_sink_input_assert_ref(i);
1388 pa_assert_ctl_context();
1389 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1390 pa_assert(i->sink);
1391 pa_sink_assert_ref(dest);
1392
1393 if (dest == i->sink)
1394 return 0;
1395
1396 if (!pa_sink_input_may_move_to(i, dest))
1397 return -PA_ERR_NOTSUPPORTED;
1398
1399 pa_sink_input_ref(i);
1400
1401 if ((r = pa_sink_input_start_move(i)) < 0) {
1402 pa_sink_input_unref(i);
1403 return r;
1404 }
1405
1406 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1407 pa_sink_input_fail_move(i);
1408 pa_sink_input_unref(i);
1409 return r;
1410 }
1411
1412 pa_sink_input_unref(i);
1413
1414 return 0;
1415 }
1416
1417 /* Called from IO thread context */
1418 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1419 pa_bool_t corking, uncorking;
1420
1421 pa_sink_input_assert_ref(i);
1422 pa_sink_input_assert_io_context(i);
1423
1424 if (state == i->thread_info.state)
1425 return;
1426
1427 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1428 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1429 pa_atomic_store(&i->thread_info.drained, 1);
1430
1431 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1432 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1433
1434 if (i->state_change)
1435 i->state_change(i, state);
1436
1437 i->thread_info.state = state;
1438
1439 if (corking) {
1440
1441 pa_log_debug("Requesting rewind due to corking");
1442
1443 /* This will tell the implementing sink input driver to rewind
1444 * so that the unplayed already mixed data is not lost */
1445 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1446
1447 } else if (uncorking) {
1448
1449 i->thread_info.underrun_for = (uint64_t) -1;
1450 i->thread_info.playing_for = 0;
1451
1452 pa_log_debug("Requesting rewind due to uncorking");
1453
1454 /* OK, we're being uncorked. Make sure we're not rewound when
1455 * the hw buffer is remixed and request a remix. */
1456 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1457 }
1458 }
1459
1460 /* Called from thread context, except when it is not. */
1461 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1462 pa_sink_input *i = PA_SINK_INPUT(o);
1463 pa_sink_input_assert_ref(i);
1464
1465 switch (code) {
1466
1467 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1468 if (pa_atomic_load(&i->before_ramping_v))
1469 i->thread_info.future_soft_volume = i->soft_volume;
1470
1471 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1472 if (!pa_atomic_load(&i->before_ramping_v))
1473 i->thread_info.soft_volume = i->soft_volume;
1474 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1475 }
1476 return 0;
1477
1478 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1479 if (pa_atomic_load(&i->before_ramping_m))
1480 i->thread_info.future_muted = i->muted;
1481
1482 if (i->thread_info.muted != i->muted) {
1483 if (!pa_atomic_load(&i->before_ramping_m))
1484 i->thread_info.muted = i->muted;
1485 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1486 }
1487 return 0;
1488
1489 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1490 pa_usec_t *r = userdata;
1491
1492 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1493 r[1] += pa_sink_get_latency_within_thread(i->sink);
1494
1495 return 0;
1496 }
1497
1498 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1499
1500 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1501 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1502
1503 return 0;
1504
1505 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1506 pa_sink_input *ssync;
1507
1508 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1509
1510 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1511 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1512
1513 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1514 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1515
1516 return 0;
1517 }
1518
1519 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1520 pa_usec_t *usec = userdata;
1521
1522 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1523 return 0;
1524 }
1525
1526 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1527 pa_usec_t *r = userdata;
1528
1529 *r = i->thread_info.requested_sink_latency;
1530 return 0;
1531 }
1532
1533 case PA_SINK_INPUT_MESSAGE_SET_ENVELOPE: {
1534 if (!i->thread_info.ramp_info.envelope)
1535 i->thread_info.ramp_info.envelope = pa_envelope_new(&i->sink->sample_spec);
1536
1537 if (i->thread_info.ramp_info.envelope && i->thread_info.ramp_info.item) {
1538 pa_envelope_remove(i->thread_info.ramp_info.envelope, i->thread_info.ramp_info.item);
1539 i->thread_info.ramp_info.item = NULL;
1540 }
1541
1542 i->thread_info.ramp_info.item = pa_envelope_add(i->thread_info.ramp_info.envelope, &i->using_def);
1543 i->thread_info.ramp_info.is_ramping = TRUE;
1544 i->thread_info.ramp_info.envelope_dead = FALSE;
1545 i->thread_info.ramp_info.envelope_dying = 0;
1546
1547 if (i->thread_info.ramp_info.envelope)
1548 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1549
1550 return 0;
1551 }
1552 }
1553
1554 return -PA_ERR_NOTIMPLEMENTED;
1555 }
1556
1557 /* Called from main thread */
1558 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1559 pa_sink_input_assert_ref(i);
1560 pa_assert_ctl_context();
1561
1562 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1563 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1564
1565 return i->state;
1566 }
1567
1568 /* Called from IO context */
1569 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1570 pa_sink_input_assert_ref(i);
1571 pa_sink_input_assert_io_context(i);
1572
1573 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1574 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1575
1576 return TRUE;
1577 }
1578
1579 /* Called from IO context */
1580 void pa_sink_input_request_rewind(
1581 pa_sink_input *i,
1582 size_t nbytes /* in our sample spec */,
1583 pa_bool_t rewrite,
1584 pa_bool_t flush,
1585 pa_bool_t dont_rewind_render) {
1586
1587 size_t lbq;
1588
1589 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1590 * and possible and the exact value of this is passed back the
1591 * implementor via process_rewind(). If 'flush' is also TRUE all
1592 * already rendered data is also dropped.
1593 *
1594 * If 'rewrite' is FALSE the sink is rewound as far as requested
1595 * and possible and the already rendered data is dropped so that
1596 * in the next iteration we read new data from the
1597 * implementor. This implies 'flush' is TRUE. If
1598 * dont_rewind_render is TRUE then the render memblockq is not
1599 * rewound. */
1600
1601 /* nbytes = 0 means maximum rewind request */
1602
1603 pa_sink_input_assert_ref(i);
1604 pa_sink_input_assert_io_context(i);
1605 pa_assert(rewrite || flush);
1606 pa_assert(!dont_rewind_render || !rewrite);
1607
1608 /* We don't take rewind requests while we are corked */
1609 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1610 return;
1611
1612 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1613
1614 /* pa_log_debug("request rewrite %zu", nbytes); */
1615
1616 /* Calculate how much we can rewind locally without having to
1617 * touch the sink */
1618 if (rewrite)
1619 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1620 else
1621 lbq = 0;
1622
1623 /* Check if rewinding for the maximum is requested, and if so, fix up */
1624 if (nbytes <= 0) {
1625
1626 /* Calculate maximum number of bytes that could be rewound in theory */
1627 nbytes = i->sink->thread_info.max_rewind + lbq;
1628
1629 /* Transform from sink domain */
1630 if (i->thread_info.resampler)
1631 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1632 }
1633
1634 /* Remember how much we actually want to rewrite */
1635 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1636 if (rewrite) {
1637 /* Make sure to not overwrite over underruns */
1638 if (nbytes > i->thread_info.playing_for)
1639 nbytes = (size_t) i->thread_info.playing_for;
1640
1641 i->thread_info.rewrite_nbytes = nbytes;
1642 } else
1643 i->thread_info.rewrite_nbytes = (size_t) -1;
1644 }
1645
1646 i->thread_info.rewrite_flush =
1647 i->thread_info.rewrite_flush ||
1648 (flush && i->thread_info.rewrite_nbytes != 0);
1649
1650 i->thread_info.dont_rewind_render =
1651 i->thread_info.dont_rewind_render ||
1652 dont_rewind_render;
1653
1654 if (nbytes != (size_t) -1) {
1655
1656 /* Transform to sink domain */
1657 if (i->thread_info.resampler)
1658 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1659
1660 if (nbytes > lbq)
1661 pa_sink_request_rewind(i->sink, nbytes - lbq);
1662 else
1663 /* This call will make sure process_rewind() is called later */
1664 pa_sink_request_rewind(i->sink, 0);
1665 }
1666 }
1667
1668 /* Called from main context */
1669 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1670 pa_sink_input_assert_ref(i);
1671 pa_assert_ctl_context();
1672 pa_assert(ret);
1673
1674 /* FIXME: Shouldn't access resampler object from main context! */
1675
1676 pa_silence_memchunk_get(
1677 &i->core->silence_cache,
1678 i->core->mempool,
1679 ret,
1680 &i->sample_spec,
1681 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1682
1683 return ret;
1684 }
1685
1686 /* Called from main context */
1687 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1688 pa_proplist *pl = NULL;
1689 pa_sink_input_send_event_hook_data hook_data;
1690
1691 pa_sink_input_assert_ref(i);
1692 pa_assert_ctl_context();
1693 pa_assert(event);
1694
1695 if (!i->send_event)
1696 return;
1697
1698 if (!data)
1699 data = pl = pa_proplist_new();
1700
1701 hook_data.sink_input = i;
1702 hook_data.data = data;
1703 hook_data.event = event;
1704
1705 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1706 goto finish;
1707
1708 i->send_event(i, event, data);
1709
1710 finish:
1711 if (pl)
1712 pa_proplist_free(pl);
1713 }
1714
1715 /* Called from IO context */
1716 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk) {
1717 pa_assert(i);
1718 pa_assert(chunk);
1719 pa_assert(chunk->memblock);
1720 pa_assert(i->thread_info.ramp_info.is_ramping);
1721
1722 /* Volume is adjusted with ramping effect here */
1723 pa_envelope_apply(i->thread_info.ramp_info.envelope, chunk);
1724
1725 if (pa_envelope_is_finished(i->thread_info.ramp_info.envelope)) {
1726 i->thread_info.ramp_info.is_ramping = FALSE;
1727 if (pa_atomic_load(&i->before_ramping_v)) {
1728 i->thread_info.soft_volume = i->thread_info.future_soft_volume;
1729 pa_atomic_store(&i->before_ramping_v, 0);
1730 }
1731 else if (pa_atomic_load(&i->before_ramping_m)) {
1732 i->thread_info.muted = i->thread_info.future_muted;
1733 pa_atomic_store(&i->before_ramping_m, 0);
1734 }
1735 }
1736 }
1737
1738 /*
1739 * Called from main context
1740 * This function should be called inside pa_sink_input_set_volume_with_ramping
1741 * should be called after soft_volume of sink_input and sink are all adjusted
1742 */
1743 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) {
1744
1745 int32_t target_abs_vol, target_apply_vol, pre_apply_vol;
1746 pa_assert(i);
1747
1748 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)));
1749
1750 /* Calculation formula are target_abs_vol := i->soft_volume
1751 * target_apply_vol := lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000)
1752 * pre_apply_vol := ( previous_virtual_volume / target_virtual_volume ) * target_apply_vol
1753 *
1754 * Will do volume adjustment inside pa_sink_input_peek
1755 */
1756 target_abs_vol = pa_cvolume_avg(&i->soft_volume);
1757 target_apply_vol = (int32_t) lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000);
1758 pre_apply_vol = (int32_t) ((pa_sw_volume_to_linear(pre_virtual_volume) / pa_sw_volume_to_linear(target_virtual_volume)) * target_apply_vol);
1759
1760 i->using_def.n_points = 2;
1761 i->using_def.points_x[0] = 0;
1762 i->using_def.points_x[1] = t;
1763 i->using_def.points_y.i[0] = pre_apply_vol;
1764 i->using_def.points_y.i[1] = target_apply_vol;
1765 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1766 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1767
1768 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],
1769 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1770
1771 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1772 }
1773
1774 /* Called from main context */
1775 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t) {
1776
1777 int32_t cur_vol;
1778 pa_assert(i);
1779
1780 i->using_def.n_points = 2;
1781 i->using_def.points_x[0] = 0;
1782 i->using_def.points_x[1] = t;
1783 cur_vol = (int32_t) lrint( pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)) * 0x10000);
1784
1785 if (mute) {
1786 i->using_def.points_y.i[0] = cur_vol;
1787 i->using_def.points_y.i[1] = 0;
1788 } else {
1789 i->using_def.points_y.i[0] = 0;
1790 i->using_def.points_y.i[1] = cur_vol;
1791 }
1792
1793 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1794 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1795
1796 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],
1797 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1798
1799 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1800 }
1801
1802 /* Called from IO context */
1803 static void sink_input_release_envelope(pa_sink_input *i) {
1804 pa_assert(i);
1805 pa_assert(!i->thread_info.ramp_info.is_ramping);
1806 pa_assert(i->thread_info.ramp_info.envelope_dead);
1807
1808 pa_envelope_free(i->thread_info.ramp_info.envelope);
1809 i->thread_info.ramp_info.envelope = NULL;
1810 i->thread_info.ramp_info.item = NULL;
1811 }
1812
1813 /* Called from IO context */
1814 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) {
1815 pa_assert(i);
1816
1817 if (!i->thread_info.ramp_info.envelope_dead) {
1818 int32_t envelope_length;
1819
1820 pa_assert(i->thread_info.ramp_info.envelope);
1821
1822 envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope);
1823
1824 if (i->thread_info.ramp_info.envelope_dying > envelope_length) {
1825 if ((int32_t) (i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) {
1826 pa_log_debug("Envelope Become Alive");
1827 pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes));
1828 i->thread_info.ramp_info.is_ramping = TRUE;
1829 }
1830 } else if (i->thread_info.ramp_info.envelope_dying < envelope_length) {
1831 if ((i->thread_info.ramp_info.envelope_dying - (ssize_t) nbytes) <= 0) {
1832 pa_log_debug("Envelope Restart");
1833 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1834 }
1835 else {
1836 pa_log_debug("Envelope Simple Rewind");
1837 pa_envelope_rewind(i->thread_info.ramp_info.envelope, nbytes);
1838 }
1839 }
1840
1841 i->thread_info.ramp_info.envelope_dying -= nbytes;
1842 if (i->thread_info.ramp_info.envelope_dying <= 0)
1843 i->thread_info.ramp_info.envelope_dying = 0;
1844 }
1845 }
1846
1847 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){
1848 pa_cvolume v;
1849 pa_volume_t previous_virtual_volume, target_virtual_volume;
1850
1851 pa_sink_input_assert_ref(i);
1852 pa_assert_ctl_context();
1853 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1854 pa_assert(volume);
1855 pa_assert(pa_cvolume_valid(volume));
1856 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1857
1858 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
1859 v = i->sink->reference_volume;
1860 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1861
1862 if (pa_cvolume_compatible(volume, &i->sample_spec))
1863 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1864 else
1865 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1866 } else {
1867
1868 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1869 v = i->volume;
1870 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1871 }
1872 }
1873
1874 if (pa_cvolume_equal(volume, &i->volume)) {
1875 i->save_volume = i->save_volume || save;
1876 return;
1877 }
1878
1879 previous_virtual_volume = pa_cvolume_avg(&i->volume);
1880 target_virtual_volume = pa_cvolume_avg(volume);
1881
1882 if (t > 0 && target_virtual_volume > 0)
1883 pa_log_debug("SetVolumeWithRamping: Virtual Volume From %u=%f to %u=%f\n", previous_virtual_volume, pa_sw_volume_to_linear(previous_virtual_volume),
1884 target_virtual_volume, pa_sw_volume_to_linear(target_virtual_volume));
1885
1886 i->volume = *volume;
1887 i->save_volume = save;
1888
1889 /* Set this flag before the following code modify i->thread_info.soft_volume */
1890 if (t > 0 && target_virtual_volume > 0)
1891 pa_atomic_store(&i->before_ramping_v, 1);
1892
1893 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1894 /* We are in flat volume mode, so let's update all sink input
1895 * volumes and update the flat volume of the sink */
1896
1897 pa_sink_set_volume(i->sink, NULL, TRUE, save);
1898
1899 } else {
1900 /* OK, we are in normal volume mode. The volume only affects
1901 * ourselves */
1902 set_real_ratio(i, volume);
1903
1904 /* Copy the new soft_volume to the thread_info struct */
1905 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1906 }
1907
1908 if (t > 0 && target_virtual_volume > 0)
1909 sink_input_set_ramping_info(i, previous_virtual_volume, target_virtual_volume, t);
1910
1911 /* The volume changed, let's tell people so */
1912 if (i->volume_changed)
1913 i->volume_changed(i);
1914
1915 /* The virtual volume changed, let's tell people so */
1916 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1917 }
1918
1919 void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){
1920
1921 pa_sink_input_assert_ref(i);
1922 pa_assert_ctl_context();
1923 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1924
1925 if (!i->muted == !mute) {
1926 i->save_muted = i->save_muted || mute;
1927 return;
1928 }
1929
1930 i->muted = mute;
1931 i->save_muted = save;
1932
1933 /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */
1934 if (t > 0)
1935 pa_atomic_store(&i->before_ramping_m, 1);
1936
1937 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1938
1939 if (t > 0)
1940 sink_input_set_ramping_info_for_mute(i, mute, t);
1941
1942 /* The mute status changed, let's tell people so */
1943 if (i->mute_changed)
1944 i->mute_changed(i);
1945
1946 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1947 }