native: rework handling of seeks that depend on variables the client does not know...
[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 #include <string.h>
30
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
34
35 #include <pulsecore/sample-util.h>
36 #include <pulsecore/core-subscribe.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/play-memblockq.h>
39 #include <pulsecore/namereg.h>
40 #include <pulsecore/core-util.h>
41 #include <pulse/timeval.h>
42
43 #include "sink-input.h"
44
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
47
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
49
50 static void sink_input_free(pa_object *o);
51 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
52 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t  pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t);
53 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t);
54 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk);
55 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes);
56 static void sink_input_release_envelope(pa_sink_input *i);
57
58 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
59     pa_assert(data);
60
61     pa_zero(*data);
62     data->resample_method = PA_RESAMPLER_INVALID;
63     data->proplist = pa_proplist_new();
64
65     return data;
66 }
67
68 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
69     pa_assert(data);
70
71     if ((data->sample_spec_is_set = !!spec))
72         data->sample_spec = *spec;
73 }
74
75 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
76     pa_assert(data);
77
78     if ((data->channel_map_is_set = !!map))
79         data->channel_map = *map;
80 }
81
82 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
83     pa_assert(data);
84
85     if ((data->volume_is_set = !!volume))
86         data->volume = *volume;
87 }
88
89 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
90     pa_assert(data);
91     pa_assert(volume_factor);
92
93     if (data->volume_factor_is_set)
94         pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
95     else {
96         data->volume_factor_is_set = TRUE;
97         data->volume_factor = *volume_factor;
98     }
99 }
100
101 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
102     pa_assert(data);
103     pa_assert(volume_factor);
104
105     if (data->volume_factor_sink_is_set)
106         pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
107     else {
108         data->volume_factor_sink_is_set = TRUE;
109         data->volume_factor_sink = *volume_factor;
110     }
111 }
112
113 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
114     pa_assert(data);
115
116     data->muted_is_set = TRUE;
117     data->muted = !!mute;
118 }
119
120 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
121     pa_assert(data);
122
123     pa_proplist_free(data->proplist);
124 }
125
126 /* Called from main context */
127 static void reset_callbacks(pa_sink_input *i) {
128     pa_assert(i);
129
130     i->pop = NULL;
131     i->process_rewind = NULL;
132     i->update_max_rewind = NULL;
133     i->update_max_request = NULL;
134     i->update_sink_requested_latency = NULL;
135     i->update_sink_latency_range = NULL;
136     i->update_sink_fixed_latency = NULL;
137     i->attach = NULL;
138     i->detach = NULL;
139     i->suspend = NULL;
140     i->suspend_within_thread = NULL;
141     i->moving = NULL;
142     i->kill = NULL;
143     i->get_latency = NULL;
144     i->state_change = NULL;
145     i->may_move_to = NULL;
146     i->send_event = NULL;
147     i->volume_changed = NULL;
148     i->mute_changed = NULL;
149 }
150
151 /* Called from main context */
152 int pa_sink_input_new(
153         pa_sink_input **_i,
154         pa_core *core,
155         pa_sink_input_new_data *data) {
156
157     pa_sink_input *i;
158     pa_resampler *resampler = NULL;
159     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
160     pa_channel_map original_cm;
161     int r;
162     char *pt;
163
164     pa_assert(_i);
165     pa_assert(core);
166     pa_assert(data);
167     pa_assert_ctl_context();
168
169     if (data->client)
170         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
171
172     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
173         return r;
174
175     pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
176
177     if (!data->sink) {
178         data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
179         data->save_sink = FALSE;
180     }
181
182     pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
183     pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
184     pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
185
186     if (!data->sample_spec_is_set)
187         data->sample_spec = data->sink->sample_spec;
188
189     pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
190
191     if (!data->channel_map_is_set) {
192         if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
193             data->channel_map = data->sink->channel_map;
194         else
195             pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
196     }
197
198     pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
199
200     if (!data->volume_is_set) {
201         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
202         data->volume_is_absolute = FALSE;
203         data->save_volume = FALSE;
204     }
205
206     pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
207
208     if (!data->volume_factor_is_set)
209         pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
210
211     pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
212
213     if (!data->volume_factor_sink_is_set)
214         pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
215
216     pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
217
218     if (!data->muted_is_set)
219         data->muted = FALSE;
220
221     if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
222         data->sample_spec.format = data->sink->sample_spec.format;
223
224     if (data->flags & PA_SINK_INPUT_FIX_RATE)
225         data->sample_spec.rate = data->sink->sample_spec.rate;
226
227     original_cm = data->channel_map;
228
229     if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
230         data->sample_spec.channels = data->sink->sample_spec.channels;
231         data->channel_map = data->sink->channel_map;
232     }
233
234     pa_assert(pa_sample_spec_valid(&data->sample_spec));
235     pa_assert(pa_channel_map_valid(&data->channel_map));
236
237     /* Due to the fixing of the sample spec the volume might not match anymore */
238     pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
239
240     if (data->resample_method == PA_RESAMPLER_INVALID)
241         data->resample_method = core->resample_method;
242
243     pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
244
245     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
246         return r;
247
248     if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
249         pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
250         pa_log_warn("Failed to create sink input: sink is suspended.");
251         return -PA_ERR_BADSTATE;
252     }
253
254     if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
255         pa_log_warn("Failed to create sink input: too many inputs per sink.");
256         return -PA_ERR_TOOLARGE;
257     }
258
259     if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
260         !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
261         !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
262
263         if (!(resampler = pa_resampler_new(
264                       core->mempool,
265                       &data->sample_spec, &data->channel_map,
266                       &data->sink->sample_spec, &data->sink->channel_map,
267                       data->resample_method,
268                       ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
269                       ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
270                       (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
271                       (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
272             pa_log_warn("Unsupported resampling operation.");
273             return -PA_ERR_NOTSUPPORTED;
274         }
275     }
276
277     i = pa_msgobject_new(pa_sink_input);
278     i->parent.parent.free = sink_input_free;
279     i->parent.process_msg = pa_sink_input_process_msg;
280
281     i->core = core;
282     i->state = PA_SINK_INPUT_INIT;
283     i->flags = data->flags;
284     i->proplist = pa_proplist_copy(data->proplist);
285     i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
286     i->module = data->module;
287     i->sink = data->sink;
288     i->client = data->client;
289
290     i->requested_resample_method = data->resample_method;
291     i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
292     i->sample_spec = data->sample_spec;
293     i->channel_map = data->channel_map;
294
295     if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
296         pa_cvolume remapped;
297
298         /* When the 'absolute' bool is not set then we'll treat the volume
299          * as relative to the sink volume even in flat volume mode */
300         remapped = data->sink->reference_volume;
301         pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
302         pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
303     } else
304         i->volume = data->volume;
305
306     i->volume_factor = data->volume_factor;
307     i->volume_factor_sink = data->volume_factor_sink;
308     i->real_ratio = i->reference_ratio = data->volume;
309     pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
310     pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
311     i->save_volume = data->save_volume;
312     i->save_sink = data->save_sink;
313     i->save_muted = data->save_muted;
314
315     i->muted = data->muted;
316
317     if (data->sync_base) {
318         i->sync_next = data->sync_base->sync_next;
319         i->sync_prev = data->sync_base;
320
321         if (data->sync_base->sync_next)
322             data->sync_base->sync_next->sync_prev = i;
323         data->sync_base->sync_next = i;
324     } else
325         i->sync_next = i->sync_prev = NULL;
326
327     i->direct_outputs = pa_idxset_new(NULL, NULL);
328
329     reset_callbacks(i);
330     i->userdata = NULL;
331
332     /* Set Ramping info */
333     i->thread_info.ramp_info.is_ramping = FALSE;
334     i->thread_info.ramp_info.envelope_dead = TRUE;
335     i->thread_info.ramp_info.envelope = NULL;
336     i->thread_info.ramp_info.item = NULL;
337     i->thread_info.ramp_info.envelope_dying = 0;
338
339     pa_atomic_store(&i->before_ramping_v, 0);
340     pa_atomic_store(&i->before_ramping_m, 0);
341
342     i->thread_info.state = i->state;
343     i->thread_info.attached = FALSE;
344     pa_atomic_store(&i->thread_info.drained, 1);
345     i->thread_info.sample_spec = i->sample_spec;
346     i->thread_info.resampler = resampler;
347     i->thread_info.soft_volume = i->soft_volume;
348     i->thread_info.muted = i->muted;
349     i->thread_info.requested_sink_latency = (pa_usec_t) -1;
350     i->thread_info.rewrite_nbytes = 0;
351     i->thread_info.rewrite_flush = FALSE;
352     i->thread_info.dont_rewind_render = FALSE;
353     i->thread_info.underrun_for = (uint64_t) -1;
354     i->thread_info.playing_for = 0;
355     i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
356
357     i->thread_info.render_memblockq = pa_memblockq_new(
358             0,
359             MEMBLOCKQ_MAXLENGTH,
360             0,
361             pa_frame_size(&i->sink->sample_spec),
362             0,
363             1,
364             0,
365             &i->sink->silence);
366
367     pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
368     pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
369
370     if (i->client)
371         pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
372
373     pt = pa_proplist_to_string_sep(i->proplist, "\n    ");
374     pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n    %s",
375                 i->index,
376                 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
377                 i->sink->name,
378                 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
379                 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
380                 pt);
381     pa_xfree(pt);
382
383     /* Don't forget to call pa_sink_input_put! */
384
385     *_i = i;
386     return 0;
387 }
388
389 /* Called from main context */
390 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
391     pa_assert(i);
392     pa_assert_ctl_context();
393
394     if (!i->sink)
395         return;
396
397     if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
398         pa_assert_se(i->sink->n_corked -- >= 1);
399     else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
400         i->sink->n_corked++;
401 }
402
403 /* Called from main context */
404 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
405     pa_sink_input *ssync;
406     pa_assert(i);
407     pa_assert_ctl_context();
408
409     if (state == PA_SINK_INPUT_DRAINED)
410         state = PA_SINK_INPUT_RUNNING;
411
412     if (i->state == state)
413         return;
414
415     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);
416
417     update_n_corked(i, state);
418     i->state = state;
419
420     for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
421         update_n_corked(ssync, state);
422         ssync->state = state;
423     }
424     for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
425         update_n_corked(ssync, state);
426         ssync->state = state;
427     }
428
429     if (state != PA_SINK_INPUT_UNLINKED) {
430         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
431
432         for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
433             pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
434
435         for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
436             pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
437     }
438
439     pa_sink_update_status(i->sink);
440 }
441
442 /* Called from main context */
443 void pa_sink_input_unlink(pa_sink_input *i) {
444     pa_bool_t linked;
445     pa_source_output *o, *p =  NULL;
446
447     pa_assert(i);
448     pa_assert_ctl_context();
449
450     /* See pa_sink_unlink() for a couple of comments how this function
451      * works */
452
453     pa_sink_input_ref(i);
454
455     linked = PA_SINK_INPUT_IS_LINKED(i->state);
456
457     if (linked)
458         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
459
460     if (i->sync_prev)
461         i->sync_prev->sync_next = i->sync_next;
462     if (i->sync_next)
463         i->sync_next->sync_prev = i->sync_prev;
464
465     i->sync_prev = i->sync_next = NULL;
466
467     pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
468
469     if (i->sink)
470         if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
471             pa_sink_input_unref(i);
472
473     if (i->client)
474         pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
475
476     while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
477         pa_assert(o != p);
478         pa_source_output_kill(o);
479         p = o;
480     }
481
482     update_n_corked(i, PA_SINK_INPUT_UNLINKED);
483     i->state = PA_SINK_INPUT_UNLINKED;
484
485     if (linked && i->sink) {
486         /* We might need to update the sink's volume if we are in flat volume mode. */
487         if (i->sink->flags & PA_SINK_FLAT_VOLUME)
488             pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
489
490         if (i->sink->asyncmsgq)
491             pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
492     }
493
494     reset_callbacks(i);
495
496     if (linked) {
497         pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
498         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
499     }
500
501     if (i->sink) {
502         pa_sink_update_status(i->sink);
503         i->sink = NULL;
504     }
505
506     pa_core_maybe_vacuum(i->core);
507
508     pa_sink_input_unref(i);
509 }
510
511 /* Called from main context */
512 static void sink_input_free(pa_object *o) {
513     pa_sink_input* i = PA_SINK_INPUT(o);
514
515     pa_assert(i);
516     pa_assert_ctl_context();
517     pa_assert(pa_sink_input_refcnt(i) == 0);
518
519     if (PA_SINK_INPUT_IS_LINKED(i->state))
520         pa_sink_input_unlink(i);
521
522     pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
523
524     /* Side note: this function must be able to destruct properly any
525      * kind of sink input in any state, even those which are
526      * "half-moved" or are connected to sinks that have no asyncmsgq
527      * and are hence half-destructed themselves! */
528
529     if (i->thread_info.ramp_info.envelope) {
530         pa_log_debug ("Freeing envelope\n");
531         pa_envelope_free(i->thread_info.ramp_info.envelope);
532         i->thread_info.ramp_info.envelope = NULL;
533     }
534
535     if (i->thread_info.render_memblockq)
536         pa_memblockq_free(i->thread_info.render_memblockq);
537
538     if (i->thread_info.resampler)
539         pa_resampler_free(i->thread_info.resampler);
540
541     if (i->proplist)
542         pa_proplist_free(i->proplist);
543
544     if (i->direct_outputs)
545         pa_idxset_free(i->direct_outputs, NULL, NULL);
546
547     if (i->thread_info.direct_outputs)
548         pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
549
550     pa_xfree(i->driver);
551     pa_xfree(i);
552 }
553
554 /* Called from main context */
555 void pa_sink_input_put(pa_sink_input *i) {
556     pa_sink_input_state_t state;
557
558     pa_sink_input_assert_ref(i);
559     pa_assert_ctl_context();
560
561     pa_assert(i->state == PA_SINK_INPUT_INIT);
562
563     /* The following fields must be initialized properly */
564     pa_assert(i->pop);
565     pa_assert(i->process_rewind);
566     pa_assert(i->kill);
567
568     state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
569
570     update_n_corked(i, state);
571     i->state = state;
572
573     /* We might need to update the sink's volume if we are in flat volume mode. */
574     if (i->sink->flags & PA_SINK_FLAT_VOLUME)
575         pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
576     else
577         set_real_ratio(i, &i->volume);
578
579     i->thread_info.soft_volume = i->soft_volume;
580     i->thread_info.muted = i->muted;
581
582     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
583
584     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
585     pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
586
587     pa_sink_update_status(i->sink);
588 }
589
590 /* Called from main context */
591 void pa_sink_input_kill(pa_sink_input*i) {
592     pa_sink_input_assert_ref(i);
593     pa_assert_ctl_context();
594     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
595
596     i->kill(i);
597 }
598
599 /* Called from main context */
600 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
601     pa_usec_t r[2] = { 0, 0 };
602
603     pa_sink_input_assert_ref(i);
604     pa_assert_ctl_context();
605     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
606
607     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
608
609     if (i->get_latency)
610         r[0] += i->get_latency(i);
611
612     if (sink_latency)
613         *sink_latency = r[1];
614
615     return r[0];
616 }
617
618 /* Called from thread context */
619 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
620     pa_bool_t do_volume_adj_here, need_volume_factor_sink;
621     pa_bool_t volume_is_norm;
622     pa_bool_t ramping;
623     size_t block_size_max_sink, block_size_max_sink_input;
624     size_t ilength;
625
626     pa_sink_input_assert_ref(i);
627     pa_sink_input_assert_io_context(i);
628     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
629     pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
630     pa_assert(chunk);
631     pa_assert(volume);
632
633 /*     pa_log_debug("peek"); */
634
635     pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
636               i->thread_info.state == PA_SINK_INPUT_CORKED ||
637               i->thread_info.state == PA_SINK_INPUT_DRAINED);
638
639     block_size_max_sink_input = i->thread_info.resampler ?
640         pa_resampler_max_block_size(i->thread_info.resampler) :
641         pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
642
643     block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
644
645     /* Default buffer size */
646     if (slength <= 0)
647         slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
648
649     if (slength > block_size_max_sink)
650         slength = block_size_max_sink;
651
652     if (i->thread_info.resampler) {
653         ilength = pa_resampler_request(i->thread_info.resampler, slength);
654
655         if (ilength <= 0)
656             ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
657     } else
658         ilength = slength;
659
660     if (ilength > block_size_max_sink_input)
661         ilength = block_size_max_sink_input;
662
663     /* If the channel maps of the sink and this stream differ, we need
664      * to adjust the volume *before* we resample. Otherwise we can do
665      * it after and leave it for the sink code */
666
667     do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map) || i->thread_info.ramp_info.is_ramping;
668     volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
669     need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
670
671     while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
672         pa_memchunk tchunk;
673
674         /* There's nothing in our render queue. We need to fill it up
675          * with data from the implementor. */
676
677         if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
678             i->pop(i, ilength, &tchunk) < 0) {
679
680             /* OK, we're corked or the implementor didn't give us any
681              * data, so let's just hand out silence */
682             pa_atomic_store(&i->thread_info.drained, 1);
683
684             pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
685             i->thread_info.playing_for = 0;
686             if (i->thread_info.underrun_for != (uint64_t) -1)
687                 i->thread_info.underrun_for += ilength;
688             break;
689         }
690
691         pa_atomic_store(&i->thread_info.drained, 0);
692
693         pa_assert(tchunk.length > 0);
694         pa_assert(tchunk.memblock);
695
696         i->thread_info.underrun_for = 0;
697         i->thread_info.playing_for += tchunk.length;
698
699         while (tchunk.length > 0) {
700             pa_memchunk wchunk;
701             pa_bool_t nvfs = need_volume_factor_sink;
702
703             wchunk = tchunk;
704             pa_memblock_ref(wchunk.memblock);
705
706             if (wchunk.length > block_size_max_sink_input)
707                 wchunk.length = block_size_max_sink_input;
708
709             /* It might be necessary to adjust the volume here */
710             if (do_volume_adj_here && !volume_is_norm && !i->thread_info.ramp_info.is_ramping) {
711                 pa_memchunk_make_writable(&wchunk, 0);
712
713                 if (i->thread_info.muted) {
714                     pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
715                     nvfs = FALSE;
716
717                 } else if (!i->thread_info.resampler && nvfs) {
718                     pa_cvolume v;
719
720                     /* If we don't need a resampler we can merge the
721                      * post and the pre volume adjustment into one */
722
723                     pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
724                     pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
725                     nvfs = FALSE;
726
727                 } else
728                     pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
729             }
730
731             if (!i->thread_info.resampler) {
732
733                 if (nvfs) {
734                     pa_memchunk_make_writable(&wchunk, 0);
735                     pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
736                 }
737
738                 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
739             } else {
740                 pa_memchunk rchunk;
741                 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
742
743 /*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
744
745                 if (rchunk.memblock) {
746
747                     if (nvfs) {
748                         pa_memchunk_make_writable(&rchunk, 0);
749                         pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
750                     }
751
752                     pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
753                     pa_memblock_unref(rchunk.memblock);
754                 }
755             }
756
757             pa_memblock_unref(wchunk.memblock);
758
759             tchunk.index += wchunk.length;
760             tchunk.length -= wchunk.length;
761         }
762
763         pa_memblock_unref(tchunk.memblock);
764     }
765
766     pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
767
768     pa_assert(chunk->length > 0);
769     pa_assert(chunk->memblock);
770
771 /*     pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
772
773     if (chunk->length > block_size_max_sink)
774         chunk->length = block_size_max_sink;
775
776     ramping = i->thread_info.ramp_info.is_ramping;
777     if (ramping)
778         sink_input_volume_ramping(i, chunk);
779
780     if (!i->thread_info.ramp_info.envelope_dead) {
781         i->thread_info.ramp_info.envelope_dying += chunk->length;
782         pa_log_debug("Envelope dying is %d, chunk length is %zu, dead thresholder is %lu\n", i->thread_info.ramp_info.envelope_dying,
783                 chunk->length,
784                 i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope));
785
786         if (i->thread_info.ramp_info.envelope_dying >= (int32_t) (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) {
787             pa_log_debug("RELEASE Envelop");
788             i->thread_info.ramp_info.envelope_dead = TRUE;
789             sink_input_release_envelope(i);
790         }
791     }
792
793     /* Let's see if we had to apply the volume adjustment ourselves,
794      * or if this can be done by the sink for us */
795
796     if (do_volume_adj_here)
797         /* We had different channel maps, so we already did the adjustment */
798         pa_cvolume_reset(volume, i->sink->sample_spec.channels);
799     else if (i->thread_info.muted)
800         /* We've both the same channel map, so let's have the sink do the adjustment for us*/
801         pa_cvolume_mute(volume, i->sink->sample_spec.channels);
802     else
803         *volume = i->thread_info.soft_volume;
804 }
805
806 /* Called from thread context */
807 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
808
809     pa_sink_input_assert_ref(i);
810     pa_sink_input_assert_io_context(i);
811     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
812     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
813     pa_assert(nbytes > 0);
814
815 /*     pa_log_debug("dropping %lu", (unsigned long) nbytes); */
816
817     pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
818 }
819
820 /* Called from thread context */
821 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
822     size_t lbq;
823     pa_bool_t called = FALSE;
824
825     pa_sink_input_assert_ref(i);
826     pa_sink_input_assert_io_context(i);
827     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
828     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
829
830 /*     pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
831
832     lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
833
834     if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
835         pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
836         pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
837         sink_input_rewind_ramp_info(i, nbytes);
838     }
839
840     if (i->thread_info.rewrite_nbytes == (size_t) -1) {
841
842         /* We were asked to drop all buffered data, and rerequest new
843          * data from implementor the next time push() is called */
844
845         pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
846
847     } else if (i->thread_info.rewrite_nbytes > 0) {
848         size_t max_rewrite, amount;
849
850         /* Calculate how much make sense to rewrite at most */
851         max_rewrite = nbytes + lbq;
852
853         /* Transform into local domain */
854         if (i->thread_info.resampler)
855             max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
856
857         /* Calculate how much of the rewinded data should actually be rewritten */
858         amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
859
860         if (amount > 0) {
861             pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
862
863             /* Tell the implementor */
864             if (i->process_rewind)
865                 i->process_rewind(i, amount);
866             called = TRUE;
867
868             /* Convert back to to sink domain */
869             if (i->thread_info.resampler)
870                 amount = pa_resampler_result(i->thread_info.resampler, amount);
871
872             if (amount > 0)
873                 /* Ok, now update the write pointer */
874                 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
875
876             if (i->thread_info.rewrite_flush)
877                 pa_memblockq_silence(i->thread_info.render_memblockq);
878
879             /* And reset the resampler */
880             if (i->thread_info.resampler)
881                 pa_resampler_reset(i->thread_info.resampler);
882         }
883     }
884
885     if (!called)
886         if (i->process_rewind)
887             i->process_rewind(i, 0);
888
889     i->thread_info.rewrite_nbytes = 0;
890     i->thread_info.rewrite_flush = FALSE;
891     i->thread_info.dont_rewind_render = FALSE;
892 }
893
894 /* Called from thread context */
895 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
896     pa_sink_input_assert_ref(i);
897     pa_sink_input_assert_io_context(i);
898
899     return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
900 }
901
902 /* Called from thread context */
903 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
904     pa_sink_input_assert_ref(i);
905     pa_sink_input_assert_io_context(i);
906
907     /* We're not verifying the status here, to allow this to be called
908      * in the state change handler between _INIT and _RUNNING */
909
910     return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
911 }
912
913 /* Called from thread context */
914 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes  /* in the sink's sample spec */) {
915     pa_sink_input_assert_ref(i);
916     pa_sink_input_assert_io_context(i);
917     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
918     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
919
920     pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
921
922     if (i->update_max_rewind)
923         i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
924 }
925
926 /* Called from thread context */
927 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes  /* in the sink's sample spec */) {
928     pa_sink_input_assert_ref(i);
929     pa_sink_input_assert_io_context(i);
930     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
931     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
932
933     if (i->update_max_request)
934         i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
935 }
936
937 /* Called from thread context */
938 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
939     pa_sink_input_assert_ref(i);
940     pa_sink_input_assert_io_context(i);
941
942     if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
943         usec = i->sink->thread_info.fixed_latency;
944
945     if (usec != (pa_usec_t) -1)
946         usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
947
948     i->thread_info.requested_sink_latency = usec;
949     pa_sink_invalidate_requested_latency(i->sink, TRUE);
950
951     return usec;
952 }
953
954 /* Called from main context */
955 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
956     pa_sink_input_assert_ref(i);
957     pa_assert_ctl_context();
958
959     if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
960         pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
961         return usec;
962     }
963
964     /* If this sink input is not realized yet or we are being moved,
965      * we have to touch the thread info data directly */
966
967     if (i->sink) {
968         if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
969             usec = pa_sink_get_fixed_latency(i->sink);
970
971         if (usec != (pa_usec_t) -1) {
972             pa_usec_t min_latency, max_latency;
973             pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
974             usec =  PA_CLAMP(usec, min_latency, max_latency);
975         }
976     }
977
978     i->thread_info.requested_sink_latency = usec;
979
980     return usec;
981 }
982
983 /* Called from main context */
984 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
985     pa_sink_input_assert_ref(i);
986     pa_assert_ctl_context();
987
988     if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
989         pa_usec_t usec = 0;
990         pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
991         return usec;
992     }
993
994     /* If this sink input is not realized yet or we are being moved,
995      * we have to touch the thread info data directly */
996
997     return i->thread_info.requested_sink_latency;
998 }
999
1000 /* Called from main context */
1001 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1002     pa_sink_input_assert_ref(i);
1003     pa_assert_ctl_context();
1004     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1005     pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1006
1007     /* This basically calculates:
1008      *
1009      * i->real_ratio := v
1010      * i->soft_volume := i->real_ratio * i->volume_factor */
1011
1012     if (v)
1013         i->real_ratio = *v;
1014     else
1015         pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1016
1017     pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1018     /* We don't copy the data to the thread_info data. That's left for someone else to do */
1019 }
1020
1021 /* Called from main context */
1022 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
1023     /* test ramping -> return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 2000 * PA_USEC_PER_MSEC); */
1024     return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 0);
1025 }
1026
1027 /* Called from main context */
1028 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1029     pa_sink_input_assert_ref(i);
1030     pa_assert_ctl_context();
1031     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1032
1033     if (absolute || !(i->sink->flags & PA_SINK_FLAT_VOLUME))
1034         *volume = i->volume;
1035     else
1036         *volume = i->reference_ratio;
1037
1038     return volume;
1039 }
1040
1041 /* Called from main context */
1042 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1043     /* test ramping -> return pa_sink_input_set_mute_with_ramping(i, mute, save, 2000 * PA_USEC_PER_MSEC); */
1044     return pa_sink_input_set_mute_with_ramping(i, mute, save, 0);
1045 }
1046
1047 /* Called from main context */
1048 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1049     pa_sink_input_assert_ref(i);
1050     pa_assert_ctl_context();
1051     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1052
1053     return i->muted;
1054 }
1055
1056 /* Called from main thread */
1057 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1058     pa_sink_input_assert_ref(i);
1059     pa_assert_ctl_context();
1060
1061     if (p)
1062         pa_proplist_update(i->proplist, mode, p);
1063
1064     if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1065         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1066         pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1067     }
1068 }
1069
1070 /* Called from main context */
1071 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1072     pa_sink_input_assert_ref(i);
1073     pa_assert_ctl_context();
1074     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1075
1076     sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1077 }
1078
1079 /* Called from main context */
1080 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1081     pa_sink_input_assert_ref(i);
1082     pa_assert_ctl_context();
1083     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1084     pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1085
1086     if (i->sample_spec.rate == rate)
1087         return 0;
1088
1089     i->sample_spec.rate = rate;
1090
1091     pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1092
1093     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1094     return 0;
1095 }
1096
1097 /* Called from main context */
1098 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1099     const char *old;
1100     pa_sink_input_assert_ref(i);
1101     pa_assert_ctl_context();
1102
1103     if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1104         return;
1105
1106     old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1107
1108     if (old && name && pa_streq(old, name))
1109         return;
1110
1111     if (name)
1112         pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1113     else
1114         pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1115
1116     if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1117         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1118         pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1119     }
1120 }
1121
1122 /* Called from main context */
1123 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1124     pa_sink_input_assert_ref(i);
1125     pa_assert_ctl_context();
1126
1127     return i->actual_resample_method;
1128 }
1129
1130 /* Called from main context */
1131 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1132     pa_sink_input_assert_ref(i);
1133     pa_assert_ctl_context();
1134     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1135
1136     if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1137         return FALSE;
1138
1139     if (i->sync_next || i->sync_prev) {
1140         pa_log_warn("Moving synchronised streams not supported.");
1141         return FALSE;
1142     }
1143
1144     return TRUE;
1145 }
1146
1147 /* Called from main context */
1148 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1149     pa_sink_input_assert_ref(i);
1150     pa_assert_ctl_context();
1151     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1152     pa_sink_assert_ref(dest);
1153
1154     if (dest == i->sink)
1155         return TRUE;
1156
1157     if (!pa_sink_input_may_move(i))
1158         return FALSE;
1159
1160     if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1161         pa_log_warn("Failed to move sink input: too many inputs per sink.");
1162         return FALSE;
1163     }
1164
1165     if (i->may_move_to)
1166         if (!i->may_move_to(i, dest))
1167             return FALSE;
1168
1169     return TRUE;
1170 }
1171
1172 /* Called from main context */
1173 int pa_sink_input_start_move(pa_sink_input *i) {
1174     pa_source_output *o, *p = NULL;
1175     int r;
1176
1177     pa_sink_input_assert_ref(i);
1178     pa_assert_ctl_context();
1179     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1180     pa_assert(i->sink);
1181
1182     if (!pa_sink_input_may_move(i))
1183         return -PA_ERR_NOTSUPPORTED;
1184
1185     if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1186         return r;
1187
1188     /* Kill directly connected outputs */
1189     while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1190         pa_assert(o != p);
1191         pa_source_output_kill(o);
1192         p = o;
1193     }
1194     pa_assert(pa_idxset_isempty(i->direct_outputs));
1195
1196     pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1197
1198     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1199         pa_assert_se(i->sink->n_corked-- >= 1);
1200
1201     if (i->sink->flags & PA_SINK_FLAT_VOLUME)
1202         /* We might need to update the sink's volume if we are in flat
1203          * volume mode. */
1204         pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1205
1206     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1207
1208     pa_sink_update_status(i->sink);
1209     pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1210     i->sink = NULL;
1211
1212     pa_sink_input_unref(i);
1213
1214     return 0;
1215 }
1216
1217 /* Called from main context */
1218 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1219     pa_resampler *new_resampler;
1220
1221     pa_sink_input_assert_ref(i);
1222     pa_assert_ctl_context();
1223     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1224     pa_assert(!i->sink);
1225     pa_sink_assert_ref(dest);
1226
1227     if (!pa_sink_input_may_move_to(i, dest))
1228         return -PA_ERR_NOTSUPPORTED;
1229
1230     if (i->thread_info.resampler &&
1231         pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1232         pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1233
1234         /* Try to reuse the old resampler if possible */
1235         new_resampler = i->thread_info.resampler;
1236
1237     else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1238              !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1239              !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1240
1241         /* Okey, we need a new resampler for the new sink */
1242
1243         if (!(new_resampler = pa_resampler_new(
1244                       i->core->mempool,
1245                       &i->sample_spec, &i->channel_map,
1246                       &dest->sample_spec, &dest->channel_map,
1247                       i->requested_resample_method,
1248                       ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1249                       ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1250                       (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1251             pa_log_warn("Unsupported resampling operation.");
1252             return -PA_ERR_NOTSUPPORTED;
1253         }
1254     } else
1255         new_resampler = NULL;
1256
1257     if (i->moving)
1258         i->moving(i, dest);
1259
1260     i->sink = dest;
1261     i->save_sink = save;
1262     pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1263
1264     pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1265
1266     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1267         i->sink->n_corked++;
1268
1269     /* Replace resampler and render queue */
1270     if (new_resampler != i->thread_info.resampler) {
1271
1272         if (i->thread_info.resampler)
1273             pa_resampler_free(i->thread_info.resampler);
1274         i->thread_info.resampler = new_resampler;
1275
1276         pa_memblockq_free(i->thread_info.render_memblockq);
1277
1278         i->thread_info.render_memblockq = pa_memblockq_new(
1279                 0,
1280                 MEMBLOCKQ_MAXLENGTH,
1281                 0,
1282                 pa_frame_size(&i->sink->sample_spec),
1283                 0,
1284                 1,
1285                 0,
1286                 &i->sink->silence);
1287     }
1288     pa_sink_update_status(dest);
1289
1290     if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1291         pa_cvolume remapped;
1292
1293         /* Make relative volumes absolute */
1294         remapped = dest->reference_volume;
1295         pa_cvolume_remap(&remapped, &dest->channel_map, &i->channel_map);
1296         pa_sw_cvolume_multiply(&i->volume, &i->reference_ratio, &remapped);
1297
1298         /* We might need to update the sink's volume if we are in flat volume mode. */
1299         pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1300     }
1301
1302     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1303
1304     pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1305
1306     /* Notify everyone */
1307     pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1308
1309     if (i->volume_changed)
1310         i->volume_changed(i);
1311
1312     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1313
1314     return 0;
1315 }
1316
1317 /* Called from main context */
1318 void pa_sink_input_fail_move(pa_sink_input *i) {
1319
1320     pa_sink_input_assert_ref(i);
1321     pa_assert_ctl_context();
1322     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1323     pa_assert(!i->sink);
1324
1325     /* Check if someone wants this sink input? */
1326     if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1327         return;
1328
1329     if (i->moving)
1330         i->moving(i, NULL);
1331
1332     pa_sink_input_kill(i);
1333 }
1334
1335 /* Called from main context */
1336 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1337     int r;
1338
1339     pa_sink_input_assert_ref(i);
1340     pa_assert_ctl_context();
1341     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1342     pa_assert(i->sink);
1343     pa_sink_assert_ref(dest);
1344
1345     if (dest == i->sink)
1346         return 0;
1347
1348     if (!pa_sink_input_may_move_to(i, dest))
1349         return -PA_ERR_NOTSUPPORTED;
1350
1351     pa_sink_input_ref(i);
1352
1353     if ((r = pa_sink_input_start_move(i)) < 0) {
1354         pa_sink_input_unref(i);
1355         return r;
1356     }
1357
1358     if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1359         pa_sink_input_fail_move(i);
1360         pa_sink_input_unref(i);
1361         return r;
1362     }
1363
1364     pa_sink_input_unref(i);
1365
1366     return 0;
1367 }
1368
1369 /* Called from IO thread context */
1370 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1371     pa_bool_t corking, uncorking;
1372
1373     pa_sink_input_assert_ref(i);
1374     pa_sink_input_assert_io_context(i);
1375
1376     if (state == i->thread_info.state)
1377         return;
1378
1379     if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1380         !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1381         pa_atomic_store(&i->thread_info.drained, 1);
1382
1383     corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1384     uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1385
1386     if (i->state_change)
1387         i->state_change(i, state);
1388
1389     i->thread_info.state = state;
1390
1391     if (corking) {
1392
1393         pa_log_debug("Requesting rewind due to corking");
1394
1395         /* This will tell the implementing sink input driver to rewind
1396          * so that the unplayed already mixed data is not lost */
1397         pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1398
1399     } else if (uncorking) {
1400
1401         i->thread_info.underrun_for = (uint64_t) -1;
1402         i->thread_info.playing_for = 0;
1403
1404         pa_log_debug("Requesting rewind due to uncorking");
1405
1406         /* OK, we're being uncorked. Make sure we're not rewound when
1407          * the hw buffer is remixed and request a remix. */
1408         pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1409     }
1410 }
1411
1412 /* Called from thread context, except when it is not. */
1413 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1414     pa_sink_input *i = PA_SINK_INPUT(o);
1415     pa_sink_input_assert_ref(i);
1416
1417     switch (code) {
1418
1419         case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1420             if (pa_atomic_load(&i->before_ramping_v))
1421                 i->thread_info.future_soft_volume = i->soft_volume;
1422
1423             if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1424                 if (!pa_atomic_load(&i->before_ramping_v))
1425                     i->thread_info.soft_volume = i->soft_volume;
1426                 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1427             }
1428             return 0;
1429
1430         case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1431             if (pa_atomic_load(&i->before_ramping_m))
1432                 i->thread_info.future_muted = i->muted;
1433
1434             if (i->thread_info.muted != i->muted) {
1435                 if (!pa_atomic_load(&i->before_ramping_m))
1436                     i->thread_info.muted = i->muted;
1437                 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1438             }
1439             return 0;
1440
1441         case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1442             pa_usec_t *r = userdata;
1443
1444             r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1445             r[1] += pa_sink_get_latency_within_thread(i->sink);
1446
1447             return 0;
1448         }
1449
1450         case PA_SINK_INPUT_MESSAGE_SET_RATE:
1451
1452             i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1453             pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1454
1455             return 0;
1456
1457         case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1458             pa_sink_input *ssync;
1459
1460             pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1461
1462             for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1463                 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1464
1465             for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1466                 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1467
1468             return 0;
1469         }
1470
1471         case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1472             pa_usec_t *usec = userdata;
1473
1474             *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1475             return 0;
1476         }
1477
1478         case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1479             pa_usec_t *r = userdata;
1480
1481             *r = i->thread_info.requested_sink_latency;
1482             return 0;
1483         }
1484
1485         case PA_SINK_INPUT_MESSAGE_SET_ENVELOPE: {
1486             if (!i->thread_info.ramp_info.envelope)
1487                 i->thread_info.ramp_info.envelope = pa_envelope_new(&i->sink->sample_spec);
1488
1489             if (i->thread_info.ramp_info.envelope && i->thread_info.ramp_info.item) {
1490                 pa_envelope_remove(i->thread_info.ramp_info.envelope, i->thread_info.ramp_info.item);
1491                 i->thread_info.ramp_info.item = NULL;
1492             }
1493
1494             i->thread_info.ramp_info.item = pa_envelope_add(i->thread_info.ramp_info.envelope, &i->using_def);
1495             i->thread_info.ramp_info.is_ramping = TRUE;
1496             i->thread_info.ramp_info.envelope_dead = FALSE;
1497             i->thread_info.ramp_info.envelope_dying = 0;
1498
1499             if (i->thread_info.ramp_info.envelope)
1500                 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1501
1502             return 0;
1503         }
1504     }
1505
1506     return -PA_ERR_NOTIMPLEMENTED;
1507 }
1508
1509 /* Called from main thread */
1510 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1511     pa_sink_input_assert_ref(i);
1512     pa_assert_ctl_context();
1513
1514     if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1515         return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1516
1517     return i->state;
1518 }
1519
1520 /* Called from IO context */
1521 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1522     pa_sink_input_assert_ref(i);
1523     pa_sink_input_assert_io_context(i);
1524
1525     if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1526         return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1527
1528     return TRUE;
1529 }
1530
1531 /* Called from IO context */
1532 void pa_sink_input_request_rewind(
1533         pa_sink_input *i,
1534         size_t nbytes  /* in our sample spec */,
1535         pa_bool_t rewrite,
1536         pa_bool_t flush,
1537         pa_bool_t dont_rewind_render) {
1538
1539     size_t lbq;
1540
1541     /* If 'rewrite' is TRUE the sink is rewound as far as requested
1542      * and possible and the exact value of this is passed back the
1543      * implementor via process_rewind(). If 'flush' is also TRUE all
1544      * already rendered data is also dropped.
1545      *
1546      * If 'rewrite' is FALSE the sink is rewound as far as requested
1547      * and possible and the already rendered data is dropped so that
1548      * in the next iteration we read new data from the
1549      * implementor. This implies 'flush' is TRUE.  If
1550      * dont_rewind_render is TRUE then the render memblockq is not
1551      * rewound. */
1552
1553     /* nbytes = 0 means maximum rewind request */
1554
1555     pa_sink_input_assert_ref(i);
1556     pa_sink_input_assert_io_context(i);
1557     pa_assert(rewrite || flush);
1558     pa_assert(!dont_rewind_render || !rewrite);
1559
1560     /* We don't take rewind requests while we are corked */
1561     if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1562         return;
1563
1564     nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1565
1566     /* pa_log_debug("request rewrite %zu", nbytes); */
1567
1568     /* Calculate how much we can rewind locally without having to
1569      * touch the sink */
1570     if (rewrite)
1571         lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1572     else
1573         lbq = 0;
1574
1575     /* Check if rewinding for the maximum is requested, and if so, fix up */
1576     if (nbytes <= 0) {
1577
1578         /* Calculate maximum number of bytes that could be rewound in theory */
1579         nbytes = i->sink->thread_info.max_rewind + lbq;
1580
1581         /* Transform from sink domain */
1582         if (i->thread_info.resampler)
1583             nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1584     }
1585
1586     /* Remember how much we actually want to rewrite */
1587     if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1588         if (rewrite) {
1589             /* Make sure to not overwrite over underruns */
1590             if (nbytes > i->thread_info.playing_for)
1591                 nbytes = (size_t) i->thread_info.playing_for;
1592
1593             i->thread_info.rewrite_nbytes = nbytes;
1594         } else
1595             i->thread_info.rewrite_nbytes = (size_t) -1;
1596     }
1597
1598     i->thread_info.rewrite_flush =
1599         i->thread_info.rewrite_flush ||
1600         (flush && i->thread_info.rewrite_nbytes != 0);
1601
1602     i->thread_info.dont_rewind_render =
1603         i->thread_info.dont_rewind_render ||
1604         dont_rewind_render;
1605
1606     if (nbytes != (size_t) -1) {
1607
1608         /* Transform to sink domain */
1609         if (i->thread_info.resampler)
1610             nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1611
1612         if (nbytes > lbq)
1613             pa_sink_request_rewind(i->sink, nbytes - lbq);
1614         else
1615             /* This call will make sure process_rewind() is called later */
1616             pa_sink_request_rewind(i->sink, 0);
1617     }
1618 }
1619
1620 /* Called from main context */
1621 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1622     pa_sink_input_assert_ref(i);
1623     pa_assert_ctl_context();
1624     pa_assert(ret);
1625
1626     /* FIXME: Shouldn't access resampler object from main context! */
1627
1628     pa_silence_memchunk_get(
1629                 &i->core->silence_cache,
1630                 i->core->mempool,
1631                 ret,
1632                 &i->sample_spec,
1633                 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1634
1635     return ret;
1636 }
1637
1638 /* Called from main context */
1639 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1640     pa_proplist *pl = NULL;
1641     pa_sink_input_send_event_hook_data hook_data;
1642
1643     pa_sink_input_assert_ref(i);
1644     pa_assert_ctl_context();
1645     pa_assert(event);
1646
1647     if (!i->send_event)
1648         return;
1649
1650     if (!data)
1651         data = pl = pa_proplist_new();
1652
1653     hook_data.sink_input = i;
1654     hook_data.data = data;
1655     hook_data.event = event;
1656
1657     if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1658         goto finish;
1659
1660     i->send_event(i, event, data);
1661
1662 finish:
1663     if (pl)
1664         pa_proplist_free(pl);
1665 }
1666
1667 /* Called from IO context */
1668 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk) {
1669     pa_assert(i);
1670     pa_assert(chunk);
1671     pa_assert(chunk->memblock);
1672     pa_assert(i->thread_info.ramp_info.is_ramping);
1673
1674     /* Volume is adjusted with ramping effect here */
1675     pa_envelope_apply(i->thread_info.ramp_info.envelope, chunk);
1676
1677     if (pa_envelope_is_finished(i->thread_info.ramp_info.envelope)) {
1678         i->thread_info.ramp_info.is_ramping = FALSE;
1679         if (pa_atomic_load(&i->before_ramping_v)) {
1680             i->thread_info.soft_volume = i->thread_info.future_soft_volume;
1681             pa_atomic_store(&i->before_ramping_v, 0);
1682         }
1683         else if (pa_atomic_load(&i->before_ramping_m)) {
1684             i->thread_info.muted = i->thread_info.future_muted;
1685             pa_atomic_store(&i->before_ramping_m, 0);
1686         }
1687     }
1688 }
1689
1690 /*
1691  * Called from main context
1692  * This function should be called inside pa_sink_input_set_volume_with_ramping
1693  * should be called after soft_volume of sink_input and sink are all adjusted
1694  */
1695 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t  pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t) {
1696
1697     int32_t target_abs_vol, target_apply_vol, pre_apply_vol;
1698     pa_assert(i);
1699
1700     pa_log_debug("Sink input's soft volume is %d= %f ", pa_cvolume_avg(&i->soft_volume), pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)));
1701
1702     /* Calculation formula are target_abs_vol := i->soft_volume
1703      *                                   target_apply_vol := lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000)
1704      *                                   pre_apply_vol := ( previous_virtual_volume / target_virtual_volume ) * target_apply_vol
1705      *
1706      * Will do volume adjustment inside pa_sink_input_peek
1707      */
1708     target_abs_vol = pa_cvolume_avg(&i->soft_volume);
1709     target_apply_vol = (int32_t) lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000);
1710     pre_apply_vol = (int32_t) ((pa_sw_volume_to_linear(pre_virtual_volume) / pa_sw_volume_to_linear(target_virtual_volume)) * target_apply_vol);
1711
1712     i->using_def.n_points = 2;
1713     i->using_def.points_x[0] = 0;
1714     i->using_def.points_x[1] = t;
1715     i->using_def.points_y.i[0] = pre_apply_vol;
1716     i->using_def.points_y.i[1] = target_apply_vol;
1717     i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1718     i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1719
1720     pa_log_debug("Volume Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1721                                    i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1722
1723     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1724 }
1725
1726 /* Called from main context */
1727 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t) {
1728
1729     int32_t cur_vol;
1730     pa_assert(i);
1731
1732     i->using_def.n_points = 2;
1733     i->using_def.points_x[0] = 0;
1734     i->using_def.points_x[1] = t;
1735     cur_vol = (int32_t) lrint( pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)) * 0x10000);
1736
1737     if (mute) {
1738         i->using_def.points_y.i[0] = cur_vol;
1739         i->using_def.points_y.i[1] = 0;
1740     } else {
1741         i->using_def.points_y.i[0] = 0;
1742         i->using_def.points_y.i[1] = cur_vol;
1743     }
1744
1745     i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1746     i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1747
1748     pa_log_debug("Mute Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1749                    i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1750
1751     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1752 }
1753
1754 /* Called from IO context */
1755 static void sink_input_release_envelope(pa_sink_input *i) {
1756     pa_assert(i);
1757     pa_assert(!i->thread_info.ramp_info.is_ramping);
1758     pa_assert(i->thread_info.ramp_info.envelope_dead);
1759
1760     pa_envelope_free(i->thread_info.ramp_info.envelope);
1761     i->thread_info.ramp_info.envelope = NULL;
1762     i->thread_info.ramp_info.item = NULL;
1763 }
1764
1765 /* Called from IO context */
1766 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) {
1767     pa_assert(i);
1768
1769     if (!i->thread_info.ramp_info.envelope_dead) {
1770         int32_t envelope_length;
1771
1772         pa_assert(i->thread_info.ramp_info.envelope);
1773
1774         envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope);
1775
1776         if (i->thread_info.ramp_info.envelope_dying > envelope_length) {
1777             if ((int32_t) (i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) {
1778                 pa_log_debug("Envelope Become Alive");
1779                 pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes));
1780                 i->thread_info.ramp_info.is_ramping = TRUE;
1781             }
1782         } else if (i->thread_info.ramp_info.envelope_dying < envelope_length) {
1783             if ((i->thread_info.ramp_info.envelope_dying - (ssize_t) nbytes) <= 0) {
1784                 pa_log_debug("Envelope Restart");
1785                 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1786             }
1787             else {
1788                 pa_log_debug("Envelope Simple Rewind");
1789                 pa_envelope_rewind(i->thread_info.ramp_info.envelope, nbytes);
1790             }
1791         }
1792
1793         i->thread_info.ramp_info.envelope_dying -= nbytes;
1794         if (i->thread_info.ramp_info.envelope_dying <= 0)
1795             i->thread_info.ramp_info.envelope_dying = 0;
1796     }
1797 }
1798
1799 void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t t){
1800     pa_cvolume v;
1801     pa_volume_t previous_virtual_volume, target_virtual_volume;
1802
1803     pa_sink_input_assert_ref(i);
1804     pa_assert_ctl_context();
1805     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1806     pa_assert(volume);
1807     pa_assert(pa_cvolume_valid(volume));
1808     pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1809
1810     if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
1811         v = i->sink->reference_volume;
1812         pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1813
1814         if (pa_cvolume_compatible(volume, &i->sample_spec))
1815             volume = pa_sw_cvolume_multiply(&v, &v, volume);
1816         else
1817             volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1818     } else {
1819
1820         if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1821             v = i->volume;
1822             volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1823         }
1824     }
1825
1826     if (pa_cvolume_equal(volume, &i->volume)) {
1827         i->save_volume = i->save_volume || save;
1828         return;
1829     }
1830
1831     previous_virtual_volume = pa_cvolume_avg(&i->volume);
1832     target_virtual_volume = pa_cvolume_avg(volume);
1833
1834     if (t > 0 && target_virtual_volume > 0)
1835         pa_log_debug("SetVolumeWithRamping: Virtual Volume From %u=%f to %u=%f\n", previous_virtual_volume, pa_sw_volume_to_linear(previous_virtual_volume),
1836                                              target_virtual_volume, pa_sw_volume_to_linear(target_virtual_volume));
1837
1838     i->volume = *volume;
1839     i->save_volume = save;
1840
1841     /* Set this flag before the following code modify i->thread_info.soft_volume */
1842     if (t > 0 && target_virtual_volume > 0)
1843         pa_atomic_store(&i->before_ramping_v, 1);
1844
1845     if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1846         /* We are in flat volume mode, so let's update all sink input
1847          * volumes and update the flat volume of the sink */
1848
1849         pa_sink_set_volume(i->sink, NULL, TRUE, save);
1850
1851     } else {
1852         /* OK, we are in normal volume mode. The volume only affects
1853          * ourselves */
1854         set_real_ratio(i, volume);
1855
1856         /* Copy the new soft_volume to the thread_info struct */
1857         pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1858     }
1859
1860     if (t > 0 && target_virtual_volume > 0)
1861         sink_input_set_ramping_info(i, previous_virtual_volume, target_virtual_volume, t);
1862
1863     /* The volume changed, let's tell people so */
1864     if (i->volume_changed)
1865         i->volume_changed(i);
1866
1867     /* The virtual volume changed, let's tell people so */
1868     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1869 }
1870
1871 void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){
1872
1873     pa_sink_input_assert_ref(i);
1874     pa_assert_ctl_context();
1875     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1876
1877     if (!i->muted == !mute) {
1878         i->save_muted = i->save_muted || mute;
1879         return;
1880     }
1881
1882     i->muted = mute;
1883     i->save_muted = save;
1884
1885     /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */
1886     if (t > 0)
1887         pa_atomic_store(&i->before_ramping_m, 1);
1888
1889     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1890
1891     if (t > 0)
1892         sink_input_set_ramping_info_for_mute(i, mute, t);
1893
1894     /* The mute status changed, let's tell people so */
1895     if (i->mute_changed)
1896         i->mute_changed(i);
1897
1898     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1899 }