]> 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 if (nvfs) {
721 pa_memchunk_make_writable(&rchunk, 0);
722 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
723 }
724
725 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
726
727 if (rchunk.memblock) {
728 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
729 pa_memblock_unref(rchunk.memblock);
730 }
731 }
732
733 pa_memblock_unref(wchunk.memblock);
734
735 tchunk.index += wchunk.length;
736 tchunk.length -= wchunk.length;
737 }
738
739 pa_memblock_unref(tchunk.memblock);
740 }
741
742 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
743
744 pa_assert(chunk->length > 0);
745 pa_assert(chunk->memblock);
746
747 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
748
749 if (chunk->length > block_size_max_sink)
750 chunk->length = block_size_max_sink;
751
752 /* Let's see if we had to apply the volume adjustment ourselves,
753 * or if this can be done by the sink for us */
754
755 if (do_volume_adj_here)
756 /* We had different channel maps, so we already did the adjustment */
757 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
758 else if (i->thread_info.muted)
759 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
760 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
761 else
762 *volume = i->thread_info.soft_volume;
763 }
764
765 /* Called from thread context */
766 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
767
768 pa_sink_input_assert_ref(i);
769 pa_sink_input_assert_io_context(i);
770 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
771 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
772 pa_assert(nbytes > 0);
773
774 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
775
776 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
777 }
778
779 /* Called from thread context */
780 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
781 size_t lbq;
782 pa_bool_t called = FALSE;
783
784 pa_sink_input_assert_ref(i);
785 pa_sink_input_assert_io_context(i);
786 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
787 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
788
789 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
790
791 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
792
793 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
794 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
795 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
796 }
797
798 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
799
800 /* We were asked to drop all buffered data, and rerequest new
801 * data from implementor the next time push() is called */
802
803 pa_memblockq_flush_write(i->thread_info.render_memblockq);
804
805 } else if (i->thread_info.rewrite_nbytes > 0) {
806 size_t max_rewrite, amount;
807
808 /* Calculate how much make sense to rewrite at most */
809 max_rewrite = nbytes + lbq;
810
811 /* Transform into local domain */
812 if (i->thread_info.resampler)
813 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
814
815 /* Calculate how much of the rewinded data should actually be rewritten */
816 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
817
818 if (amount > 0) {
819 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
820
821 /* Tell the implementor */
822 if (i->process_rewind)
823 i->process_rewind(i, amount);
824 called = TRUE;
825
826 /* Convert back to to sink domain */
827 if (i->thread_info.resampler)
828 amount = pa_resampler_result(i->thread_info.resampler, amount);
829
830 if (amount > 0)
831 /* Ok, now update the write pointer */
832 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
833
834 if (i->thread_info.rewrite_flush)
835 pa_memblockq_silence(i->thread_info.render_memblockq);
836
837 /* And reset the resampler */
838 if (i->thread_info.resampler)
839 pa_resampler_reset(i->thread_info.resampler);
840 }
841 }
842
843 if (!called)
844 if (i->process_rewind)
845 i->process_rewind(i, 0);
846
847 i->thread_info.rewrite_nbytes = 0;
848 i->thread_info.rewrite_flush = FALSE;
849 i->thread_info.dont_rewind_render = FALSE;
850 }
851
852 /* Called from thread context */
853 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
854 pa_sink_input_assert_ref(i);
855 pa_sink_input_assert_io_context(i);
856
857 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
858 }
859
860 /* Called from thread context */
861 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
862 pa_sink_input_assert_ref(i);
863 pa_sink_input_assert_io_context(i);
864
865 /* We're not verifying the status here, to allow this to be called
866 * in the state change handler between _INIT and _RUNNING */
867
868 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
869 }
870
871 /* Called from thread context */
872 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
873 pa_sink_input_assert_ref(i);
874 pa_sink_input_assert_io_context(i);
875 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
876 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
877
878 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
879
880 if (i->update_max_rewind)
881 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
882 }
883
884 /* Called from thread context */
885 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
886 pa_sink_input_assert_ref(i);
887 pa_sink_input_assert_io_context(i);
888 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
889 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
890
891 if (i->update_max_request)
892 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
893 }
894
895 /* Called from thread context */
896 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
897 pa_sink_input_assert_ref(i);
898 pa_sink_input_assert_io_context(i);
899
900 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
901 usec = i->sink->thread_info.fixed_latency;
902
903 if (usec != (pa_usec_t) -1)
904 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
905
906 i->thread_info.requested_sink_latency = usec;
907 pa_sink_invalidate_requested_latency(i->sink, TRUE);
908
909 return usec;
910 }
911
912 /* Called from main context */
913 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
914 pa_sink_input_assert_ref(i);
915 pa_assert_ctl_context();
916
917 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
918 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
919 return usec;
920 }
921
922 /* If this sink input is not realized yet or we are being moved,
923 * we have to touch the thread info data directly */
924
925 if (i->sink) {
926 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
927 usec = pa_sink_get_fixed_latency(i->sink);
928
929 if (usec != (pa_usec_t) -1) {
930 pa_usec_t min_latency, max_latency;
931 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
932 usec = PA_CLAMP(usec, min_latency, max_latency);
933 }
934 }
935
936 i->thread_info.requested_sink_latency = usec;
937
938 return usec;
939 }
940
941 /* Called from main context */
942 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
943 pa_sink_input_assert_ref(i);
944 pa_assert_ctl_context();
945
946 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
947 pa_usec_t usec = 0;
948 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
949 return usec;
950 }
951
952 /* If this sink input is not realized yet or we are being moved,
953 * we have to touch the thread info data directly */
954
955 return i->thread_info.requested_sink_latency;
956 }
957
958 /* Called from main context */
959 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
960 pa_sink_input_assert_ref(i);
961 pa_assert_ctl_context();
962 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
963 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
964
965 /* This basically calculates:
966 *
967 * i->real_ratio := v
968 * i->soft_volume := i->real_ratio * i->volume_factor */
969
970 if (v)
971 i->real_ratio = *v;
972 else
973 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
974
975 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
976 /* We don't copy the data to the thread_info data. That's left for someone else to do */
977 }
978
979 /* Called from main context */
980 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
981 pa_cvolume v;
982
983 pa_sink_input_assert_ref(i);
984 pa_assert_ctl_context();
985 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
986 pa_assert(volume);
987 pa_assert(pa_cvolume_valid(volume));
988 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
989
990 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
991 v = i->sink->reference_volume;
992 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
993
994 if (pa_cvolume_compatible(volume, &i->sample_spec))
995 volume = pa_sw_cvolume_multiply(&v, &v, volume);
996 else
997 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
998 } else {
999
1000 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1001 v = i->volume;
1002 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1003 }
1004 }
1005
1006 if (pa_cvolume_equal(volume, &i->volume)) {
1007 i->save_volume = i->save_volume || save;
1008 return;
1009 }
1010
1011 i->volume = *volume;
1012 i->save_volume = save;
1013
1014 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
1015 /* We are in flat volume mode, so let's update all sink input
1016 * volumes and update the flat volume of the sink */
1017
1018 pa_sink_set_volume(i->sink, NULL, TRUE, save);
1019
1020 else {
1021 /* OK, we are in normal volume mode. The volume only affects
1022 * ourselves */
1023 set_real_ratio(i, volume);
1024
1025 /* Copy the new soft_volume to the thread_info struct */
1026 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1027 }
1028
1029 /* The volume changed, let's tell people so */
1030 if (i->volume_changed)
1031 i->volume_changed(i);
1032
1033 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1034 }
1035
1036 /* Called from main context */
1037 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1038 pa_sink_input_assert_ref(i);
1039 pa_assert_ctl_context();
1040 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1041
1042 if (absolute || !(i->sink->flags & PA_SINK_FLAT_VOLUME))
1043 *volume = i->volume;
1044 else
1045 *volume = i->reference_ratio;
1046
1047 return volume;
1048 }
1049
1050 /* Called from main context */
1051 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1052 pa_sink_input_assert_ref(i);
1053 pa_assert_ctl_context();
1054 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1055
1056 if (!i->muted == !mute)
1057 return;
1058
1059 i->muted = mute;
1060 i->save_muted = save;
1061
1062 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1063
1064 /* The mute status changed, let's tell people so */
1065 if (i->mute_changed)
1066 i->mute_changed(i);
1067
1068 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1069 }
1070
1071 /* Called from main context */
1072 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1073 pa_sink_input_assert_ref(i);
1074 pa_assert_ctl_context();
1075 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1076
1077 return i->muted;
1078 }
1079
1080 /* Called from main thread */
1081 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1082 pa_sink_input_assert_ref(i);
1083 pa_assert_ctl_context();
1084
1085 if (p)
1086 pa_proplist_update(i->proplist, mode, p);
1087
1088 if (PA_SINK_IS_LINKED(i->state)) {
1089 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1090 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1091 }
1092 }
1093
1094 /* Called from main context */
1095 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1096 pa_sink_input_assert_ref(i);
1097 pa_assert_ctl_context();
1098 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1099
1100 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1101 }
1102
1103 /* Called from main context */
1104 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1105 pa_sink_input_assert_ref(i);
1106 pa_assert_ctl_context();
1107 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1108 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1109
1110 if (i->sample_spec.rate == rate)
1111 return 0;
1112
1113 i->sample_spec.rate = rate;
1114
1115 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1116
1117 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1118 return 0;
1119 }
1120
1121 /* Called from main context */
1122 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1123 const char *old;
1124 pa_sink_input_assert_ref(i);
1125 pa_assert_ctl_context();
1126
1127 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1128 return;
1129
1130 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1131
1132 if (old && name && pa_streq(old, name))
1133 return;
1134
1135 if (name)
1136 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1137 else
1138 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1139
1140 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1141 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1142 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1143 }
1144 }
1145
1146 /* Called from main context */
1147 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1148 pa_sink_input_assert_ref(i);
1149 pa_assert_ctl_context();
1150
1151 return i->actual_resample_method;
1152 }
1153
1154 /* Called from main context */
1155 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1156 pa_sink_input_assert_ref(i);
1157 pa_assert_ctl_context();
1158 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1159
1160 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1161 return FALSE;
1162
1163 if (i->sync_next || i->sync_prev) {
1164 pa_log_warn("Moving synchronised streams not supported.");
1165 return FALSE;
1166 }
1167
1168 return TRUE;
1169 }
1170
1171 /* Called from main context */
1172 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1173 pa_sink_input_assert_ref(i);
1174 pa_assert_ctl_context();
1175 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1176 pa_sink_assert_ref(dest);
1177
1178 if (dest == i->sink)
1179 return TRUE;
1180
1181 if (!pa_sink_input_may_move(i))
1182 return FALSE;
1183
1184 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1185 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1186 return FALSE;
1187 }
1188
1189 if (i->may_move_to)
1190 if (!i->may_move_to(i, dest))
1191 return FALSE;
1192
1193 return TRUE;
1194 }
1195
1196 /* Called from main context */
1197 int pa_sink_input_start_move(pa_sink_input *i) {
1198 pa_source_output *o, *p = NULL;
1199 int r;
1200
1201 pa_sink_input_assert_ref(i);
1202 pa_assert_ctl_context();
1203 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1204 pa_assert(i->sink);
1205
1206 if (!pa_sink_input_may_move(i))
1207 return -PA_ERR_NOTSUPPORTED;
1208
1209 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1210 return r;
1211
1212 /* Kill directly connected outputs */
1213 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1214 pa_assert(o != p);
1215 pa_source_output_kill(o);
1216 p = o;
1217 }
1218 pa_assert(pa_idxset_isempty(i->direct_outputs));
1219
1220 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1221
1222 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1223 pa_assert_se(i->sink->n_corked-- >= 1);
1224
1225 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
1226 /* We might need to update the sink's volume if we are in flat
1227 * volume mode. */
1228 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1229
1230 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1231
1232 pa_sink_update_status(i->sink);
1233 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1234 i->sink = NULL;
1235
1236 pa_sink_input_unref(i);
1237
1238 return 0;
1239 }
1240
1241 /* Called from main context */
1242 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1243 pa_resampler *new_resampler;
1244
1245 pa_sink_input_assert_ref(i);
1246 pa_assert_ctl_context();
1247 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1248 pa_assert(!i->sink);
1249 pa_sink_assert_ref(dest);
1250
1251 if (!pa_sink_input_may_move_to(i, dest))
1252 return -PA_ERR_NOTSUPPORTED;
1253
1254 if (i->thread_info.resampler &&
1255 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1256 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1257
1258 /* Try to reuse the old resampler if possible */
1259 new_resampler = i->thread_info.resampler;
1260
1261 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1262 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1263 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1264
1265 /* Okey, we need a new resampler for the new sink */
1266
1267 if (!(new_resampler = pa_resampler_new(
1268 i->core->mempool,
1269 &i->sample_spec, &i->channel_map,
1270 &dest->sample_spec, &dest->channel_map,
1271 i->requested_resample_method,
1272 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1273 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1274 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1275 pa_log_warn("Unsupported resampling operation.");
1276 return -PA_ERR_NOTSUPPORTED;
1277 }
1278 } else
1279 new_resampler = NULL;
1280
1281 if (i->moving)
1282 i->moving(i, dest);
1283
1284 i->sink = dest;
1285 i->save_sink = save;
1286 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1287
1288 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1289
1290 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1291 i->sink->n_corked++;
1292
1293 /* Replace resampler and render queue */
1294 if (new_resampler != i->thread_info.resampler) {
1295
1296 if (i->thread_info.resampler)
1297 pa_resampler_free(i->thread_info.resampler);
1298 i->thread_info.resampler = new_resampler;
1299
1300 pa_memblockq_free(i->thread_info.render_memblockq);
1301
1302 i->thread_info.render_memblockq = pa_memblockq_new(
1303 0,
1304 MEMBLOCKQ_MAXLENGTH,
1305 0,
1306 pa_frame_size(&i->sink->sample_spec),
1307 0,
1308 1,
1309 0,
1310 &i->sink->silence);
1311 }
1312 pa_sink_update_status(dest);
1313
1314 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1315 pa_cvolume remapped;
1316
1317 /* Make relative volumes absolute */
1318 remapped = dest->reference_volume;
1319 pa_cvolume_remap(&remapped, &dest->channel_map, &i->channel_map);
1320 pa_sw_cvolume_multiply(&i->volume, &i->reference_ratio, &remapped);
1321
1322 /* We might need to update the sink's volume if we are in flat volume mode. */
1323 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1324 }
1325
1326 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1327
1328 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1329
1330 /* Notify everyone */
1331 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1332
1333 if (i->volume_changed)
1334 i->volume_changed(i);
1335
1336 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1337
1338 return 0;
1339 }
1340
1341 /* Called from main context */
1342 void pa_sink_input_fail_move(pa_sink_input *i) {
1343
1344 pa_sink_input_assert_ref(i);
1345 pa_assert_ctl_context();
1346 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1347 pa_assert(!i->sink);
1348
1349 /* Check if someone wants this sink input? */
1350 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1351 return;
1352
1353 if (i->moving)
1354 i->moving(i, NULL);
1355
1356 pa_sink_input_kill(i);
1357 }
1358
1359 /* Called from main context */
1360 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1361 int r;
1362
1363 pa_sink_input_assert_ref(i);
1364 pa_assert_ctl_context();
1365 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1366 pa_assert(i->sink);
1367 pa_sink_assert_ref(dest);
1368
1369 if (dest == i->sink)
1370 return 0;
1371
1372 if (!pa_sink_input_may_move_to(i, dest))
1373 return -PA_ERR_NOTSUPPORTED;
1374
1375 pa_sink_input_ref(i);
1376
1377 if ((r = pa_sink_input_start_move(i)) < 0) {
1378 pa_sink_input_unref(i);
1379 return r;
1380 }
1381
1382 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1383 pa_sink_input_fail_move(i);
1384 pa_sink_input_unref(i);
1385 return r;
1386 }
1387
1388 pa_sink_input_unref(i);
1389
1390 return 0;
1391 }
1392
1393 /* Called from IO thread context */
1394 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1395 pa_bool_t corking, uncorking;
1396
1397 pa_sink_input_assert_ref(i);
1398 pa_sink_input_assert_io_context(i);
1399
1400 if (state == i->thread_info.state)
1401 return;
1402
1403 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1404 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1405 pa_atomic_store(&i->thread_info.drained, 1);
1406
1407 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1408 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1409
1410 if (i->state_change)
1411 i->state_change(i, state);
1412
1413 i->thread_info.state = state;
1414
1415 if (corking) {
1416
1417 pa_log_debug("Requesting rewind due to corking");
1418
1419 /* This will tell the implementing sink input driver to rewind
1420 * so that the unplayed already mixed data is not lost */
1421 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1422
1423 } else if (uncorking) {
1424
1425 i->thread_info.underrun_for = (uint64_t) -1;
1426 i->thread_info.playing_for = 0;
1427
1428 pa_log_debug("Requesting rewind due to uncorking");
1429
1430 /* OK, we're being uncorked. Make sure we're not rewound when
1431 * the hw buffer is remixed and request a remix. */
1432 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1433 }
1434 }
1435
1436 /* Called from thread context, except when it is not. */
1437 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1438 pa_sink_input *i = PA_SINK_INPUT(o);
1439 pa_sink_input_assert_ref(i);
1440
1441 switch (code) {
1442
1443 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1444 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1445 i->thread_info.soft_volume = i->soft_volume;
1446 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1447 }
1448 return 0;
1449
1450 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1451 if (i->thread_info.muted != i->muted) {
1452 i->thread_info.muted = i->muted;
1453 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1454 }
1455 return 0;
1456
1457 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1458 pa_usec_t *r = userdata;
1459
1460 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1461 r[1] += pa_sink_get_latency_within_thread(i->sink);
1462
1463 return 0;
1464 }
1465
1466 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1467
1468 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1469 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1470
1471 return 0;
1472
1473 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1474 pa_sink_input *ssync;
1475
1476 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1477
1478 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1479 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1480
1481 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1482 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1483
1484 return 0;
1485 }
1486
1487 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1488 pa_usec_t *usec = userdata;
1489
1490 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1491 return 0;
1492 }
1493
1494 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1495 pa_usec_t *r = userdata;
1496
1497 *r = i->thread_info.requested_sink_latency;
1498 return 0;
1499 }
1500 }
1501
1502 return -PA_ERR_NOTIMPLEMENTED;
1503 }
1504
1505 /* Called from main thread */
1506 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1507 pa_sink_input_assert_ref(i);
1508 pa_assert_ctl_context();
1509
1510 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1511 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1512
1513 return i->state;
1514 }
1515
1516 /* Called from IO context */
1517 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1518 pa_sink_input_assert_ref(i);
1519 pa_sink_input_assert_io_context(i);
1520
1521 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1522 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1523
1524 return TRUE;
1525 }
1526
1527 /* Called from IO context */
1528 void pa_sink_input_request_rewind(
1529 pa_sink_input *i,
1530 size_t nbytes /* in our sample spec */,
1531 pa_bool_t rewrite,
1532 pa_bool_t flush,
1533 pa_bool_t dont_rewind_render) {
1534
1535 size_t lbq;
1536
1537 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1538 * and possible and the exact value of this is passed back the
1539 * implementor via process_rewind(). If 'flush' is also TRUE all
1540 * already rendered data is also dropped.
1541 *
1542 * If 'rewrite' is FALSE the sink is rewound as far as requested
1543 * and possible and the already rendered data is dropped so that
1544 * in the next iteration we read new data from the
1545 * implementor. This implies 'flush' is TRUE. If
1546 * dont_rewind_render is TRUE then the render memblockq is not
1547 * rewound. */
1548
1549 /* nbytes = 0 means maximum rewind request */
1550
1551 pa_sink_input_assert_ref(i);
1552 pa_sink_input_assert_io_context(i);
1553 pa_assert(rewrite || flush);
1554 pa_assert(!dont_rewind_render || !rewrite);
1555
1556 /* We don't take rewind requests while we are corked */
1557 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1558 return;
1559
1560 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1561
1562 /* pa_log_debug("request rewrite %zu", nbytes); */
1563
1564 /* Calculate how much we can rewind locally without having to
1565 * touch the sink */
1566 if (rewrite)
1567 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1568 else
1569 lbq = 0;
1570
1571 /* Check if rewinding for the maximum is requested, and if so, fix up */
1572 if (nbytes <= 0) {
1573
1574 /* Calculate maximum number of bytes that could be rewound in theory */
1575 nbytes = i->sink->thread_info.max_rewind + lbq;
1576
1577 /* Transform from sink domain */
1578 if (i->thread_info.resampler)
1579 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1580 }
1581
1582 /* Remember how much we actually want to rewrite */
1583 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1584 if (rewrite) {
1585 /* Make sure to not overwrite over underruns */
1586 if (nbytes > i->thread_info.playing_for)
1587 nbytes = (size_t) i->thread_info.playing_for;
1588
1589 i->thread_info.rewrite_nbytes = nbytes;
1590 } else
1591 i->thread_info.rewrite_nbytes = (size_t) -1;
1592 }
1593
1594 i->thread_info.rewrite_flush =
1595 i->thread_info.rewrite_flush ||
1596 (flush && i->thread_info.rewrite_nbytes != 0);
1597
1598 i->thread_info.dont_rewind_render =
1599 i->thread_info.dont_rewind_render ||
1600 dont_rewind_render;
1601
1602 if (nbytes != (size_t) -1) {
1603
1604 /* Transform to sink domain */
1605 if (i->thread_info.resampler)
1606 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1607
1608 if (nbytes > lbq)
1609 pa_sink_request_rewind(i->sink, nbytes - lbq);
1610 else
1611 /* This call will make sure process_rewind() is called later */
1612 pa_sink_request_rewind(i->sink, 0);
1613 }
1614 }
1615
1616 /* Called from main context */
1617 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1618 pa_sink_input_assert_ref(i);
1619 pa_assert_ctl_context();
1620 pa_assert(ret);
1621
1622 /* FIXME: Shouldn't access resampler object from main context! */
1623
1624 pa_silence_memchunk_get(
1625 &i->core->silence_cache,
1626 i->core->mempool,
1627 ret,
1628 &i->sample_spec,
1629 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1630
1631 return ret;
1632 }
1633
1634 /* Called from main context */
1635 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1636 pa_proplist *pl = NULL;
1637 pa_sink_input_send_event_hook_data hook_data;
1638
1639 pa_sink_input_assert_ref(i);
1640 pa_assert_ctl_context();
1641 pa_assert(event);
1642
1643 if (!i->send_event)
1644 return;
1645
1646 if (!data)
1647 data = pl = pa_proplist_new();
1648
1649 hook_data.sink_input = i;
1650 hook_data.data = data;
1651 hook_data.event = event;
1652
1653 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1654 goto finish;
1655
1656 i->send_event(i, event, data);
1657
1658 finish:
1659 if (pl)
1660 pa_proplist_free(pl);
1661 }