1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2004-2006 Lennart Poettering 5 6 PulseAudio is free software; you can redistribute it and/or modify 7 it under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 2.1 of the License, 9 or (at your option) any later version. 10 11 PulseAudio is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#ifdef HAVE_CONFIG_H 21#include <config.h> 22#endif 23 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27 28#include <pulse/utf8.h> 29#include <pulse/xmalloc.h> 30#include <pulse/util.h> 31#include <pulse/internal.h> 32#include <pulse/timeval.h> 33 34#include <pulsecore/core-format.h> 35#include <pulsecore/mix.h> 36#include <pulsecore/stream-util.h> 37#include <pulsecore/core-subscribe.h> 38#include <pulsecore/log.h> 39#include <pulsecore/namereg.h> 40#include <pulsecore/core-util.h> 41 42#include "source-output.h" 43 44#define MEMBLOCKQ_MAXLENGTH (32*1024*1024) 45 46PA_DEFINE_PUBLIC_CLASS(pa_source_output, pa_msgobject); 47 48static void source_output_free(pa_object* mo); 49static void set_real_ratio(pa_source_output *o, const pa_cvolume *v); 50 51pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) { 52 pa_assert(data); 53 54 pa_zero(*data); 55 data->resample_method = PA_RESAMPLER_INVALID; 56 data->proplist = pa_proplist_new(); 57 data->volume_writable = true; 58 59 return data; 60} 61 62void pa_source_output_new_data_set_sample_spec(pa_source_output_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 69void pa_source_output_new_data_set_channel_map(pa_source_output_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 76bool pa_source_output_new_data_is_passthrough(pa_source_output_new_data *data) { 77 pa_assert(data); 78 79 if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format))) 80 return true; 81 82 if (PA_UNLIKELY(data->flags & PA_SOURCE_OUTPUT_PASSTHROUGH)) 83 return true; 84 85 return false; 86} 87 88void pa_source_output_new_data_set_volume(pa_source_output_new_data *data, const pa_cvolume *volume) { 89 pa_assert(data); 90 pa_assert(data->volume_writable); 91 92 if ((data->volume_is_set = !!volume)) 93 data->volume = *volume; 94} 95 96void pa_source_output_new_data_apply_volume_factor(pa_source_output_new_data *data, const pa_cvolume *volume_factor) { 97 pa_assert(data); 98 pa_assert(volume_factor); 99 100 if (data->volume_factor_is_set) 101 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor); 102 else { 103 data->volume_factor_is_set = true; 104 data->volume_factor = *volume_factor; 105 } 106} 107 108void pa_source_output_new_data_apply_volume_factor_source(pa_source_output_new_data *data, const pa_cvolume *volume_factor) { 109 pa_assert(data); 110 pa_assert(volume_factor); 111 112 if (data->volume_factor_source_is_set) 113 pa_sw_cvolume_multiply(&data->volume_factor_source, &data->volume_factor_source, volume_factor); 114 else { 115 data->volume_factor_source_is_set = true; 116 data->volume_factor_source = *volume_factor; 117 } 118} 119 120void pa_source_output_new_data_set_muted(pa_source_output_new_data *data, bool mute) { 121 pa_assert(data); 122 123 data->muted_is_set = true; 124 data->muted = mute; 125} 126 127bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save, 128 bool requested_by_application) { 129 bool ret = true; 130 pa_idxset *formats = NULL; 131 132 pa_assert(data); 133 pa_assert(s); 134 135 if (!data->req_formats) { 136 /* We're not working with the extended API */ 137 data->source = s; 138 if (save) { 139 pa_xfree(data->preferred_source); 140 data->preferred_source = pa_xstrdup(s->name); 141 } 142 data->source_requested_by_application = requested_by_application; 143 } else { 144 /* Extended API: let's see if this source supports the formats the client would like */ 145 formats = pa_source_check_formats(s, data->req_formats); 146 147 if (formats && !pa_idxset_isempty(formats)) { 148 /* Source supports at least one of the requested formats */ 149 data->source = s; 150 if (save) { 151 pa_xfree(data->preferred_source); 152 data->preferred_source = pa_xstrdup(s->name); 153 } 154 data->source_requested_by_application = requested_by_application; 155 if (data->nego_formats) 156 pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free); 157 data->nego_formats = formats; 158 } else { 159 /* Source doesn't support any of the formats requested by the client */ 160 if (formats) 161 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free); 162 ret = false; 163 } 164 } 165 166 return ret; 167} 168 169bool pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_idxset *formats) { 170 pa_assert(data); 171 pa_assert(formats); 172 173 if (data->req_formats) 174 pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free); 175 176 data->req_formats = formats; 177 178 if (data->source) { 179 /* Trigger format negotiation */ 180 return pa_source_output_new_data_set_source(data, data->source, (data->preferred_source != NULL), 181 data->source_requested_by_application); 182 } 183 184 return true; 185} 186 187void pa_source_output_new_data_done(pa_source_output_new_data *data) { 188 pa_assert(data); 189 190 if (data->req_formats) 191 pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free); 192 193 if (data->nego_formats) 194 pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free); 195 196 if (data->format) 197 pa_format_info_free(data->format); 198 199 if (data->preferred_source) 200 pa_xfree(data->preferred_source); 201 202 pa_proplist_free(data->proplist); 203} 204 205/* Called from main context */ 206static void reset_callbacks(pa_source_output *o) { 207 pa_assert(o); 208 209 o->push = NULL; 210 o->process_rewind = NULL; 211 o->update_max_rewind = NULL; 212 o->update_source_requested_latency = NULL; 213 o->update_source_latency_range = NULL; 214 o->update_source_fixed_latency = NULL; 215 o->attach = NULL; 216 o->detach = NULL; 217 o->suspend = NULL; 218 o->suspend_within_thread = NULL; 219 o->moving = NULL; 220 o->kill = NULL; 221 o->get_latency = NULL; 222 o->state_change = NULL; 223 o->may_move_to = NULL; 224 o->send_event = NULL; 225 o->volume_changed = NULL; 226 o->mute_changed = NULL; 227} 228 229/* Called from main context */ 230int pa_source_output_new( 231 pa_source_output**_o, 232 pa_core *core, 233 pa_source_output_new_data *data) { 234 235 pa_source_output *o; 236 pa_resampler *resampler = NULL; 237 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], fmt[PA_FORMAT_INFO_SNPRINT_MAX]; 238 pa_channel_map volume_map; 239 int r; 240 char *pt; 241 size_t resampler_history; 242 243 pa_assert(_o); 244 pa_assert(core); 245 pa_assert(data); 246 pa_assert_ctl_context(); 247 248 if (data->client) 249 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); 250 251 if (data->destination_source && (data->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) 252 data->volume_writable = false; 253 254 if (!data->req_formats) { 255 /* From this point on, we want to work only with formats, and get back 256 * to using the sample spec and channel map after all decisions w.r.t. 257 * routing are complete. */ 258 pa_format_info *f; 259 pa_idxset *formats; 260 261 f = pa_format_info_from_sample_spec2(&data->sample_spec, data->channel_map_is_set ? &data->channel_map : NULL, 262 !(data->flags & PA_SOURCE_OUTPUT_FIX_FORMAT), 263 !(data->flags & PA_SOURCE_OUTPUT_FIX_RATE), 264 !(data->flags & PA_SOURCE_OUTPUT_FIX_CHANNELS)); 265 if (!f) 266 return -PA_ERR_INVALID; 267 268 formats = pa_idxset_new(NULL, NULL); 269 pa_idxset_put(formats, f, NULL); 270 pa_source_output_new_data_set_formats(data, formats); 271 } 272 273 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], data)) < 0) 274 return r; 275 276 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID); 277 278 if (!data->source) { 279 pa_source *source; 280 281 if (data->direct_on_input) { 282 source = data->direct_on_input->sink->monitor_source; 283 pa_return_val_if_fail(source, -PA_ERR_INVALID); 284 } else { 285 source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE); 286 pa_return_val_if_fail(source, -PA_ERR_NOENTITY); 287 } 288 289 pa_source_output_new_data_set_source(data, source, false, false); 290 } 291 292 /* If something didn't pick a format for us, pick the top-most format since 293 * we assume this is sorted in priority order */ 294 if (!data->format && data->nego_formats && !pa_idxset_isempty(data->nego_formats)) 295 data->format = pa_format_info_copy(pa_idxset_first(data->nego_formats, NULL)); 296 297 if (PA_LIKELY(data->format)) { 298 /* We know that data->source is set, because data->format has been set. 299 * data->format is set after a successful format negotiation, and that 300 * can't happen before data->source has been set. */ 301 pa_assert(data->source); 302 303 pa_log_debug("Negotiated format: %s", pa_format_info_snprint(fmt, sizeof(fmt), data->format)); 304 } else { 305 pa_format_info *format; 306 uint32_t idx; 307 308 pa_log_info("Source does not support any requested format:"); 309 PA_IDXSET_FOREACH(format, data->req_formats, idx) 310 pa_log_info(" -- %s", pa_format_info_snprint(fmt, sizeof(fmt), format)); 311 312 return -PA_ERR_NOTSUPPORTED; 313 } 314 315 pa_return_val_if_fail(PA_SOURCE_IS_LINKED(data->source->state), -PA_ERR_BADSTATE); 316 pa_return_val_if_fail(!data->direct_on_input || data->direct_on_input->sink == data->source->monitor_of, -PA_ERR_INVALID); 317 318 /* Routing is done. We have a source and a format. */ 319 320 if (data->volume_is_set && !pa_source_output_new_data_is_passthrough(data)) { 321 /* If volume is set, we need to save the original data->channel_map, 322 * so that we can remap the volume from the original channel map to the 323 * final channel map of the stream in case data->channel_map gets 324 * modified in pa_format_info_to_sample_spec2(). */ 325 r = pa_stream_get_volume_channel_map(&data->volume, data->channel_map_is_set ? &data->channel_map : NULL, data->format, &volume_map); 326 if (r < 0) 327 return r; 328 } else { 329 /* Initialize volume_map to invalid state. We check the state later to 330 * determine if volume remapping is needed. */ 331 pa_channel_map_init(&volume_map); 332 } 333 334 /* Now populate the sample spec and channel map according to the final 335 * format that we've negotiated */ 336 r = pa_format_info_to_sample_spec2(data->format, &data->sample_spec, &data->channel_map, &data->source->sample_spec, 337 &data->source->channel_map); 338 if (r < 0) 339 return r; 340 341 /* Don't restore (or save) stream volume for passthrough streams and 342 * prevent attenuation/gain */ 343 if (pa_source_output_new_data_is_passthrough(data)) { 344 data->volume_is_set = true; 345 pa_cvolume_reset(&data->volume, data->sample_spec.channels); 346 data->volume_is_absolute = true; 347 data->save_volume = false; 348 } 349 350 if (!data->volume_is_set) { 351 pa_cvolume_reset(&data->volume, data->sample_spec.channels); 352 data->volume_is_absolute = false; 353 data->save_volume = false; 354 } 355 356 if (!data->volume_writable) 357 data->save_volume = false; 358 359 if (pa_channel_map_valid(&volume_map)) 360 /* The original volume channel map may be different than the final 361 * stream channel map, so remapping may be needed. */ 362 pa_cvolume_remap(&data->volume, &volume_map, &data->channel_map); 363 364 if (!data->volume_factor_is_set) 365 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels); 366 367 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID); 368 369 if (!data->volume_factor_source_is_set) 370 pa_cvolume_reset(&data->volume_factor_source, data->source->sample_spec.channels); 371 372 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_source, &data->source->sample_spec), -PA_ERR_INVALID); 373 374 if (!data->muted_is_set) 375 data->muted = false; 376 377 if (!(data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) && 378 !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec)) { 379 /* try to change source format and rate. This is done before the FIXATE hook since 380 module-suspend-on-idle can resume a source */ 381 382 pa_log_info("Trying to change sample spec"); 383 pa_source_reconfigure(data->source, &data->sample_spec, pa_source_output_new_data_is_passthrough(data)); 384 } 385 386 if (pa_source_output_new_data_is_passthrough(data) && 387 !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec)) { 388 /* rate update failed, or other parts of sample spec didn't match */ 389 390 pa_log_debug("Could not update source sample spec to match passthrough stream"); 391 return -PA_ERR_NOTSUPPORTED; 392 } 393 394 if (data->resample_method == PA_RESAMPLER_INVALID) 395 data->resample_method = core->resample_method; 396 397 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID); 398 399 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], data)) < 0) 400 return r; 401 402 if ((data->flags & PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND) && 403 data->source->state == PA_SOURCE_SUSPENDED) { 404 pa_log("Failed to create source output: source is suspended."); 405 return -PA_ERR_BADSTATE; 406 } 407 408 if (pa_idxset_size(data->source->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { 409 pa_log("Failed to create source output: too many outputs per source."); 410 return -PA_ERR_TOOLARGE; 411 } 412 413 if ((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) || 414 !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) || 415 !pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) { 416 417 if (!pa_source_output_new_data_is_passthrough(data)) /* no resampler for passthrough content */ 418 if (!(resampler = pa_resampler_new( 419 core->mempool, 420 &data->source->sample_spec, &data->source->channel_map, 421 &data->sample_spec, &data->channel_map, 422 core->lfe_crossover_freq, 423 data->resample_method, 424 ((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) | 425 ((data->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) | 426 (core->disable_remixing || (data->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) | 427 (core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) | 428 (core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) | 429 (core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0)))) { 430 pa_log_warn("Unsupported resampling operation."); 431 return -PA_ERR_NOTSUPPORTED; 432 } 433 } 434 435 o = pa_msgobject_new(pa_source_output); 436 o->parent.parent.free = source_output_free; 437 o->parent.process_msg = pa_source_output_process_msg; 438 439 o->core = core; 440 o->state = PA_SOURCE_OUTPUT_INIT; 441 o->flags = data->flags; 442 o->proplist = pa_proplist_copy(data->proplist); 443 o->driver = pa_xstrdup(pa_path_get_filename(data->driver)); 444 o->module = data->module; 445 o->source = data->source; 446 o->source_requested_by_application = data->source_requested_by_application; 447 o->destination_source = data->destination_source; 448 o->client = data->client; 449 450 o->requested_resample_method = data->resample_method; 451 o->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID; 452 o->sample_spec = data->sample_spec; 453 o->channel_map = data->channel_map; 454 o->format = pa_format_info_copy(data->format); 455 456 if (!data->volume_is_absolute && pa_source_flat_volume_enabled(o->source)) { 457 pa_cvolume remapped; 458 459 /* When the 'absolute' bool is not set then we'll treat the volume 460 * as relative to the source volume even in flat volume mode */ 461 remapped = data->source->reference_volume; 462 pa_cvolume_remap(&remapped, &data->source->channel_map, &data->channel_map); 463 pa_sw_cvolume_multiply(&o->volume, &data->volume, &remapped); 464 } else 465 o->volume = data->volume; 466 467 o->volume_factor = data->volume_factor; 468 o->volume_factor_source = data->volume_factor_source; 469 o->real_ratio = o->reference_ratio = data->volume; 470 pa_cvolume_reset(&o->soft_volume, o->sample_spec.channels); 471 pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels); 472 o->volume_writable = data->volume_writable; 473 o->save_volume = data->save_volume; 474 o->preferred_source = pa_xstrdup(data->preferred_source); 475 o->save_muted = data->save_muted; 476 477 o->muted = data->muted; 478 479 o->direct_on_input = data->direct_on_input; 480 481 reset_callbacks(o); 482 o->userdata = NULL; 483 484 o->thread_info.state = o->state; 485 o->thread_info.attached = false; 486 o->thread_info.sample_spec = o->sample_spec; 487 o->thread_info.resampler = resampler; 488 o->thread_info.soft_volume = o->soft_volume; 489 o->thread_info.muted = o->muted; 490 o->thread_info.requested_source_latency = (pa_usec_t) -1; 491 o->thread_info.direct_on_input = o->direct_on_input; 492 493 o->thread_info.delay_memblockq = pa_memblockq_new( 494 "source output delay_memblockq", 495 0, 496 MEMBLOCKQ_MAXLENGTH, 497 0, 498 &o->source->sample_spec, 499 0, 500 1, 501 0, 502 &o->source->silence); 503 504 resampler_history = (uint64_t) PA_RESAMPLER_MAX_DELAY_USEC * o->source->sample_spec.rate / PA_USEC_PER_SEC; 505 resampler_history *= pa_frame_size(&o->source->sample_spec); 506 507 pa_memblockq_set_maxrewind(o->thread_info.delay_memblockq, resampler_history + pa_source_get_max_rewind(o->source)); 508 509 pa_assert_se(pa_idxset_put(core->source_outputs, o, &o->index) == 0); 510 pa_assert_se(pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL) == 0); 511 512 if (o->client) 513 pa_assert_se(pa_idxset_put(o->client->source_outputs, o, NULL) >= 0); 514 515 if (o->direct_on_input) 516 pa_assert_se(pa_idxset_put(o->direct_on_input->direct_outputs, o, NULL) == 0); 517 518 pt = pa_proplist_to_string_sep(o->proplist, "\n "); 519 pa_log_info("Created output %u \"%s\" on %s with sample spec %s and channel map %s\n %s", 520 o->index, 521 pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)), 522 o->source->name, 523 pa_sample_spec_snprint(st, sizeof(st), &o->sample_spec), 524 pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map), 525 pt); 526 pa_xfree(pt); 527 528 /* Don't forget to call pa_source_output_put! */ 529 530 *_o = o; 531 return 0; 532} 533 534/* Called from main context */ 535static void update_n_corked(pa_source_output *o, pa_source_output_state_t state) { 536 pa_assert(o); 537 pa_assert_ctl_context(); 538 539 if (!o->source) 540 return; 541 542 if (o->state == PA_SOURCE_OUTPUT_CORKED && state != PA_SOURCE_OUTPUT_CORKED) 543 pa_assert_se(o->source->n_corked -- >= 1); 544 else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED) 545 o->source->n_corked++; 546} 547 548/* Called from main context */ 549static void source_output_set_state(pa_source_output *o, pa_source_output_state_t state) { 550 551 pa_assert(o); 552 pa_assert_ctl_context(); 553 554 if (o->state == state) 555 return; 556 557 if (o->source) { 558 if (o->state == PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_RUNNING && pa_source_used_by(o->source) == 0 && 559 !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec)) { 560 /* We were uncorked and the source was not playing anything -- let's try 561 * to update the sample format and rate to avoid resampling */ 562 pa_source_reconfigure(o->source, &o->sample_spec, pa_source_output_is_passthrough(o)); 563 } 564 565 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0); 566 } else 567 /* If the source is not valid, pa_source_output_set_state_within_thread() must be called directly */ 568 pa_source_output_set_state_within_thread(o, state); 569 570 update_n_corked(o, state); 571 o->state = state; 572 573 if (state != PA_SOURCE_OUTPUT_UNLINKED) { 574 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], o); 575 576 if (PA_SOURCE_OUTPUT_IS_LINKED(state)) 577 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 578 } 579 580 if (o->source) 581 pa_source_update_status(o->source); 582} 583 584/* Called from main context */ 585void pa_source_output_unlink(pa_source_output*o) { 586 bool linked; 587 588 pa_source_output_assert_ref(o); 589 pa_assert_ctl_context(); 590 591 /* See pa_sink_unlink() for a couple of comments how this function 592 * works */ 593 594 pa_source_output_ref(o); 595 596 linked = PA_SOURCE_OUTPUT_IS_LINKED(o->state); 597 598 if (linked) 599 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], o); 600 601 if (o->direct_on_input) 602 pa_idxset_remove_by_data(o->direct_on_input->direct_outputs, o, NULL); 603 604 pa_idxset_remove_by_data(o->core->source_outputs, o, NULL); 605 606 if (o->source) 607 if (pa_idxset_remove_by_data(o->source->outputs, o, NULL)) 608 pa_source_output_unref(o); 609 610 if (o->client) 611 pa_idxset_remove_by_data(o->client->source_outputs, o, NULL); 612 613 update_n_corked(o, PA_SOURCE_OUTPUT_UNLINKED); 614 o->state = PA_SOURCE_OUTPUT_UNLINKED; 615 616 if (linked && o->source) { 617 if (pa_source_output_is_passthrough(o)) 618 pa_source_leave_passthrough(o->source); 619 620 /* We might need to update the source's volume if we are in flat volume mode. */ 621 if (pa_source_flat_volume_enabled(o->source)) 622 pa_source_set_volume(o->source, NULL, false, false); 623 624 if (o->source->asyncmsgq) 625 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL) == 0); 626 } 627 628 reset_callbacks(o); 629 630 if (o->source) { 631 if (PA_SOURCE_IS_LINKED(o->source->state)) 632 pa_source_update_status(o->source); 633 634 o->source = NULL; 635 } 636 637 if (linked) { 638 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); 639 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], o); 640 } 641 642 pa_core_maybe_vacuum(o->core); 643 644 pa_source_output_unref(o); 645} 646 647/* Called from main context */ 648static void source_output_free(pa_object* mo) { 649 pa_source_output *o = PA_SOURCE_OUTPUT(mo); 650 651 pa_assert(o); 652 pa_assert_ctl_context(); 653 pa_assert(pa_source_output_refcnt(o) == 0); 654 pa_assert(!PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 655 656 pa_log_info("Freeing output %u \"%s\"", o->index, 657 o->proplist ? pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)) : ""); 658 659 if (o->thread_info.delay_memblockq) 660 pa_memblockq_free(o->thread_info.delay_memblockq); 661 662 if (o->thread_info.resampler) 663 pa_resampler_free(o->thread_info.resampler); 664 665 if (o->format) 666 pa_format_info_free(o->format); 667 668 if (o->proplist) 669 pa_proplist_free(o->proplist); 670 671 if (o->preferred_source) 672 pa_xfree(o->preferred_source); 673 674 pa_xfree(o->driver); 675 pa_xfree(o); 676} 677 678/* Called from main context */ 679void pa_source_output_put(pa_source_output *o) { 680 pa_source_output_state_t state; 681 682 pa_source_output_assert_ref(o); 683 pa_assert_ctl_context(); 684 685 pa_assert(o->state == PA_SOURCE_OUTPUT_INIT); 686 687 /* The following fields must be initialized properly */ 688 pa_assert(o->push); 689 pa_assert(o->kill); 690 691 state = o->flags & PA_SOURCE_OUTPUT_START_CORKED ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; 692 693 update_n_corked(o, state); 694 o->state = state; 695 696 /* We might need to update the source's volume if we are in flat volume mode. */ 697 if (pa_source_flat_volume_enabled(o->source)) 698 pa_source_set_volume(o->source, NULL, false, o->save_volume); 699 else { 700 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) { 701 pa_assert(pa_cvolume_is_norm(&o->volume)); 702 pa_assert(pa_cvolume_is_norm(&o->reference_ratio)); 703 } 704 705 set_real_ratio(o, &o->volume); 706 } 707 708 if (pa_source_output_is_passthrough(o)) 709 pa_source_enter_passthrough(o->source); 710 711 o->thread_info.soft_volume = o->soft_volume; 712 o->thread_info.muted = o->muted; 713 714 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL) == 0); 715 716 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); 717 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], o); 718 719 pa_source_update_status(o->source); 720} 721 722/* Called from main context */ 723void pa_source_output_kill(pa_source_output*o) { 724 pa_source_output_assert_ref(o); 725 pa_assert_ctl_context(); 726 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 727 728 o->kill(o); 729} 730 731/* Called from main context */ 732pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency) { 733 pa_usec_t r[2] = { 0, 0 }; 734 735 pa_source_output_assert_ref(o); 736 pa_assert_ctl_context(); 737 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 738 739 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0); 740 741 if (o->get_latency) 742 r[0] += o->get_latency(o); 743 744 if (source_latency) 745 *source_latency = r[1]; 746 747 return r[0]; 748} 749 750/* Called from thread context */ 751void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { 752 bool need_volume_factor_source; 753 bool volume_is_norm; 754 size_t length; 755 size_t limit, mbs = 0; 756 757 pa_source_output_assert_ref(o); 758 pa_source_output_assert_io_context(o); 759 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->thread_info.state)); 760 pa_assert(chunk); 761 pa_assert(pa_frame_aligned(chunk->length, &o->source->sample_spec)); 762 763 if (!o->push || o->thread_info.state == PA_SOURCE_OUTPUT_CORKED) 764 return; 765 766 pa_assert(o->thread_info.state == PA_SOURCE_OUTPUT_RUNNING); 767 768 if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) { 769 pa_log_debug("Delay queue overflow!"); 770 pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE, true); 771 } 772 773 limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind; 774 775 volume_is_norm = pa_cvolume_is_norm(&o->thread_info.soft_volume) && !o->thread_info.muted; 776 need_volume_factor_source = !pa_cvolume_is_norm(&o->volume_factor_source); 777 778 if (limit > 0 && o->source->monitor_of) { 779 pa_usec_t latency; 780 size_t n; 781 782 /* Hmm, check the latency for knowing how much of the buffered 783 * data is actually still unplayed and might hence still 784 * change. This is suboptimal. Ideally we'd have a call like 785 * pa_sink_get_changeable_size() or so that tells us how much 786 * of the queued data is actually still changeable. Hence 787 * FIXME! */ 788 789 latency = pa_sink_get_latency_within_thread(o->source->monitor_of, false); 790 791 n = pa_usec_to_bytes(latency, &o->source->sample_spec); 792 793 if (n < limit) 794 limit = n; 795 } 796 797 /* Implement the delay queue */ 798 while ((length = pa_memblockq_get_length(o->thread_info.delay_memblockq)) > limit) { 799 pa_memchunk qchunk; 800 bool nvfs = need_volume_factor_source; 801 802 length -= limit; 803 804 pa_assert_se(pa_memblockq_peek(o->thread_info.delay_memblockq, &qchunk) >= 0); 805 806 if (qchunk.length > length) 807 qchunk.length = length; 808 809 pa_assert(qchunk.length > 0); 810 811 /* It might be necessary to adjust the volume here */ 812 if (!volume_is_norm) { 813 pa_memchunk_make_writable(&qchunk, 0); 814 815 if (o->thread_info.muted) { 816 pa_silence_memchunk(&qchunk, &o->source->sample_spec); 817 nvfs = false; 818 819 } else if (!o->thread_info.resampler && nvfs) { 820 pa_cvolume v; 821 822 /* If we don't need a resampler we can merge the 823 * post and the pre volume adjustment into one */ 824 825 pa_sw_cvolume_multiply(&v, &o->thread_info.soft_volume, &o->volume_factor_source); 826 pa_volume_memchunk(&qchunk, &o->source->sample_spec, &v); 827 nvfs = false; 828 829 } else 830 pa_volume_memchunk(&qchunk, &o->source->sample_spec, &o->thread_info.soft_volume); 831 } 832 833 if (nvfs) { 834 pa_memchunk_make_writable(&qchunk, 0); 835 pa_volume_memchunk(&qchunk, &o->source->sample_spec, &o->volume_factor_source); 836 } 837 838 if (!o->thread_info.resampler) 839 o->push(o, &qchunk); 840 else { 841 pa_memchunk rchunk; 842 843 if (mbs == 0) 844 mbs = pa_resampler_max_block_size(o->thread_info.resampler); 845 846 if (qchunk.length > mbs) 847 qchunk.length = mbs; 848 849 pa_resampler_run(o->thread_info.resampler, &qchunk, &rchunk); 850 851 if (rchunk.length > 0) 852 o->push(o, &rchunk); 853 854 if (rchunk.memblock) 855 pa_memblock_unref(rchunk.memblock); 856 } 857 858 pa_memblock_unref(qchunk.memblock); 859 pa_memblockq_drop(o->thread_info.delay_memblockq, qchunk.length); 860 } 861} 862 863/* Called from thread context */ 864void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in source sample spec */) { 865 866 pa_source_output_assert_ref(o); 867 pa_source_output_assert_io_context(o); 868 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->thread_info.state)); 869 pa_assert(pa_frame_aligned(nbytes, &o->source->sample_spec)); 870 871 if (nbytes <= 0) 872 return; 873 874 if (o->process_rewind) { 875 size_t source_output_nbytes; 876 size_t length; 877 878 /* The length of the memblockq may be non-zero if pa_source_output_rewind() is called twice 879 * without pa_source_output_push() called in between. In that case, the resampler has already 880 * been reset and we can skip that part. */ 881 length = pa_memblockq_get_length(o->thread_info.delay_memblockq); 882 883 pa_memblockq_rewind(o->thread_info.delay_memblockq, nbytes); 884 885 source_output_nbytes = pa_resampler_result(o->thread_info.resampler, nbytes); 886 887 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) source_output_nbytes); 888 889 if (source_output_nbytes > 0) 890 o->process_rewind(o, source_output_nbytes); 891 892 if (o->thread_info.resampler && length == 0) { 893 size_t resampler_bytes; 894 895 /* Round down to full frames */ 896 resampler_bytes = (size_t) pa_resampler_get_delay(o->thread_info.resampler, false) * pa_frame_size(&o->source->sample_spec); 897 if (resampler_bytes > 0) 898 pa_memblockq_rewind(o->thread_info.delay_memblockq, resampler_bytes); 899 900 pa_resampler_rewind(o->thread_info.resampler, source_output_nbytes, NULL, 0); 901 } 902 } 903 904 pa_memblockq_seek(o->thread_info.delay_memblockq, - ((int64_t) nbytes), PA_SEEK_RELATIVE, true); 905} 906 907/* Called from thread context */ 908size_t pa_source_output_get_max_rewind(pa_source_output *o) { 909 pa_source_output_assert_ref(o); 910 pa_source_output_assert_io_context(o); 911 912 return pa_resampler_result(o->thread_info.resampler, o->source->thread_info.max_rewind); 913} 914 915/* Called from thread context */ 916void pa_source_output_update_max_rewind(pa_source_output *o, size_t nbytes /* in the source's sample spec */) { 917 size_t resampler_history; 918 919 pa_source_output_assert_ref(o); 920 pa_source_output_assert_io_context(o); 921 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->thread_info.state)); 922 pa_assert(pa_frame_aligned(nbytes, &o->source->sample_spec)); 923 924 resampler_history = (uint64_t) PA_RESAMPLER_MAX_DELAY_USEC * o->source->sample_spec.rate / PA_USEC_PER_SEC; 925 resampler_history *= pa_frame_size(&o->source->sample_spec); 926 927 pa_memblockq_set_maxrewind(o->thread_info.delay_memblockq, resampler_history + nbytes); 928 929 if (o->update_max_rewind) 930 o->update_max_rewind(o, pa_resampler_result(o->thread_info.resampler, nbytes)); 931} 932 933/* Called from thread context */ 934pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec) { 935 pa_source_output_assert_ref(o); 936 pa_source_output_assert_io_context(o); 937 938 if (!(o->source->flags & PA_SOURCE_DYNAMIC_LATENCY)) 939 usec = o->source->thread_info.fixed_latency; 940 941 if (usec != (pa_usec_t) -1) 942 usec = PA_CLAMP(usec, o->source->thread_info.min_latency, o->source->thread_info.max_latency); 943 944 o->thread_info.requested_source_latency = usec; 945 pa_source_invalidate_requested_latency(o->source, true); 946 947 return usec; 948} 949 950/* Called from main context */ 951pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec) { 952 pa_source_output_assert_ref(o); 953 pa_assert_ctl_context(); 954 955 if (PA_SOURCE_OUTPUT_IS_LINKED(o->state) && o->source) { 956 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0); 957 return usec; 958 } 959 960 /* If this source output is not realized yet or is being moved, we 961 * have to touch the thread info data directly */ 962 963 if (o->source) { 964 if (!(o->source->flags & PA_SOURCE_DYNAMIC_LATENCY)) 965 usec = pa_source_get_fixed_latency(o->source); 966 967 if (usec != (pa_usec_t) -1) { 968 pa_usec_t min_latency, max_latency; 969 pa_source_get_latency_range(o->source, &min_latency, &max_latency); 970 usec = PA_CLAMP(usec, min_latency, max_latency); 971 } 972 } 973 974 o->thread_info.requested_source_latency = usec; 975 976 return usec; 977} 978 979/* Called from main context */ 980pa_usec_t pa_source_output_get_requested_latency(pa_source_output *o) { 981 pa_source_output_assert_ref(o); 982 pa_assert_ctl_context(); 983 984 if (PA_SOURCE_OUTPUT_IS_LINKED(o->state) && o->source) { 985 pa_usec_t usec = 0; 986 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0); 987 return usec; 988 } 989 990 /* If this source output is not realized yet or is being moved, we 991 * have to touch the thread info data directly */ 992 993 return o->thread_info.requested_source_latency; 994} 995 996/* Called from main context */ 997void pa_source_output_set_volume(pa_source_output *o, const pa_cvolume *volume, bool save, bool absolute) { 998 pa_cvolume v; 999 1000 pa_source_output_assert_ref(o); 1001 pa_assert_ctl_context(); 1002 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1003 pa_assert(volume); 1004 pa_assert(pa_cvolume_valid(volume)); 1005 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &o->sample_spec)); 1006 pa_assert(o->volume_writable); 1007 1008 if (!absolute && pa_source_flat_volume_enabled(o->source)) { 1009 v = o->source->reference_volume; 1010 pa_cvolume_remap(&v, &o->source->channel_map, &o->channel_map); 1011 1012 if (pa_cvolume_compatible(volume, &o->sample_spec)) 1013 volume = pa_sw_cvolume_multiply(&v, &v, volume); 1014 else 1015 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume)); 1016 } else { 1017 if (!pa_cvolume_compatible(volume, &o->sample_spec)) { 1018 v = o->volume; 1019 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume)); 1020 } 1021 } 1022 1023 if (pa_cvolume_equal(volume, &o->volume)) { 1024 o->save_volume = o->save_volume || save; 1025 return; 1026 } 1027 1028 pa_source_output_set_volume_direct(o, volume); 1029 o->save_volume = save; 1030 1031 if (pa_source_flat_volume_enabled(o->source)) { 1032 /* We are in flat volume mode, so let's update all source input 1033 * volumes and update the flat volume of the source */ 1034 1035 pa_source_set_volume(o->source, NULL, true, save); 1036 1037 } else { 1038 /* OK, we are in normal volume mode. The volume only affects 1039 * ourselves */ 1040 set_real_ratio(o, volume); 1041 1042 /* Copy the new soft_volume to the thread_info struct */ 1043 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0); 1044 } 1045 1046 /* The volume changed, let's tell people so */ 1047 if (o->volume_changed) 1048 o->volume_changed(o); 1049 1050 /* The virtual volume changed, let's tell people so */ 1051 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1052} 1053 1054/* Called from main context */ 1055static void set_real_ratio(pa_source_output *o, const pa_cvolume *v) { 1056 pa_source_output_assert_ref(o); 1057 pa_assert_ctl_context(); 1058 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1059 pa_assert(!v || pa_cvolume_compatible(v, &o->sample_spec)); 1060 1061 /* This basically calculates: 1062 * 1063 * o->real_ratio := v 1064 * o->soft_volume := o->real_ratio * o->volume_factor */ 1065 1066 if (v) 1067 o->real_ratio = *v; 1068 else 1069 pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels); 1070 1071 pa_sw_cvolume_multiply(&o->soft_volume, &o->real_ratio, &o->volume_factor); 1072 /* We don't copy the data to the thread_info data. That's left for someone else to do */ 1073} 1074 1075/* Called from main or I/O context */ 1076bool pa_source_output_is_passthrough(pa_source_output *o) { 1077 pa_source_output_assert_ref(o); 1078 1079 if (PA_UNLIKELY(!pa_format_info_is_pcm(o->format))) 1080 return true; 1081 1082 if (PA_UNLIKELY(o->flags & PA_SOURCE_OUTPUT_PASSTHROUGH)) 1083 return true; 1084 1085 return false; 1086} 1087 1088/* Called from main context */ 1089bool pa_source_output_is_volume_readable(pa_source_output *o) { 1090 pa_source_output_assert_ref(o); 1091 pa_assert_ctl_context(); 1092 1093 return !pa_source_output_is_passthrough(o); 1094} 1095 1096/* Called from main context */ 1097pa_cvolume *pa_source_output_get_volume(pa_source_output *o, pa_cvolume *volume, bool absolute) { 1098 pa_source_output_assert_ref(o); 1099 pa_assert_ctl_context(); 1100 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1101 pa_assert(pa_source_output_is_volume_readable(o)); 1102 1103 if (absolute || !pa_source_flat_volume_enabled(o->source)) 1104 *volume = o->volume; 1105 else 1106 *volume = o->reference_ratio; 1107 1108 return volume; 1109} 1110 1111/* Called from main context */ 1112void pa_source_output_set_mute(pa_source_output *o, bool mute, bool save) { 1113 bool old_mute; 1114 1115 pa_source_output_assert_ref(o); 1116 pa_assert_ctl_context(); 1117 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1118 1119 old_mute = o->muted; 1120 1121 if (mute == old_mute) { 1122 o->save_muted |= save; 1123 return; 1124 } 1125 1126 o->muted = mute; 1127 pa_log_debug("The mute of source output %u changed from %s to %s.", o->index, pa_yes_no(old_mute), pa_yes_no(mute)); 1128 1129 o->save_muted = save; 1130 1131 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0); 1132 1133 /* The mute status changed, let's tell people so */ 1134 if (o->mute_changed) 1135 o->mute_changed(o); 1136 1137 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1138 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MUTE_CHANGED], o); 1139} 1140 1141void pa_source_output_set_property(pa_source_output *o, const char *key, const char *value) { 1142 char *old_value = NULL; 1143 const char *new_value; 1144 1145 pa_assert(o); 1146 pa_assert(key); 1147 1148 if (pa_proplist_contains(o->proplist, key)) { 1149 old_value = pa_xstrdup(pa_proplist_gets(o->proplist, key)); 1150 if (value && old_value && pa_streq(value, old_value)) 1151 goto finish; 1152 1153 if (!old_value) 1154 old_value = pa_xstrdup("(data)"); 1155 } else { 1156 if (!value) 1157 goto finish; 1158 1159 old_value = pa_xstrdup("(unset)"); 1160 } 1161 1162 if (value) { 1163 pa_proplist_sets(o->proplist, key, value); 1164 new_value = value; 1165 } else { 1166 pa_proplist_unset(o->proplist, key); 1167 new_value = "(unset)"; 1168 } 1169 1170 if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) { 1171 pa_log_debug("Source output %u: proplist[%s]: %s -> %s", o->index, key, old_value, new_value); 1172 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o); 1173 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1174 } 1175 1176finish: 1177 pa_xfree(old_value); 1178} 1179 1180void pa_source_output_set_property_arbitrary(pa_source_output *o, const char *key, const uint8_t *value, size_t nbytes) { 1181 const uint8_t *old_value; 1182 size_t old_nbytes; 1183 const char *old_value_str; 1184 const char *new_value_str; 1185 1186 pa_assert(o); 1187 pa_assert(key); 1188 1189 if (pa_proplist_get(o->proplist, key, (const void **) &old_value, &old_nbytes) >= 0) { 1190 if (value && nbytes == old_nbytes && !memcmp(value, old_value, nbytes)) 1191 return; 1192 1193 old_value_str = "(data)"; 1194 1195 } else { 1196 if (!value) 1197 return; 1198 1199 old_value_str = "(unset)"; 1200 } 1201 1202 if (value) { 1203 pa_proplist_set(o->proplist, key, value, nbytes); 1204 new_value_str = "(data)"; 1205 } else { 1206 pa_proplist_unset(o->proplist, key); 1207 new_value_str = "(unset)"; 1208 } 1209 1210 if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) { 1211 pa_log_debug("Source output %u: proplist[%s]: %s -> %s", o->index, key, old_value_str, new_value_str); 1212 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o); 1213 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1214 } 1215} 1216 1217/* Called from main thread */ 1218void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) { 1219 void *state; 1220 const char *key; 1221 const uint8_t *value; 1222 size_t nbytes; 1223 1224 pa_source_output_assert_ref(o); 1225 pa_assert(p); 1226 pa_assert_ctl_context(); 1227 1228 switch (mode) { 1229 case PA_UPDATE_SET: 1230 /* Delete everything that is not in p. */ 1231 for (state = NULL; (key = pa_proplist_iterate(o->proplist, &state));) { 1232 if (!pa_proplist_contains(p, key)) 1233 pa_source_output_set_property(o, key, NULL); 1234 } 1235 1236 /* Fall through. */ 1237 case PA_UPDATE_REPLACE: 1238 for (state = NULL; (key = pa_proplist_iterate(p, &state));) { 1239 pa_proplist_get(p, key, (const void **) &value, &nbytes); 1240 pa_source_output_set_property_arbitrary(o, key, value, nbytes); 1241 } 1242 1243 break; 1244 case PA_UPDATE_MERGE: 1245 for (state = NULL; (key = pa_proplist_iterate(p, &state));) { 1246 if (pa_proplist_contains(o->proplist, key)) 1247 continue; 1248 1249 pa_proplist_get(p, key, (const void **) &value, &nbytes); 1250 pa_source_output_set_property_arbitrary(o, key, value, nbytes); 1251 } 1252 1253 break; 1254 } 1255} 1256 1257/* Called from main context */ 1258void pa_source_output_cork(pa_source_output *o, bool b) { 1259 pa_source_output_assert_ref(o); 1260 pa_assert_ctl_context(); 1261 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1262 1263 source_output_set_state(o, b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING); 1264} 1265 1266/* Called from main context */ 1267int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { 1268 pa_source_output_assert_ref(o); 1269 pa_assert_ctl_context(); 1270 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1271 pa_return_val_if_fail(o->thread_info.resampler, -PA_ERR_BADSTATE); 1272 1273 if (o->sample_spec.rate == rate) 1274 return 0; 1275 1276 o->sample_spec.rate = rate; 1277 1278 pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL); 1279 1280 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1281 return 0; 1282} 1283 1284/* Called from main context */ 1285pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { 1286 pa_source_output_assert_ref(o); 1287 pa_assert_ctl_context(); 1288 1289 return o->actual_resample_method; 1290} 1291 1292/* Called from main context */ 1293bool pa_source_output_may_move(pa_source_output *o) { 1294 pa_source_output_assert_ref(o); 1295 pa_assert_ctl_context(); 1296 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1297 1298 if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE) 1299 return false; 1300 1301 if (o->direct_on_input) 1302 return false; 1303 1304 return true; 1305} 1306 1307static bool find_filter_source_output(pa_source_output *target, pa_source *s) { 1308 unsigned PA_UNUSED i = 0; 1309 while (s && s->output_from_master) { 1310 if (s->output_from_master == target) 1311 return true; 1312 s = s->output_from_master->source; 1313 pa_assert(i++ < 100); 1314 } 1315 return false; 1316} 1317 1318static bool is_filter_source_moving(pa_source_output *o) { 1319 pa_source *source = o->source; 1320 1321 if (!source) 1322 return false; 1323 1324 while (source->output_from_master) { 1325 source = source->output_from_master->source; 1326 1327 if (!source) 1328 return true; 1329 } 1330 1331 return false; 1332} 1333 1334/* Called from main context */ 1335bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) { 1336 pa_source_output_assert_ref(o); 1337 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1338 pa_source_assert_ref(dest); 1339 1340 if (dest == o->source) 1341 return true; 1342 1343 if (dest->unlink_requested) 1344 return false; 1345 1346 if (!pa_source_output_may_move(o)) 1347 return false; 1348 1349 /* Make sure we're not creating a filter source cycle */ 1350 if (find_filter_source_output(o, dest)) { 1351 pa_log_debug("Can't connect output to %s, as that would create a cycle.", dest->name); 1352 return false; 1353 } 1354 1355 /* If this source output is connected to a filter source that itself is 1356 * moving, then don't allow the move. Moving requires sending a message to 1357 * the IO thread of the old source, and if the old source is a filter 1358 * source that is moving, there's no IO thread associated to the old 1359 * source. */ 1360 if (is_filter_source_moving(o)) { 1361 pa_log_debug("Can't move output from filter source %s, because the filter source itself is currently moving.", 1362 o->source->name); 1363 return false; 1364 } 1365 1366 if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { 1367 pa_log_warn("Failed to move source output: too many outputs per source."); 1368 return false; 1369 } 1370 1371 if (o->may_move_to) 1372 if (!o->may_move_to(o, dest)) 1373 return false; 1374 1375 return true; 1376} 1377 1378/* Called from main context */ 1379int pa_source_output_start_move(pa_source_output *o) { 1380 pa_source *origin; 1381 int r; 1382 1383 pa_source_output_assert_ref(o); 1384 pa_assert_ctl_context(); 1385 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1386 pa_assert(o->source); 1387 1388 if (!pa_source_output_may_move(o)) 1389 return -PA_ERR_NOTSUPPORTED; 1390 1391 if ((r = pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_START], o)) < 0) 1392 return r; 1393 1394 pa_log_debug("Starting to move source output %u from '%s'", (unsigned) o->index, o->source->name); 1395 1396 origin = o->source; 1397 1398 pa_idxset_remove_by_data(o->source->outputs, o, NULL); 1399 1400 if (o->state == PA_SOURCE_OUTPUT_CORKED) 1401 pa_assert_se(origin->n_corked-- >= 1); 1402 1403 if (pa_source_output_is_passthrough(o)) 1404 pa_source_leave_passthrough(o->source); 1405 1406 if (pa_source_flat_volume_enabled(o->source)) 1407 /* We might need to update the source's volume if we are in flat 1408 * volume mode. */ 1409 pa_source_set_volume(o->source, NULL, false, false); 1410 1411 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL) == 0); 1412 1413 pa_source_update_status(o->source); 1414 1415 pa_cvolume_remap(&o->volume_factor_source, &o->source->channel_map, &o->channel_map); 1416 1417 o->source = NULL; 1418 o->source_requested_by_application = false; 1419 1420 pa_source_output_unref(o); 1421 1422 return 0; 1423} 1424 1425/* Called from main context. If it has an origin source that uses volume sharing, 1426 * then also the origin source and all streams connected to it need to update 1427 * their volume - this function does all that by using recursion. */ 1428static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) { 1429 pa_cvolume new_volume; 1430 1431 pa_assert(o); 1432 pa_assert(dest); 1433 pa_assert(o->source); /* The destination source should already be set. */ 1434 1435 if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) { 1436 pa_source *root_source; 1437 pa_source_output *destination_source_output; 1438 uint32_t idx; 1439 1440 root_source = pa_source_get_master(o->source); 1441 1442 if (PA_UNLIKELY(!root_source)) 1443 return; 1444 1445 if (pa_source_flat_volume_enabled(o->source)) { 1446 /* Ok, so the origin source uses volume sharing, and flat volume is 1447 * enabled. The volume will have to be updated as follows: 1448 * 1449 * o->volume := o->source->real_volume 1450 * (handled later by pa_source_set_volume) 1451 * o->reference_ratio := o->volume / o->source->reference_volume 1452 * (handled later by pa_source_set_volume) 1453 * o->real_ratio stays unchanged 1454 * (streams whose origin source uses volume sharing should 1455 * always have real_ratio of 0 dB) 1456 * o->soft_volume stays unchanged 1457 * (streams whose origin source uses volume sharing should 1458 * always have volume_factor as soft_volume, so no change 1459 * should be needed) */ 1460 1461 pa_assert(pa_cvolume_is_norm(&o->real_ratio)); 1462 pa_assert(pa_cvolume_equal(&o->soft_volume, &o->volume_factor)); 1463 1464 /* Notifications will be sent by pa_source_set_volume(). */ 1465 1466 } else { 1467 /* Ok, so the origin source uses volume sharing, and flat volume is 1468 * disabled. The volume will have to be updated as follows: 1469 * 1470 * o->volume := 0 dB 1471 * o->reference_ratio := 0 dB 1472 * o->real_ratio stays unchanged 1473 * (streams whose origin source uses volume sharing should 1474 * always have real_ratio of 0 dB) 1475 * o->soft_volume stays unchanged 1476 * (streams whose origin source uses volume sharing should 1477 * always have volume_factor as soft_volume, so no change 1478 * should be needed) */ 1479 1480 pa_cvolume_reset(&new_volume, o->volume.channels); 1481 pa_source_output_set_volume_direct(o, &new_volume); 1482 pa_source_output_set_reference_ratio(o, &new_volume); 1483 pa_assert(pa_cvolume_is_norm(&o->real_ratio)); 1484 pa_assert(pa_cvolume_equal(&o->soft_volume, &o->volume_factor)); 1485 } 1486 1487 /* Additionally, the origin source volume needs updating: 1488 * 1489 * o->destination_source->reference_volume := root_source->reference_volume 1490 * o->destination_source->real_volume := root_source->real_volume 1491 * o->destination_source->soft_volume stays unchanged 1492 * (sources that use volume sharing should always have 1493 * soft_volume of 0 dB) */ 1494 1495 new_volume = root_source->reference_volume; 1496 pa_cvolume_remap(&new_volume, &root_source->channel_map, &o->destination_source->channel_map); 1497 pa_source_set_reference_volume_direct(o->destination_source, &new_volume); 1498 1499 o->destination_source->real_volume = root_source->real_volume; 1500 pa_cvolume_remap(&o->destination_source->real_volume, &root_source->channel_map, &o->destination_source->channel_map); 1501 1502 pa_assert(pa_cvolume_is_norm(&o->destination_source->soft_volume)); 1503 1504 /* If you wonder whether o->destination_source->set_volume() should be 1505 * called somewhere, that's not the case, because sources that use 1506 * volume sharing shouldn't have any internal volume that set_volume() 1507 * would update. If you wonder whether the thread_info variables should 1508 * be synced, yes, they should, and it's done by the 1509 * PA_SOURCE_MESSAGE_FINISH_MOVE message handler. */ 1510 1511 /* Recursively update origin source outputs. */ 1512 PA_IDXSET_FOREACH(destination_source_output, o->destination_source->outputs, idx) 1513 update_volume_due_to_moving(destination_source_output, dest); 1514 1515 } else { 1516 if (pa_source_flat_volume_enabled(o->source)) { 1517 /* Ok, so this is a regular stream, and flat volume is enabled. The 1518 * volume will have to be updated as follows: 1519 * 1520 * o->volume := o->reference_ratio * o->source->reference_volume 1521 * o->reference_ratio stays unchanged 1522 * o->real_ratio := o->volume / o->source->real_volume 1523 * (handled later by pa_source_set_volume) 1524 * o->soft_volume := o->real_ratio * o->volume_factor 1525 * (handled later by pa_source_set_volume) */ 1526 1527 new_volume = o->source->reference_volume; 1528 pa_cvolume_remap(&new_volume, &o->source->channel_map, &o->channel_map); 1529 pa_sw_cvolume_multiply(&new_volume, &new_volume, &o->reference_ratio); 1530 pa_source_output_set_volume_direct(o, &new_volume); 1531 1532 } else { 1533 /* Ok, so this is a regular stream, and flat volume is disabled. 1534 * The volume will have to be updated as follows: 1535 * 1536 * o->volume := o->reference_ratio 1537 * o->reference_ratio stays unchanged 1538 * o->real_ratio := o->reference_ratio 1539 * o->soft_volume := o->real_ratio * o->volume_factor */ 1540 1541 pa_source_output_set_volume_direct(o, &o->reference_ratio); 1542 o->real_ratio = o->reference_ratio; 1543 pa_sw_cvolume_multiply(&o->soft_volume, &o->real_ratio, &o->volume_factor); 1544 1545 /* If this is a virtual source stream, we have to apply the source volume 1546 * to the source output. */ 1547 if (o->destination_source) { 1548 pa_cvolume vol; 1549 1550 vol = o->destination_source->real_volume; 1551 pa_cvolume_remap(&vol, &o->destination_source->channel_map, &o->channel_map); 1552 pa_source_output_set_volume(o, &vol, o->destination_source->save_volume, true); 1553 } 1554 } 1555 } 1556 1557 /* If o->source == dest, then recursion has finished, and we can finally call 1558 * pa_source_set_volume(), which will do the rest of the updates. */ 1559 if ((o->source == dest) && pa_source_flat_volume_enabled(o->source)) 1560 pa_source_set_volume(o->source, NULL, false, o->save_volume); 1561} 1562 1563/* Called from the main thread. */ 1564static void set_preferred_source(pa_source_output *o, const char *source_name) { 1565 pa_assert(o); 1566 1567 if (pa_safe_streq(o->preferred_source, source_name)) 1568 return; 1569 1570 pa_log_debug("Source output %u: preferred_source: %s -> %s", 1571 o->index, o->preferred_source ? o->preferred_source : "(unset)", source_name ? source_name : "(unset)"); 1572 pa_xfree(o->preferred_source); 1573 o->preferred_source = pa_xstrdup(source_name); 1574 1575 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1576 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PREFERRED_SOURCE_CHANGED], o); 1577} 1578 1579/* Called from main context */ 1580int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, bool save) { 1581 pa_source_output_assert_ref(o); 1582 pa_assert_ctl_context(); 1583 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1584 pa_assert(!o->source); 1585 pa_source_assert_ref(dest); 1586 1587 if (!pa_source_output_may_move_to(o, dest)) 1588 return -PA_ERR_NOTSUPPORTED; 1589 1590 if (pa_source_output_is_passthrough(o) && !pa_source_check_format(dest, o->format)) { 1591 pa_proplist *p = pa_proplist_new(); 1592 pa_log_debug("New source doesn't support stream format, sending format-changed and killing"); 1593 /* Tell the client what device we want to be on if it is going to 1594 * reconnect */ 1595 pa_proplist_sets(p, "device", dest->name); 1596 pa_source_output_send_event(o, PA_STREAM_EVENT_FORMAT_LOST, p); 1597 pa_proplist_free(p); 1598 return -PA_ERR_NOTSUPPORTED; 1599 } 1600 1601 if (!(o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) && 1602 !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec)) { 1603 /* try to change dest source format and rate if possible without glitches. 1604 module-suspend-on-idle resumes destination source with 1605 SOURCE_OUTPUT_MOVE_FINISH hook */ 1606 1607 pa_log_info("Trying to change sample spec"); 1608 pa_source_reconfigure(dest, &o->sample_spec, pa_source_output_is_passthrough(o)); 1609 } 1610 1611 if (o->moving) 1612 o->moving(o, dest); 1613 1614 o->source = dest; 1615 /* save == true, means user is calling the move_to() and want to 1616 save the preferred_source */ 1617 if (save) { 1618 if (dest == dest->core->default_source) 1619 set_preferred_source(o, NULL); 1620 else 1621 set_preferred_source(o, dest->name); 1622 } 1623 1624 pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL); 1625 1626 pa_cvolume_remap(&o->volume_factor_source, &o->channel_map, &o->source->channel_map); 1627 1628 if (o->state == PA_SOURCE_OUTPUT_CORKED) 1629 o->source->n_corked++; 1630 1631 pa_source_output_update_resampler(o); 1632 1633 pa_source_update_status(dest); 1634 1635 update_volume_due_to_moving(o, dest); 1636 1637 if (pa_source_output_is_passthrough(o)) 1638 pa_source_enter_passthrough(o->source); 1639 1640 pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL) == 0); 1641 1642 pa_log_debug("Successfully moved source output %i to %s.", o->index, dest->name); 1643 1644 /* Notify everyone */ 1645 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], o); 1646 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1647 1648 return 0; 1649} 1650 1651/* Called from main context */ 1652void pa_source_output_fail_move(pa_source_output *o) { 1653 1654 pa_source_output_assert_ref(o); 1655 pa_assert_ctl_context(); 1656 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1657 pa_assert(!o->source); 1658 1659 /* Check if someone wants this source output? */ 1660 if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL], o) == PA_HOOK_STOP) 1661 return; 1662 1663 /* Can we move the source output to the default source? */ 1664 if (o->core->rescue_streams && pa_source_output_may_move_to(o, o->core->default_source)) { 1665 if (pa_source_output_finish_move(o, o->core->default_source, false) >= 0) 1666 return; 1667 } 1668 1669 if (o->moving) 1670 o->moving(o, NULL); 1671 1672 pa_source_output_kill(o); 1673} 1674 1675/* Called from main context */ 1676int pa_source_output_move_to(pa_source_output *o, pa_source *dest, bool save) { 1677 int r; 1678 1679 pa_source_output_assert_ref(o); 1680 pa_assert_ctl_context(); 1681 pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); 1682 pa_assert(o->source); 1683 pa_source_assert_ref(dest); 1684 1685 if (dest == o->source) 1686 return 0; 1687 1688 if (!pa_source_output_may_move_to(o, dest)) 1689 return -PA_ERR_NOTSUPPORTED; 1690 1691 pa_source_output_ref(o); 1692 1693 if ((r = pa_source_output_start_move(o)) < 0) { 1694 pa_source_output_unref(o); 1695 return r; 1696 } 1697 1698 if ((r = pa_source_output_finish_move(o, dest, save)) < 0) { 1699 pa_source_output_fail_move(o); 1700 pa_source_output_unref(o); 1701 return r; 1702 } 1703 1704 pa_source_output_unref(o); 1705 1706 return 0; 1707} 1708 1709/* Called from IO thread context except when cork() is called without a valid source. */ 1710void pa_source_output_set_state_within_thread(pa_source_output *o, pa_source_output_state_t state) { 1711 pa_source_output_assert_ref(o); 1712 1713 if (state == o->thread_info.state) 1714 return; 1715 1716 if (o->state_change) 1717 o->state_change(o, state); 1718 1719 o->thread_info.state = state; 1720} 1721 1722/* Called from IO thread context, except when it is not */ 1723int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) { 1724 pa_source_output *o = PA_SOURCE_OUTPUT(mo); 1725 pa_source_output_assert_ref(o); 1726 1727 switch (code) { 1728 1729 case PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY: { 1730 pa_usec_t *r = userdata; 1731 1732 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(o->thread_info.delay_memblockq), &o->source->sample_spec); 1733 r[0] += pa_resampler_get_delay_usec(o->thread_info.resampler); 1734 r[1] += pa_source_get_latency_within_thread(o->source, false); 1735 1736 return 0; 1737 } 1738 1739 case PA_SOURCE_OUTPUT_MESSAGE_SET_RATE: 1740 1741 o->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); 1742 pa_resampler_set_output_rate(o->thread_info.resampler, PA_PTR_TO_UINT(userdata)); 1743 return 0; 1744 1745 case PA_SOURCE_OUTPUT_MESSAGE_SET_STATE: 1746 1747 pa_source_output_set_state_within_thread(o, PA_PTR_TO_UINT(userdata)); 1748 1749 return 0; 1750 1751 case PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY: { 1752 pa_usec_t *usec = userdata; 1753 1754 *usec = pa_source_output_set_requested_latency_within_thread(o, *usec); 1755 1756 return 0; 1757 } 1758 1759 case PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY: { 1760 pa_usec_t *r = userdata; 1761 1762 *r = o->thread_info.requested_source_latency; 1763 return 0; 1764 } 1765 1766 case PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME: 1767 if (!pa_cvolume_equal(&o->thread_info.soft_volume, &o->soft_volume)) { 1768 o->thread_info.soft_volume = o->soft_volume; 1769 } 1770 return 0; 1771 1772 case PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE: 1773 if (o->thread_info.muted != o->muted) { 1774 o->thread_info.muted = o->muted; 1775 } 1776 return 0; 1777 } 1778 1779 return -PA_ERR_NOTIMPLEMENTED; 1780} 1781 1782/* Called from main context */ 1783void pa_source_output_send_event(pa_source_output *o, const char *event, pa_proplist *data) { 1784 pa_proplist *pl = NULL; 1785 pa_source_output_send_event_hook_data hook_data; 1786 1787 pa_source_output_assert_ref(o); 1788 pa_assert_ctl_context(); 1789 pa_assert(event); 1790 1791 if (!o->send_event) 1792 return; 1793 1794 if (!data) 1795 data = pl = pa_proplist_new(); 1796 1797 hook_data.source_output = o; 1798 hook_data.data = data; 1799 hook_data.event = event; 1800 1801 if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT], &hook_data) < 0) 1802 goto finish; 1803 1804 o->send_event(o, event, data); 1805 1806finish: 1807 if (pl) 1808 pa_proplist_free(pl); 1809} 1810 1811/* Called from main context */ 1812/* Updates the source output's resampler with whatever the current source 1813 * requires -- useful when the underlying source's sample spec might have changed */ 1814int pa_source_output_update_resampler(pa_source_output *o) { 1815 pa_resampler *new_resampler; 1816 char *memblockq_name; 1817 size_t resampler_history; 1818 1819 pa_source_output_assert_ref(o); 1820 pa_assert_ctl_context(); 1821 1822 if (o->thread_info.resampler && 1823 pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &o->source->sample_spec) && 1824 pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &o->source->channel_map)) 1825 1826 new_resampler = o->thread_info.resampler; 1827 1828 else if (!pa_source_output_is_passthrough(o) && 1829 ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) || 1830 !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec) || 1831 !pa_channel_map_equal(&o->channel_map, &o->source->channel_map))) { 1832 1833 new_resampler = pa_resampler_new(o->core->mempool, 1834 &o->source->sample_spec, &o->source->channel_map, 1835 &o->sample_spec, &o->channel_map, 1836 o->core->lfe_crossover_freq, 1837 o->requested_resample_method, 1838 ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) | 1839 ((o->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) | 1840 (o->core->disable_remixing || (o->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) | 1841 (o->core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) | 1842 (o->core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) | 1843 (o->core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0)); 1844 1845 if (!new_resampler) { 1846 pa_log_warn("Unsupported resampling operation."); 1847 return -PA_ERR_NOTSUPPORTED; 1848 } 1849 } else 1850 new_resampler = NULL; 1851 1852 if (new_resampler == o->thread_info.resampler) 1853 return 0; 1854 1855 if (o->thread_info.resampler) 1856 pa_resampler_free(o->thread_info.resampler); 1857 1858 o->thread_info.resampler = new_resampler; 1859 1860 pa_memblockq_free(o->thread_info.delay_memblockq); 1861 1862 memblockq_name = pa_sprintf_malloc("source output delay_memblockq [%u]", o->index); 1863 o->thread_info.delay_memblockq = pa_memblockq_new( 1864 memblockq_name, 1865 0, 1866 MEMBLOCKQ_MAXLENGTH, 1867 0, 1868 &o->source->sample_spec, 1869 0, 1870 1, 1871 0, 1872 &o->source->silence); 1873 pa_xfree(memblockq_name); 1874 1875 resampler_history = (uint64_t) PA_RESAMPLER_MAX_DELAY_USEC * o->source->sample_spec.rate / PA_USEC_PER_SEC; 1876 resampler_history *= pa_frame_size(&o->source->sample_spec); 1877 1878 pa_memblockq_set_maxrewind(o->thread_info.delay_memblockq, resampler_history + pa_source_get_max_rewind(o->source)); 1879 1880 o->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID; 1881 1882 pa_log_debug("Updated resampler for source output %d", o->index); 1883 1884 return 0; 1885} 1886 1887/* Called from the IO thread. */ 1888void pa_source_output_attach(pa_source_output *o) { 1889 pa_assert(o); 1890 pa_assert(!o->thread_info.attached); 1891 1892 o->thread_info.attached = true; 1893 1894 if (o->attach) 1895 o->attach(o); 1896} 1897 1898/* Called from the IO thread. */ 1899void pa_source_output_detach(pa_source_output *o) { 1900 pa_assert(o); 1901 1902 if (!o->thread_info.attached) 1903 return; 1904 1905 o->thread_info.attached = false; 1906 1907 if (o->detach) 1908 o->detach(o); 1909} 1910 1911/* Called from the main thread. */ 1912void pa_source_output_set_volume_direct(pa_source_output *o, const pa_cvolume *volume) { 1913 pa_cvolume old_volume; 1914 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; 1915 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; 1916 1917 pa_assert(o); 1918 pa_assert(volume); 1919 1920 old_volume = o->volume; 1921 1922 if (pa_cvolume_equal(volume, &old_volume)) 1923 return; 1924 1925 o->volume = *volume; 1926 pa_log_debug("The volume of source output %u changed from %s to %s.", o->index, 1927 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &o->channel_map, true), 1928 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &o->channel_map, true)); 1929 1930 if (o->volume_changed) 1931 o->volume_changed(o); 1932 1933 pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); 1934 pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_VOLUME_CHANGED], o); 1935} 1936 1937/* Called from the main thread. */ 1938void pa_source_output_set_reference_ratio(pa_source_output *o, const pa_cvolume *ratio) { 1939 pa_cvolume old_ratio; 1940 char old_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; 1941 char new_ratio_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; 1942 1943 pa_assert(o); 1944 pa_assert(ratio); 1945 1946 old_ratio = o->reference_ratio; 1947 1948 if (pa_cvolume_equal(ratio, &old_ratio)) 1949 return; 1950 1951 o->reference_ratio = *ratio; 1952 1953 if (!PA_SOURCE_OUTPUT_IS_LINKED(o->state)) 1954 return; 1955 1956 pa_log_debug("Source output %u reference ratio changed from %s to %s.", o->index, 1957 pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), &old_ratio, &o->channel_map, true), 1958 pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), ratio, &o->channel_map, true)); 1959} 1960 1961/* Called from the main thread. 1962 * 1963 * This is called when e.g. module-stream-restore wants to change the preferred 1964 * source. As a side effect the stream is moved to the new preferred source. 1965 * Note that things can work also in the other direction: if the user moves 1966 * a stream, as a side effect the preferred source is changed. This could cause 1967 * an infinite loop, but it's avoided by these two measures: 1968 * - When pa_source_output_set_preferred_source() is called, it calls 1969 * pa_source_output_move_to() with save=false, which avoids the recursive 1970 * pa_source_output_set_preferred_source() call. 1971 * - When the primary operation is to move a stream, 1972 * pa_source_output_finish_move() calls set_preferred_source() instead of 1973 * pa_source_output_set_preferred_source(). set_preferred_source() doesn't 1974 * move the stream as a side effect. 1975 */ 1976void pa_source_output_set_preferred_source(pa_source_output *o, pa_source *s) { 1977 pa_assert(o); 1978 1979 if (s) { 1980 set_preferred_source(o, s->name); 1981 pa_source_output_move_to(o, s, false); 1982 } else { 1983 set_preferred_source(o, NULL); 1984 pa_source_output_move_to(o, o->core->default_source, false); 1985 } 1986} 1987