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