From 54007b2b441ce3f4481dc39833b6be6a179afa78 Mon Sep 17 00:00:00 2001 From: Drew Thomas Date: Mon, 13 May 2024 12:56:32 -0700 Subject: [PATCH 1/2] Add simple `MediaSourceAttachment` class Registers `MediaSource` objects to the `MediaSourceRegistry` through a `MediaSourceAttachment` proxy. The new `MediaSourceAttachment` class is cross-thread reference counting safe, unlike `MediaSource`, which will allow for utilizing `MediaSource` objects created on Dedicated Workers. This change does not add any additional functionality, and is intended as an incremental update towards enabling the creation of `MediaSource` objects on Dedicated Worker threads. See [Chromium's `MediaSourceAttachment` interface][1], and the commit that [initially introduced it][2]. [1]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/media/media_source_attachment.h [2]: https://chromium-review.googlesource.com/c/chromium/src/+/2300804 b/338425449 Change-Id: I016c010c9ef4a0e576bd67ce584d75dbe75986ec --- cobalt/browser/web_module.cc | 5 ++- cobalt/dom/BUILD.gn | 1 + cobalt/dom/dom_settings.h | 4 +- cobalt/dom/html_element_context.h | 4 +- cobalt/dom/html_media_element.cc | 7 +++- cobalt/dom/media_source.h | 2 - cobalt/dom/media_source_attachment.h | 56 ++++++++++++++++++++++++++++ cobalt/dom/url_media_source.cc | 7 +++- cobalt/dom/window.cc | 4 +- cobalt/dom/window.h | 4 +- 10 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 cobalt/dom/media_source_attachment.h diff --git a/cobalt/browser/web_module.cc b/cobalt/browser/web_module.cc index 1a1e0d0b0224..7713adf1eae7 100644 --- a/cobalt/browser/web_module.cc +++ b/cobalt/browser/web_module.cc @@ -52,6 +52,7 @@ #include "cobalt/dom/keyboard_event.h" #include "cobalt/dom/keyboard_event_init.h" #include "cobalt/dom/local_storage_database.h" +#include "cobalt/dom/media_source_attachment.h" #include "cobalt/dom/mutation_observer_task_manager.h" #include "cobalt/dom/navigation_type.h" #include "cobalt/dom/navigator.h" @@ -417,7 +418,7 @@ class WebModule::Impl { dom::MutationObserverTaskManager mutation_observer_task_manager_; // Object to register and retrieve MediaSource object with a string key. - std::unique_ptr media_source_registry_; + std::unique_ptr media_source_registry_; // The Window object wraps all DOM-related components. scoped_refptr window_; @@ -584,7 +585,7 @@ WebModule::Impl::Impl(web::Context* web_context, const ConstructionData& data) web_context_->name(), data.options.track_event_stats)); DCHECK(web_module_stat_tracker_); - media_source_registry_.reset(new dom::MediaSource::Registry); + media_source_registry_.reset(new dom::MediaSourceAttachment::Registry); const media::DecoderBufferMemoryInfo* memory_info = nullptr; diff --git a/cobalt/dom/BUILD.gn b/cobalt/dom/BUILD.gn index af60d2dfad66..d121aee9b819 100644 --- a/cobalt/dom/BUILD.gn +++ b/cobalt/dom/BUILD.gn @@ -194,6 +194,7 @@ static_library("dom") { "media_settings.cc", "media_source.cc", "media_source.h", + "media_source_attachment.h", "memory_info.cc", "memory_info.h", "mime_type_array.cc", diff --git a/cobalt/dom/dom_settings.h b/cobalt/dom/dom_settings.h index d2be5880dab5..be5ecacd6f84 100644 --- a/cobalt/dom/dom_settings.h +++ b/cobalt/dom/dom_settings.h @@ -39,14 +39,14 @@ class GlobalEnvironment; class JavaScriptEngine; } // namespace script namespace dom { -class MediaSource; +class MediaSourceAttachment; class Window; // A package of global state to be passed around to script objects // that ask for it in their IDL custom attributes. class DOMSettings : public web::EnvironmentSettings { public: - typedef web::UrlRegistry MediaSourceRegistry; + typedef web::UrlRegistry MediaSourceRegistry; // Hold optional settings for DOMSettings. struct Options { // Microphone options. diff --git a/cobalt/dom/html_element_context.h b/cobalt/dom/html_element_context.h index 72e9de7e808f..ff675b58c613 100644 --- a/cobalt/dom/html_element_context.h +++ b/cobalt/dom/html_element_context.h @@ -42,14 +42,14 @@ namespace cobalt { namespace dom { class HTMLElementFactory; -class MediaSource; +class MediaSourceAttachment; // This class contains references to several objects that are required by HTML // elements, including HTML element factory, which is used to create new // HTML elements. class HTMLElementContext { public: - typedef web::UrlRegistry MediaSourceRegistry; + typedef web::UrlRegistry MediaSourceRegistry; #if !defined(COBALT_BUILD_TYPE_GOLD) // No-args constructor for tests. diff --git a/cobalt/dom/html_media_element.cc b/cobalt/dom/html_media_element.cc index b84d390db999..498fb35d6de3 100644 --- a/cobalt/dom/html_media_element.cc +++ b/cobalt/dom/html_media_element.cc @@ -40,6 +40,7 @@ #include "cobalt/dom/html_video_element.h" #include "cobalt/dom/media_settings.h" #include "cobalt/dom/media_source.h" +#include "cobalt/dom/media_source_attachment.h" #include "cobalt/dom/media_source_ready_state.h" #include "cobalt/loader/fetcher_factory.h" #include "cobalt/media/url_fetcher_data_source.h" @@ -892,8 +893,10 @@ void HTMLMediaElement::LoadResource(const GURL& initial_url, return; } - media_source_ = - html_element_context()->media_source_registry()->Retrieve(url.spec()); + media_source_ = html_element_context() + ->media_source_registry() + ->Retrieve(url.spec()) + ->media_source(); if (!media_source_) { NoneSupported("Media source is NULL."); return; diff --git a/cobalt/dom/media_source.h b/cobalt/dom/media_source.h index a57c936eab6e..b0941a72280d 100644 --- a/cobalt/dom/media_source.h +++ b/cobalt/dom/media_source.h @@ -67,7 +67,6 @@ #include "cobalt/script/environment_settings.h" #include "cobalt/script/exception_state.h" #include "cobalt/web/event_target.h" -#include "cobalt/web/url_registry.h" #include "media/filters/chunk_demuxer.h" namespace cobalt { @@ -79,7 +78,6 @@ namespace dom { class MediaSource : public web::EventTarget { public: typedef ::media::ChunkDemuxer ChunkDemuxer; - typedef web::UrlRegistry Registry; // Custom, not in any spec. // diff --git a/cobalt/dom/media_source_attachment.h b/cobalt/dom/media_source_attachment.h new file mode 100644 index 000000000000..09aa65b5e5fa --- /dev/null +++ b/cobalt/dom/media_source_attachment.h @@ -0,0 +1,56 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// 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 COBALT_DOM_MEDIA_SOURCE_ATTACHMENT_H_ +#define COBALT_DOM_MEDIA_SOURCE_ATTACHMENT_H_ + +#include "base/memory/ref_counted.h" +#include "cobalt/dom/media_source.h" +#include "cobalt/script/tracer.h" +#include "cobalt/web/url_registry.h" + +namespace cobalt { +namespace dom { + +// Interface for potential cross-context management of MediaSource objects. +// Used with the MediaSourceRegistry for attaching MediaSources to media +// elements. +class MediaSourceAttachment + : public base::RefCountedThreadSafe, + public script::Traceable { + public: + typedef web::UrlRegistry Registry; + + explicit MediaSourceAttachment(scoped_refptr media_source) + : media_source_(media_source) {} + + scoped_refptr media_source() const { return media_source_; } + + void TraceMembers(script::Tracer* tracer) override { + tracer->Trace(media_source_); + } + + private: + friend class base::RefCountedThreadSafe; + ~MediaSourceAttachment() = default; + + scoped_refptr media_source_; + + DISALLOW_COPY_AND_ASSIGN(MediaSourceAttachment); +}; + +} // namespace dom +} // namespace cobalt + +#endif // COBALT_DOM_MEDIA_SOURCE_ATTACHMENT_H_ diff --git a/cobalt/dom/url_media_source.cc b/cobalt/dom/url_media_source.cc index 15fbd8a2a217..26df3bddb175 100644 --- a/cobalt/dom/url_media_source.cc +++ b/cobalt/dom/url_media_source.cc @@ -17,6 +17,7 @@ #include "cobalt/base/polymorphic_downcast.h" #include "cobalt/dom/dom_settings.h" #include "cobalt/dom/media_source.h" +#include "cobalt/dom/media_source_attachment.h" #include "cobalt/web/context.h" #include "cobalt/web/environment_settings.h" #include "cobalt/web/url.h" @@ -34,7 +35,11 @@ void RegisterMediaSourceObjectURL( base::polymorphic_downcast(environment_settings); DCHECK(dom_settings); DCHECK(dom_settings->media_source_registry()); - dom_settings->media_source_registry()->Register(blob_url, media_source); + + scoped_refptr attachment = + base::MakeRefCounted(media_source); + + dom_settings->media_source_registry()->Register(blob_url, attachment); } // extern diff --git a/cobalt/dom/window.cc b/cobalt/dom/window.cc index 07bb9a9a63e5..8c25335b8d12 100644 --- a/cobalt/dom/window.cc +++ b/cobalt/dom/window.cc @@ -37,7 +37,7 @@ #include "cobalt/dom/input_event.h" #include "cobalt/dom/keyboard_event.h" #include "cobalt/dom/location.h" -#include "cobalt/dom/media_source.h" +#include "cobalt/dom/media_source_attachment.h" #include "cobalt/dom/mouse_event.h" #include "cobalt/dom/mutation_observer_task_manager.h" #include "cobalt/dom/navigator.h" @@ -102,7 +102,7 @@ Window::Window( script::ExecutionState* execution_state, script::ScriptRunner* script_runner, script::ScriptValueFactory* script_value_factory, - MediaSource::Registry* media_source_registry, + MediaSourceAttachment::Registry* media_source_registry, DomStatTracker* dom_stat_tracker, const std::string& font_language_script, const base::Callback navigation_callback, const loader::Decoder::OnCompleteFunction& load_complete_callback, diff --git a/cobalt/dom/window.h b/cobalt/dom/window.h index 63e76eac64b4..11b3fd5d1ed1 100644 --- a/cobalt/dom/window.h +++ b/cobalt/dom/window.h @@ -93,7 +93,7 @@ class Element; class History; class LocalStorageDatabase; class Location; -class MediaSource; +class MediaSourceAttachment; class Navigator; class OnScreenKeyboard; class Performance; @@ -119,7 +119,7 @@ class Window : public web::WindowOrWorkerGlobalScope, // base::TimeDelta parameter will contain the document's timeline time when // close() was called. typedef base::Callback CloseCallback; - typedef web::UrlRegistry MediaSourceRegistry; + typedef web::UrlRegistry MediaSourceRegistry; typedef base::Callback&)> CacheCallback; From 8abcd8ef5fe8a33f696612c99ff2f28952cfd3a4 Mon Sep 17 00:00:00 2001 From: Drew Thomas Date: Tue, 14 May 2024 12:51:09 -0700 Subject: [PATCH 2/2] Add check for nullptr Change-Id: I6e7d522bf99d77a2d81dbbdb6136cb84d51b1d2b --- cobalt/dom/html_media_element.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cobalt/dom/html_media_element.cc b/cobalt/dom/html_media_element.cc index 498fb35d6de3..cc2c7b0567fb 100644 --- a/cobalt/dom/html_media_element.cc +++ b/cobalt/dom/html_media_element.cc @@ -893,10 +893,16 @@ void HTMLMediaElement::LoadResource(const GURL& initial_url, return; } - media_source_ = html_element_context() - ->media_source_registry() - ->Retrieve(url.spec()) - ->media_source(); + scoped_refptr attachment = + html_element_context()->media_source_registry()->Retrieve(url.spec()); + + if (!attachment) { + NoneSupported("Media source is NULL."); + return; + } + + media_source_ = attachment->media_source(); + if (!media_source_) { NoneSupported("Media source is NULL."); return;