OpusParser.cpp (7232B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "OpusParser.h" 8 9 #include <opus/opus.h> 10 11 #include <algorithm> 12 13 #include "VideoUtils.h" 14 #include "mozilla/EndianUtils.h" 15 extern "C" { 16 #include <opus/opus_multistream.h> 17 } 18 19 #include <cmath> 20 21 namespace mozilla { 22 23 extern LazyLogModule gMediaDecoderLog; 24 #define OPUS_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg) 25 26 OpusParser::OpusParser() 27 : mRate(0), 28 mNominalRate(0), 29 mChannels(0), 30 mPreSkip(0), 31 #ifdef MOZ_SAMPLE_TYPE_FLOAT32 32 mGain(1.0f), 33 #else 34 mGain_Q16(65536), 35 #endif 36 mChannelMapping(0), 37 mStreams(0), 38 mCoupledStreams(0), 39 mPrevPacketGranulepos(0) { 40 } 41 42 bool OpusParser::DecodeHeader(unsigned char* aData, size_t aLength) { 43 if (aLength < 19 || memcmp(aData, "OpusHead", 8) != 0) { 44 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: unrecognized header")); 45 return false; 46 } 47 48 mRate = 48000; // The Opus decoder runs at 48 kHz regardless. 49 50 int version = aData[8]; 51 // Accept file format versions 0.x. 52 if ((version & 0xf0) != 0) { 53 OPUS_LOG(LogLevel::Debug, 54 ("Rejecting unknown Opus file version %d", version)); 55 return false; 56 } 57 58 mChannels = aData[9]; 59 if (mChannels < 1) { 60 OPUS_LOG(LogLevel::Debug, 61 ("Invalid Opus file: Number of channels %d", mChannels)); 62 return false; 63 } 64 65 mPreSkip = LittleEndian::readUint16(aData + 10); 66 mNominalRate = LittleEndian::readUint32(aData + 12); 67 double gain_dB = LittleEndian::readInt16(aData + 16) / 256.0; 68 #ifdef MOZ_SAMPLE_TYPE_FLOAT32 69 mGain = static_cast<float>(pow(10, 0.05 * gain_dB)); 70 #else 71 mGain_Q16 = static_cast<int32_t>(std::min( 72 65536 * pow(10, 0.05 * gain_dB) + 0.5, static_cast<double>(INT32_MAX))); 73 #endif 74 mChannelMapping = aData[18]; 75 76 if (mChannelMapping == 0) { 77 // Mapping family 0 only allows two channels 78 if (mChannels > 2) { 79 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: too many channels (%d) for" 80 " mapping family 0.", 81 mChannels)); 82 return false; 83 } 84 mStreams = 1; 85 mCoupledStreams = mChannels - 1; 86 mMappingTable[0] = 0; 87 mMappingTable[1] = 1; 88 } else if (mChannelMapping == 1 || mChannelMapping == 2 || 89 mChannelMapping == 255) { 90 // Currently only up to 8 channels are defined for mapping family 1 91 if (mChannelMapping == 1 && mChannels > 8) { 92 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: too many channels (%d) for" 93 " mapping family 1.", 94 mChannels)); 95 return false; 96 } 97 if (mChannelMapping == 2) { 98 if (!IsValidMapping2ChannelsCount(mChannels)) { 99 return false; 100 } 101 } 102 if (aLength > static_cast<unsigned>(20 + mChannels)) { 103 mStreams = aData[19]; 104 mCoupledStreams = aData[20]; 105 int i; 106 for (i = 0; i < mChannels; i++) { 107 mMappingTable[i] = aData[21 + i]; 108 } 109 } else { 110 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: channel mapping %d," 111 " but no channel mapping table", 112 mChannelMapping)); 113 return false; 114 } 115 } else { 116 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: unsupported channel mapping " 117 "family %d", 118 mChannelMapping)); 119 return false; 120 } 121 if (mStreams < 1) { 122 OPUS_LOG(LogLevel::Debug, ("Invalid Opus file: no streams")); 123 return false; 124 } 125 if (mCoupledStreams > mStreams) { 126 OPUS_LOG(LogLevel::Debug, 127 ("Invalid Opus file: more coupled streams (%d) than " 128 "total streams (%d)", 129 mCoupledStreams, mStreams)); 130 return false; 131 } 132 133 #ifdef DEBUG 134 OPUS_LOG(LogLevel::Debug, ("Opus stream header:")); 135 OPUS_LOG(LogLevel::Debug, (" channels: %d", mChannels)); 136 OPUS_LOG(LogLevel::Debug, (" preskip: %d", mPreSkip)); 137 OPUS_LOG(LogLevel::Debug, (" original: %d Hz", mNominalRate)); 138 OPUS_LOG(LogLevel::Debug, (" gain: %.2f dB", gain_dB)); 139 OPUS_LOG(LogLevel::Debug, ("Channel Mapping:")); 140 OPUS_LOG(LogLevel::Debug, (" family: %d", mChannelMapping)); 141 OPUS_LOG(LogLevel::Debug, (" streams: %d", mStreams)); 142 #endif 143 return true; 144 } 145 146 bool OpusParser::DecodeTags(unsigned char* aData, size_t aLength) { 147 if (aLength < 16 || memcmp(aData, "OpusTags", 8) != 0) { 148 return false; 149 } 150 151 // Copy out the raw comment lines, but only do basic validation 152 // checks against the string packing: too little data, too many 153 // comments, or comments that are too long. Rejecting these cases 154 // helps reduce the propagation of broken files. 155 // We do not ensure they are valid UTF-8 here, nor do we validate 156 // the required ASCII_TAG=value format of the user comments. 157 const unsigned char* buf = aData + 8; 158 uint32_t bytes = aLength - 8; 159 uint32_t len; 160 // Read the vendor string. 161 len = LittleEndian::readUint32(buf); 162 buf += 4; 163 bytes -= 4; 164 if (len > bytes) return false; 165 mVendorString = nsCString(reinterpret_cast<const char*>(buf), len); 166 buf += len; 167 bytes -= len; 168 // Read the user comments. 169 if (bytes < 4) return false; 170 uint32_t ncomments = LittleEndian::readUint32(buf); 171 buf += 4; 172 bytes -= 4; 173 // If there are so many comments even their length fields 174 // won't fit in the packet, stop reading now. 175 if (ncomments > (bytes >> 2)) return false; 176 for (uint32_t i = 0; i < ncomments; i++) { 177 if (bytes < 4) return false; 178 len = LittleEndian::readUint32(buf); 179 buf += 4; 180 bytes -= 4; 181 if (len > bytes) return false; 182 mTags.AppendElement(nsCString(reinterpret_cast<const char*>(buf), len)); 183 buf += len; 184 bytes -= len; 185 } 186 187 #ifdef DEBUG 188 OPUS_LOG(LogLevel::Debug, ("Opus metadata header:")); 189 OPUS_LOG(LogLevel::Debug, (" vendor: %s", mVendorString.get())); 190 for (uint32_t i = 0; i < mTags.Length(); i++) { 191 OPUS_LOG(LogLevel::Debug, (" %s", mTags[i].get())); 192 } 193 #endif 194 return true; 195 } 196 197 /* static */ 198 bool OpusParser::IsValidMapping2ChannelsCount(uint8_t aChannels) { 199 // https://tools.ietf.org/html/draft-ietf-codec-ambisonics-08#page-4 200 // For both channel mapping family 2 and family 3, the allowed numbers 201 // of channels: (1 + n)^2 + 2j for n = 0, 1, ..., 14 and j = 0 or 1, 202 // where n denotes the (highest) ambisonic order and j denotes whether 203 // or not there is a separate non-diegetic stereo stream Explicitly the 204 // allowed number of channels are 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36, 205 // 38, 49, 51, 64, 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171, 206 // 196, 198, 225, and 227. 207 208 // We use the property that int(sqrt(n)) == int(sqrt(n+2)) for n != 3 209 // which is handled by the test n^2 + 2 != channel 210 if (aChannels < 1 || aChannels > 227) { 211 return false; 212 } 213 double val = sqrt(aChannels); 214 int32_t valInt = int32_t(val); 215 return val == valInt || valInt * valInt + 2 == aChannels; 216 } 217 218 #undef OPUS_LOG 219 220 } // namespace mozilla