mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
module-jack: load libjack.so.0 with dlopen
This way we can search for the real jack library instead of using our custom libjack.so. Add an option to override the search path with LIBJACK_PATH and an option to select the library name to load.
This commit is contained in:
parent
7da4eb13f7
commit
0629647cb5
3 changed files with 228 additions and 35 deletions
179
src/modules/module-jack-tunnel/weakjack.h
Normal file
179
src/modules/module-jack-tunnel/weakjack.h
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef PIPEWIRE_WEAK_JACK_H
|
||||
#define PIPEWIRE_WEAK_JACK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <jack/jack.h>
|
||||
#include <jack/transport.h>
|
||||
|
||||
struct weakjack {
|
||||
jack_nframes_t (*cycle_wait) (jack_client_t* client);
|
||||
void (*cycle_signal) (jack_client_t* client, int status);
|
||||
|
||||
jack_nframes_t (*frame_time) (const jack_client_t *);
|
||||
int (*get_cycle_times) (const jack_client_t *client,
|
||||
jack_nframes_t *current_frames,
|
||||
jack_time_t *current_usecs,
|
||||
jack_time_t *next_usecs,
|
||||
float *period_usecs);
|
||||
jack_transport_state_t (*transport_query) (const jack_client_t *client,
|
||||
jack_position_t *pos);
|
||||
|
||||
jack_client_t * (*client_open) (const char *client_name,
|
||||
jack_options_t options,
|
||||
jack_status_t *status, ...);
|
||||
int (*client_close) (jack_client_t *client);
|
||||
|
||||
|
||||
int (*activate) (jack_client_t *client);
|
||||
int (*deactivate) (jack_client_t *client);
|
||||
|
||||
jack_nframes_t (*get_sample_rate) (jack_client_t *);
|
||||
|
||||
int (*recompute_total_latencies) (jack_client_t *client);
|
||||
|
||||
jack_port_t * (*port_register) (jack_client_t *client,
|
||||
const char *port_name,
|
||||
const char *port_type,
|
||||
unsigned long flags,
|
||||
unsigned long buffer_size);
|
||||
int (*port_unregister) (jack_client_t *client, jack_port_t *port);
|
||||
void * (*port_get_buffer) (jack_port_t *port, jack_nframes_t);
|
||||
const char * (*port_name) (const jack_port_t *port);
|
||||
|
||||
void (*port_get_latency_range) (jack_port_t *port,
|
||||
jack_latency_callback_mode_t mode,
|
||||
jack_latency_range_t *range);
|
||||
void (*port_set_latency_range) (jack_port_t *port,
|
||||
jack_latency_callback_mode_t mode,
|
||||
jack_latency_range_t *range);
|
||||
|
||||
|
||||
int (*connect) (jack_client_t *client,
|
||||
const char *source_port,
|
||||
const char *destination_port);
|
||||
int (*disconnect) (jack_client_t *client,
|
||||
const char *source_port,
|
||||
const char *destination_port);
|
||||
|
||||
const char ** (*get_ports) (jack_client_t *client,
|
||||
const char *port_name_pattern,
|
||||
const char *type_name_pattern,
|
||||
unsigned long flags);
|
||||
void (*free) (void* ptr);
|
||||
|
||||
int (*set_process_thread) (jack_client_t* client,
|
||||
JackThreadCallback thread_callback, void *arg);
|
||||
int (*set_xrun_callback) (jack_client_t *client,
|
||||
JackXRunCallback xrun_callback, void *arg);
|
||||
void (*on_info_shutdown) (jack_client_t *client,
|
||||
JackInfoShutdownCallback shutdown_callback, void *arg);
|
||||
int (*set_latency_callback) (jack_client_t *client,
|
||||
JackLatencyCallback latency_callback, void *arg);
|
||||
};
|
||||
|
||||
|
||||
static inline int weakjack_load_by_path(struct weakjack *jack, const char *path)
|
||||
{
|
||||
void *hnd;
|
||||
|
||||
hnd = dlopen(path, RTLD_NOW);
|
||||
if (hnd == NULL)
|
||||
return -errno;
|
||||
|
||||
pw_log_info("opened libjack: %s", path);
|
||||
|
||||
#define LOAD_SYM(name) ({ \
|
||||
if ((jack->name = dlsym(hnd, "jack_"#name )) == NULL) \
|
||||
return -ENOSYS; \
|
||||
})
|
||||
spa_zero(*jack);
|
||||
LOAD_SYM(cycle_wait);
|
||||
LOAD_SYM(cycle_signal);
|
||||
LOAD_SYM(frame_time);
|
||||
LOAD_SYM(get_cycle_times);
|
||||
LOAD_SYM(transport_query);
|
||||
|
||||
LOAD_SYM(client_open);
|
||||
LOAD_SYM(client_close);
|
||||
|
||||
LOAD_SYM(activate);
|
||||
LOAD_SYM(deactivate);
|
||||
|
||||
LOAD_SYM(get_sample_rate);
|
||||
|
||||
LOAD_SYM(recompute_total_latencies);
|
||||
|
||||
LOAD_SYM(port_register);
|
||||
LOAD_SYM(port_unregister);
|
||||
LOAD_SYM(port_get_buffer);
|
||||
LOAD_SYM(port_name);
|
||||
|
||||
LOAD_SYM(port_get_latency_range);
|
||||
LOAD_SYM(port_set_latency_range);
|
||||
|
||||
LOAD_SYM(connect);
|
||||
LOAD_SYM(disconnect);
|
||||
|
||||
LOAD_SYM(get_ports);
|
||||
LOAD_SYM(free);
|
||||
|
||||
LOAD_SYM(set_process_thread);
|
||||
LOAD_SYM(set_xrun_callback);
|
||||
LOAD_SYM(on_info_shutdown);
|
||||
LOAD_SYM(set_latency_callback);
|
||||
#undef LOAD_SYM
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int weakjack_load(struct weakjack *jack, const char *lib)
|
||||
{
|
||||
int res = -ENOENT;
|
||||
|
||||
if (lib[0] != '/') {
|
||||
const char *search_dirs, *p, *state = NULL;
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
search_dirs = getenv("LIBJACK_PATH");
|
||||
if (!search_dirs)
|
||||
search_dirs = "/usr/lib64:/usr/lib/:" LIBDIR;
|
||||
|
||||
|
||||
while ((p = pw_split_walk(search_dirs, ":", &len, &state))) {
|
||||
int pathlen;
|
||||
|
||||
if (len >= sizeof(path)) {
|
||||
res = -ENAMETOOLONG;
|
||||
continue;
|
||||
}
|
||||
pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib);
|
||||
if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) {
|
||||
res = -ENAMETOOLONG;
|
||||
continue;
|
||||
}
|
||||
if ((res = weakjack_load_by_path(jack, path)) == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
res = weakjack_load_by_path(jack, lib);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PIPEWIRE_WEAK_JACK_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue