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