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