зеркало из https://github.com/mozilla/gecko-dev.git
Bug 851530: Part 1 - Added support for decoding uLaw and aLaw enconded wave files. r=jya
--HG-- extra : rebase_source : f9179aa998afb3bf6b7c3a2ef2b841aded6c1153
This commit is contained in:
Родитель
d5d114572a
Коммит
6545052865
|
@ -134,8 +134,10 @@ static const char* const gWaveTypes[5] = {
|
|||
nullptr
|
||||
};
|
||||
|
||||
static char const *const gWaveCodecs[2] = {
|
||||
static char const *const gWaveCodecs[4] = {
|
||||
"1", // Microsoft PCM Format
|
||||
"6", // aLaw Encoding
|
||||
"7", // uLaw Encoding
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,39 @@ 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 AudioInfo& aConfig,
|
||||
FlushableTaskQueue* aTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback)
|
||||
|
@ -69,18 +102,30 @@ WaveDataDecoder::DoDecode(MediaRawData* aSample)
|
|||
auto buffer = MakeUnique<AudioDataValue[]>(frames * mInfo.mChannels);
|
||||
for (int i = 0; i < frames; ++i) {
|
||||
for (unsigned int j = 0; j < mInfo.mChannels; ++j) {
|
||||
if (mInfo.mBitDepth == 8) {
|
||||
if (mInfo.mProfile == 6) { //ALAW Data
|
||||
uint8_t v = aReader.ReadU8();
|
||||
int16_t decoded = DecodeALawSample(v);
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
UInt8bitToAudioSample<AudioDataValue>(v);
|
||||
} else if (mInfo.mBitDepth == 16) {
|
||||
int16_t v = aReader.ReadLE16();
|
||||
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>(v);
|
||||
} else if (mInfo.mBitDepth == 24) {
|
||||
int32_t v = aReader.ReadLE24();
|
||||
buffer[i * mInfo.mChannels + j] =
|
||||
Int24bitToAudioSample<AudioDataValue>(v);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +177,8 @@ WaveDataDecoder::IsWave(const nsACString& aMimeType)
|
|||
// 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");
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,8 @@ AndroidDecoderModule::SupportsMimeType(const nsACString& aMimeType) const
|
|||
// To avoid this we check for wav types here.
|
||||
if (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")) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ WaveDecoder::CanHandleMediaType(const nsACString& aType,
|
|||
{
|
||||
if (aType.EqualsASCII("audio/wave") || aType.EqualsASCII("audio/x-wav") ||
|
||||
aType.EqualsASCII("audio/wav") || aType.EqualsASCII("audio/x-pn-wav")) {
|
||||
return IsEnabled() && (aCodecs.IsEmpty() || aCodecs.EqualsASCII("1"));
|
||||
return IsEnabled() && (aCodecs.IsEmpty() ||
|
||||
aCodecs.EqualsASCII("1") ||
|
||||
aCodecs.EqualsASCII("6") ||
|
||||
aCodecs.EqualsASCII("7"));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче