177 lines
5.6 KiB
C++
177 lines
5.6 KiB
C++
/* -*- 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)
|
|
: mData(std::move(aData)) {}
|
|
|
|
explicit AudioDataResource() : mData() {}
|
|
|
|
static AudioDataResource* Create(const Span<uint8_t>& aData) {
|
|
AudioDataResource* resource = new AudioDataResource();
|
|
if (!resource->mData.AppendElements(aData, mozilla::fallible_t())) {
|
|
return nullptr;
|
|
}
|
|
return resource;
|
|
}
|
|
|
|
static Result<already_AddRefed<AudioDataResource>, nsresult> Construct(
|
|
const OwningAllowSharedBufferSource& aInit);
|
|
|
|
Span<uint8_t> 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<uint8_t> 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<AudioSampleFormat> mAudioSampleFormat;
|
|
RefPtr<AudioDataResource> mResource;
|
|
};
|
|
|
|
} // namespace mozilla::dom
|
|
|
|
#endif // mozilla_dom_AudioData_h
|