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, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include <pulse/utf8.h>
29 #include <pulse/xmalloc.h>
30 #include <pulse/util.h>
31 #include <pulse/internal.h>
32
33 #include <pulsecore/core-format.h>
34 #include <pulsecore/mix.h>
35 #include <pulsecore/stream-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
42 #include "sink-input.h"
43
44 /* #define SINK_INPUT_DEBUG */
45
46 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
47 #define CONVERT_BUFFER_LENGTH (pa_page_size())
48
49 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
50
51 struct volume_factor_entry {
52 char *key;
53 pa_cvolume volume;
54 };
55
volume_factor_entry_new(const char * key,const pa_cvolume * volume)56 static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
57 struct volume_factor_entry *entry;
58
59 pa_assert(key);
60 pa_assert(volume);
61
62 entry = pa_xnew(struct volume_factor_entry, 1);
63 entry->key = pa_xstrdup(key);
64
65 entry->volume = *volume;
66
67 return entry;
68 }
69
volume_factor_entry_free(struct volume_factor_entry * volume_entry)70 static void volume_factor_entry_free(struct volume_factor_entry *volume_entry) {
71 pa_assert(volume_entry);
72
73 pa_xfree(volume_entry->key);
74 pa_xfree(volume_entry);
75 }
76
volume_factor_from_hashmap(pa_cvolume * v,pa_hashmap * items,uint8_t channels)77 static void volume_factor_from_hashmap(pa_cvolume *v, pa_hashmap *items, uint8_t channels) {
78 struct volume_factor_entry *entry;
79 void *state = NULL;
80
81 pa_cvolume_reset(v, channels);
82 PA_HASHMAP_FOREACH(entry, items, state)
83 pa_sw_cvolume_multiply(v, v, &entry->volume);
84 }
85
86 static void sink_input_free(pa_object *o);
87 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
88
check_passthrough_connection(bool passthrough,pa_sink * dest)89 static int check_passthrough_connection(bool passthrough, pa_sink *dest) {
90 if (pa_sink_is_passthrough(dest)) {
91 pa_log_warn("Sink is already connected to PASSTHROUGH input");
92 return -PA_ERR_BUSY;
93 }
94
95 /* If current input(s) exist, check new input is not PASSTHROUGH */
96 if (pa_idxset_size(dest->inputs) > 0 && passthrough) {
97 pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
98 return -PA_ERR_BUSY;
99 }
100
101 return PA_OK;
102 }
103
pa_sink_input_new_data_init(pa_sink_input_new_data * data)104 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
105 pa_assert(data);
106
107 pa_zero(*data);
108 data->resample_method = PA_RESAMPLER_INVALID;
109 data->proplist = pa_proplist_new();
110 data->volume_writable = true;
111
112 data->volume_factor_items = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
113 (pa_free_cb_t) volume_factor_entry_free);
114 data->volume_factor_sink_items = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
115 (pa_free_cb_t) volume_factor_entry_free);
116
117 return data;
118 }
119
pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data * data,const pa_sample_spec * spec)120 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
121 pa_assert(data);
122
123 if ((data->sample_spec_is_set = !!spec))
124 data->sample_spec = *spec;
125 }
126
pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data * data,const pa_channel_map * map)127 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
128 pa_assert(data);
129
130 if ((data->channel_map_is_set = !!map))
131 data->channel_map = *map;
132 }
133
pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data * data)134 bool pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data) {
135 pa_assert(data);
136
137 if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format)))
138 return true;
139
140 if (PA_UNLIKELY(data->flags & PA_SINK_INPUT_PASSTHROUGH))
141 return true;
142
143 return false;
144 }
145
pa_sink_input_new_data_set_volume(pa_sink_input_new_data * data,const pa_cvolume * volume)146 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
147 pa_assert(data);
148 pa_assert(data->volume_writable);
149
150 if ((data->volume_is_set = !!volume))
151 data->volume = *volume;
152 }
153
pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data * data,const char * key,const pa_cvolume * volume_factor)154 void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor) {
155 struct volume_factor_entry *v;
156
157 pa_assert(data);
158 pa_assert(key);
159 pa_assert(volume_factor);
160
161 v = volume_factor_entry_new(key, volume_factor);
162 pa_assert_se(pa_hashmap_put(data->volume_factor_items, v->key, v) >= 0);
163 }
164
pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data * data,const char * key,const pa_cvolume * volume_factor)165 void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor) {
166 struct volume_factor_entry *v;
167
168 pa_assert(data);
169 pa_assert(key);
170 pa_assert(volume_factor);
171
172 v = volume_factor_entry_new(key, volume_factor);
173 pa_assert_se(pa_hashmap_put(data->volume_factor_sink_items, v->key, v) >= 0);
174 }
175
pa_sink_input_new_data_set_muted(pa_sink_input_new_data * data,bool mute)176 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, bool mute) {
177 pa_assert(data);
178
179 data->muted_is_set = true;
180 data->muted = mute;
181 }
182
pa_sink_input_new_data_set_sink(pa_sink_input_new_data * data,pa_sink * s,bool save,bool requested_by_application)183 bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, bool save, bool requested_by_application) {
184 bool ret = true;
185 pa_idxset *formats = NULL;
186
187 pa_assert(data);
188 pa_assert(s);
189
190 if (!data->req_formats) {
191 /* We're not working with the extended API */
192 data->sink = s;
193 if (save) {
194 pa_xfree(data->preferred_sink);
195 data->preferred_sink = pa_xstrdup(s->name);
196 }
197 data->sink_requested_by_application = requested_by_application;
198 } else {
199 /* Extended API: let's see if this sink supports the formats the client can provide */
200 formats = pa_sink_check_formats(s, data->req_formats);
201
202 if (formats && !pa_idxset_isempty(formats)) {
203 /* Sink supports at least one of the requested formats */
204 data->sink = s;
205 if (save) {
206 pa_xfree(data->preferred_sink);
207 data->preferred_sink = pa_xstrdup(s->name);
208 }
209 data->sink_requested_by_application = requested_by_application;
210 if (data->nego_formats)
211 pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
212 data->nego_formats = formats;
213 } else {
214 /* Sink doesn't support any of the formats requested by the client */
215 if (formats)
216 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
217 ret = false;
218 }
219 }
220
221 return ret;
222 }
223
pa_sink_input_new_data_set_formats(pa_sink_input_new_data * data,pa_idxset * formats)224 bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset *formats) {
225 pa_assert(data);
226 pa_assert(formats);
227
228 if (data->req_formats)
229 pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
230
231 data->req_formats = formats;
232
233 if (data->sink) {
234 /* Trigger format negotiation */
235 return pa_sink_input_new_data_set_sink(data, data->sink, (data->preferred_sink != NULL), data->sink_requested_by_application);
236 }
237
238 return true;
239 }
240
pa_sink_input_new_data_done(pa_sink_input_new_data * data)241 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
242 pa_assert(data);
243
244 if (data->req_formats)
245 pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
246
247 if (data->nego_formats)
248 pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
249
250 if (data->format)
251 pa_format_info_free(data->format);
252
253 if (data->volume_factor_items)
254 pa_hashmap_free(data->volume_factor_items);
255
256 if (data->volume_factor_sink_items)
257 pa_hashmap_free(data->volume_factor_sink_items);
258
259 if (data->preferred_sink)
260 pa_xfree(data->preferred_sink);
261
262 pa_proplist_free(data->proplist);
263 }
264
265 /* Called from main context */
reset_callbacks(pa_sink_input * i)266 static void reset_callbacks(pa_sink_input *i) {
267 pa_assert(i);
268
269 i->pop = NULL;
270 i->process_underrun = NULL;
271 i->process_rewind = NULL;
272 i->update_max_rewind = NULL;
273 i->update_max_request = NULL;
274 i->update_sink_requested_latency = NULL;
275 i->update_sink_latency_range = NULL;
276 i->update_sink_fixed_latency = NULL;
277 i->attach = NULL;
278 i->detach = NULL;
279 i->suspend = NULL;
280 i->suspend_within_thread = NULL;
281 i->moving = NULL;
282 i->kill = NULL;
283 i->get_latency = NULL;
284 i->state_change = NULL;
285 i->may_move_to = NULL;
286 i->send_event = NULL;
287 i->volume_changed = NULL;
288 i->mute_changed = NULL;
289 }
290
291 /* Called from main context */
pa_sink_input_new(pa_sink_input ** _i,pa_core * core,pa_sink_input_new_data * data)292 int pa_sink_input_new(
293 pa_sink_input **_i,
294 pa_core *core,
295 pa_sink_input_new_data *data) {
296
297 pa_sink_input *i;
298 pa_resampler *resampler = NULL;
299 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], fmt[PA_FORMAT_INFO_SNPRINT_MAX];
300 pa_channel_map volume_map;
301 int r;
302 char *pt;
303 char *memblockq_name;
304
305 pa_assert(_i);
306 pa_assert(core);
307 pa_assert(data);
308 pa_assert_ctl_context();
309
310 if (data->client)
311 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
312
313 if (data->origin_sink && (data->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
314 data->volume_writable = false;
315
316 if (!data->req_formats) {
317 /* From this point on, we want to work only with formats, and get back
318 * to using the sample spec and channel map after all decisions w.r.t.
319 * routing are complete. */
320 pa_format_info *f;
321 pa_idxset *formats;
322
323 f = pa_format_info_from_sample_spec2(&data->sample_spec, data->channel_map_is_set ? &data->channel_map : NULL,
324 !(data->flags & PA_SINK_INPUT_FIX_FORMAT),
325 !(data->flags & PA_SINK_INPUT_FIX_RATE),
326 !(data->flags & PA_SINK_INPUT_FIX_CHANNELS));
327 if (!f)
328 return -PA_ERR_INVALID;
329
330 formats = pa_idxset_new(NULL, NULL);
331 pa_idxset_put(formats, f, NULL);
332 pa_sink_input_new_data_set_formats(data, formats);
333 }
334
335 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
336 return r;
337
338 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
339
340 if (!data->sink) {
341 pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
342 pa_return_val_if_fail(sink, -PA_ERR_NOENTITY);
343 pa_sink_input_new_data_set_sink(data, sink, false, false);
344 }
345
346 /* If something didn't pick a format for us, pick the top-most format since
347 * we assume this is sorted in priority order */
348 if (!data->format && data->nego_formats && !pa_idxset_isempty(data->nego_formats))
349 data->format = pa_format_info_copy(pa_idxset_first(data->nego_formats, NULL));
350
351 if (PA_LIKELY(data->format)) {
352 /* We know that data->sink is set, because data->format has been set.
353 * data->format is set after a successful format negotiation, and that
354 * can't happen before data->sink has been set. */
355 pa_assert(data->sink);
356
357 pa_log_debug("Negotiated format: %s", pa_format_info_snprint(fmt, sizeof(fmt), data->format));
358 } else {
359 pa_format_info *format;
360 uint32_t idx;
361
362 pa_log_info("Sink does not support any requested format:");
363 PA_IDXSET_FOREACH(format, data->req_formats, idx)
364 pa_log_info(" -- %s", pa_format_info_snprint(fmt, sizeof(fmt), format));
365
366 return -PA_ERR_NOTSUPPORTED;
367 }
368
369 pa_return_val_if_fail(PA_SINK_IS_LINKED(data->sink->state), -PA_ERR_BADSTATE);
370 pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink
371 && data->sync_base->state == PA_SINK_INPUT_CORKED),
372 -PA_ERR_INVALID);
373
374 /* Routing is done. We have a sink and a format. */
375
376 if (data->volume_is_set && !pa_sink_input_new_data_is_passthrough(data)) {
377 /* If volume is set, we need to save the original data->channel_map,
378 * so that we can remap the volume from the original channel map to the
379 * final channel map of the stream in case data->channel_map gets
380 * modified in pa_format_info_to_sample_spec2(). */
381 r = pa_stream_get_volume_channel_map(&data->volume, data->channel_map_is_set ? &data->channel_map : NULL, data->format, &volume_map);
382 if (r < 0)
383 return r;
384 } else {
385 /* Initialize volume_map to invalid state. We check the state later to
386 * determine if volume remapping is needed. */
387 pa_channel_map_init(&volume_map);
388 }
389
390 /* Now populate the sample spec and channel map according to the final
391 * format that we've negotiated */
392 r = pa_format_info_to_sample_spec2(data->format, &data->sample_spec, &data->channel_map, &data->sink->sample_spec,
393 &data->sink->channel_map);
394 if (r < 0)
395 return r;
396
397 r = check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data), data->sink);
398 if (r != PA_OK)
399 return r;
400
401 /* Don't restore (or save) stream volume for passthrough streams and
402 * prevent attenuation/gain */
403 if (pa_sink_input_new_data_is_passthrough(data)) {
404 data->volume_is_set = true;
405 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
406 data->volume_is_absolute = true;
407 data->save_volume = false;
408 }
409
410 if (!data->volume_is_set) {
411 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
412 data->volume_is_absolute = false;
413 data->save_volume = false;
414 }
415
416 if (!data->volume_writable)
417 data->save_volume = false;
418
419 if (pa_channel_map_valid(&volume_map))
420 /* The original volume channel map may be different than the final
421 * stream channel map, so remapping may be needed. */
422 pa_cvolume_remap(&data->volume, &volume_map, &data->channel_map);
423
424 if (!data->muted_is_set)
425 data->muted = false;
426
427 if (!(data->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
428 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec)) {
429 /* try to change sink format and rate. This is done before the FIXATE hook since
430 module-suspend-on-idle can resume a sink */
431
432 pa_log_info("Trying to change sample spec");
433 pa_sink_reconfigure(data->sink, &data->sample_spec, pa_sink_input_new_data_is_passthrough(data));
434 }
435
436 if (pa_sink_input_new_data_is_passthrough(data) &&
437 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec)) {
438 /* rate update failed, or other parts of sample spec didn't match */
439
440 pa_log_debug("Could not update sink sample spec to match passthrough stream");
441 return -PA_ERR_NOTSUPPORTED;
442 }
443
444 if (data->resample_method == PA_RESAMPLER_INVALID)
445 data->resample_method = core->resample_method;
446
447 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
448
449 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
450 return r;
451
452 if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
453 data->sink->state == PA_SINK_SUSPENDED) {
454 pa_log_warn("Failed to create sink input: sink is suspended.");
455 return -PA_ERR_BADSTATE;
456 }
457
458 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
459 pa_log_warn("Failed to create sink input: too many inputs per sink.");
460 return -PA_ERR_TOOLARGE;
461 }
462
463 if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
464 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
465 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
466
467 /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
468 if (!pa_sink_input_new_data_is_passthrough(data)) /* no resampler for passthrough content */
469 if (!(resampler = pa_resampler_new(
470 core->mempool,
471 &data->sample_spec, &data->channel_map,
472 &data->sink->sample_spec, &data->sink->channel_map,
473 core->lfe_crossover_freq,
474 data->resample_method,
475 ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
476 ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
477 (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
478 (core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
479 (core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
480 (core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0)))) {
481 pa_log_warn("Unsupported resampling operation.");
482 return -PA_ERR_NOTSUPPORTED;
483 }
484 }
485
486 i = pa_msgobject_new(pa_sink_input);
487 i->parent.parent.free = sink_input_free;
488 i->parent.process_msg = pa_sink_input_process_msg;
489
490 i->core = core;
491 i->state = PA_SINK_INPUT_INIT;
492 i->flags = data->flags;
493 i->proplist = pa_proplist_copy(data->proplist);
494 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
495 i->module = data->module;
496 i->sink = data->sink;
497 i->sink_requested_by_application = data->sink_requested_by_application;
498 i->origin_sink = data->origin_sink;
499 i->client = data->client;
500
501 i->requested_resample_method = data->resample_method;
502 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
503 i->sample_spec = data->sample_spec;
504 i->channel_map = data->channel_map;
505 i->format = pa_format_info_copy(data->format);
506
507 if (!data->volume_is_absolute && pa_sink_flat_volume_enabled(i->sink)) {
508 pa_cvolume remapped;
509
510 /* When the 'absolute' bool is not set then we'll treat the volume
511 * as relative to the sink volume even in flat volume mode */
512 remapped = data->sink->reference_volume;
513 pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
514 pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
515 } else
516 i->volume = data->volume;
517
518 i->volume_factor_items = data->volume_factor_items;
519 data->volume_factor_items = NULL;
520 volume_factor_from_hashmap(&i->volume_factor, i->volume_factor_items, i->sample_spec.channels);
521
522 i->volume_factor_sink_items = data->volume_factor_sink_items;
523 data->volume_factor_sink_items = NULL;
524 volume_factor_from_hashmap(&i->volume_factor_sink, i->volume_factor_sink_items, i->sink->sample_spec.channels);
525
526 i->real_ratio = i->reference_ratio = data->volume;
527 pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
528 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
529 i->volume_writable = data->volume_writable;
530 i->save_volume = data->save_volume;
531 i->preferred_sink = pa_xstrdup(data->preferred_sink);
532 i->save_muted = data->save_muted;
533
534 i->muted = data->muted;
535
536 if (data->sync_base) {
537 i->sync_next = data->sync_base->sync_next;
538 i->sync_prev = data->sync_base;
539
540 if (data->sync_base->sync_next)
541 data->sync_base->sync_next->sync_prev = i;
542 data->sync_base->sync_next = i;
543 } else
544 i->sync_next = i->sync_prev = NULL;
545
546 i->direct_outputs = pa_idxset_new(NULL, NULL);
547
548 reset_callbacks(i);
549 i->userdata = NULL;
550
551 i->thread_info.state = i->state;
552 i->thread_info.attached = false;
553 i->thread_info.sample_spec = i->sample_spec;
554 i->thread_info.resampler = resampler;
555 i->thread_info.soft_volume = i->soft_volume;
556 i->thread_info.muted = i->muted;
557 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
558 i->thread_info.rewrite_nbytes = 0;
559 i->thread_info.rewrite_flush = false;
560 i->thread_info.dont_rewind_render = false;
561 i->thread_info.underrun_for = (uint64_t) -1;
562 i->thread_info.underrun_for_sink = 0;
563 i->thread_info.playing_for = 0;
564 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
565
566 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
567 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
568
569 if (i->client)
570 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
571
572 memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
573 i->thread_info.render_memblockq = pa_memblockq_new(
574 memblockq_name,
575 0,
576 MEMBLOCKQ_MAXLENGTH,
577 0,
578 &i->sink->sample_spec,
579 0,
580 1,
581 0,
582 &i->sink->silence);
583 pa_xfree(memblockq_name);
584
585 pt = pa_proplist_to_string_sep(i->proplist, "\n ");
586 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
587 i->index,
588 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
589 i->sink->name,
590 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
591 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
592 pt);
593 pa_xfree(pt);
594
595 /* Don't forget to call pa_sink_input_put! */
596
597 *_i = i;
598 return 0;
599 }
600
601 /* Called from main context */
update_n_corked(pa_sink_input * i,pa_sink_input_state_t state)602 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
603 pa_assert(i);
604 pa_assert_ctl_context();
605
606 if (!i->sink)
607 return;
608
609 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
610 pa_assert_se(i->sink->n_corked -- >= 1);
611 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
612 i->sink->n_corked++;
613 }
614
615 /* Called from main context */
sink_input_set_state(pa_sink_input * i,pa_sink_input_state_t state)616 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
617 pa_sink_input *ssync;
618 pa_assert(i);
619 pa_assert_ctl_context();
620
621 if (i->state == state)
622 return;
623
624 if (i->sink) {
625 if (i->state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING && pa_sink_used_by(i->sink) == 0 &&
626 !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec)) {
627 /* We were uncorked and the sink was not playing anything -- let's try
628 * to update the sample format and rate to avoid resampling */
629 pa_sink_reconfigure(i->sink, &i->sample_spec, pa_sink_input_is_passthrough(i));
630 }
631
632 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);
633 } else {
634 /* If the sink is not valid, pa_sink_input_set_state_within_thread() must be called directly */
635
636 pa_sink_input_set_state_within_thread(i, state);
637
638 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
639 pa_sink_input_set_state_within_thread(ssync, state);
640
641 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
642 pa_sink_input_set_state_within_thread(ssync, state);
643 }
644
645 update_n_corked(i, state);
646 i->state = state;
647
648 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
649 update_n_corked(ssync, state);
650 ssync->state = state;
651 }
652 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
653 update_n_corked(ssync, state);
654 ssync->state = state;
655 }
656
657 if (state != PA_SINK_INPUT_UNLINKED) {
658 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
659
660 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
661 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
662
663 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
664 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
665
666 if (PA_SINK_INPUT_IS_LINKED(state))
667 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
668 }
669
670 if (i->sink)
671 pa_sink_update_status(i->sink);
672 }
673
674 /* Called from main context */
pa_sink_input_unlink(pa_sink_input * i)675 void pa_sink_input_unlink(pa_sink_input *i) {
676 bool linked;
677 pa_source_output *o, PA_UNUSED *p = NULL;
678
679 pa_sink_input_assert_ref(i);
680 pa_assert_ctl_context();
681
682 /* See pa_sink_unlink() for a couple of comments how this function
683 * works */
684
685 pa_sink_input_ref(i);
686
687 linked = PA_SINK_INPUT_IS_LINKED(i->state);
688
689 if (linked)
690 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
691
692 if (i->sync_prev)
693 i->sync_prev->sync_next = i->sync_next;
694 if (i->sync_next)
695 i->sync_next->sync_prev = i->sync_prev;
696
697 i->sync_prev = i->sync_next = NULL;
698
699 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
700
701 if (i->sink)
702 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
703 pa_sink_input_unref(i);
704
705 if (i->client)
706 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
707
708 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
709 pa_assert(o != p);
710 pa_source_output_kill(o);
711 p = o;
712 }
713
714 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
715 i->state = PA_SINK_INPUT_UNLINKED;
716
717 if (linked && i->sink) {
718 if (pa_sink_input_is_passthrough(i))
719 pa_sink_leave_passthrough(i->sink);
720
721 /* We might need to update the sink's volume if we are in flat volume mode. */
722 if (pa_sink_flat_volume_enabled(i->sink))
723 pa_sink_set_volume(i->sink, NULL, false, false);
724
725 if (i->sink->asyncmsgq)
726 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
727 }
728
729 reset_callbacks(i);
730
731 if (i->sink) {
732 if (PA_SINK_IS_LINKED(i->sink->state))
733 pa_sink_update_status(i->sink);
734
735 i->sink = NULL;
736 }
737
738 if (linked) {
739 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
740 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
741 }
742
743 pa_core_maybe_vacuum(i->core);
744
745 pa_sink_input_unref(i);
746 }
747
748 /* Called from main context */
sink_input_free(pa_object * o)749 static void sink_input_free(pa_object *o) {
750 pa_sink_input* i = PA_SINK_INPUT(o);
751
752 pa_assert(i);
753 pa_assert_ctl_context();
754 pa_assert(pa_sink_input_refcnt(i) == 0);
755 pa_assert(!PA_SINK_INPUT_IS_LINKED(i->state));
756
757 pa_log_info("Freeing input %u \"%s\"", i->index,
758 i->proplist ? pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)) : "");
759
760 /* Side note: this function must be able to destruct properly any
761 * kind of sink input in any state, even those which are
762 * "half-moved" or are connected to sinks that have no asyncmsgq
763 * and are hence half-destructed themselves! */
764
765 if (i->thread_info.render_memblockq)
766 pa_memblockq_free(i->thread_info.render_memblockq);
767
768 if (i->thread_info.resampler)
769 pa_resampler_free(i->thread_info.resampler);
770
771 if (i->format)
772 pa_format_info_free(i->format);
773
774 if (i->proplist)
775 pa_proplist_free(i->proplist);
776
777 if (i->direct_outputs)
778 pa_idxset_free(i->direct_outputs, NULL);
779
780 if (i->thread_info.direct_outputs)
781 pa_hashmap_free(i->thread_info.direct_outputs);
782
783 if (i->volume_factor_items)
784 pa_hashmap_free(i->volume_factor_items);
785
786 if (i->volume_factor_sink_items)
787 pa_hashmap_free(i->volume_factor_sink_items);
788
789 if (i->preferred_sink)
790 pa_xfree(i->preferred_sink);
791
792 pa_xfree(i->driver);
793 pa_xfree(i);
794 }
795
796 /* Called from main context */
pa_sink_input_put(pa_sink_input * i)797 void pa_sink_input_put(pa_sink_input *i) {
798 pa_sink_input_state_t state;
799
800 pa_sink_input_assert_ref(i);
801 pa_assert_ctl_context();
802
803 pa_assert(i->state == PA_SINK_INPUT_INIT);
804
805 /* The following fields must be initialized properly */
806 pa_assert(i->pop);
807 pa_assert(i->process_rewind);
808 pa_assert(i->kill);
809
810 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
811
812 update_n_corked(i, state);
813 i->state = state;
814
815 /* We might need to update the sink's volume if we are in flat volume mode. */
816 if (pa_sink_flat_volume_enabled(i->sink))
817 pa_sink_set_volume(i->sink, NULL, false, i->save_volume);
818 else {
819 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
820 pa_assert(pa_cvolume_is_norm(&i->volume));
821 pa_assert(pa_cvolume_is_norm(&i->reference_ratio));
822 }
823
824 set_real_ratio(i, &i->volume);
825 }
826
827 if (pa_sink_input_is_passthrough(i))
828 pa_sink_enter_passthrough(i->sink);
829
830 i->thread_info.soft_volume = i->soft_volume;
831 i->thread_info.muted = i->muted;
832
833 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
834
835 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
836 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
837
838 pa_sink_update_status(i->sink);
839 }
840
841 /* Called from main context */
pa_sink_input_kill(pa_sink_input * i)842 void pa_sink_input_kill(pa_sink_input*i) {
843 pa_sink_input_assert_ref(i);
844 pa_assert_ctl_context();
845 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
846
847 i->kill(i);
848 }
849
850 /* Called from main context */
pa_sink_input_get_latency(pa_sink_input * i,pa_usec_t * sink_latency)851 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
852 pa_usec_t r[2] = { 0, 0 };
853
854 pa_sink_input_assert_ref(i);
855 pa_assert_ctl_context();
856 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
857
858 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
859
860 if (i->get_latency)
861 r[0] += i->get_latency(i);
862
863 if (sink_latency)
864 *sink_latency = r[1];
865
866 return r[0];
867 }
868
869 /* Called from thread context */
pa_sink_input_peek(pa_sink_input * i,size_t slength,pa_memchunk * chunk,pa_cvolume * volume)870 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa_memchunk *chunk, pa_cvolume *volume) {
871 bool do_volume_adj_here, need_volume_factor_sink;
872 bool volume_is_norm;
873 size_t block_size_max_sink, block_size_max_sink_input;
874 size_t ilength;
875 size_t ilength_full;
876
877 pa_sink_input_assert_ref(i);
878 pa_sink_input_assert_io_context(i);
879 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
880 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
881 pa_assert(chunk);
882 pa_assert(volume);
883
884 #ifdef SINK_INPUT_DEBUG
885 pa_log_debug("peek");
886 #endif
887
888 block_size_max_sink_input = i->thread_info.resampler ?
889 pa_resampler_max_block_size(i->thread_info.resampler) :
890 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
891
892 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
893
894 /* Default buffer size */
895 if (slength <= 0)
896 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
897
898 if (slength > block_size_max_sink)
899 slength = block_size_max_sink;
900
901 if (i->thread_info.resampler) {
902 ilength = pa_resampler_request(i->thread_info.resampler, slength);
903
904 if (ilength <= 0)
905 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
906 } else
907 ilength = slength;
908
909 /* Length corresponding to slength (without limiting to
910 * block_size_max_sink_input). */
911 ilength_full = ilength;
912
913 if (ilength > block_size_max_sink_input)
914 ilength = block_size_max_sink_input;
915
916 /* If the channel maps of the sink and this stream differ, we need
917 * to adjust the volume *before* we resample. Otherwise we can do
918 * it after and leave it for the sink code */
919
920 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
921 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
922 need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
923
924 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
925 pa_memchunk tchunk;
926
927 /* There's nothing in our render queue. We need to fill it up
928 * with data from the implementor. */
929
930 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
931 i->pop(i, ilength, &tchunk) < 0) {
932
933 /* OK, we're corked or the implementor didn't give us any
934 * data, so let's just hand out silence */
935
936 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, true);
937 i->thread_info.playing_for = 0;
938 if (i->thread_info.underrun_for != (uint64_t) -1) {
939 i->thread_info.underrun_for += ilength_full;
940 i->thread_info.underrun_for_sink += slength;
941 }
942 break;
943 }
944
945 pa_assert(tchunk.length > 0);
946 pa_assert(tchunk.memblock);
947
948 i->thread_info.underrun_for = 0;
949 i->thread_info.underrun_for_sink = 0;
950 i->thread_info.playing_for += tchunk.length;
951
952 while (tchunk.length > 0) {
953 pa_memchunk wchunk;
954 bool nvfs = need_volume_factor_sink;
955
956 wchunk = tchunk;
957 pa_memblock_ref(wchunk.memblock);
958
959 if (wchunk.length > block_size_max_sink_input)
960 wchunk.length = block_size_max_sink_input;
961
962 /* It might be necessary to adjust the volume here */
963 if (do_volume_adj_here && !volume_is_norm) {
964 pa_memchunk_make_writable(&wchunk, 0);
965
966 if (i->thread_info.muted) {
967 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
968 nvfs = false;
969
970 } else if (!i->thread_info.resampler && nvfs) {
971 pa_cvolume v;
972
973 /* If we don't need a resampler we can merge the
974 * post and the pre volume adjustment into one */
975
976 pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
977 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
978 nvfs = false;
979
980 } else
981 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
982 }
983
984 if (!i->thread_info.resampler) {
985
986 if (nvfs) {
987 pa_memchunk_make_writable(&wchunk, 0);
988 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
989 }
990
991 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
992 } else {
993 pa_memchunk rchunk;
994 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
995
996 #ifdef SINK_INPUT_DEBUG
997 pa_log_debug("pushing %lu", (unsigned long) rchunk.length);
998 #endif
999
1000 if (rchunk.memblock) {
1001
1002 if (nvfs) {
1003 pa_memchunk_make_writable(&rchunk, 0);
1004 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
1005 }
1006
1007 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
1008 pa_memblock_unref(rchunk.memblock);
1009 }
1010 }
1011
1012 pa_memblock_unref(wchunk.memblock);
1013
1014 tchunk.index += wchunk.length;
1015 tchunk.length -= wchunk.length;
1016 }
1017
1018 pa_memblock_unref(tchunk.memblock);
1019 }
1020
1021 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
1022
1023 pa_assert(chunk->length > 0);
1024 pa_assert(chunk->memblock);
1025
1026 #ifdef SINK_INPUT_DEBUG
1027 pa_log_debug("peeking %lu", (unsigned long) chunk->length);
1028 #endif
1029
1030 if (chunk->length > block_size_max_sink)
1031 chunk->length = block_size_max_sink;
1032
1033 /* Let's see if we had to apply the volume adjustment ourselves,
1034 * or if this can be done by the sink for us */
1035
1036 if (do_volume_adj_here)
1037 /* We had different channel maps, so we already did the adjustment */
1038 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
1039 else if (i->thread_info.muted)
1040 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
1041 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
1042 else
1043 *volume = i->thread_info.soft_volume;
1044 }
1045
1046 /* Called from thread context */
pa_sink_input_drop(pa_sink_input * i,size_t nbytes)1047 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
1048
1049 pa_sink_input_assert_ref(i);
1050 pa_sink_input_assert_io_context(i);
1051 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1052 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1053 pa_assert(nbytes > 0);
1054
1055 #ifdef SINK_INPUT_DEBUG
1056 pa_log_debug("dropping %lu", (unsigned long) nbytes);
1057 #endif
1058
1059 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
1060 }
1061
1062 /* Called from thread context */
pa_sink_input_process_underrun(pa_sink_input * i)1063 bool pa_sink_input_process_underrun(pa_sink_input *i) {
1064 pa_sink_input_assert_ref(i);
1065 pa_sink_input_assert_io_context(i);
1066
1067 if (pa_memblockq_is_readable(i->thread_info.render_memblockq))
1068 return false;
1069
1070 if (i->process_underrun && i->process_underrun(i)) {
1071 /* All valid data has been played back, so we can empty this queue. */
1072 pa_memblockq_silence(i->thread_info.render_memblockq);
1073 return true;
1074 }
1075 return false;
1076 }
1077
1078 /* Called from thread context */
pa_sink_input_process_rewind(pa_sink_input * i,size_t nbytes)1079 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
1080 size_t lbq;
1081 bool called = false;
1082
1083 pa_sink_input_assert_ref(i);
1084 pa_sink_input_assert_io_context(i);
1085 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1086 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1087
1088 #ifdef SINK_INPUT_DEBUG
1089 pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes);
1090 #endif
1091
1092 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1093
1094 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
1095 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
1096 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
1097 }
1098
1099 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
1100
1101 /* We were asked to drop all buffered data, and rerequest new
1102 * data from implementor the next time peek() is called */
1103
1104 pa_memblockq_flush_write(i->thread_info.render_memblockq, true);
1105
1106 } else if (i->thread_info.rewrite_nbytes > 0) {
1107 size_t max_rewrite, amount;
1108
1109 /* Calculate how much make sense to rewrite at most */
1110 max_rewrite = nbytes;
1111 if (nbytes > 0)
1112 max_rewrite += lbq;
1113
1114 /* Transform into local domain */
1115 if (i->thread_info.resampler)
1116 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
1117
1118 /* Calculate how much of the rewinded data should actually be rewritten */
1119 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
1120
1121 if (amount > 0) {
1122 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
1123
1124 /* Tell the implementor */
1125 if (i->process_rewind)
1126 i->process_rewind(i, amount);
1127 called = true;
1128
1129 /* Convert back to sink domain */
1130 if (i->thread_info.resampler)
1131 amount = pa_resampler_result(i->thread_info.resampler, amount);
1132
1133 if (amount > 0)
1134 /* Ok, now update the write pointer */
1135 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, true);
1136
1137 if (i->thread_info.rewrite_flush)
1138 pa_memblockq_silence(i->thread_info.render_memblockq);
1139
1140 /* And rewind the resampler */
1141 if (i->thread_info.resampler)
1142 pa_resampler_rewind(i->thread_info.resampler, amount);
1143 }
1144 }
1145
1146 if (!called)
1147 if (i->process_rewind)
1148 i->process_rewind(i, 0);
1149
1150 i->thread_info.rewrite_nbytes = 0;
1151 i->thread_info.rewrite_flush = false;
1152 i->thread_info.dont_rewind_render = false;
1153 }
1154
1155 /* Called from thread context */
pa_sink_input_get_max_rewind(pa_sink_input * i)1156 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
1157 pa_sink_input_assert_ref(i);
1158 pa_sink_input_assert_io_context(i);
1159
1160 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
1161 }
1162
1163 /* Called from thread context */
pa_sink_input_get_max_request(pa_sink_input * i)1164 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
1165 pa_sink_input_assert_ref(i);
1166 pa_sink_input_assert_io_context(i);
1167
1168 /* We're not verifying the status here, to allow this to be called
1169 * in the state change handler between _INIT and _RUNNING */
1170
1171 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
1172 }
1173
1174 /* Called from thread context */
pa_sink_input_update_max_rewind(pa_sink_input * i,size_t nbytes)1175 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1176 pa_sink_input_assert_ref(i);
1177 pa_sink_input_assert_io_context(i);
1178 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1179 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1180
1181 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
1182
1183 if (i->update_max_rewind)
1184 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1185 }
1186
1187 /* Called from thread context */
pa_sink_input_update_max_request(pa_sink_input * i,size_t nbytes)1188 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
1189 pa_sink_input_assert_ref(i);
1190 pa_sink_input_assert_io_context(i);
1191 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
1192 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
1193
1194 if (i->update_max_request)
1195 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
1196 }
1197
1198 /* Called from thread context */
pa_sink_input_set_requested_latency_within_thread(pa_sink_input * i,pa_usec_t usec)1199 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
1200 pa_sink_input_assert_ref(i);
1201 pa_sink_input_assert_io_context(i);
1202
1203 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1204 usec = i->sink->thread_info.fixed_latency;
1205
1206 if (usec != (pa_usec_t) -1)
1207 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
1208
1209 i->thread_info.requested_sink_latency = usec;
1210 pa_sink_invalidate_requested_latency(i->sink, true);
1211
1212 return usec;
1213 }
1214
1215 /* Called from main context */
pa_sink_input_set_requested_latency(pa_sink_input * i,pa_usec_t usec)1216 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
1217 pa_sink_input_assert_ref(i);
1218 pa_assert_ctl_context();
1219
1220 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1221 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1222 return usec;
1223 }
1224
1225 /* If this sink input is not realized yet or we are being moved,
1226 * we have to touch the thread info data directly */
1227
1228 if (i->sink) {
1229 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
1230 usec = pa_sink_get_fixed_latency(i->sink);
1231
1232 if (usec != (pa_usec_t) -1) {
1233 pa_usec_t min_latency, max_latency;
1234 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
1235 usec = PA_CLAMP(usec, min_latency, max_latency);
1236 }
1237 }
1238
1239 i->thread_info.requested_sink_latency = usec;
1240
1241 return usec;
1242 }
1243
1244 /* Called from main context */
pa_sink_input_get_requested_latency(pa_sink_input * i)1245 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
1246 pa_sink_input_assert_ref(i);
1247 pa_assert_ctl_context();
1248
1249 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
1250 pa_usec_t usec = 0;
1251 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1252 return usec;
1253 }
1254
1255 /* If this sink input is not realized yet or we are being moved,
1256 * we have to touch the thread info data directly */
1257
1258 return i->thread_info.requested_sink_latency;
1259 }
1260
1261 /* Called from main context */
pa_sink_input_set_volume(pa_sink_input * i,const pa_cvolume * volume,bool save,bool absolute)1262 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, bool save, bool absolute) {
1263 pa_cvolume v;
1264
1265 pa_sink_input_assert_ref(i);
1266 pa_assert_ctl_context();
1267 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1268 pa_assert(volume);
1269 pa_assert(pa_cvolume_valid(volume));
1270 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1271 pa_assert(i->volume_writable);
1272
1273 if (!absolute && pa_sink_flat_volume_enabled(i->sink)) {
1274 v = i->sink->reference_volume;
1275 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1276
1277 if (pa_cvolume_compatible(volume, &i->sample_spec))
1278 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1279 else
1280 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1281 } else {
1282 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1283 v = i->volume;
1284 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1285 }
1286 }
1287
1288 if (pa_cvolume_equal(volume, &i->volume)) {
1289 i->save_volume = i->save_volume || save;
1290 return;
1291 }
1292
1293 pa_sink_input_set_volume_direct(i, volume);
1294 i->save_volume = save;
1295
1296 if (pa_sink_flat_volume_enabled(i->sink)) {
1297 /* We are in flat volume mode, so let's update all sink input
1298 * volumes and update the flat volume of the sink */
1299
1300 pa_sink_set_volume(i->sink, NULL, true, save);
1301
1302 } else {
1303 /* OK, we are in normal volume mode. The volume only affects
1304 * ourselves */
1305 set_real_ratio(i, volume);
1306 pa_sink_input_set_reference_ratio(i, &i->volume);
1307
1308 /* Copy the new soft_volume to the thread_info struct */
1309 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1310 }
1311 }
1312
pa_sink_input_add_volume_factor(pa_sink_input * i,const char * key,const pa_cvolume * volume_factor)1313 void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor) {
1314 struct volume_factor_entry *v;
1315
1316 pa_sink_input_assert_ref(i);
1317 pa_assert_ctl_context();
1318 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1319 pa_assert(volume_factor);
1320 pa_assert(key);
1321 pa_assert(pa_cvolume_valid(volume_factor));
1322 pa_assert(volume_factor->channels == 1 || pa_cvolume_compatible(volume_factor, &i->sample_spec));
1323
1324 v = volume_factor_entry_new(key, volume_factor);
1325 if (!pa_cvolume_compatible(volume_factor, &i->sample_spec))
1326 pa_cvolume_set(&v->volume, i->sample_spec.channels, volume_factor->values[0]);
1327
1328 pa_assert_se(pa_hashmap_put(i->volume_factor_items, v->key, v) >= 0);
1329 if (pa_hashmap_size(i->volume_factor_items) == 1)
1330 i->volume_factor = v->volume;
1331 else
1332 pa_sw_cvolume_multiply(&i->volume_factor, &i->volume_factor, &v->volume);
1333
1334 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1335
1336 /* Copy the new soft_volume to the thread_info struct */
1337 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1338 }
1339
1340 /* Returns 0 if an entry was removed and -1 if no entry for the given key was
1341 * found. */
pa_sink_input_remove_volume_factor(pa_sink_input * i,const char * key)1342 int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
1343 struct volume_factor_entry *v;
1344
1345 pa_sink_input_assert_ref(i);
1346 pa_assert(key);
1347 pa_assert_ctl_context();
1348 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1349
1350 if (pa_hashmap_remove_and_free(i->volume_factor_items, key) < 0)
1351 return -1;
1352
1353 switch (pa_hashmap_size(i->volume_factor_items)) {
1354 case 0:
1355 pa_cvolume_reset(&i->volume_factor, i->sample_spec.channels);
1356 break;
1357 case 1:
1358 v = pa_hashmap_first(i->volume_factor_items);
1359 i->volume_factor = v->volume;
1360 break;
1361 default:
1362 volume_factor_from_hashmap(&i->volume_factor, i->volume_factor_items, i->volume_factor.channels);
1363 }
1364
1365 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1366
1367 /* Copy the new soft_volume to the thread_info struct */
1368 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1369
1370 return 0;
1371 }
1372
1373 /* Called from main context */
set_real_ratio(pa_sink_input * i,const pa_cvolume * v)1374 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1375 pa_sink_input_assert_ref(i);
1376 pa_assert_ctl_context();
1377 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1378 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1379
1380 /* This basically calculates:
1381 *
1382 * i->real_ratio := v
1383 * i->soft_volume := i->real_ratio * i->volume_factor */
1384
1385 if (v)
1386 i->real_ratio = *v;
1387 else
1388 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1389
1390 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1391 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1392 }
1393
1394 /* Called from main or I/O context */
pa_sink_input_is_passthrough(pa_sink_input * i)1395 bool pa_sink_input_is_passthrough(pa_sink_input *i) {
1396 pa_sink_input_assert_ref(i);
1397
1398 if (PA_UNLIKELY(!pa_format_info_is_pcm(i->format)))
1399 return true;
1400
1401 if (PA_UNLIKELY(i->flags & PA_SINK_INPUT_PASSTHROUGH))
1402 return true;
1403
1404 return false;
1405 }
1406
1407 /* Called from main context */
pa_sink_input_is_volume_readable(pa_sink_input * i)1408 bool pa_sink_input_is_volume_readable(pa_sink_input *i) {
1409 pa_sink_input_assert_ref(i);
1410 pa_assert_ctl_context();
1411
1412 return !pa_sink_input_is_passthrough(i);
1413 }
1414
1415 /* Called from main context */
pa_sink_input_get_volume(pa_sink_input * i,pa_cvolume * volume,bool absolute)1416 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute) {
1417 pa_sink_input_assert_ref(i);
1418 pa_assert_ctl_context();
1419 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1420 pa_assert(pa_sink_input_is_volume_readable(i));
1421
1422 if (absolute || !pa_sink_flat_volume_enabled(i->sink))
1423 *volume = i->volume;
1424 else
1425 *volume = i->reference_ratio;
1426
1427 return volume;
1428 }
1429
1430 /* Called from main context */
pa_sink_input_set_mute(pa_sink_input * i,bool mute,bool save)1431 void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save) {
1432 bool old_mute;
1433
1434 pa_sink_input_assert_ref(i);
1435 pa_assert_ctl_context();
1436 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1437
1438 old_mute = i->muted;
1439
1440 if (mute == old_mute) {
1441 i->save_muted |= save;
1442 return;
1443 }
1444
1445 i->muted = mute;
1446 pa_log_debug("The mute of sink input %u changed from %s to %s.", i->index, pa_yes_no(old_mute), pa_yes_no(mute));
1447
1448 i->save_muted = save;
1449
1450 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1451
1452 /* The mute status changed, let's tell people so */
1453 if (i->mute_changed)
1454 i->mute_changed(i);
1455
1456 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1457 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MUTE_CHANGED], i);
1458 }
1459
pa_sink_input_set_property(pa_sink_input * i,const char * key,const char * value)1460 void pa_sink_input_set_property(pa_sink_input *i, const char *key, const char *value) {
1461 char *old_value = NULL;
1462 const char *new_value;
1463
1464 pa_assert(i);
1465 pa_assert(key);
1466
1467 if (pa_proplist_contains(i->proplist, key)) {
1468 old_value = pa_xstrdup(pa_proplist_gets(i->proplist, key));
1469 if (value && old_value && pa_streq(value, old_value))
1470 goto finish;
1471
1472 if (!old_value)
1473 old_value = pa_xstrdup("(data)");
1474 } else {
1475 if (!value)
1476 goto finish;
1477
1478 old_value = pa_xstrdup("(unset)");
1479 }
1480
1481 if (value) {
1482 pa_proplist_sets(i->proplist, key, value);
1483 new_value = value;
1484 } else {
1485 pa_proplist_unset(i->proplist, key);
1486 new_value = "(unset)";
1487 }
1488
1489 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1490 pa_log_debug("Sink input %u: proplist[%s]: %s -> %s", i->index, key, old_value, new_value);
1491 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1492 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1493 }
1494
1495 finish:
1496 pa_xfree(old_value);
1497 }
1498
pa_sink_input_set_property_arbitrary(pa_sink_input * i,const char * key,const uint8_t * value,size_t nbytes)1499 void pa_sink_input_set_property_arbitrary(pa_sink_input *i, const char *key, const uint8_t *value, size_t nbytes) {
1500 const uint8_t *old_value;
1501 size_t old_nbytes;
1502 const char *old_value_str;
1503 const char *new_value_str;
1504
1505 pa_assert(i);
1506 pa_assert(key);
1507
1508 if (pa_proplist_get(i->proplist, key, (const void **) &old_value, &old_nbytes) >= 0) {
1509 if (value && nbytes == old_nbytes && !memcmp(value, old_value, nbytes))
1510 return;
1511
1512 old_value_str = "(data)";
1513
1514 } else {
1515 if (!value)
1516 return;
1517
1518 old_value_str = "(unset)";
1519 }
1520
1521 if (value) {
1522 pa_proplist_set(i->proplist, key, value, nbytes);
1523 new_value_str = "(data)";
1524 } else {
1525 pa_proplist_unset(i->proplist, key);
1526 new_value_str = "(unset)";
1527 }
1528
1529 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1530 pa_log_debug("Sink input %u: proplist[%s]: %s -> %s", i->index, key, old_value_str, new_value_str);
1531 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1532 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1533 }
1534 }
1535
1536 /* Called from main thread */
pa_sink_input_update_proplist(pa_sink_input * i,pa_update_mode_t mode,pa_proplist * p)1537 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1538 void *state;
1539 const char *key;
1540 const uint8_t *value;
1541 size_t nbytes;
1542
1543 pa_sink_input_assert_ref(i);
1544 pa_assert(p);
1545 pa_assert_ctl_context();
1546
1547 switch (mode) {
1548 case PA_UPDATE_SET:
1549 /* Delete everything that is not in p. */
1550 for (state = NULL; (key = pa_proplist_iterate(i->proplist, &state));) {
1551 if (!pa_proplist_contains(p, key))
1552 pa_sink_input_set_property(i, key, NULL);
1553 }
1554
1555 /* Fall through. */
1556 case PA_UPDATE_REPLACE:
1557 for (state = NULL; (key = pa_proplist_iterate(p, &state));) {
1558 pa_proplist_get(p, key, (const void **) &value, &nbytes);
1559 pa_sink_input_set_property_arbitrary(i, key, value, nbytes);
1560 }
1561
1562 break;
1563 case PA_UPDATE_MERGE:
1564 for (state = NULL; (key = pa_proplist_iterate(p, &state));) {
1565 if (pa_proplist_contains(i->proplist, key))
1566 continue;
1567
1568 pa_proplist_get(p, key, (const void **) &value, &nbytes);
1569 pa_sink_input_set_property_arbitrary(i, key, value, nbytes);
1570 }
1571
1572 break;
1573 }
1574 }
1575
1576 /* Called from main context */
pa_sink_input_cork(pa_sink_input * i,bool b)1577 void pa_sink_input_cork(pa_sink_input *i, bool b) {
1578 pa_sink_input_assert_ref(i);
1579 pa_assert_ctl_context();
1580 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1581
1582 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1583 }
1584
1585 /* Called from main context */
pa_sink_input_set_rate(pa_sink_input * i,uint32_t rate)1586 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1587 pa_sink_input_assert_ref(i);
1588 pa_assert_ctl_context();
1589 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1590 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1591
1592 if (i->sample_spec.rate == rate)
1593 return 0;
1594
1595 i->sample_spec.rate = rate;
1596
1597 if (i->sink)
1598 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1599 else {
1600 i->thread_info.sample_spec.rate = rate;
1601 pa_resampler_set_input_rate(i->thread_info.resampler, rate);
1602 }
1603
1604 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1605 return 0;
1606 }
1607
1608 /* Called from main context */
pa_sink_input_get_resample_method(pa_sink_input * i)1609 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1610 pa_sink_input_assert_ref(i);
1611 pa_assert_ctl_context();
1612
1613 return i->actual_resample_method;
1614 }
1615
1616 /* Called from main context */
pa_sink_input_may_move(pa_sink_input * i)1617 bool pa_sink_input_may_move(pa_sink_input *i) {
1618 pa_sink_input_assert_ref(i);
1619 pa_assert_ctl_context();
1620 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1621
1622 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1623 return false;
1624
1625 if (i->sync_next || i->sync_prev) {
1626 pa_log_warn("Moving synchronized streams not supported.");
1627 return false;
1628 }
1629
1630 return true;
1631 }
1632
find_filter_sink_input(pa_sink_input * target,pa_sink * s)1633 static bool find_filter_sink_input(pa_sink_input *target, pa_sink *s) {
1634 unsigned PA_UNUSED i = 0;
1635 while (s && s->input_to_master) {
1636 if (s->input_to_master == target)
1637 return true;
1638 s = s->input_to_master->sink;
1639 pa_assert(i++ < 100);
1640 }
1641 return false;
1642 }
1643
is_filter_sink_moving(pa_sink_input * i)1644 static bool is_filter_sink_moving(pa_sink_input *i) {
1645 pa_sink *sink = i->sink;
1646
1647 if (!sink)
1648 return false;
1649
1650 while (sink->input_to_master) {
1651 sink = sink->input_to_master->sink;
1652
1653 if (!sink)
1654 return true;
1655 }
1656
1657 return false;
1658 }
1659
1660 /* Called from main context */
pa_sink_input_may_move_to(pa_sink_input * i,pa_sink * dest)1661 bool pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1662 pa_sink_input_assert_ref(i);
1663 pa_assert_ctl_context();
1664 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1665 pa_sink_assert_ref(dest);
1666
1667 if (dest == i->sink)
1668 return true;
1669
1670 if (dest->unlink_requested)
1671 return false;
1672
1673 if (!pa_sink_input_may_move(i))
1674 return false;
1675
1676 /* Make sure we're not creating a filter sink cycle */
1677 if (find_filter_sink_input(i, dest)) {
1678 pa_log_debug("Can't connect input to %s, as that would create a cycle.", dest->name);
1679 return false;
1680 }
1681
1682 /* If this sink input is connected to a filter sink that itself is moving,
1683 * then don't allow the move. Moving requires sending a message to the IO
1684 * thread of the old sink, and if the old sink is a filter sink that is
1685 * moving, there's no IO thread associated to the old sink. */
1686 if (is_filter_sink_moving(i)) {
1687 pa_log_debug("Can't move input from filter sink %s, because the filter sink itself is currently moving.",
1688 i->sink->name);
1689 return false;
1690 }
1691
1692 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1693 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1694 return false;
1695 }
1696
1697 if (check_passthrough_connection(pa_sink_input_is_passthrough(i), dest) < 0)
1698 return false;
1699
1700 if (i->may_move_to)
1701 if (!i->may_move_to(i, dest))
1702 return false;
1703
1704 return true;
1705 }
1706
1707 /* Called from main context */
pa_sink_input_start_move(pa_sink_input * i)1708 int pa_sink_input_start_move(pa_sink_input *i) {
1709 pa_source_output *o, PA_UNUSED *p = NULL;
1710 struct volume_factor_entry *v;
1711 void *state = NULL;
1712 int r;
1713
1714 pa_sink_input_assert_ref(i);
1715 pa_assert_ctl_context();
1716 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1717 pa_assert(i->sink);
1718
1719 if (!pa_sink_input_may_move(i))
1720 return -PA_ERR_NOTSUPPORTED;
1721
1722 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1723 return r;
1724
1725 pa_log_debug("Starting to move sink input %u from '%s'", (unsigned) i->index, i->sink->name);
1726
1727 /* Kill directly connected outputs */
1728 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1729 pa_assert(o != p);
1730 pa_source_output_kill(o);
1731 p = o;
1732 }
1733 pa_assert(pa_idxset_isempty(i->direct_outputs));
1734
1735 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1736
1737 if (i->state == PA_SINK_INPUT_CORKED)
1738 pa_assert_se(i->sink->n_corked-- >= 1);
1739
1740 if (pa_sink_input_is_passthrough(i))
1741 pa_sink_leave_passthrough(i->sink);
1742
1743 if (pa_sink_flat_volume_enabled(i->sink))
1744 /* We might need to update the sink's volume if we are in flat
1745 * volume mode. */
1746 pa_sink_set_volume(i->sink, NULL, false, false);
1747
1748 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1749
1750 pa_sink_update_status(i->sink);
1751
1752 PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
1753 pa_cvolume_remap(&v->volume, &i->sink->channel_map, &i->channel_map);
1754
1755 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1756
1757 i->sink = NULL;
1758 i->sink_requested_by_application = false;
1759
1760 pa_sink_input_unref(i);
1761
1762 return 0;
1763 }
1764
1765 /* Called from main context. If i has an origin sink that uses volume sharing,
1766 * then also the origin sink and all streams connected to it need to update
1767 * their volume - this function does all that by using recursion. */
update_volume_due_to_moving(pa_sink_input * i,pa_sink * dest)1768 static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
1769 pa_cvolume new_volume;
1770
1771 pa_assert(i);
1772 pa_assert(dest);
1773 pa_assert(i->sink); /* The destination sink should already be set. */
1774
1775 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1776 pa_sink *root_sink = pa_sink_get_master(i->sink);
1777 pa_sink_input *origin_sink_input;
1778 uint32_t idx;
1779
1780 if (PA_UNLIKELY(!root_sink))
1781 return;
1782
1783 if (pa_sink_flat_volume_enabled(i->sink)) {
1784 /* Ok, so the origin sink uses volume sharing, and flat volume is
1785 * enabled. The volume will have to be updated as follows:
1786 *
1787 * i->volume := i->sink->real_volume
1788 * (handled later by pa_sink_set_volume)
1789 * i->reference_ratio := i->volume / i->sink->reference_volume
1790 * (handled later by pa_sink_set_volume)
1791 * i->real_ratio stays unchanged
1792 * (streams whose origin sink uses volume sharing should
1793 * always have real_ratio of 0 dB)
1794 * i->soft_volume stays unchanged
1795 * (streams whose origin sink uses volume sharing should
1796 * always have volume_factor as soft_volume, so no change
1797 * should be needed) */
1798
1799 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1800 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1801
1802 /* Notifications will be sent by pa_sink_set_volume(). */
1803
1804 } else {
1805 /* Ok, so the origin sink uses volume sharing, and flat volume is
1806 * disabled. The volume will have to be updated as follows:
1807 *
1808 * i->volume := 0 dB
1809 * i->reference_ratio := 0 dB
1810 * i->real_ratio stays unchanged
1811 * (streams whose origin sink uses volume sharing should
1812 * always have real_ratio of 0 dB)
1813 * i->soft_volume stays unchanged
1814 * (streams whose origin sink uses volume sharing should
1815 * always have volume_factor as soft_volume, so no change
1816 * should be needed) */
1817
1818 pa_cvolume_reset(&new_volume, i->volume.channels);
1819 pa_sink_input_set_volume_direct(i, &new_volume);
1820 pa_sink_input_set_reference_ratio(i, &new_volume);
1821 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1822 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1823 }
1824
1825 /* Additionally, the origin sink volume needs updating:
1826 *
1827 * i->origin_sink->reference_volume := root_sink->reference_volume
1828 * i->origin_sink->real_volume := root_sink->real_volume
1829 * i->origin_sink->soft_volume stays unchanged
1830 * (sinks that use volume sharing should always have
1831 * soft_volume of 0 dB) */
1832
1833 new_volume = root_sink->reference_volume;
1834 pa_cvolume_remap(&new_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1835 pa_sink_set_reference_volume_direct(i->origin_sink, &new_volume);
1836
1837 i->origin_sink->real_volume = root_sink->real_volume;
1838 pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1839
1840 pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
1841
1842 /* If you wonder whether i->origin_sink->set_volume() should be called
1843 * somewhere, that's not the case, because sinks that use volume
1844 * sharing shouldn't have any internal volume that set_volume() would
1845 * update. If you wonder whether the thread_info variables should be
1846 * synced, yes, they should, and it's done by the
1847 * PA_SINK_MESSAGE_FINISH_MOVE message handler. */
1848
1849 /* Recursively update origin sink inputs. */
1850 PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
1851 update_volume_due_to_moving(origin_sink_input, dest);
1852
1853 } else {
1854 if (pa_sink_flat_volume_enabled(i->sink)) {
1855 /* Ok, so this is a regular stream, and flat volume is enabled. The
1856 * volume will have to be updated as follows:
1857 *
1858 * i->volume := i->reference_ratio * i->sink->reference_volume
1859 * i->reference_ratio stays unchanged
1860 * i->real_ratio := i->volume / i->sink->real_volume
1861 * (handled later by pa_sink_set_volume)
1862 * i->soft_volume := i->real_ratio * i->volume_factor
1863 * (handled later by pa_sink_set_volume) */
1864
1865 new_volume = i->sink->reference_volume;
1866 pa_cvolume_remap(&new_volume, &i->sink->channel_map, &i->channel_map);
1867 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
1868 pa_sink_input_set_volume_direct(i, &new_volume);
1869
1870 } else {
1871 /* Ok, so this is a regular stream, and flat volume is disabled.
1872 * The volume will have to be updated as follows:
1873 *
1874 * i->volume := i->reference_ratio
1875 * i->reference_ratio stays unchanged
1876 * i->real_ratio := i->reference_ratio
1877 * i->soft_volume := i->real_ratio * i->volume_factor */
1878
1879 pa_sink_input_set_volume_direct(i, &i->reference_ratio);
1880 i->real_ratio = i->reference_ratio;
1881 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1882 }
1883 }
1884
1885 /* If i->sink == dest, then recursion has finished, and we can finally call
1886 * pa_sink_set_volume(), which will do the rest of the updates. */
1887 if ((i->sink == dest) && pa_sink_flat_volume_enabled(i->sink))
1888 pa_sink_set_volume(i->sink, NULL, false, i->save_volume);
1889 }
1890
1891 /* Called from main context */
pa_sink_input_finish_move(pa_sink_input * i,pa_sink * dest,bool save)1892 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) {
1893 struct volume_factor_entry *v;
1894 void *state = NULL;
1895
1896 pa_sink_input_assert_ref(i);
1897 pa_assert_ctl_context();
1898 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1899 pa_assert(!i->sink);
1900 pa_sink_assert_ref(dest);
1901
1902 if (!pa_sink_input_may_move_to(i, dest))
1903 return -PA_ERR_NOTSUPPORTED;
1904
1905 if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
1906 pa_proplist *p = pa_proplist_new();
1907 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
1908 /* Tell the client what device we want to be on if it is going to
1909 * reconnect */
1910 pa_proplist_sets(p, "device", dest->name);
1911 pa_sink_input_send_event(i, PA_STREAM_EVENT_FORMAT_LOST, p);
1912 pa_proplist_free(p);
1913 return -PA_ERR_NOTSUPPORTED;
1914 }
1915
1916 if (!(i->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
1917 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec)) {
1918 /* try to change dest sink format and rate if possible without glitches.
1919 module-suspend-on-idle resumes destination sink with
1920 SINK_INPUT_MOVE_FINISH hook */
1921
1922 pa_log_info("Trying to change sample spec");
1923 pa_sink_reconfigure(dest, &i->sample_spec, pa_sink_input_is_passthrough(i));
1924 }
1925
1926 if (i->moving)
1927 i->moving(i, dest);
1928
1929 i->sink = dest;
1930 /* save == true, means user is calling the move_to() and want to
1931 save the preferred_sink */
1932 if (save) {
1933 pa_xfree(i->preferred_sink);
1934 if (dest == dest->core->default_sink)
1935 i->preferred_sink = NULL;
1936 else
1937 i->preferred_sink = pa_xstrdup(dest->name);
1938 }
1939
1940 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1941
1942 PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
1943 pa_cvolume_remap(&v->volume, &i->channel_map, &i->sink->channel_map);
1944
1945 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1946
1947 if (i->state == PA_SINK_INPUT_CORKED)
1948 i->sink->n_corked++;
1949
1950 pa_sink_input_update_resampler(i);
1951
1952 pa_sink_update_status(dest);
1953
1954 update_volume_due_to_moving(i, dest);
1955
1956 if (pa_sink_input_is_passthrough(i))
1957 pa_sink_enter_passthrough(i->sink);
1958
1959 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1960
1961 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1962
1963 /* Notify everyone */
1964 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1965 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1966
1967 return 0;
1968 }
1969
1970 /* Called from main context */
pa_sink_input_fail_move(pa_sink_input * i)1971 void pa_sink_input_fail_move(pa_sink_input *i) {
1972
1973 pa_sink_input_assert_ref(i);
1974 pa_assert_ctl_context();
1975 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1976 pa_assert(!i->sink);
1977
1978 /* Check if someone wants this sink input? */
1979 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1980 return;
1981
1982 /* Can we move the sink input to the default sink? */
1983 if (i->core->rescue_streams && pa_sink_input_may_move_to(i, i->core->default_sink)) {
1984 if (pa_sink_input_finish_move(i, i->core->default_sink, false) >= 0)
1985 return;
1986 }
1987
1988 if (i->moving)
1989 i->moving(i, NULL);
1990
1991 pa_sink_input_kill(i);
1992 }
1993
1994 /* Called from main context */
pa_sink_input_move_to(pa_sink_input * i,pa_sink * dest,bool save)1995 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, bool save) {
1996 int r;
1997
1998 pa_sink_input_assert_ref(i);
1999 pa_assert_ctl_context();
2000 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
2001 pa_assert(i->sink);
2002 pa_sink_assert_ref(dest);
2003
2004 if (dest == i->sink)
2005 return 0;
2006
2007 if (!pa_sink_input_may_move_to(i, dest))
2008 return -PA_ERR_NOTSUPPORTED;
2009
2010 pa_sink_input_ref(i);
2011
2012 if ((r = pa_sink_input_start_move(i)) < 0) {
2013 pa_sink_input_unref(i);
2014 return r;
2015 }
2016
2017 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
2018 pa_sink_input_fail_move(i);
2019 pa_sink_input_unref(i);
2020 return r;
2021 }
2022
2023 pa_sink_input_unref(i);
2024
2025 return 0;
2026 }
2027
2028 /* Called from IO thread context except when cork() is called without a valid sink. */
pa_sink_input_set_state_within_thread(pa_sink_input * i,pa_sink_input_state_t state)2029 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
2030 bool corking, uncorking;
2031
2032 pa_sink_input_assert_ref(i);
2033
2034 if (state == i->thread_info.state)
2035 return;
2036
2037 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
2038 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2039
2040 if (i->state_change)
2041 i->state_change(i, state);
2042
2043 if (corking) {
2044
2045 pa_log_debug("Requesting rewind due to corking");
2046
2047 /* This will tell the implementing sink input driver to rewind
2048 * so that the unplayed already mixed data is not lost */
2049 if (i->sink)
2050 pa_sink_input_request_rewind(i, 0, true, true, false);
2051
2052 /* Set the corked state *after* requesting rewind */
2053 i->thread_info.state = state;
2054
2055 } else if (uncorking) {
2056
2057 pa_log_debug("Requesting rewind due to uncorking");
2058
2059 i->thread_info.underrun_for = (uint64_t) -1;
2060 i->thread_info.underrun_for_sink = 0;
2061 i->thread_info.playing_for = 0;
2062
2063 /* Set the uncorked state *before* requesting rewind */
2064 i->thread_info.state = state;
2065
2066 /* OK, we're being uncorked. Make sure we're not rewound when
2067 * the hw buffer is remixed and request a remix. */
2068 if (i->sink)
2069 pa_sink_input_request_rewind(i, 0, false, true, true);
2070 } else
2071 /* We may not be corking or uncorking, but we still need to set the state. */
2072 i->thread_info.state = state;
2073 }
2074
2075 /* Called from thread context, except when it is not. */
pa_sink_input_process_msg(pa_msgobject * o,int code,void * userdata,int64_t offset,pa_memchunk * chunk)2076 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2077 pa_sink_input *i = PA_SINK_INPUT(o);
2078 pa_sink_input_assert_ref(i);
2079
2080 switch (code) {
2081
2082 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
2083 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
2084 i->thread_info.soft_volume = i->soft_volume;
2085 pa_sink_input_request_rewind(i, 0, true, false, false);
2086 }
2087 return 0;
2088
2089 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
2090 if (i->thread_info.muted != i->muted) {
2091 i->thread_info.muted = i->muted;
2092 pa_sink_input_request_rewind(i, 0, true, false, false);
2093 }
2094 return 0;
2095
2096 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
2097 pa_usec_t *r = userdata;
2098
2099 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
2100 r[1] += pa_sink_get_latency_within_thread(i->sink, false);
2101
2102 return 0;
2103 }
2104
2105 case PA_SINK_INPUT_MESSAGE_SET_RATE:
2106
2107 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
2108 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
2109
2110 return 0;
2111
2112 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
2113 pa_sink_input *ssync;
2114
2115 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
2116
2117 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
2118 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
2119
2120 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
2121 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
2122
2123 return 0;
2124 }
2125
2126 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
2127 pa_usec_t *usec = userdata;
2128
2129 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
2130 return 0;
2131 }
2132
2133 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
2134 pa_usec_t *r = userdata;
2135
2136 *r = i->thread_info.requested_sink_latency;
2137 return 0;
2138 }
2139 }
2140
2141 return -PA_ERR_NOTIMPLEMENTED;
2142 }
2143
2144 /* Called from IO context */
pa_sink_input_safe_to_remove(pa_sink_input * i)2145 bool pa_sink_input_safe_to_remove(pa_sink_input *i) {
2146 pa_sink_input_assert_ref(i);
2147 pa_sink_input_assert_io_context(i);
2148
2149 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
2150 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
2151
2152 return true;
2153 }
2154
2155 /* Called from IO context */
pa_sink_input_request_rewind(pa_sink_input * i,size_t nbytes,bool rewrite,bool flush,bool dont_rewind_render)2156 void pa_sink_input_request_rewind(
2157 pa_sink_input *i,
2158 size_t nbytes /* in our sample spec */,
2159 bool rewrite, /* rewrite what we have, or get fresh data? */
2160 bool flush, /* flush render memblockq? */
2161 bool dont_rewind_render) {
2162
2163 size_t lbq;
2164
2165 /* If 'rewrite' is true the sink is rewound as far as requested
2166 * and possible and the exact value of this is passed back the
2167 * implementor via process_rewind(). If 'flush' is also true all
2168 * already rendered data is also dropped.
2169 *
2170 * If 'rewrite' is false the sink is rewound as far as requested
2171 * and possible and the already rendered data is dropped so that
2172 * in the next iteration we read new data from the
2173 * implementor. This implies 'flush' is true. If
2174 * dont_rewind_render is true then the render memblockq is not
2175 * rewound. */
2176
2177 /* nbytes = 0 means maximum rewind request */
2178
2179 pa_sink_input_assert_ref(i);
2180 pa_sink_input_assert_io_context(i);
2181 pa_assert(rewrite || flush);
2182 pa_assert(!dont_rewind_render || !rewrite);
2183
2184 /* We don't take rewind requests while we are corked */
2185 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
2186 return;
2187
2188 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
2189
2190 #ifdef SINK_INPUT_DEBUG
2191 pa_log_debug("request rewrite %zu", nbytes);
2192 #endif
2193
2194 /* Calculate how much we can rewind locally without having to
2195 * touch the sink */
2196 if (rewrite)
2197 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
2198 else
2199 lbq = 0;
2200
2201 /* Check if rewinding for the maximum is requested, and if so, fix up */
2202 if (nbytes <= 0) {
2203
2204 /* Calculate maximum number of bytes that could be rewound in theory */
2205 nbytes = i->sink->thread_info.max_rewind + lbq;
2206
2207 /* Transform from sink domain */
2208 if (i->thread_info.resampler)
2209 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
2210 }
2211
2212 /* Remember how much we actually want to rewrite */
2213 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
2214 if (rewrite) {
2215 /* Make sure to not overwrite over underruns */
2216 if (nbytes > i->thread_info.playing_for)
2217 nbytes = (size_t) i->thread_info.playing_for;
2218
2219 i->thread_info.rewrite_nbytes = nbytes;
2220 } else
2221 i->thread_info.rewrite_nbytes = (size_t) -1;
2222 }
2223
2224 i->thread_info.rewrite_flush =
2225 i->thread_info.rewrite_flush || flush;
2226
2227 i->thread_info.dont_rewind_render =
2228 i->thread_info.dont_rewind_render ||
2229 dont_rewind_render;
2230
2231 /* nbytes is -1 if some earlier rewind request had rewrite == false. */
2232 if (nbytes != (size_t) -1) {
2233
2234 /* Transform to sink domain */
2235 if (i->thread_info.resampler)
2236 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
2237
2238 if (nbytes > lbq)
2239 pa_sink_request_rewind(i->sink, nbytes - lbq);
2240 else
2241 /* This call will make sure process_rewind() is called later */
2242 pa_sink_request_rewind(i->sink, 0);
2243 }
2244 }
2245
2246 /* Called from main context */
pa_sink_input_get_silence(pa_sink_input * i,pa_memchunk * ret)2247 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
2248 pa_sink_input_assert_ref(i);
2249 pa_assert_ctl_context();
2250 pa_assert(ret);
2251
2252 /* FIXME: Shouldn't access resampler object from main context! */
2253
2254 pa_silence_memchunk_get(
2255 &i->core->silence_cache,
2256 i->core->mempool,
2257 ret,
2258 &i->sample_spec,
2259 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
2260
2261 return ret;
2262 }
2263
2264 /* Called from main context */
pa_sink_input_send_event(pa_sink_input * i,const char * event,pa_proplist * data)2265 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
2266 pa_proplist *pl = NULL;
2267 pa_sink_input_send_event_hook_data hook_data;
2268
2269 pa_sink_input_assert_ref(i);
2270 pa_assert_ctl_context();
2271 pa_assert(event);
2272
2273 if (!i->send_event)
2274 return;
2275
2276 if (!data)
2277 data = pl = pa_proplist_new();
2278
2279 hook_data.sink_input = i;
2280 hook_data.data = data;
2281 hook_data.event = event;
2282
2283 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
2284 goto finish;
2285
2286 i->send_event(i, event, data);
2287
2288 finish:
2289 if (pl)
2290 pa_proplist_free(pl);
2291 }
2292
2293 /* Called from main context */
2294 /* Updates the sink input's resampler with whatever the current sink requires
2295 * -- useful when the underlying sink's sample spec might have changed */
pa_sink_input_update_resampler(pa_sink_input * i)2296 int pa_sink_input_update_resampler(pa_sink_input *i) {
2297 pa_resampler *new_resampler;
2298 char *memblockq_name;
2299
2300 pa_sink_input_assert_ref(i);
2301 pa_assert_ctl_context();
2302
2303 if (i->thread_info.resampler &&
2304 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &i->sink->sample_spec) &&
2305 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &i->sink->channel_map))
2306
2307 new_resampler = i->thread_info.resampler;
2308
2309 else if (!pa_sink_input_is_passthrough(i) &&
2310 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
2311 !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec) ||
2312 !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map))) {
2313
2314 new_resampler = pa_resampler_new(i->core->mempool,
2315 &i->sample_spec, &i->channel_map,
2316 &i->sink->sample_spec, &i->sink->channel_map,
2317 i->core->lfe_crossover_freq,
2318 i->requested_resample_method,
2319 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
2320 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
2321 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
2322 (i->core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
2323 (i->core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
2324 (i->core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0));
2325
2326 if (!new_resampler) {
2327 pa_log_warn("Unsupported resampling operation.");
2328 return -PA_ERR_NOTSUPPORTED;
2329 }
2330 } else
2331 new_resampler = NULL;
2332
2333 if (new_resampler == i->thread_info.resampler)
2334 return 0;
2335
2336 if (i->thread_info.resampler)
2337 pa_resampler_free(i->thread_info.resampler);
2338
2339 i->thread_info.resampler = new_resampler;
2340
2341 pa_memblockq_free(i->thread_info.render_memblockq);
2342
2343 memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
2344 i->thread_info.render_memblockq = pa_memblockq_new(
2345 memblockq_name,
2346 0,
2347 MEMBLOCKQ_MAXLENGTH,
2348 0,
2349 &i->sink->sample_spec,
2350 0,
2351 1,
2352 0,
2353 &i->sink->silence);
2354 pa_xfree(memblockq_name);
2355
2356 i->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
2357
2358 pa_log_debug("Updated resampler for sink input %d", i->index);
2359
2360 return 0;
2361 }
2362
2363 /* Called from the IO thread. */
pa_sink_input_attach(pa_sink_input * i)2364 void pa_sink_input_attach(pa_sink_input *i) {
2365 pa_assert(i);
2366 pa_assert(!i->thread_info.attached);
2367
2368 i->thread_info.attached = true;
2369
2370 if (i->attach)
2371 i->attach(i);
2372 }
2373
2374 /* Called from the IO thread. */
pa_sink_input_detach(pa_sink_input * i)2375 void pa_sink_input_detach(pa_sink_input *i) {
2376 pa_assert(i);
2377
2378 if (!i->thread_info.attached)
2379 return;
2380
2381 i->thread_info.attached = false;
2382
2383 if (i->detach)
2384 i->detach(i);
2385 }
2386
2387 /* Called from the main thread. */
pa_sink_input_set_volume_direct(pa_sink_input * i,const pa_cvolume * volume)2388 void pa_sink_input_set_volume_direct(pa_sink_input *i, const pa_cvolume *volume) {
2389 pa_cvolume old_volume;
2390 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2391 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2392
2393 pa_assert(i);
2394 pa_assert(volume);
2395
2396 old_volume = i->volume;
2397
2398 if (pa_cvolume_equal(volume, &old_volume))
2399 return;
2400
2401 i->volume = *volume;
2402 pa_log_debug("The volume of sink input %u changed from %s to %s.", i->index,
2403 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &i->channel_map, true),
2404 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &i->channel_map, true));
2405
2406 if (i->volume_changed)
2407 i->volume_changed(i);
2408
2409 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
2410 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_VOLUME_CHANGED], i);
2411 }
2412
2413 /* Called from the main thread. */
pa_sink_input_set_reference_ratio(pa_sink_input * i,const pa_cvolume * ratio)2414 void pa_sink_input_set_reference_ratio(pa_sink_input *i, const pa_cvolume *ratio) {
2415 pa_cvolume old_ratio;
2416 char old_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2417 char new_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2418
2419 pa_assert(i);
2420 pa_assert(ratio);
2421
2422 old_ratio = i->reference_ratio;
2423
2424 if (pa_cvolume_equal(ratio, &old_ratio))
2425 return;
2426
2427 i->reference_ratio = *ratio;
2428
2429 if (!PA_SINK_INPUT_IS_LINKED(i->state))
2430 return;
2431
2432 pa_log_debug("Sink input %u reference ratio changed from %s to %s.", i->index,
2433 pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), &old_ratio, &i->channel_map, true),
2434 pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), ratio, &i->channel_map, true));
2435 }
2436
2437 /* Called from the main thread. */
pa_sink_input_set_preferred_sink(pa_sink_input * i,pa_sink * s)2438 void pa_sink_input_set_preferred_sink(pa_sink_input *i, pa_sink *s) {
2439 pa_assert(i);
2440
2441 pa_xfree(i->preferred_sink);
2442 if (s) {
2443 i->preferred_sink = pa_xstrdup(s->name);
2444 pa_sink_input_move_to(i, s, false);
2445 } else {
2446 i->preferred_sink = NULL;
2447 pa_sink_input_move_to(i, i->core->default_sink, false);
2448 }
2449 }
2450