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