Shaka Packager SDK
adts_header.cc
1 // Copyright 2014 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <packager/media/formats/mp2t/adts_header.h>
8 
9 #include <absl/log/check.h>
10 
11 #include <packager/macros/logging.h>
12 #include <packager/media/base/bit_reader.h>
13 #include <packager/media/base/bit_writer.h>
14 #include <packager/media/formats/mp2t/mp2t_common.h>
15 
16 namespace {
17 const size_t kAdtsHeaderMinSize = 7;
18 
19 // The following conversion table is extracted from ISO 14496 Part 3 -
20 // Table 1.16 - Sampling Frequency Index.
21 const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100,
22  32000, 24000, 22050, 16000, 12000,
23  11025, 8000, 7350};
24 const size_t kAdtsFrequencyTableSize = std::size(kAdtsFrequencyTable);
25 
26 // The following conversion table is extracted from ISO 14496 Part 3 -
27 // Table 1.17 - Channel Configuration.
28 const int kAdtsNumChannelsTable[] = {0, 1, 2, 3, 4, 5, 6, 8};
29 const size_t kAdtsNumChannelsTableSize = std::size(kAdtsNumChannelsTable);
30 } // namespace
31 
32 namespace shaka {
33 namespace media {
34 namespace mp2t {
35 
36 bool AdtsHeader::IsSyncWord(const uint8_t* buf) const {
37  return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
38 }
39 
41  return kAdtsHeaderMinSize + 1;
42 }
43 
45  const size_t kSamplesPerAacFrame = 1024;
46  return kSamplesPerAacFrame;
47 }
48 
49 bool AdtsHeader::Parse(const uint8_t* adts_frame, size_t adts_frame_size) {
50  CHECK(adts_frame);
51 
52  if (adts_frame_size < kAdtsHeaderMinSize)
53  return false;
54 
55  BitReader frame(adts_frame, adts_frame_size);
56  // Verify frame starts with sync bits (0xfff).
57  uint32_t sync;
58  RCHECK(frame.ReadBits(12, &sync));
59  RCHECK(sync == 0xfff);
60  // Skip MPEG version and layer.
61  RCHECK(frame.SkipBits(3));
62  RCHECK(frame.ReadBits(1, &protection_absent_));
63  RCHECK(frame.ReadBits(2, &profile_));
64  RCHECK(frame.ReadBits(4, &sampling_frequency_index_));
65  RCHECK(sampling_frequency_index_ < kAdtsFrequencyTableSize);
66  // Skip private stream bit.
67  RCHECK(frame.SkipBits(1));
68  RCHECK(frame.ReadBits(3, &channel_configuration_));
69  RCHECK(channel_configuration_ < kAdtsNumChannelsTableSize);
70  // Skip originality, home and copyright info.
71  RCHECK(frame.SkipBits(4));
72  RCHECK(frame.ReadBits(13, &frame_size_));
73  // Skip buffer fullness indicator.
74  RCHECK(frame.SkipBits(11));
75  uint8_t num_blocks_minus_1;
76  RCHECK(frame.ReadBits(2, &num_blocks_minus_1));
77  if (num_blocks_minus_1) {
78  NOTIMPLEMENTED() << "ADTS frames with more than one data block "
79  "not supported.";
80  return false;
81  }
82  return true;
83 }
84 
85 size_t AdtsHeader::GetHeaderSize() const {
86  const size_t kCrcSize = sizeof(uint16_t);
87  return kAdtsHeaderMinSize + (protection_absent_ ? 0 : kCrcSize);
88 }
89 
90 size_t AdtsHeader::GetFrameSize() const {
91  return frame_size_;
92 }
93 
94 size_t AdtsHeader::GetFrameSizeWithoutParsing(const uint8_t* data,
95  size_t num_bytes) const {
96  DCHECK_GT(num_bytes, static_cast<size_t>(5));
97  return ((static_cast<int>(data[5]) >> 5) | (static_cast<int>(data[4]) << 3) |
98  ((static_cast<int>(data[3]) & 0x3) << 11));
99 }
100 
101 void AdtsHeader::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
102  DCHECK(buffer);
103  buffer->clear();
104  BitWriter config(buffer);
105  config.WriteBits(GetObjectType(), 5);
106  config.WriteBits(sampling_frequency_index_, 4);
107  config.WriteBits(channel_configuration_, 4);
108  config.Flush();
109 }
110 
111 uint8_t AdtsHeader::GetObjectType() const {
112  return profile_ + 1;
113 }
114 
116  DCHECK_LT(sampling_frequency_index_, kAdtsFrequencyTableSize);
117  return kAdtsFrequencyTable[sampling_frequency_index_];
118 }
119 
120 uint8_t AdtsHeader::GetNumChannels() const {
121  DCHECK_LT(channel_configuration_, kAdtsNumChannelsTableSize);
122  return kAdtsNumChannelsTable[channel_configuration_];
123 }
124 
125 } // namespace mp2t
126 } // namespace media
127 } // namespace shaka
A class to read bit streams.
Definition: bit_reader.h:20
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:26
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:38
void Flush()
Write pending bits, and align bitstream with extra zero bits.
Definition: bit_writer.cc:33
void WriteBits(uint32_t bits, size_t number_of_bits)
Definition: bit_writer.cc:17
size_t GetSamplesPerFrame() const override
Definition: adts_header.cc:44
uint8_t GetNumChannels() const override
Definition: adts_header.cc:120
void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
Definition: adts_header.cc:101
size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
Definition: adts_header.cc:94
size_t GetHeaderSize() const override
Definition: adts_header.cc:85
bool IsSyncWord(const uint8_t *buf) const override
Definition: adts_header.cc:36
bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
Definition: adts_header.cc:49
size_t GetMinFrameSize() const override
Definition: adts_header.cc:40
uint8_t GetObjectType() const override
Definition: adts_header.cc:111
size_t GetFrameSize() const override
Definition: adts_header.cc:90
uint32_t GetSamplingFrequency() const override
Definition: adts_header.cc:115
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66