From a2e8f12656173c19662c6095707e564319822ffa Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Sat, 23 Aug 2025 00:06:09 -0400 Subject: [PATCH 1/8] Remove support for CEF 3770 and older The zeroed memory hack only applies on Windows if using CEF older than 3770, which we no longer support. --- obs-browser-plugin.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/obs-browser-plugin.cpp b/obs-browser-plugin.cpp index a7a61e0fe..f4ea29ffa 100644 --- a/obs-browser-plugin.cpp +++ b/obs-browser-plugin.cpp @@ -377,17 +377,8 @@ static void BrowserInit(void) BackupSignalHandlers(); bool success = CefInitialize(args, settings, app, nullptr); RestoreSignalHandlers(); -#elif (CHROME_VERSION_BUILD > 3770) - bool success = CefInitialize(args, settings, app, nullptr); #else - /* Massive (but amazing) hack to prevent chromium from modifying our - * process tokens and permissions, which caused us problems with winrt, - * used with window capture. Note, the structure internally is just - * two pointers normally. If it causes problems with future versions - * we'll just switch back to the static library but I doubt we'll need - * to. */ - uintptr_t zeroed_memory_lol[32] = {}; - bool success = CefInitialize(args, settings, app, zeroed_memory_lol); + bool success = CefInitialize(args, settings, app, nullptr); #endif if (!success) { From a84c73d51adc86460826b953520ebd071d6b2947 Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Sat, 23 Aug 2025 00:13:50 -0400 Subject: [PATCH 2/8] Remove support for CEF versions older than 4103 Assume we're always using CEF 5060 or newer. --- CMakeLists.txt | 1 - browser-client.cpp | 75 ------------------------------- browser-client.hpp | 14 +----- obs-browser-plugin.cpp | 9 ---- obs-browser-source-audio.cpp | 85 ------------------------------------ obs-browser-source.cpp | 15 +------ obs-browser-source.hpp | 22 +--------- 7 files changed, 5 insertions(+), 216 deletions(-) delete mode 100644 obs-browser-source-audio.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4662a84bc..a6c9952f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,6 @@ target_sources( deps/wide-string.cpp deps/wide-string.hpp obs-browser-plugin.cpp - obs-browser-source-audio.cpp obs-browser-source.cpp obs-browser-source.hpp) diff --git a/browser-client.cpp b/browser-client.cpp index 9b334b476..572dc9ff9 100644 --- a/browser-client.cpp +++ b/browser-client.cpp @@ -535,7 +535,6 @@ static speaker_layout GetSpeakerLayout(CefAudioHandler::ChannelLayout cefLayout) } } -#if CHROME_VERSION_BUILD >= 4103 void BrowserClient::OnAudioStreamStarted(CefRefPtr browser, const CefAudioParameters ¶ms_, int channels_) { @@ -608,80 +607,6 @@ bool BrowserClient::GetAudioParameters(CefRefPtr browser, CefAudioPa params.frames_per_buffer = kFramesPerBuffer; return true; } -#elif CHROME_VERSION_BUILD < 4103 -void BrowserClient::OnAudioStreamStarted(CefRefPtr browser, int id, int, ChannelLayout channel_layout, - int sample_rate, int) -{ - UNUSED_PARAMETER(browser); - if (!valid()) { - return; - } - - AudioStream &stream = bs->audio_streams[id]; - if (!stream.source) { - stream.source = obs_source_create_private("audio_line", nullptr, nullptr); - - obs_source_add_active_child(bs->source, stream.source); - - std::lock_guard lock(bs->audio_sources_mutex); - bs->audio_sources.push_back(stream.source); - } - - stream.speakers = GetSpeakerLayout(channel_layout); - stream.channels = get_audio_channels(stream.speakers); - stream.sample_rate = sample_rate; -} - -void BrowserClient::OnAudioStreamPacket(CefRefPtr browser, int id, const float **data, int frames, - int64_t pts) -{ - UNUSED_PARAMETER(browser); - if (!valid()) { - return; - } - - AudioStream &stream = bs->audio_streams[id]; - struct obs_source_audio audio = {}; - - const uint8_t **pcm = (const uint8_t **)data; - for (int i = 0; i < stream.channels; i++) - audio.data[i] = pcm[i]; - - audio.samples_per_sec = stream.sample_rate; - audio.frames = frames; - audio.format = AUDIO_FORMAT_FLOAT_PLANAR; - audio.speakers = stream.speakers; - audio.timestamp = (uint64_t)pts * 1000000LLU; - - obs_source_output_audio(stream.source, &audio); -} - -void BrowserClient::OnAudioStreamStopped(CefRefPtr browser, int id) -{ - UNUSED_PARAMETER(browser); - if (!valid()) { - return; - } - - auto pair = bs->audio_streams.find(id); - if (pair == bs->audio_streams.end()) { - return; - } - - AudioStream &stream = pair->second; - { - std::lock_guard lock(bs->audio_sources_mutex); - for (size_t i = 0; i < bs->audio_sources.size(); i++) { - obs_source_t *source = bs->audio_sources[i]; - if (source == stream.source) { - bs->audio_sources.erase(bs->audio_sources.begin() + i); - break; - } - } - } - bs->audio_streams.erase(pair); -} -#endif void BrowserClient::OnLoadEnd(CefRefPtr, CefRefPtr frame, int) { diff --git a/browser-client.hpp b/browser-client.hpp index bf21fdf55..787767b04 100644 --- a/browser-client.hpp +++ b/browser-client.hpp @@ -50,12 +50,11 @@ class BrowserClient : public CefClient, CefRect popupRect; CefRect originalPopupRect; -#if CHROME_VERSION_BUILD >= 4103 int sample_rate; int channels; ChannelLayout channel_layout; int frames_per_buffer; -#endif + inline BrowserClient(BrowserSource *bs_, bool sharing_avail, bool reroute_audio_, ControlLevel webpage_control_level_) : sharing_available(sharing_avail), @@ -137,7 +136,7 @@ class BrowserClient : public CefClient, const RectList &dirtyRects, void *shared_handle, bool new_texture) override; #endif #endif -#if CHROME_VERSION_BUILD >= 4103 + virtual void OnAudioStreamPacket(CefRefPtr browser, const float **data, int frames, int64_t pts) override; @@ -148,16 +147,7 @@ class BrowserClient : public CefClient, virtual void OnAudioStreamError(CefRefPtr browser, const CefString &message) override; const int kFramesPerBuffer = 1024; virtual bool GetAudioParameters(CefRefPtr browser, CefAudioParameters ¶ms) override; -#else - virtual void OnAudioStreamPacket(CefRefPtr browser, int audio_stream_id, const float **data, - int frames, int64_t pts) override; - - virtual void OnAudioStreamStopped(CefRefPtr browser, int audio_stream_id); - virtual void OnAudioStreamStarted(CefRefPtr browser, int audio_stream_id, int channels, - ChannelLayout channel_layout, int sample_rate, - int frames_per_buffer) override; -#endif /* CefLoadHandler */ virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) override; diff --git a/obs-browser-plugin.cpp b/obs-browser-plugin.cpp index f4ea29ffa..cf40a2631 100644 --- a/obs-browser-plugin.cpp +++ b/obs-browser-plugin.cpp @@ -469,15 +469,6 @@ void RegisterBrowserSource() info.video_render = [](void *data, gs_effect_t *) { static_cast(data)->Render(); }; -#if CHROME_VERSION_BUILD < 4103 - info.audio_mix = [](void *data, uint64_t *ts_out, struct audio_output_data *audio_output, size_t channels, - size_t sample_rate) { - return static_cast(data)->AudioMix(ts_out, audio_output, channels, sample_rate); - }; - info.enum_active_sources = [](void *data, obs_source_enum_proc_t cb, void *param) { - static_cast(data)->EnumAudioStreams(cb, param); - }; -#endif info.mouse_click = [](void *data, const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count) { static_cast(data)->SendMouseClick(event, type, mouse_up, click_count); diff --git a/obs-browser-source-audio.cpp b/obs-browser-source-audio.cpp deleted file mode 100644 index 58309714d..000000000 --- a/obs-browser-source-audio.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************** - Copyright (C) 2023 by Lain Bailey - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - ******************************************************************************/ - -#include "obs-browser-source.hpp" -#if CHROME_VERSION_BUILD < 4103 -void BrowserSource::EnumAudioStreams(obs_source_enum_proc_t cb, void *param) -{ - std::lock_guard lock(audio_sources_mutex); - for (obs_source_t *audio_source : audio_sources) { - cb(source, audio_source, param); - } -} - -static inline void mix_audio(float *__restrict p_out, const float *__restrict p_in, size_t pos, size_t count) -{ - float *__restrict out = p_out; - const float *__restrict in = p_in + pos; - const float *__restrict end = in + count; - - while (in < end) - *out++ += *in++; -} - -bool BrowserSource::AudioMix(uint64_t *ts_out, struct audio_output_data *audio_output, size_t channels, - size_t sample_rate) -{ - uint64_t timestamp = 0; - struct obs_source_audio_mix child_audio; - - std::lock_guard lock(audio_sources_mutex); - for (obs_source_t *s : audio_sources) { - if (!obs_source_audio_pending(s)) { - uint64_t source_ts = obs_source_get_audio_timestamp(s); - - if (source_ts && (!timestamp || source_ts < timestamp)) - timestamp = source_ts; - } - } - - if (!timestamp) - return false; - - for (obs_source_t *s : audio_sources) { - uint64_t source_ts; - size_t pos, count; - - if (obs_source_audio_pending(s)) { - continue; - } - - source_ts = obs_source_get_audio_timestamp(s); - if (!source_ts) { - continue; - } - - pos = (size_t)ns_to_audio_frames(sample_rate, source_ts - timestamp); - count = AUDIO_OUTPUT_FRAMES - pos; - - obs_source_get_audio_mix(s, &child_audio); - for (size_t ch = 0; ch < channels; ch++) { - float *out = audio_output->data[ch]; - float *in = child_audio.output[0].data[ch]; - - mix_audio(out, in, pos, count); - } - } - - *ts_out = timestamp; - return true; -} -#endif diff --git a/obs-browser-source.cpp b/obs-browser-source.cpp index edad36eda..1ebe84f0d 100644 --- a/obs-browser-source.cpp +++ b/obs-browser-source.cpp @@ -262,16 +262,7 @@ void BrowserSource::DestroyBrowser() ExecuteOnBrowser(ActuallyCloseBrowser, true); SetBrowser(nullptr); } -#if CHROME_VERSION_BUILD < 4103 -void BrowserSource::ClearAudioStreams() -{ - QueueCEFTask([this]() { - audio_streams.clear(); - std::lock_guard lock(audio_sources_mutex); - audio_sources.clear(); - }); -} -#endif + void BrowserSource::SendMouseClick(const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count) { @@ -590,9 +581,7 @@ void BrowserSource::Update(obs_data_t *settings) DestroyBrowser(); DestroyTextures(); -#if CHROME_VERSION_BUILD < 4103 - ClearAudioStreams(); -#endif + if (!shutdown_on_invisible || obs_source_showing(source)) create_browser = true; diff --git a/obs-browser-source.hpp b/obs-browser-source.hpp index 1aa2da6ae..5bf26b5ce 100644 --- a/obs-browser-source.hpp +++ b/obs-browser-source.hpp @@ -27,19 +27,6 @@ #include #include -#if CHROME_VERSION_BUILD < 4103 -#include -#include -#include - -struct AudioStream { - OBSSourceAutoRelease source; - speaker_layout speakers; - int channels; - int sample_rate; -}; -#endif - enum class ControlLevel : int { None, ReadObs, @@ -129,14 +116,7 @@ struct BrowserSource { void Update(obs_data_t *settings = nullptr); void Tick(); void Render(); -#if CHROME_VERSION_BUILD < 4103 - void ClearAudioStreams(); - void EnumAudioStreams(obs_source_enum_proc_t cb, void *param); - bool AudioMix(uint64_t *ts_out, struct audio_output_data *audio_output, size_t channels, size_t sample_rate); - std::mutex audio_sources_mutex; - std::vector audio_sources; - std::unordered_map audio_streams; -#endif + void SendMouseClick(const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count); void SendMouseMove(const struct obs_mouse_event *event, bool mouse_leave); void SendMouseWheel(const struct obs_mouse_event *event, int x_delta, int y_delta); From 651f3b29ee465e80fb98bcd541967c802c41c631 Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Sat, 23 Aug 2025 00:17:17 -0400 Subject: [PATCH 3/8] Remove support for CEF versions older than 4183 Assume we're always using CEF 5060 or newer. --- obs-browser-plugin.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/obs-browser-plugin.cpp b/obs-browser-plugin.cpp index cf40a2631..b659ce0a3 100644 --- a/obs-browser-plugin.cpp +++ b/obs-browser-plugin.cpp @@ -758,11 +758,6 @@ bool obs_module_load(void) } #endif -#if defined(__APPLE__) && CHROME_VERSION_BUILD < 4183 - // Make sure CEF malloc hijacking happens early in the process - obs_browser_initialize(); -#endif - return true; } From 1de68661c7081e177f217eea0e8e34d8af921666 Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Sat, 23 Aug 2025 00:38:46 -0400 Subject: [PATCH 4/8] Remove support for CEF versions older than 4430 Assume we're always using CEF 5060 or newer. The check regarding ENABLE_WASHIDDEN is left intact on purpose so that it can be removed separately. --- obs-browser-source.cpp | 22 +--------------------- panel/browser-panel.cpp | 13 ------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/obs-browser-source.cpp b/obs-browser-source.cpp index 1ebe84f0d..548e024e4 100644 --- a/obs-browser-source.cpp +++ b/obs-browser-source.cpp @@ -200,13 +200,8 @@ bool BrowserSource::CreateBrowser() new BrowserClient(this, hwaccel && tex_sharing_avail, reroute_audio, webpage_control_level); CefWindowInfo windowInfo; -#if CHROME_VERSION_BUILD < 4430 - windowInfo.width = width; - windowInfo.height = height; -#else windowInfo.bounds.width = width; windowInfo.bounds.height = height; -#endif windowInfo.windowless_rendering_enabled = true; #ifdef ENABLE_BROWSER_SHARED_TEXTURE @@ -236,13 +231,6 @@ bool BrowserSource::CreateBrowser() cefBrowserSettings.default_font_size = 16; cefBrowserSettings.default_fixed_font_size = 16; -#if ENABLE_LOCAL_FILE_URL_SCHEME && CHROME_VERSION_BUILD < 4430 - if (is_local) { - /* Disable web security for file:// URLs to allow - * local content access to remote APIs */ - cefBrowserSettings.web_security = STATE_DISABLED; - } -#endif auto browser = CefBrowserHost::CreateBrowserSync(windowInfo, browserClient, url, cefBrowserSettings, CefRefPtr(), nullptr); @@ -318,15 +306,7 @@ void BrowserSource::SendMouseWheel(const struct obs_mouse_event *event, int x_de void BrowserSource::SendFocus(bool focus) { - ExecuteOnBrowser( - [=](CefRefPtr cefBrowser) { -#if CHROME_VERSION_BUILD < 4430 - cefBrowser->GetHost()->SendFocusEvent(focus); -#else - cefBrowser->GetHost()->SetFocus(focus); -#endif - }, - true); + ExecuteOnBrowser([=](CefRefPtr cefBrowser) { cefBrowser->GetHost()->SetFocus(focus); }, true); } void BrowserSource::SendKeyClick(const struct obs_key_event *event, bool key_up) diff --git a/panel/browser-panel.cpp b/panel/browser-panel.cpp index 51810c813..77bbdafbb 100644 --- a/panel/browser-panel.cpp +++ b/panel/browser-panel.cpp @@ -313,20 +313,7 @@ void QCefWidgetInternal::Init() windowInfo.runtime_style = CEF_RUNTIME_STYLE_ALLOY; #endif -#if CHROME_VERSION_BUILD < 4430 -#ifdef __APPLE__ - windowInfo.SetAsChild((CefWindowHandle)handle, 0, 0, size.width(), size.height()); -#else -#ifdef _WIN32 - RECT rc = {0, 0, size.width(), size.height()}; -#else - CefRect rc = {0, 0, size.width(), size.height()}; -#endif - windowInfo.SetAsChild((CefWindowHandle)handle, rc); -#endif -#else windowInfo.SetAsChild((CefWindowHandle)handle, CefRect(0, 0, size.width(), size.height())); -#endif CefRefPtr browserClient = new QCefBrowserClient(this, script, allowAllPopups_); From 40602ebd4a72acbd221defa092a4221ad9d2b038 Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Sat, 23 Aug 2025 00:41:34 -0400 Subject: [PATCH 5/8] Remove ENABLE_WASHIDDEN ENABLE_WASHIDDEN is defined to 1 for CEF 90+ (4430+), which we always use. Remove it and any code that would not be executed due to this value. --- browser-app.cpp | 86 ------------------------------------------ browser-app.hpp | 7 ---- cef-headers.hpp | 6 --- obs-browser-source.cpp | 10 ----- 4 files changed, 109 deletions(-) diff --git a/browser-app.cpp b/browser-app.cpp index 7a6c893a9..5d2c4dc76 100644 --- a/browser-app.cpp +++ b/browser-app.cpp @@ -122,14 +122,7 @@ void BrowserApp::OnContextCreated(CefRefPtr browser, CefRefPtrSetValue(name, func, V8_PROPERTY_ATTRIBUTE_NONE); } -#if !ENABLE_WASHIDDEN - int id = browser->GetIdentifier(); - if (browserVis.find(id) != browserVis.end()) { - SetDocumentVisibility(browser, browserVis[id]); - } -#else UNUSED_PARAMETER(browser); -#endif } void BrowserApp::ExecuteJSFunction(CefRefPtr browser, const char *functionName, CefV8ValueList arguments) @@ -158,81 +151,6 @@ void BrowserApp::ExecuteJSFunction(CefRefPtr browser, const char *fu } } -#if !ENABLE_WASHIDDEN -void BrowserApp::SetFrameDocumentVisibility(CefRefPtr browser, CefRefPtr frame, bool isVisible) -{ - UNUSED_PARAMETER(browser); - - CefRefPtr context = frame->GetV8Context(); - - context->Enter(); - - CefRefPtr globalObj = context->GetGlobal(); - - CefRefPtr documentObject = globalObj->GetValue("document"); - - if (!!documentObject) { - documentObject->SetValue("hidden", CefV8Value::CreateBool(!isVisible), V8_PROPERTY_ATTRIBUTE_READONLY); - - documentObject->SetValue("visibilityState", CefV8Value::CreateString(isVisible ? "visible" : "hidden"), - V8_PROPERTY_ATTRIBUTE_READONLY); - - std::string script = "new CustomEvent('visibilitychange', {});"; - - CefRefPtr returnValue; - CefRefPtr exception; - - /* Create the CustomEvent object - * We have to use eval to invoke the new operator */ - bool success = context->Eval(script, frame->GetURL(), 0, returnValue, exception); - - if (success) { - CefV8ValueList arguments; - arguments.push_back(returnValue); - - CefRefPtr dispatchEvent = documentObject->GetValue("dispatchEvent"); - - /* Dispatch visibilitychange event on the document - * object */ - dispatchEvent->ExecuteFunction(documentObject, arguments); - } - } - - context->Exit(); -} - -void BrowserApp::SetDocumentVisibility(CefRefPtr browser, bool isVisible) -{ - /* This method might be called before OnContextCreated - * call is made. We'll save the requested visibility - * state here, and use it later in OnContextCreated to - * set initial page visibility state. */ - browserVis[browser->GetIdentifier()] = isVisible; - - std::vector frameIdentifiers; - /* Set visibility state for every frame in the browser - * - * According to the Page Visibility API documentation: - * https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API - * - * "Visibility states of an