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