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