Ejemplo n.º 1
0
bool PulseHandler::SuspendInternal(bool suspend)
{
    // set everything up...
    if (!Init())
        return false;

    // just in case it all goes pete tong
    if (!is_current_thread(m_thread))
        LOG(VB_AUDIO, LOG_WARNING, LOC +
            "PulseHandler called from a different thread");

    QString action = suspend ? "suspend" : "resume";
    // don't bother to suspend a networked server
    if (!pa_context_is_local(m_ctx))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
                "PulseAudio server is remote. No need to " + action);
        return false;
    }

    // create and dispatch 2 operations to suspend or resume all current sinks
    // and all current sources
    m_pending_operations = 2;
    pa_operation *operation_sink =
        pa_context_suspend_sink_by_index(
            m_ctx, PA_INVALID_INDEX, suspend, OperationCallback, this);
    pa_operation_unref(operation_sink);

    pa_operation *operation_source =
        pa_context_suspend_source_by_index(
            m_ctx, PA_INVALID_INDEX, suspend, OperationCallback, this);
    pa_operation_unref(operation_source);

    // run the loop manually and wait for the callbacks
    int count = 0;
    int ret = 0;
    while (m_pending_operations && count++ < 100)
    {
        pa_mainloop_iterate(m_loop, 0, &ret);
        usleep(10000);
    }

    // a failure isn't necessarily disastrous
    if (m_pending_operations)
    {
        m_pending_operations = 0;
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to " + action);
        return false;
    }

    // rejoice
    LOG(VB_GENERAL, LOG_INFO, LOC + "PulseAudio " + action + " OK");
    return true;
}
Ejemplo n.º 2
0
char* context_info_str(pa_context* c)
{
    return g_strdup_printf(
            "Server String: %s\n"
            "Library Protocol Version: %u\n"
            "Server Protocol Version: %u\n"
            "Is Local: %s\n"
            "Client Index: %u\n"
            "Tile Size: %zu",
            pa_context_get_server(c),
            pa_context_get_protocol_version(c),
            pa_context_get_server_protocol_version(c),
            pa_context_is_local(c) ? "yes" : "no",
            pa_context_get_index(c),
            pa_context_get_tile_size(c, NULL));
}
Ejemplo n.º 3
0
/**
 * Initializes the PulseAudio main loop and connects to the PulseAudio server.
 * @return a PulseAudio context on success, or NULL on error
 */
pa_context *vlc_pa_connect (vlc_object_t *obj, pa_threaded_mainloop **mlp)
{
    msg_Dbg (obj, "using library version %s", pa_get_library_version ());
    msg_Dbg (obj, " (compiled with version %s, protocol %u)",
             pa_get_headers_version (), PA_PROTOCOL_VERSION);

    /* Initialize main loop */
    pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new ();
    if (unlikely(mainloop == NULL))
        return NULL;

    if (pa_threaded_mainloop_start (mainloop) < 0)
    {
        pa_threaded_mainloop_free (mainloop);
        return NULL;
    }

    /* Fill in context (client) properties */
    char *ua = var_InheritString (obj, "user-agent");
    pa_proplist *props = pa_proplist_new ();
    if (likely(props != NULL))
    {
        pa_proplist_sets (props, PA_PROP_APPLICATION_NAME, ua);
        pa_proplist_sets (props, PA_PROP_APPLICATION_ID, "org.VideoLAN.VLC");
        pa_proplist_sets (props, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION);
        pa_proplist_sets (props, PA_PROP_APPLICATION_ICON_NAME, PACKAGE_NAME);
        //pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE, _("C"));
        pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE,
                          setlocale (LC_MESSAGES, NULL));

        pa_proplist_setf (props, PA_PROP_APPLICATION_PROCESS_ID, "%lu",
                          (unsigned long) getpid ());
        //pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_BINARY,
        //                  PACKAGE_NAME);

        for (size_t max = sysconf (_SC_GETPW_R_SIZE_MAX), len = max % 1024 + 1024;
             len < max; len += 1024)
        {
            struct passwd pwbuf, *pw;
            char buf[len];

            if (getpwuid_r (getuid (), &pwbuf, buf, sizeof (buf), &pw) == 0
             && pw != NULL)
                pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_USER,
                                  pw->pw_name);
        }

        for (size_t max = sysconf (_SC_HOST_NAME_MAX), len = max % 1024 + 1024;
             len < max; len += 1024)
        {
            char hostname[len];

            if (gethostname (hostname, sizeof (hostname)) == 0)
                pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_HOST,
                                  hostname);
        }

        const char *session = getenv ("XDG_SESSION_COOKIE");
        if (session != NULL)
        {
            pa_proplist_setf (props, PA_PROP_APPLICATION_PROCESS_MACHINE_ID,
                              "%.32s", session); /* XXX: is this valid? */
            pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_SESSION_ID,
                              session);
        }
    }

    /* Connect to PulseAudio daemon */
    pa_context *ctx;
    pa_mainloop_api *api;

    pa_threaded_mainloop_lock (mainloop);
    api = pa_threaded_mainloop_get_api (mainloop);
    ctx = pa_context_new_with_proplist (api, ua, props);
    free (ua);
    if (props != NULL)
        pa_proplist_free (props);
    if (unlikely(ctx == NULL))
        goto fail;

    pa_context_set_state_callback (ctx, context_state_cb, mainloop);
    if (pa_context_connect (ctx, NULL, 0, NULL) < 0
     || context_wait (ctx, mainloop))
    {
        vlc_pa_error (obj, "PulseAudio server connection failure", ctx);
        pa_context_unref (ctx);
        goto fail;
    }
    msg_Dbg (obj, "connected %s to %s as client #%"PRIu32,
             pa_context_is_local (ctx) ? "locally" : "remotely",
             pa_context_get_server (ctx), pa_context_get_index (ctx));
    msg_Dbg (obj, "using protocol %"PRIu32", server protocol %"PRIu32,
             pa_context_get_protocol_version (ctx),
             pa_context_get_server_protocol_version (ctx));

    pa_threaded_mainloop_unlock (mainloop);
    *mlp = mainloop;
    return ctx;

fail:
    pa_threaded_mainloop_unlock (mainloop);
    pa_threaded_mainloop_stop (mainloop);
    pa_threaded_mainloop_free (mainloop);
    return NULL;
}