コード例 #1
0
static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_output_new_data *data, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_assert(data);
    pa_assert(u);

    if (data->source->monitor_of)
        d = pa_hashmap_get(u->device_infos, data->source->monitor_of);
    else
        d = pa_hashmap_get(u->device_infos, data->source);

    if (d) {
        resume(d);
        if (d->source) {
            if (pa_source_check_suspend(d->source) <= 0)
                restart(d);
        } else {
            /* The source output is connected to a monitor source. */
            pa_assert(d->sink);
            if (pa_sink_check_suspend(d->sink) <= 0)
                restart(d);
        }
    }

    return PA_HOOK_OK;
}
コード例 #2
0
ファイル: memblock.c プロジェクト: DryakhlyyZlodey/pulseaudio
/* Self-locked */
pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) {
    pa_memblock *b = NULL;
    pa_memimport_segment *seg;

    pa_assert(i);

    pa_mutex_lock(i->mutex);

    if ((b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(block_id)))) {
        pa_memblock_ref(b);
        goto finish;
    }

    if (pa_hashmap_size(i->blocks) >= PA_MEMIMPORT_SLOTS_MAX)
        goto finish;

    if (!(seg = pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id))))
        if (!(seg = segment_attach(i, shm_id)))
            goto finish;

    if (offset+size > seg->memory.size)
        goto finish;

    if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks))))
        b = pa_xnew(pa_memblock, 1);

    PA_REFCNT_INIT(b);
    b->pool = i->pool;
    b->type = PA_MEMBLOCK_IMPORTED;
    b->read_only = true;
    b->is_silence = false;
    pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset);
    b->length = size;
    pa_atomic_store(&b->n_acquired, 0);
    pa_atomic_store(&b->please_signal, 0);
    b->per_type.imported.id = block_id;
    b->per_type.imported.segment = seg;

    pa_hashmap_put(i->blocks, PA_UINT32_TO_PTR(block_id), b);

    seg->n_blocks++;

    stat_add(b);

finish:
    pa_mutex_unlock(i->mutex);

    return b;
}
コード例 #3
0
static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_object_assert_ref(o);
    pa_assert(u);

    if (!(d = pa_hashmap_get(u->device_infos, o)))
        return PA_HOOK_OK;

    if (pa_sink_isinstance(o)) {
        pa_sink *s = PA_SINK(o);
        pa_sink_state_t state = pa_sink_get_state(s);

        if (pa_sink_check_suspend(s) <= 0)
            if (PA_SINK_IS_OPENED(state))
                restart(d);

    } else if (pa_source_isinstance(o)) {
        pa_source *s = PA_SOURCE(o);
        pa_source_state_t state = pa_source_get_state(s);

        if (pa_source_check_suspend(s) <= 0)
            if (PA_SOURCE_IS_OPENED(state))
                restart(d);
    }

    return PA_HOOK_OK;
}
コード例 #4
0
ファイル: context.c プロジェクト: felfert/pulseaudio
static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
    pa_context *c = userdata;
    pa_stream *s;

    pa_assert(p);
    pa_assert(chunk);
    pa_assert(chunk->length > 0);
    pa_assert(c);
    pa_assert(PA_REFCNT_VALUE(c) >= 1);

    pa_context_ref(c);

    if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {

        if (chunk->memblock) {
            pa_memblockq_seek(s->record_memblockq, offset, seek, TRUE);
            pa_memblockq_push_align(s->record_memblockq, chunk);
        } else
            pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, TRUE);

        if (s->read_callback) {
            size_t l;

            if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
                s->read_callback(s, l, s->read_userdata);
        }
    }

    pa_context_unref(c);
}
コード例 #5
0
static struct service *get_service(struct userdata *u, pa_object *device) {
    struct service *s;
    char *hn, *un;
    const char *n;

    pa_assert(u);
    pa_object_assert_ref(device);

    if ((s = pa_hashmap_get(u->services, device)))
        return s;

    s = pa_xnew0(struct service, 1);
    s->userdata = u;
    s->device = device;

    if (pa_sink_isinstance(device)) {
        if (!(n = pa_proplist_gets(PA_SINK(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
            n = PA_SINK(device)->name;
    } else {
        if (!(n = pa_proplist_gets(PA_SOURCE(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
            n = PA_SOURCE(device)->name;
    }

    hn = pa_get_host_name_malloc();
    un = pa_get_user_name_malloc();

    s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s: %s", un, hn, n), kDNSServiceMaxDomainName-1);

    pa_xfree(un);
    pa_xfree(hn);

    pa_hashmap_put(u->services, s->device, s);

    return s;
}
コード例 #6
0
ファイル: autoload.c プロジェクト: thewb/mokoiax
static pa_autoload_entry* entry_new(pa_core *c, const char *name) {
    pa_autoload_entry *e = NULL;

    pa_core_assert_ref(c);
    pa_assert(name);

    if (c->autoload_hashmap && (e = pa_hashmap_get(c->autoload_hashmap, name)))
        return NULL;

    e = pa_xnew(pa_autoload_entry, 1);
    e->core = c;
    e->name = pa_xstrdup(name);
    e->module = e->argument = NULL;
    e->in_action = 0;

    if (!c->autoload_hashmap)
        c->autoload_hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
    pa_assert(c->autoload_hashmap);

    pa_hashmap_put(c->autoload_hashmap, e->name, e);

    if (!c->autoload_idxset)
        c->autoload_idxset = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
    pa_idxset_put(c->autoload_idxset, e, &e->index);

    pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, e->index);

    return e;
}
コード例 #7
0
static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_output_new_data *data, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_assert(data);
    pa_assert(u);

    if (data->source->monitor_of)
        d = pa_hashmap_get(u->device_infos, data->source->monitor_of);
    else
        d = pa_hashmap_get(u->device_infos, data->source);

    if (d)
        resume(d);

    return PA_HOOK_OK;
}
コード例 #8
0
static pa_hook_result_t source_output_state_changed_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) {
    pa_assert(c);
    pa_source_output_assert_ref(s);
    pa_assert(u);

    if (pa_source_output_get_state(s) == PA_SOURCE_OUTPUT_RUNNING) {
        struct device_info *d;

        if (s->source->monitor_of)
            d = pa_hashmap_get(u->device_infos, s->source->monitor_of);
        else
            d = pa_hashmap_get(u->device_infos, s->source);

        if (d)
            resume(d);
    }

    return PA_HOOK_OK;
}
コード例 #9
0
ファイル: autoload.c プロジェクト: thewb/mokoiax
const pa_autoload_entry* pa_autoload_get_by_name(pa_core *c, const char*name, pa_namereg_type_t type) {
    pa_autoload_entry *e;

    pa_core_assert_ref(c);
    pa_assert(name);

    if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type)
        return NULL;

    return e;
}
コード例 #10
0
static pa_hook_result_t source_output_move_start_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) {
    struct device_info *d = NULL;

    pa_assert(c);
    pa_source_output_assert_ref(s);
    pa_assert(u);

    if (s->source->monitor_of) {
        if (pa_sink_check_suspend(s->source->monitor_of) <= 1)
            d = pa_hashmap_get(u->device_infos, s->source->monitor_of);
    } else {
        if (pa_source_check_suspend(s->source) <= 1)
            d = pa_hashmap_get(u->device_infos, s->source);
    }

    if (d)
        restart(d);

    return PA_HOOK_OK;
}
コード例 #11
0
static void card_changed(struct userdata *u, struct udev_device *dev) {
    struct device *d;
    const char *path;
    const char *t;
    char *n;

    pa_assert(u);
    pa_assert(dev);

    /* Maybe /dev/snd is now available? */
    setup_inotify(u);

    path = udev_device_get_devpath(dev);

    if ((d = pa_hashmap_get(u->devices, path))) {
        verify_access(u, d);
        return;
    }

    d = pa_xnew0(struct device, 1);
    d->path = pa_xstrdup(path);
    d->module = PA_INVALID_INDEX;
    PA_INIT_RATELIMIT(d->ratelimit, 10*PA_USEC_PER_SEC, 5);

    if (!(t = udev_device_get_property_value(dev, "PULSE_NAME")))
        if (!(t = udev_device_get_property_value(dev, "ID_ID")))
            if (!(t = udev_device_get_property_value(dev, "ID_PATH")))
                t = path_get_card_id(path);

    n = pa_namereg_make_valid_name(t);
    d->card_name = pa_sprintf_malloc("alsa_card.%s", n);
    d->args = pa_sprintf_malloc("device_id=\"%s\" "
                                "name=\"%s\" "
                                "card_name=\"%s\" "
                                "namereg_fail=false "
                                "tsched=%s "
                                "fixed_latency_range=%s "
                                "ignore_dB=%s "
                                "deferred_volume=%s "
                                "use_ucm=1 "
                                "card_properties=\"module-udev-detect.discovered=1\"",
                                path_get_card_id(path),
                                n,
                                d->card_name,
                                pa_yes_no(u->use_tsched),
                                pa_yes_no(u->fixed_latency_range),
                                pa_yes_no(u->ignore_dB),
                                pa_yes_no(u->deferred_volume));
    pa_xfree(n);

    pa_hashmap_put(u->devices, d->path, d);

    verify_access(u, d);
}
コード例 #12
0
static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userdata *u) {
    struct service *s;

    pa_assert(c);
    pa_object_assert_ref(o);

    if ((s = pa_hashmap_get(u->services, o)))
        service_free(s);

    return PA_HOOK_OK;
}
コード例 #13
0
ファイル: headerlist.c プロジェクト: Distrotech/pulseaudio
int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
    struct header *hdr;
    bool add = false;

    pa_assert(p);
    pa_assert(key);

    if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
        hdr = pa_xnew(struct header, 1);
        hdr->key = pa_xstrdup(key);
        add = true;
    } else
コード例 #14
0
ファイル: props.c プロジェクト: thewb/mokoiax
void* pa_property_get(pa_core *c, const char *name) {
    pa_property *p;

    pa_assert(c);
    pa_assert(name);
    pa_assert(c->properties);

    if (!(p = pa_hashmap_get(c->properties, name)))
        return NULL;

    return p->data;
}
コード例 #15
0
ファイル: shared.c プロジェクト: jprvita/pulseaudio
void* pa_shared_get(pa_core *c, const char *name) {
    pa_shared *p;

    pa_assert(c);
    pa_assert(name);
    pa_assert(c->shared);

    if (!(p = pa_hashmap_get(c->shared, name)))
        return NULL;

    return p->data;
}
コード例 #16
0
static void browser_cb(
        AvahiServiceBrowser *b,
        AvahiIfIndex interface, AvahiProtocol protocol,
        AvahiBrowserEvent event,
        const char *name, const char *type, const char *domain,
        AvahiLookupResultFlags flags,
        void *userdata) {

    struct userdata *u = userdata;
    struct tunnel *t;

    pa_assert(u);

    if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
        return;

    t = tunnel_new(interface, protocol, name, type, domain);

    if (event == AVAHI_BROWSER_NEW) {

        if (!pa_hashmap_get(u->tunnels, t))
            if (!(avahi_service_resolver_new(u->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolver_cb, u)))
                pa_log("avahi_service_resolver_new() failed: %s", avahi_strerror(avahi_client_errno(u->client)));

        /* We ignore the returned resolver object here, since the we don't
         * need to attach any special data to it, and we can still destroy
         * it from the callback */

    } else if (event == AVAHI_BROWSER_REMOVE) {
        struct tunnel *t2;

        if ((t2 = pa_hashmap_get(u->tunnels, t))) {
            pa_module_unload_request_by_index(u->core, t2->module_index, TRUE);
            pa_hashmap_remove(u->tunnels, t2);
            tunnel_free(t2);
        }
    }

    tunnel_free(t);
}
コード例 #17
0
static pa_hook_result_t sink_input_move_start_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_sink_input_assert_ref(s);
    pa_assert(u);

    if (pa_sink_check_suspend(s->sink) <= 1)
        if ((d = pa_hashmap_get(u->device_infos, s->sink)))
            restart(d);

    return PA_HOOK_OK;
}
コード例 #18
0
ファイル: autoload.c プロジェクト: thewb/mokoiax
int pa_autoload_remove_by_name(pa_core *c, const char*name, pa_namereg_type_t type) {
    pa_autoload_entry *e;

    pa_assert(c);
    pa_assert(name);
    pa_assert(type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE);

    if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type)
        return -1;

    entry_remove_and_free(e);
    return 0;
}
コード例 #19
0
ファイル: device-port.c プロジェクト: Oboyma/pulseaudio
void pa_device_port_set_available(pa_device_port *p, pa_port_available_t status)
{
    uint32_t state;
    pa_card *card;
/*    pa_source *source;
    pa_sink *sink; */
    pa_core *core;

    pa_assert(p);

    if (p->available == status)
        return;

/*    pa_assert(status != PA_PORT_AVAILABLE_UNKNOWN); */

    p->available = status;
    pa_log_debug("Setting port %s to status %s", p->name, status == PA_PORT_AVAILABLE_YES ? "yes" :
       status == PA_PORT_AVAILABLE_NO ? "no" : "unknown");

    /* Post subscriptions to the card which owns us */
    pa_assert_se(core = p->core);
    PA_IDXSET_FOREACH(card, core->cards, state)
        if (p == pa_hashmap_get(card->ports, p->name))
            pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, card->index);
#if 0
/* This stuff is temporarily commented out while figuring out whether to actually do this */
    if (p->is_output)
        PA_IDXSET_FOREACH(sink, core->sinks, state)
            if (p == pa_hashmap_get(sink->ports, p->name))
                pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index);
    if (p->is_input)
        PA_IDXSET_FOREACH(source, core->sources, state)
            if (p == pa_hashmap_get(source->ports, p->name))
                pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, source->index);
#endif

    pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p);
}
コード例 #20
0
ファイル: shared.c プロジェクト: jprvita/pulseaudio
int pa_shared_set(pa_core *c, const char *name, void *data) {
    pa_shared *p;

    pa_assert(c);
    pa_assert(name);
    pa_assert(data);
    pa_assert(c->shared);

    if (pa_hashmap_get(c->shared, name))
        return -1;

    p = shared_new(name, data);
    pa_hashmap_put(c->shared, p->name, p);
    return 0;
}
コード例 #21
0
ファイル: props.c プロジェクト: thewb/mokoiax
int pa_property_set(pa_core *c, const char *name, void *data) {
    pa_property *p;

    pa_assert(c);
    pa_assert(name);
    pa_assert(data);
    pa_assert(c->properties);

    if (pa_hashmap_get(c->properties, name))
        return -1;

    p = property_new(name, data);
    pa_hashmap_put(c->properties, p->name, p);
    return 0;
}
コード例 #22
0
static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
    struct device_info *d;
    pa_sink_input_state_t state;

    pa_assert(c);
    pa_sink_input_assert_ref(s);
    pa_assert(u);

    state = pa_sink_input_get_state(s);
    if (state == PA_SINK_INPUT_RUNNING || state == PA_SINK_INPUT_DRAINED)
        if ((d = pa_hashmap_get(u->device_infos, s->sink)))
            resume(d);

    return PA_HOOK_OK;
}
コード例 #23
0
ファイル: proplist.c プロジェクト: poljar/pulseaudio
/** Will accept only valid UTF-8 */
int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
    struct property *prop;
    bool add = false;

    pa_assert(p);
    pa_assert(key);
    pa_assert(value);

    if (!pa_proplist_key_valid(key) || !pa_utf8_valid(value))
        return -1;

    if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
        prop = pa_xnew(struct property, 1);
        prop->key = pa_xstrdup(key);
        add = true;
    } else
コード例 #24
0
ファイル: proplist.c プロジェクト: KimT/pulseaudio_kt
/** Will accept only valid UTF-8 */
int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
    struct property *prop;
    pa_bool_t add = FALSE;

    pa_assert(p);
    pa_assert(key);
    pa_assert(value);

    if (!property_name_valid(key) || !pa_utf8_valid(value))
        return -1;

    if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
        prop = pa_xnew(struct property, 1);
        prop->key = pa_xstrdup(key);
        add = TRUE;
    } else
コード例 #25
0
static pa_hook_result_t sink_input_fixate_hook_cb(pa_core *c, pa_sink_input_new_data *data, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_assert(data);
    pa_assert(u);

    /* We need to resume the audio device here even for
     * PA_SINK_INPUT_START_CORKED, since we need the device parameters
     * to be fully available while the stream is set up. */

    if ((d = pa_hashmap_get(u->device_infos, data->sink)))
        resume(d);

    return PA_HOOK_OK;
}
コード例 #26
0
ファイル: module-volume-restore.c プロジェクト: thewb/mokoiax
static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *data, struct userdata *u) {
    struct rule *r;
    char *name;

    pa_assert(data);

    if (!data->client || !(name = client_name(data->client)))
        return PA_HOOK_OK;

    if ((r = pa_hashmap_get(u->hashmap, name))) {
        if (!data->source && r->source) {
            if ((data->source = pa_namereg_get(c, r->source, PA_NAMEREG_SOURCE, 1)))
                pa_log_info("Restoring source for <%s>", r->name);
        }
    }

    return PA_HOOK_OK;
}
コード例 #27
0
static int port_device_is_typeof(struct pa_classify_device_def *defs,
                                 const char *name, const char *type,
                                 struct pa_classify_device_data **data)
{
    struct pa_classify_device_def *d;

    for (d = defs;  d->type;  d++) {
        if (pa_streq(type, d->type)) {
            if (d->data.ports && pa_hashmap_get(d->data.ports, name)) {
                if (data != NULL)
                    *data = &d->data;

                return TRUE;
            }
        }
    }

    return FALSE;
}
コード例 #28
0
ファイル: memblock.c プロジェクト: DryakhlyyZlodey/pulseaudio
int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) {
    pa_memblock *b;
    int ret = 0;
    pa_assert(i);

    pa_mutex_lock(i->mutex);

    if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) {
        ret = -1;
        goto finish;
    }

    memblock_replace_import(b);

finish:
    pa_mutex_unlock(i->mutex);

    return ret;
}
コード例 #29
0
static pa_hook_result_t sink_input_fixate_hook_cb(pa_core *c, pa_sink_input_new_data *data, struct userdata *u) {
    struct device_info *d;

    pa_assert(c);
    pa_assert(data);
    pa_assert(u);

    /* We need to resume the audio device here even for
     * PA_SINK_INPUT_START_CORKED, since we need the device parameters
     * to be fully available while the stream is set up. In that case,
     * make sure we close the sink again after the timeout interval. */

    if ((d = pa_hashmap_get(u->device_infos, data->sink))) {
        resume(d);
        if (pa_sink_check_suspend(d->sink) <= 0)
            restart(d);
    }

    return PA_HOOK_OK;
}
コード例 #30
0
ファイル: autoload.c プロジェクト: thewb/mokoiax
void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) {
    pa_autoload_entry *e;
    pa_module *m;

    pa_assert(c);
    pa_assert(name);

    if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || (e->type != type))
        return;

    if (e->in_action)
        return;

    e->in_action = 1;

    if (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE) {
        if ((m = pa_module_load(c, e->module, e->argument)))
            m->auto_unload = 1;
    }

    e->in_action = 0;
}