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