3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
14 #include "libbluray/bluray.h"
21 BLURAY_TITLE_INFO
** title_info
;
29 /***********************************************************************
31 **********************************************************************/
32 static int next_packet( BLURAY
*bd
, uint8_t *pkt
);
33 static int title_info_compare_mpls(const void *, const void *);
35 /***********************************************************************
37 ***********************************************************************
39 **********************************************************************/
40 hb_bd_t
* hb_bd_init( hb_handle_t
*h
, char * path
)
45 d
= calloc( sizeof( hb_bd_t
), 1 );
49 d
->bd
= bd_open( path
, NULL
);
53 * Not an error, may be a stream - which we'll try in a moment.
55 hb_log( "bd: not a bd - trying as a stream/file instead" );
59 d
->title_count
= bd_get_titles( d
->bd
, TITLES_RELEVANT
, 0 );
60 if ( d
->title_count
== 0 )
62 hb_log( "bd: not a bd - trying as a stream/file instead" );
65 d
->title_info
= calloc( sizeof( BLURAY_TITLE_INFO
* ) , d
->title_count
);
66 for ( ii
= 0; ii
< d
->title_count
; ii
++ )
68 d
->title_info
[ii
] = bd_get_title_info( d
->bd
, ii
, 0 );
70 qsort(d
->title_info
, d
->title_count
, sizeof( BLURAY_TITLE_INFO
* ), title_info_compare_mpls
);
71 d
->path
= strdup( path
);
76 if( d
->bd
) bd_close( d
->bd
);
81 /***********************************************************************
83 **********************************************************************/
84 int hb_bd_title_count( hb_bd_t
* d
)
86 return d
->title_count
;
89 static void add_subtitle(int track
, hb_list_t
*list_subtitle
, BLURAY_STREAM_INFO
*bdsub
, uint32_t codec
)
91 hb_subtitle_t
* subtitle
;
94 subtitle
= calloc( sizeof( hb_subtitle_t
), 1 );
96 subtitle
->track
= track
;
97 subtitle
->id
= bdsub
->pid
;
98 lang
= lang_for_code2( (char*)bdsub
->lang
);
99 snprintf( subtitle
->lang
, sizeof( subtitle
->lang
), "%s",
100 strlen(lang
->native_name
) ? lang
->native_name
: lang
->eng_name
);
101 snprintf( subtitle
->iso639_2
, sizeof( subtitle
->iso639_2
), "%s",
104 switch ( bdsub
->coding_type
)
106 case BLURAY_STREAM_TYPE_SUB_PG
:
107 subtitle
->source
= PGSSUB
;
108 subtitle
->format
= PICTURESUB
;
109 subtitle
->config
.dest
= RENDERSUB
;
112 // Unrecognized, don't add to list
116 subtitle
->reg_desc
= STR4_TO_UINT32("HDMV");
117 subtitle
->stream_type
= bdsub
->coding_type
;
118 subtitle
->codec
= codec
;
120 hb_log( "bd: subtitle id=0x%x, lang=%s, 3cc=%s", subtitle
->id
,
121 subtitle
->lang
, subtitle
->iso639_2
);
123 hb_list_add( list_subtitle
, subtitle
);
127 static void add_audio(int track
, hb_list_t
*list_audio
, BLURAY_STREAM_INFO
*bdaudio
, int substream_type
, uint32_t codec
, uint32_t codec_param
)
129 const char * codec_name
;
131 iso639_lang_t
* lang
;
133 audio
= calloc( sizeof( hb_audio_t
), 1 );
135 audio
->id
= (substream_type
<< 16) | bdaudio
->pid
;
136 audio
->config
.in
.reg_desc
= STR4_TO_UINT32("HDMV");
137 audio
->config
.in
.stream_type
= bdaudio
->coding_type
;
138 audio
->config
.in
.substream_type
= substream_type
;
139 audio
->config
.in
.codec
= codec
;
140 audio
->config
.in
.codec_param
= codec_param
;
142 switch( audio
->config
.in
.codec
)
152 if( audio
->config
.in
.codec
& HB_ACODEC_FF_MASK
)
154 switch( bdaudio
->coding_type
)
156 case BLURAY_STREAM_TYPE_AUDIO_AC3PLUS
:
157 codec_name
= "E-AC3";
159 case BLURAY_STREAM_TYPE_AUDIO_DTSHD
:
160 codec_name
= "DTS-HD HRA";
162 case BLURAY_STREAM_TYPE_AUDIO_DTSHD_MASTER
:
163 codec_name
= "DTS-HD MA";
165 case BLURAY_STREAM_TYPE_AUDIO_LPCM
:
166 codec_name
= "BD LPCM";
168 case BLURAY_STREAM_TYPE_AUDIO_MPEG1
:
169 codec_name
= "MPEG1";
171 case BLURAY_STREAM_TYPE_AUDIO_MPEG2
:
172 codec_name
= "MPEG2";
174 case BLURAY_STREAM_TYPE_AUDIO_TRUHD
:
175 codec_name
= "TrueHD";
178 codec_name
= "Unknown FFmpeg";
184 codec_name
= "Unknown";
190 lang
= lang_for_code2( (char*)bdaudio
->lang
);
192 audio
->config
.lang
.type
= 0;
194 snprintf( audio
->config
.lang
.simple
,
195 sizeof( audio
->config
.lang
.simple
), "%s",
196 strlen( lang
->native_name
) ? lang
->native_name
: lang
->eng_name
);
197 snprintf( audio
->config
.lang
.iso639_2
,
198 sizeof( audio
->config
.lang
.iso639_2
), "%s", lang
->iso639_2
);
200 hb_log("bd: audio id=0x%x, lang=%s (%s), 3cc=%s", audio
->id
,
201 audio
->config
.lang
.simple
, codec_name
, audio
->config
.lang
.iso639_2
);
203 audio
->config
.in
.track
= track
;
204 hb_list_add( list_audio
, audio
);
208 static int bd_audio_equal( BLURAY_CLIP_INFO
*a
, BLURAY_CLIP_INFO
*b
)
212 if ( a
->audio_stream_count
!= b
->audio_stream_count
)
215 if ( a
->audio_stream_count
== 0 )
218 for ( ii
= 0; ii
< a
->audio_stream_count
; ii
++ )
220 BLURAY_STREAM_INFO
* s
= &a
->audio_streams
[ii
];
222 for ( jj
= 0; jj
< b
->audio_stream_count
; jj
++ )
224 if ( s
->pid
== b
->audio_streams
[jj
].pid
&&
225 s
->coding_type
== b
->audio_streams
[jj
].coding_type
)
237 /***********************************************************************
239 **********************************************************************/
240 hb_title_t
* hb_bd_title_scan( hb_bd_t
* d
, int tt
, uint64_t min_duration
)
244 hb_chapter_t
* chapter
;
246 BLURAY_TITLE_INFO
* ti
= NULL
;
248 hb_log( "bd: scanning title %d", tt
);
250 title
= hb_title_init( d
->path
, tt
);
251 title
->demuxer
= HB_TS_DEMUXER
;
252 title
->type
= HB_BD_TYPE
;
253 title
->reg_desc
= STR4_TO_UINT32("HDMV");
255 char * p_cur
, * p_last
= d
->path
;
256 for( p_cur
= d
->path
; *p_cur
; p_cur
++ )
258 if( IS_DIR_SEP(p_cur
[0]) && p_cur
[1] )
263 snprintf( title
->name
, sizeof( title
->name
), "%s", p_last
);
264 char *dot_term
= strrchr(title
->name
, '.');
271 ti
= d
->title_info
[tt
- 1];
274 hb_log( "bd: invalid title" );
277 if ( ti
->clip_count
== 0 )
279 hb_log( "bd: stream has no clips" );
282 if ( ti
->clips
[0].video_stream_count
== 0 )
284 hb_log( "bd: stream has no video" );
288 hb_log( "bd: playlist %05d.MPLS", ti
->playlist
);
289 title
->playlist
= ti
->playlist
;
291 uint64_t pkt_count
= 0;
292 for ( ii
= 0; ii
< ti
->clip_count
; ii
++ )
294 pkt_count
+= ti
->clips
[ii
].pkt_count
;
296 title
->block_start
= 0;
297 title
->block_end
= pkt_count
;
298 title
->block_count
= pkt_count
;
300 title
->angle_count
= ti
->angle_count
;
303 title
->duration
= ti
->duration
;
304 title
->hours
= title
->duration
/ 90000 / 3600;
305 title
->minutes
= ( ( title
->duration
/ 90000 ) % 3600 ) / 60;
306 title
->seconds
= ( title
->duration
/ 90000 ) % 60;
307 hb_log( "bd: duration is %02d:%02d:%02d (%"PRIu64
" ms)",
308 title
->hours
, title
->minutes
, title
->seconds
,
309 title
->duration
/ 90 );
311 /* ignore short titles because they're often stills */
312 if( ti
->duration
< min_duration
)
314 hb_log( "bd: ignoring title (too short)" );
318 BLURAY_STREAM_INFO
* bdvideo
= &ti
->clips
[0].video_streams
[0];
320 title
->video_id
= bdvideo
->pid
;
321 title
->video_stream_type
= bdvideo
->coding_type
;
323 hb_log( "bd: video id=0x%x, stream type=%s, format %s", title
->video_id
,
324 bdvideo
->coding_type
== BLURAY_STREAM_TYPE_VIDEO_MPEG1
? "MPEG1" :
325 bdvideo
->coding_type
== BLURAY_STREAM_TYPE_VIDEO_MPEG2
? "MPEG2" :
326 bdvideo
->coding_type
== BLURAY_STREAM_TYPE_VIDEO_VC1
? "VC-1" :
327 bdvideo
->coding_type
== BLURAY_STREAM_TYPE_VIDEO_H264
? "H.264" :
329 bdvideo
->format
== BLURAY_VIDEO_FORMAT_480I
? "480i" :
330 bdvideo
->format
== BLURAY_VIDEO_FORMAT_576I
? "576i" :
331 bdvideo
->format
== BLURAY_VIDEO_FORMAT_480P
? "480p" :
332 bdvideo
->format
== BLURAY_VIDEO_FORMAT_1080I
? "1080i" :
333 bdvideo
->format
== BLURAY_VIDEO_FORMAT_720P
? "720p" :
334 bdvideo
->format
== BLURAY_VIDEO_FORMAT_1080P
? "1080p" :
335 bdvideo
->format
== BLURAY_VIDEO_FORMAT_576P
? "576p" :
339 switch( bdvideo
->coding_type
)
341 case BLURAY_STREAM_TYPE_VIDEO_MPEG1
:
342 case BLURAY_STREAM_TYPE_VIDEO_MPEG2
:
343 title
->video_codec
= WORK_DECAVCODECV
;
344 title
->video_codec_param
= AV_CODEC_ID_MPEG2VIDEO
;
347 case BLURAY_STREAM_TYPE_VIDEO_VC1
:
348 title
->video_codec
= WORK_DECAVCODECV
;
349 title
->video_codec_param
= AV_CODEC_ID_VC1
;
352 case BLURAY_STREAM_TYPE_VIDEO_H264
:
353 title
->video_codec
= WORK_DECAVCODECV
;
354 title
->video_codec_param
= AV_CODEC_ID_H264
;
358 hb_log( "scan: unknown video codec (0x%x)",
359 bdvideo
->coding_type
);
363 switch ( bdvideo
->aspect
)
365 case BLURAY_ASPECT_RATIO_4_3
:
366 title
->container_dar
.num
= 4;
367 title
->container_dar
.den
= 3;
369 case BLURAY_ASPECT_RATIO_16_9
:
370 title
->container_dar
.num
= 16;
371 title
->container_dar
.den
= 9;
374 hb_log( "bd: unknown aspect" );
377 hb_log("bd: aspect = %d:%d",
378 title
->container_dar
.num
, title
->container_dar
.den
);
381 // Max primary BD audios is 32
384 int audio_clip_index
= 0;
385 if (ti
->clip_count
> 2)
387 // All BD clips are not all required to have the same audio.
388 // But clips that have seamless transition are required
389 // to have the same audio as the previous clip.
390 // So find the clip that has the most other clips with the
392 for ( ii
= 0; ii
< ti
->clip_count
; ii
++ )
395 for ( jj
= 0; jj
< ti
->clip_count
; jj
++ )
397 if ( bd_audio_equal( &ti
->clips
[ii
], &ti
->clips
[jj
] ) )
402 if ( matches
> most_audio
)
404 most_audio
= matches
;
405 audio_clip_index
= ii
;
409 else if (ti
->clip_count
== 2)
411 // If there are only 2 clips, pick audios from the longer clip
412 if (ti
->clips
[0].pkt_count
< ti
->clips
[1].pkt_count
)
413 audio_clip_index
= 1;
416 // Add all the audios found in the above clip.
417 for (ii
= 0; ii
< ti
->clips
[audio_clip_index
].audio_stream_count
; ii
++)
419 BLURAY_STREAM_INFO
* bdaudio
;
421 bdaudio
= &ti
->clips
[audio_clip_index
].audio_streams
[ii
];
423 switch (bdaudio
->coding_type
)
425 case BLURAY_STREAM_TYPE_AUDIO_TRUHD
:
426 // Add 2 audio tracks. One for TrueHD and one for AC-3
427 add_audio(ii
, title
->list_audio
, bdaudio
, HB_SUBSTREAM_BD_AC3
,
428 HB_ACODEC_AC3
, AV_CODEC_ID_AC3
);
429 add_audio(ii
, title
->list_audio
, bdaudio
, HB_SUBSTREAM_BD_TRUEHD
,
430 HB_ACODEC_FFTRUEHD
, AV_CODEC_ID_TRUEHD
);
433 case BLURAY_STREAM_TYPE_AUDIO_DTS
:
434 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
435 HB_ACODEC_DCA
, AV_CODEC_ID_DTS
);
438 case BLURAY_STREAM_TYPE_AUDIO_MPEG2
:
439 case BLURAY_STREAM_TYPE_AUDIO_MPEG1
:
440 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
441 HB_ACODEC_FFMPEG
, AV_CODEC_ID_MP2
);
444 case BLURAY_STREAM_TYPE_AUDIO_AC3PLUS
:
445 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
446 HB_ACODEC_FFEAC3
, AV_CODEC_ID_EAC3
);
449 case BLURAY_STREAM_TYPE_AUDIO_LPCM
:
450 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
451 HB_ACODEC_FFMPEG
, AV_CODEC_ID_PCM_BLURAY
);
454 case BLURAY_STREAM_TYPE_AUDIO_AC3
:
455 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
456 HB_ACODEC_AC3
, AV_CODEC_ID_AC3
);
459 case BLURAY_STREAM_TYPE_AUDIO_DTSHD_MASTER
:
460 case BLURAY_STREAM_TYPE_AUDIO_DTSHD
:
461 // Add 2 audio tracks. One for DTS-HD and one for DTS
462 add_audio(ii
, title
->list_audio
, bdaudio
, HB_SUBSTREAM_BD_DTS
,
463 HB_ACODEC_DCA
, AV_CODEC_ID_DTS
);
464 // DTS-HD is special. The substreams must be concatinated
465 // DTS-core followed by DTS-hd-extensions. Setting
466 // a substream id of 0 says use all substreams.
467 add_audio(ii
, title
->list_audio
, bdaudio
, 0,
468 HB_ACODEC_DCA_HD
, AV_CODEC_ID_DTS
);
472 hb_log("scan: unknown audio pid 0x%x codec 0x%x", bdaudio
->pid
,
473 bdaudio
->coding_type
);
478 // Add all the subtitles found in the above clip.
479 for ( ii
= 0; ii
< ti
->clips
[audio_clip_index
].pg_stream_count
; ii
++ )
481 BLURAY_STREAM_INFO
* bdpgs
;
483 bdpgs
= &ti
->clips
[audio_clip_index
].pg_streams
[ii
];
485 switch( bdpgs
->coding_type
)
487 case BLURAY_STREAM_TYPE_SUB_PG
:
488 add_subtitle(ii
, title
->list_subtitle
, bdpgs
, WORK_DECPGSSUB
);
491 hb_log( "scan: unknown subtitle pid 0x%x codec 0x%x",
492 bdpgs
->pid
, bdpgs
->coding_type
);
498 for ( ii
= 0, jj
= 0; ii
< ti
->chapter_count
; ii
++ )
500 char chapter_title
[80];
502 // Sanity check start time of this chapter.
503 // If it is beyond the end of the title, drop it.
504 if (ti
->chapters
[ii
].start
> ti
->duration
)
506 hb_log("bd: chapter %d invalid start %"PRIu64
", dropping", ii
+1,
507 ti
->chapters
[ii
].start
);
511 chapter
= calloc( sizeof( hb_chapter_t
), 1 );
513 chapter
->index
= ++jj
;
514 sprintf( chapter_title
, "Chapter %d", chapter
->index
);
515 hb_chapter_set_title( chapter
, chapter_title
);
517 chapter
->duration
= ti
->chapters
[ii
].duration
;
518 chapter
->block_start
= ti
->chapters
[ii
].offset
;
520 // Sanity check chapter duration and start times
521 // Have seen some invalid durations in the wild
522 if (ii
< ti
->chapter_count
- 1)
524 // Validate start time
525 if (ti
->chapters
[ii
+1].start
< ti
->chapters
[ii
].start
)
527 hb_log("bd: chapter %d invalid start %"PRIu64
"", ii
+1,
528 ti
->chapters
[ii
+1].start
);
529 ti
->chapters
[ii
+1].start
= ti
->chapters
[ii
].start
+
532 if (ti
->chapters
[ii
+1].start
- ti
->chapters
[ii
].start
!=
535 hb_log("bd: chapter %d invalid duration %"PRIu64
"", ii
+1,
537 chapter
->duration
= ti
->chapters
[ii
+1].start
-
538 ti
->chapters
[ii
].start
;
543 if (ti
->duration
- ti
->chapters
[ii
].start
!= chapter
->duration
)
545 hb_log("bd: chapter %d invalid duration %"PRIu64
"", ii
+1,
547 chapter
->duration
= ti
->duration
- ti
->chapters
[ii
].start
;
551 int seconds
= ( chapter
->duration
+ 45000 ) / 90000;
552 chapter
->hours
= ( seconds
/ 3600 );
553 chapter
->minutes
= ( seconds
% 3600 ) / 60;
554 chapter
->seconds
= ( seconds
% 60 );
556 hb_log( "bd: chap %d packet=%"PRIu64
", %"PRIu64
" ms",
558 chapter
->block_start
,
559 chapter
->duration
/ 90 );
561 hb_list_add( title
->list_chapter
, chapter
);
563 hb_log( "bd: title %d has %d chapters", tt
, ti
->chapter_count
);
565 /* This title is ok so far */
569 hb_title_close( &title
);
576 /***********************************************************************
578 **********************************************************************/
579 int hb_bd_main_feature( hb_bd_t
* d
, hb_list_t
* list_title
)
583 uint64_t longest_duration
= 0;
584 int highest_rank
= 0;
585 int most_chapters
= 0;
586 int rank
[8] = {0, 1, 3, 2, 6, 5, 7, 4};
587 BLURAY_TITLE_INFO
* ti
;
589 for ( ii
= 0; ii
< hb_list_count( list_title
); ii
++ )
591 hb_title_t
* title
= hb_list_item( list_title
, ii
);
592 ti
= d
->title_info
[title
->index
- 1];
595 BLURAY_STREAM_INFO
* bdvideo
= &ti
->clips
[0].video_streams
[0];
596 if ( title
->duration
> longest_duration
* 0.7 && bdvideo
->format
< 8 )
598 if (highest_rank
< rank
[bdvideo
->format
] ||
599 ( title
->duration
> longest_duration
&&
600 highest_rank
== rank
[bdvideo
->format
]))
602 longest
= title
->index
;
603 longest_duration
= title
->duration
;
604 highest_rank
= rank
[bdvideo
->format
];
605 most_chapters
= ti
->chapter_count
;
607 else if (highest_rank
== rank
[bdvideo
->format
] &&
608 title
->duration
== longest_duration
&&
609 ti
->chapter_count
> most_chapters
)
611 longest
= title
->index
;
612 most_chapters
= ti
->chapter_count
;
616 else if ( title
->duration
> longest_duration
)
618 longest_duration
= title
->duration
;
619 longest
= title
->index
;
625 /***********************************************************************
627 ***********************************************************************
628 * Title and chapter start at 1
629 **********************************************************************/
630 int hb_bd_start( hb_bd_t
* d
, hb_title_t
*title
)
634 d
->duration
= title
->duration
;
636 // Calling bd_get_event initializes libbluray event queue.
637 bd_select_title( d
->bd
, d
->title_info
[title
->index
- 1]->idx
);
638 bd_get_event( d
->bd
, &event
);
640 d
->stream
= hb_bd_stream_open( d
->h
, title
);
641 if ( d
->stream
== NULL
)
648 /***********************************************************************
650 ***********************************************************************
652 **********************************************************************/
653 void hb_bd_stop( hb_bd_t
* d
)
655 if( d
->stream
) hb_stream_close( &d
->stream
);
658 /***********************************************************************
660 ***********************************************************************
662 **********************************************************************/
663 int hb_bd_seek( hb_bd_t
* d
, float f
)
665 uint64_t pos
= f
* d
->duration
;
667 bd_seek_time(d
->bd
, pos
);
668 d
->next_chap
= bd_get_current_chapter( d
->bd
) + 1;
669 hb_ts_stream_reset(d
->stream
);
673 int hb_bd_seek_pts( hb_bd_t
* d
, uint64_t pts
)
675 bd_seek_time(d
->bd
, pts
);
676 d
->next_chap
= bd_get_current_chapter( d
->bd
) + 1;
677 hb_ts_stream_reset(d
->stream
);
681 int hb_bd_seek_chapter( hb_bd_t
* d
, int c
)
684 bd_seek_chapter( d
->bd
, c
- 1 );
685 hb_ts_stream_reset(d
->stream
);
689 /***********************************************************************
691 ***********************************************************************
693 **********************************************************************/
694 hb_buffer_t
* hb_bd_read( hb_bd_t
* d
)
701 hb_buffer_t
* out
= NULL
;
702 uint8_t discontinuity
;
708 if ( d
->next_chap
!= d
->chapter
)
710 new_chap
= d
->chapter
= d
->next_chap
;
712 result
= next_packet( d
->bd
, buf
);
715 hb_error("bd: Read Error");
716 pos
= bd_tell( d
->bd
);
717 bd_seek( d
->bd
, pos
+ 192 );
719 if (error_count
> 10)
721 hb_error("bd: Error, too many consecutive read errors");
722 hb_set_work_error(d
->h
, HB_ERROR_READ
);
727 else if ( result
== 0 )
733 while ( bd_get_event( d
->bd
, &event
) )
735 switch ( event
.event
)
737 case BD_EVENT_CHAPTER
:
738 // The muxers expect to only get chapter 2 and above
739 // They write chapter 1 when chapter 2 is detected.
740 d
->next_chap
= event
.param
;
743 case BD_EVENT_PLAYITEM
:
745 hb_deep_log(2, "bd: Playitem %u", event
.param
);
749 bd_read_skip_still( d
->bd
);
756 // buf+4 to skip the BD timestamp at start of packet
757 out
= hb_ts_decode_pkt( d
->stream
, buf
+4, new_chap
, discontinuity
);
764 /***********************************************************************
766 ***********************************************************************
767 * Returns in which chapter the next block to be read is.
768 * Chapter numbers start at 1.
769 **********************************************************************/
770 int hb_bd_chapter( hb_bd_t
* d
)
775 /***********************************************************************
777 ***********************************************************************
778 * Closes and frees everything
779 **********************************************************************/
780 void hb_bd_close( hb_bd_t
** _d
)
787 for ( ii
= 0; ii
< d
->title_count
; ii
++ )
788 bd_free_title_info( d
->title_info
[ii
] );
789 free( d
->title_info
);
791 if( d
->stream
) hb_stream_close( &d
->stream
);
792 if( d
->bd
) bd_close( d
->bd
);
793 if( d
->path
) free( d
->path
);
799 /***********************************************************************
801 ***********************************************************************
802 * Sets the angle to read
803 **********************************************************************/
804 void hb_bd_set_angle( hb_bd_t
* d
, int angle
)
807 if ( !bd_select_angle( d
->bd
, angle
) )
809 hb_log("bd_select_angle failed");
813 static int check_ts_sync(const uint8_t *buf
)
815 // must have initial sync byte, no scrambling & a legal adaptation ctrl
816 return (buf
[0] == 0x47) && ((buf
[3] >> 6) == 0) && ((buf
[3] >> 4) > 0);
819 static int have_ts_sync(const uint8_t *buf
, int psize
)
821 return check_ts_sync(&buf
[0*psize
]) && check_ts_sync(&buf
[1*psize
]) &&
822 check_ts_sync(&buf
[2*psize
]) && check_ts_sync(&buf
[3*psize
]) &&
823 check_ts_sync(&buf
[4*psize
]) && check_ts_sync(&buf
[5*psize
]) &&
824 check_ts_sync(&buf
[6*psize
]) && check_ts_sync(&buf
[7*psize
]);
827 #define MAX_HOLE 192*80
829 static uint64_t align_to_next_packet(BLURAY
*bd
, uint8_t *pkt
)
832 uint8_t buf
[MAX_HOLE
];
834 uint64_t start
= bd_tell(bd
);
838 memcpy(buf
, pkt
, 192);
839 if ( start
>= 192 ) {
846 result
= bd_read(bd
, buf
+ off
, sizeof(buf
) - off
);
847 if (result
== sizeof(buf
) - off
)
849 const uint8_t *bp
= buf
;
852 for ( i
= sizeof(buf
) - 8 * 192; --i
>= 0; ++bp
)
854 if ( have_ts_sync( bp
, 192 ) )
865 memcpy(buf
, buf
+ sizeof(buf
) - off
, off
);
866 start
+= sizeof(buf
) - off
;
877 off
= start
+ pos
- 4;
878 // bd_seek seeks to the nearest access unit *before* the requested position
879 // we don't want to seek backwards, so we need to read until we get
880 // past that position.
882 while (off
> bd_tell(bd
))
884 result
= bd_read(bd
, buf
, 192);
889 else if (result
!= 192)
894 return start
- orig
+ pos
;
897 static int next_packet( BLURAY
*bd
, uint8_t *pkt
)
903 result
= bd_read( bd
, pkt
, 192 );
912 // Sync byte is byte 4. 0-3 are timestamp.
917 // lost sync - back up to where we started then try to re-establish.
918 uint64_t pos
= bd_tell(bd
);
919 uint64_t pos2
= align_to_next_packet(bd
, pkt
);
926 hb_log("next_packet: eof while re-establishing sync @ %"PRIu64
"", pos
);
929 hb_log("next_packet: sync lost @ %"PRIu64
", regained after %"PRIu64
" bytes",
934 static int title_info_compare_mpls(const void *va
, const void *vb
)
936 BLURAY_TITLE_INFO
*a
, *b
;
938 a
= *(BLURAY_TITLE_INFO
**)va
;
939 b
= *(BLURAY_TITLE_INFO
**)vb
;
941 return a
->playlist
- b
->playlist
;