Commit 0b4e5b62 authored by Matt Wolenetz's avatar Matt Wolenetz Committed by Commit Bot

MSE-in-Workers: Remove direct usage of media element from MSE

Replaces remaining direct usage of the attached HTMLMediaElement from
MediaSource and SourceBuffer, relying instead on the attachment to
moderate that communication.

Specifically, this change:

* Adds attachment helpers to enable SourceBuffers to create their audio
  and video tracklist members, including a same-thread attachment
  implementation. Cross-thread attachment implementation of this is
  deferred until TrackListBase and TrackBase can be owned off the main
  thread (in a worker thread), and until they can function without
  themselves directly accessing an HTMLMediaElement.

* Removes superfluous usage in SourceBuffer of `source_->MediaElement()`
  in DCHECKs; other DCHECKs already suffice.

* Removes MediaSource::MediaElement() and `attached_element_`. Removes
  their superfluous implementation and usage from MediaSource.

* Fixes outdated assumptions in various DCHECKs that all attachments use
  a tracer. Only same-thread attachments use a tracer.

BUG=878133

Change-Id: I346b320804a0ffbf731788b7ea7c344588f660b3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2439677
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Reviewed-by: default avatarWill Cassella <cassew@google.com>
Cr-Commit-Position: refs/heads/master@{#814329}
parent d4220da0
......@@ -64,6 +64,22 @@ bool CrossThreadMediaSourceAttachment::GetElementError(
return true;
}
AudioTrackList* CrossThreadMediaSourceAttachment::CreateAudioTrackList(
MediaSourceTracer* /* tracer */) {
// TODO(https://crbug.com/878133): Implement this once worker thread can
// create track lists.
NOTIMPLEMENTED();
return nullptr;
}
VideoTrackList* CrossThreadMediaSourceAttachment::CreateVideoTrackList(
MediaSourceTracer* /* tracer */) {
// TODO(https://crbug.com/878133): Implement this once worker thread can
// create track lists.
NOTIMPLEMENTED();
return nullptr;
}
void CrossThreadMediaSourceAttachment::AddAudioTrackToMediaElement(
MediaSourceTracer* /* tracer */,
AudioTrack* /* track */) {
......
......@@ -39,6 +39,8 @@ class CrossThreadMediaSourceAttachment final
void NotifyDurationChanged(MediaSourceTracer* tracer, double duration) final;
double GetRecentMediaTime(MediaSourceTracer* tracer) final;
bool GetElementError(MediaSourceTracer* tracer) final;
AudioTrackList* CreateAudioTrackList(MediaSourceTracer* tracer) final;
VideoTrackList* CreateVideoTrackList(MediaSourceTracer* tracer) final;
void AddAudioTrackToMediaElement(MediaSourceTracer* tracer,
AudioTrack* track) final;
void AddVideoTrackToMediaElement(MediaSourceTracer* tracer,
......
......@@ -108,7 +108,6 @@ MediaSource::MediaSource(ExecutionContext* context)
async_event_queue_(
MakeGarbageCollected<EventQueue>(context,
TaskType::kMediaElementEvent)),
attached_element_(nullptr),
source_buffers_(
MakeGarbageCollected<SourceBufferList>(GetExecutionContext(),
async_event_queue_.Get())),
......@@ -291,7 +290,6 @@ void MediaSource::OnReadyStateChange(const ReadyState old_state,
source_buffers_->item(i)->RemovedFromMediaSource();
source_buffers_->Clear();
attached_element_.Clear();
media_source_attachment_.reset();
attachment_tracer_ = nullptr;
......@@ -387,7 +385,6 @@ ExecutionContext* MediaSource::GetExecutionContext() const {
void MediaSource::Trace(Visitor* visitor) const {
visitor->Trace(async_event_queue_);
visitor->Trace(attachment_tracer_);
visitor->Trace(attached_element_);
visitor->Trace(source_buffers_);
visitor->Trace(active_source_buffers_);
visitor->Trace(live_seekable_range_);
......@@ -402,9 +399,8 @@ void MediaSource::CompleteAttachingToMediaElement(
TRACE_ID_LOCAL(this));
DCHECK(web_media_source);
DCHECK(!web_media_source_);
DCHECK(attached_element_);
DCHECK(media_source_attachment_);
DCHECK(attachment_tracer_);
DCHECK_EQ(!attachment_tracer_, !IsMainThread());
web_media_source_ = std::move(web_media_source);
SetReadyState(ReadyState::kOpen);
......@@ -472,8 +468,9 @@ TimeRanges* MediaSource::Buffered() const {
}
WebTimeRanges MediaSource::SeekableInternal() const {
DCHECK(attached_element_ && media_source_attachment_ && attachment_tracer_)
DCHECK(media_source_attachment_)
<< "Seekable should only be used when attached to HTMLMediaElement";
DCHECK_EQ(!attachment_tracer_, !IsMainThread());
// Implements MediaSource algorithm for HTMLMediaElement.seekable.
// http://w3c.github.io/media-source/#htmlmediaelement-extensions
......@@ -787,12 +784,6 @@ void MediaSource::SetSourceBufferActive(SourceBuffer* source_buffer,
active_source_buffers_->insert(insert_position, source_buffer);
}
// TODO(https://crbug.com/878133): Remove this getter and instead rely on
// Attachment() to communicate about the media element.
HTMLMediaElement* MediaSource::MediaElement() const {
return attached_element_.Get();
}
std::pair<scoped_refptr<MediaSourceAttachmentSupplement>, MediaSourceTracer*>
MediaSource::AttachmentAndTracer() const {
return std::make_pair(media_source_attachment_, attachment_tracer_);
......@@ -810,11 +801,11 @@ void MediaSource::EndOfStreamAlgorithm(
web_media_source_->MarkEndOfStream(eos_status);
if (eos_status == WebMediaSource::kEndOfStreamStatusNoError) {
// The implementation may not have immediately informed the
// |attached_element_| (or the element known by the |attachment_tracer_|
// for the current |media_source_attachment_|) of the potentially reduced
// duration. Prevent app-visible duration race by synchronously running the
// duration change algorithm. The MSE spec supports this:
// The implementation may not have immediately informed the attached element
// (known by the |media_source_attachment_| and |attachment_tracer_|) of the
// potentially reduced duration. Prevent app-visible duration race by
// synchronously running the duration change algorithm. The MSE spec
// supports this:
// https://www.w3.org/TR/media-source/#end-of-stream-algorithm
// 2.4.7.3 (If error is not set)
// Run the duration change algorithm with new duration set to the largest
......@@ -844,20 +835,15 @@ void MediaSource::Close() {
MediaSourceTracer* MediaSource::StartAttachingToMediaElement(
scoped_refptr<MediaSourceAttachmentSupplement> attachment,
HTMLMediaElement* element) {
if (attached_element_) {
DCHECK(media_source_attachment_);
DCHECK(attachment_tracer_);
if (media_source_attachment_ || attachment_tracer_) {
return nullptr;
}
DCHECK(!media_source_attachment_);
DCHECK(!attachment_tracer_);
DCHECK(IsClosed());
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media",
"MediaSource::StartAttachingToMediaElement",
TRACE_ID_LOCAL(this));
attached_element_ = element;
media_source_attachment_ = attachment;
attachment_tracer_ =
MakeGarbageCollected<SameThreadMediaSourceTracer>(element, this);
......
......@@ -107,7 +107,6 @@ class MediaSource final : public EventTargetWithInlineData,
void OpenIfInEndedState();
bool IsOpen() const;
void SetSourceBufferActive(SourceBuffer*, bool);
HTMLMediaElement* MediaElement() const;
std::pair<scoped_refptr<MediaSourceAttachmentSupplement>, MediaSourceTracer*>
AttachmentAndTracer() const;
void EndOfStreamAlgorithm(const WebMediaSource::EndOfStreamStatus);
......@@ -148,11 +147,8 @@ class MediaSource final : public EventTargetWithInlineData,
// cross-thread, for instance) must be the same semantic as the actual derived
// type of the tracer. Further, if there is no attachment, then there must be
// no tracer that's tracking an active attachment.
// TODO(https://crbug.com/878133): Remove |attached_element_| once it is fully
// replaced by usage of |media_source_attachment_| and |attachment_tracer_|.
scoped_refptr<MediaSourceAttachmentSupplement> media_source_attachment_;
Member<MediaSourceTracer> attachment_tracer_;
Member<HTMLMediaElement> attached_element_;
Member<SourceBufferList> source_buffers_;
Member<SourceBufferList> active_source_buffers_;
......
......@@ -15,7 +15,9 @@
namespace blink {
class AudioTrackList;
class MediaSource;
class VideoTrackList;
// Modules-specific common extension of the core MediaSourceAttachment
// interface. Includes extra interface methods used by concrete attachments to
......@@ -47,6 +49,13 @@ class MediaSourceAttachmentSupplement : public MediaSourceAttachment {
// attachment (in a cross-thread implementation).
virtual bool GetElementError(MediaSourceTracer* tracer) = 0;
// Construct track lists for use by a SourceBuffer.
// TODO(https://crbug.com/878133): Update these to support worker-owned
// SourceBuffer lists when completing AudioVideoTracks feature support with
// MSE-in-Workers.
virtual AudioTrackList* CreateAudioTrackList(MediaSourceTracer* tracer) = 0;
virtual VideoTrackList* CreateVideoTrackList(MediaSourceTracer* tracer) = 0;
// Add/Remove tracks to/from the media Element's audioTracks() or
// videoTracks() list. Note that this is synchronous in
// SameThreadMediaSourceAttachment, but the CrossThreadMediaSourceAttachment
......
......@@ -95,6 +95,26 @@ bool SameThreadMediaSourceAttachment::GetElementError(
return current_element_error_state;
}
AudioTrackList* SameThreadMediaSourceAttachment::CreateAudioTrackList(
MediaSourceTracer* tracer) {
DVLOG(1) << __func__ << " this=" << this;
VerifyCalledWhileContextsAliveForDebugging();
HTMLMediaElement* element = GetMediaElement(tracer);
return MakeGarbageCollected<AudioTrackList>(*element);
}
VideoTrackList* SameThreadMediaSourceAttachment::CreateVideoTrackList(
MediaSourceTracer* tracer) {
DVLOG(1) << __func__ << " this=" << this;
VerifyCalledWhileContextsAliveForDebugging();
HTMLMediaElement* element = GetMediaElement(tracer);
return MakeGarbageCollected<VideoTrackList>(*element);
}
void SameThreadMediaSourceAttachment::AddAudioTrackToMediaElement(
MediaSourceTracer* tracer,
AudioTrack* track) {
......
......@@ -35,6 +35,8 @@ class SameThreadMediaSourceAttachment final
void NotifyDurationChanged(MediaSourceTracer* tracer, double duration) final;
double GetRecentMediaTime(MediaSourceTracer* tracer) final;
bool GetElementError(MediaSourceTracer* tracer) final;
AudioTrackList* CreateAudioTrackList(MediaSourceTracer* tracer) final;
VideoTrackList* CreateVideoTrackList(MediaSourceTracer* tracer) final;
void AddAudioTrackToMediaElement(MediaSourceTracer* tracer,
AudioTrack* track) final;
void AddVideoTrackToMediaElement(MediaSourceTracer* tracer,
......
......@@ -127,14 +127,23 @@ SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer,
DCHECK(web_source_buffer_);
DCHECK(source_);
DCHECK(source_->MediaElement());
scoped_refptr<MediaSourceAttachmentSupplement> attachment;
MediaSourceTracer* tracer;
std::tie(attachment, tracer) = source_->AttachmentAndTracer();
DCHECK(attachment);
if (GetExecutionContext()->IsWindow()) {
DCHECK(IsMainThread());
audio_tracks_ =
MakeGarbageCollected<AudioTrackList>(*source_->MediaElement());
video_tracks_ =
MakeGarbageCollected<VideoTrackList>(*source_->MediaElement());
DCHECK(tracer); // Same-thread attachments must use a tracer.
// Have the attachment construct our audio and video tracklist members for
// us, since it knows how to do this with knowledge of the attached media
// element.
audio_tracks_ = attachment->CreateAudioTrackList(tracer);
DCHECK(audio_tracks_);
video_tracks_ = attachment->CreateVideoTrackList(tracer);
DCHECK(video_tracks_);
} else {
DCHECK(RuntimeEnabledFeatures::MediaSourceInWorkersEnabled() &&
GetExecutionContext()->IsDedicatedWorkerGlobalScope());
......@@ -1001,7 +1010,6 @@ bool SourceBuffer::InitializationSegmentReceived(
const WebVector<MediaTrackInfo>& new_tracks) {
DVLOG(3) << __func__ << " this=" << this << " tracks=" << new_tracks.size();
DCHECK(source_);
DCHECK(source_->MediaElement());
scoped_refptr<MediaSourceAttachmentSupplement> attachment;
MediaSourceTracer* tracer;
......@@ -1435,7 +1443,6 @@ bool SourceBuffer::PrepareAppend(double media_time,
bool SourceBuffer::EvictCodedFrames(double media_time, size_t new_data_size) {
DCHECK(source_);
DCHECK(source_->MediaElement());
// Nothing to do if this SourceBuffer does not yet have frames to evict.
if (!first_initialization_segment_received_)
......
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