summaryrefslogtreecommitdiffstats
path: root/dom/base/StructuredCloneHolder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/StructuredCloneHolder.cpp')
-rw-r--r--dom/base/StructuredCloneHolder.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/dom/base/StructuredCloneHolder.cpp b/dom/base/StructuredCloneHolder.cpp
index bf3945b1d7..f3e2bea46b 100644
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -34,6 +34,8 @@
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/DocGroup.h"
+#include "mozilla/dom/EncodedAudioChunk.h"
+#include "mozilla/dom/EncodedAudioChunkBinding.h"
#include "mozilla/dom/EncodedVideoChunk.h"
#include "mozilla/dom/EncodedVideoChunkBinding.h"
#include "mozilla/dom/File.h"
@@ -58,6 +60,7 @@
#include "mozilla/dom/TransformStream.h"
#include "mozilla/dom/TransformStreamBinding.h"
#include "mozilla/dom/VideoFrame.h"
+#include "mozilla/dom/AudioData.h"
#include "mozilla/dom/VideoFrameBinding.h"
#include "mozilla/dom/WebIDLSerializable.h"
#include "mozilla/dom/WritableStream.h"
@@ -399,6 +402,7 @@ void StructuredCloneHolder::Read(nsIGlobalObject* aGlobal, JSContext* aCx,
mClonedSurfaces.Clear();
mInputStreamArray.Clear();
mVideoFrames.Clear();
+ mEncodedAudioChunks.Clear();
mEncodedVideoChunks.Clear();
Clear();
}
@@ -1127,6 +1131,28 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
}
}
+ if (StaticPrefs::dom_media_webcodecs_enabled() &&
+ aTag == SCTAG_DOM_AUDIODATA &&
+ CloneScope() == StructuredCloneScope::SameProcess &&
+ aCloneDataPolicy.areIntraClusterClonableSharedObjectsAllowed()) {
+ JS::Rooted<JSObject*> global(aCx, mGlobal->GetGlobalJSObject());
+ if (AudioData_Binding::ConstructorEnabled(aCx, global)) {
+ return AudioData::ReadStructuredClone(aCx, mGlobal, aReader,
+ AudioData()[aIndex]);
+ }
+ }
+
+ if (StaticPrefs::dom_media_webcodecs_enabled() &&
+ aTag == SCTAG_DOM_ENCODEDAUDIOCHUNK &&
+ CloneScope() == StructuredCloneScope::SameProcess &&
+ aCloneDataPolicy.areIntraClusterClonableSharedObjectsAllowed()) {
+ JS::Rooted<JSObject*> global(aCx, mGlobal->GetGlobalJSObject());
+ if (EncodedAudioChunk_Binding::ConstructorEnabled(aCx, global)) {
+ return EncodedAudioChunk::ReadStructuredClone(
+ aCx, mGlobal, aReader, EncodedAudioChunks()[aIndex]);
+ }
+ }
+
return ReadFullySerializableObjects(aCx, aReader, aTag, false);
}
@@ -1246,6 +1272,29 @@ bool StructuredCloneHolder::CustomWriteHandler(
}
}
+ // See if this is an AudioData object.
+ if (StaticPrefs::dom_media_webcodecs_enabled()) {
+ mozilla::dom::AudioData* audioData = nullptr;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(AudioData, &obj, audioData))) {
+ SameProcessScopeRequired(aSameProcessScopeRequired);
+ return CloneScope() == StructuredCloneScope::SameProcess
+ ? audioData->WriteStructuredClone(aWriter, this)
+ : false;
+ }
+ }
+
+ // See if this is a EncodedAudioChunk object.
+ if (StaticPrefs::dom_media_webcodecs_enabled()) {
+ EncodedAudioChunk* encodedAudioChunk = nullptr;
+ if (NS_SUCCEEDED(
+ UNWRAP_OBJECT(EncodedAudioChunk, &obj, encodedAudioChunk))) {
+ SameProcessScopeRequired(aSameProcessScopeRequired);
+ return CloneScope() == StructuredCloneScope::SameProcess
+ ? encodedAudioChunk->WriteStructuredClone(aWriter, this)
+ : false;
+ }
+ }
+
{
// We only care about streams, so ReflectorToISupportsStatic is fine.
nsCOMPtr<nsISupports> base = xpc::ReflectorToISupportsStatic(aObj);
@@ -1429,6 +1478,39 @@ StructuredCloneHolder::CustomReadTransferHandler(
return true;
}
+ if (StaticPrefs::dom_media_webcodecs_enabled() &&
+ aTag == SCTAG_DOM_AUDIODATA &&
+ CloneScope() == StructuredCloneScope::SameProcess &&
+ aCloneDataPolicy.areIntraClusterClonableSharedObjectsAllowed()) {
+ MOZ_ASSERT(aContent);
+
+ JS::Rooted<JSObject*> globalObj(aCx, mGlobal->GetGlobalJSObject());
+ // aContent will be released in CustomFreeTransferHandler.
+ if (!AudioData_Binding::ConstructorEnabled(aCx, globalObj)) {
+ return false;
+ }
+
+ AudioData::TransferredData* data =
+ static_cast<AudioData::TransferredData*>(aContent);
+ nsCOMPtr<nsIGlobalObject> global = mGlobal;
+ RefPtr<mozilla::dom::AudioData> audioData =
+ AudioData::FromTransferred(global.get(), data);
+ // aContent will be released in CustomFreeTransferHandler if frame is null.
+ if (!audioData) {
+ return false;
+ }
+ delete data;
+ aContent = nullptr;
+
+ JS::Rooted<JS::Value> value(aCx);
+ if (!GetOrCreateDOMReflector(aCx, audioData, &value)) {
+ JS_ClearPendingException(aCx);
+ return false;
+ }
+ aReturnObject.set(&value.toObject());
+ return true;
+ }
+
return false;
}
@@ -1530,6 +1612,26 @@ StructuredCloneHolder::CustomWriteTransferHandler(
return true;
}
}
+ if (StaticPrefs::dom_media_webcodecs_enabled()) {
+ mozilla::dom::AudioData* audioData = nullptr;
+ rv = UNWRAP_OBJECT(AudioData, &obj, audioData);
+ if (NS_SUCCEEDED(rv)) {
+ MOZ_ASSERT(audioData);
+
+ *aExtraData = 0;
+ *aTag = SCTAG_DOM_AUDIODATA;
+ *aContent = nullptr;
+
+ UniquePtr<AudioData::TransferredData> data = audioData->Transfer();
+ if (!data) {
+ return false;
+ }
+ *aContent = data.release();
+ MOZ_ASSERT(*aContent);
+ *aOwnership = JS::SCTAG_TMO_CUSTOM;
+ return true;
+ }
+ }
}
{
@@ -1667,6 +1769,16 @@ void StructuredCloneHolder::CustomFreeTransferHandler(
}
return;
}
+ if (StaticPrefs::dom_media_webcodecs_enabled() &&
+ aTag == SCTAG_DOM_AUDIODATA &&
+ CloneScope() == StructuredCloneScope::SameProcess) {
+ if (aContent) {
+ AudioData::TransferredData* data =
+ static_cast<AudioData::TransferredData*>(aContent);
+ delete data;
+ }
+ return;
+ }
}
bool StructuredCloneHolder::CustomCanTransferHandler(
@@ -1750,6 +1862,15 @@ bool StructuredCloneHolder::CustomCanTransferHandler(
}
}
+ if (StaticPrefs::dom_media_webcodecs_enabled()) {
+ mozilla::dom::AudioData* audioData = nullptr;
+ nsresult rv = UNWRAP_OBJECT(AudioData, &obj, audioData);
+ if (NS_SUCCEEDED(rv)) {
+ SameProcessScopeRequired(aSameProcessScopeRequired);
+ return CloneScope() == StructuredCloneScope::SameProcess;
+ }
+ }
+
return false;
}