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