Shaka Packager SDK
Loading...
Searching...
No Matches
ac3_header.cc
1// Copyright 2017 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/ac3_header.h>
8
9#include <cstddef>
10#include <cstdint>
11#include <iterator>
12#include <vector>
13
14#include <absl/log/check.h>
15
16#include <packager/media/base/bit_reader.h>
17#include <packager/media/base/bit_writer.h>
18#include <packager/media/formats/mp2t/mp2t_common.h>
19
20namespace shaka {
21namespace media {
22namespace mp2t {
23namespace {
24
25// ASTC Standard A/52:2012 Table 5.6 Sample Rate Codes.
26const uint32_t kAc3SampleRateTable[] = {48000, 44100, 32000};
27
28// ASTC Standard A/52:2012 Table 5.8 Audio Coding Mode.
29const uint8_t kAc3NumChannelsTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
30
31// ATSC Standard A/52:2012 Table 5.18 Frame Size Code Table
32// (in words = 16 bits).
33const size_t kFrameSizeCodeTable[][3] = {
34 // {32kHz, 44.1kHz, 48kHz}
35 {96, 69, 64}, {96, 70, 64}, {120, 87, 80},
36 {120, 88, 80}, {144, 104, 96}, {144, 105, 96},
37 {168, 121, 112}, {168, 122, 112}, {192, 139, 128},
38 {192, 140, 128}, {240, 174, 160}, {240, 175, 160},
39 {288, 208, 192}, {288, 209, 192}, {336, 243, 224},
40 {336, 244, 224}, {384, 278, 256}, {384, 279, 256},
41 {480, 348, 320}, {480, 349, 320}, {576, 417, 384},
42 {576, 418, 384}, {672, 487, 448}, {672, 488, 448},
43 {768, 557, 512}, {768, 558, 512}, {960, 696, 640},
44 {960, 697, 640}, {1152, 835, 768}, {1152, 836, 768},
45 {1344, 975, 896}, {1344, 976, 896}, {1536, 1114, 1024},
46 {1536, 1115, 1024}, {1728, 1253, 1152}, {1728, 1254, 1152},
47 {1920, 1393, 1280}, {1920, 1394, 1280},
48};
49
50// Calculate the size of the frame from the sample rate code and the
51// frame size code.
52// @return the size of the frame (header + payload).
53size_t CalcFrameSize(uint8_t fscod, uint8_t frmsizecod) {
54 const size_t kNumFscode = std::size(kAc3SampleRateTable);
55 DCHECK_LT(fscod, kNumFscode);
56 DCHECK_LT(frmsizecod, std::size(kFrameSizeCodeTable));
57 // The order of frequencies are reversed in |kFrameSizeCodeTable| compared to
58 // |kAc3SampleRateTable|.
59 const int index = kNumFscode - 1 - fscod;
60 return kFrameSizeCodeTable[frmsizecod][index] * 2;
61}
62
63} // namespace
64
65bool Ac3Header::IsSyncWord(const uint8_t* buf) const {
66 DCHECK(buf);
67 // ATSC Standard A/52:2012 5.4.1 syncinfo: Synchronization Information.
68 return buf[0] == 0x0B && buf[1] == 0x77;
69}
70
72 // Arbitrary. Actual frame size starts with 96 words.
73 const size_t kMinAc3FrameSize = 10u;
74 return kMinAc3FrameSize;
75}
76
78 // ATSC Standard A/52:2012
79 // Annex A: AC-3 Elementary Streams in the MPEG-2 Multiplex.
80 const size_t kSamplesPerAc3Frame = 1536;
81 return kSamplesPerAc3Frame;
82}
83
84bool Ac3Header::Parse(const uint8_t* audio_frame, size_t audio_frame_size) {
85 BitReader frame(audio_frame, audio_frame_size);
86
87 // ASTC Standard A/52:2012 5. BIT STREAM SYNTAX.
88 // syncinfo: synchronization information section.
89 uint16_t syncword;
90 RCHECK(frame.ReadBits(16, &syncword));
91 RCHECK(syncword == 0x0B77);
92 uint16_t crc1;
93 RCHECK(frame.ReadBits(16, &crc1));
94 RCHECK(frame.ReadBits(2, &fscod_));
95 RCHECK(fscod_ < std::size(kAc3SampleRateTable));
96 RCHECK(frame.ReadBits(6, &frmsizecod_));
97 RCHECK(frmsizecod_ < std::size(kFrameSizeCodeTable));
98
99 // bsi: bit stream information section.
100 RCHECK(frame.ReadBits(5, &bsid_));
101 RCHECK(frame.ReadBits(3, &bsmod_));
102
103 RCHECK(frame.ReadBits(3, &acmod_));
104 RCHECK(acmod_ < std::size(kAc3NumChannelsTable));
105 // If 3 front channels.
106 if ((acmod_ & 0x01) && (acmod_ != 0x01))
107 RCHECK(frame.SkipBits(2)); // cmixlev.
108 // If a surround channel exists.
109 if (acmod_ & 0x04)
110 RCHECK(frame.SkipBits(2)); // surmixlev.
111 // If in 2/0 mode.
112 if (acmod_ == 0x02)
113 RCHECK(frame.SkipBits(2)); // dsurmod.
114
115 RCHECK(frame.ReadBits(1, &lfeon_));
116
117 return true;
118}
119
121 // Unlike ADTS, for AC3, the whole frame is included in the media sample, so
122 // return 0 header size.
123 return 0;
124}
125
127 return CalcFrameSize(fscod_, frmsizecod_);
128}
129
130size_t Ac3Header::GetFrameSizeWithoutParsing(const uint8_t* data,
131 size_t num_bytes) const {
132 DCHECK_GT(num_bytes, static_cast<size_t>(4));
133 uint8_t fscod = data[4] >> 6;
134 uint8_t frmsizecod = data[4] & 0x3f;
135 return CalcFrameSize(fscod, frmsizecod);
136}
137
138void Ac3Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
139 DCHECK(buffer);
140 buffer->clear();
141 BitWriter config(buffer);
142 // Accoding to ETSI TS 102 366 V1.3.1 (2014-08) F.4 AC3SpecificBox.
143 config.WriteBits(fscod_, 2);
144 config.WriteBits(bsid_, 5);
145 config.WriteBits(bsmod_, 3);
146 config.WriteBits(acmod_, 3);
147 config.WriteBits(lfeon_, 1);
148 const uint8_t bit_rate_code = frmsizecod_ >> 1;
149 config.WriteBits(bit_rate_code, 5);
150 config.Flush();
151}
152
154 // Only useful for AAC. Return a dummy value instead.
155 return 0;
156}
157
159 DCHECK_LT(fscod_, std::size(kAc3SampleRateTable));
160 return kAc3SampleRateTable[fscod_];
161}
162
164 DCHECK_LT(acmod_, std::size(kAc3NumChannelsTable));
165 return kAc3NumChannelsTable[acmod_] + (lfeon_ ? 1 : 0);
166}
167
168} // namespace mp2t
169} // namespace media
170} // namespace shaka
A class to read bit streams.
Definition bit_reader.h:19
bool SkipBits(size_t num_bits)
Definition bit_reader.cc:28
bool ReadBits(size_t num_bits, T *out)
Definition bit_reader.h:37
void Flush()
Write pending bits, and align bitstream with extra zero bits.
Definition bit_writer.cc:37
void WriteBits(uint32_t bits, size_t number_of_bits)
Definition bit_writer.cc:21
bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
Definition ac3_header.cc:84
size_t GetMinFrameSize() const override
Definition ac3_header.cc:71
bool IsSyncWord(const uint8_t *buf) const override
Definition ac3_header.cc:65
uint8_t GetObjectType() const override
size_t GetHeaderSize() const override
size_t GetFrameSize() const override
size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
uint32_t GetSamplingFrequency() const override
uint8_t GetNumChannels() const override
size_t GetSamplesPerFrame() const override
Definition ac3_header.cc:77
All the methods that are virtual are virtual for mocking.