Skip to content

Instantly share code, notes, and snippets.

@GloriousEggroll
Created November 12, 2023 09:41
Show Gist options
  • Save GloriousEggroll/be69950e6d0c8cacae789ac160f9eda1 to your computer and use it in GitHub Desktop.
Save GloriousEggroll/be69950e6d0c8cacae789ac160f9eda1 to your computer and use it in GitHub Desktop.
chromium dlopen
From a19fe8c2f6b9cdda194ca8d51c025389067a068a Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
Date: Tue, 7 Feb 2023 14:05:29 +0100
Subject: Allow to dlopen openh264
---
media/BUILD.gn | 3 +++
media/media_options.gni | 4 +++
media/video/BUILD.gn | 19 ++++++++++++-
media/video/openh264.sigs | 9 +++++++
media/video/openh264_stub_header.fragment | 8 ++++++
media/video/openh264_video_encoder.cc | 25 +++++++++++++++++
sandbox/policy/linux/bpf_gpu_policy_linux.cc | 1 +
.../renderer/modules/mediarecorder/BUILD.gn | 18 ++++++++++++-
.../modules/mediarecorder/h264_encoder.cc | 27 +++++++++++++++++++
.../modules/mediarecorder/h264_encoder.h | 2 ++
.../modules/mediarecorder/openh264.sigs | 14 ++++++++++
.../openh264_stub_header.fragment | 11 ++++++++
.../blink/renderer/modules/webcodecs/BUILD.gn | 3 ---
13 files changed, 139 insertions(+), 5 deletions(-)
create mode 100644 media/video/openh264.sigs
create mode 100644 media/video/openh264_stub_header.fragment
create mode 100644 third_party/blink/renderer/modules/mediarecorder/openh264.sigs
create mode 100644 third_party/blink/renderer/modules/mediarecorder/openh264_stub_header.fragment
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 8ebd7c5757..c43f6d1000 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -97,6 +97,9 @@ config("media_config") {
if (use_cras) {
defines += [ "USE_CRAS" ]
}
+ if (media_use_openh264 && media_dlopen_openh264) {
+ defines += [ "DLOPEN_OPENH264" ]
+ }
}
# Internal grouping of the configs necessary to support sub-folders having their
diff --git a/media/media_options.gni b/media/media_options.gni
index 61d5046d0c..039197a84b 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -64,6 +64,10 @@ declare_args() {
media_use_openh264 = false
}
+ # Allow to use OpenH264 on systems where OpenH264 cannot be installed by
+ # default due to licensing, but can be installed later from other sources.
+ media_dlopen_openh264 = false
+
# Override to dynamically link the cras (ChromeOS audio) library.
use_cras = is_chromeos_device
diff --git a/media/video/BUILD.gn b/media/video/BUILD.gn
index 4e27ad1b04..973c58c306 100644
--- a/media/video/BUILD.gn
+++ b/media/video/BUILD.gn
@@ -3,6 +3,18 @@
# found in the LICENSE file.
import("//media/media_options.gni")
+import("//tools/generate_stubs/rules.gni")
+
+if (media_use_openh264 && media_dlopen_openh264) {
+ # When OpenH264 is not directly linked, use stubs to allow for dlopening of
+ # the binary.
+ generate_stubs("openh264_stubs") {
+ extra_header = "openh264_stub_header.fragment"
+ output_name = "openh264_stubs"
+ sigs = [ "openh264.sigs" ]
+ deps = [ "//base" ]
+ }
+}
source_set("video") {
# Do not expand the visibility here without double-checking with OWNERS, this
@@ -116,7 +128,12 @@ source_set("video") {
"openh264_video_encoder.cc",
"openh264_video_encoder.h",
]
- deps += [ "//third_party/openh264:encoder" ]
+
+ if (media_dlopen_openh264) {
+ deps += [ ":openh264_stubs" ]
+ } else {
+ deps += [ "//third_party/openh264:encoder" ]
+ }
}
if (is_apple) {
diff --git a/media/video/openh264.sigs b/media/video/openh264.sigs
new file mode 100644
index 0000000000..82f6b43619
--- /dev/null
+++ b/media/video/openh264.sigs
@@ -0,0 +1,9 @@
+// Copyright 2023 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//------------------------------------------------
+// Functions from OpenH264.
+//------------------------------------------------
+int WelsCreateSVCEncoder(ISVCEncoder **ppEncoder);
+void WelsDestroySVCEncoder(ISVCEncoder *pEncoder);
diff --git a/media/video/openh264_stub_header.fragment b/media/video/openh264_stub_header.fragment
new file mode 100644
index 0000000000..937dffc847
--- /dev/null
+++ b/media/video/openh264_stub_header.fragment
@@ -0,0 +1,8 @@
+// The extra include header needed in the generated stub file for defining
+// various OpenH264 types.
+
+extern "C" {
+
+#include "third_party/openh264/src/codec/api/wels/codec_api.h"
+
+}
diff --git a/media/video/openh264_video_encoder.cc b/media/video/openh264_video_encoder.cc
index 831de2f083..cda82b7f96 100644
--- a/media/video/openh264_video_encoder.cc
+++ b/media/video/openh264_video_encoder.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <limits>
+#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/system/sys_info.h"
@@ -17,10 +18,22 @@
#include "media/base/video_util.h"
#include "media/video/video_encoder_info.h"
+#if defined(DLOPEN_OPENH264)
+#include "media/video/openh264_stubs.h"
+#endif // defined(DLOPEN_OPENH264)
+
namespace media {
namespace {
+#if defined(DLOPEN_OPENH264)
+using media_video::InitializeStubs;
+using media_video::kModuleOpenh264;
+using media_video::StubPathMap;
+
+static const base::FilePath::CharType kOpenH264Lib[] = FILE_PATH_LITERAL("libopenh264.so.7");
+#endif // defined(DLOPEN_OPENH264)
+
EProfileIdc ToOpenH264Profile(media::VideoCodecProfile profile) {
switch (profile) {
case media::H264PROFILE_BASELINE:
@@ -173,6 +186,18 @@ void OpenH264VideoEncoder::Initialize(VideoCodecProfile profile,
return;
}
+#if defined(DLOPEN_OPENH264)
+ StubPathMap paths;
+ paths[kModuleOpenh264].push_back(kOpenH264Lib);
+
+ if (!InitializeStubs(paths)) {
+ std::move(done_cb).Run(
+ EncoderStatus(EncoderStatus::Codes::kEncoderInitializationError,
+ "Failed on loading the openh264 library and symbols,"));
+ return;
+ }
+#endif // defined(DLOPEN_OPENH264)
+
ISVCEncoder* raw_codec = nullptr;
if (WelsCreateSVCEncoder(&raw_codec) != 0) {
std::move(done_cb).Run(
diff --git a/sandbox/policy/linux/bpf_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
index 35ccbb7a7f..dd6b990d2e 100644
--- a/sandbox/policy/linux/bpf_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
@@ -41,6 +41,7 @@ GpuProcessPolicy::~GpuProcessPolicy() {}
// Main policy for x86_64/i386. Extended by CrosArmGpuProcessPolicy.
ResultExpr GpuProcessPolicy::EvaluateSyscall(int sysno) const {
+ VLOG(1) << "GpuProcessPolicy::EvaluateSyscall";
// Many GPU drivers need to dlopen additional libraries (see the file
// permissions in gpu_sandbox_hook_linux.cc that end in .so).
if (SyscallSets::IsDlopen(sysno)) {
diff --git a/third_party/blink/renderer/modules/mediarecorder/BUILD.gn b/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
index 078ae08a59..6353e12ad9 100644
--- a/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
+++ b/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
@@ -7,12 +7,23 @@ import("//media/media_options.gni")
import("//third_party/blink/renderer/modules/modules.gni")
import("//third_party/libaom/options.gni")
import("//third_party/webrtc/webrtc.gni")
+import("//tools/generate_stubs/rules.gni")
buildflag_header("buildflags") {
header = "buildflags.h"
flags = [ "RTC_USE_H264=$rtc_use_h264" ]
}
+if (rtc_use_h264 && rtc_dlopen_openh264) {
+ # When OpenH264 is not directly linked, use stubs to allow for dlopening of
+ # the binary.
+ generate_stubs("openh264_stubs") {
+ extra_header = "openh264_stub_header.fragment"
+ output_name = "openh264_stubs"
+ sigs = [ "openh264.sigs" ]
+ }
+}
+
blink_modules_sources("mediarecorder") {
sources = [
"audio_track_encoder.cc",
@@ -63,7 +74,12 @@ blink_modules_sources("mediarecorder") {
"h264_encoder.h",
]
- deps += [ "//third_party/openh264:encoder" ]
+ if (rtc_dlopen_openh264) {
+ defines = [ "BLINK_DLOPEN_OPENH264" ]
+ deps += [ ":openh264_stubs" ]
+ } else {
+ deps += [ "//third_party/openh264:encoder" ]
+ }
}
if (enable_libaom) {
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
index 5fff436833..bba0564731 100644
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -28,9 +28,21 @@
#include "third_party/openh264/src/codec/api/wels/codec_def.h"
#include "ui/gfx/geometry/size.h"
+#if defined(BLINK_DLOPEN_OPENH264)
+#include "third_party/blink/renderer/modules/mediarecorder/openh264_stubs.h"
+#endif // defined(BLINK_DLOPEN_OPENH264)
+
namespace blink {
namespace {
+#if defined(BLINK_DLOPEN_OPENH264)
+using third_party_blink_renderer_modules_mediarecorder::InitializeStubs;
+using third_party_blink_renderer_modules_mediarecorder::kModuleOpenh264;
+using third_party_blink_renderer_modules_mediarecorder::StubPathMap;
+
+static constexpr char kOpenH264Lib[] = "libopenh264.so.7";
+#endif
+
absl::optional<EProfileIdc> ToOpenH264Profile(
media::VideoCodecProfile profile) {
static constexpr auto kProfileToEProfileIdc =
@@ -95,6 +107,13 @@ H264Encoder::H264Encoder(
bits_per_second),
codec_profile_(codec_profile) {
DCHECK_EQ(codec_profile_.codec_id, VideoTrackRecorder::CodecId::kH264);
+
+#if defined(BLINK_DLOPEN_OPENH264)
+ StubPathMap paths;
+ paths[kModuleOpenh264].push_back(kOpenH264Lib);
+
+ openh264_dlopened_ = InitializeStubs(paths);
+#endif
}
// Needs to be defined here to combat a Windows linking issue.
@@ -189,6 +208,14 @@ void H264Encoder::EncodeFrame(scoped_refptr<media::VideoFrame> frame,
bool H264Encoder::ConfigureEncoder(const gfx::Size& size) {
TRACE_EVENT0("media", "H264Encoder::ConfigureEncoder");
+
+#if defined(BLINK_DLOPEN_OPENH264)
+ if (!openh264_dlopened_) {
+ NOTREACHED() << "Failed to dlopen openh264";
+ return false;
+ }
+#endif
+
ISVCEncoder* temp_encoder = nullptr;
if (WelsCreateSVCEncoder(&temp_encoder) != 0) {
NOTREACHED() << "Failed to create OpenH264 encoder";
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
index ff80d42a7b..5f2e823194 100644
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
@@ -57,6 +57,8 @@ class MODULES_EXPORT H264Encoder final : public VideoTrackRecorder::Encoder {
gfx::Size configured_size_;
ScopedISVCEncoderPtr openh264_encoder_;
+ bool openh264_dlopened_ = false;
+
// The |VideoFrame::timestamp()| of the first received frame.
base::TimeTicks first_frame_timestamp_;
base::WeakPtrFactory<H264Encoder> weak_factory_{this};
diff --git a/third_party/blink/renderer/modules/mediarecorder/openh264.sigs b/third_party/blink/renderer/modules/mediarecorder/openh264.sigs
new file mode 100644
index 0000000000..4924f8e9a1
--- /dev/null
+++ b/third_party/blink/renderer/modules/mediarecorder/openh264.sigs
@@ -0,0 +1,14 @@
+// Copyright 2022 The WebRTC project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//------------------------------------------------
+// Functions from OpenH264.
+//------------------------------------------------
+int WelsCreateSVCEncoder(ISVCEncoder **ppEncoder);
+void WelsDestroySVCEncoder(ISVCEncoder *pEncoder);
+int WelsGetDecoderCapability(SDecoderCapability *pDecCapability);
+long WelsCreateDecoder(ISVCDecoder **ppDecoder);
+void WelsDestroyDecoder(ISVCDecoder *pDecoder);
+OpenH264Version WelsGetCodecVersion(void);
+void WelsGetCodecVersionEx(OpenH264Version *pVersion);
diff --git a/third_party/blink/renderer/modules/mediarecorder/openh264_stub_header.fragment b/third_party/blink/renderer/modules/mediarecorder/openh264_stub_header.fragment
new file mode 100644
index 0000000000..9bc0a7cbee
--- /dev/null
+++ b/third_party/blink/renderer/modules/mediarecorder/openh264_stub_header.fragment
@@ -0,0 +1,11 @@
+// The extra include header needed in the generated stub file for defining
+// various OpenH264 types.
+
+extern "C" {
+
+#include "third_party/openh264/src/codec/api/wels/codec_api.h"
+#include "third_party/openh264/src/codec/api/wels/codec_app_def.h"
+#include "third_party/openh264/src/codec/api/wels/codec_def.h"
+#include "third_party/openh264/src/codec/api/wels/codec_ver.h"
+
+}
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
index 70f30624dd..659161b295 100644
--- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -109,9 +109,6 @@ blink_modules_sources("webcodecs") {
if (media_use_libvpx) {
deps += [ "//third_party/libvpx" ]
}
- if (media_use_openh264) {
- deps += [ "//third_party/openh264:encoder" ]
- }
if (is_fuchsia) {
deps += [ "//media/fuchsia/video" ]
}
--
2.41.0
From 4c84adf2f52d64c32f7d86eca9d8f4988e990292 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Mon, 23 Jan 2023 09:30:48 +0100
Subject: [WebRTC] Video encoding: allow to dlopen h264
---
.../webrtc/modules/video_coding/BUILD.gn | 30 ++++++++++++++++---
.../codecs/h264/h264_encoder_impl.cc | 21 +++++++++++++
.../video_coding/codecs/h264/openh264.sigs | 14 +++++++++
.../codecs/h264/openh264_stub_header.fragment | 11 +++++++
third_party/webrtc/webrtc.gni | 4 +++
5 files changed, 76 insertions(+), 4 deletions(-)
create mode 100644 third_party/webrtc/modules/video_coding/codecs/h264/openh264.sigs
create mode 100644 third_party/webrtc/modules/video_coding/codecs/h264/openh264_stub_header.fragment
diff --git a/third_party/webrtc/modules/video_coding/BUILD.gn b/third_party/webrtc/modules/video_coding/BUILD.gn
index f0bce34e3e..320fa57ec7 100644
--- a/third_party/webrtc/modules/video_coding/BUILD.gn
+++ b/third_party/webrtc/modules/video_coding/BUILD.gn
@@ -7,6 +7,7 @@
# be found in the AUTHORS file in the root of the source tree.
import("//third_party/libaom/options.gni")
+import("//tools/generate_stubs/rules.gni")
import("../../webrtc.gni")
rtc_library("encoded_frame") {
@@ -453,6 +454,21 @@ rtc_library("video_coding_utility") {
]
}
+if (rtc_use_h264 && rtc_dlopen_openh264) {
+ # When OpenH264 is not directly linked, use stubs to allow for dlopening of
+ # the binary.
+ generate_stubs("openh264_stubs") {
+ configs = [ "../../:common_config" ]
+ deps = [ "../../rtc_base:logging" ]
+ extra_header = "codecs/h264/openh264_stub_header.fragment"
+ logging_function = "RTC_LOG(LS_VERBOSE)"
+ logging_include = "rtc_base/logging.h"
+ output_name = "codecs/h264/openh264_stubs"
+ path_from_source = "modules/video_coding/codecs/h264"
+ sigs = [ "codecs/h264/openh264.sigs" ]
+ }
+}
+
rtc_library("webrtc_h264") {
visibility = [ "*" ]
sources = [
@@ -499,10 +514,17 @@ rtc_library("webrtc_h264") {
]
if (rtc_use_h264) {
- deps += [
- "//third_party/ffmpeg",
- "//third_party/openh264:encoder",
- ]
+ deps += [ "//third_party/ffmpeg" ]
+
+ if (rtc_dlopen_openh264) {
+ defines = [ "WEBRTC_DLOPEN_OPENH264" ]
+ deps += [ ":openh264_stubs" ]
+ } else {
+ deps += [
+ "//third_party/openh264:encoder",
+ ]
+ }
+
if (!build_with_mozilla) {
deps += [ "../../media:rtc_media_base" ]
}
diff --git a/third_party/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/third_party/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index 7a9f640ce6..a6f8f36d09 100644
--- a/third_party/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+++ b/third_party/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
@@ -39,10 +39,22 @@
#include "third_party/openh264/src/codec/api/wels/codec_def.h"
#include "third_party/openh264/src/codec/api/wels/codec_ver.h"
+#if defined(WEBRTC_DLOPEN_OPENH264)
+#include "modules/video_coding/codecs/h264/openh264_stubs.h"
+#endif // defined(WEBRTC_DLOPEN_OPENH264)
+
namespace webrtc {
namespace {
+#if defined(WEBRTC_DLOPEN_OPENH264)
+using modules_video_coding_codecs_h264::InitializeStubs;
+using modules_video_coding_codecs_h264::kModuleOpenh264;
+using modules_video_coding_codecs_h264::StubPathMap;
+
+static constexpr char kOpenH264Lib[] = "libopenh264.so.7";
+#endif
+
const bool kOpenH264EncoderDetailedLogging = false;
// QP scaling thresholds.
@@ -198,6 +210,15 @@ H264EncoderImpl::~H264EncoderImpl() {
int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
const VideoEncoder::Settings& settings) {
+#if defined(WEBRTC_DLOPEN_OPENH264)
+ StubPathMap paths;
+ paths[kModuleOpenh264].push_back(kOpenH264Lib);
+
+ static bool result = InitializeStubs(paths);
+ if (!result)
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+#endif
+
ReportInit();
if (!inst || inst->codecType != kVideoCodecH264) {
ReportError();
diff --git a/third_party/webrtc/modules/video_coding/codecs/h264/openh264.sigs b/third_party/webrtc/modules/video_coding/codecs/h264/openh264.sigs
new file mode 100644
index 0000000000..4924f8e9a1
--- /dev/null
+++ b/third_party/webrtc/modules/video_coding/codecs/h264/openh264.sigs
@@ -0,0 +1,14 @@
+// Copyright 2022 The WebRTC project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//------------------------------------------------
+// Functions from OpenH264.
+//------------------------------------------------
+int WelsCreateSVCEncoder(ISVCEncoder **ppEncoder);
+void WelsDestroySVCEncoder(ISVCEncoder *pEncoder);
+int WelsGetDecoderCapability(SDecoderCapability *pDecCapability);
+long WelsCreateDecoder(ISVCDecoder **ppDecoder);
+void WelsDestroyDecoder(ISVCDecoder *pDecoder);
+OpenH264Version WelsGetCodecVersion(void);
+void WelsGetCodecVersionEx(OpenH264Version *pVersion);
diff --git a/third_party/webrtc/modules/video_coding/codecs/h264/openh264_stub_header.fragment b/third_party/webrtc/modules/video_coding/codecs/h264/openh264_stub_header.fragment
new file mode 100644
index 0000000000..9bc0a7cbee
--- /dev/null
+++ b/third_party/webrtc/modules/video_coding/codecs/h264/openh264_stub_header.fragment
@@ -0,0 +1,11 @@
+// The extra include header needed in the generated stub file for defining
+// various OpenH264 types.
+
+extern "C" {
+
+#include "third_party/openh264/src/codec/api/wels/codec_api.h"
+#include "third_party/openh264/src/codec/api/wels/codec_app_def.h"
+#include "third_party/openh264/src/codec/api/wels/codec_def.h"
+#include "third_party/openh264/src/codec/api/wels/codec_ver.h"
+
+}
diff --git a/third_party/webrtc/webrtc.gni b/third_party/webrtc/webrtc.gni
index 5a1c43c888..ceda0a70bd 100644
--- a/third_party/webrtc/webrtc.gni
+++ b/third_party/webrtc/webrtc.gni
@@ -192,6 +192,10 @@ declare_args() {
# Enable to use H265
rtc_use_h265 = proprietary_codecs
+ # Allow to use OpenH264 on systems where OpenH264 cannot be installed by
+ # default due to licensing, but can be installed later from other sources.
+ rtc_dlopen_openh264 = false
+
# Enable this flag to make webrtc::Mutex be implemented by absl::Mutex.
rtc_use_absl_mutex = false
--
2.41.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment