diff options
Diffstat (limited to 'dom/base/StructuredCloneHolder.cpp')
-rw-r--r-- | dom/base/StructuredCloneHolder.cpp | 121 |
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; } |