Shaka Packager SDK
mpeg1_header.cc
1 // Copyright 2023 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/mpeg1_header.h>
8 
9 #include <absl/log/check.h>
10 
11 #include <packager/media/base/bit_reader.h>
12 #include <packager/media/base/bit_writer.h>
13 #include <packager/media/formats/mp2t/mp2t_common.h>
14 
15 // Parsing is done according to
16 // https://www.datavoyage.com/mpgscript/mpeghdr.htm
17 namespace {
18 const size_t kMpeg1HeaderMinSize = 4;
19 
20 const uint8_t kMpeg1V_INV = 0b01; /* Invalid version */
21 const uint8_t kMpeg1L_INV = 0b00; /* Invalid layer */
22 
23 const uint8_t kMpeg1L_3 = 0b01;
24 const uint8_t kMpeg1L_2 = 0b10;
25 const uint8_t kMpeg1L_1 = 0b11;
26 
27 const size_t kMpeg1SamplesPerFrameTable[] = {
28  // L1, L2, L3
29  384, 1152, 1152};
30 
31 const uint32_t kMpeg1SampleRateTable[][3] = {
32  // clang-format off
33  // V1, V2, V2.5
34  {44100, 22050, 11025},
35  {48000, 24000, 12000},
36  {32000, 16000, 8000}};
37  // clang-format on
38 const size_t kMpeg1SampleRateTableSize = std::size(kMpeg1SampleRateTable);
39 
40 static inline uint32_t Mpeg1SampleRate(uint8_t sr_idx, uint8_t version) {
41  static int sr_version_indexes[] = {2, -1, 1, 0}; // {V2.5, RESERVED, V2, V1}
42  DCHECK_NE(version, 1);
43  DCHECK_LT(sr_idx, kMpeg1SampleRateTableSize);
44  return kMpeg1SampleRateTable[sr_idx][sr_version_indexes[version]];
45 }
46 
47 const uint32_t kMpeg1BitrateTable[][5] = {
48  // clang-format off
49  // V1:L1, V1:L2, V1:L3, V2:L1, V2&V2.5:L2&L3
50  { 0, 0, 0, 0, 0},
51  { 32, 32, 32, 32, 8},
52  { 64, 48, 40, 48, 16},
53  { 96, 56, 48, 56, 24},
54  { 128, 64, 56, 64, 32},
55  { 160, 80, 64, 80, 40},
56  { 192, 96, 80, 96, 48},
57  { 224, 112, 96, 112, 56},
58  { 256, 128, 112, 128, 64},
59  { 288, 160, 128, 144, 80},
60  { 320, 192, 160, 160, 96},
61  { 352, 224, 192, 176, 112},
62  { 384, 256, 224, 192, 128},
63  { 416, 320, 256, 224, 144},
64  { 448, 384, 320, 256, 160}};
65  // clang-format on
66 const size_t kMpeg1BitrateTableSize = std::size(kMpeg1BitrateTable);
67 
68 static inline uint32_t Mpeg1BitRate(uint8_t btr_idx,
69  uint8_t version,
70  uint8_t layer) {
71  static int btr_version_indexes[] = {1, -1, 1, 0}; // {V2.5, RESERVED, V2, V1}
72  static int btr_layer_indexes[] = {-1, 2, 1, 0}; // {RESERVED, L3, L2, L1}
73 
74  DCHECK_NE(version, 1);
75  DCHECK_NE(layer, 0);
76  int vidx = btr_version_indexes[version];
77  int lidx = btr_layer_indexes[layer];
78  if (vidx == 1 && lidx > 1)
79  lidx = 1;
80 
81  DCHECK_LT(vidx * 3 + lidx, 5);
82  DCHECK_LT(btr_idx, kMpeg1BitrateTableSize);
83  return kMpeg1BitrateTable[btr_idx][vidx * 3 + lidx] * 1000;
84 }
85 
86 static inline size_t Mpeg1FrameSize(uint8_t layer,
87  uint32_t bitrate,
88  uint32_t sample_rate,
89  uint8_t padded) {
90  DCHECK_GT(sample_rate, static_cast<uint32_t>(0));
91  if (layer == kMpeg1L_1)
92  return (12 * bitrate / sample_rate + padded) * 4;
93  return 144 * bitrate / sample_rate + padded;
94 }
95 
96 } // namespace
97 
98 namespace shaka {
99 namespace media {
100 namespace mp2t {
101 
102 bool Mpeg1Header::IsSyncWord(const uint8_t* buf) const {
103  return (buf[0] == 0xff) &&
104  ((buf[1] & 0b11100000) == 0b11100000)
105  // Version 01 is reserved
106  && ((buf[1] & 0b00011000) != 0b00001000)
107  // Layer 00 is reserved
108  && ((buf[1] & 0b00000110) != 0b00000000);
109 }
110 
112  return kMpeg1HeaderMinSize + 1;
113 }
114 
116  static int spf_layer_indexes[] = {-1, 2, 1, 0}; // {RESERVED, L3, L2, L1}
117  DCHECK_NE(layer_, 0);
118  return kMpeg1SamplesPerFrameTable[spf_layer_indexes[layer_]];
119 }
120 
121 bool Mpeg1Header::Parse(const uint8_t* mpeg1_frame, size_t mpeg1_frame_size) {
122  DCHECK(mpeg1_frame);
123 
124  if (mpeg1_frame_size < kMpeg1HeaderMinSize)
125  return false;
126 
127  BitReader frame(mpeg1_frame, mpeg1_frame_size);
128  // Verify frame starts with sync bits (0x7ff).
129  uint32_t sync;
130  RCHECK(frame.ReadBits(11, &sync));
131  RCHECK(sync == 0x7ff);
132  // MPEG version and layer.
133  RCHECK(frame.ReadBits(2, &version_));
134  RCHECK(version_ != kMpeg1V_INV);
135  RCHECK(frame.ReadBits(2, &layer_));
136  RCHECK(layer_ != kMpeg1L_INV);
137  RCHECK(frame.ReadBits(1, &protection_absent_));
138 
139  uint8_t btr_idx;
140  RCHECK(frame.ReadBits(4, &btr_idx));
141  RCHECK(btr_idx > 0);
142  bitrate_ = Mpeg1BitRate(btr_idx, version_, layer_);
143 
144  uint8_t sr_idx;
145  RCHECK(frame.ReadBits(2, &sr_idx));
146  RCHECK(sr_idx < 0b11);
147  sample_rate_ = Mpeg1SampleRate(sr_idx, version_);
148 
149  RCHECK(frame.ReadBits(1, &padded_));
150  // Skip private stream bit.
151  RCHECK(frame.SkipBits(1));
152 
153  RCHECK(frame.ReadBits(2, &channel_mode_));
154  // Skip Mode extension
155  RCHECK(frame.SkipBits(2));
156  // Skip copyright, origination and emphasis info.
157  RCHECK(frame.SkipBits(4));
158 
159  return true;
160 }
161 
163  // Unlike ADTS, for MP3, the whole frame is included in the media sample, so
164  // return 0 header size.
165  return 0;
166 }
167 
169  return Mpeg1FrameSize(layer_, bitrate_, sample_rate_, padded_);
170 }
171 
172 size_t Mpeg1Header::GetFrameSizeWithoutParsing(const uint8_t* data,
173  size_t num_bytes) const {
174  DCHECK_GT(num_bytes, static_cast<size_t>(2));
175  uint8_t version = (data[1] & 0b00011000) >> 3;
176  uint8_t layer = (data[1] & 0b00000110) >> 1;
177  uint8_t btr_idx = (data[2] & 0b11110000) >> 4;
178  uint8_t sr_idx = (data[2] & 0b00001100) >> 2;
179  uint8_t padded = (data[2] & 0b00000010) >> 1;
180 
181  if ((version == kMpeg1V_INV) || (layer == kMpeg1L_INV) || (btr_idx == 0) ||
182  (sr_idx == 0b11))
183  return 0;
184 
185  uint32_t bitrate = Mpeg1BitRate(btr_idx, version, layer);
186  uint32_t samplerate = Mpeg1SampleRate(sr_idx, version);
187  return Mpeg1FrameSize(layer, bitrate, samplerate, padded);
188 }
189 
190 void Mpeg1Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
191  // The following conversion table is extracted from ISO 14496 Part 3 -
192  // Table 1.16 - Sampling Frequency Index.
193  static const size_t kConfigFrequencyTable[] = {
194  96000, 88200, 64000, 48000, 44100, 32000, 24000,
195  22050, 16000, 12000, 11025, 8000, 7350};
196  static const size_t kConfigFrequencyTableSize =
197  std::size(kConfigFrequencyTable);
198  uint8_t cft_idx;
199 
200  for (cft_idx = 0; cft_idx < kConfigFrequencyTableSize; cft_idx++)
201  if (sample_rate_ == kConfigFrequencyTable[cft_idx])
202  break;
203 
204  DCHECK(buffer);
205  buffer->clear();
206  BitWriter config(buffer);
207 
208  // ISO/IEC 14496:3 Table 1.16 Syntax of GetAudioObjetType()
209  auto object_type = GetObjectType();
210  if (object_type <= 31) {
211  config.WriteBits(object_type, 5);
212  } else {
213  config.WriteBits(31, 5);
214  config.WriteBits(object_type - 32, 6);
215  }
216 
217  config.WriteBits(cft_idx, 4);
218  /*
219  * NOTE: Number of channels matches channel_configuration index,
220  * since mpeg1 audio has only 1 or 2 channels
221  */
222  config.WriteBits(GetNumChannels(), 4);
223  config.Flush();
224 }
225 
226 uint8_t Mpeg1Header::GetObjectType() const {
227  /*
228  * ISO14496-3:2009 Table 1.17 - Audio Object Types
229  */
230  if (layer_ == kMpeg1L_1)
231  return 32;
232  if (layer_ == kMpeg1L_2)
233  return 33;
234 
235  DCHECK_EQ(layer_, kMpeg1L_3);
236  return 34;
237 }
238 
240  return sample_rate_;
241 }
242 
244  if (channel_mode_ == 0b11)
245  return 1;
246  return 2;
247 }
248 
249 } // namespace mp2t
250 } // namespace media
251 } // 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 GetMinFrameSize() const override
size_t GetFrameSize() const override
void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
bool IsSyncWord(const uint8_t *buf) const override
uint8_t GetObjectType() const override
uint8_t GetNumChannels() const override
size_t GetSamplesPerFrame() const override
uint32_t GetSamplingFrequency() const override
bool Parse(const uint8_t *mpeg1_frame, size_t mpeg1_frame_size) override
size_t GetHeaderSize() const override
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66