1 /*
2  * This file is part of libbluray
3  * Copyright (C) 2009-2010  John Stebbins
4  * Copyright (C) 2012  Petri Hintukainen <phintuka@users.sourceforge.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "mpls_parse.h"
26 
27 #include "extdata_parse.h"
28 #include "bdmv_parse.h"
29 #include "mpls_data.h"
30 #include "uo_mask.h"
31 
32 #include "disc/disc.h"
33 
34 #include "file/file.h"
35 #include "util/bits.h"
36 #include "util/logging.h"
37 #include "util/macro.h"
38 
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #define MPLS_SIG1 ('M' << 24 | 'P' << 16 | 'L' << 8 | 'S')
43 
44 static int
_parse_uo(BITSTREAM * bits,BD_UO_MASK * uo)45 _parse_uo(BITSTREAM *bits, BD_UO_MASK *uo)
46 {
47     uint8_t buf[8];
48     bs_read_bytes(bits, buf, 8);
49     return uo_mask_parse(buf, uo);
50 }
51 
52 static int
_parse_appinfo(BITSTREAM * bits,MPLS_AI * ai)53 _parse_appinfo(BITSTREAM *bits, MPLS_AI *ai)
54 {
55     int64_t /*pos,*/ len;
56 
57     if (!bs_is_align(bits, 0x07)) {
58         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_appinfo: alignment error\n");
59     }
60     //pos = bs_pos(bits) >> 3;
61     len = bs_read(bits, 32);
62 
63     if (bs_avail(bits) < len * 8) {
64         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_appinfo: unexpected end of file\n");
65         return 0;
66     }
67 
68     // Reserved
69     bs_skip(bits, 8);
70     ai->playback_type = bs_read(bits, 8);
71     if (ai->playback_type == 2 || ai->playback_type == 3) {
72         ai->playback_count = bs_read(bits, 16);
73     } else {
74         // Reserved
75         bs_skip(bits, 16);
76     }
77     _parse_uo(bits, &ai->uo_mask);
78     ai->random_access_flag = bs_read(bits, 1);
79     ai->audio_mix_flag = bs_read(bits, 1);
80     ai->lossless_bypass_flag = bs_read(bits, 1);
81     ai->mvc_base_view_r_flag = bs_read(bits, 1);
82     ai->sdr_conversion_notification_flag = bs_read(bits, 1);
83 #if 0
84     // Reserved
85     bs_skip(bits, 11);
86     bs_seek_byte(bits, pos + len);
87 #endif
88     return 1;
89 }
90 
91 static int
_parse_header(BITSTREAM * bits,MPLS_PL * pl)92 _parse_header(BITSTREAM *bits, MPLS_PL *pl)
93 {
94     pl->type_indicator = MPLS_SIG1;
95     if (!bdmv_parse_header(bits, pl->type_indicator, &pl->type_indicator2)) {
96         return 0;
97     }
98 
99     if (bs_avail(bits) < 5 * 32 + 160) {
100         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_header: unexpected end of file\n");
101         return 0;
102     }
103 
104     pl->list_pos = bs_read(bits, 32);
105     pl->mark_pos = bs_read(bits, 32);
106     pl->ext_pos  = bs_read(bits, 32);
107 
108     // Skip 160 reserved bits
109     bs_skip(bits, 160);
110 
111     _parse_appinfo(bits, &pl->app_info);
112     return 1;
113 }
114 
115 static int
_parse_stream(BITSTREAM * bits,MPLS_STREAM * s)116 _parse_stream(BITSTREAM *bits, MPLS_STREAM *s)
117 {
118     int len;
119     int64_t pos;
120 
121     if (!bs_is_align(bits, 0x07)) {
122         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_stream: Stream alignment error\n");
123     }
124     len = bs_read(bits, 8);
125     pos = bs_pos(bits) >> 3;
126 
127     s->stream_type = bs_read(bits, 8);
128     switch (s->stream_type) {
129         case 1:
130             s->pid = bs_read(bits, 16);
131             break;
132 
133         case 2:
134             s->subpath_id = bs_read(bits, 8);
135             s->subclip_id = bs_read(bits, 8);
136             s->pid        = bs_read(bits, 16);
137             break;
138 
139         case 3:
140         case 4:
141             s->subpath_id = bs_read(bits, 8);
142             s->pid        = bs_read(bits, 16);
143             break;
144 
145         default:
146             BD_DEBUG(DBG_NAV | DBG_CRIT, "unrecognized stream type %02x\n", s->stream_type);
147             break;
148     };
149 
150     if (bs_seek_byte(bits, pos + len) < 0) {
151         return 0;
152     }
153 
154     len = bs_read(bits, 8);
155     pos = bs_pos(bits) >> 3;
156 
157     s->lang[0] = '\0';
158     s->coding_type = bs_read(bits, 8);
159     switch (s->coding_type) {
160         case 0x01:
161         case 0x02:
162         case 0xea:
163         case 0x1b:
164         case 0x24:
165             s->format = bs_read(bits, 4);
166             s->rate   = bs_read(bits, 4);
167             if (s->coding_type == 0x24) {
168                 s->dynamic_range_type = bs_read(bits, 4);
169                 s->color_space        = bs_read(bits, 4);
170                 s->cr_flag            = bs_read(bits, 1);
171                 s->hdr_plus_flag      = bs_read(bits, 1);
172             }
173             break;
174 
175         case 0x03:
176         case 0x04:
177         case 0x80:
178         case 0x81:
179         case 0x82:
180         case 0x83:
181         case 0x84:
182         case 0x85:
183         case 0x86:
184         case 0xa1:
185         case 0xa2:
186             s->format = bs_read(bits, 4);
187             s->rate   = bs_read(bits, 4);
188             bs_read_string(bits, s->lang, 3);
189             break;
190 
191         case 0x90:
192         case 0x91:
193             bs_read_string(bits, s->lang, 3);
194             break;
195 
196         case 0x92:
197             s->char_code = bs_read(bits, 8);
198             bs_read_string(bits, s->lang, 3);
199             break;
200 
201         default:
202             BD_DEBUG(DBG_NAV | DBG_CRIT, "unrecognized coding type %02x\n", s->coding_type);
203             break;
204     };
205     s->lang[3] = '\0';
206 
207     if (bs_seek_byte(bits, pos + len) < 0) {
208         return 0;
209     }
210 
211     return 1;
212 }
213 
214 static int
_parse_stn(BITSTREAM * bits,MPLS_STN * stn)215 _parse_stn(BITSTREAM *bits, MPLS_STN *stn)
216 {
217     int len;
218     int64_t pos;
219     MPLS_STREAM    *ss;
220     int ii,jj;
221 
222     if (!bs_is_align(bits, 0x07)) {
223         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_stream: Stream alignment error\n");
224     }
225     // Skip STN len
226     len = bs_read(bits, 16);
227     pos = bs_pos(bits) >> 3;
228 
229     // Skip 2 reserved bytes
230     bs_skip(bits, 16);
231 
232     stn->num_video           = bs_read(bits, 8);
233     stn->num_audio           = bs_read(bits, 8);
234     stn->num_pg              = bs_read(bits, 8);
235     stn->num_ig              = bs_read(bits, 8);
236     stn->num_secondary_audio = bs_read(bits, 8);
237     stn->num_secondary_video = bs_read(bits, 8);
238     stn->num_pip_pg          = bs_read(bits, 8);
239     stn->num_dv              = bs_read(bits, 8);
240 
241     // 4 reserve bytes
242     bs_skip(bits, 4 * 8);
243 
244     // Primary Video Streams
245     ss = NULL;
246     if (stn->num_video) {
247         ss = calloc(stn->num_video, sizeof(MPLS_STREAM));
248         if (!ss) {
249             return 0;
250         }
251         for (ii = 0; ii < stn->num_video; ii++) {
252             if (!_parse_stream(bits, &ss[ii])) {
253                 X_FREE(ss);
254                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing video entry\n");
255                 return 0;
256             }
257         }
258     }
259     stn->video = ss;
260 
261     // Primary Audio Streams
262     ss = NULL;
263     if (stn->num_audio) {
264         ss = calloc(stn->num_audio, sizeof(MPLS_STREAM));
265         if (!ss) {
266             return 0;
267         }
268         for (ii = 0; ii < stn->num_audio; ii++) {
269 
270             if (!_parse_stream(bits, &ss[ii])) {
271                 X_FREE(ss);
272                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing audio entry\n");
273                 return 0;
274             }
275         }
276     }
277     stn->audio = ss;
278 
279     // Presentation Graphic Streams
280     ss = NULL;
281     if (stn->num_pg  || stn->num_pip_pg) {
282         ss = calloc(stn->num_pg + stn->num_pip_pg, sizeof(MPLS_STREAM));
283         if (!ss) {
284             return 0;
285         }
286         for (ii = 0; ii < (stn->num_pg + stn->num_pip_pg); ii++) {
287             if (!_parse_stream(bits, &ss[ii])) {
288                 X_FREE(ss);
289                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing pg/pip-pg entry\n");
290                 return 0;
291             }
292         }
293     }
294     stn->pg = ss;
295 
296     // Interactive Graphic Streams
297     ss = NULL;
298     if (stn->num_ig) {
299         ss = calloc(stn->num_ig, sizeof(MPLS_STREAM));
300         if (!ss) {
301             return 0;
302         }
303         for (ii = 0; ii < stn->num_ig; ii++) {
304             if (!_parse_stream(bits, &ss[ii])) {
305                 X_FREE(ss);
306                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing ig entry\n");
307                 return 0;
308             }
309         }
310     }
311     stn->ig = ss;
312 
313     // Secondary Audio Streams
314     if (stn->num_secondary_audio) {
315         ss = calloc(stn->num_secondary_audio, sizeof(MPLS_STREAM));
316         if (!ss) {
317             return 0;
318         }
319         stn->secondary_audio = ss;
320         for (ii = 0; ii < stn->num_secondary_audio; ii++) {
321             if (!_parse_stream(bits, &ss[ii])) {
322                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing secondary audio entry\n");
323                 return 0;
324             }
325             // Read Secondary Audio Extra Attributes
326             ss[ii].sa_num_primary_audio_ref = bs_read(bits, 8);
327             bs_skip(bits, 8);
328             if (ss[ii].sa_num_primary_audio_ref) {
329                 ss[ii].sa_primary_audio_ref = calloc(ss[ii].sa_num_primary_audio_ref, sizeof(uint8_t));
330                 if (!ss[ii].sa_primary_audio_ref) {
331                     return 0;
332                 }
333                 for (jj = 0; jj < ss[ii].sa_num_primary_audio_ref; jj++) {
334                    ss[ii].sa_primary_audio_ref[jj] = bs_read(bits, 8);
335                 }
336                 if (ss[ii].sa_num_primary_audio_ref % 2) {
337                     bs_skip(bits, 8);
338                 }
339             }
340         }
341     }
342 
343     // Secondary Video Streams
344     if (stn->num_secondary_video) {
345         ss = calloc(stn->num_secondary_video, sizeof(MPLS_STREAM));
346         if (!ss) {
347             return 0;
348         }
349         stn->secondary_video = ss;
350         for (ii = 0; ii < stn->num_secondary_video; ii++) {
351             if (!_parse_stream(bits, &ss[ii])) {
352                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing secondary video entry\n");
353                 return 0;
354             }
355             // Read Secondary Video Extra Attributes
356             ss[ii].sv_num_secondary_audio_ref = bs_read(bits, 8);
357             bs_skip(bits, 8);
358             if (ss[ii].sv_num_secondary_audio_ref) {
359                 ss[ii].sv_secondary_audio_ref = calloc(ss[ii].sv_num_secondary_audio_ref, sizeof(uint8_t));
360                 if (!ss[ii].sv_secondary_audio_ref) {
361                     return 0;
362                 }
363                 for (jj = 0; jj < ss[ii].sv_num_secondary_audio_ref; jj++) {
364                     ss[ii].sv_secondary_audio_ref[jj] = bs_read(bits, 8);
365                 }
366                 if (ss[ii].sv_num_secondary_audio_ref % 2) {
367                     bs_skip(bits, 8);
368                 }
369             }
370             ss[ii].sv_num_pip_pg_ref = bs_read(bits, 8);
371             bs_skip(bits, 8);
372             if (ss[ii].sv_num_pip_pg_ref) {
373                 ss[ii].sv_pip_pg_ref = calloc(ss[ii].sv_num_pip_pg_ref, sizeof(uint8_t));
374                 if (!ss[ii].sv_pip_pg_ref) {
375                     return 0;
376                 }
377                 for (jj = 0; jj < ss[ii].sv_num_pip_pg_ref; jj++) {
378                     ss[ii].sv_pip_pg_ref[jj] = bs_read(bits, 8);
379                 }
380                 if (ss[ii].sv_num_pip_pg_ref % 2) {
381                     bs_skip(bits, 8);
382                 }
383             }
384 
385         }
386     }
387 
388     // Dolby Vision Enhancement Layer Streams
389     ss = NULL;
390     if (stn->num_dv) {
391         ss = calloc(stn->num_dv, sizeof(MPLS_STREAM));
392         if (!ss) {
393             return 0;
394         }
395         for (ii = 0; ii < stn->num_dv; ii++) {
396             if (!_parse_stream(bits, &ss[ii])) {
397                 X_FREE(ss);
398                 BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing dv entry\n");
399                 return 0;
400             }
401         }
402     }
403     stn->dv = ss;
404 
405     if (bs_seek_byte(bits, pos + len) < 0) {
406         return 0;
407     }
408 
409     return 1;
410 }
411 
412 static void
_clean_stn(MPLS_STN * stn)413 _clean_stn(MPLS_STN *stn)
414 {
415     unsigned ii;
416 
417     if(stn->secondary_audio) {
418         for (ii = 0; ii < stn->num_secondary_audio; ii++) {
419             X_FREE(stn->secondary_audio[ii].sa_primary_audio_ref);
420         }
421     }
422     if(stn->secondary_video) {
423         for (ii = 0; ii < stn->num_secondary_video; ii++) {
424             X_FREE(stn->secondary_video[ii].sv_secondary_audio_ref);
425             X_FREE(stn->secondary_video[ii].sv_pip_pg_ref);
426         }
427     }
428 
429     X_FREE(stn->video);
430     X_FREE(stn->audio);
431     X_FREE(stn->pg);
432     X_FREE(stn->ig);
433     X_FREE(stn->secondary_audio);
434     X_FREE(stn->secondary_video);
435 }
436 
437 static int
_parse_playitem(BITSTREAM * bits,MPLS_PI * pi)438 _parse_playitem(BITSTREAM *bits, MPLS_PI *pi)
439 {
440     int len, ii;
441     int64_t pos;
442     char clip_id[6], codec_id[5];
443     uint8_t stc_id;
444 
445     if (!bs_is_align(bits, 0x07)) {
446         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playitem: Stream alignment error\n");
447     }
448 
449     // PlayItem Length
450     len = bs_read(bits, 16);
451     pos = bs_pos(bits) >> 3;
452 
453     if (len < 18) {
454         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playitem: invalid length %d\n", len);
455         return 0;
456     }
457     if (bs_avail(bits)/8 < len) {
458         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playitem: unexpected EOF\n");
459         return 0;
460     }
461 
462     // Primary Clip identifer
463     bs_read_string(bits, clip_id, 5);
464 
465     bs_read_string(bits, codec_id, 4);
466     if (memcmp(codec_id, "M2TS", 4) != 0 && memcmp(codec_id, "FMTS", 4) != 0) {
467         BD_DEBUG(DBG_NAV | DBG_CRIT, "Incorrect CodecIdentifier (%s)\n", codec_id);
468     }
469 
470     // Skip reserved 11 bits
471     bs_skip(bits, 11);
472 
473     pi->is_multi_angle = bs_read(bits, 1);
474 
475     pi->connection_condition = bs_read(bits, 4);
476     if (pi->connection_condition != 0x01 &&
477         pi->connection_condition != 0x05 &&
478         pi->connection_condition != 0x06) {
479 
480         BD_DEBUG(DBG_NAV | DBG_CRIT, "Unexpected connection condition %02x\n",
481                 pi->connection_condition);
482     }
483 
484     stc_id   = bs_read(bits, 8);
485     pi->in_time  = bs_read(bits, 32);
486     pi->out_time = bs_read(bits, 32);
487 
488     _parse_uo(bits, &pi->uo_mask);
489     pi->random_access_flag = bs_read(bits, 1);
490     bs_skip(bits, 7);
491     pi->still_mode = bs_read(bits, 8);
492     if (pi->still_mode == 0x01) {
493         pi->still_time = bs_read(bits, 16);
494     } else {
495         bs_skip(bits, 16);
496     }
497 
498     pi->angle_count = 1;
499     if (pi->is_multi_angle) {
500         pi->angle_count = bs_read(bits, 8);
501         if (pi->angle_count < 1) {
502             pi->angle_count = 1;
503         }
504         bs_skip(bits, 6);
505         pi->is_different_audio = bs_read(bits, 1);
506         pi->is_seamless_angle = bs_read(bits, 1);
507     }
508     pi->clip = calloc(pi->angle_count, sizeof(MPLS_CLIP));
509     if (!pi->clip) {
510         return 0;
511     }
512     strcpy(pi->clip[0].clip_id, clip_id);
513     strcpy(pi->clip[0].codec_id, codec_id);
514     pi->clip[0].stc_id = stc_id;
515     for (ii = 1; ii < pi->angle_count; ii++) {
516         bs_read_string(bits, pi->clip[ii].clip_id, 5);
517 
518         bs_read_string(bits, pi->clip[ii].codec_id, 4);
519         if (memcmp(pi->clip[ii].codec_id, "M2TS", 4) != 0 && memcmp(pi->clip[ii].codec_id, "FMTS", 4) != 0) {
520             BD_DEBUG(DBG_NAV | DBG_CRIT, "Incorrect CodecIdentifier (%s)\n", pi->clip[ii].codec_id);
521         }
522         pi->clip[ii].stc_id   = bs_read(bits, 8);
523     }
524     if (!_parse_stn(bits, &pi->stn)) {
525         return 0;
526     }
527 
528     // Seek past any unused items
529     if (bs_seek_byte(bits, pos + len) < 0) {
530         return 0;
531     }
532 
533     return 1;
534 }
535 
536 static void
_clean_playitem(MPLS_PI * pi)537 _clean_playitem(MPLS_PI *pi)
538 {
539     X_FREE(pi->clip);
540     _clean_stn(&pi->stn);
541 }
542 
543 static int
_parse_subplayitem(BITSTREAM * bits,MPLS_SUB_PI * spi)544 _parse_subplayitem(BITSTREAM *bits, MPLS_SUB_PI *spi)
545 {
546     int len, ii;
547     int64_t pos;
548     char clip_id[6], codec_id[5];
549     uint8_t stc_id;
550 
551     if (!bs_is_align(bits, 0x07)) {
552         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_subplayitem: alignment error\n");
553     }
554 
555     // PlayItem Length
556     len = bs_read(bits, 16);
557     pos = bs_pos(bits) >> 3;
558 
559     if (len < 24) {
560         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_subplayitem: invalid length %d\n", len);
561         return 0;
562     }
563 
564     if (bs_avail(bits)/8 < len) {
565         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_subplayitem: unexpected EOF\n");
566         return 0;
567     }
568 
569     // Primary Clip identifer
570     bs_read_string(bits, clip_id, 5);
571 
572     bs_read_string(bits, codec_id, 4);
573     if (memcmp(codec_id, "M2TS", 4) != 0 && memcmp(codec_id, "FMTS", 4) != 0) {
574         BD_DEBUG(DBG_NAV | DBG_CRIT, "Incorrect CodecIdentifier (%s)\n", codec_id);
575     }
576 
577     bs_skip(bits, 27);
578 
579     spi->connection_condition = bs_read(bits, 4);
580 
581     if (spi->connection_condition != 0x01 &&
582         spi->connection_condition != 0x05 &&
583         spi->connection_condition != 0x06) {
584 
585         BD_DEBUG(DBG_NAV | DBG_CRIT, "Unexpected connection condition %02x\n",
586                 spi->connection_condition);
587     }
588     spi->is_multi_clip     = bs_read(bits, 1);
589     stc_id                 = bs_read(bits, 8);
590     spi->in_time           = bs_read(bits, 32);
591     spi->out_time          = bs_read(bits, 32);
592     spi->sync_play_item_id = bs_read(bits, 16);
593     spi->sync_pts          = bs_read(bits, 32);
594     spi->clip_count = 1;
595     if (spi->is_multi_clip) {
596         spi->clip_count    = bs_read(bits, 8);
597         if (spi->clip_count < 1) {
598             spi->clip_count = 1;
599         }
600     }
601     spi->clip = calloc(spi->clip_count, sizeof(MPLS_CLIP));
602     if (!spi->clip) {
603         return 0;
604     }
605     strcpy(spi->clip[0].clip_id, clip_id);
606     strcpy(spi->clip[0].codec_id, codec_id);
607     spi->clip[0].stc_id = stc_id;
608     for (ii = 1; ii < spi->clip_count; ii++) {
609         // Primary Clip identifer
610         bs_read_string(bits, spi->clip[ii].clip_id, 5);
611 
612         bs_read_string(bits, spi->clip[ii].codec_id, 4);
613         if (memcmp(spi->clip[ii].codec_id, "M2TS", 4) != 0 && memcmp(spi->clip[ii].codec_id, "FMTS", 4) != 0) {
614             BD_DEBUG(DBG_NAV | DBG_CRIT, "Incorrect CodecIdentifier (%s)\n", spi->clip[ii].codec_id);
615         }
616         spi->clip[ii].stc_id = bs_read(bits, 8);
617     }
618 
619 
620     // Seek to end of subpath
621     if (bs_seek_byte(bits, pos + len) < 0) {
622         return 0;
623     }
624 
625     return 1;
626 }
627 
628 static void
_clean_subplayitem(MPLS_SUB_PI * spi)629 _clean_subplayitem(MPLS_SUB_PI *spi)
630 {
631     X_FREE(spi->clip);
632 }
633 
634 static int
_parse_subpath(BITSTREAM * bits,MPLS_SUB * sp)635 _parse_subpath(BITSTREAM *bits, MPLS_SUB *sp)
636 {
637     int len, ii;
638     int64_t pos;
639     MPLS_SUB_PI *spi = NULL;
640 
641     if (!bs_is_align(bits, 0x07)) {
642         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_subpath: alignment error\n");
643     }
644 
645     // PlayItem Length
646     len = bs_read(bits, 32);
647     pos = bs_pos(bits) >> 3;
648 
649     bs_skip(bits, 8);
650     sp->type = bs_read(bits, 8);
651     bs_skip(bits, 15);
652     sp->is_repeat = bs_read(bits, 1);
653     bs_skip(bits, 8);
654     sp->sub_playitem_count = bs_read(bits, 8);
655 
656     if (sp->sub_playitem_count) {
657     spi = calloc(sp->sub_playitem_count,  sizeof(MPLS_SUB_PI));
658         if (!spi) {
659             return 0;
660         }
661     sp->sub_play_item = spi;
662     for (ii = 0; ii < sp->sub_playitem_count; ii++) {
663         if (!_parse_subplayitem(bits, &spi[ii])) {
664             BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing sub play item\n");
665             return 0;
666         }
667     }
668     }
669 
670     // Seek to end of subpath
671     if (bs_seek_byte(bits, pos + len) < 0) {
672         return 0;
673     }
674 
675     return 1;
676 }
677 
678 static void
_clean_subpath(MPLS_SUB * sp)679 _clean_subpath(MPLS_SUB *sp)
680 {
681     int ii;
682 
683     for (ii = 0; ii < sp->sub_playitem_count; ii++) {
684         _clean_subplayitem(&sp->sub_play_item[ii]);
685     }
686     X_FREE(sp->sub_play_item);
687 }
688 
689 static int
_parse_playlistmark(BITSTREAM * bits,MPLS_PL * pl)690 _parse_playlistmark(BITSTREAM *bits, MPLS_PL *pl)
691 {
692     int64_t len;
693     int ii;
694     MPLS_PLM *plm = NULL;
695 
696     if (bs_seek_byte(bits, pl->mark_pos) < 0) {
697         return 0;
698     }
699 
700     // length field
701     len = bs_read(bits, 32);
702 
703     if (bs_avail(bits)/8 < len) {
704         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playlistmark: unexpected EOF\n");
705         return 0;
706     }
707 
708     // Then get the number of marks
709     pl->mark_count = bs_read(bits, 16);
710 
711     if (bs_avail(bits)/(8*14) < pl->mark_count) {
712         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playlistmark: unexpected EOF\n");
713         return 0;
714     }
715 
716     plm = calloc(pl->mark_count, sizeof(MPLS_PLM));
717     if (pl->mark_count && !plm) {
718         BD_DEBUG(DBG_CRIT, "out of memory\n");
719         return 0;
720     }
721 
722     for (ii = 0; ii < pl->mark_count; ii++) {
723         bs_skip(bits, 8); /* reserved */
724         plm[ii].mark_type     = bs_read(bits, 8);
725         plm[ii].play_item_ref = bs_read(bits, 16);
726         plm[ii].time          = bs_read(bits, 32);
727         plm[ii].entry_es_pid  = bs_read(bits, 16);
728         plm[ii].duration      = bs_read(bits, 32);
729     }
730     pl->play_mark = plm;
731     return 1;
732 }
733 
734 static int
_parse_playlist(BITSTREAM * bits,MPLS_PL * pl)735 _parse_playlist(BITSTREAM *bits, MPLS_PL *pl)
736 {
737     int64_t len;
738     int ii;
739     MPLS_PI *pi = NULL;
740     MPLS_SUB *sub_path = NULL;
741 
742     if (bs_seek_byte(bits, pl->list_pos) < 0) {
743         return 0;
744     }
745 
746     // playlist length
747     len = bs_read(bits, 32);
748 
749     if (bs_avail(bits) < len * 8) {
750         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_playlist: unexpected end of file\n");
751         return 0;
752     }
753 
754     // Skip reserved bytes
755     bs_skip(bits, 16);
756 
757     pl->list_count = bs_read(bits, 16);
758     pl->sub_count = bs_read(bits, 16);
759 
760     if (pl->list_count) {
761     pi = calloc(pl->list_count,  sizeof(MPLS_PI));
762         if (!pi) {
763             return 0;
764         }
765     pl->play_item = pi;
766     for (ii = 0; ii < pl->list_count; ii++) {
767         if (!_parse_playitem(bits, &pi[ii])) {
768             BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing play list item\n");
769             return 0;
770         }
771     }
772     }
773 
774     if (pl->sub_count) {
775     sub_path = calloc(pl->sub_count,  sizeof(MPLS_SUB));
776         if (!sub_path) {
777             return 0;
778         }
779     pl->sub_path = sub_path;
780     for (ii = 0; ii < pl->sub_count; ii++)
781     {
782         if (!_parse_subpath(bits, &sub_path[ii]))
783         {
784             BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing subpath\n");
785             return 0;
786         }
787     }
788     }
789 
790     return 1;
791 }
792 
_clean_pip_data(MPLS_PIP_METADATA * p)793 static void _clean_pip_data(MPLS_PIP_METADATA *p)
794 {
795     X_FREE(p->data);
796 }
797 
798 static void
_clean_playlist(MPLS_PL * pl)799 _clean_playlist(MPLS_PL *pl)
800 {
801     int ii;
802 
803     if (pl->play_item != NULL) {
804         for (ii = 0; ii < pl->list_count; ii++) {
805             _clean_playitem(&pl->play_item[ii]);
806         }
807         X_FREE(pl->play_item);
808     }
809     if (pl->sub_path != NULL) {
810         for (ii = 0; ii < pl->sub_count; ii++) {
811             _clean_subpath(&pl->sub_path[ii]);
812         }
813         X_FREE(pl->sub_path);
814     }
815     if (pl->ext_sub_path != NULL) {
816         for (ii = 0; ii < pl->ext_sub_count; ii++) {
817             _clean_subpath(&pl->ext_sub_path[ii]);
818         }
819         X_FREE(pl->ext_sub_path);
820     }
821     if (pl->ext_pip_data != NULL) {
822         for (ii = 0; ii < pl->ext_pip_data_count; ii++) {
823             _clean_pip_data(&pl->ext_pip_data[ii]);
824         }
825         X_FREE(pl->ext_pip_data);
826     }
827 
828     X_FREE(pl->ext_static_metadata);
829     X_FREE(pl->play_mark);
830     X_FREE(pl);
831 }
832 
833 void
mpls_free(MPLS_PL ** pl)834 mpls_free(MPLS_PL **pl)
835 {
836     if (*pl) {
837         _clean_playlist(*pl);
838         *pl = NULL;
839     }
840 }
841 
842 static int
_parse_pip_data(BITSTREAM * bits,MPLS_PIP_METADATA * block)843 _parse_pip_data(BITSTREAM *bits, MPLS_PIP_METADATA *block)
844 {
845     MPLS_PIP_DATA *data;
846     unsigned ii;
847 
848     uint16_t entries = bs_read(bits, 16);
849     if (entries < 1) {
850         return 1;
851     }
852 
853     data = calloc(entries, sizeof(MPLS_PIP_DATA));
854     if (!data) {
855         BD_DEBUG(DBG_CRIT, "out of memory\n");
856         return 0;
857     }
858 
859     for (ii = 0; ii < entries; ii++) {
860 
861         data[ii].time = bs_read(bits, 32);
862         data[ii].xpos = bs_read(bits, 12);
863         data[ii].ypos = bs_read(bits, 12);
864         data[ii].scale_factor = bs_read(bits, 4);
865         bs_skip(bits, 4);
866     }
867 
868     block->data_count = entries;
869     block->data = data;
870 
871     return 1;
872 }
873 
874 static int
_parse_pip_metadata_block(BITSTREAM * bits,uint32_t start_address,MPLS_PIP_METADATA * data)875 _parse_pip_metadata_block(BITSTREAM *bits, uint32_t start_address, MPLS_PIP_METADATA *data)
876 {
877     uint32_t data_address;
878     int result;
879     int64_t pos;
880 
881     data->clip_ref            = bs_read(bits, 16);
882     data->secondary_video_ref = bs_read(bits, 8);
883     bs_skip(bits, 8);
884     data->timeline_type       = bs_read(bits, 4);
885     data->luma_key_flag       = bs_read(bits, 1);
886     data->trick_play_flag     = bs_read(bits, 1);
887     bs_skip(bits, 10);
888     if (data->luma_key_flag) {
889         bs_skip(bits, 8);
890         data->upper_limit_luma_key = bs_read(bits, 8);
891     } else {
892         bs_skip(bits, 16);
893     }
894     bs_skip(bits, 16);
895 
896     data_address = bs_read(bits, 32);
897 
898     pos = bs_pos(bits) / 8;
899     if (bs_seek_byte(bits, start_address + data_address) < 0) {
900         return 0;
901     }
902     result = _parse_pip_data(bits, data);
903     if (bs_seek_byte(bits, pos) < 0) {
904         return 0;
905     }
906 
907     return result;
908 }
909 
910 static int
_parse_pip_metadata_extension(BITSTREAM * bits,MPLS_PL * pl)911 _parse_pip_metadata_extension(BITSTREAM *bits, MPLS_PL *pl)
912 {
913     MPLS_PIP_METADATA *data;
914     int ii;
915 
916     uint32_t start_address = (uint32_t)bs_pos(bits) / 8;
917     uint32_t len           = bs_read(bits, 32);
918     int      entries       = bs_read(bits, 16);
919 
920     if (len < 1 || entries < 1) {
921         return 0;
922     }
923 
924     data = calloc(entries, sizeof(MPLS_PIP_METADATA));
925     if (!data) {
926         BD_DEBUG(DBG_CRIT, "out of memory\n");
927         return 0;
928     }
929 
930     for (ii = 0; ii < entries; ii++) {
931         if (!_parse_pip_metadata_block(bits, start_address, &data[ii])) {
932             goto error;
933         }
934     }
935 
936     pl->ext_pip_data_count = entries;
937     pl->ext_pip_data       = data;
938 
939     return 1;
940 
941  error:
942     BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing pip metadata extension\n");
943     for (ii = 0; ii < entries; ii++) {
944         _clean_pip_data(&data[ii]);
945     }
946     X_FREE(data);
947     return 0;
948 
949 }
950 
951 static int
_parse_subpath_extension(BITSTREAM * bits,MPLS_PL * pl)952 _parse_subpath_extension(BITSTREAM *bits, MPLS_PL *pl)
953 {
954     MPLS_SUB *sub_path;
955     int ii;
956 
957     uint32_t len       = bs_read(bits, 32);
958     int      sub_count = bs_read(bits, 16);
959 
960     if (len < 1 || sub_count < 1) {
961         return 0;
962     }
963 
964     sub_path = calloc(sub_count,  sizeof(MPLS_SUB));
965     if (!sub_path) {
966         BD_DEBUG(DBG_CRIT, "out of memory\n");
967         return 0;
968     }
969 
970     for (ii = 0; ii < sub_count; ii++) {
971         if (!_parse_subpath(bits, &sub_path[ii])) {
972             goto error;
973         }
974     }
975     pl->ext_sub_path  = sub_path;
976     pl->ext_sub_count = sub_count;
977 
978     return 1;
979 
980  error:
981     BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing extension subpath\n");
982     for (ii = 0; ii < sub_count; ii++) {
983         _clean_subpath(&sub_path[ii]);
984     }
985     X_FREE(sub_path);
986     return 0;
987 }
988 
989 static int
_parse_static_metadata(BITSTREAM * bits,MPLS_STATIC_METADATA * data)990 _parse_static_metadata(BITSTREAM *bits, MPLS_STATIC_METADATA *data)
991 {
992     int ii;
993 
994     if (bs_avail(bits) < 28 * 8) {
995         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_static_metadata: unexpected end of file\n");
996         return 0;
997     }
998 
999     data->dynamic_range_type              = bs_read(bits, 4);
1000     bs_skip(bits,4);
1001     bs_skip(bits,24);
1002     for(ii = 0; ii < 3; ii++){
1003         data->display_primaries_x[ii]     = bs_read(bits, 16);
1004         data->display_primaries_y[ii]     = bs_read(bits, 16);
1005     }
1006     data->white_point_x                   = bs_read(bits, 16);
1007     data->white_point_y                   = bs_read(bits, 16);
1008     data->max_display_mastering_luminance = bs_read(bits, 16);
1009     data->min_display_mastering_luminance = bs_read(bits, 16);
1010     data->max_CLL                         = bs_read(bits, 16);
1011     data->max_FALL                        = bs_read(bits, 16);
1012 
1013     return 1;
1014 }
1015 
1016 static int
_parse_static_metadata_extension(BITSTREAM * bits,MPLS_PL * pl)1017 _parse_static_metadata_extension(BITSTREAM *bits, MPLS_PL *pl)
1018 {
1019     MPLS_STATIC_METADATA *static_metadata;
1020     uint32_t len;
1021     int ii;
1022 
1023     len = bs_read(bits, 32);
1024     if (len < 32) {     // At least one static metadata entry
1025         return 0;
1026     }
1027     if (bs_avail(bits) < len * 8) {
1028         BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_static_metadata_extension: unexpected end of file\n");
1029         return 0;
1030     }
1031 
1032     uint8_t sm_count = bs_read(bits, 8);
1033     if (sm_count < 1) {
1034         return 0;
1035     }
1036     bs_skip(bits, 24);
1037 
1038     static_metadata = calloc(sm_count,  sizeof(MPLS_STATIC_METADATA));
1039     if (!static_metadata) {
1040         BD_DEBUG(DBG_CRIT, "out of memory\n");
1041         return 0;
1042     }
1043 
1044     for (ii = 0; ii < sm_count; ii++) {
1045         if (!_parse_static_metadata(bits, &static_metadata[ii])) {
1046             goto error;
1047         }
1048     }
1049     pl->ext_static_metadata       = static_metadata;
1050     pl->ext_static_metadata_count = sm_count;
1051 
1052     return 1;
1053 
1054  error:
1055     BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing static metadata extension\n");
1056     X_FREE(static_metadata);
1057     return 0;
1058 }
1059 
1060 static int
_parse_mpls_extension(BITSTREAM * bits,int id1,int id2,void * handle)1061 _parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle)
1062 {
1063     MPLS_PL *pl = (MPLS_PL*)handle;
1064 
1065     if (id1 == 1) {
1066         if (id2 == 1) {
1067             // PiP metadata extension
1068             return _parse_pip_metadata_extension(bits, pl);
1069         }
1070     }
1071 
1072     if (id1 == 2) {
1073         if (id2 == 1) {
1074             return 0;
1075         }
1076         if (id2 == 2) {
1077             // SubPath entries extension
1078             return _parse_subpath_extension(bits, pl);
1079         }
1080     }
1081 
1082     if (id1 == 3) {
1083         if (id2 == 5) {
1084             // Static metadata extension
1085             return _parse_static_metadata_extension(bits, pl);
1086         }
1087     }
1088 
1089     BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_mpls_extension(): unhandled extension %d.%d\n", id1, id2);
1090 
1091     return 0;
1092 }
1093 
1094 static MPLS_PL*
_mpls_parse(BD_FILE_H * fp)1095 _mpls_parse(BD_FILE_H *fp)
1096 {
1097     BITSTREAM  bits;
1098     MPLS_PL   *pl = NULL;
1099 
1100     if (bs_init(&bits, fp) < 0) {
1101         BD_DEBUG(DBG_NAV, "?????.mpls: read error\n");
1102         return NULL;
1103     }
1104 
1105     pl = calloc(1, sizeof(MPLS_PL));
1106     if (pl == NULL) {
1107         BD_DEBUG(DBG_CRIT, "out of memory\n");
1108         return NULL;
1109     }
1110 
1111     if (!_parse_header(&bits, pl)) {
1112         _clean_playlist(pl);
1113         return NULL;
1114     }
1115     if (!_parse_playlist(&bits, pl)) {
1116         _clean_playlist(pl);
1117         return NULL;
1118     }
1119     if (!_parse_playlistmark(&bits, pl)) {
1120         _clean_playlist(pl);
1121         return NULL;
1122     }
1123 
1124     if (pl->ext_pos > 0) {
1125         bdmv_parse_extension_data(&bits,
1126                                   pl->ext_pos,
1127                                   _parse_mpls_extension,
1128                                   pl);
1129     }
1130 
1131     return pl;
1132 }
1133 
1134 MPLS_PL*
mpls_parse(const char * path)1135 mpls_parse(const char *path)
1136 {
1137     MPLS_PL   *pl;
1138     BD_FILE_H *fp;
1139 
1140     fp = file_open(path, "rb");
1141     if (!fp) {
1142         BD_DEBUG(DBG_NAV | DBG_CRIT, "Failed to open %s\n", path);
1143         return NULL;
1144     }
1145 
1146     pl = _mpls_parse(fp);
1147     file_close(fp);
1148     return pl;
1149 }
1150 
1151 static MPLS_PL*
_mpls_get(BD_DISC * disc,const char * dir,const char * file)1152 _mpls_get(BD_DISC *disc, const char *dir, const char *file)
1153 {
1154     MPLS_PL   *pl;
1155     BD_FILE_H *fp;
1156 
1157     fp = disc_open_file(disc, dir, file);
1158     if (!fp) {
1159         return NULL;
1160     }
1161 
1162     pl = _mpls_parse(fp);
1163     file_close(fp);
1164     return pl;
1165 }
1166 
1167 MPLS_PL*
mpls_get(BD_DISC * disc,const char * file)1168 mpls_get(BD_DISC *disc, const char *file)
1169 {
1170     MPLS_PL *pl;
1171 
1172     pl = _mpls_get(disc, "BDMV" DIR_SEP "PLAYLIST", file);
1173     if (pl) {
1174         return pl;
1175     }
1176 
1177     /* if failed, try backup file */
1178     pl = _mpls_get(disc, "BDMV" DIR_SEP "BACKUP" DIR_SEP "PLAYLIST", file);
1179     return pl;
1180 }
1181