Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | //#define LOG_NDEBUG 0 |
| 18 | #define LOG_TAG "AC4Parser" |
| 19 | |
| 20 | #include <inttypes.h> |
| 21 | #include <utils/Log.h> |
| 22 | #include <utils/misc.h> |
| 23 | |
| 24 | #include "AC4Parser.h" |
| 25 | |
| 26 | #define BOOLSTR(a) ((a)?"true":"false") |
| 27 | #define BYTE_ALIGN mBitReader.skipBits(mBitReader.numBitsLeft() % 8) |
| 28 | #define CHECK_BITS_LEFT(n) if (mBitReader.numBitsLeft() < n) {return false;} |
| 29 | |
| 30 | namespace android { |
| 31 | |
| 32 | AC4Parser::AC4Parser() { |
| 33 | } |
| 34 | |
| 35 | AC4DSIParser::AC4DSIParser(ABitReader &br) |
| 36 | : mBitReader(br){ |
| 37 | |
| 38 | mDSISize = mBitReader.numBitsLeft(); |
| 39 | } |
| 40 | |
| 41 | // ETSI TS 103 190-2 V1.1.1 (2015-09) Table 79: channel_mode |
| 42 | static const char *ChannelModes[] = { |
| 43 | "mono", |
| 44 | "stereo", |
| 45 | "3.0", |
| 46 | "5.0", |
| 47 | "5.1", |
| 48 | "7.0 (3/4/0)", |
| 49 | "7.1 (3/4/0.1)", |
| 50 | "7.0 (5/2/0)", |
| 51 | "7.1 (5/2/0.1)", |
| 52 | "7.0 (3/2/2)", |
| 53 | "7.1 (3/2/2.1)", |
| 54 | "7.0.4", |
| 55 | "7.1.4", |
| 56 | "9.0.4", |
| 57 | "9.1.4", |
| 58 | "22.2" |
| 59 | }; |
| 60 | |
| 61 | static const char* ContentClassifier[] = { |
| 62 | "Complete Main", |
| 63 | "Music and Effects", |
| 64 | "Visually Impaired", |
| 65 | "Hearing Impaired", |
| 66 | "Dialog", |
| 67 | "Commentary", |
| 68 | "Emergency", |
| 69 | "Voice Over" |
| 70 | }; |
| 71 | |
| 72 | bool AC4DSIParser::parseLanguageTag(uint32_t presentationID, uint32_t substreamID){ |
| 73 | CHECK_BITS_LEFT(6); |
| 74 | uint32_t n_language_tag_bytes = mBitReader.getBits(6); |
| 75 | if (n_language_tag_bytes < 2 || n_language_tag_bytes >= 42) { |
| 76 | return false; |
| 77 | } |
| 78 | CHECK_BITS_LEFT(n_language_tag_bytes * 8); |
| 79 | char language_tag_bytes[42]; // TS 103 190 part 1 4.3.3.8.7 |
| 80 | for (uint32_t i = 0; i < n_language_tag_bytes; i++) { |
| 81 | language_tag_bytes[i] = (char)mBitReader.getBits(8); |
| 82 | } |
| 83 | language_tag_bytes[n_language_tag_bytes] = 0; |
| 84 | ALOGV("%u.%u: language_tag = %s\n", presentationID, substreamID, language_tag_bytes); |
| 85 | |
| 86 | std::string language(language_tag_bytes, n_language_tag_bytes); |
| 87 | mPresentations[presentationID].mLanguage = language; |
| 88 | |
| 89 | return true; |
| 90 | } |
| 91 | |
| 92 | // TS 103 190-1 v1.2.1 E.5 and TS 103 190-2 v1.1.1 E.9 |
| 93 | bool AC4DSIParser::parseSubstreamDSI(uint32_t presentationID, uint32_t substreamID){ |
| 94 | CHECK_BITS_LEFT(5); |
| 95 | uint32_t channel_mode = mBitReader.getBits(5); |
| 96 | CHECK_BITS_LEFT(2); |
| 97 | uint32_t dsi_sf_multiplier = mBitReader.getBits(2); |
| 98 | CHECK_BITS_LEFT(1); |
| 99 | bool b_substream_bitrate_indicator = (mBitReader.getBits(1) == 1); |
| 100 | ALOGV("%u.%u: channel_mode = %u (%s)\n", presentationID, substreamID, channel_mode, |
| 101 | channel_mode < NELEM(ChannelModes) ? ChannelModes[channel_mode] : "reserved"); |
| 102 | ALOGV("%u.%u: dsi_sf_multiplier = %u\n", presentationID, |
| 103 | substreamID, dsi_sf_multiplier); |
| 104 | ALOGV("%u.%u: b_substream_bitrate_indicator = %s\n", presentationID, |
| 105 | substreamID, BOOLSTR(b_substream_bitrate_indicator)); |
| 106 | |
| 107 | if (b_substream_bitrate_indicator) { |
| 108 | CHECK_BITS_LEFT(5); |
| 109 | uint32_t substream_bitrate_indicator = mBitReader.getBits(5); |
| 110 | ALOGV("%u.%u: substream_bitrate_indicator = %u\n", presentationID, substreamID, |
| 111 | substream_bitrate_indicator); |
| 112 | } |
| 113 | if (channel_mode >= 7 && channel_mode <= 10) { |
| 114 | CHECK_BITS_LEFT(1); |
| 115 | uint32_t add_ch_base = mBitReader.getBits(1); |
| 116 | ALOGV("%u.%u: add_ch_base = %u\n", presentationID, substreamID, add_ch_base); |
| 117 | } |
| 118 | CHECK_BITS_LEFT(1); |
| 119 | bool b_content_type = (mBitReader.getBits(1) == 1); |
| 120 | ALOGV("%u.%u: b_content_type = %s\n", presentationID, substreamID, BOOLSTR(b_content_type)); |
| 121 | if (b_content_type) { |
| 122 | CHECK_BITS_LEFT(3); |
| 123 | uint32_t content_classifier = mBitReader.getBits(3); |
| 124 | ALOGV("%u.%u: content_classifier = %u (%s)\n", presentationID, substreamID, |
| 125 | content_classifier, ContentClassifier[content_classifier]); |
| 126 | |
| 127 | // For streams based on TS 103 190 part 1 the presentation level channel_mode doesn't |
| 128 | // exist and so we use the channel_mode from either the CM or M&E substream |
| 129 | // (they are mutually exclusive) |
| 130 | if (mPresentations[presentationID].mChannelMode == -1 && |
| 131 | (content_classifier == 0 || content_classifier == 1)) { |
| 132 | mPresentations[presentationID].mChannelMode = channel_mode; |
| 133 | } |
| 134 | mPresentations[presentationID].mContentClassifier = content_classifier; |
| 135 | CHECK_BITS_LEFT(1); |
| 136 | bool b_language_indicator = (mBitReader.getBits(1) == 1); |
| 137 | ALOGV("%u.%u: b_language_indicator = %s\n", presentationID, substreamID, |
| 138 | BOOLSTR(b_language_indicator)); |
| 139 | if (b_language_indicator) { |
| 140 | if (!parseLanguageTag(presentationID, substreamID)) { |
| 141 | return false; |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | return true; |
| 147 | } |
| 148 | |
| 149 | // ETSI TS 103 190-2 v1.1.1 section E.11 |
| 150 | bool AC4DSIParser::parseSubstreamGroupDSI(uint32_t presentationID, uint32_t groupID) |
| 151 | { |
| 152 | CHECK_BITS_LEFT(1); |
| 153 | bool b_substreams_present = (mBitReader.getBits(1) == 1); |
| 154 | CHECK_BITS_LEFT(1); |
| 155 | bool b_hsf_ext = (mBitReader.getBits(1) == 1); |
| 156 | CHECK_BITS_LEFT(1); |
| 157 | bool b_channel_coded = (mBitReader.getBits(1) == 1); |
| 158 | CHECK_BITS_LEFT(8); |
| 159 | uint32_t n_substreams = mBitReader.getBits(8); |
| 160 | ALOGV("%u.%u: b_substreams_present = %s\n", presentationID, groupID, |
| 161 | BOOLSTR(b_substreams_present)); |
| 162 | ALOGV("%u.%u: b_hsf_ext = %s\n", presentationID, groupID, BOOLSTR(b_hsf_ext)); |
| 163 | ALOGV("%u.%u: b_channel_coded = %s\n", presentationID, groupID, BOOLSTR(b_channel_coded)); |
| 164 | ALOGV("%u.%u: n_substreams = %u\n", presentationID, groupID, n_substreams); |
| 165 | |
| 166 | for (uint32_t i = 0; i < n_substreams; i++) { |
| 167 | CHECK_BITS_LEFT(2); |
| 168 | uint32_t dsi_sf_multiplier = mBitReader.getBits(2); |
| 169 | CHECK_BITS_LEFT(1); |
| 170 | bool b_substream_bitrate_indicator = (mBitReader.getBits(1) == 1); |
| 171 | ALOGV("%u.%u.%u: dsi_sf_multiplier = %u\n", presentationID, groupID, i, dsi_sf_multiplier); |
| 172 | ALOGV("%u.%u.%u: b_substream_bitrate_indicator = %s\n", presentationID, groupID, i, |
| 173 | BOOLSTR(b_substream_bitrate_indicator)); |
| 174 | |
| 175 | if (b_substream_bitrate_indicator) { |
| 176 | CHECK_BITS_LEFT(5); |
| 177 | uint32_t substream_bitrate_indicator = mBitReader.getBits(5); |
| 178 | ALOGV("%u.%u.%u: substream_bitrate_indicator = %u\n", presentationID, groupID, i, |
| 179 | substream_bitrate_indicator); |
| 180 | } |
| 181 | if (b_channel_coded) { |
| 182 | CHECK_BITS_LEFT(24); |
| 183 | uint32_t dsi_substream_channel_mask = mBitReader.getBits(24); |
| 184 | ALOGV("%u.%u.%u: dsi_substream_channel_mask = 0x%06x\n", presentationID, groupID, i, |
| 185 | dsi_substream_channel_mask); |
| 186 | } else { |
| 187 | CHECK_BITS_LEFT(1); |
| 188 | bool b_ajoc = (mBitReader.getBits(1) == 1); |
| 189 | ALOGV("%u.%u.%u: b_ajoc = %s\n", presentationID, groupID, i, BOOLSTR(b_ajoc)); |
| 190 | if (b_ajoc) { |
| 191 | CHECK_BITS_LEFT(1); |
| 192 | bool b_static_dmx = (mBitReader.getBits(1) == 1); |
| 193 | ALOGV("%u.%u.%u: b_static_dmx = %s\n", presentationID, groupID, i, |
| 194 | BOOLSTR(b_static_dmx)); |
| 195 | if (!b_static_dmx) { |
| 196 | CHECK_BITS_LEFT(4); |
| 197 | uint32_t n_dmx_objects_minus1 = mBitReader.getBits(4); |
| 198 | ALOGV("%u.%u.%u: n_dmx_objects_minus1 = %u\n", presentationID, groupID, i, |
| 199 | n_dmx_objects_minus1); |
| 200 | } |
| 201 | CHECK_BITS_LEFT(6); |
| 202 | uint32_t n_umx_objects_minus1 = mBitReader.getBits(6); |
| 203 | ALOGV("%u.%u.%u: n_umx_objects_minus1 = %u\n", presentationID, groupID, i, |
| 204 | n_umx_objects_minus1); |
| 205 | } |
| 206 | CHECK_BITS_LEFT(4); |
| 207 | mBitReader.skipBits(4); // objects_assignment_mask |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | CHECK_BITS_LEFT(1); |
| 212 | bool b_content_type = (mBitReader.getBits(1) == 1); |
| 213 | ALOGV("%u.%u: b_content_type = %s\n", presentationID, groupID, BOOLSTR(b_content_type)); |
| 214 | if (b_content_type) { |
| 215 | CHECK_BITS_LEFT(3); |
| 216 | uint32_t content_classifier = mBitReader.getBits(3); |
| 217 | ALOGV("%u.%u: content_classifier = %s (%u)\n", presentationID, groupID, |
| 218 | ContentClassifier[content_classifier], content_classifier); |
| 219 | |
| 220 | mPresentations[presentationID].mContentClassifier = content_classifier; |
| 221 | |
| 222 | CHECK_BITS_LEFT(1); |
| 223 | bool b_language_indicator = (mBitReader.getBits(1) == 1); |
| 224 | ALOGV("%u.%u: b_language_indicator = %s\n", presentationID, groupID, |
| 225 | BOOLSTR(b_language_indicator)); |
| 226 | |
| 227 | if (b_language_indicator) { |
| 228 | if (!parseLanguageTag(presentationID, groupID)) { |
| 229 | return false; |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | return true; |
| 235 | } |
| 236 | |
| 237 | bool AC4DSIParser::parseBitrateDsi() { |
| 238 | CHECK_BITS_LEFT(2 + 32 + 32); |
| 239 | mBitReader.skipBits(2); // bit_rate_mode |
| 240 | mBitReader.skipBits(32); // bit_rate |
| 241 | mBitReader.skipBits(32); // bit_rate_precision |
| 242 | |
| 243 | return true; |
| 244 | } |
| 245 | |
| 246 | // TS 103 190-1 section E.4 (ac4_dsi) and TS 103 190-2 section E.6 (ac4_dsi_v1) |
| 247 | bool AC4DSIParser::parse() { |
| 248 | CHECK_BITS_LEFT(3); |
| 249 | uint32_t ac4_dsi_version = mBitReader.getBits(3); |
| 250 | if (ac4_dsi_version > 1) { |
| 251 | ALOGE("error while parsing ac-4 dsi: only versions 0 and 1 are supported"); |
| 252 | return false; |
| 253 | } |
| 254 | |
| 255 | CHECK_BITS_LEFT(7 + 1 + 4 + 9); |
| 256 | uint32_t bitstream_version = mBitReader.getBits(7); |
| 257 | mBitReader.skipBits(1); // fs_index |
| 258 | mBitReader.skipBits(4); // frame_rate_index |
| 259 | uint32_t n_presentations = mBitReader.getBits(9); |
| 260 | |
| 261 | int32_t short_program_id = -1; |
| 262 | if (bitstream_version > 1) { |
ybai | 4d6916a | 2019-02-28 14:34:37 +0800 | [diff] [blame] | 263 | if (ac4_dsi_version == 0) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 264 | ALOGE("invalid ac4 dsi"); |
| 265 | return false; |
| 266 | } |
| 267 | CHECK_BITS_LEFT(1); |
| 268 | bool b_program_id = (mBitReader.getBits(1) == 1); |
| 269 | if (b_program_id) { |
| 270 | CHECK_BITS_LEFT(16 + 1); |
| 271 | short_program_id = mBitReader.getBits(16); |
| 272 | bool b_uuid = (mBitReader.getBits(1) == 1); |
| 273 | if (b_uuid) { |
| 274 | const uint32_t kAC4UUIDSizeInBytes = 16; |
| 275 | char program_uuid[kAC4UUIDSizeInBytes]; |
| 276 | CHECK_BITS_LEFT(kAC4UUIDSizeInBytes * 8); |
| 277 | for (uint32_t i = 0; i < kAC4UUIDSizeInBytes; i++) { |
| 278 | program_uuid[i] = (char)(mBitReader.getBits(8)); |
| 279 | } |
| 280 | ALOGV("UUID = %s", program_uuid); |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | if (ac4_dsi_version == 1) { |
| 286 | if (!parseBitrateDsi()) { |
| 287 | return false; |
| 288 | } |
| 289 | BYTE_ALIGN; |
| 290 | } |
| 291 | |
| 292 | for (uint32_t presentation = 0; presentation < n_presentations; presentation++) { |
| 293 | mPresentations[presentation].mProgramID = short_program_id; |
| 294 | // known as b_single_substream in ac4_dsi_version 0 |
| 295 | bool b_single_substream_group = false; |
| 296 | uint32_t presentation_config = 0, presentation_version = 0; |
| 297 | uint32_t pres_bytes = 0; |
ybai | 4d6916a | 2019-02-28 14:34:37 +0800 | [diff] [blame] | 298 | uint64_t start = 0; |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 299 | |
| 300 | if (ac4_dsi_version == 0) { |
| 301 | CHECK_BITS_LEFT(1 + 5 + 5); |
| 302 | b_single_substream_group = (mBitReader.getBits(1) == 1); |
| 303 | presentation_config = mBitReader.getBits(5); |
| 304 | presentation_version = mBitReader.getBits(5); |
| 305 | } else if (ac4_dsi_version == 1) { |
| 306 | CHECK_BITS_LEFT(8 + 8); |
| 307 | presentation_version = mBitReader.getBits(8); |
| 308 | pres_bytes = mBitReader.getBits(8); |
| 309 | if (pres_bytes == 0xff) { |
| 310 | CHECK_BITS_LEFT(16); |
| 311 | pres_bytes += mBitReader.getBits(16); |
| 312 | } |
| 313 | ALOGV("%u: pres_bytes = %u\n", presentation, pres_bytes); |
Previr Rangroo | 070f41e | 2018-11-22 18:33:57 +1100 | [diff] [blame] | 314 | if (presentation_version > 2) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 315 | CHECK_BITS_LEFT(pres_bytes * 8); |
| 316 | mBitReader.skipBits(pres_bytes * 8); |
| 317 | continue; |
| 318 | } |
ybai | 4d6916a | 2019-02-28 14:34:37 +0800 | [diff] [blame] | 319 | /* record a marker, less the size of the presentation_config */ |
| 320 | start = (mDSISize - mBitReader.numBitsLeft()) / 8; |
Previr Rangroo | 070f41e | 2018-11-22 18:33:57 +1100 | [diff] [blame] | 321 | // ac4_presentation_v0_dsi(), ac4_presentation_v1_dsi() and ac4_presentation_v2_dsi() |
| 322 | // all start with a presentation_config of 5 bits |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 323 | CHECK_BITS_LEFT(5); |
| 324 | presentation_config = mBitReader.getBits(5); |
| 325 | b_single_substream_group = (presentation_config == 0x1f); |
| 326 | } |
| 327 | |
| 328 | static const char *PresentationConfig[] = { |
| 329 | "Music&Effects + Dialog", |
| 330 | "Main + DE", |
| 331 | "Main + Associate", |
| 332 | "Music&Effects + Dialog + Associate", |
| 333 | "Main + DE + Associate", |
| 334 | "Arbitrary substream groups", |
| 335 | "EMDF only" |
| 336 | }; |
| 337 | ALOGV("%u: b_single_substream/group = %s\n", presentation, |
| 338 | BOOLSTR(b_single_substream_group)); |
| 339 | ALOGV("%u: presentation_version = %u\n", presentation, presentation_version); |
| 340 | ALOGV("%u: presentation_config = %u (%s)\n", presentation, presentation_config, |
| 341 | (presentation_config >= NELEM(PresentationConfig) ? |
| 342 | "reserved" : PresentationConfig[presentation_config])); |
| 343 | |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 344 | bool b_add_emdf_substreams = false; |
| 345 | if (!b_single_substream_group && presentation_config == 6) { |
| 346 | b_add_emdf_substreams = true; |
| 347 | ALOGV("%u: b_add_emdf_substreams = %s\n", presentation, BOOLSTR(b_add_emdf_substreams)); |
| 348 | } else { |
| 349 | CHECK_BITS_LEFT(3 + 1); |
| 350 | uint32_t mdcompat = mBitReader.getBits(3); |
| 351 | ALOGV("%u: mdcompat = %d\n", presentation, mdcompat); |
| 352 | |
| 353 | bool b_presentation_group_index = (mBitReader.getBits(1) == 1); |
| 354 | ALOGV("%u: b_presentation_group_index = %s\n", presentation, |
| 355 | BOOLSTR(b_presentation_group_index)); |
| 356 | if (b_presentation_group_index) { |
| 357 | CHECK_BITS_LEFT(5); |
| 358 | mPresentations[presentation].mGroupIndex = mBitReader.getBits(5); |
| 359 | ALOGV("%u: presentation_group_index = %d\n", presentation, |
| 360 | mPresentations[presentation].mGroupIndex); |
| 361 | } |
| 362 | CHECK_BITS_LEFT(2); |
| 363 | uint32_t dsi_frame_rate_multiply_info = mBitReader.getBits(2); |
| 364 | ALOGV("%u: dsi_frame_rate_multiply_info = %d\n", presentation, |
| 365 | dsi_frame_rate_multiply_info); |
Previr Rangroo | 070f41e | 2018-11-22 18:33:57 +1100 | [diff] [blame] | 366 | if (ac4_dsi_version == 1 && (presentation_version == 1 || presentation_version == 2)) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 367 | CHECK_BITS_LEFT(2); |
| 368 | uint32_t dsi_frame_rate_fraction_info = mBitReader.getBits(2); |
| 369 | ALOGV("%u: dsi_frame_rate_fraction_info = %d\n", presentation, |
| 370 | dsi_frame_rate_fraction_info); |
| 371 | } |
| 372 | CHECK_BITS_LEFT(5 + 10); |
| 373 | uint32_t presentation_emdf_version = mBitReader.getBits(5); |
| 374 | uint32_t presentation_key_id = mBitReader.getBits(10); |
| 375 | ALOGV("%u: presentation_emdf_version = %d\n", presentation, presentation_emdf_version); |
| 376 | ALOGV("%u: presentation_key_id = %d\n", presentation, presentation_key_id); |
| 377 | |
| 378 | if (ac4_dsi_version == 1) { |
| 379 | bool b_presentation_channel_coded = false; |
| 380 | if (presentation_version == 0) { |
| 381 | b_presentation_channel_coded = true; |
| 382 | } else { |
| 383 | CHECK_BITS_LEFT(1); |
| 384 | b_presentation_channel_coded = (mBitReader.getBits(1) == 1); |
| 385 | } |
| 386 | ALOGV("%u: b_presentation_channel_coded = %s\n", presentation, |
| 387 | BOOLSTR(b_presentation_channel_coded)); |
| 388 | if (b_presentation_channel_coded) { |
Previr Rangroo | 070f41e | 2018-11-22 18:33:57 +1100 | [diff] [blame] | 389 | if (presentation_version == 1 || presentation_version == 2) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 390 | CHECK_BITS_LEFT(5); |
| 391 | uint32_t dsi_presentation_ch_mode = mBitReader.getBits(5); |
| 392 | mPresentations[presentation].mChannelMode = dsi_presentation_ch_mode; |
| 393 | ALOGV("%u: dsi_presentation_ch_mode = %d (%s)\n", presentation, |
| 394 | dsi_presentation_ch_mode, |
| 395 | dsi_presentation_ch_mode < NELEM(ChannelModes) ? |
| 396 | ChannelModes[dsi_presentation_ch_mode] : "reserved"); |
| 397 | |
| 398 | if (dsi_presentation_ch_mode >= 11 && dsi_presentation_ch_mode <= 14) { |
| 399 | CHECK_BITS_LEFT(1 + 2); |
| 400 | uint32_t pres_b_4_back_channels_present = mBitReader.getBits(1); |
| 401 | uint32_t pres_top_channel_pairs = mBitReader.getBits(2); |
| 402 | ALOGV("%u: pres_b_4_back_channels_present = %s\n", presentation, |
| 403 | BOOLSTR(pres_b_4_back_channels_present)); |
| 404 | ALOGV("%u: pres_top_channel_pairs = %d\n", presentation, |
| 405 | pres_top_channel_pairs); |
| 406 | } |
| 407 | } |
| 408 | // presentation_channel_mask in ac4_presentation_v0_dsi() |
| 409 | CHECK_BITS_LEFT(24); |
| 410 | uint32_t presentation_channel_mask_v1 = mBitReader.getBits(24); |
| 411 | ALOGV("%u: presentation_channel_mask_v1 = 0x%06x\n", presentation, |
| 412 | presentation_channel_mask_v1); |
| 413 | } |
Previr Rangroo | 070f41e | 2018-11-22 18:33:57 +1100 | [diff] [blame] | 414 | if (presentation_version == 1 || presentation_version == 2) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 415 | CHECK_BITS_LEFT(1); |
| 416 | bool b_presentation_core_differs = (mBitReader.getBits(1) == 1); |
| 417 | ALOGV("%u: b_presentation_core_differs = %s\n", presentation, |
| 418 | BOOLSTR(b_presentation_core_differs)); |
| 419 | if (b_presentation_core_differs) { |
| 420 | CHECK_BITS_LEFT(1); |
| 421 | bool b_presentation_core_channel_coded = (mBitReader.getBits(1) == 1); |
| 422 | if (b_presentation_core_channel_coded) { |
| 423 | CHECK_BITS_LEFT(2); |
| 424 | mBitReader.skipBits(2); // dsi_presentation_channel_mode_core |
| 425 | } |
| 426 | } |
| 427 | CHECK_BITS_LEFT(1); |
| 428 | bool b_presentation_filter = (mBitReader.getBits(1) == 1); |
| 429 | ALOGV("%u: b_presentation_filter = %s\n", presentation, |
| 430 | BOOLSTR(b_presentation_filter)); |
| 431 | if (b_presentation_filter) { |
| 432 | CHECK_BITS_LEFT(1 + 8); |
| 433 | bool b_enable_presentation = (mBitReader.getBits(1) == 1); |
| 434 | if (!b_enable_presentation) { |
| 435 | mPresentations[presentation].mEnabled = false; |
| 436 | } |
| 437 | ALOGV("%u: b_enable_presentation = %s\n", presentation, |
| 438 | BOOLSTR(b_enable_presentation)); |
| 439 | uint32_t n_filter_bytes = mBitReader.getBits(8); |
| 440 | CHECK_BITS_LEFT(n_filter_bytes * 8); |
| 441 | for (uint32_t i = 0; i < n_filter_bytes; i++) { |
| 442 | mBitReader.skipBits(8); // filter_data |
| 443 | } |
| 444 | } |
| 445 | } |
| 446 | } /* ac4_dsi_version == 1 */ |
| 447 | |
| 448 | if (b_single_substream_group) { |
| 449 | if (presentation_version == 0) { |
| 450 | if (!parseSubstreamDSI(presentation, 0)) { |
| 451 | return false; |
| 452 | } |
| 453 | } else { |
| 454 | if (!parseSubstreamGroupDSI(presentation, 0)) { |
| 455 | return false; |
| 456 | } |
| 457 | } |
| 458 | } else { |
| 459 | if (ac4_dsi_version == 1) { |
| 460 | CHECK_BITS_LEFT(1); |
| 461 | bool b_multi_pid = (mBitReader.getBits(1) == 1); |
| 462 | ALOGV("%u: b_multi_pid = %s\n", presentation, BOOLSTR(b_multi_pid)); |
| 463 | } else { |
| 464 | CHECK_BITS_LEFT(1); |
| 465 | bool b_hsf_ext = (mBitReader.getBits(1) == 1); |
| 466 | ALOGV("%u: b_hsf_ext = %s\n", presentation, BOOLSTR(b_hsf_ext)); |
| 467 | } |
| 468 | switch (presentation_config) { |
| 469 | case 0: |
| 470 | case 1: |
| 471 | case 2: |
| 472 | if (presentation_version == 0) { |
| 473 | if (!parseSubstreamDSI(presentation, 0)) { |
| 474 | return false; |
| 475 | } |
| 476 | if (!parseSubstreamDSI(presentation, 1)) { |
| 477 | return false; |
| 478 | } |
| 479 | } else { |
| 480 | if (!parseSubstreamGroupDSI(presentation, 0)) { |
| 481 | return false; |
| 482 | } |
| 483 | if (!parseSubstreamGroupDSI(presentation, 1)) { |
| 484 | return false; |
| 485 | } |
| 486 | } |
| 487 | break; |
| 488 | case 3: |
| 489 | case 4: |
| 490 | if (presentation_version == 0) { |
| 491 | if (!parseSubstreamDSI(presentation, 0)) { |
| 492 | return false; |
| 493 | } |
| 494 | if (!parseSubstreamDSI(presentation, 1)) { |
| 495 | return false; |
| 496 | } |
| 497 | if (!parseSubstreamDSI(presentation, 2)) { |
| 498 | return false; |
| 499 | } |
| 500 | } else { |
| 501 | if (!parseSubstreamGroupDSI(presentation, 0)) { |
| 502 | return false; |
| 503 | } |
| 504 | if (!parseSubstreamGroupDSI(presentation, 1)) { |
| 505 | return false; |
| 506 | } |
| 507 | if (!parseSubstreamGroupDSI(presentation, 2)) { |
| 508 | return false; |
| 509 | } |
| 510 | } |
| 511 | break; |
| 512 | case 5: |
| 513 | if (presentation_version == 0) { |
| 514 | if (!parseSubstreamDSI(presentation, 0)) { |
| 515 | return false; |
| 516 | } |
| 517 | } else { |
| 518 | CHECK_BITS_LEFT(3); |
| 519 | uint32_t n_substream_groups_minus2 = mBitReader.getBits(3); |
| 520 | ALOGV("%u: n_substream_groups_minus2 = %d\n", presentation, |
| 521 | n_substream_groups_minus2); |
| 522 | for (uint32_t sg = 0; sg < n_substream_groups_minus2 + 2; sg++) { |
| 523 | if (!parseSubstreamGroupDSI(presentation, sg)) { |
| 524 | return false; |
| 525 | } |
| 526 | } |
| 527 | } |
| 528 | break; |
| 529 | default: |
| 530 | CHECK_BITS_LEFT(7); |
| 531 | uint32_t n_skip_bytes = mBitReader.getBits(7); |
| 532 | CHECK_BITS_LEFT(n_skip_bytes * 8) |
| 533 | for (uint32_t j = 0; j < n_skip_bytes; j++) { |
| 534 | mBitReader.getBits(8); |
| 535 | } |
| 536 | break; |
| 537 | } |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 538 | } |
ybai | 4d6916a | 2019-02-28 14:34:37 +0800 | [diff] [blame] | 539 | CHECK_BITS_LEFT(1 + 1); |
| 540 | bool b_pre_virtualized = (mBitReader.getBits(1) == 1); |
| 541 | mPresentations[presentation].mPreVirtualized = b_pre_virtualized; |
| 542 | b_add_emdf_substreams = (mBitReader.getBits(1) == 1); |
| 543 | ALOGV("%u: b_pre_virtualized = %s\n", presentation, BOOLSTR(b_pre_virtualized)); |
| 544 | ALOGV("%u: b_add_emdf_substreams = %s\n", presentation, |
| 545 | BOOLSTR(b_add_emdf_substreams)); |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 546 | } |
| 547 | if (b_add_emdf_substreams) { |
| 548 | CHECK_BITS_LEFT(7); |
| 549 | uint32_t n_add_emdf_substreams = mBitReader.getBits(7); |
| 550 | for (uint32_t j = 0; j < n_add_emdf_substreams; j++) { |
| 551 | CHECK_BITS_LEFT(5 + 10); |
| 552 | uint32_t substream_emdf_version = mBitReader.getBits(5); |
| 553 | uint32_t substream_key_id = mBitReader.getBits(10); |
| 554 | ALOGV("%u: emdf_substream[%d]: version=%d, key_id=%d\n", presentation, j, |
| 555 | substream_emdf_version, substream_key_id); |
| 556 | } |
| 557 | } |
| 558 | |
| 559 | bool b_presentation_bitrate_info = false; |
| 560 | if (presentation_version > 0) { |
| 561 | CHECK_BITS_LEFT(1); |
| 562 | b_presentation_bitrate_info = (mBitReader.getBits(1) == 1); |
| 563 | } |
| 564 | |
| 565 | ALOGV("b_presentation_bitrate_info = %s\n", BOOLSTR(b_presentation_bitrate_info)); |
| 566 | if (b_presentation_bitrate_info) { |
| 567 | if (!parseBitrateDsi()) { |
| 568 | return false; |
| 569 | } |
| 570 | } |
| 571 | |
| 572 | if (presentation_version > 0) { |
| 573 | CHECK_BITS_LEFT(1); |
| 574 | bool b_alternative = (mBitReader.getBits(1) == 1); |
| 575 | ALOGV("b_alternative = %s\n", BOOLSTR(b_alternative)); |
| 576 | if (b_alternative) { |
| 577 | BYTE_ALIGN; |
| 578 | CHECK_BITS_LEFT(16); |
| 579 | uint32_t name_len = mBitReader.getBits(16); |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 580 | CHECK_BITS_LEFT(name_len * 8); |
Greg Kaiser | 661e90a | 2018-07-11 06:20:25 -0700 | [diff] [blame] | 581 | std::string &presentation_name = |
| 582 | mPresentations[presentation].mDescription; |
| 583 | presentation_name.clear(); |
| 584 | presentation_name.resize(name_len); |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 585 | for (uint32_t i = 0; i < name_len; i++) { |
| 586 | presentation_name[i] = (char)(mBitReader.getBits(8)); |
| 587 | } |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 588 | CHECK_BITS_LEFT(5); |
| 589 | uint32_t n_targets = mBitReader.getBits(5); |
| 590 | CHECK_BITS_LEFT(n_targets * (3 + 8)); |
| 591 | for (uint32_t i = 0; i < n_targets; i++){ |
| 592 | mBitReader.skipBits(3); // target_md_compat |
| 593 | mBitReader.skipBits(8); // target_device_category |
| 594 | } |
| 595 | } |
| 596 | } |
| 597 | |
| 598 | BYTE_ALIGN; |
| 599 | |
| 600 | if (ac4_dsi_version == 1) { |
| 601 | uint64_t end = (mDSISize - mBitReader.numBitsLeft()) / 8; |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 602 | uint64_t presentation_bytes = end - start; |
ybai | c9e162b | 2020-02-26 09:01:57 +0800 | [diff] [blame] | 603 | if (pres_bytes < presentation_bytes) { |
| 604 | ALOGE("pres_bytes is smaller than presentation_bytes."); |
| 605 | return false; |
| 606 | } |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 607 | uint64_t skip_bytes = pres_bytes - presentation_bytes; |
| 608 | ALOGV("skipping = %" PRIu64 " bytes", skip_bytes); |
| 609 | CHECK_BITS_LEFT(skip_bytes * 8); |
| 610 | mBitReader.skipBits(skip_bytes * 8); |
| 611 | } |
| 612 | |
| 613 | // we should know this or something is probably wrong |
| 614 | // with the bitstream (or we don't support it) |
ybai | 4d6916a | 2019-02-28 14:34:37 +0800 | [diff] [blame] | 615 | if (mPresentations[presentation].mChannelMode == -1) { |
Previr Rangroo | 7e6ac73 | 2017-11-13 20:20:20 -0800 | [diff] [blame] | 616 | ALOGE("could not determing channel mode of presentation %d", presentation); |
| 617 | return false; |
| 618 | } |
| 619 | } /* each presentation */ |
| 620 | |
| 621 | return true; |
| 622 | } |
| 623 | |
| 624 | }; |