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