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
AC4Parser()32 AC4Parser::AC4Parser() {
33 }
34
AC4DSIParser(ABitReader & br)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
parseLanguageTag(uint32_t presentationID,uint32_t substreamID)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
parseSubstreamDSI(uint32_t presentationID,uint32_t substreamID)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
parseSubstreamGroupDSI(uint32_t presentationID,uint32_t groupID)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
parseBitrateDsi()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)
parse()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) {
263 if (ac4_dsi_version == 0) {
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;
298 uint64_t start = 0;
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);
314 if (presentation_version > 2) {
315 CHECK_BITS_LEFT(pres_bytes * 8);
316 mBitReader.skipBits(pres_bytes * 8);
317 continue;
318 }
319 /* record a marker, less the size of the presentation_config */
320 start = (mDSISize - mBitReader.numBitsLeft()) / 8;
321 // ac4_presentation_v0_dsi(), ac4_presentation_v1_dsi() and ac4_presentation_v2_dsi()
322 // all start with a presentation_config of 5 bits
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
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);
366 if (ac4_dsi_version == 1 && (presentation_version == 1 || presentation_version == 2)) {
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) {
389 if (presentation_version == 1 || presentation_version == 2) {
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 }
414 if (presentation_version == 1 || presentation_version == 2) {
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 }
538 }
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));
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);
580 CHECK_BITS_LEFT(name_len * 8);
581 std::string &presentation_name =
582 mPresentations[presentation].mDescription;
583 presentation_name.clear();
584 presentation_name.resize(name_len);
585 for (uint32_t i = 0; i < name_len; i++) {
586 presentation_name[i] = (char)(mBitReader.getBits(8));
587 }
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;
602 uint64_t presentation_bytes = end - start;
603 if (pres_bytes < presentation_bytes) {
604 ALOGE("pres_bytes is smaller than presentation_bytes.");
605 return false;
606 }
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)
615 if (mPresentations[presentation].mChannelMode == -1) {
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 };
625