Ejemplo n.º 1
0
static void context_unlink(pa_context *c) {
    pa_stream *s;

    pa_assert(c);

    s = c->streams ? pa_stream_ref(c->streams) : NULL;
    while (s) {
        pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
        pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
        pa_stream_unref(s);
        s = n;
    }

    while (c->operations)
        pa_operation_cancel(c->operations);

    if (c->pdispatch) {
        pa_pdispatch_unref(c->pdispatch);
        c->pdispatch = NULL;
    }

    if (c->pstream) {
        pa_pstream_unlink(c->pstream);
        pa_pstream_unref(c->pstream);
        c->pstream = NULL;
    }

    if (c->client) {
        pa_socket_client_unref(c->client);
        c->client = NULL;
    }

    reset_callbacks(c);
}
Ejemplo n.º 2
0
int pa_stream_connect_upload(pa_stream *s, size_t length) {
    pa_tagstruct *t;
    uint32_t tag;
    const char *name;

    pa_assert(s);
    pa_assert(PA_REFCNT_VALUE(s) >= 1);

    PA_CHECK_VALIDITY(s->context, !pa_detect_fork(), PA_ERR_FORKED);
    PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE);
    PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID);
    PA_CHECK_VALIDITY(s->context, length == (size_t) (uint32_t) length, PA_ERR_INVALID);
    PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);

    if (!(name = pa_proplist_gets(s->proplist, PA_PROP_EVENT_ID)))
        name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME);

    PA_CHECK_VALIDITY(s->context, name && *name && pa_utf8_valid(name), PA_ERR_INVALID);

    pa_stream_ref(s);

    s->direction = PA_STREAM_UPLOAD;
    s->flags = 0;

    t = pa_tagstruct_command(s->context, PA_COMMAND_CREATE_UPLOAD_STREAM, &tag);

    pa_tagstruct_puts(t, name);
    pa_tagstruct_put_sample_spec(t, &s->sample_spec);
    pa_tagstruct_put_channel_map(t, &s->channel_map);
    pa_tagstruct_putu32(t, (uint32_t) length);

    if (s->context->version >= 13)
        pa_tagstruct_put_proplist(t, s->proplist);

    pa_pstream_send_tagstruct(s->context->pstream, t);
    pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);

    pa_stream_set_state(s, PA_STREAM_CREATING);

    pa_stream_unref(s);
    return 0;
}
Ejemplo n.º 3
0
int pa_stream_finish_upload(pa_stream *s) {
    pa_tagstruct *t;
    uint32_t tag;

    pa_assert(s);
    pa_assert(PA_REFCNT_VALUE(s) >= 1);

    PA_CHECK_VALIDITY(s->context, !pa_detect_fork(), PA_ERR_FORKED);
    PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE);
    PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);

    pa_stream_ref(s);

    t = pa_tagstruct_command(s->context, PA_COMMAND_FINISH_UPLOAD_STREAM, &tag);
    pa_tagstruct_putu32(t, s->channel);
    pa_pstream_send_tagstruct(s->context->pstream, t);
    pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_disconnect_callback, s, NULL);

    pa_stream_unref(s);
    return 0;
}
Ejemplo n.º 4
0
static
int
do_connect_pcm(pa_stream *s, snd_pcm_stream_t stream_direction)
{
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
    int dir;
    unsigned int rate;
    const char *dev_name;

    switch (stream_direction) {
    default:
    case SND_PCM_STREAM_PLAYBACK:
        dev_name = getenv("APULSE_PLAYBACK_DEVICE");
        CHECK_A(snd_pcm_open, (&s->ph, dev_name ? dev_name : "default", stream_direction, 0));
        break;
    case SND_PCM_STREAM_CAPTURE:
        dev_name = getenv("APULSE_CAPTURE_DEVICE");
        CHECK_A(snd_pcm_open, (&s->ph, dev_name ? dev_name : "default", stream_direction, 0));
        break;
    }

    CHECK_A(snd_pcm_hw_params_malloc, (&hw_params));
    CHECK_A(snd_pcm_hw_params_any, (s->ph, hw_params));
    CHECK_A(snd_pcm_hw_params_set_access, (s->ph, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED));
    CHECK_A(snd_pcm_hw_params_set_format, (s->ph, hw_params, pa_format_to_alsa(s->ss.format)));
    CHECK_A(snd_pcm_hw_params_set_rate_resample, (s->ph, hw_params, 1));
    rate = s->ss.rate;
    dir = 0;
    CHECK_A(snd_pcm_hw_params_set_rate_near, (s->ph, hw_params, &rate, &dir));
    CHECK_A(snd_pcm_hw_params_set_channels, (s->ph, hw_params, s->ss.channels));

    unsigned int period_time = 20 * 1000;
    dir = 1;
    CHECK_A(snd_pcm_hw_params_set_period_time_near, (s->ph, hw_params, &period_time, &dir));

    unsigned int buffer_time = 4 * period_time;
    dir = 1;
    CHECK_A(snd_pcm_hw_params_set_buffer_time_near, (s->ph, hw_params, &buffer_time, &dir));
    CHECK_A(snd_pcm_hw_params, (s->ph, hw_params));
    snd_pcm_hw_params_free(hw_params);

    CHECK_A(snd_pcm_sw_params_malloc, (&sw_params));
    CHECK_A(snd_pcm_sw_params_current, (s->ph, sw_params));

    const snd_pcm_uframes_t period_size = (uint64_t)period_time * rate / (1000 * 1000);
    CHECK_A(snd_pcm_sw_params_set_avail_min, (s->ph, sw_params, period_size));
    // no period event requested
    CHECK_A(snd_pcm_sw_params, (s->ph, sw_params));
    snd_pcm_sw_params_free(sw_params);

    CHECK_A(snd_pcm_prepare, (s->ph));

    int nfds = snd_pcm_poll_descriptors_count(s->ph);
    struct pollfd *fds = calloc(nfds, sizeof(struct pollfd));
    s->ioe = calloc(nfds, sizeof(pa_io_event *));
    s->nioe = nfds;
    snd_pcm_poll_descriptors(s->ph, fds, nfds);
    for (int k = 0; k < nfds; k ++) {
        pa_mainloop_api *api = s->c->mainloop_api;
        s->ioe[k] = api->io_new(api, fds[k].fd, 0x80000000 | fds[k].events,
                                data_available_for_stream, s);
        s->ioe[k]->pcm = s->ph;
    }
    free(fds);

    s->state = PA_STREAM_READY;
    pa_stream_ref(s);
    s->c->mainloop_api->defer_new(s->c->mainloop_api, deh_stream_state_changed, s);
    pa_stream_ref(s);
    s->c->mainloop_api->defer_new(s->c->mainloop_api, deh_stream_first_readwrite_callback, s);

    return 0;
err:
    return -1;
}