author | Jean-Yves Avenard <jyavenard@mozilla.com> |
Mon, 29 Oct 2018 09:44:18 +0000 | |
changeset 443306 | 4a85f19e21f4a4a437d4c10c1784fdcbe8788686 |
parent 443305 | deb0260b33c1b57a0a98c409d2f839a74596985a |
child 443307 | a78e285cc06f6b98cbe0f2d090871c00f68823b5 |
push id | 71881 |
push user | jyavenard@mozilla.com |
push date | Mon, 29 Oct 2018 09:57:18 +0000 |
treeherder | autoland@4a85f19e21f4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | padenot |
bugs | 1502488 |
milestone | 65.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/dom/media/gtest/TestOpusParser.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "gtest/gtest.h" +#include "OpusParser.h" +#include <algorithm> + +TEST(OpusParser, Mapping2) +{ + uint8_t validChannels[] = { + 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36, 38, 49, 51, 64, + 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171, 196, 198, 225, 227 + }; + for (uint8_t channels = 0; channels < 255; channels++) { + bool found = OpusParser::IsValidMapping2ChannelsCount(channels); + bool foundTable = + std::find(std::begin(validChannels), std::end(validChannels), channels) != + std::end(validChannels); + EXPECT_EQ(found, foundTable); + } +}
--- a/dom/media/gtest/moz.build +++ b/dom/media/gtest/moz.build @@ -28,16 +28,17 @@ UNIFIED_SOURCES += [ 'TestGMPRemoveAndDelete.cpp', 'TestGMPUtils.cpp', 'TestIntervalSet.cpp', 'TestMediaDataDecoder.cpp', 'TestMediaEventSource.cpp', 'TestMediaMIMETypes.cpp', 'TestMP3Demuxer.cpp', 'TestMP4Demuxer.cpp', + 'TestOpusParser.cpp', 'TestRust.cpp', 'TestVideoSegment.cpp', 'TestVideoUtils.cpp', 'TestVPXDecoding.cpp', 'TestWebMBuffered.cpp', ] if CONFIG['MOZ_WEBM_ENCODER']:
--- a/dom/media/ogg/OpusParser.cpp +++ b/dom/media/ogg/OpusParser.cpp @@ -88,37 +88,19 @@ bool OpusParser::DecodeHeader(unsigned c if (mChannelMapping == 1 && mChannels > 8) { OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: too many channels (%d) for" " mapping family 1.", mChannels)); return false; } if (mChannelMapping == 2) { - // https://tools.ietf.org/html/draft-ietf-codec-ambisonics-08#page-3 - // For both channel mapping family 2 and family 3, the allowed numbers - // of channels: (1 + n)^2 + 2j for n = 0, 1, ..., 14 and j = 0 or 1, - // where n denotes the (highest) ambisonic order and j denotes whether - // or not there is a separate non-diegetic stereo stream Explicitly the - // allowed number of channels are 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36, - // 38, 49, 51, 64, 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171, - // 196, 198, 225, and 227. - - // We use the property that int(sqrt(n)) == int(sqrt(n+2)) for n != 3 - // which is handled by the test n^2 + 2 != channel - double val = sqrt(mChannels); - if (val == 0 || val > 15) { + if (!IsValidMapping2ChannelsCount(mChannels)) { return false; } - if (val != int32_t(val)) { - if (val * val + 2 != mChannels) { - // Not a valid channel count. - return false; - } - } } if (aLength > static_cast<unsigned>(20 + mChannels)) { mStreams = aData[19]; mCoupledStreams = aData[20]; int i; for (i = 0; i < mChannels; i++) { mMappingTable[i] = aData[21 + i]; } @@ -210,9 +192,31 @@ bool OpusParser::DecodeTags(unsigned cha OPUS_LOG(LogLevel::Debug, (" vendor: %s", mVendorString.get())); for (uint32_t i = 0; i < mTags.Length(); i++) { OPUS_LOG(LogLevel::Debug, (" %s", mTags[i].get())); } #endif return true; } +/* static */ bool +OpusParser::IsValidMapping2ChannelsCount(uint8_t aChannels) +{ + // https://tools.ietf.org/html/draft-ietf-codec-ambisonics-08#page-4 + // For both channel mapping family 2 and family 3, the allowed numbers + // of channels: (1 + n)^2 + 2j for n = 0, 1, ..., 14 and j = 0 or 1, + // where n denotes the (highest) ambisonic order and j denotes whether + // or not there is a separate non-diegetic stereo stream Explicitly the + // allowed number of channels are 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36, + // 38, 49, 51, 64, 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171, + // 196, 198, 225, and 227. + + // We use the property that int(sqrt(n)) == int(sqrt(n+2)) for n != 3 + // which is handled by the test n^2 + 2 != channel + if (aChannels < 1 || aChannels > 227) { + return false; + } + double val = sqrt(aChannels); + int32_t valInt = int32_t(val); + return val == valInt || valInt * valInt + 2 == aChannels; +} + } // namespace mozilla
--- a/dom/media/ogg/OpusParser.h +++ b/dom/media/ogg/OpusParser.h @@ -13,16 +13,17 @@ namespace mozilla { class OpusParser { public: OpusParser(); bool DecodeHeader(unsigned char* aData, size_t aLength); bool DecodeTags(unsigned char* aData, size_t aLength); + static bool IsValidMapping2ChannelsCount(uint8_t aChannels); // Various fields from the Ogg Opus header. int mRate; // Sample rate the decoder uses (always 48 kHz). uint32_t mNominalRate; // Original sample rate of the data (informational). int mChannels; // Number of channels the stream encodes. uint16_t mPreSkip; // Number of samples to strip after decoder reset. #ifdef MOZ_SAMPLE_TYPE_FLOAT32 float mGain; // Gain to apply to decoder output.