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