summaryrefslogtreecommitdiffstats
path: root/dom/media/webcodecs/AudioData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webcodecs/AudioData.cpp')
-rw-r--r--dom/media/webcodecs/AudioData.cpp84
1 files changed, 36 insertions, 48 deletions
diff --git a/dom/media/webcodecs/AudioData.cpp b/dom/media/webcodecs/AudioData.cpp
index 0b21798be8..aae58fb32c 100644
--- a/dom/media/webcodecs/AudioData.cpp
+++ b/dom/media/webcodecs/AudioData.cpp
@@ -151,25 +151,6 @@ JSObject* AudioData::WrapObject(JSContext* aCx,
return AudioData_Binding::Wrap(aCx, this, aGivenProto);
}
-uint32_t BytesPerSamples(const mozilla::dom::AudioSampleFormat& aFormat) {
- switch (aFormat) {
- case AudioSampleFormat::U8:
- case AudioSampleFormat::U8_planar:
- return sizeof(uint8_t);
- case AudioSampleFormat::S16:
- case AudioSampleFormat::S16_planar:
- return sizeof(int16_t);
- case AudioSampleFormat::S32:
- case AudioSampleFormat::F32:
- case AudioSampleFormat::S32_planar:
- case AudioSampleFormat::F32_planar:
- return sizeof(float);
- default:
- MOZ_ASSERT_UNREACHABLE("wrong enum value");
- }
- return 0;
-}
-
Result<Ok, nsCString> IsValidAudioDataInit(const AudioDataInit& aInit) {
if (aInit.mSampleRate <= 0.0) {
auto msg = nsLiteralCString("sampleRate must be positive");
@@ -205,37 +186,13 @@ Result<Ok, nsCString> IsValidAudioDataInit(const AudioDataInit& aInit) {
return Ok();
}
-const char* FormatToString(AudioSampleFormat aFormat) {
- switch (aFormat) {
- case AudioSampleFormat::U8:
- return "u8";
- case AudioSampleFormat::S16:
- return "s16";
- case AudioSampleFormat::S32:
- return "s32";
- case AudioSampleFormat::F32:
- return "f32";
- case AudioSampleFormat::U8_planar:
- return "u8-planar";
- case AudioSampleFormat::S16_planar:
- return "s16-planar";
- case AudioSampleFormat::S32_planar:
- return "s32-planar";
- case AudioSampleFormat::F32_planar:
- return "f32-planar";
- default:
- MOZ_ASSERT_UNREACHABLE("wrong enum value");
- }
- return "unsupported";
-}
-
/* static */
already_AddRefed<AudioData> AudioData::Constructor(const GlobalObject& aGlobal,
const AudioDataInit& aInit,
ErrorResult& aRv) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
LOGD("[%p] AudioData(fmt: %s, rate: %f, ch: %" PRIu32 ", ts: %" PRId64 ")",
- global.get(), FormatToString(aInit.mFormat), aInit.mSampleRate,
+ global.get(), GetEnumString(aInit.mFormat).get(), aInit.mSampleRate,
aInit.mNumberOfChannels, aInit.mTimestamp);
if (!global) {
LOGE("Global unavailable");
@@ -311,6 +268,9 @@ struct CopyToSpec {
const uint32_t mFrameOffset;
const uint32_t mPlaneIndex;
const AudioSampleFormat mFormat;
+ // False if this is used internally, and this copy call doesn't come from
+ // script.
+ DebugOnly<bool> mFromScript = true;
};
bool IsInterleaved(const AudioSampleFormat& aFormat) {
@@ -463,7 +423,7 @@ void CopySamples(Span<S> aSource, Span<D> aDest, uint32_t aSourceChannelCount,
}
if (!IsInterleaved(aSourceFormat) && IsInterleaved(aCopyToSpec.mFormat)) {
- MOZ_CRASH("This should never be hit -- current spec doesn't support it");
+ MOZ_ASSERT(!aCopyToSpec.mFromScript);
// Planar to interleaved -- copy of all channels of the source into the
// destination buffer.
MOZ_ASSERT(aCopyToSpec.mPlaneIndex == 0);
@@ -505,7 +465,7 @@ nsCString AudioData::ToString() const {
return nsPrintfCString("AudioData[%zu bytes %s %fHz %" PRIu32 "x%" PRIu32
"ch]",
mResource->Data().LengthBytes(),
- FormatToString(mAudioSampleFormat.value()),
+ GetEnumString(mAudioSampleFormat.value()).get(),
mSampleRate, mNumberOfFrames, mNumberOfChannels);
}
@@ -515,8 +475,9 @@ nsCString CopyToToString(size_t aDestBufSize,
"AudioDataCopyToOptions[data: %zu bytes %s frame count:%" PRIu32
" frame offset: %" PRIu32 " plane: %" PRIu32 "]",
aDestBufSize,
- aOptions.mFormat.WasPassed() ? FormatToString(aOptions.mFormat.Value())
- : "null",
+ aOptions.mFormat.WasPassed()
+ ? GetEnumString(aOptions.mFormat.Value()).get()
+ : "null",
aOptions.mFrameCount.WasPassed() ? aOptions.mFrameCount.Value() : 0,
aOptions.mFrameOffset, aOptions.mPlaneIndex);
}
@@ -650,6 +611,8 @@ void AudioData::Close() {
mAudioSampleFormat = Nothing();
}
+bool AudioData::IsClosed() const { return !mResource; }
+
// https://w3c.github.io/webcodecs/#ref-for-deserialization-steps%E2%91%A1
/* static */
JSObject* AudioData::ReadStructuredClone(JSContext* aCx,
@@ -724,6 +687,31 @@ void AudioData::CloseIfNeeded() {
}
}
+RefPtr<mozilla::AudioData> AudioData::ToAudioData() const {
+ // Always convert to f32 interleaved for now, as this Gecko's prefered
+ // internal audio representation for encoding and decoding.
+ Span<uint8_t> data = mResource->Data();
+ DebugOnly<uint32_t> frames = mNumberOfFrames;
+ uint32_t bytesPerSample = BytesPerSamples(mAudioSampleFormat.value());
+ uint32_t samples = data.Length() / bytesPerSample;
+ DebugOnly<uint32_t> computedFrames = samples / mNumberOfChannels;
+ MOZ_ASSERT(frames == computedFrames);
+ AlignedAudioBuffer buf(samples);
+ Span<uint8_t> storage(reinterpret_cast<uint8_t*>(buf.Data()),
+ samples * sizeof(float));
+
+ CopyToSpec spec(mNumberOfFrames, 0, 0, AudioSampleFormat::F32);
+#ifdef DEBUG
+ spec.mFromScript = false;
+#endif
+
+ DoCopy(data, storage, mNumberOfChannels, mAudioSampleFormat.value(), spec);
+
+ return MakeRefPtr<mozilla::AudioData>(
+ 0, media::TimeUnit::FromMicroseconds(mTimestamp), std::move(buf),
+ mNumberOfChannels, mSampleRate);
+}
+
#undef LOGD
#undef LOGE
#undef LOG_INTERNAL