AudioData.h (6293B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_AudioData_h 8 #define mozilla_dom_AudioData_h 9 10 #include "MediaData.h" 11 #include "WebCodecsUtils.h" 12 #include "js/TypeDecls.h" 13 #include "mozilla/ErrorResult.h" 14 #include "mozilla/Span.h" 15 #include "mozilla/dom/AudioDataBinding.h" 16 #include "mozilla/dom/BindingDeclarations.h" 17 #include "mozilla/dom/BufferSourceBindingFwd.h" 18 #include "mozilla/dom/StructuredCloneHolder.h" 19 #include "nsCycleCollectionParticipant.h" 20 #include "nsWrapperCache.h" 21 22 class nsIGlobalObject; 23 class nsIURI; 24 25 namespace mozilla::dom { 26 27 class Promise; 28 struct AudioDataBufferInit; 29 struct AudioDataCopyToOptions; 30 struct AudioDataInit; 31 32 } // namespace mozilla::dom 33 34 namespace mozilla::dom { 35 36 class AudioData; 37 class AudioDataResource; 38 struct AudioDataSerializedData; 39 40 class AudioData final : public nsISupports, public nsWrapperCache { 41 public: 42 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 43 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(AudioData) 44 45 public: 46 AudioData(nsIGlobalObject* aParent, const AudioDataSerializedData& aData); 47 AudioData(nsIGlobalObject* aParent, 48 already_AddRefed<AudioDataResource> aResource, 49 const AudioDataInit& aInit); 50 AudioData(nsIGlobalObject* aParent, 51 already_AddRefed<mozilla::dom::AudioDataResource> aResource, 52 int64_t aTimestamp, uint32_t aNumberOfChannels, 53 uint32_t aNumberOfFrames, float aSampleRate, 54 AudioSampleFormat aAudioSampleFormat); 55 AudioData(const AudioData& aOther); 56 57 protected: 58 ~AudioData() = default; 59 60 public: 61 nsIGlobalObject* GetParentObject() const; 62 63 JSObject* WrapObject(JSContext* aCx, 64 JS::Handle<JSObject*> aGivenProto) override; 65 66 static already_AddRefed<AudioData> Constructor(const GlobalObject& aGlobal, 67 const AudioDataInit& aInit, 68 ErrorResult& aRv); 69 70 Nullable<mozilla::dom::AudioSampleFormat> GetFormat() const; 71 72 float SampleRate() const; 73 74 uint32_t NumberOfFrames() const; 75 76 uint32_t NumberOfChannels() const; 77 78 uint64_t Duration() const; // microseconds 79 80 int64_t Timestamp() const; // microseconds 81 82 uint32_t AllocationSize(const AudioDataCopyToOptions& aOptions, 83 ErrorResult& aRv); 84 85 void CopyTo(const AllowSharedBufferSource& aDestination, 86 const AudioDataCopyToOptions& aOptions, ErrorResult& aRv); 87 88 already_AddRefed<AudioData> Clone(ErrorResult& aRv); 89 90 void Close(); 91 bool IsClosed() const; 92 93 // [Serializable] implementations: {Read, Write}StructuredClone 94 static JSObject* ReadStructuredClone(JSContext* aCx, nsIGlobalObject* aGlobal, 95 JSStructuredCloneReader* aReader, 96 const AudioDataSerializedData& aData); 97 98 bool WriteStructuredClone(JSStructuredCloneWriter* aWriter, 99 StructuredCloneHolder* aHolder) const; 100 101 // [Transferable] implementations: Transfer, FromTransferred 102 using TransferredData = AudioDataSerializedData; 103 104 UniquePtr<TransferredData> Transfer(); 105 106 static already_AddRefed<AudioData> FromTransferred(nsIGlobalObject* aGlobal, 107 TransferredData* aData); 108 109 nsCString ToString() const; 110 111 RefPtr<mozilla::AudioData> ToAudioData() const; 112 113 private: 114 size_t ComputeCopyElementCount(const AudioDataCopyToOptions& aOptions, 115 ErrorResult& aRv); 116 // AudioData can run on either main thread or worker thread. 117 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(AudioData); } 118 void CloseIfNeeded(); 119 120 nsCOMPtr<nsIGlobalObject> mParent; 121 122 friend struct AudioDataSerializedData; 123 124 int64_t mTimestamp; 125 uint32_t mNumberOfChannels; 126 uint32_t mNumberOfFrames; 127 float mSampleRate; 128 Maybe<AudioSampleFormat> mAudioSampleFormat; 129 RefPtr<mozilla::dom::AudioDataResource> mResource; 130 }; 131 132 class AudioDataResource final { 133 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioDataResource); 134 explicit AudioDataResource(FallibleTArray<uint8_t>&& aData) 135 : mCopiedData(std::move(aData)) {} 136 137 explicit AudioDataResource() : mCopiedData() {} 138 /// Create AudioDataResource, transferring ownership from js_malloc'd data. 139 AudioDataResource(UniquePtr<uint8_t[], JS::FreePolicy>&& aData, 140 size_t aOffset, size_t aLen) 141 : mAdoptedData(std::move(aData)), 142 mAdoptedDataOffset(aOffset), 143 mAdoptedDataLen(aLen) {} 144 145 static AudioDataResource* Create(const Span<uint8_t>& aData) { 146 AudioDataResource* resource = new AudioDataResource(); 147 if (!resource->mCopiedData.AppendElements(aData, mozilla::fallible_t())) { 148 return nullptr; 149 } 150 return resource; 151 } 152 153 static Result<already_AddRefed<AudioDataResource>, nsresult> Construct( 154 const OwningAllowSharedBufferSource& aInit); 155 156 Span<uint8_t> Data() { 157 return mAdoptedData 158 ? Span(mAdoptedData.get() + mAdoptedDataOffset, mAdoptedDataLen) 159 : Span(mCopiedData.Elements(), mCopiedData.Length()); 160 } 161 162 private: 163 ~AudioDataResource() = default; 164 // It's always possible for the allocation to fail -- the size is 165 // controled by script. 166 FallibleTArray<uint8_t> mCopiedData; 167 UniquePtr<uint8_t[], JS::FreePolicy> mAdoptedData; 168 size_t mAdoptedDataOffset; 169 size_t mAdoptedDataLen; 170 }; 171 172 struct AudioDataSerializedData { 173 explicit AudioDataSerializedData(const AudioData& aFrom) 174 : mTimestamp(aFrom.Timestamp()), 175 mNumberOfChannels(aFrom.NumberOfChannels()), 176 mNumberOfFrames(aFrom.NumberOfFrames()), 177 mSampleRate(aFrom.SampleRate()), 178 mAudioSampleFormat(NullableToMaybe(aFrom.GetFormat())), 179 mResource(aFrom.mResource) {} 180 int64_t mTimestamp{}; 181 uint32_t mNumberOfChannels{}; 182 uint32_t mNumberOfFrames{}; 183 float mSampleRate{}; 184 Maybe<AudioSampleFormat> mAudioSampleFormat; 185 RefPtr<AudioDataResource> mResource; 186 }; 187 188 } // namespace mozilla::dom 189 190 #endif // mozilla_dom_AudioData_h