Adts.h (4782B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef ADTS_H_ 6 #define ADTS_H_ 7 8 #include <stdint.h> 9 10 #include "MediaData.h" 11 #include "mozilla/Result.h" 12 13 namespace mozilla { 14 class MediaRawData; 15 16 namespace ADTS { 17 18 // adts::FrameHeader - Holds the ADTS frame header and its parsing 19 // state. 20 // 21 // ADTS Frame Structure 22 // 23 // 11111111 1111BCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP(QQQQQQQQ 24 // QQQQQQQQ) 25 // 26 // Header consists of 7 or 9 bytes(without or with CRC). 27 // Letter Length(bits) Description 28 // { sync } 12 syncword 0xFFF, all bits must be 1 29 // B 1 MPEG Version: 0 for MPEG-4, 1 for MPEG-2 30 // C 2 Layer: always 0 31 // D 1 protection absent, Warning, set to 1 if there is no 32 // CRC and 0 if there is CRC 33 // E 2 profile, the MPEG-4 Audio Object Type minus 1 34 // F 4 MPEG-4 Sampling Frequency Index (15 is forbidden) 35 // H 3 MPEG-4 Channel Configuration (in the case of 0, the 36 // channel configuration is sent via an in-band PCE) 37 // M 13 frame length, this value must include 7 or 9 bytes of 38 // header length: FrameLength = 39 // (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame) 40 // O 11 Buffer fullness 41 // P 2 Number of AAC frames(RDBs) in ADTS frame minus 1, for 42 // maximum compatibility always use 1 AAC frame per ADTS 43 // frame 44 // Q 16 CRC if protection absent is 0 45 class FrameHeader { 46 public: 47 uint32_t mFrameLength{}; 48 uint32_t mSampleRate{}; 49 uint32_t mSamples{}; 50 uint32_t mChannels{}; 51 uint8_t mObjectType{}; 52 uint8_t mSamplingIndex{}; 53 uint8_t mChannelConfig{}; 54 uint8_t mNumAACFrames{}; 55 bool mHaveCrc{}; 56 57 // Returns whether aPtr matches a valid ADTS header sync marker 58 static bool MatchesSync(const Span<const uint8_t>& aData); 59 FrameHeader(); 60 // Header size 61 uint64_t HeaderSize() const; 62 bool IsValid() const; 63 // Resets the state to allow for a new parsing session. 64 void Reset(); 65 66 // Returns whether the byte creates a valid sequence up to this point. 67 bool Parse(const Span<const uint8_t>& aData); 68 }; 69 class Frame { 70 public: 71 Frame(); 72 73 uint64_t Offset() const; 74 size_t Length() const; 75 // Returns the offset to the start of frame's raw data. 76 uint64_t PayloadOffset() const; 77 78 size_t PayloadLength() const; 79 // Returns the parsed frame header. 80 const FrameHeader& Header() const; 81 bool IsValid() const; 82 // Resets the frame header and data. 83 void Reset(); 84 // Returns whether the valid 85 bool Parse(uint64_t aOffset, const uint8_t* aStart, const uint8_t* aEnd); 86 87 private: 88 // The offset to the start of the header. 89 uint64_t mOffset; 90 // The currently parsed frame header. 91 FrameHeader mHeader; 92 }; 93 94 class FrameParser { 95 public: 96 // Returns the currently parsed frame. Reset via Reset or EndFrameSession. 97 const Frame& CurrentFrame(); 98 // Returns the first parsed frame. Reset via Reset. 99 const Frame& FirstFrame() const; 100 // Resets the parser. Don't use between frames as first frame data is reset. 101 void Reset(); 102 // Clear the last parsed frame to allow for next frame parsing, i.e.: 103 // - sets PrevFrame to CurrentFrame 104 // - resets the CurrentFrame 105 // - resets ID3Header if no valid header was parsed yet 106 void EndFrameSession(); 107 // Parses contents of given ByteReader for a valid frame header and returns 108 // true if one was found. After returning, the variable passed to 109 // 'aBytesToSkip' holds the amount of bytes to be skipped (if any) in order to 110 // jump across a large ID3v2 tag spanning multiple buffers. 111 bool Parse(uint64_t aOffset, const uint8_t* aStart, const uint8_t* aEnd); 112 113 private: 114 // We keep the first parsed frame around for static info access, the 115 // previously parsed frame for debugging and the currently parsed frame. 116 Frame mFirstFrame; 117 Frame mFrame; 118 }; 119 120 // Extract the audiospecificconfig from an ADTS header 121 void InitAudioSpecificConfig(const Frame& aFrame, MediaByteBuffer* aBuffer); 122 bool StripHeader(MediaRawData* aSample); 123 Result<uint8_t, bool> GetFrequencyIndex(uint32_t aSamplesPerSecond); 124 bool ConvertSample(uint16_t aChannelCount, uint8_t aFrequencyIndex, 125 uint8_t aProfile, mozilla::MediaRawData* aSample); 126 bool RevertSample(MediaRawData* aSample); 127 Result<already_AddRefed<MediaByteBuffer>, nsresult> MakeSpecificConfig( 128 uint8_t aObjectType, uint32_t aFrequency, uint32_t aChannelCount); 129 } // namespace ADTS 130 } // namespace mozilla 131 132 #endif