7 #include "packager/media/codecs/ec3_audio_util.h"
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"
37 enum kEC3AudioChannelMap {
41 kLeftSurround = 0x1000,
42 kRightSurround = 0x800,
45 kCenterSurround = 0x100,
46 kTopCenterSurround = 0x80,
50 kCenterVerticalHeight = 0x8,
57 const size_t kChannelCountArray[] = {
58 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1,
60 static_assert(arraysize(kChannelCountArray) == 16u,
61 "Channel count array should have 16 entries.");
66 const uint16_t kEC3AudioCodingModeMap[] = {
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,
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);
87 uint32_t EC3ChannelMaptoMPEGValue(uint32_t channel_map) {
90 switch (channel_map) {
97 case kCenter| kLeft | kRight:
100 case kCenter | kLeft | kRight | kCenterSurround:
103 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround:
106 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
110 case kCenter | kLeft | kRight | kLwRwPair | kLeftSurround | kRightSurround |
114 case kLeft | kRight | kCenterSurround:
117 case kLeft | kRight | kLeftSurround | kRightSurround:
120 case kCenter | kLeft | kRight | kLrsRrsPair | kCenterSurround | kLFEScreen:
123 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
124 kLrsRrsPair | kLFEScreen:
127 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
128 kLFEScreen | kLvhRvhPair:
131 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
132 kLFEScreen | kLvhRvhPair | kLtsRtsPair:
135 case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
136 kLFEScreen | kLvhRvhPair | kCenterVerticalHeight | kLtsRtsPair |
140 case kCenter | kLeft | kRight | kLsdRsdPair | kLrsRrsPair | kLFEScreen |
141 kLvhRvhPair | kLtsRtsPair:
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());
157 uint8_t number_independent_substreams;
158 RCHECK(bit_reader.SkipBits(13) &&
159 bit_reader.ReadBits(3, &number_independent_substreams));
162 ++number_independent_substreams;
180 RCHECK(bit_reader.SkipBits(12));
181 RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
182 RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
184 uint8_t number_dependent_substreams = 0;
185 RCHECK(bit_reader.SkipBits(3));
186 RCHECK(bit_reader.ReadBits(4, &number_dependent_substreams));
188 *dependent_substreams_layout = 0;
189 if (number_dependent_substreams > 0) {
190 RCHECK(bit_reader.ReadBits(9, dependent_substreams_layout));
192 RCHECK(bit_reader.SkipBits(1));
194 *ec3_joc_complexity = 0;
195 if (bit_reader.bits_available() < 16) {
199 RCHECK(bit_reader.SkipBits(7));
201 RCHECK(bit_reader.ReadBits(1, &ec3_joc_flag));
203 RCHECK(bit_reader.ReadBits(8, ec3_joc_complexity));
210 bool CalculateEC3ChannelMap(
const std::vector<uint8_t>& ec3_data,
211 uint32_t* channel_map) {
212 uint8_t audio_coding_mode;
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());
236 const uint8_t reversed_dependent_substreams_layout =
237 ReverseBits8(dependent_substreams_layout & 0xFF);
239 *channel_map = kEC3AudioCodingModeMap[audio_coding_mode] |
240 (reversed_dependent_substreams_layout << 3);
241 if (dependent_substreams_layout & 0x100)
242 *channel_map |= kLFE2;
244 *channel_map |= kLFEScreen;
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))
253 *ec3_channel_mpeg_value = EC3ChannelMaptoMPEGValue(channel_map);
257 size_t GetEc3NumChannels(
const std::vector<uint8_t>& ec3_data) {
258 uint32_t channel_map;
259 if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
262 size_t num_channels = 0;
264 for (
size_t channel_count : kChannelCountArray) {
265 if (channel_map & bit)
266 num_channels += channel_count;
273 bool GetEc3JocComplexity(
const std::vector<uint8_t>& ec3_data,
274 uint32_t* ec3_joc_complexity) {
275 uint8_t audio_coding_mode;
277 uint16_t dependent_substreams_layout;
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());