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