/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_AudioData_h #define mozilla_dom_AudioData_h #include "MediaData.h" #include "WebCodecsUtils.h" #include "js/TypeDecls.h" #include "mozilla/ErrorResult.h" #include "mozilla/Span.h" #include "mozilla/dom/AudioDataBinding.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/StructuredCloneHolder.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" class nsIGlobalObject; class nsIURI; namespace mozilla::dom { class MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer; class OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer; class Promise; struct AudioDataBufferInit; struct AudioDataCopyToOptions; struct AudioDataInit; } // namespace mozilla::dom namespace mozilla::dom { class AudioData; class AudioDataResource; struct AudioDataSerializedData; class AudioData final : public nsISupports, public nsWrapperCache { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(AudioData) public: AudioData(nsIGlobalObject* aParent, const AudioDataSerializedData& aData); AudioData(nsIGlobalObject* aParent, already_AddRefed aResource, const AudioDataInit& aInit); AudioData(nsIGlobalObject* aParent, already_AddRefed aResource, int64_t aTimestamp, uint32_t aNumberOfChannels, uint32_t aNumberOfFrames, float aSampleRate, AudioSampleFormat aAudioSampleFormat); AudioData(const AudioData& aOther); protected: ~AudioData() = default; public: nsIGlobalObject* GetParentObject() const; JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; static already_AddRefed Constructor(const GlobalObject& aGlobal, const AudioDataInit& aInit, ErrorResult& aRv); Nullable GetFormat() const; float SampleRate() const; uint32_t NumberOfFrames() const; uint32_t NumberOfChannels() const; uint64_t Duration() const; // microseconds int64_t Timestamp() const; // microseconds uint32_t AllocationSize(const AudioDataCopyToOptions& aOptions, ErrorResult& aRv); void CopyTo( const MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aDestination, const AudioDataCopyToOptions& aOptions, ErrorResult& aRv); already_AddRefed Clone(ErrorResult& aRv); void Close(); // [Serializable] implementations: {Read, Write}StructuredClone static JSObject* ReadStructuredClone(JSContext* aCx, nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader, const AudioDataSerializedData& aData); bool WriteStructuredClone(JSStructuredCloneWriter* aWriter, StructuredCloneHolder* aHolder) const; // [Transferable] implementations: Transfer, FromTransferred using TransferredData = AudioDataSerializedData; UniquePtr Transfer(); static already_AddRefed FromTransferred(nsIGlobalObject* aGlobal, TransferredData* aData); private: size_t ComputeCopyElementCount(const AudioDataCopyToOptions& aOptions, ErrorResult& aRv); nsCString ToString() const; // AudioData can run on either main thread or worker thread. void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(AudioData); } void CloseIfNeeded(); nsCOMPtr mParent; friend struct AudioDataSerializedData; int64_t mTimestamp; uint32_t mNumberOfChannels; uint32_t mNumberOfFrames; float mSampleRate; Maybe mAudioSampleFormat; RefPtr mResource; }; class AudioDataResource final { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioDataResource); explicit AudioDataResource(FallibleTArray&& aData) : mData(std::move(aData)) {} explicit AudioDataResource() : mData() {} static AudioDataResource* Create(const Span& aData) { AudioDataResource* resource = new AudioDataResource(); if (!resource->mData.AppendElements(aData, mozilla::fallible_t())) { return nullptr; } return resource; } static Result, nsresult> Construct( const OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aInit); Span Data() { return Span(mData.Elements(), mData.Length()); }; private: ~AudioDataResource() = default; // It's always possible for the allocation to fail -- the size is // controled by script. FallibleTArray mData; }; struct AudioDataSerializedData { explicit AudioDataSerializedData(const AudioData& aFrom) : mTimestamp(aFrom.Timestamp()), mNumberOfChannels(aFrom.NumberOfChannels()), mNumberOfFrames(aFrom.NumberOfFrames()), mSampleRate(aFrom.SampleRate()), mAudioSampleFormat(NullableToMaybe(aFrom.GetFormat())), mResource(aFrom.mResource) {} int64_t mTimestamp{}; uint32_t mNumberOfChannels{}; uint32_t mNumberOfFrames{}; float mSampleRate{}; Maybe mAudioSampleFormat; RefPtr mResource; }; } // namespace mozilla::dom #endif // mozilla_dom_AudioData_h