Bug 1431221 - P10. Properly retrieve and set channel layout for opus and vorbis. r=cpearce

MozReview-Commit-ID: A4jEQzHRKDT
This commit is contained in:
Jean-Yves Avenard 2018-02-11 18:58:03 +01:00
parent c69d04a58b
commit eae919be64
3 changed files with 36 additions and 16 deletions

View File

@ -35,6 +35,7 @@ OpusDataDecoder::OpusDataDecoder(const CreateDecoderParams& aParams)
, mDecodedHeader(false)
, mPaddingDiscarded(false)
, mFrames(0)
, mChannelMap(AudioConfig::ChannelLayout::UNKNOWN_MAP)
{
}
@ -130,18 +131,23 @@ OpusDataDecoder::DecodeHeader(const unsigned char* aData, size_t aLength)
}
int channels = mOpusParser->mChannels;
AudioConfig::ChannelLayout layout(channels);
if (!layout.IsValid()) {
AudioConfig::ChannelLayout vorbisLayout(
channels, VorbisDataDecoder::VorbisLayout(channels));
if (!vorbisLayout.IsValid()) {
OPUS_DEBUG("Invalid channel mapping. Source is %d channels", channels);
return NS_ERROR_FAILURE;
}
mChannelMap = vorbisLayout.Map();
AudioConfig::ChannelLayout vorbisLayout(
channels, VorbisDataDecoder::VorbisLayout(channels));
AudioConfig::ChannelLayout smpteLayout(channels);
static_assert(sizeof(mOpusParser->mMappingTable) / sizeof(mOpusParser->mMappingTable[0]) >= MAX_AUDIO_CHANNELS,
"Invalid size set");
uint8_t map[sizeof(mOpusParser->mMappingTable) / sizeof(mOpusParser->mMappingTable[0])];
AudioConfig::ChannelLayout smpteLayout(
AudioConfig::ChannelLayout::SMPTEDefault(vorbisLayout));
static_assert(sizeof(mOpusParser->mMappingTable) /
sizeof(mOpusParser->mMappingTable[0]) >=
MAX_AUDIO_CHANNELS,
"Invalid size set");
uint8_t map[sizeof(mOpusParser->mMappingTable) /
sizeof(mOpusParser->mMappingTable[0])];
if (vorbisLayout.MappingTable(smpteLayout, map)) {
for (int i = 0; i < channels; i++) {
mMappingTable[i] = mOpusParser->mMappingTable[map[i]];
@ -318,9 +324,14 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
mFrames += frames;
return DecodePromise::CreateAndResolve(
DecodedData{ new AudioData(aSample->mOffset, time, duration,
frames, Move(buffer), mOpusParser->mChannels,
mOpusParser->mRate) },
DecodedData{ new AudioData(aSample->mOffset,
time,
duration,
frames,
Move(buffer),
mOpusParser->mChannels,
mOpusParser->mRate,
mChannelMap) },
__func__);
}

View File

@ -69,6 +69,7 @@ private:
int64_t mFrames;
Maybe<int64_t> mLastFrameTime;
uint8_t mMappingTable[MAX_AUDIO_CHANNELS]; // Channel mapping table.
AudioConfig::ChannelLayout::ChannelMap mChannelMap;
};
} // namespace mozilla

View File

@ -233,9 +233,10 @@ VorbisDataDecoder::ProcessDecode(MediaRawData* aSample)
};
if (!mAudioConverter) {
AudioConfig in(
AudioConfig::ChannelLayout(channels, VorbisLayout(channels)), rate);
AudioConfig out(channels, rate);
const AudioConfig::ChannelLayout layout =
AudioConfig::ChannelLayout(channels, VorbisLayout(channels));
AudioConfig in(layout, rate);
AudioConfig out(AudioConfig::ChannelLayout::SMPTEDefault(layout), rate);
if (!in.IsValid() || !out.IsValid()) {
return DecodePromise::CreateAndReject(
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
@ -248,8 +249,15 @@ VorbisDataDecoder::ProcessDecode(MediaRawData* aSample)
AudioSampleBuffer data(Move(buffer));
data = mAudioConverter->Process(Move(data));
results.AppendElement(new AudioData(aOffset, time, duration,
frames, data.Forget(), channels, rate));
results.AppendElement(
new AudioData(aOffset,
time,
duration,
frames,
data.Forget(),
channels,
rate,
mAudioConverter->OutputConfig().Layout().Map()));
mFrames += frames;
err = vorbis_synthesis_read(&mVorbisDsp, frames);
if (err) {