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