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