1 /* $Id: dvd.c,v 1.12 2005/11/25 15:05:25 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
11 #include "dvdread/ifo_read.h"
12 #include "dvdread/ifo_print.h"
13 #include "dvdread/nav_read.h"
15 static hb_dvd_t * hb_dvdread_init( char * path );
16 static void hb_dvdread_close( hb_dvd_t ** _d );
17 static char * hb_dvdread_name( char * path );
18 static int hb_dvdread_title_count( hb_dvd_t * d );
19 static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * d, int t, uint64_t min_duration );
20 static int hb_dvdread_start( hb_dvd_t * d, hb_title_t *title, int chapter );
21 static void hb_dvdread_stop( hb_dvd_t * d );
22 static int hb_dvdread_seek( hb_dvd_t * d, float f );
23 static int hb_dvdread_read( hb_dvd_t * d, hb_buffer_t * b );
24 static int hb_dvdread_chapter( hb_dvd_t * d );
25 static int hb_dvdread_angle_count( hb_dvd_t * d );
26 static void hb_dvdread_set_angle( hb_dvd_t * d, int angle );
27 static int hb_dvdread_main_feature( hb_dvd_t * d, hb_list_t * list_title );
29 hb_dvd_func_t hb_dvdread_func =
34 hb_dvdread_title_count,
35 hb_dvdread_title_scan,
41 hb_dvdread_angle_count,
43 hb_dvdread_main_feature
46 static hb_dvd_func_t *dvd_methods = &hb_dvdread_func;
48 /***********************************************************************
50 **********************************************************************/
51 static void FindNextCell( hb_dvdread_t * );
52 static int dvdtime2msec( dvd_time_t * );
53 static int hb_dvdread_is_break( hb_dvdread_t * d );
55 hb_dvd_func_t * hb_dvdread_methods( void )
57 return &hb_dvdread_func;
60 static int hb_dvdread_main_feature( hb_dvd_t * e, hb_list_t * list_title )
63 uint64_t longest_duration = 0;
66 for ( ii = 0; ii < hb_list_count( list_title ); ii++ )
68 hb_title_t * title = hb_list_item( list_title, ii );
69 if ( title->duration > longest_duration )
71 longest_duration = title->duration;
72 longest = title->index;
78 static char * hb_dvdread_name( char * path )
80 static char name[1024];
81 unsigned char unused[1024];
82 dvd_reader_t * reader;
84 reader = DVDOpen( path );
90 if( DVDUDFVolumeInfo( reader, name, sizeof( name ),
91 unused, sizeof( unused ) ) )
101 /***********************************************************************
103 ***********************************************************************
105 **********************************************************************/
106 hb_dvd_t * hb_dvdread_init( char * path )
112 e = calloc( sizeof( hb_dvd_t ), 1 );
115 /* Log DVD drive region code */
116 if ( hb_dvd_region( path, ®ion_mask ) == 0 )
118 hb_log( "dvd: Region mask 0x%02x", region_mask );
119 if ( region_mask == 0xFF )
121 hb_log( "dvd: Warning, DVD device has no region set" );
126 if( !( d->reader = DVDOpen( path ) ) )
129 * Not an error, may be a stream - which we'll try in a moment.
131 hb_log( "dvd: not a dvd - trying as a stream/file instead" );
136 if( !( d->vmg = ifoOpen( d->reader, 0 ) ) )
138 hb_error( "dvd: ifoOpen failed" );
142 d->path = strdup( path );
147 if( d->vmg ) ifoClose( d->vmg );
148 if( d->reader ) DVDClose( d->reader );
153 /***********************************************************************
154 * hb_dvdread_title_count
155 **********************************************************************/
156 static int hb_dvdread_title_count( hb_dvd_t * e )
158 hb_dvdread_t *d = &(e->dvdread);
159 return d->vmg->tt_srpt->nr_of_srpts;
162 /***********************************************************************
163 * hb_dvdread_title_scan
164 **********************************************************************/
165 static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_duration )
168 hb_dvdread_t *d = &(e->dvdread);
170 ifo_handle_t * vts = NULL;
172 hb_chapter_t * chapter;
175 float duration_correction;
176 unsigned char unused[1024];
178 hb_log( "scan: scanning title %d", t );
180 title = hb_title_init( d->path, t );
181 title->type = HB_DVD_TYPE;
183 if( DVDUDFVolumeInfo( d->reader, title->name, sizeof( title->name ),
184 unused, sizeof( unused ) ) )
186 char * p_cur, * p_last = d->path;
187 for( p_cur = d->path; *p_cur; p_cur++ )
189 if( p_cur[0] == '/' && p_cur[1] )
194 snprintf( title->name, sizeof( title->name ), "%s", p_last );
197 /* VTS which our title is in */
198 title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
202 /* A VTS of 0 means the title wasn't found in the title set */
203 hb_error("Invalid VTS (title set) number: %i", title->vts);
207 hb_log( "scan: opening IFO for VTS %d", title->vts );
208 if( !( vts = ifoOpen( d->reader, title->vts ) ) )
210 hb_error( "scan: ifoOpen failed" );
214 /* ignore titles with bogus cell addresses so we don't abort later
216 for ( i = 0; i < vts->vts_c_adt->nr_of_vobs; ++i)
218 if( (vts->vts_c_adt->cell_adr_table[i].start_sector & 0xffffff ) ==
221 hb_error( "scan: cell_adr_table[%d].start_sector invalid (0x%x) "
222 "- skipping title", i,
223 vts->vts_c_adt->cell_adr_table[i].start_sector );
226 if( (vts->vts_c_adt->cell_adr_table[i].last_sector & 0xffffff ) ==
229 hb_error( "scan: cell_adr_table[%d].last_sector invalid (0x%x) "
230 "- skipping title", i,
231 vts->vts_c_adt->cell_adr_table[i].last_sector );
234 if( vts->vts_c_adt->cell_adr_table[i].start_sector >=
235 vts->vts_c_adt->cell_adr_table[i].last_sector )
237 hb_error( "scan: cell_adr_table[%d].start_sector (0x%x) "
238 "is not before last_sector (0x%x) - skipping title", i,
239 vts->vts_c_adt->cell_adr_table[i].start_sector,
240 vts->vts_c_adt->cell_adr_table[i].last_sector );
245 if( global_verbosity_level == 3 )
247 ifo_print( d->reader, title->vts );
250 /* Position of the title in the VTS */
251 title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
252 if ( title->ttn < 1 || title->ttn > vts->vts_ptt_srpt->nr_of_srpts )
254 hb_error( "invalid VTS PTT offset %d for title %d, skipping", title->ttn, t );
259 pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
260 if ( pgc_id < 1 || pgc_id > vts->vts_pgcit->nr_of_pgci_srp )
262 hb_error( "invalid PGC ID %d for title %d, skipping", pgc_id, t );
265 pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
266 d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
268 hb_log("pgc_id: %d, pgn: %d: pgc: %p", pgc_id, pgn, d->pgc);
272 hb_error( "scan: pgc not valid, skipping" );
276 if( pgn <= 0 || pgn > 99 )
278 hb_error( "scan: pgn %d not valid, skipping", pgn );
283 title->cell_start = d->pgc->program_map[pgn-1] - 1;
284 title->block_start = d->pgc->cell_playback[title->cell_start].first_sector;
287 title->cell_end = d->pgc->nr_of_cells - 1;
288 title->block_end = d->pgc->cell_playback[title->cell_end].last_sector;
291 title->block_count = 0;
292 d->cell_cur = title->cell_start;
293 while( d->cell_cur <= title->cell_end )
295 #define cp d->pgc->cell_playback[d->cell_cur]
296 title->block_count += cp.last_sector + 1 - cp.first_sector;
299 d->cell_cur = d->cell_next;
302 hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
303 "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
304 title->cell_end, title->block_start, title->block_end,
305 title->block_count );
308 title->duration = 90LL * dvdtime2msec( &d->pgc->playback_time );
309 title->hours = title->duration / 90000 / 3600;
310 title->minutes = ( ( title->duration / 90000 ) % 3600 ) / 60;
311 title->seconds = ( title->duration / 90000 ) % 60;
312 hb_log( "scan: duration is %02d:%02d:%02d (%"PRId64" ms)",
313 title->hours, title->minutes, title->seconds,
314 title->duration / 90 );
316 /* ignore titles under 10 seconds because they're often stills or
317 * clips with no audio & our preview code doesn't currently handle
318 * either of these. */
319 if( title->duration < min_duration )
321 hb_log( "scan: ignoring title (too short)" );
325 /* Detect languages */
326 for( i = 0; i < vts->vtsi_mat->nr_of_vts_audio_streams; i++ )
328 hb_audio_t * audio, * audio_tmp;
329 int audio_format, lang_code, audio_control,
331 iso639_lang_t * lang;
332 int lang_extension = 0;
334 hb_log( "scan: checking audio %d", i + 1 );
336 audio = calloc( sizeof( hb_audio_t ), 1 );
338 audio_format = vts->vtsi_mat->vts_audio_attr[i].audio_format;
339 lang_code = vts->vtsi_mat->vts_audio_attr[i].lang_code;
340 lang_extension = vts->vtsi_mat->vts_audio_attr[i].code_extension;
342 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i];
344 if( !( audio_control & 0x8000 ) )
346 hb_log( "scan: audio channel is not active" );
351 position = ( audio_control & 0x7F00 ) >> 8;
353 switch( audio_format )
356 audio->id = ( ( 0x80 + position ) << 8 ) | 0xbd;
357 audio->config.in.codec = HB_ACODEC_AC3;
362 audio->id = 0xc0 + position;
363 audio->config.in.codec = HB_ACODEC_MPGA;
367 audio->id = ( ( 0xa0 + position ) << 8 ) | 0xbd;
368 audio->config.in.codec = HB_ACODEC_LPCM;
372 audio->id = ( ( 0x88 + position ) << 8 ) | 0xbd;
373 audio->config.in.codec = HB_ACODEC_DCA;
378 audio->config.in.codec = 0;
379 hb_log( "scan: unknown audio codec (%x)",
388 /* Check for duplicate tracks */
390 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
392 audio_tmp = hb_list_item( title->list_audio, j );
393 if( audio->id == audio_tmp->id )
401 hb_log( "scan: duplicate audio track" );
406 audio->config.lang.type = lang_extension;
408 lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code );
410 snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)",
411 strlen(lang->native_name) ? lang->native_name : lang->eng_name,
412 audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec ==
413 HB_ACODEC_DCA ? "DTS" : ( audio->config.in.codec ==
414 HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );
415 snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s",
416 strlen(lang->native_name) ? lang->native_name : lang->eng_name );
417 snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s",
420 switch( lang_extension )
426 strcat( audio->config.lang.description, " (Visually Impaired)" );
429 strcat( audio->config.lang.description, " (Director's Commentary 1)" );
432 strcat( audio->config.lang.description, " (Director's Commentary 2)" );
438 hb_log( "scan: id=%x, lang=%s, 3cc=%s ext=%i", audio->id,
439 audio->config.lang.description, audio->config.lang.iso639_2,
442 audio->config.in.track = i;
443 hb_list_add( title->list_audio, audio );
446 /* Check for subtitles */
447 for( i = 0; i < vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
449 hb_subtitle_t * subtitle;
452 iso639_lang_t * lang;
453 int lang_extension = 0;
455 hb_log( "scan: checking subtitle %d", i + 1 );
458 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i];
460 if( !( spu_control & 0x80000000 ) )
462 hb_log( "scan: subtitle channel is not active" );
466 if( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
468 switch( vts->vtsi_mat->vts_video_attr.permitted_df )
471 position = spu_control & 0xFF;
474 position = ( spu_control >> 8 ) & 0xFF;
477 position = ( spu_control >> 16 ) & 0xFF;
482 position = ( spu_control >> 24 ) & 0x7F;
485 lang_extension = vts->vtsi_mat->vts_subp_attr[i].code_extension;
487 lang = lang_for_code( vts->vtsi_mat->vts_subp_attr[i].lang_code );
489 subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
490 subtitle->track = i+1;
491 subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd;
492 snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s",
493 strlen(lang->native_name) ? lang->native_name : lang->eng_name);
494 snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "%s",
496 subtitle->format = PICTURESUB;
497 subtitle->source = VOBSUB;
498 subtitle->config.dest = RENDERSUB; // By default render (burn-in) the VOBSUB.
500 subtitle->type = lang_extension;
502 memcpy( subtitle->palette,
503 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
504 16 * sizeof( uint32_t ) );
506 switch( lang_extension )
513 strcat( subtitle->lang, " (Caption with bigger size character)");
516 strcat( subtitle->lang, " (Caption for Children)");
521 strcat( subtitle->lang, " (Closed Caption)");
524 strcat( subtitle->lang, " (Closed Caption with bigger size character)");
527 strcat( subtitle->lang, " (Closed Caption for Children)");
532 strcat( subtitle->lang, " (Forced Caption)");
541 strcat( subtitle->lang, " (Director's Commentary)");
544 strcat( subtitle->lang, " (Director's Commentary with bigger size character)");
547 strcat( subtitle->lang, " (Director's Commentary for Children)");
552 hb_log( "scan: id=%x, lang=%s, 3cc=%s", subtitle->id,
553 subtitle->lang, subtitle->iso639_2 );
555 hb_list_add( title->list_subtitle, subtitle );
559 hb_log( "scan: title %d has %d chapters", t,
560 vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts );
562 i < vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
564 chapter = calloc( sizeof( hb_chapter_t ), 1 );
565 /* remember the on-disc chapter number */
566 chapter->index = i + 1;
568 pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
569 pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
570 d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
573 chapter->cell_start = d->pgc->program_map[pgn-1] - 1;
574 chapter->block_start =
575 d->pgc->cell_playback[chapter->cell_start].first_sector;
577 // if there are no more programs in this pgc, the end cell is the
578 // last cell. Otherwise it's the cell before the start cell of the
580 if ( pgn == d->pgc->nr_of_programs )
582 chapter->cell_end = d->pgc->nr_of_cells - 1;
586 chapter->cell_end = d->pgc->program_map[pgn] - 2;;
588 chapter->block_end = d->pgc->cell_playback[chapter->cell_end].last_sector;
590 /* Block count, duration */
591 chapter->block_count = 0;
592 chapter->duration = 0;
594 d->cell_cur = chapter->cell_start;
595 while( d->cell_cur <= chapter->cell_end )
597 #define cp d->pgc->cell_playback[d->cell_cur]
598 chapter->block_count += cp.last_sector + 1 - cp.first_sector;
599 chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
602 d->cell_cur = d->cell_next;
604 hb_list_add( title->list_chapter, chapter );
608 /* The durations we get for chapters aren't precise. Scale them so
609 the total matches the title duration */
611 for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
613 chapter = hb_list_item( title->list_chapter, i );
614 duration += chapter->duration;
616 duration_correction = (float) title->duration / (float) duration;
617 for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
620 chapter = hb_list_item( title->list_chapter, i );
621 chapter->duration = duration_correction * chapter->duration;
622 seconds = ( chapter->duration + 45000 ) / 90000;
623 chapter->hours = seconds / 3600;
624 chapter->minutes = ( seconds % 3600 ) / 60;
625 chapter->seconds = seconds % 60;
627 hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
628 chapter->index, chapter->cell_start, chapter->cell_end,
629 chapter->block_start, chapter->block_end,
630 chapter->block_count, chapter->duration / 90 );
633 /* Get aspect. We don't get width/height/rate infos here as
634 they tend to be wrong */
635 switch( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
638 title->container_aspect = 4. / 3.;
641 title->container_aspect = 16. / 9.;
644 hb_log( "scan: unknown aspect" );
648 hb_log( "scan: aspect = %g", title->aspect );
650 /* This title is ok so far */
654 hb_list_close( &title->list_audio );
659 if( vts ) ifoClose( vts );
664 /***********************************************************************
666 ***********************************************************************
667 * Title and chapter start at 1
668 **********************************************************************/
669 static int hb_dvdread_start( hb_dvd_t * e, hb_title_t *title, int chapter )
671 hb_dvdread_t *d = &(e->dvdread);
674 int t = title->index;
676 /* Open the IFO and the VOBs for this title */
677 d->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
678 d->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
679 if( !( d->ifo = ifoOpen( d->reader, d->vts ) ) )
681 hb_error( "dvd: ifoOpen failed for VTS %d", d->vts );
684 if( !( d->file = DVDOpenFile( d->reader, d->vts,
685 DVD_READ_TITLE_VOBS ) ) )
687 hb_error( "dvd: DVDOpenFile failed for VTS %d", d->vts );
691 /* Get title first and last blocks */
692 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgcn;
693 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgn;
694 d->pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
695 d->cell_start = d->pgc->program_map[pgn - 1] - 1;
696 d->cell_end = d->pgc->nr_of_cells - 1;
697 d->title_start = d->pgc->cell_playback[d->cell_start].first_sector;
698 d->title_end = d->pgc->cell_playback[d->cell_end].last_sector;
701 d->title_block_count = 0;
702 for( i = d->cell_start; i <= d->cell_end; i++ )
704 d->title_block_count += d->pgc->cell_playback[i].last_sector + 1 -
705 d->pgc->cell_playback[i].first_sector;
708 /* Get pgc for the current chapter */
709 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgcn;
710 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgn;
711 d->pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
713 /* Get the two first cells */
714 d->cell_cur = d->pgc->program_map[pgn-1] - 1;
717 d->block = d->pgc->cell_playback[d->cell_cur].first_sector;
718 d->next_vobu = d->block;
727 /***********************************************************************
729 ***********************************************************************
731 **********************************************************************/
732 static void hb_dvdread_stop( hb_dvd_t * e )
734 hb_dvdread_t *d = &(e->dvdread);
742 DVDCloseFile( d->file );
747 /***********************************************************************
749 ***********************************************************************
751 **********************************************************************/
752 static int hb_dvdread_seek( hb_dvd_t * e, float f )
754 hb_dvdread_t *d = &(e->dvdread);
758 count = f * d->title_block_count;
760 for( i = d->cell_start; i <= d->cell_end; i++ )
762 sizeCell = d->pgc->cell_playback[i].last_sector + 1 -
763 d->pgc->cell_playback[i].first_sector;
765 if( count < sizeCell )
771 /* Now let hb_dvdread_read find the next VOBU */
772 d->next_vobu = d->pgc->cell_playback[i].first_sector + count;
780 if( i > d->cell_end )
786 * Assume that we are in sync, even if we are not given that it is obvious
787 * that we are out of sync if we have just done a seek.
795 /***********************************************************************
797 ***********************************************************************/
798 int is_nav_pack( unsigned char *buf )
801 * The NAV Pack is comprised of the PCI Packet and DSI Packet, both
802 * of these start at known offsets and start with a special identifier.
805 * PCI = { 00 00 01 bf # private stream header
810 * DSI = { 00 00 01 bf # private stream header
816 * The PCI starts at offset 0x26 into the sector, and the DSI starts at 0x400
818 * This information from: http://dvd.sourceforge.net/dvdinfo/
820 if( ( buf[0x26] == 0x00 && // PCI
824 buf[0x2c] == 0x00 ) &&
825 ( buf[0x400] == 0x00 && // DSI
826 buf[0x401] == 0x00 &&
827 buf[0x402] == 0x01 &&
828 buf[0x403] == 0xbf &&
829 buf[0x406] == 0x01 ) )
838 /***********************************************************************
840 ***********************************************************************
842 **********************************************************************/
843 static int hb_dvdread_read( hb_dvd_t * e, hb_buffer_t * b )
845 hb_dvdread_t *d = &(e->dvdread);
853 // if we've just finished the last cell of the title we don't
854 // want to read another block because our next_vobu pointer
855 // is probably invalid. Just return 'no data' & our caller
856 // should check and discover we're at eof.
857 if ( d->cell_cur > d->cell_end )
862 int block, pack_len, next_vobu, read_retry;
864 for( read_retry = 1; read_retry < 1024; read_retry++ )
866 if( DVDReadBlocks( d->file, d->next_vobu, 1, b->data ) == 1 )
871 if( read_retry > 1 && !is_nav_pack( b->data) )
873 // But wasn't a nav pack, so carry on looking
880 // First retry the same block, then try the next one,
881 // adjust the skip increment upwards so that we can skip
882 // large sections of bad blocks more efficiently (at the
883 // cost of some missed good blocks at the end).
884 hb_log( "dvd: vobu read error blk %d - skipping to next blk incr %d",
885 d->next_vobu, (read_retry * 10));
886 d->next_vobu += (read_retry * 10);
891 if( read_retry == 1024 )
893 // That's too many bad blocks, jump to the start of the
895 hb_log( "dvd: vobu read error blk %d - skipping to cell %d",
896 d->next_vobu, d->cell_next );
897 d->cell_cur = d->cell_next;
898 if ( d->cell_cur > d->cell_end )
901 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
907 if ( !is_nav_pack( b->data ) ) {
909 if( d->in_sync == 1 ) {
910 hb_log("dvd: Lost sync, searching for NAV pack at blk %d",
917 navRead_DSI( &dsi_pack, &b->data[DSI_START_BYTE] );
919 if ( d->in_sync == 0 && d->cur_cell_id &&
920 (d->cur_vob_id != dsi_pack.dsi_gi.vobu_vob_idn ||
921 d->cur_cell_id != dsi_pack.dsi_gi.vobu_c_idn ) )
923 // We walked out of the cell we're supposed to be in.
924 // If we're not at the start of our next cell go there.
925 hb_log("dvd: left cell %d (%u,%u) for (%u,%u) at block %u",
926 d->cell_cur, d->cur_vob_id, d->cur_cell_id,
927 dsi_pack.dsi_gi.vobu_vob_idn, dsi_pack.dsi_gi.vobu_c_idn,
929 if ( d->next_vobu != d->pgc->cell_playback[d->cell_next].first_sector )
931 d->next_vobu = d->pgc->cell_playback[d->cell_next].first_sector;
937 block = dsi_pack.dsi_gi.nv_pck_lbn;
938 pack_len = dsi_pack.dsi_gi.vobu_ea;
940 // There are a total of 21 next vobu offsets (and 21 prev_vobu
941 // offsets) in the navpack SRI structure. The primary one is
942 // 'next_vobu' which is the offset (in dvd blocks) from the current
943 // block to the start of the next vobu. If the block at 'next_vobu'
944 // can't be read, 'next_video' is the offset to the vobu closest to it.
945 // The other 19 offsets are vobus at successively longer distances from
946 // the current block (this is so that a hardware player can do
947 // adaptive error recovery to skip over a bad spot on the disk). In all
948 // these offsets the high bit is set to indicate when it contains a
949 // valid offset. The next bit (2^30) is set to indicate that there's
950 // another valid offset in the SRI that's closer to the current block.
951 // A hardware player uses these bits to chose the closest valid offset
952 // and uses that as its next vobu. (Some mastering schemes appear to
953 // put a bogus offset in next_vobu with the 2^30 bit set & the
954 // correct offset in next_video. This works fine in hardware players
955 // but will mess up software that doesn't implement the full next
956 // vobu decision logic.) In addition to the flag bits there's a
957 // reserved value of the offset that indicates 'no next vobu' (which
958 // indicates the end of a cell). But having no next vobu pointer with a
959 // 'valid' bit set also indicates end of cell. Different mastering
960 // schemes seem to use all possible combinations of the flag bits
961 // and reserved values to indicate end of cell so we have to check
962 // them all or we'll get a disk read error from following an
964 uint32_t next_ptr = dsi_pack.vobu_sri.next_vobu;
965 if ( ( next_ptr & ( 1 << 31 ) ) == 0 ||
966 ( next_ptr & ( 1 << 30 ) ) != 0 ||
967 ( next_ptr & 0x3fffffff ) == 0x3fffffff )
969 next_ptr = dsi_pack.vobu_sri.next_video;
970 if ( ( next_ptr & ( 1 << 31 ) ) == 0 ||
971 ( next_ptr & 0x3fffffff ) == 0x3fffffff )
973 // don't have a valid forward pointer - assume end-of-cell
975 d->pack_len = pack_len;
979 next_vobu = block + ( next_ptr & 0x3fffffff );
983 block >= d->next_vobu &&
984 ( block <= d->title_start + d->title_block_count ||
985 block <= d->title_end ) )
988 d->pack_len = pack_len;
989 d->next_vobu = next_vobu;
993 /* Wasn't a valid VOBU, try next block */
996 hb_log( "dvd: couldn't find a VOBU after 1024 blocks" );
1003 if( d->in_sync == 0 || d->in_sync == 2 )
1005 if( d->in_sync == 0 )
1007 hb_log( "dvd: In sync with DVD at block %d", d->block );
1012 // Revert the cell overlap, and check for a chapter break
1013 // If this cell is zero length (prev_vobu & next_vobu both
1014 // set to END_OF_CELL) we need to check for beginning of
1015 // cell before checking for end or we'll advance to the next
1016 // cell too early and fail to generate a chapter mark when this
1017 // cell starts a chapter.
1018 if( ( dsi_pack.vobu_sri.prev_vobu & (1 << 31 ) ) == 0 ||
1019 ( dsi_pack.vobu_sri.prev_vobu & 0x3fffffff ) == 0x3fffffff )
1021 // A vobu that's not at the start of a cell can have an
1022 // EOC prev pointer (this seems to be associated with some
1023 // sort of drm). The rest of the content in the cell may be
1024 // booby-trapped so treat this like an end-of-cell rather
1025 // than a beginning of cell.
1026 if ( d->pgc->cell_playback[d->cell_cur].first_sector < dsi_pack.dsi_gi.nv_pck_lbn &&
1027 d->pgc->cell_playback[d->cell_cur].last_sector >= dsi_pack.dsi_gi.nv_pck_lbn )
1029 hb_log( "dvd: null prev_vobu in cell %d at block %d", d->cell_cur,
1031 // treat like end-of-cell then go directly to start of next cell.
1032 d->cell_cur = d->cell_next;
1034 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1036 d->cell_overlap = 1;
1041 if ( d->block != d->pgc->cell_playback[d->cell_cur].first_sector )
1043 hb_log( "dvd: beginning of cell %d at block %d", d->cell_cur,
1048 hb_error( "dvd: assuming missed end of cell %d at block %d", d->cell_cur, d->block );
1049 d->cell_cur = d->cell_next;
1050 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1052 d->cell_overlap = 1;
1057 d->cur_vob_id = dsi_pack.dsi_gi.vobu_vob_idn;
1058 d->cur_cell_id = dsi_pack.dsi_gi.vobu_c_idn;
1060 if( d->cell_overlap )
1062 b->new_chap = hb_dvdread_is_break( d );
1063 d->cell_overlap = 0;
1068 if( ( dsi_pack.vobu_sri.next_vobu & (1 << 31 ) ) == 0 ||
1069 ( dsi_pack.vobu_sri.next_vobu & 0x3fffffff ) == 0x3fffffff )
1071 if ( d->block <= d->pgc->cell_playback[d->cell_cur].first_sector ||
1072 d->block > d->pgc->cell_playback[d->cell_cur].last_sector )
1074 hb_log( "dvd: end of cell %d at block %d", d->cell_cur,
1077 d->cell_cur = d->cell_next;
1079 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1081 d->cell_overlap = 1;
1087 if( DVDReadBlocks( d->file, d->block, 1, b->data ) != 1 )
1089 // this may be a real DVD error or may be DRM. Either way
1090 // we don't want to quit because of one bad block so set
1091 // things up so we'll advance to the next vobu and recurse.
1092 hb_error( "dvd: DVDReadBlocks failed (%d), skipping to vobu %u",
1093 d->block, d->next_vobu );
1095 goto top; /* XXX need to restructure this routine & avoid goto */
1105 /***********************************************************************
1106 * hb_dvdread_chapter
1107 ***********************************************************************
1108 * Returns in which chapter the next block to be read is.
1109 * Chapter numbers start at 1.
1110 **********************************************************************/
1111 static int hb_dvdread_chapter( hb_dvd_t * e )
1113 hb_dvdread_t *d = &(e->dvdread);
1116 int nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
1119 for( i = nr_of_ptts - 1;
1123 /* Get pgc for chapter (i+1) */
1124 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgcn;
1125 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgn;
1126 pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1128 if( d->cell_cur - d->cell_overlap >= pgc->program_map[pgn-1] - 1 &&
1129 d->cell_cur - d->cell_overlap <= pgc->nr_of_cells - 1 )
1131 /* We are in this chapter */
1140 /***********************************************************************
1141 * hb_dvdread_is_break
1142 ***********************************************************************
1143 * Returns chapter number if the current block is a new chapter start
1144 **********************************************************************/
1145 static int hb_dvdread_is_break( hb_dvdread_t * d )
1149 int nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
1153 for( i = nr_of_ptts - 1;
1157 /* Get pgc for chapter (i+1) */
1158 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgcn;
1159 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgn;
1160 pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1161 cell = pgc->program_map[pgn-1] - 1;
1163 if( cell <= d->cell_start )
1166 // This must not match against the start cell.
1167 if( pgc->cell_playback[cell].first_sector == d->block && cell != d->cell_start )
1176 /***********************************************************************
1178 ***********************************************************************
1179 * Closes and frees everything
1180 **********************************************************************/
1181 static void hb_dvdread_close( hb_dvd_t ** _d )
1183 hb_dvdread_t * d = &((*_d)->dvdread);
1191 DVDClose( d->reader );
1198 /***********************************************************************
1199 * hb_dvdread_angle_count
1200 ***********************************************************************
1201 * Returns the number of angles supported. We do not support angles
1203 **********************************************************************/
1204 static int hb_dvdread_angle_count( hb_dvd_t * d )
1209 /***********************************************************************
1210 * hb_dvdread_set_angle
1211 ***********************************************************************
1212 * Sets the angle to read. Not supported with dvdread
1213 **********************************************************************/
1214 static void hb_dvdread_set_angle( hb_dvd_t * d, int angle )
1218 /***********************************************************************
1220 ***********************************************************************
1221 * Assumes pgc and cell_cur are correctly set, and sets cell_next to the
1222 * cell to be read when we will be done with cell_cur.
1223 **********************************************************************/
1224 static void FindNextCell( hb_dvdread_t * d )
1228 if( d->pgc->cell_playback[d->cell_cur].block_type ==
1229 BLOCK_TYPE_ANGLE_BLOCK )
1232 while( d->pgc->cell_playback[d->cell_cur+i].block_mode !=
1233 BLOCK_MODE_LAST_CELL )
1237 d->cell_next = d->cell_cur + i + 1;
1238 hb_log( "dvd: Skipping multi-angle cells %d-%d",
1244 d->cell_next = d->cell_cur + 1;
1248 /***********************************************************************
1250 ***********************************************************************
1252 **********************************************************************/
1253 static int dvdtime2msec(dvd_time_t * dt)
1255 double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97};
1256 double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6];
1258 ms = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000;
1259 ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
1260 ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;
1264 ms += ((dt->frame_u & 0x30) >> 3) * 5 +
1265 (dt->frame_u & 0x0f) * 1000.0 / fps;
1271 char * hb_dvd_name( char * path )
1273 return dvd_methods->name(path);
1276 hb_dvd_t * hb_dvd_init( char * path )
1278 return dvd_methods->init(path);
1281 int hb_dvd_title_count( hb_dvd_t * d )
1283 return dvd_methods->title_count(d);
1286 hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t, uint64_t min_duration )
1288 return dvd_methods->title_scan(d, t, min_duration);
1291 int hb_dvd_start( hb_dvd_t * d, hb_title_t *title, int chapter )
1293 return dvd_methods->start(d, title, chapter);
1296 void hb_dvd_stop( hb_dvd_t * d )
1298 dvd_methods->stop(d);
1301 int hb_dvd_seek( hb_dvd_t * d, float f )
1303 return dvd_methods->seek(d, f);
1306 int hb_dvd_read( hb_dvd_t * d, hb_buffer_t * b )
1308 return dvd_methods->read(d, b);
1311 int hb_dvd_chapter( hb_dvd_t * d )
1313 return dvd_methods->chapter(d);
1316 void hb_dvd_close( hb_dvd_t ** _d )
1318 dvd_methods->close(_d);
1321 int hb_dvd_angle_count( hb_dvd_t * d )
1323 return dvd_methods->angle_count(d);
1326 void hb_dvd_set_angle( hb_dvd_t * d, int angle )
1328 dvd_methods->set_angle(d, angle);
1331 int hb_dvd_main_feature( hb_dvd_t * d, hb_list_t * list_title )
1333 return dvd_methods->main_feature(d, list_title);
1336 // hb_dvd_set_dvdnav must only be called when no dvd source is open
1337 // it rips the rug out from under things so be careful
1338 void hb_dvd_set_dvdnav( int enable )
1341 dvd_methods = hb_dvdnav_methods();
1343 dvd_methods = hb_dvdread_methods();