Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <glib.h>
#include "mozilla/Types.h"
#include "prlink.h"
#include <pipewire/pipewire.h>
#define GET_FUNC(func, lib) \
func##_fn = \
(decltype(func##_fn))PR_FindFunctionSymbol(lib, #func) \
#define IS_FUNC_LOADED(func) \
(func != nullptr) \
struct GUnixFDList;
extern "C" gint
g_unix_fd_list_get(struct GUnixFDList *list,
gint index_,
GError **error)
{
static PRLibrary* gioLib = nullptr;
static bool gioInitialized = false;
static gint (*g_unix_fd_list_get_fn)(struct GUnixFDList *list,
gint index_, GError **error) = nullptr;
if (!gioInitialized) {
gioInitialized = true;
gioLib = PR_LoadLibrary("libgio-2.0.so.0");
if (!gioLib) {
return -1;
}
GET_FUNC(g_unix_fd_list_get, gioLib);
}
if (!g_unix_fd_list_get_fn) {
return -1;
}
return g_unix_fd_list_get_fn(list, index_, error);
}
static struct pw_core * (*pw_context_connect_fn)(struct pw_context *context,
struct pw_properties *properties,
size_t user_data_size);
static struct pw_core * (*pw_context_connect_fd_fn)(struct pw_context *context,
int fd,
struct pw_properties *properties,
size_t user_data_size);
static void (*pw_context_destroy_fn)(struct pw_context *context);
struct pw_context * (*pw_context_new_fn)(struct pw_loop *main_loop,
struct pw_properties *props,
size_t user_data_size);
static int (*pw_core_disconnect_fn)(struct pw_core *core);
static void (*pw_init_fn)(int *argc, char **argv[]);
static void (*pw_proxy_destroy_fn)(struct pw_proxy *proxy);
static void (*pw_stream_add_listener_fn)(struct pw_stream *stream,
struct spa_hook *listener,
const struct pw_stream_events *events,
void *data);
static int (*pw_stream_connect_fn)(struct pw_stream *stream,
enum pw_direction direction,
uint32_t target_id,
enum pw_stream_flags flags,
const struct spa_pod **params,
uint32_t n_params);
static int (*pw_stream_disconnect_fn)(struct pw_stream *stream);
static struct pw_buffer* (*pw_stream_dequeue_buffer_fn)(struct pw_stream *stream);
static void (*pw_stream_destroy_fn)(struct pw_stream *stream);
static struct pw_stream* (*pw_stream_new_fn)(struct pw_core *core,
const char *name,
struct pw_properties *props);
static int (*pw_stream_queue_buffer_fn)(struct pw_stream *stream,
struct pw_buffer *buffer);
static const char * (*pw_stream_state_as_string_fn)(enum pw_stream_state state);
static int (*pw_stream_update_params_fn)(struct pw_stream *stream,
const struct spa_pod **params,
uint32_t n_params);
static void (*pw_thread_loop_destroy_fn)(struct pw_thread_loop *loop);
static struct pw_loop* (*pw_thread_loop_get_loop_fn)(struct pw_thread_loop *loop);
static struct pw_thread_loop* (*pw_thread_loop_new_fn)(const char *name,
const struct spa_dict *props);
static int (*pw_thread_loop_start_fn)(struct pw_thread_loop *loop);
static void (*pw_thread_loop_stop_fn)(struct pw_thread_loop *loop);
static void (*pw_thread_loop_lock_fn)(struct pw_thread_loop *loop);
static void (*pw_thread_loop_unlock_fn)(struct pw_thread_loop *loop);
static void (*pw_thread_loop_wait_fn)(struct pw_thread_loop *loop);
static void (*pw_thread_loop_signal_fn)(struct pw_thread_loop *loop, bool wait_for_accept);
static struct pw_properties* (*pw_properties_new_string_fn)(const char *str);
static const char* (*pw_get_library_version_fn)();
bool IsPwLibraryLoaded() {
static bool isLoaded =
(IS_FUNC_LOADED(pw_context_connect_fn) &&
IS_FUNC_LOADED(pw_context_connect_fd_fn) &&
IS_FUNC_LOADED(pw_context_destroy_fn) &&
IS_FUNC_LOADED(pw_context_new_fn) &&
IS_FUNC_LOADED(pw_core_disconnect_fn) &&
IS_FUNC_LOADED(pw_init_fn) &&
IS_FUNC_LOADED(pw_proxy_destroy_fn) &&
IS_FUNC_LOADED(pw_stream_add_listener_fn) &&
IS_FUNC_LOADED(pw_stream_connect_fn) &&
IS_FUNC_LOADED(pw_stream_disconnect_fn) &&
IS_FUNC_LOADED(pw_stream_dequeue_buffer_fn) &&
IS_FUNC_LOADED(pw_stream_destroy_fn) &&
IS_FUNC_LOADED(pw_stream_new_fn) &&
IS_FUNC_LOADED(pw_stream_queue_buffer_fn) &&
IS_FUNC_LOADED(pw_stream_state_as_string_fn) &&
IS_FUNC_LOADED(pw_stream_update_params_fn) &&
IS_FUNC_LOADED(pw_thread_loop_destroy_fn) &&
IS_FUNC_LOADED(pw_thread_loop_get_loop_fn) &&
IS_FUNC_LOADED(pw_thread_loop_new_fn) &&
IS_FUNC_LOADED(pw_thread_loop_start_fn) &&
IS_FUNC_LOADED(pw_thread_loop_stop_fn) &&
IS_FUNC_LOADED(pw_thread_loop_lock_fn) &&
IS_FUNC_LOADED(pw_thread_loop_unlock_fn) &&
IS_FUNC_LOADED(pw_thread_loop_signal_fn) &&
IS_FUNC_LOADED(pw_thread_loop_wait_fn) &&
IS_FUNC_LOADED(pw_properties_new_string_fn) &&
IS_FUNC_LOADED(pw_get_library_version_fn));
return isLoaded;
}
bool LoadPWLibrary() {
static PRLibrary* pwLib = nullptr;
static bool pwInitialized = false;
//TODO Thread safe
if (!pwInitialized) {
pwInitialized = true;
pwLib = PR_LoadLibrary("libpipewire-0.3.so.0");
if (!pwLib) {
return false;
}
GET_FUNC(pw_context_connect, pwLib);
GET_FUNC(pw_context_connect_fd, pwLib);
GET_FUNC(pw_context_destroy, pwLib);
GET_FUNC(pw_context_new, pwLib);
GET_FUNC(pw_core_disconnect, pwLib);
GET_FUNC(pw_init, pwLib);
GET_FUNC(pw_stream_add_listener, pwLib);
GET_FUNC(pw_stream_connect, pwLib);
GET_FUNC(pw_stream_disconnect, pwLib);
GET_FUNC(pw_stream_dequeue_buffer, pwLib);
GET_FUNC(pw_stream_destroy, pwLib);
GET_FUNC(pw_stream_new, pwLib);
GET_FUNC(pw_stream_queue_buffer, pwLib);
GET_FUNC(pw_stream_update_params, pwLib);
GET_FUNC(pw_stream_state_as_string, pwLib);
GET_FUNC(pw_thread_loop_destroy, pwLib);
GET_FUNC(pw_thread_loop_get_loop, pwLib);
GET_FUNC(pw_thread_loop_new, pwLib);
GET_FUNC(pw_thread_loop_start, pwLib);
GET_FUNC(pw_thread_loop_stop, pwLib);
GET_FUNC(pw_thread_loop_lock, pwLib);
GET_FUNC(pw_thread_loop_unlock, pwLib);
GET_FUNC(pw_thread_loop_signal, pwLib);
GET_FUNC(pw_thread_loop_wait, pwLib);
GET_FUNC(pw_properties_new_string, pwLib);
GET_FUNC(pw_get_library_version, pwLib);
GET_FUNC(pw_proxy_destroy, pwLib);
}
return IsPwLibraryLoaded();
}
struct pw_core *
pw_context_connect(struct pw_context *context,
struct pw_properties *properties,
size_t user_data_size)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_context_connect_fn(context, properties, user_data_size);
}
struct pw_core *
pw_context_connect_fd(struct pw_context *context,
int fd,
struct pw_properties *properties,
size_t user_data_size)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_context_connect_fd_fn(context, fd, properties, user_data_size);
}
void
pw_context_destroy(struct pw_context *context)
{
if (!LoadPWLibrary()) {
return;
}
pw_context_destroy_fn(context);
}
struct pw_context *
pw_context_new(struct pw_loop *main_loop,
struct pw_properties *props,
size_t user_data_size)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_context_new_fn(main_loop, props, user_data_size);
}
int
pw_core_disconnect(struct pw_core *core)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_core_disconnect_fn(core);
}
void
pw_init(int *argc, char **argv[])
{
if (!LoadPWLibrary()) {
return;
}
return pw_init_fn(argc, argv);
}
void
pw_proxy_destroy(struct pw_proxy *proxy)
{
if (!LoadPWLibrary()) {
return;
}
return pw_proxy_destroy_fn(proxy);
}
void
pw_stream_add_listener(struct pw_stream *stream,
struct spa_hook *listener,
const struct pw_stream_events *events,
void *data)
{
if (!LoadPWLibrary()) {
return;
}
return pw_stream_add_listener_fn(stream, listener, events, data);
}
int
pw_stream_connect(struct pw_stream *stream,
enum pw_direction direction,
uint32_t target_id,
enum pw_stream_flags flags,
const struct spa_pod **params,
uint32_t n_params)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_stream_connect_fn(stream, direction, target_id, flags,
params, n_params);
}
int
pw_stream_disconnect(struct pw_stream *stream)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_stream_disconnect_fn(stream);
}
struct pw_buffer *
pw_stream_dequeue_buffer(struct pw_stream *stream)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_stream_dequeue_buffer_fn(stream);
}
void
pw_stream_destroy(struct pw_stream *stream)
{
if (!LoadPWLibrary()) {
return;
}
return pw_stream_destroy_fn(stream);
}
struct pw_stream *
pw_stream_new(struct pw_core *core,
const char *name,
struct pw_properties *props)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_stream_new_fn(core, name, props);
}
int
pw_stream_queue_buffer(struct pw_stream *stream,
struct pw_buffer *buffer)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_stream_queue_buffer_fn(stream, buffer);
}
const char *
pw_stream_state_as_string(enum pw_stream_state state)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_stream_state_as_string_fn(state);
}
int
pw_stream_update_params(struct pw_stream *stream,
const struct spa_pod **params,
uint32_t n_params)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_stream_update_params_fn(stream, params, n_params);
}
void
pw_thread_loop_destroy(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_destroy_fn(loop);
}
struct pw_loop *
pw_thread_loop_get_loop(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_thread_loop_get_loop_fn(loop);
}
struct pw_thread_loop *
pw_thread_loop_new(const char *name,
const struct spa_dict *props)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_thread_loop_new_fn(name, props);
}
int
pw_thread_loop_start(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return 0;
}
return pw_thread_loop_start_fn(loop);
}
void
pw_thread_loop_stop(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_stop_fn(loop);
}
void
pw_thread_loop_lock(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_lock_fn(loop);
}
void
pw_thread_loop_unlock(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_unlock_fn(loop);
}
void
pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_signal_fn(loop, wait_for_accept);
}
void
pw_thread_loop_wait(struct pw_thread_loop *loop)
{
if (!LoadPWLibrary()) {
return;
}
return pw_thread_loop_wait_fn(loop);
}
struct pw_properties *
pw_properties_new_string(const char *str)
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_properties_new_string_fn(str);
}
const char*
pw_get_library_version()
{
if (!LoadPWLibrary()) {
return nullptr;
}
return pw_get_library_version_fn();
}