Commit 91b6c8f7 authored by Matt Wolenetz's avatar Matt Wolenetz Committed by Commit Bot

MSE-in-Workers: Introduce basic MediaSourceAttachment interface

To prepare for cross-thread HTMLMediaElement+MediaSource API
attachments, aka "MSE-in-Workers", this CL decouples the MediaSource
object from what is directly registered. A new type,
MediaSourceAttachment, is used to register available MediaSource
objects, and a simple concrete implementation is included in this type
to resolve the underlying MediaSource for use in actual attachment.

This CL is needed as a prerequisite for cross-thread attachments
because subsequent CLs are significantly complex. They will:
1) Move MediaSourceRegistry singleton creation to modules initializer to
ensure it is owned on the main thread, even if a worker thread was the
first to need it (see bullet 3, below).
2) Update MediaSourceAttachment to be an interface and move the
communication between HTMLMediaElement and the MediaSource to be done
via the interface with concrete implementation(s) in modules.
3) Add a cross-thread attachment implementation.  This part will be
complex, and will be better handled if the existing same-thread behavior
and the new cross-thread behavior are distinct implementations of a
common attachment interface. Further, having a non-oilpan type (the
concrete implementations of MediaSourceAttachment) as the registrable
enables the implementations to safely operate when lifetimes of either
side of the attachment vary. And such a non-oilpan type must be used as
the registrable if the registry singleton's internal initialization is
done prior to Oilpan being ready (during the modules initializer).
4) Refine the interface and concrete implementations for performance and
quality specific to the types of attachment being used.

BUG=878133

Change-Id: I8376f6483142d3653e5d39d76f5a245c80365b18
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2300804Reviewed-by: default avatarKeishi Hattori <keishi@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796549}
parent 4f813c6d
......@@ -496,8 +496,10 @@ blink_core_sources("html") {
"media/media_fragment_uri_parser.h",
"media/media_remoting_interstitial.cc",
"media/media_remoting_interstitial.h",
"media/media_source.cc",
"media/media_source.h",
"media/media_source_attachment.cc",
"media/media_source_attachment.h",
"media/media_source_registry.h",
"media/picture_in_picture_interstitial.cc",
"media/picture_in_picture_interstitial.h",
"media/remote_playback_controller.cc",
......
......@@ -75,6 +75,7 @@
#include "third_party/blink/renderer/core/html/media/media_error.h"
#include "third_party/blink/renderer/core/html/media/media_fragment_uri_parser.h"
#include "third_party/blink/renderer/core/html/media/media_source.h"
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/core/html/track/audio_track.h"
#include "third_party/blink/renderer/core/html/track/audio_track_list.h"
......@@ -1193,7 +1194,7 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
bool attempt_load = true;
media_source_ = MediaSource::Lookup(url.GetString());
media_source_ = MediaSourceAttachment::LookupMediaSource(url.GetString());
if (media_source_) {
if (media_source_->StartAttachingToMediaElement(this)) {
// If the associated feature is enabled, auto-revoke the MediaSource
......
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/core/html/media/media_source.h"
namespace blink {
URLRegistry* MediaSource::registry_ = nullptr;
void MediaSource::SetRegistry(URLRegistry* registry) {
DCHECK(!registry_);
registry_ = registry;
}
} // namespace blink
......@@ -34,7 +34,6 @@
#include <memory>
#include "third_party/blink/public/platform/web_time_range.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
......@@ -45,15 +44,19 @@ class HTMLMediaElement;
class TimeRanges;
class TrackBase;
class CORE_EXPORT MediaSource : public URLRegistrable,
public GarbageCollectedMixin {
// Interface for the Media Source Extensions (MSE) API's MediaSource object
// implementation (see also https://w3.org/TR/media-source/). Web apps can
// extend an HTMLMediaElement's instance to use the MSE API (also known as
// "attaching MSE to a media element") by using a Media Source object URL as the
// media element's src attribute or the src attribute of a <source> inside the
// media element.
// TODO(https://crbug.com/878133): Migrate the HTMLME<->MS API communication to
// be moderated by MediaSourceAttachment. Lifetime management of attached
// HTMLMediaElement+MSE object groups using Oilpan may also be moved to be
// moderated by MediaSourceAttachment, hopefully mitigating the need for this
// interface in core eventually.
class CORE_EXPORT MediaSource : public GarbageCollectedMixin {
public:
static void SetRegistry(URLRegistry*);
static MediaSource* Lookup(const String& url) {
return registry_ ? static_cast<MediaSource*>(registry_->Lookup(url))
: nullptr;
}
// These two methods are called in sequence when an HTMLMediaElement is
// attempting to attach to this object. The WebMediaSource is not available
// to the element initially, so between the two calls, the attachment could be
......@@ -85,12 +88,6 @@ class CORE_EXPORT MediaSource : public URLRegistrable,
virtual WebTimeRanges SeekableInternal() const = 0;
virtual TimeRanges* Buffered() const = 0;
virtual void OnTrackChanged(TrackBase*) = 0;
// URLRegistrable
URLRegistry& Registry() const override { return *registry_; }
private:
static URLRegistry* registry_;
};
} // namespace blink
......
// Copyright 2020 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.
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
#include "third_party/blink/renderer/core/html/media/media_source.h"
#include "third_party/blink/renderer/core/html/media/media_source_registry.h"
namespace blink {
// static
URLRegistry* MediaSourceAttachment::registry_ = nullptr;
// static
void MediaSourceAttachment::SetRegistry(MediaSourceRegistry* registry) {
DCHECK(IsMainThread());
DCHECK(!registry_);
registry_ = registry;
}
// static
MediaSource* MediaSourceAttachment::LookupMediaSource(const String& url) {
// The only expected caller is an HTMLMediaElement on the main thread.
DCHECK(IsMainThread());
if (!registry_)
return nullptr;
// This cast is safe because the only setter of |registry_| is SetRegistry().
MediaSourceRegistry* ms_registry =
static_cast<MediaSourceRegistry*>(registry_);
scoped_refptr<MediaSourceAttachment> attachment =
ms_registry->LookupMediaSource(url);
return attachment ? attachment->registered_media_source_.Get() : nullptr;
}
MediaSourceAttachment::MediaSourceAttachment(MediaSource* media_source)
: registered_media_source_(media_source) {
// For this initial implementation, construction must be on the main thread,
// since no MSE-in-Workers implementation is yet included.
DCHECK(IsMainThread());
DVLOG(1) << __func__ << " media_source=" << media_source;
// Verify that at construction time, refcounting of this object begins at
// precisely 1.
DCHECK(HasOneRef());
}
void MediaSourceAttachment::Unregister() {
DVLOG(1) << __func__ << " this=" << this;
// The only expected caller is a MediaSourceRegistryImpl on the main thread.
DCHECK(IsMainThread());
// Release our strong reference to the MediaSource. Note that
// revokeObjectURL of the url associated with this attachment could commonly
// follow this path while the MediaSource (and any attachment to an
// HTMLMediaElement) may still be alive/active.
DCHECK(registered_media_source_);
registered_media_source_ = nullptr;
}
MediaSourceAttachment::~MediaSourceAttachment() = default;
} // namespace blink
// Copyright 2020 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_ATTACHMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_ATTACHMENT_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace blink {
class MediaSource;
class MediaSourceRegistry;
// Interface for concrete non-oilpan types to coordinate potentially
// cross-context registration, deregistration, and lookup of a MediaSource via
// the MediaSourceRegistry. Upon successful lookup, enables the extension of an
// HTMLMediaElement by the MSE API, aka attachment. This type is not managed by
// oilpan due to the potentially varying context lifetimes. Concrete
// implementations of this handle same-thread (main thread) attachments
// distinctly from cross-context (MSE-in-Worker, HTMLMediaElement in main
// thread) attachments due to the increased complexity for handling the latter.
// Concrete implementations of this interface are reference counted to ensure
// they are available potentially cross-thread and from the registry.
//
// TODO(https://crbug.com/878133): This is not yet implementing the multi-thread
// aspect.
class CORE_EXPORT MediaSourceAttachment
: public URLRegistrable,
public WTF::ThreadSafeRefCounted<MediaSourceAttachment> {
public:
// Intended to be set by the MediaSourceRegistry during its singleton
// initialization on the main thread. Caches the pointer in |registry_|.
static void SetRegistry(MediaSourceRegistry*);
// Services lookup calls, expected from HTMLMediaElement during its load
// algorithm. If |url| is not known by MediaSourceRegistry, returns nullptr.
// Otherwise, returns the MediaSource associated with |url|.
// TODO(https://crbug.com/878133): Change this to return the refcounted
// attachment itself, so that further operation by HTMLMediaElement on the
// MediaSource is moderated by the attachment instance.
static MediaSource* LookupMediaSource(const String& url);
// The only intended caller of this constructor is
// URLMediaSource::createObjectUrl. The raw pointer is then adopted into a
// scoped_refptr in MediaSourceRegistryImpl::RegisterURL.
explicit MediaSourceAttachment(MediaSource* media_source);
// This is called on the main thread when the URLRegistry unregisters the
// objectURL for this attachment. It releases the strong reference to the
// MediaSource such that GC might collect it if there is no active attachment
// represented by other strong references.
void Unregister();
// URLRegistrable
URLRegistry& Registry() const override { return *registry_; }
private:
friend class WTF::ThreadSafeRefCounted<MediaSourceAttachment>;
~MediaSourceAttachment() override;
static URLRegistry* registry_;
// Cache of the registered MediaSource for this initial same-thread-only
// migration of the registrable from MediaSource to MediaSourceAttachment.
// TODO(https://crbug.com/878133): Refactor this to be mostly internal to the
// concrete implementations of this attachment type in modules.
Persistent<MediaSource> registered_media_source_;
DISALLOW_COPY_AND_ASSIGN(MediaSourceAttachment);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_ATTACHMENT_H_
// Copyright 2020 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_REGISTRY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_REGISTRY_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
namespace blink {
// Core interface extension of URLRegistry to allow interactions with a
// URLRegistry for registered MediaSourceAttachments handled with a
// scoped_refptr.
class CORE_EXPORT MediaSourceRegistry : public URLRegistry {
public:
virtual scoped_refptr<MediaSourceAttachment> LookupMediaSource(
const String& url) = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_REGISTRY_H_
......@@ -10,8 +10,8 @@ blink_modules_sources("mediasource") {
"html_video_element_media_source.h",
"media_source_impl.cc",
"media_source_impl.h",
"media_source_registry.cc",
"media_source_registry.h",
"media_source_registry_impl.cc",
"media_source_registry_impl.h",
"source_buffer.cc",
"source_buffer.h",
"source_buffer_list.cc",
......
......@@ -43,7 +43,6 @@
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/track/audio_track_list.h"
#include "third_party/blink/renderer/core/html/track/video_track_list.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_registry.h"
#include "third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
......@@ -137,8 +136,7 @@ MediaSourceImpl::MediaSourceImpl(ExecutionContext* context)
active_source_buffers_(
MakeGarbageCollected<SourceBufferList>(GetExecutionContext(),
async_event_queue_.Get())),
live_seekable_range_(MakeGarbageCollected<TimeRanges>()),
added_to_registry_counter_(0) {
live_seekable_range_(MakeGarbageCollected<TimeRanges>()) {
DVLOG(1) << __func__ << " this=" << this;
DCHECK(RuntimeEnabledFeatures::MediaSourceInWorkersEnabled() ||
......@@ -413,17 +411,6 @@ void MediaSourceImpl::CompleteAttachingToMediaElement(
SetReadyState(OpenKeyword());
}
void MediaSourceImpl::AddedToRegistry() {
++added_to_registry_counter_;
// Ensure there's no counter overflow.
CHECK_GT(added_to_registry_counter_, 0);
}
void MediaSourceImpl::RemovedFromRegistry() {
DCHECK_GT(added_to_registry_counter_, 0);
--added_to_registry_counter_;
}
double MediaSourceImpl::duration() const {
return IsClosed() ? std::numeric_limits<float>::quiet_NaN()
: web_media_source_->Duration();
......@@ -874,8 +861,7 @@ bool MediaSourceImpl::HasPendingActivity() const {
// further motivation for apps to properly revokeObjectUrl and for the MSE
// spec, implementations and API users to transition to using HTMLME srcObject
// for MSE attachment instead of objectUrl.
return async_event_queue_->HasPendingEvents() ||
added_to_registry_counter_ > 0;
return async_event_queue_->HasPendingEvents();
}
void MediaSourceImpl::ContextDestroyed() {
......@@ -932,8 +918,4 @@ void MediaSourceImpl::ScheduleEvent(const AtomicString& event_name) {
async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
URLRegistry& MediaSourceImpl::Registry() const {
return MediaSourceRegistry::Registry();
}
} // namespace blink
......@@ -36,7 +36,6 @@
#include "third_party/blink/public/platform/web_media_source.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/core/html/media/media_source.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
......@@ -114,9 +113,6 @@ class MediaSourceImpl final : public EventTargetWithInlineData,
// ExecutionContextLifecycleObserver interface
void ContextDestroyed() override;
// URLRegistrable interface
URLRegistry& Registry() const override;
// Used by SourceBuffer.
void OpenIfInEndedState();
bool IsOpen() const;
......@@ -124,10 +120,6 @@ class MediaSourceImpl final : public EventTargetWithInlineData,
HTMLMediaElement* MediaElement() const;
void EndOfStreamAlgorithm(const WebMediaSource::EndOfStreamStatus);
// Used by MediaSourceRegistry.
void AddedToRegistry();
void RemovedFromRegistry();
void Trace(Visitor*) const override;
private:
......@@ -161,8 +153,6 @@ class MediaSourceImpl final : public EventTargetWithInlineData,
Member<SourceBufferList> active_source_buffers_;
Member<TimeRanges> live_seekable_range_;
int added_to_registry_counter_;
};
} // namespace blink
......
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_REGISTRY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_REGISTRY_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
namespace blink {
class KURL;
class MediaSourceImpl;
class MediaSourceRegistry final : public URLRegistry {
public:
// Returns a single instance of MediaSourceRegistry.
static MediaSourceRegistry& Registry();
// Registers a blob URL referring to the specified media source.
void RegisterURL(SecurityOrigin*, const KURL&, URLRegistrable*) override;
void UnregisterURL(const KURL&) override;
URLRegistrable* Lookup(const String&) override;
private:
MediaSourceRegistry();
Persistent<HeapHashMap<String, Member<MediaSourceImpl>>> media_sources_;
};
} // namespace blink
#endif
......@@ -28,51 +28,56 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/modules/mediasource/media_source_registry.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
MediaSourceRegistry& MediaSourceRegistry::Registry() {
// static
MediaSourceRegistryImpl& MediaSourceRegistryImpl::EnsureRegistry() {
DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(MediaSourceRegistry, instance, ());
DEFINE_STATIC_LOCAL(MediaSourceRegistryImpl, instance, ());
return instance;
}
void MediaSourceRegistry::RegisterURL(SecurityOrigin*,
const KURL& url,
URLRegistrable* registrable) {
DCHECK_EQ(&registrable->Registry(), this);
void MediaSourceRegistryImpl::RegisterURL(SecurityOrigin*,
const KURL& url,
URLRegistrable* registrable) {
DCHECK(IsMainThread());
DCHECK_EQ(&registrable->Registry(), this);
DVLOG(1) << __func__ << " url=" << url;
MediaSourceImpl* source = static_cast<MediaSourceImpl*>(registrable);
source->AddedToRegistry();
media_sources_->Set(url.GetString(), source);
scoped_refptr<MediaSourceAttachment> attachment =
base::AdoptRef(static_cast<MediaSourceAttachment*>(registrable));
media_sources_.Set(url.GetString(), std::move(attachment));
}
void MediaSourceRegistry::UnregisterURL(const KURL& url) {
void MediaSourceRegistryImpl::UnregisterURL(const KURL& url) {
DVLOG(1) << __func__ << " url=" << url;
DCHECK(IsMainThread());
HeapHashMap<String, Member<MediaSourceImpl>>::iterator iter =
media_sources_->find(url.GetString());
if (iter == media_sources_->end())
auto iter = media_sources_.find(url.GetString());
if (iter == media_sources_.end())
return;
MediaSourceImpl* source = iter->value;
media_sources_->erase(iter);
source->RemovedFromRegistry();
scoped_refptr<MediaSourceAttachment> attachment = iter->value;
attachment->Unregister();
media_sources_.erase(iter);
}
URLRegistrable* MediaSourceRegistry::Lookup(const String& url) {
scoped_refptr<MediaSourceAttachment> MediaSourceRegistryImpl::LookupMediaSource(
const String& url) {
DCHECK(IsMainThread());
return url.IsNull() ? nullptr : media_sources_->at(url);
return url.IsNull() ? scoped_refptr<MediaSourceAttachment>()
: media_sources_.at(url);
}
MediaSourceRegistry::MediaSourceRegistry()
: media_sources_(MakeGarbageCollected<
HeapHashMap<String, Member<MediaSourceImpl>>>()) {
MediaSource::SetRegistry(this);
MediaSourceRegistryImpl::MediaSourceRegistryImpl() {
DCHECK(IsMainThread());
MediaSourceAttachment::SetRegistry(this);
}
} // namespace blink
// Copyright 2020 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_REGISTRY_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_REGISTRY_IMPL_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
#include "third_party/blink/renderer/core/html/media/media_source_registry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
namespace blink {
class KURL;
// This singleton lives on the main thread. It allows registration and
// deregistration of MediaSource objectUrls.
// TODO(https://crbug.com/878133): Refactor this to allow registration and
// lookup of cross-thread (worker) MediaSource objectUrls.
class MediaSourceRegistryImpl final : public MediaSourceRegistry {
public:
// Returns the singleton instance of MediaSourceRegistry, constructing it if
// necessary.
static MediaSourceRegistryImpl& EnsureRegistry();
// MediaSourceRegistry : URLRegistry overrides for (un)registering blob URLs
// referring to the specified media source attachment. RegisterURL creates a
// scoped_refptr to manage the registrable's ref-counted lifetime and puts it
// in |media_sources_|.
void RegisterURL(SecurityOrigin*, const KURL&, URLRegistrable*) override;
// UnregisterURL removes the corresponding scoped_refptr and KURL from
// |media_sources_| if its KURL was there.
void UnregisterURL(const KURL&) override;
// MediaSourceRegistry override that finds |url| in |media_sources_| and
// returns the corresponding scoped_refptr if found. Otherwise, returns an
// unset scoped_refptr.
scoped_refptr<MediaSourceAttachment> LookupMediaSource(
const String& url) override;
private:
MediaSourceRegistryImpl();
HashMap<String, scoped_refptr<MediaSourceAttachment>> media_sources_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_REGISTRY_IMPL_H_
......@@ -32,8 +32,10 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
#include "third_party/blink/renderer/core/url/dom_url.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
......@@ -43,15 +45,41 @@ namespace blink {
String URLMediaSource::createObjectURL(ScriptState* script_state,
MediaSourceImpl* source) {
// Since WebWorkers cannot obtain MediaSource objects (yet), we should be on
// the main thread. TODO(wolenetz): Let DedicatedWorkers create MediaSource
// object URLs. See https://crbug.com/878133.
// the main thread.
// TODO(https://crbug.com/878133): Let DedicatedWorkers create MediaSource
// object URLs.
DCHECK(IsMainThread());
ExecutionContext* execution_context = ExecutionContext::From(script_state);
DCHECK(execution_context);
DCHECK(source);
UseCounter::Count(execution_context, WebFeature::kCreateObjectURLMediaSource);
return DOMURL::CreatePublicURL(execution_context, source);
// This creation of a ThreadSafeRefCounted object should have a refcount of 1
// immediately. It will be adopted into a scoped_refptr in
// MediaSourceRegistryImpl::RegisterURL. See also MediaSourceAttachment (and
// usage in HTMLMediaElement, MediaSourceRegistry{Impl}, and
// MediaSource{Impl}) for further detail.
MediaSourceAttachment* attachment = new MediaSourceAttachment(source);
DCHECK(attachment->HasOneRef());
// Ensure the MediaSourceRegistryImpl singleton is constructed, such that the
// URLRegistrable implementation of ::Registry() in MediaSourceAttachment is
// available prior to MediaSourceAttachment's public URL creation, which uses
// it.
// TODO(https://crbug.com/878133): Remove this priming of the registry in
// favor of initialization of the registry singleton from the modules
// initializer.
MediaSourceRegistryImpl::EnsureRegistry(); // Ignore the return value.
String url = DOMURL::CreatePublicURL(execution_context, attachment);
// If attachment's registration failed, release its start-at-one reference to
// let it be destructed.
if (url.IsEmpty())
attachment->Release();
return url;
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment