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