Shaka Packager SDK
ec3_audio_util.cc
1 // Copyright 2016 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/codecs/ec3_audio_util.h"
8 
9 #include "packager/base/macros.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/media/base/bit_reader.h"
12 #include "packager/media/base/rcheck.h"
13 
14 namespace shaka {
15 namespace media {
16 
17 namespace {
18 
19 // Channels bit map. 16 bits.
20 // Bit, Location
21 // 0(MSB), Left
22 // 1, Center
23 // 2, Right
24 // 3, Left Surround
25 // 4, Right Surround
26 // 5, Left center/Right center pair
27 // 6, Left rear surround/Right rear surround pair
28 // 7, Center surround
29 // 8, Top center surround
30 // 9, Left surround direct/Right surround direct pair
31 // 10, Left wide/Right wide pair
32 // 11, Lvertical height/Right vertical height pair
33 // 12, Center vertical height
34 // 13, Lts/Rts pair
35 // 14, LFE2
36 // 15, LFE
37 enum kEC3AudioChannelMap {
38  kLeft = 0x8000,
39  kCenter = 0x4000,
40  kRight = 0x2000,
41  kLeftSurround = 0x1000,
42  kRightSurround = 0x800,
43  kLcRcPair = 0x400,
44  kLrsRrsPair = 0x200,
45  kCenterSurround = 0x100,
46  kTopCenterSurround = 0x80,
47  kLsdRsdPair = 0x40,
48  kLwRwPair = 0x20,
49  kLvhRvhPair = 0x10,
50  kCenterVerticalHeight = 0x8,
51  kLtsRtsPair = 0x4,
52  kLFE2 = 0x2,
53  kLFEScreen = 0x1
54 };
55 // Number of channels for the channel bit above. The first entry corresponds to
56 // kLeft, which has one channel. All the XxxPairs bits have two channels.
57 const size_t kChannelCountArray[] = {
58  1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1,
59 };
60 static_assert(arraysize(kChannelCountArray) == 16u,
61  "Channel count array should have 16 entries.");
62 
63 // EC3 Audio coding mode map (acmod) to determine EC3 audio channel layout. The
64 // value stands for the existence of Left, Center, Right, Left surround, and
65 // Right surround.
66 const uint16_t kEC3AudioCodingModeMap[] = {
67  kLeft | kRight,
68  kCenter,
69  kLeft | kRight,
70  kLeft | kCenter | kRight,
71  kLeft | kRight | kLeftSurround | kRightSurround,
72  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
73  kLeft | kRight | kLeftSurround | kRightSurround,
74  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
75 };
76 
77 // Reverse bit order.
78 uint8_t ReverseBits8(uint8_t n) {
79  n = ((n >> 1) & 0x55) | ((n & 0x55) << 1);
80  n = ((n >> 2) & 0x33) | ((n & 0x33) << 2);
81  return ((n >> 4) & 0x0f) | ((n & 0x0f) << 4);
82 }
83 
84 // Mapping of channel configurations to the MPEG audio value based on
85 // ETSI TS 102 366 V1.4.1 Digital Audio Compression (AC-3, Enhanced AC-3)
86 // Standard Table I.1.1
87 uint32_t EC3ChannelMaptoMPEGValue(uint32_t channel_map) {
88  uint32_t ret = 0;
89 
90  switch (channel_map) {
91  case kCenter:
92  ret = 1;
93  break;
94  case kLeft | kRight:
95  ret = 2;
96  break;
97  case kCenter| kLeft | kRight:
98  ret = 3;
99  break;
100  case kCenter | kLeft | kRight | kCenterSurround:
101  ret = 4;
102  break;
103  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround:
104  ret = 5;
105  break;
106  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
107  kLFEScreen:
108  ret = 6;
109  break;
110  case kCenter | kLeft | kRight | kLwRwPair | kLeftSurround | kRightSurround |
111  kLFEScreen:
112  ret = 7;
113  break;
114  case kLeft | kRight | kCenterSurround:
115  ret = 9;
116  break;
117  case kLeft | kRight | kLeftSurround | kRightSurround:
118  ret = 10;
119  break;
120  case kCenter | kLeft | kRight | kLrsRrsPair | kCenterSurround | kLFEScreen:
121  ret = 11;
122  break;
123  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
124  kLrsRrsPair | kLFEScreen:
125  ret = 12;
126  break;
127  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
128  kLFEScreen | kLvhRvhPair:
129  ret = 14;
130  break;
131  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
132  kLFEScreen | kLvhRvhPair | kLtsRtsPair:
133  ret = 16;
134  break;
135  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
136  kLFEScreen | kLvhRvhPair | kCenterVerticalHeight | kLtsRtsPair |
137  kTopCenterSurround:
138  ret = 17;
139  break;
140  case kCenter | kLeft | kRight | kLsdRsdPair | kLrsRrsPair | kLFEScreen |
141  kLvhRvhPair | kLtsRtsPair:
142  ret = 19;
143  break;
144  default:
145  ret = 0xFFFFFFFF;
146  }
147  return ret;
148 }
149 
150 bool ExtractEc3Data(const std::vector<uint8_t>& ec3_data,
151  uint8_t* audio_coding_mode,
152  bool* lfe_channel_on,
153  uint16_t* dependent_substreams_layout,
154  uint32_t* ec3_joc_complexity) {
155  BitReader bit_reader(ec3_data.data(), ec3_data.size());
156  // Read number of independent substreams and parse the independent substreams.
157  uint8_t number_independent_substreams;
158  RCHECK(bit_reader.SkipBits(13) &&
159  bit_reader.ReadBits(3, &number_independent_substreams));
160  // The value of this field is one less than the number of independent
161  // substreams present.
162  ++number_independent_substreams;
163 
164  // Parse audio_coding_mode, dependent_substreams_layout and lfe_channel_on
165  // from the first independent substream.
166  // Independent substream in EC3Specific box:
167  // fscod: 2 bits
168  // bsid: 5 bits
169  // reserved_1: 1 bit
170  // asvc: 1 bit
171  // bsmod: 3 bits
172  // acmod: 3 bits
173  // lfeon: 1 bit
174  // reserved_2: 3 bits
175  // num_dep_sub: 4 bits
176  // If num_dep_sub > 0, chan_loc is present and the size is 9 bits.
177  // Otherwise, reserved_3 is present and the size is 1 bit.
178  // chan_loc: 9 bits
179  // reserved_3: 1 bit
180  RCHECK(bit_reader.SkipBits(12));
181  RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
182  RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
183 
184  uint8_t number_dependent_substreams = 0;
185  RCHECK(bit_reader.SkipBits(3));
186  RCHECK(bit_reader.ReadBits(4, &number_dependent_substreams));
187 
188  *dependent_substreams_layout = 0;
189  if (number_dependent_substreams > 0) {
190  RCHECK(bit_reader.ReadBits(9, dependent_substreams_layout));
191  } else {
192  RCHECK(bit_reader.SkipBits(1));
193  }
194  *ec3_joc_complexity = 0;
195  if (bit_reader.bits_available() < 16) {
196  return true;
197  }
198 
199  RCHECK(bit_reader.SkipBits(7));
200  bool ec3_joc_flag;
201  RCHECK(bit_reader.ReadBits(1, &ec3_joc_flag));
202  if (ec3_joc_flag) {
203  RCHECK(bit_reader.ReadBits(8, ec3_joc_complexity));
204  }
205  return true;
206 }
207 
208 } // namespace
209 
210 bool CalculateEC3ChannelMap(const std::vector<uint8_t>& ec3_data,
211  uint32_t* channel_map) {
212  uint8_t audio_coding_mode;
213  bool lfe_channel_on;
214  uint16_t dependent_substreams_layout;
215  uint32_t ec3_joc_complexity;
216  if (!ExtractEc3Data(ec3_data, &audio_coding_mode, &lfe_channel_on,
217  &dependent_substreams_layout, &ec3_joc_complexity)) {
218  LOG(WARNING) << "Seeing invalid EC3 data: "
219  << base::HexEncode(ec3_data.data(), ec3_data.size());
220  return false;
221  }
222 
223  // Dependent substreams layout bit map:
224  // Bit, Location
225  // 0, Lc/Rc pair
226  // 1, Lrs/Rrs pair
227  // 2, Cs
228  // 3, Ts
229  // 4, Lsd/Rsd pair
230  // 5, Lw/Rw pair
231  // 6, Lvh/Rvh pair
232  // 7, Cvh
233  // 8(MSB), LFE2
234  // Reverse bit order of dependent substreams channel layout (LFE2 not
235  // included) to apply on channel_map bit 5 - 12.
236  const uint8_t reversed_dependent_substreams_layout =
237  ReverseBits8(dependent_substreams_layout & 0xFF);
238 
239  *channel_map = kEC3AudioCodingModeMap[audio_coding_mode] |
240  (reversed_dependent_substreams_layout << 3);
241  if (dependent_substreams_layout & 0x100)
242  *channel_map |= kLFE2;
243  if (lfe_channel_on)
244  *channel_map |= kLFEScreen;
245  return true;
246 }
247 
248 bool CalculateEC3ChannelMPEGValue(const std::vector<uint8_t>& ec3_data,
249  uint32_t* ec3_channel_mpeg_value) {
250  uint32_t channel_map;
251  if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
252  return false;
253  *ec3_channel_mpeg_value = EC3ChannelMaptoMPEGValue(channel_map);
254  return true;
255 }
256 
257 size_t GetEc3NumChannels(const std::vector<uint8_t>& ec3_data) {
258  uint32_t channel_map;
259  if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
260  return 0;
261 
262  size_t num_channels = 0;
263  int bit = kLeft;
264  for (size_t channel_count : kChannelCountArray) {
265  if (channel_map & bit)
266  num_channels += channel_count;
267  bit >>= 1;
268  }
269  DCHECK_EQ(bit, 0);
270  return num_channels;
271 }
272 
273 bool GetEc3JocComplexity(const std::vector<uint8_t>& ec3_data,
274  uint32_t* ec3_joc_complexity) {
275  uint8_t audio_coding_mode;
276  bool lfe_channel_on;
277  uint16_t dependent_substreams_layout;
278 
279  if (!ExtractEc3Data(ec3_data, &audio_coding_mode, &lfe_channel_on,
280  &dependent_substreams_layout, ec3_joc_complexity)) {
281  LOG(WARNING) << "Seeing invalid EC3 data: "
282  << base::HexEncode(ec3_data.data(), ec3_data.size());
283  return false;
284  }
285  return true;
286 }
287 
288 } // namespace media
289 } // namespace shaka
shaka
All the methods that are virtual are virtual for mocking.
Definition: gflags_hex_bytes.cc:11