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