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