1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
/* -*- 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/BufferSourceBindingFwd.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
class nsIGlobalObject;
class nsIURI;
namespace mozilla::dom {
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<AudioDataResource> aResource,
const AudioDataInit& aInit);
AudioData(nsIGlobalObject* aParent,
already_AddRefed<mozilla::dom::AudioDataResource> 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<JSObject*> aGivenProto) override;
static already_AddRefed<AudioData> Constructor(const GlobalObject& aGlobal,
const AudioDataInit& aInit,
ErrorResult& aRv);
Nullable<mozilla::dom::AudioSampleFormat> 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 AllowSharedBufferSource& aDestination,
const AudioDataCopyToOptions& aOptions, ErrorResult& aRv);
already_AddRefed<AudioData> Clone(ErrorResult& aRv);
void Close();
bool IsClosed() const;
// [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<TransferredData> Transfer();
static already_AddRefed<AudioData> FromTransferred(nsIGlobalObject* aGlobal,
TransferredData* aData);
nsCString ToString() const;
RefPtr<mozilla::AudioData> ToAudioData() const;
private:
size_t ComputeCopyElementCount(const AudioDataCopyToOptions& aOptions,
ErrorResult& aRv);
// AudioData can run on either main thread or worker thread.
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(AudioData); }
void CloseIfNeeded();
nsCOMPtr<nsIGlobalObject> mParent;
friend struct AudioDataSerializedData;
int64_t mTimestamp;
uint32_t mNumberOfChannels;
uint32_t mNumberOfFrames;
float mSampleRate;
Maybe<AudioSampleFormat> mAudioSampleFormat;
RefPtr<mozilla::dom::AudioDataResource> mResource;
};
class AudioDataResource final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioDataResource);
explicit AudioDataResource(FallibleTArray<uint8_t>&& aData)
: mCopiedData(std::move(aData)) {}
explicit AudioDataResource() : mCopiedData() {}
/// Create AudioDataResource, transferring ownership from js_malloc'd data.
AudioDataResource(UniquePtr<uint8_t[], JS::FreePolicy>&& aData,
size_t aOffset, size_t aLen)
: mAdoptedData(std::move(aData)),
mAdoptedDataOffset(aOffset),
mAdoptedDataLen(aLen) {}
static AudioDataResource* Create(const Span<uint8_t>& aData) {
AudioDataResource* resource = new AudioDataResource();
if (!resource->mCopiedData.AppendElements(aData, mozilla::fallible_t())) {
return nullptr;
}
return resource;
}
static Result<already_AddRefed<AudioDataResource>, nsresult> Construct(
const OwningAllowSharedBufferSource& aInit);
Span<uint8_t> Data() {
return mAdoptedData
? Span(mAdoptedData.get() + mAdoptedDataOffset, mAdoptedDataLen)
: Span(mCopiedData.Elements(), mCopiedData.Length());
}
private:
~AudioDataResource() = default;
// It's always possible for the allocation to fail -- the size is
// controled by script.
FallibleTArray<uint8_t> mCopiedData;
UniquePtr<uint8_t[], JS::FreePolicy> mAdoptedData;
size_t mAdoptedDataOffset;
size_t mAdoptedDataLen;
};
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<AudioSampleFormat> mAudioSampleFormat;
RefPtr<AudioDataResource> mResource;
};
} // namespace mozilla::dom
#endif // mozilla_dom_AudioData_h
|