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