void voice_source_outputs_may_move(pa_source *s, pa_bool_t move) {
    pa_source_output *i;
    uint32_t idx;

    for (i = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); i; i = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) {
        if (move)
            i->flags &= ~PA_SOURCE_OUTPUT_DONT_MOVE;
        else
            i->flags |= PA_SOURCE_OUTPUT_DONT_MOVE;
    }
}
static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_sink_input) {
    const char *want;
    pa_proplist *pl, *parent_pl;

    if (is_sink_input) {
        pl = PA_SINK_INPUT(o)->proplist;
        parent_pl = PA_SINK_INPUT(o)->sink->proplist;
    } else {
        pl = PA_SOURCE_OUTPUT(o)->proplist;
        parent_pl = PA_SOURCE_OUTPUT(o)->source->proplist;
    }

    /* If the stream already specifies what it must have, then let it be. */
    if (!pa_proplist_gets(pl, PA_PROP_FILTER_HEURISTICS) && pa_proplist_gets(pl, PA_PROP_FILTER_APPLY))
        return PA_HOOK_OK;

    /* On phone sinks, make sure we're not applying echo cancellation */
    if (pa_str_in_list_spaces(pa_proplist_gets(parent_pl, PA_PROP_DEVICE_INTENDED_ROLES), "phone")) {
        const char *apply = pa_proplist_gets(pl, PA_PROP_FILTER_APPLY);

        if (apply && pa_streq(apply, "echo-cancel")) {
            pa_proplist_unset(pl, PA_PROP_FILTER_APPLY);
            pa_proplist_unset(pl, PA_PROP_FILTER_HEURISTICS);
        }

        return PA_HOOK_OK;
    }

    want = pa_proplist_gets(pl, PA_PROP_FILTER_WANT);

    if (want) {
        /* There's a filter that we want, ask module-filter-apply to apply it, and remember that we're managing filter.apply */
        pa_proplist_sets(pl, PA_PROP_FILTER_APPLY, want);
        pa_proplist_sets(pl, PA_PROP_FILTER_HEURISTICS, "1");
    }

    return PA_HOOK_OK;
}
Beispiel #3
0
/* Called from I/O thread context */
static int source_output_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u;
    pa_assert_se(u = PA_SOURCE_OUTPUT(o)->userdata);

    switch (code) {
        case PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY:
            *((pa_usec_t*) data) = pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &u->source_output->sample_spec);

            /* Fall through, the default handler will add in the extra
             * latency added by the resampler */
            break;
    }

    return pa_source_output_process_msg(o, code, data, offset, chunk);
}
Beispiel #4
0
/* 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;
}
/* Called from output thread context */
static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;

    switch (code) {

        case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT: {
            size_t length;

            length = pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq);

            u->latency_snapshot.send_counter = u->send_counter;
            u->latency_snapshot.source_output_buffer = u->source_output->thread_info.resampler ? pa_resampler_result(u->source_output->thread_info.resampler, length) : length;
            u->latency_snapshot.source_latency = pa_source_get_latency_within_thread(u->source_output->source);

            return 0;
        }
    }

    return pa_source_output_process_msg(obj, code, data, offset, chunk);
}
/* Called from output thread context */
static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;

    switch (code) {

        case SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT: {
            size_t length;

            length = pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq);

            u->latency_snapshot.send_counter = u->send_counter;
            /* Add content of delay memblockq to the source latency */
            u->latency_snapshot.source_latency = pa_source_get_latency_within_thread(u->source_output->source) +
                                                 pa_bytes_to_usec(length, &u->source_output->source->sample_spec);
            u->latency_snapshot.source_timestamp = pa_rtclock_now();

            return 0;
        }
    }

    return pa_source_output_process_msg(obj, code, data, offset, chunk);
}
Beispiel #7
0
/* Called from main context */
static void source_output_free(pa_object* mo) {
    pa_source_output *o = PA_SOURCE_OUTPUT(mo);

    pa_assert(o);
    pa_assert_ctl_context();
    pa_assert(pa_source_output_refcnt(o) == 0);

    if (PA_SOURCE_OUTPUT_IS_LINKED(o->state))
        pa_source_output_unlink(o);

    pa_log_info("Freeing output %u \"%s\"", o->index, pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)));

    if (o->thread_info.delay_memblockq)
        pa_memblockq_free(o->thread_info.delay_memblockq);

    if (o->thread_info.resampler)
        pa_resampler_free(o->thread_info.resampler);

    if (o->proplist)
        pa_proplist_free(o->proplist);

    pa_xfree(o->driver);
    pa_xfree(o);
}