Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/actions/test-natives/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,22 @@ runs:
name: natives-${{ inputs.platform-name }}
path: natives

# PulseAudio is deliberately absent on the test runners: the natives open
# it at runtime, and the tests prove that they load without it.
# PulseAudio, libudev and libdbus are deliberately not installed here: the
# natives open them at runtime, and the armhf lane, whose image has none of
# them, proves that they load without them.
- name: Install 32-bit runtime libraries
if: runner.os == 'Linux' && inputs.java-architecture == 'armv7'
run: |
sudo dpkg --add-architecture armhf
sudo apt-get update
sudo apt-get install -y libc6:armhf libstdc++6:armhf zlib1g:armhf libx11-6:armhf libxext6:armhf libxfixes3:armhf libxdamage1:armhf libxtst6:armhf libxrandr2:armhf libxcomposite1:armhf libglib2.0-0:armhf libgbm1:armhf libdrm2:armhf libdbus-1-3:armhf libudev1:armhf
sudo apt-get install -y libc6:armhf libstdc++6:armhf zlib1g:armhf libx11-6:armhf libxext6:armhf libxfixes3:armhf libxdamage1:armhf libxtst6:armhf libxrandr2:armhf libxcomposite1:armhf libglib2.0-0:armhf libgbm1:armhf libdrm2:armhf
shell: bash

- name: Install runtime libraries
if: runner.os == 'Linux' && inputs.java-architecture != 'armv7'
run: |
sudo apt-get update
sudo apt-get install -y libx11-6 libxext6 libxfixes3 libxdamage1 libxtst6 libxrandr2 libxcomposite1 libglib2.0-0 libgbm1 libdrm2 libdbus-1-3 libudev1
sudo apt-get install -y libx11-6 libxext6 libxfixes3 libxdamage1 libxtst6 libxrandr2 libxcomposite1 libglib2.0-0 libgbm1 libdrm2
shell: bash

- name: Set up JDK ${{ inputs.java-version }}
Expand Down
2 changes: 1 addition & 1 deletion webrtc-jni/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ if(APPLE)
elseif(LINUX)
set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi")

target_link_libraries(${PROJECT_NAME} ${CXX_LIBS} udev)
target_link_libraries(${PROJECT_NAME} ${CXX_LIBS})
target_link_libraries(${PROJECT_NAME} dl)
elseif(WIN32)
target_link_libraries(${PROJECT_NAME} dwmapi.lib mf.lib mfreadwrite.lib mfplat.lib mfuuid.lib shcore.lib)
Expand Down
4 changes: 2 additions & 2 deletions webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ if(APPLE)
target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_MAC WEBRTC_POSIX WEBRTC_USE_H264)
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreAudio" "-framework CoreVideo" "-framework ScreenCaptureKit" "-framework AudioToolbox" "-framework IOSurface" "-framework ApplicationServices" "-framework AppKit")
elseif(LINUX)
# Find DBus
# Find DBus (headers only: the JNI code opens libdbus at runtime)
find_package(PkgConfig QUIET REQUIRED) # Include functions provided by PkgConfig module.
pkg_check_modules(DBUS REQUIRED dbus-1)
# Wayland/PipeWire desktop capture: libwebrtc.a references gio, gbm and libdrm
Expand All @@ -226,7 +226,7 @@ elseif(LINUX)
# libpipewire dev package.)
target_include_directories(${PROJECT_NAME} PUBLIC ${DBUS_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS})
target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_LINUX WEBRTC_POSIX WEBRTC_USE_H264 WEBRTC_USE_X11 WEBRTC_USE_PIPEWIRE WEBRTC_USE_GIO)
target_link_libraries(${PROJECT_NAME} X11 Xext Xfixes Xdamage Xtst Xrandr Xcomposite dbus-1 ${GIO_LIBRARIES} ${GBM_LIBRARIES} ${DRM_LIBRARIES})
target_link_libraries(${PROJECT_NAME} X11 Xext Xfixes Xdamage Xtst Xrandr Xcomposite ${GIO_LIBRARIES} ${GBM_LIBRARIES} ${DRM_LIBRARIES})
elseif(WIN32)
# RTC_ENABLE_WIN_WGC must match the gn build: webrtc.lib is compiled with gn's
# default rtc_enable_win_wgc=true (webrtc.gni: "rtc_enable_win_wgc = is_win"),
Expand Down
124 changes: 124 additions & 0 deletions webrtc-jni/src/main/cpp/include/media/video/desktop/linux/DBusLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright 2019 Alex Andres
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#ifndef JNI_WEBRTC_MEDIA_DESKTOP_LINUX_DBUS_LOADER_H_
#define JNI_WEBRTC_MEDIA_DESKTOP_LINUX_DBUS_LOADER_H_

#include <dbus/dbus.h>

#include <dlfcn.h>

namespace jni
{
namespace avdev
{
typedef void (*dbus_error_init_t)(DBusError * error);
typedef void (*dbus_error_free_t)(DBusError * error);
typedef dbus_bool_t (*dbus_error_is_set_t)(const DBusError * error);
typedef DBusConnection * (*dbus_bus_get_t)(DBusBusType type, DBusError * error);
typedef dbus_bool_t (*dbus_bus_name_has_owner_t)(DBusConnection * connection, const char * name, DBusError * error);
typedef void (*dbus_connection_unref_t)(DBusConnection * connection);
typedef DBusMessage * (*dbus_connection_send_with_reply_and_block_t)(DBusConnection * connection, DBusMessage * message, int timeout, DBusError * error);
typedef DBusMessage * (*dbus_message_new_method_call_t)(const char * destination, const char * path, const char * iface, const char * method);
typedef dbus_bool_t (*dbus_message_append_args_t)(DBusMessage * message, int firstArgType, ...);
typedef void (*dbus_message_unref_t)(DBusMessage * message);
typedef dbus_bool_t (*dbus_message_iter_init_t)(DBusMessage * message, DBusMessageIter * iter);
typedef void (*dbus_message_iter_get_basic_t)(DBusMessageIter * iter, void * value);

class DBusLoader
{
public:
static DBusLoader & instance()
{
static DBusLoader instance;
return instance;
}

bool load()
{
if (loaded) {
return true;
}

handle = dlopen("libdbus-1.so.3", RTLD_NOW);

if (!handle) {
return false;
}

#define DBUS_LOAD_SYM(name) \
name = (name##_t) dlsym(handle, #name); \
if (!name) { close(); return false; }

DBUS_LOAD_SYM(dbus_error_init);
DBUS_LOAD_SYM(dbus_error_free);
DBUS_LOAD_SYM(dbus_error_is_set);
DBUS_LOAD_SYM(dbus_bus_get);
DBUS_LOAD_SYM(dbus_bus_name_has_owner);
DBUS_LOAD_SYM(dbus_connection_unref);
DBUS_LOAD_SYM(dbus_connection_send_with_reply_and_block);
DBUS_LOAD_SYM(dbus_message_new_method_call);
DBUS_LOAD_SYM(dbus_message_append_args);
DBUS_LOAD_SYM(dbus_message_unref);
DBUS_LOAD_SYM(dbus_message_iter_init);
DBUS_LOAD_SYM(dbus_message_iter_get_basic);

#undef DBUS_LOAD_SYM

loaded = true;

return true;
}

void close()
{
if (handle) {
dlclose(handle);
handle = nullptr;
}

loaded = false;
}

bool isLoaded() const
{
return loaded;
}

dbus_error_init_t dbus_error_init;
dbus_error_free_t dbus_error_free;
dbus_error_is_set_t dbus_error_is_set;
dbus_bus_get_t dbus_bus_get;
dbus_bus_name_has_owner_t dbus_bus_name_has_owner;
dbus_connection_unref_t dbus_connection_unref;
dbus_connection_send_with_reply_and_block_t dbus_connection_send_with_reply_and_block;
dbus_message_new_method_call_t dbus_message_new_method_call;
dbus_message_append_args_t dbus_message_append_args;
dbus_message_unref_t dbus_message_unref;
dbus_message_iter_init_t dbus_message_iter_init;
dbus_message_iter_get_basic_t dbus_message_iter_get_basic;

private:
DBusLoader() : loaded(false), handle(nullptr) {}

bool loaded;
void * handle;
};
}
}

#endif
151 changes: 151 additions & 0 deletions webrtc-jni/src/main/cpp/include/media/video/linux/UdevLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright 2019 Alex Andres
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#ifndef JNI_WEBRTC_MEDIA_V4L2_UDEV_LOADER_H_
#define JNI_WEBRTC_MEDIA_V4L2_UDEV_LOADER_H_

#include <libudev.h>

#include <dlfcn.h>

namespace jni
{
namespace avdev
{
typedef struct udev * (*udev_new_t)();
typedef struct udev * (*udev_unref_t)(struct udev * udev);
typedef struct udev_enumerate * (*udev_enumerate_new_t)(struct udev * udev);
typedef struct udev_enumerate * (*udev_enumerate_unref_t)(struct udev_enumerate * enumerate);
typedef int (*udev_enumerate_add_match_subsystem_t)(struct udev_enumerate * enumerate, const char * subsystem);
typedef int (*udev_enumerate_scan_devices_t)(struct udev_enumerate * enumerate);
typedef struct udev_list_entry * (*udev_enumerate_get_list_entry_t)(struct udev_enumerate * enumerate);
typedef struct udev_list_entry * (*udev_list_entry_get_next_t)(struct udev_list_entry * entry);
typedef const char * (*udev_list_entry_get_name_t)(struct udev_list_entry * entry);
typedef struct udev_device * (*udev_device_new_from_syspath_t)(struct udev * udev, const char * syspath);
typedef struct udev_device * (*udev_device_unref_t)(struct udev_device * device);
typedef const char * (*udev_device_get_devnode_t)(struct udev_device * device);
typedef const char * (*udev_device_get_subsystem_t)(struct udev_device * device);
typedef const char * (*udev_device_get_action_t)(struct udev_device * device);
typedef const char * (*udev_device_get_property_value_t)(struct udev_device * device, const char * key);
typedef struct udev_monitor * (*udev_monitor_new_from_netlink_t)(struct udev * udev, const char * name);
typedef struct udev_monitor * (*udev_monitor_unref_t)(struct udev_monitor * monitor);
typedef int (*udev_monitor_filter_add_match_subsystem_devtype_t)(struct udev_monitor * monitor, const char * subsystem, const char * devtype);
typedef int (*udev_monitor_enable_receiving_t)(struct udev_monitor * monitor);
typedef int (*udev_monitor_get_fd_t)(struct udev_monitor * monitor);
typedef struct udev_device * (*udev_monitor_receive_device_t)(struct udev_monitor * monitor);

class UdevLoader
{
public:
static UdevLoader & instance()
{
static UdevLoader instance;
return instance;
}

bool load()
{
if (loaded) {
return true;
}

handle = dlopen("libudev.so.1", RTLD_NOW);

if (!handle) {
return false;
}

#define UDEV_LOAD_SYM(name) \
name = (name##_t) dlsym(handle, #name); \
if (!name) { close(); return false; }

UDEV_LOAD_SYM(udev_new);
UDEV_LOAD_SYM(udev_unref);
UDEV_LOAD_SYM(udev_enumerate_new);
UDEV_LOAD_SYM(udev_enumerate_unref);
UDEV_LOAD_SYM(udev_enumerate_add_match_subsystem);
UDEV_LOAD_SYM(udev_enumerate_scan_devices);
UDEV_LOAD_SYM(udev_enumerate_get_list_entry);
UDEV_LOAD_SYM(udev_list_entry_get_next);
UDEV_LOAD_SYM(udev_list_entry_get_name);
UDEV_LOAD_SYM(udev_device_new_from_syspath);
UDEV_LOAD_SYM(udev_device_unref);
UDEV_LOAD_SYM(udev_device_get_devnode);
UDEV_LOAD_SYM(udev_device_get_subsystem);
UDEV_LOAD_SYM(udev_device_get_action);
UDEV_LOAD_SYM(udev_device_get_property_value);
UDEV_LOAD_SYM(udev_monitor_new_from_netlink);
UDEV_LOAD_SYM(udev_monitor_unref);
UDEV_LOAD_SYM(udev_monitor_filter_add_match_subsystem_devtype);
UDEV_LOAD_SYM(udev_monitor_enable_receiving);
UDEV_LOAD_SYM(udev_monitor_get_fd);
UDEV_LOAD_SYM(udev_monitor_receive_device);

#undef UDEV_LOAD_SYM

loaded = true;

return true;
}

void close()
{
if (handle) {
dlclose(handle);
handle = nullptr;
}

loaded = false;
}

bool isLoaded() const
{
return loaded;
}

udev_new_t udev_new;
udev_unref_t udev_unref;
udev_enumerate_new_t udev_enumerate_new;
udev_enumerate_unref_t udev_enumerate_unref;
udev_enumerate_add_match_subsystem_t udev_enumerate_add_match_subsystem;
udev_enumerate_scan_devices_t udev_enumerate_scan_devices;
udev_enumerate_get_list_entry_t udev_enumerate_get_list_entry;
udev_list_entry_get_next_t udev_list_entry_get_next;
udev_list_entry_get_name_t udev_list_entry_get_name;
udev_device_new_from_syspath_t udev_device_new_from_syspath;
udev_device_unref_t udev_device_unref;
udev_device_get_devnode_t udev_device_get_devnode;
udev_device_get_subsystem_t udev_device_get_subsystem;
udev_device_get_action_t udev_device_get_action;
udev_device_get_property_value_t udev_device_get_property_value;
udev_monitor_new_from_netlink_t udev_monitor_new_from_netlink;
udev_monitor_unref_t udev_monitor_unref;
udev_monitor_filter_add_match_subsystem_devtype_t udev_monitor_filter_add_match_subsystem_devtype;
udev_monitor_enable_receiving_t udev_monitor_enable_receiving;
udev_monitor_get_fd_t udev_monitor_get_fd;
udev_monitor_receive_device_t udev_monitor_receive_device;

private:
UdevLoader() : loaded(false), handle(nullptr) {}

bool loaded;
void * handle;
};
}
}

#endif
Loading
Loading