Skip to content

Commit

Permalink
MSE-in-Workers: srcObject part 3: serialize handle
Browse files Browse the repository at this point in the history
Adds ability to serialize a MediaSourceHandleImpl, conditionally failing
with DataCloneError if the handle is_serialized() already or if the
handle is_used() (both of those are initialized to be false
in the new instance created during deserialization.)
Later changes will enable apps to attach the handle to a main thread
HTMLMediaElement via the srcObject attribute; they will also include
test updates.

References:
Full prototype CL:
    https://chromium-review.googlesource.com/c/chromium/src/+/3515334
MSE spec issue:
    w3c/media-source#175
MSE spec feature updates switching from worker MSE attachment via
  object URL to attachment via srcObject MediaSourceHandle:
  * w3c/media-source#305
  * further clarifications in discussion at
    w3c/media-source#306 (comment)

BUG=878133

Change-Id: I19cc8a450423964aef78e8e468776e8cd912503a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688599
Reviewed-by: Will Cassella <cassew@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1012132}
NOKEYCHECK=True
GitOrigin-RevId: d5d391975da969d6242e5785c68609d6cd15fda3
  • Loading branch information
wolenetz authored and copybara-github committed Jun 8, 2022
1 parent f31cbc6 commit 2d06ca3
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ enum SerializationTag {

kCropTargetTag = 'c', // crop_id:WebCoreString

kMediaSourceHandleTag = 'S', // uint32_t -> transferred MediaSourceHandle

// The following tags were used by the Shape Detection API implementation
// between M71 and M81. During these milestones, the API was always behind
// a flag. Usage was removed in https://crrev.com/c/2040378.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include "third_party/blink/renderer/modules/file_system_access/file_system_directory_handle.h"
#include "third_party/blink/renderer/modules/file_system_access/file_system_file_handle.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_attachment_supplement.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_handle_attachment.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h"
#include "third_party/blink/renderer/modules/mediastream/crop_target.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
Expand Down Expand Up @@ -97,6 +100,8 @@ ScriptWrappable* V8ScriptValueDeserializerForModules::ReadDOMObject(
return ReadMediaStreamTrack();
case kCropTargetTag:
return ReadCropTarget();
case kMediaSourceHandleTag:
return ReadMediaSourceHandle();
default:
break;
}
Expand Down Expand Up @@ -576,4 +581,33 @@ CropTarget* V8ScriptValueDeserializerForModules::ReadCropTarget() {
return MakeGarbageCollected<CropTarget>(crop_id);
}

MediaSourceHandleImpl*
V8ScriptValueDeserializerForModules::ReadMediaSourceHandle() {
if (!RuntimeEnabledFeatures::MediaSourceInWorkersEnabled(
ExecutionContext::From(GetScriptState())) ||
!RuntimeEnabledFeatures::MediaSourceInWorkersUsingHandleEnabled(
ExecutionContext::From(GetScriptState()))) {
return nullptr;
}

uint32_t index;
if (!ReadUint32(&index))
return nullptr;

const auto* attachment =
GetSerializedScriptValue()
->GetAttachmentIfExists<MediaSourceHandleAttachment>();
if (!attachment)
return nullptr;

const auto& attachments = attachment->Attachments();
if (index >= attachment->size())
return nullptr;

auto& handle_internals = attachments[index];
return MakeGarbageCollected<MediaSourceHandleImpl>(
std::move(handle_internals.attachment),
std::move(handle_internals.internal_blob_url));
}

} // namespace blink
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CryptoKey;
class EncodedAudioChunk;
class EncodedVideoChunk;
class FileSystemHandle;
class MediaSourceHandleImpl;
class RTCEncodedAudioFrame;
class RTCEncodedVideoFrame;
class VideoFrame;
Expand Down Expand Up @@ -59,6 +60,7 @@ class MODULES_EXPORT V8ScriptValueDeserializerForModules final
EncodedVideoChunk* ReadEncodedVideoChunk();
MediaStreamTrack* ReadMediaStreamTrack();
CropTarget* ReadCropTarget();
MediaSourceHandleImpl* ReadMediaSourceHandle();
};

} // namespace blink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_directory_handle.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_file_handle.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_landmark.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_source_handle.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
Expand All @@ -32,6 +33,9 @@
#include "third_party/blink/renderer/modules/crypto/crypto_key.h"
#include "third_party/blink/renderer/modules/file_system_access/file_system_handle.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_attachment_supplement.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_handle_attachment.h"
#include "third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h"
#include "third_party/blink/renderer/modules/mediastream/crop_target.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
Expand Down Expand Up @@ -252,6 +256,23 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject(

return WriteCropTarget(wrappable->ToImpl<CropTarget>());
}

if (wrapper_type_info == V8MediaSourceHandle::GetWrapperTypeInfo() &&
RuntimeEnabledFeatures::MediaSourceInWorkersEnabled(
ExecutionContext::From(GetScriptState())) &&
RuntimeEnabledFeatures::MediaSourceInWorkersUsingHandleEnabled(
ExecutionContext::From(GetScriptState()))) {
if (IsForStorage()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kDataCloneError,
"A MediaSourceHandle cannot be serialized for storage.");
return false;
}

return WriteMediaSourceHandle(wrappable->ToImpl<MediaSourceHandleImpl>(),
exception_state);
}

return false;
}

Expand Down Expand Up @@ -547,4 +568,42 @@ bool V8ScriptValueSerializerForModules::WriteCropTarget(
return true;
}

bool V8ScriptValueSerializerForModules::WriteMediaSourceHandle(
MediaSourceHandleImpl* handle,
ExceptionState& exception_state) {
if (handle->is_serialized()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kDataCloneError,
"MediaSourceHandle is already serialized.");
return false;
}

if (handle->is_used()) {
exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
"MediaSourceHandle has been used as "
"srcObject of media element already.");
return false;
}

// The collection of handle-attachment involved in serialization.
auto* attachment = GetSerializedScriptValue()
->GetOrCreateAttachment<MediaSourceHandleAttachment>();

// The collection of underlying scoped_refptr<MediaSourceAttachment>
// involved in serialization. Each is the internal state of a
// MediaSourceHandleImpl. Add the internal state of |handle| to it and
// serialize it using the index of that state in the vector.
auto& attachments = attachment->Attachments();
attachments.push_back(MediaSourceHandleAttachment::HandleInternals{
.attachment = handle->GetAttachment(),
.internal_blob_url = handle->GetInternalBlobURL()});
handle->mark_serialized();
const uint32_t index = static_cast<uint32_t>(attachments.size() - 1);

WriteTag(kMediaSourceHandleTag);
WriteUint32(index);

return true;
}

} // namespace blink
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace blink {

class CropTarget;
class FileSystemHandle;
class MediaSourceHandleImpl;
class RTCEncodedAudioFrame;
class RTCEncodedVideoFrame;
class VideoFrameHandle;
Expand Down Expand Up @@ -57,6 +58,8 @@ class MODULES_EXPORT V8ScriptValueSerializerForModules final
bool WriteMediaStreamTrack(MediaStreamTrack* track,
ExceptionState& exception_state);
bool WriteCropTarget(CropTarget*);
bool WriteMediaSourceHandle(MediaSourceHandleImpl* handle,
ExceptionState& exception_state);
};

} // namespace blink
Expand Down
2 changes: 2 additions & 0 deletions blink/renderer/modules/mediasource/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ blink_modules_sources("mediasource") {
"media_source.h",
"media_source_attachment_supplement.cc",
"media_source_attachment_supplement.h",
"media_source_handle_attachment.cc",
"media_source_handle_attachment.h",
"media_source_handle_impl.cc",
"media_source_handle_impl.h",
"media_source_registry_impl.cc",
Expand Down
1 change: 1 addition & 0 deletions blink/renderer/modules/mediasource/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ include_rules = [
"+third_party/blink/renderer/modules/event_modules.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
"+third_party/blink/renderer/modules/mediasource",
"+third_party/blink/renderer/modules/modules_export.h",
"+third_party/blink/renderer/modules/webcodecs",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2022 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/modules/mediasource/media_source_handle_attachment.h"

namespace blink {

const void* const MediaSourceHandleAttachment::kAttachmentKey = nullptr;

} // namespace blink
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2022 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_HANDLE_ATTACHMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_HANDLE_ATTACHMENT_H_

#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
#include "third_party/blink/renderer/modules/modules_export.h"

namespace blink {

// Used to serialize MediaSourceHandle
class MODULES_EXPORT MediaSourceHandleAttachment
: public SerializedScriptValue::Attachment {
public:
// Internals of a MediaSourceHandle that are included in serialization.
struct HandleInternals {
scoped_refptr<MediaSourceAttachment> attachment;
String internal_blob_url;
};

using MediaSourceHandleVector = Vector<HandleInternals>;

static const void* const kAttachmentKey;
MediaSourceHandleAttachment() = default;
~MediaSourceHandleAttachment() override = default;

bool IsLockedToAgentCluster() const override {
return !attachments_.IsEmpty();
}

size_t size() const { return attachments_.size(); }

MediaSourceHandleVector& Attachments() { return attachments_; }

const MediaSourceHandleVector& Attachments() const { return attachments_; }

private:
MediaSourceHandleVector attachments_;
};

} // namespace blink

#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_HANDLE_ATTACHMENT_H_
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ String MediaSourceHandleImpl::GetInternalBlobURL() {
return internal_blob_url_;
}

void MediaSourceHandleImpl::mark_serialized() {
DCHECK(!serialized_);
serialized_ = true;
}

void MediaSourceHandleImpl::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
}
Expand Down
2 changes: 2 additions & 0 deletions blink/renderer/modules/mediasource/media_source_handle_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class MediaSourceHandleImpl final : public ScriptWrappable,
scoped_refptr<MediaSourceAttachment> GetAttachment() override;
String GetInternalBlobURL() override;

void mark_serialized();

void Trace(Visitor*) const override;

private:
Expand Down

0 comments on commit 2d06ca3

Please sign in to comment.