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
1886 /* Kill directly connected outputs */
1887 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1888 pa_assert(o != p);
1889 pa_source_output_kill(o);
1890 p = o;
1891 }
1892 pa_assert(pa_idxset_isempty(i->direct_outputs));
1893
1894 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1895
1896 if (i->state == PA_SINK_INPUT_CORKED)
1897 pa_assert_se(i->sink->n_corked-- >= 1);
1898
1899 if (pa_sink_input_is_passthrough(i))
1900 pa_sink_leave_passthrough(i->sink);
1901
1902 if (pa_sink_flat_volume_enabled(i->sink))
1903 /* We might need to update the sink's volume if we are in flat
1904 * volume mode. */
1905 pa_sink_set_volume(i->sink, NULL, false, false);
1906
1907 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1908
1909 pa_sink_update_status(i->sink);
1910
1911 PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
1912 pa_cvolume_remap(&v->volume, &i->sink->channel_map, &i->channel_map);
1913
1914 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1915
1916 /* Calculate how much of the latency was rewound on the old sink */
1917 i->origin_rewind_bytes = pa_sink_get_last_rewind(i->sink) / pa_frame_size(&i->sink->sample_spec);
1918 i->origin_rewind_bytes = i->origin_rewind_bytes * i->sample_spec.rate / i->sink->sample_spec.rate;
1919 i->origin_rewind_bytes *= pa_frame_size(&i->sample_spec);
1920
1921 i->sink = NULL;
1922 i->sink_requested_by_application = false;
1923
1924 pa_sink_input_unref(i);
1925
1926 return 0;
1927 }
1928
1929 /* Called from main context. If i has an origin sink that uses volume sharing,
1930 * then also the origin sink and all streams connected to it need to update
1931 * their volume - this function does all that by using recursion. */
update_volume_due_to_moving(pa_sink_input * i,pa_sink * dest)1932 static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
1933 pa_cvolume new_volume;
1934
1935 pa_assert(i);
1936 pa_assert(dest);
1937 pa_assert(i->sink); /* The destination sink should already be set. */
1938
1939 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1940 pa_sink *root_sink = pa_sink_get_master(i->sink);
1941 pa_sink_input *origin_sink_input;
1942 uint32_t idx;
1943
1944 if (PA_UNLIKELY(!root_sink))
1945 return;
1946
1947 if (pa_sink_flat_volume_enabled(i->sink)) {
1948 /* Ok, so the origin sink uses volume sharing, and flat volume is
1949 * enabled. The volume will have to be updated as follows:
1950 *
1951 * i->volume := i->sink->real_volume
1952 * (handled later by pa_sink_set_volume)
1953 * i->reference_ratio := i->volume / i->sink->reference_volume
1954 * (handled later by pa_sink_set_volume)
1955 * i->real_ratio stays unchanged
1956 * (streams whose origin sink uses volume sharing should
1957 * always have real_ratio of 0 dB)
1958 * i->soft_volume stays unchanged
1959 * (streams whose origin sink uses volume sharing should
1960 * always have volume_factor as soft_volume, so no change
1961 * should be needed) */
1962
1963 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1964 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1965
1966 /* Notifications will be sent by pa_sink_set_volume(). */
1967
1968 } else {
1969 /* Ok, so the origin sink uses volume sharing, and flat volume is
1970 * disabled. The volume will have to be updated as follows:
1971 *
1972 * i->volume := 0 dB
1973 * i->reference_ratio := 0 dB
1974 * i->real_ratio stays unchanged
1975 * (streams whose origin sink uses volume sharing should
1976 * always have real_ratio of 0 dB)
1977 * i->soft_volume stays unchanged
1978 * (streams whose origin sink uses volume sharing should
1979 * always have volume_factor as soft_volume, so no change
1980 * should be needed) */
1981
1982 pa_cvolume_reset(&new_volume, i->volume.channels);
1983 pa_sink_input_set_volume_direct(i, &new_volume);
1984 pa_sink_input_set_reference_ratio(i, &new_volume);
1985 pa_assert(pa_cvolume_is_norm(&i->real_ratio));
1986 pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
1987 }
1988
1989 /* Additionally, the origin sink volume needs updating:
1990 *
1991 * i->origin_sink->reference_volume := root_sink->reference_volume
1992 * i->origin_sink->real_volume := root_sink->real_volume
1993 * i->origin_sink->soft_volume stays unchanged
1994 * (sinks that use volume sharing should always have
1995 * soft_volume of 0 dB) */
1996
1997 new_volume = root_sink->reference_volume;
1998 pa_cvolume_remap(&new_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
1999 pa_sink_set_reference_volume_direct(i->origin_sink, &new_volume);
2000
2001 i->origin_sink->real_volume = root_sink->real_volume;
2002 pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
2003
2004 pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
2005
2006 /* If you wonder whether i->origin_sink->set_volume() should be called
2007 * somewhere, that's not the case, because sinks that use volume
2008 * sharing shouldn't have any internal volume that set_volume() would
2009 * update. If you wonder whether the thread_info variables should be
2010 * synced, yes, they should, and it's done by the
2011 * PA_SINK_MESSAGE_FINISH_MOVE message handler. */
2012
2013 /* Recursively update origin sink inputs. */
2014 PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
2015 update_volume_due_to_moving(origin_sink_input, dest);
2016
2017 } else {
2018 if (pa_sink_flat_volume_enabled(i->sink)) {
2019 /* Ok, so this is a regular stream, and flat volume is enabled. The
2020 * volume will have to be updated as follows:
2021 *
2022 * i->volume := i->reference_ratio * i->sink->reference_volume
2023 * i->reference_ratio stays unchanged
2024 * i->real_ratio := i->volume / i->sink->real_volume
2025 * (handled later by pa_sink_set_volume)
2026 * i->soft_volume := i->real_ratio * i->volume_factor
2027 * (handled later by pa_sink_set_volume) */
2028
2029 new_volume = i->sink->reference_volume;
2030 pa_cvolume_remap(&new_volume, &i->sink->channel_map, &i->channel_map);
2031 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
2032 pa_sink_input_set_volume_direct(i, &new_volume);
2033
2034 } else {
2035 /* Ok, so this is a regular stream, and flat volume is disabled.
2036 * The volume will have to be updated as follows:
2037 *
2038 * i->volume := i->reference_ratio
2039 * i->reference_ratio stays unchanged
2040 * i->real_ratio := i->reference_ratio
2041 * i->soft_volume := i->real_ratio * i->volume_factor */
2042
2043 pa_sink_input_set_volume_direct(i, &i->reference_ratio);
2044 i->real_ratio = i->reference_ratio;
2045 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
2046 }
2047 }
2048
2049 /* If i->sink == dest, then recursion has finished, and we can finally call
2050 * pa_sink_set_volume(), which will do the rest of the updates. */
2051 if ((i->sink == dest) && pa_sink_flat_volume_enabled(i->sink))
2052 pa_sink_set_volume(i->sink, NULL, false, i->save_volume);
2053 }
2054
2055 /* Called from the main thread. */
set_preferred_sink(pa_sink_input * i,const char * sink_name)2056 static void set_preferred_sink(pa_sink_input *i, const char *sink_name) {
2057 pa_assert(i);
2058
2059 if (pa_safe_streq(i->preferred_sink, sink_name))
2060 return;
2061
2062 pa_log_debug("Sink input %u: preferred_sink: %s -> %s",
2063 i->index, i->preferred_sink ? i->preferred_sink : "(unset)", sink_name ? sink_name : "(unset)");
2064 pa_xfree(i->preferred_sink);
2065 i->preferred_sink = pa_xstrdup(sink_name);
2066
2067 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
2068 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PREFERRED_SINK_CHANGED], i);
2069 }
2070
2071 /* Restores the render memblockq from the history memblockq during a move.
2072 * Called from main context while the sink input is detached. */
restore_render_memblockq(pa_sink_input * i)2073 static void restore_render_memblockq(pa_sink_input *i) {
2074 size_t block_size, to_push;
2075 size_t latency_bytes = 0;
2076 size_t bytes_on_origin_sink = 0;
2077 size_t resampler_delay_bytes = 0;
2078
2079 /* Calculate how much of the latency was left on the old sink */
2080 latency_bytes = pa_usec_to_bytes(i->thread_info.origin_sink_latency, &i->sample_spec);
2081 if (latency_bytes > i->origin_rewind_bytes)
2082 bytes_on_origin_sink = latency_bytes - i->origin_rewind_bytes;
2083
2084 /* Get resampler latency of old resampler */
2085 resampler_delay_bytes = i->thread_info.resampler_delay_frames * pa_frame_size(&i->sample_spec);
2086
2087 /* Flush the render memblockq and reset the resampler */
2088 pa_memblockq_flush_write(i->thread_info.render_memblockq, true);
2089 if (i->thread_info.resampler)
2090 pa_resampler_reset(i->thread_info.resampler);
2091
2092 /* Rewind the history queue */
2093 if (i->origin_rewind_bytes + resampler_delay_bytes > 0)
2094 pa_memblockq_rewind(i->thread_info.history_memblockq, i->origin_rewind_bytes + resampler_delay_bytes);
2095
2096 /* If something is left playing on the origin sink, add silence to the render memblockq */
2097 if (bytes_on_origin_sink > 0) {
2098 pa_memchunk chunk;;
2099
2100 chunk.length = pa_resampler_result(i->thread_info.resampler, bytes_on_origin_sink);
2101 if (chunk.length > 0) {
2102 chunk.memblock = pa_memblock_new(i->core->mempool, chunk.length);
2103 chunk.index = 0;
2104 pa_silence_memchunk(&chunk, &i->sink->sample_spec);
2105 pa_memblockq_push(i->thread_info.render_memblockq, &chunk);
2106 pa_memblock_unref(chunk.memblock);
2107 }
2108 }
2109
2110 /* Determine maximum block size */
2111 if (i->thread_info.resampler)
2112 block_size = pa_resampler_max_block_size(i->thread_info.resampler);
2113 else
2114 block_size = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
2115
2116 /* Now push all the data in the history queue into the render memblockq */
2117 to_push = pa_memblockq_get_length(i->thread_info.history_memblockq);
2118 while (to_push > 0) {
2119 pa_memchunk in_chunk, out_chunk;
2120 size_t push_bytes;
2121
2122 push_bytes = block_size;
2123 if (to_push < block_size)
2124 push_bytes = to_push;
2125
2126 if (pa_memblockq_peek_fixed_size(i->thread_info.history_memblockq, push_bytes, &in_chunk) < 0) {
2127 pa_log_warn("Could not restore memblockq during move");
2128 break;
2129 }
2130
2131 if (i->thread_info.resampler) {
2132 pa_resampler_run(i->thread_info.resampler, &in_chunk, &out_chunk);
2133 pa_memblock_unref(in_chunk.memblock);
2134 } else
2135 out_chunk = in_chunk;
2136
2137 if (out_chunk.length > 0) {
2138 pa_memblockq_push(i->thread_info.render_memblockq, &out_chunk);
2139 pa_memblock_unref(out_chunk.memblock);
2140 }
2141
2142 pa_memblockq_drop(i->thread_info.history_memblockq, push_bytes);
2143 to_push -= push_bytes;
2144 }
2145
2146 /* No need to rewind the history queue here, it will be re-synchronized
2147 * with the render queue during the next pa_sink_input_drop() call. */
2148
2149 /* Tell the sink input not to ask the implementer to rewrite during the
2150 * the next rewind */
2151 i->thread_info.dont_rewrite = true;
2152 }
2153
2154 /* Called from main context */
pa_sink_input_finish_move(pa_sink_input * i,pa_sink * dest,bool save)2155 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) {
2156 struct volume_factor_entry *v;
2157 void *state = NULL;
2158
2159 pa_sink_input_assert_ref(i);
2160 pa_assert_ctl_context();
2161 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
2162 pa_assert(!i->sink);
2163 pa_sink_assert_ref(dest);
2164
2165 if (!pa_sink_input_may_move_to(i, dest))
2166 return -PA_ERR_NOTSUPPORTED;
2167
2168 if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
2169 pa_proplist *p = pa_proplist_new();
2170 pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
2171 /* Tell the client what device we want to be on if it is going to
2172 * reconnect */
2173 pa_proplist_sets(p, "device", dest->name);
2174 pa_sink_input_send_event(i, PA_STREAM_EVENT_FORMAT_LOST, p);
2175 pa_proplist_free(p);
2176 return -PA_ERR_NOTSUPPORTED;
2177 }
2178
2179 if (!(i->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
2180 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec)) {
2181 /* try to change dest sink format and rate if possible without glitches.
2182 module-suspend-on-idle resumes destination sink with
2183 SINK_INPUT_MOVE_FINISH hook */
2184
2185 pa_log_info("Trying to change sample spec");
2186 pa_sink_reconfigure(dest, &i->sample_spec, pa_sink_input_is_passthrough(i));
2187 }
2188
2189 if (i->moving)
2190 i->moving(i, dest);
2191
2192 i->sink = dest;
2193 /* save == true, means user is calling the move_to() and want to
2194 save the preferred_sink */
2195 if (save) {
2196 if (dest == dest->core->default_sink)
2197 set_preferred_sink(i, NULL);
2198 else
2199 set_preferred_sink(i, dest->name);
2200 }
2201
2202 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
2203
2204 PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
2205 pa_cvolume_remap(&v->volume, &i->channel_map, &i->sink->channel_map);
2206
2207 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
2208
2209 if (i->state == PA_SINK_INPUT_CORKED)
2210 i->sink->n_corked++;
2211
2212 pa_sink_input_update_resampler(i, false);
2213
2214 // restore_render_memblockq(i); // restore is needless for moving between sinks
2215
2216 pa_sink_update_status(dest);
2217
2218 update_volume_due_to_moving(i, dest);
2219
2220 if (pa_sink_input_is_passthrough(i))
2221 pa_sink_enter_passthrough(i->sink);
2222
2223 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
2224
2225 /* Reset move variable */
2226 i->origin_rewind_bytes = 0;
2227
2228 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
2229
2230 /* Notify everyone */
2231 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
2232 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
2233
2234 return 0;
2235 }
2236
2237 /* Called from main context */
pa_sink_input_fail_move(pa_sink_input * i)2238 void pa_sink_input_fail_move(pa_sink_input *i) {
2239
2240 pa_sink_input_assert_ref(i);
2241 pa_assert_ctl_context();
2242 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
2243 pa_assert(!i->sink);
2244
2245 /* Check if someone wants this sink input? */
2246 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
2247 return;
2248
2249 /* Can we move the sink input to the default sink? */
2250 if (i->core->rescue_streams && pa_sink_input_may_move_to(i, i->core->default_sink)) {
2251 if (pa_sink_input_finish_move(i, i->core->default_sink, false) >= 0)
2252 return;
2253 }
2254
2255 if (i->moving)
2256 i->moving(i, NULL);
2257
2258 pa_sink_input_kill(i);
2259 }
2260
2261 /* Called from main context */
pa_sink_input_move_to(pa_sink_input * i,pa_sink * dest,bool save)2262 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, bool save) {
2263 int r;
2264
2265 pa_sink_input_assert_ref(i);
2266 pa_assert_ctl_context();
2267 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
2268 pa_assert(i->sink);
2269 pa_sink_assert_ref(dest);
2270
2271 if (dest == i->sink)
2272 return 0;
2273
2274 if (!pa_sink_input_may_move_to(i, dest))
2275 return -PA_ERR_NOTSUPPORTED;
2276
2277 pa_sink_input_ref(i);
2278
2279 if ((r = pa_sink_input_start_move(i)) < 0) {
2280 pa_sink_input_unref(i);
2281 return r;
2282 }
2283
2284 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
2285 pa_sink_input_fail_move(i);
2286 pa_sink_input_unref(i);
2287 return r;
2288 }
2289
2290 pa_sink_input_unref(i);
2291
2292 return 0;
2293 }
2294
2295 /* 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)2296 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
2297 bool corking, uncorking;
2298
2299 pa_sink_input_assert_ref(i);
2300
2301 if (state == i->thread_info.state)
2302 return;
2303
2304 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
2305 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2306
2307 if (i->state_change)
2308 i->state_change(i, state);
2309
2310 if (corking) {
2311
2312 pa_log_debug("Requesting rewind due to corking");
2313
2314 /* This will tell the implementing sink input driver to rewind
2315 * so that the unplayed already mixed data is not lost */
2316 if (i->sink)
2317 pa_sink_input_request_rewind(i, 0, true, true, false);
2318
2319 /* Set the corked state *after* requesting rewind */
2320 i->thread_info.state = state;
2321
2322 } else if (uncorking) {
2323
2324 pa_log_debug("Requesting rewind due to uncorking");
2325
2326 i->thread_info.underrun_for = (uint64_t) -1;
2327 i->thread_info.underrun_for_sink = 0;
2328 i->thread_info.playing_for = 0;
2329
2330 /* Set the uncorked state *before* requesting rewind */
2331 i->thread_info.state = state;
2332
2333 /* OK, we're being uncorked. Make sure we're not rewound when
2334 * the hw buffer is remixed and request a remix. */
2335 if (i->sink)
2336 pa_sink_input_request_rewind(i, 0, false, true, true);
2337 } else
2338 /* We may not be corking or uncorking, but we still need to set the state. */
2339 i->thread_info.state = state;
2340 }
2341
2342 /* 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)2343 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2344 pa_sink_input *i = PA_SINK_INPUT(o);
2345 pa_sink_input_assert_ref(i);
2346
2347 switch (code) {
2348
2349 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
2350 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
2351 i->thread_info.soft_volume = i->soft_volume;
2352 pa_sink_input_request_rewind(i, 0, true, false, false);
2353 }
2354 return 0;
2355
2356 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
2357 if (i->thread_info.muted != i->muted) {
2358 i->thread_info.muted = i->muted;
2359 pa_sink_input_request_rewind(i, 0, true, false, false);
2360 }
2361 return 0;
2362
2363 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
2364 pa_usec_t *r = userdata;
2365
2366 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
2367 r[0] += pa_resampler_get_delay_usec(i->thread_info.resampler);
2368 r[1] += pa_sink_get_latency_within_thread(i->sink, false);
2369
2370 return 0;
2371 }
2372
2373 case PA_SINK_INPUT_MESSAGE_SET_RATE:
2374
2375 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
2376 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
2377
2378 return 0;
2379
2380 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
2381 pa_sink_input *ssync;
2382
2383 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
2384
2385 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
2386 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
2387
2388 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
2389 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
2390
2391 return 0;
2392 }
2393
2394 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
2395 pa_usec_t *usec = userdata;
2396
2397 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
2398 return 0;
2399 }
2400
2401 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
2402 pa_usec_t *r = userdata;
2403
2404 *r = i->thread_info.requested_sink_latency;
2405 return 0;
2406 }
2407 }
2408
2409 return -PA_ERR_NOTIMPLEMENTED;
2410 }
2411
2412 /* Called from IO context */
pa_sink_input_safe_to_remove(pa_sink_input * i)2413 bool pa_sink_input_safe_to_remove(pa_sink_input *i) {
2414 pa_sink_input_assert_ref(i);
2415 pa_sink_input_assert_io_context(i);
2416
2417 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
2418 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
2419
2420 return true;
2421 }
2422
2423 /* Called from IO context */
pa_sink_input_request_rewind(pa_sink_input * i,size_t nbytes,bool rewrite,bool flush,bool dont_rewind_render)2424 void pa_sink_input_request_rewind(
2425 pa_sink_input *i,
2426 size_t nbytes /* in our sample spec */,
2427 bool rewrite, /* rewrite what we have, or get fresh data? */
2428 bool flush, /* flush render memblockq? */
2429 bool dont_rewind_render) {
2430
2431 size_t lbq;
2432
2433 /* If 'rewrite' is true the sink is rewound as far as requested
2434 * and possible and the exact value of this is passed back the
2435 * implementor via process_rewind(). If 'flush' is also true all
2436 * already rendered data is also dropped.
2437 *
2438 * If 'rewrite' is false the sink is rewound as far as requested
2439 * and possible and the already rendered data is dropped so that
2440 * in the next iteration we read new data from the
2441 * implementor. This implies 'flush' is true. If
2442 * dont_rewind_render is true then the render memblockq is not
2443 * rewound. */
2444
2445 /* nbytes = 0 means maximum rewind request */
2446
2447 pa_sink_input_assert_ref(i);
2448 pa_sink_input_assert_io_context(i);
2449 pa_assert(rewrite || flush);
2450 pa_assert(!dont_rewind_render || !rewrite);
2451
2452 /* We don't take rewind requests while we are corked */
2453 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
2454 return;
2455
2456 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
2457
2458 #ifdef SINK_INPUT_DEBUG
2459 pa_log_debug("request rewrite %zu", nbytes);
2460 #endif
2461
2462 /* Calculate how much we can rewind locally without having to
2463 * touch the sink */
2464 if (rewrite)
2465 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
2466 else
2467 lbq = 0;
2468
2469 /* Check if rewinding for the maximum is requested, and if so, fix up */
2470 if (nbytes <= 0) {
2471
2472 /* Calculate maximum number of bytes that could be rewound in theory.
2473 * If the sink has a virtual sink attached, limit rewinding to max_rewind.
2474 *
2475 * The max_rewind value of a virtual sink depends on the rewinding capability
2476 * of its DSP code. The DSP code is rewound in the process_rewind() callback
2477 * of the sink input. Therefore rewinding must be limited to max_rewind here. */
2478 nbytes = i->sink->thread_info.max_rewind;
2479 if (!pa_sink_has_filter_attached(i->sink) && !pa_sink_is_filter(i->sink))
2480 nbytes += lbq;
2481
2482 /* Transform from sink domain */
2483 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
2484 }
2485
2486 /* For virtual sinks there are two situations where nbytes may exceed max_rewind:
2487 * 1) If an underrun was detected.
2488 * 2) When the sink input is rewound during a move when it is attached to
2489 * the destination sink.
2490 * Moving a sink input is handled without involving the implementer, so the
2491 * implementer will only be asked to rewind more than max_rewind if an
2492 * underrun occurs. In that case, the DSP code of virtual sinks should be
2493 * reset instead of rewound. Therefore the rewind function of filters should
2494 * check if the requested rewind exceeds the maximum possible rewind of the
2495 * filter. */
2496
2497 /* Remember how much we actually want to rewrite */
2498 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
2499 if (rewrite) {
2500 /* Make sure to not overwrite over underruns */
2501 if (nbytes > i->thread_info.playing_for)
2502 nbytes = (size_t) i->thread_info.playing_for;
2503
2504 i->thread_info.rewrite_nbytes = nbytes;
2505 } else
2506 i->thread_info.rewrite_nbytes = (size_t) -1;
2507 }
2508
2509 i->thread_info.rewrite_flush =
2510 i->thread_info.rewrite_flush || flush;
2511
2512 i->thread_info.dont_rewind_render =
2513 i->thread_info.dont_rewind_render ||
2514 dont_rewind_render;
2515
2516 /* nbytes is -1 if some earlier rewind request had rewrite == false. */
2517 if (nbytes != (size_t) -1) {
2518
2519 /* Transform to sink domain */
2520 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
2521
2522 if (nbytes > lbq)
2523 pa_sink_request_rewind(i->sink, nbytes - lbq);
2524 else
2525 /* This call will make sure process_rewind() is called later */
2526 pa_sink_request_rewind(i->sink, 0);
2527 }
2528 }
2529
2530 /* Called from main context */
pa_sink_input_get_silence(pa_sink_input * i,pa_memchunk * ret)2531 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
2532 pa_sink_input_assert_ref(i);
2533 pa_assert_ctl_context();
2534 pa_assert(ret);
2535
2536 /* FIXME: Shouldn't access resampler object from main context! */
2537
2538 pa_silence_memchunk_get(
2539 &i->core->silence_cache,
2540 i->core->mempool,
2541 ret,
2542 &i->sample_spec,
2543 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
2544
2545 return ret;
2546 }
2547
2548 /* Called from main context */
pa_sink_input_send_event(pa_sink_input * i,const char * event,pa_proplist * data)2549 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
2550 pa_proplist *pl = NULL;
2551 pa_sink_input_send_event_hook_data hook_data;
2552
2553 pa_sink_input_assert_ref(i);
2554 pa_assert_ctl_context();
2555 pa_assert(event);
2556
2557 if (!i->send_event)
2558 return;
2559
2560 if (!data)
2561 data = pl = pa_proplist_new();
2562
2563 hook_data.sink_input = i;
2564 hook_data.data = data;
2565 hook_data.event = event;
2566
2567 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
2568 goto finish;
2569
2570 i->send_event(i, event, data);
2571
2572 finish:
2573 if (pl)
2574 pa_proplist_free(pl);
2575 }
2576
2577 /* Called from main context */
2578 /* Updates the sink input's resampler with whatever the current sink requires
2579 * -- useful when the underlying sink's sample spec might have changed */
pa_sink_input_update_resampler(pa_sink_input * i,bool flush_history)2580 int pa_sink_input_update_resampler(pa_sink_input *i, bool flush_history) {
2581 pa_resampler *new_resampler;
2582 char *memblockq_name;
2583
2584 pa_sink_input_assert_ref(i);
2585 pa_assert_ctl_context();
2586
2587 if (i->thread_info.resampler &&
2588 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &i->sink->sample_spec) &&
2589 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &i->sink->channel_map))
2590
2591 new_resampler = i->thread_info.resampler;
2592
2593 else if (!pa_sink_input_is_passthrough(i) &&
2594 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
2595 !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec) ||
2596 !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map))) {
2597
2598 new_resampler = pa_resampler_new(i->core->mempool,
2599 &i->sample_spec, &i->channel_map,
2600 &i->sink->sample_spec, &i->sink->channel_map,
2601 i->core->lfe_crossover_freq,
2602 i->requested_resample_method,
2603 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
2604 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
2605 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
2606 (i->core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
2607 (i->core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
2608 (i->core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0));
2609
2610 if (!new_resampler) {
2611 pa_log_warn("Unsupported resampling operation.");
2612 return -PA_ERR_NOTSUPPORTED;
2613 }
2614 } else
2615 new_resampler = NULL;
2616
2617 if (flush_history)
2618 pa_memblockq_flush_write(i->thread_info.history_memblockq, true);
2619
2620 if (new_resampler == i->thread_info.resampler)
2621 return 0;
2622
2623 if (i->thread_info.resampler)
2624 pa_resampler_free(i->thread_info.resampler);
2625
2626 i->thread_info.resampler = new_resampler;
2627
2628 pa_memblockq_free(i->thread_info.render_memblockq);
2629
2630 memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
2631 i->thread_info.render_memblockq = pa_memblockq_new(
2632 memblockq_name,
2633 0,
2634 MEMBLOCKQ_MAXLENGTH,
2635 0,
2636 &i->sink->sample_spec,
2637 0,
2638 1,
2639 0,
2640 &i->sink->silence);
2641 pa_xfree(memblockq_name);
2642
2643 i->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
2644
2645 pa_log_debug("Updated resampler for sink input %d", i->index);
2646
2647 return 0;
2648 }
2649
2650 /* Called from the IO thread. */
pa_sink_input_attach(pa_sink_input * i)2651 void pa_sink_input_attach(pa_sink_input *i) {
2652 pa_assert(i);
2653 pa_assert(!i->thread_info.attached);
2654
2655 i->thread_info.attached = true;
2656
2657 if (i->attach)
2658 i->attach(i);
2659 }
2660
2661 /* Called from the IO thread. */
pa_sink_input_detach(pa_sink_input * i)2662 void pa_sink_input_detach(pa_sink_input *i) {
2663 pa_assert(i);
2664
2665 if (!i->thread_info.attached)
2666 return;
2667
2668 i->thread_info.attached = false;
2669
2670 if (i->detach)
2671 i->detach(i);
2672 }
2673
2674 /* Called from the main thread. */
pa_sink_input_set_volume_direct(pa_sink_input * i,const pa_cvolume * volume)2675 void pa_sink_input_set_volume_direct(pa_sink_input *i, const pa_cvolume *volume) {
2676 pa_cvolume old_volume;
2677 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2678 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2679
2680 pa_assert(i);
2681 pa_assert(volume);
2682
2683 old_volume = i->volume;
2684
2685 if (pa_cvolume_equal(volume, &old_volume))
2686 return;
2687
2688 i->volume = *volume;
2689 pa_log_debug("The volume of sink input %u changed from %s to %s.", i->index,
2690 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &i->channel_map, true),
2691 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &i->channel_map, true));
2692
2693 if (i->volume_changed)
2694 i->volume_changed(i);
2695
2696 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
2697 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_VOLUME_CHANGED], i);
2698 }
2699
2700 /* Called from the main thread. */
pa_sink_input_set_reference_ratio(pa_sink_input * i,const pa_cvolume * ratio)2701 void pa_sink_input_set_reference_ratio(pa_sink_input *i, const pa_cvolume *ratio) {
2702 pa_cvolume old_ratio;
2703 char old_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2704 char new_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
2705
2706 pa_assert(i);
2707 pa_assert(ratio);
2708
2709 old_ratio = i->reference_ratio;
2710
2711 if (pa_cvolume_equal(ratio, &old_ratio))
2712 return;
2713
2714 i->reference_ratio = *ratio;
2715
2716 if (!PA_SINK_INPUT_IS_LINKED(i->state))
2717 return;
2718
2719 pa_log_debug("Sink input %u reference ratio changed from %s to %s.", i->index,
2720 pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), &old_ratio, &i->channel_map, true),
2721 pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), ratio, &i->channel_map, true));
2722 }
2723
2724 /* Called from the main thread.
2725 *
2726 * This is called when e.g. module-stream-restore wants to change the preferred
2727 * sink. As a side effect the stream is moved to the new preferred sink. Note
2728 * that things can work also in the other direction: if the user moves
2729 * a stream, as a side effect the preferred sink is changed. This could cause
2730 * an infinite loop, but it's avoided by these two measures:
2731 * - When pa_sink_input_set_preferred_sink() is called, it calls
2732 * pa_sink_input_move_to() with save=false, which avoids the recursive
2733 * pa_sink_input_set_preferred_sink() call.
2734 * - When the primary operation is to move a stream,
2735 * pa_sink_input_finish_move() calls set_preferred_sink() instead of
2736 * pa_sink_input_set_preferred_sink(). set_preferred_sink() doesn't move
2737 * the stream as a side effect.
2738 */
pa_sink_input_set_preferred_sink(pa_sink_input * i,pa_sink * s)2739 void pa_sink_input_set_preferred_sink(pa_sink_input *i, pa_sink *s) {
2740 pa_assert(i);
2741
2742 if (s) {
2743 set_preferred_sink(i, s->name);
2744 pa_sink_input_move_to(i, s, false);
2745 } else {
2746 set_preferred_sink(i, NULL);
2747 pa_sink_input_move_to(i, i->core->default_sink, false);
2748 }
2749 }
2750
pa_sink_input_handle_ohos_underrun(pa_sink_input * i)2751 void pa_sink_input_handle_ohos_underrun(pa_sink_input *i) {
2752 if (i->process_underrun_ohos && (pa_atomic_load(&i->isFirstReaded) == 1)) {
2753 i->process_underrun_ohos(i);
2754 }
2755 }
2756