mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 09:57:32 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
158
dom/media/platforms/agnostic/WAVDecoder.cpp
Normal file
158
dom/media/platforms/agnostic/WAVDecoder.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "WAVDecoder.h"
|
||||
#include "AudioSampleFormat.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
|
||||
using mp4_demuxer::ByteReader;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
int16_t
|
||||
DecodeALawSample(uint8_t aValue)
|
||||
{
|
||||
aValue = aValue ^ 0x55;
|
||||
int8_t sign = (aValue & 0x80) ? -1 : 1;
|
||||
uint8_t exponent = (aValue & 0x70) >> 4;
|
||||
uint8_t mantissa = aValue & 0x0F;
|
||||
int16_t sample = mantissa << 4;
|
||||
switch (exponent) {
|
||||
case 0:
|
||||
sample += 8;
|
||||
break;
|
||||
case 1:
|
||||
sample += 0x108;
|
||||
break;
|
||||
default:
|
||||
sample += 0x108;
|
||||
sample <<= exponent - 1;
|
||||
}
|
||||
return sign * sample;
|
||||
}
|
||||
|
||||
int16_t
|
||||
DecodeULawSample(uint8_t aValue)
|
||||
{
|
||||
aValue = aValue ^ 0xFF;
|
||||
int8_t sign = (aValue & 0x80) ? -1 : 1;
|
||||
uint8_t exponent = (aValue & 0x70) >> 4;
|
||||
uint8_t mantissa = aValue & 0x0F;
|
||||
int16_t sample = (33 + 2 * mantissa) * (2 << (exponent + 1)) - 33;
|
||||
return sign * sample;
|
||||
}
|
||||
|
||||
WaveDataDecoder::WaveDataDecoder(const CreateDecoderParams& aParams)
|
||||
: mInfo(aParams.AudioConfig())
|
||||
, mCallback(aParams.mCallback)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WaveDataDecoder::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<MediaDataDecoder::InitPromise>
|
||||
WaveDataDecoder::Init()
|
||||
{
|
||||
return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
WaveDataDecoder::Input(MediaRawData* aSample)
|
||||
{
|
||||
MediaResult rv = DoDecode(aSample);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCallback->Error(rv);
|
||||
} else {
|
||||
mCallback->InputExhausted();
|
||||
}
|
||||
}
|
||||
|
||||
MediaResult
|
||||
WaveDataDecoder::DoDecode(MediaRawData* aSample)
|
||||
{
|
||||
size_t aLength = aSample->Size();
|
||||
ByteReader aReader(aSample->Data(), aLength);
|
||||
int64_t aOffset = aSample->mOffset;
|
||||
uint64_t aTstampUsecs = aSample->mTime;
|
||||
|
||||
int32_t frames = aLength * 8 / mInfo.mBitDepth / mInfo.mChannels;
|
||||
|
||||
AlignedAudioBuffer buffer(frames * mInfo.mChannels);
|
||||
if (!buffer) {
|
||||
return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
}
|
||||
for (int i = 0; i < frames; ++i) {
|
||||
for (unsigned int j = 0; j < mInfo.mChannels; ++j) {
|
||||
if (mInfo.mProfile == 6) { //ALAW Data
|
||||
uint8_t v = aReader.ReadU8();
|
||||
int16_t decoded = DecodeALawSample(v);
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
IntegerToAudioSample<AudioDataValue>(decoded);
|
||||
} else if (mInfo.mProfile == 7) { //ULAW Data
|
||||
uint8_t v = aReader.ReadU8();
|
||||
int16_t decoded = DecodeULawSample(v);
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
IntegerToAudioSample<AudioDataValue>(decoded);
|
||||
} else { //PCM Data
|
||||
if (mInfo.mBitDepth == 8) {
|
||||
uint8_t v = aReader.ReadU8();
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
UInt8bitToAudioSample<AudioDataValue>(v);
|
||||
} else if (mInfo.mBitDepth == 16) {
|
||||
int16_t v = aReader.ReadLE16();
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
IntegerToAudioSample<AudioDataValue>(v);
|
||||
} else if (mInfo.mBitDepth == 24) {
|
||||
int32_t v = aReader.ReadLE24();
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
Int24bitToAudioSample<AudioDataValue>(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t duration = frames / mInfo.mRate;
|
||||
|
||||
mCallback->Output(new AudioData(aOffset,
|
||||
aTstampUsecs,
|
||||
duration,
|
||||
frames,
|
||||
Move(buffer),
|
||||
mInfo.mChannels,
|
||||
mInfo.mRate));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
WaveDataDecoder::Drain()
|
||||
{
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
|
||||
void
|
||||
WaveDataDecoder::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
WaveDataDecoder::IsWave(const nsACString& aMimeType)
|
||||
{
|
||||
// Some WebAudio uses "audio/x-wav",
|
||||
// WAVdemuxer uses "audio/wave; codecs=aNum".
|
||||
return aMimeType.EqualsLiteral("audio/x-wav") ||
|
||||
aMimeType.EqualsLiteral("audio/wave; codecs=1") ||
|
||||
aMimeType.EqualsLiteral("audio/wave; codecs=6") ||
|
||||
aMimeType.EqualsLiteral("audio/wave; codecs=7") ||
|
||||
aMimeType.EqualsLiteral("audio/wave; codecs=65534");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
#undef LOG
|
||||
Loading…
Add table
Add a link
Reference in a new issue