/* Called from I/O thread context */ static void voip_source_update_requested_latency(pa_source *s) { struct userdata *u; pa_source_assert_ref(s); pa_assert_se(u = s->userdata); /* Just hand this one over to the master source */ pa_source_output_set_requested_latency_within_thread( u->hw_source_output, voice_source_get_requested_latency(s, u->raw_source)); }
/* Called from I/O thread context */ static void source_update_requested_latency_cb(pa_source *s) { struct userdata *u; pa_source_assert_ref(s); pa_assert_se(u = s->userdata); if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) || !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) return; /* Just hand this one over to the master source */ pa_source_output_set_requested_latency_within_thread( u->source_output, pa_source_get_requested_latency_within_thread(s)); }
/* Called from IO thread context, except when it is not */ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) { pa_source_output *o = PA_SOURCE_OUTPUT(mo); pa_source_output_assert_ref(o); switch (code) { case PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = userdata; r[0] += pa_bytes_to_usec(pa_memblockq_get_length(o->thread_info.delay_memblockq), &o->source->sample_spec); r[1] += pa_source_get_latency_within_thread(o->source); return 0; } case PA_SOURCE_OUTPUT_MESSAGE_SET_RATE: o->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); pa_resampler_set_output_rate(o->thread_info.resampler, PA_PTR_TO_UINT(userdata)); return 0; case PA_SOURCE_OUTPUT_MESSAGE_SET_STATE: pa_source_output_set_state_within_thread(o, PA_PTR_TO_UINT(userdata)); return 0; case PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY: { pa_usec_t *usec = userdata; *usec = pa_source_output_set_requested_latency_within_thread(o, *usec); return 0; } case PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY: { pa_usec_t *r = userdata; *r = o->thread_info.requested_source_latency; return 0; } } return -PA_ERR_NOTIMPLEMENTED; }