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