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