WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / dvd.c
blob082057bade3ef540571086621c9ace527f9b151a
1 /* dvd.c
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
8 */
10 #include "hb.h"
11 #include "lang.h"
12 #include "dvd.h"
14 #include "dvdread/ifo_read.h"
15 #include "dvdread/ifo_print.h"
16 #include "dvdread/nav_read.h"
18 static hb_dvd_t * hb_dvdread_init( hb_handle_t * h, char * path );
19 static void hb_dvdread_close( hb_dvd_t ** _d );
20 static char * hb_dvdread_name( char * path );
21 static int hb_dvdread_title_count( hb_dvd_t * d );
22 static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * d, int t, uint64_t min_duration );
23 static int hb_dvdread_start( hb_dvd_t * d, hb_title_t *title, int chapter );
24 static void hb_dvdread_stop( hb_dvd_t * d );
25 static int hb_dvdread_seek( hb_dvd_t * d, float f );
26 static hb_buffer_t * hb_dvdread_read( hb_dvd_t * d );
27 static int hb_dvdread_chapter( hb_dvd_t * d );
28 static int hb_dvdread_angle_count( hb_dvd_t * d );
29 static void hb_dvdread_set_angle( hb_dvd_t * d, int angle );
30 static int hb_dvdread_main_feature( hb_dvd_t * d, hb_list_t * list_title );
32 hb_dvd_func_t hb_dvdread_func =
34 hb_dvdread_init,
35 hb_dvdread_close,
36 hb_dvdread_name,
37 hb_dvdread_title_count,
38 hb_dvdread_title_scan,
39 hb_dvdread_start,
40 hb_dvdread_stop,
41 hb_dvdread_seek,
42 hb_dvdread_read,
43 hb_dvdread_chapter,
44 hb_dvdread_angle_count,
45 hb_dvdread_set_angle,
46 hb_dvdread_main_feature
49 static hb_dvd_func_t *dvd_methods = &hb_dvdread_func;
51 /***********************************************************************
52 * Local prototypes
53 **********************************************************************/
54 static void FindNextCell( hb_dvdread_t * );
55 static int dvdtime2msec( dvd_time_t * );
56 static int hb_dvdread_is_break( hb_dvdread_t * d );
58 hb_dvd_func_t * hb_dvdread_methods( void )
60 return &hb_dvdread_func;
63 static int hb_dvdread_main_feature( hb_dvd_t * e, hb_list_t * list_title )
65 int ii;
66 uint64_t longest_duration = 0;
67 int longest = -1;
69 for ( ii = 0; ii < hb_list_count( list_title ); ii++ )
71 hb_title_t * title = hb_list_item( list_title, ii );
72 if ( title->duration > longest_duration )
74 longest_duration = title->duration;
75 longest = title->index;
78 return longest;
81 static char * hb_dvdread_name( char * path )
83 static char name[1024];
84 unsigned char unused[1024];
85 dvd_reader_t * reader;
87 reader = DVDOpen( path );
88 if( !reader )
90 return NULL;
93 if( DVDUDFVolumeInfo( reader, name, sizeof( name ),
94 unused, sizeof( unused ) ) )
96 DVDClose( reader );
97 return NULL;
100 DVDClose( reader );
101 return name;
104 /***********************************************************************
105 * hb_dvdread_init
106 ***********************************************************************
108 **********************************************************************/
109 hb_dvd_t * hb_dvdread_init( hb_handle_t * h, char * path )
111 hb_dvd_t * e;
112 hb_dvdread_t * d;
113 int region_mask;
114 char * path_ccp;
116 e = calloc( sizeof( hb_dvd_t ), 1 );
117 d = &(e->dvdread);
118 d->h = h;
121 * Convert UTF-8 path to current code page on Windows
122 * hb_utf8_to_cp() is the same as strdup on non-Windows,
123 * so no #ifdef required here
125 path_ccp = hb_utf8_to_cp( path );
127 /* Log DVD drive region code */
128 if ( hb_dvd_region( path_ccp, &region_mask ) == 0 )
130 hb_log( "dvd: Region mask 0x%02x", region_mask );
131 if ( region_mask == 0xFF )
133 hb_log( "dvd: Warning, DVD device has no region set" );
137 /* Open device */
138 if( !( d->reader = DVDOpen( path_ccp ) ) )
141 * Not an error, may be a stream - which we'll try in a moment.
143 hb_log( "dvd: not a dvd - trying as a stream/file instead" );
144 goto fail;
147 /* Open main IFO */
148 if( !( d->vmg = ifoOpen( d->reader, 0 ) ) )
150 hb_log( "dvd: not a dvd - trying as a stream/file instead" );
151 goto fail;
154 d->path = strdup( path ); /* hb_dvdread_title_scan assumes UTF-8 path, so not path_ccp here */
155 free( path_ccp );
157 return e;
159 fail:
160 if( d->vmg ) ifoClose( d->vmg );
161 if( d->reader ) DVDClose( d->reader );
162 free( e );
163 free( path_ccp );
164 return NULL;
167 /***********************************************************************
168 * hb_dvdread_title_count
169 **********************************************************************/
170 static int hb_dvdread_title_count( hb_dvd_t * e )
172 hb_dvdread_t *d = &(e->dvdread);
173 return d->vmg->tt_srpt->nr_of_srpts;
176 /***********************************************************************
177 * hb_dvdread_title_scan
178 **********************************************************************/
179 static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_duration )
182 hb_dvdread_t *d = &(e->dvdread);
183 hb_title_t * title;
184 ifo_handle_t * vts = NULL;
185 int pgc_id, pgn, i;
186 hb_chapter_t * chapter;
187 unsigned char unused[1024];
188 const char * codec_name;
190 hb_log( "scan: scanning title %d", t );
192 title = hb_title_init( d->path, t );
193 title->type = HB_DVD_TYPE;
195 if( DVDUDFVolumeInfo( d->reader, title->name, sizeof( title->name ),
196 unused, sizeof( unused ) ) )
198 char * p_cur, * p_last = d->path;
199 for( p_cur = d->path; *p_cur; p_cur++ )
201 if( IS_DIR_SEP(p_cur[0]) && p_cur[1] )
203 p_last = &p_cur[1];
206 snprintf( title->name, sizeof( title->name ), "%s", p_last );
207 char *dot_term = strrchr(title->name, '.');
208 if (dot_term)
209 *dot_term = '\0';
212 /* VTS which our title is in */
213 title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
215 if ( !title->vts )
217 /* A VTS of 0 means the title wasn't found in the title set */
218 hb_log("Invalid VTS (title set) number: %i", title->vts);
219 goto fail;
222 hb_log( "scan: opening IFO for VTS %d", title->vts );
223 if( !( vts = ifoOpen( d->reader, title->vts ) ) )
225 hb_log( "scan: ifoOpen failed" );
226 goto fail;
229 /* ignore titles with bogus cell addresses so we don't abort later
230 * in libdvdread. */
231 for ( i = 0; i < vts->vts_c_adt->nr_of_vobs; ++i)
233 if( (vts->vts_c_adt->cell_adr_table[i].start_sector & 0xffffff ) ==
234 0xffffff )
236 hb_log( "scan: cell_adr_table[%d].start_sector invalid (0x%x) "
237 "- skipping title", i,
238 vts->vts_c_adt->cell_adr_table[i].start_sector );
239 goto fail;
241 if( (vts->vts_c_adt->cell_adr_table[i].last_sector & 0xffffff ) ==
242 0xffffff )
244 hb_log( "scan: cell_adr_table[%d].last_sector invalid (0x%x) "
245 "- skipping title", i,
246 vts->vts_c_adt->cell_adr_table[i].last_sector );
247 goto fail;
249 if( vts->vts_c_adt->cell_adr_table[i].start_sector >=
250 vts->vts_c_adt->cell_adr_table[i].last_sector )
252 hb_log( "scan: cell_adr_table[%d].start_sector (0x%x) "
253 "is not before last_sector (0x%x) - skipping title", i,
254 vts->vts_c_adt->cell_adr_table[i].start_sector,
255 vts->vts_c_adt->cell_adr_table[i].last_sector );
256 goto fail;
260 if( global_verbosity_level == 3 )
262 ifo_print( d->reader, title->vts );
265 /* Position of the title in the VTS */
266 title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
267 if ( title->ttn < 1 || title->ttn > vts->vts_ptt_srpt->nr_of_srpts )
269 hb_log( "invalid VTS PTT offset %d for title %d, skipping", title->ttn, t );
270 goto fail;
273 /* Get pgc */
274 pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
275 if ( pgc_id < 1 || pgc_id > vts->vts_pgcit->nr_of_pgci_srp )
277 hb_log( "invalid PGC ID %d for title %d, skipping", pgc_id, t );
278 goto fail;
280 pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
281 d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
283 hb_log("pgc_id: %d, pgn: %d: pgc: %p", pgc_id, pgn, d->pgc);
285 if( !d->pgc || !d->pgc->program_map )
287 hb_log( "scan: pgc not valid, skipping" );
288 goto fail;
291 if (d->pgc->cell_playback == NULL)
293 hb_log( "invalid PGC cell_playback table for title %d, skipping", t );
294 goto fail;
297 if( pgn <= 0 || pgn > 99 )
299 hb_log( "scan: pgn %d not valid, skipping", pgn );
300 goto fail;
303 /* Start cell */
304 title->cell_start = d->pgc->program_map[pgn-1] - 1;
305 title->block_start = d->pgc->cell_playback[title->cell_start].first_sector;
307 /* End cell */
308 title->cell_end = d->pgc->nr_of_cells - 1;
309 title->block_end = d->pgc->cell_playback[title->cell_end].last_sector;
311 /* Block count */
312 title->block_count = 0;
313 d->cell_cur = title->cell_start;
314 while( d->cell_cur <= title->cell_end )
316 #define cp d->pgc->cell_playback[d->cell_cur]
317 title->block_count += cp.last_sector + 1 - cp.first_sector;
318 #undef cp
319 FindNextCell( d );
320 d->cell_cur = d->cell_next;
323 hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
324 "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
325 title->cell_end, title->block_start, title->block_end,
326 title->block_count );
328 /* Get duration */
329 title->duration = 90LL * dvdtime2msec( &d->pgc->playback_time );
330 title->hours = title->duration / 90000 / 3600;
331 title->minutes = ( ( title->duration / 90000 ) % 3600 ) / 60;
332 title->seconds = ( title->duration / 90000 ) % 60;
333 hb_log( "scan: duration is %02d:%02d:%02d (%"PRId64" ms)",
334 title->hours, title->minutes, title->seconds,
335 title->duration / 90 );
337 /* ignore titles under 10 seconds because they're often stills or
338 * clips with no audio & our preview code doesn't currently handle
339 * either of these. */
340 if( title->duration < min_duration )
342 hb_log( "scan: ignoring title (too short)" );
343 goto fail;
346 /* Detect languages */
347 for( i = 0; i < vts->vtsi_mat->nr_of_vts_audio_streams; i++ )
349 int audio_format, lang_code, lang_extension, audio_control, position, j;
350 hb_audio_t * audio, * audio_tmp;
351 iso639_lang_t * lang;
353 hb_log( "scan: checking audio %d", i + 1 );
355 audio = calloc( sizeof( hb_audio_t ), 1 );
357 audio_format = vts->vtsi_mat->vts_audio_attr[i].audio_format;
358 lang_code = vts->vtsi_mat->vts_audio_attr[i].lang_code;
359 lang_extension = vts->vtsi_mat->vts_audio_attr[i].code_extension;
360 audio_control =
361 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i];
363 if( !( audio_control & 0x8000 ) )
365 hb_log( "scan: audio channel is not active" );
366 free( audio );
367 continue;
370 position = ( audio_control & 0x7F00 ) >> 8;
372 switch( audio_format )
374 case 0x00:
375 audio->id = ( ( 0x80 + position ) << 8 ) | 0xbd;
376 audio->config.in.codec = HB_ACODEC_AC3;
377 audio->config.in.codec_param = AV_CODEC_ID_AC3;
378 codec_name = "AC3";
379 break;
381 case 0x02:
382 case 0x03:
383 audio->id = 0xc0 + position;
384 audio->config.in.codec = HB_ACODEC_FFMPEG;
385 audio->config.in.codec_param = AV_CODEC_ID_MP2;
386 codec_name = "MPEG";
387 break;
389 case 0x04:
390 audio->id = ( ( 0xa0 + position ) << 8 ) | 0xbd;
391 audio->config.in.codec = HB_ACODEC_LPCM;
392 codec_name = "LPCM";
393 break;
395 case 0x06:
396 audio->id = ( ( 0x88 + position ) << 8 ) | 0xbd;
397 audio->config.in.codec = HB_ACODEC_DCA;
398 audio->config.in.codec_param = AV_CODEC_ID_DTS;
399 codec_name = "DTS";
400 break;
402 default:
403 audio->id = 0;
404 audio->config.in.codec = 0;
405 codec_name = "Unknown";
406 hb_log( "scan: unknown audio codec (%x)",
407 audio_format );
408 break;
410 if( !audio->id )
412 continue;
415 /* Check for duplicate tracks */
416 audio_tmp = NULL;
417 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
419 audio_tmp = hb_list_item( title->list_audio, j );
420 if( audio->id == audio_tmp->id )
422 break;
424 audio_tmp = NULL;
426 if( audio_tmp )
428 hb_log( "scan: duplicate audio track" );
429 free( audio );
430 continue;
433 lang = lang_for_code( lang_code );
435 audio->config.lang.type = lang_extension;
437 snprintf( audio->config.lang.simple,
438 sizeof( audio->config.lang.simple ), "%s",
439 strlen( lang->native_name ) ? lang->native_name : lang->eng_name );
440 snprintf( audio->config.lang.iso639_2,
441 sizeof( audio->config.lang.iso639_2 ), "%s", lang->iso639_2 );
443 hb_log("scan: id=0x%x, lang=%s (%s), 3cc=%s ext=%i", audio->id,
444 audio->config.lang.simple, codec_name,
445 audio->config.lang.iso639_2, lang_extension);
447 audio->config.in.track = i;
448 hb_list_add( title->list_audio, audio );
451 /* Check for subtitles */
452 for( i = 0; i < vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
454 hb_subtitle_t * subtitle;
455 int spu_control;
456 int position;
457 iso639_lang_t * lang;
458 int lang_extension = 0;
460 hb_log( "scan: checking subtitle %d", i + 1 );
462 spu_control =
463 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i];
465 if( !( spu_control & 0x80000000 ) )
467 hb_log( "scan: subtitle channel is not active" );
468 continue;
471 if( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
473 switch( vts->vtsi_mat->vts_video_attr.permitted_df )
475 case 1:
476 position = spu_control & 0xFF;
477 break;
478 case 2:
479 position = ( spu_control >> 8 ) & 0xFF;
480 break;
481 default:
482 position = ( spu_control >> 16 ) & 0xFF;
485 else
487 position = ( spu_control >> 24 ) & 0x7F;
490 lang_extension = vts->vtsi_mat->vts_subp_attr[i].code_extension;
492 lang = lang_for_code( vts->vtsi_mat->vts_subp_attr[i].lang_code );
494 subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
495 subtitle->track = i;
496 subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd;
497 snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s",
498 strlen(lang->native_name) ? lang->native_name : lang->eng_name);
499 snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "%s",
500 lang->iso639_2);
501 subtitle->format = PICTURESUB;
502 subtitle->source = VOBSUB;
503 subtitle->config.dest = RENDERSUB; // By default render (burn-in) the VOBSUB.
504 subtitle->stream_type = 0xbd;
505 subtitle->substream_type = 0x20 + position;
506 subtitle->codec = WORK_DECVOBSUB;
508 subtitle->type = lang_extension;
510 memcpy( subtitle->palette,
511 vts->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette,
512 16 * sizeof( uint32_t ) );
513 subtitle->palette_set = 1;
515 switch( lang_extension )
517 case 2:
518 strcat( subtitle->lang, " (Caption with bigger size character)" );
519 break;
520 case 3:
521 strcat( subtitle->lang, " (Caption for Children)" );
522 break;
523 case 5:
524 strcat( subtitle->lang, " (Closed Caption)" );
525 break;
526 case 6:
527 strcat( subtitle->lang, " (Closed Caption with bigger size character)" );
528 break;
529 case 7:
530 strcat( subtitle->lang, " (Closed Caption for Children)" );
531 break;
532 case 9:
533 strcat( subtitle->lang, " (Forced Caption)" );
534 break;
535 case 13:
536 strcat( subtitle->lang, " (Director's Commentary)" );
537 break;
538 case 14:
539 strcat( subtitle->lang, " (Director's Commentary with bigger size character)" );
540 break;
541 case 15:
542 strcat( subtitle->lang, " (Director's Commentary for Children)" );
543 default:
544 break;
547 hb_log( "scan: id=0x%x, lang=%s, 3cc=%s ext=%i", subtitle->id,
548 subtitle->lang, subtitle->iso639_2, lang_extension );
550 hb_list_add( title->list_subtitle, subtitle );
553 /* Chapters */
554 hb_log( "scan: title %d has %d chapters", t,
555 vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts );
556 for( i = 0;
557 i < vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
559 char chapter_title[80];
560 chapter = calloc( sizeof( hb_chapter_t ), 1 );
562 /* remember the on-disc chapter number */
563 chapter->index = i + 1;
564 sprintf( chapter_title, "Chapter %d", chapter->index );
565 hb_chapter_set_title( chapter, chapter_title );
567 pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
568 pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
569 d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
571 /* Start cell */
572 chapter->cell_start = d->pgc->program_map[pgn-1] - 1;
573 chapter->block_start =
574 d->pgc->cell_playback[chapter->cell_start].first_sector;
576 // if there are no more programs in this pgc, the end cell is the
577 // last cell. Otherwise it's the cell before the start cell of the
578 // next program.
579 if ( pgn == d->pgc->nr_of_programs )
581 chapter->cell_end = d->pgc->nr_of_cells - 1;
583 else
585 chapter->cell_end = d->pgc->program_map[pgn] - 2;;
587 chapter->block_end = d->pgc->cell_playback[chapter->cell_end].last_sector;
589 /* Block count, duration */
590 chapter->block_count = 0;
591 chapter->duration = 0;
593 d->cell_cur = chapter->cell_start;
594 while( d->cell_cur <= chapter->cell_end )
596 #define cp d->pgc->cell_playback[d->cell_cur]
597 chapter->block_count += cp.last_sector + 1 - cp.first_sector;
598 chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
599 #undef cp
600 FindNextCell( d );
601 d->cell_cur = d->cell_next;
604 hb_list_add( title->list_chapter, chapter );
607 for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
609 chapter = hb_list_item( title->list_chapter, i );
611 int seconds = ( chapter->duration + 45000 ) / 90000;
612 chapter->hours = ( seconds / 3600 );
613 chapter->minutes = ( seconds % 3600 ) / 60;
614 chapter->seconds = ( seconds % 60 );
616 hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
617 chapter->index, chapter->cell_start, chapter->cell_end,
618 chapter->block_start, chapter->block_end,
619 chapter->block_count, chapter->duration / 90 );
622 /* Get aspect. We don't get width/height/rate infos here as
623 they tend to be wrong */
624 switch( vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
626 case 0:
627 title->container_dar.num = 4;
628 title->container_dar.den = 3;
629 break;
630 case 3:
631 title->container_dar.num = 16;
632 title->container_dar.den = 9;
633 break;
634 default:
635 hb_log( "scan: unknown aspect" );
636 goto fail;
639 hb_log("scan: aspect = %d:%d",
640 title->container_dar.num, title->container_dar.den);
642 /* This title is ok so far */
643 goto cleanup;
645 fail:
646 hb_title_close( &title );
648 cleanup:
649 if( vts ) ifoClose( vts );
651 return title;
654 /***********************************************************************
655 * hb_dvdread_start
656 ***********************************************************************
657 * Title and chapter start at 1
658 **********************************************************************/
659 static int hb_dvdread_start( hb_dvd_t * e, hb_title_t *title, int chapter )
661 hb_dvdread_t *d = &(e->dvdread);
662 int pgc_id, pgn;
663 int i;
664 int t = title->index;
666 /* Open the IFO and the VOBs for this title */
667 d->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
668 d->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
669 if( !( d->ifo = ifoOpen( d->reader, d->vts ) ) )
671 hb_error( "dvd: ifoOpen failed for VTS %d", d->vts );
672 return 0;
674 if( !( d->file = DVDOpenFile( d->reader, d->vts,
675 DVD_READ_TITLE_VOBS ) ) )
677 hb_error( "dvd: DVDOpenFile failed for VTS %d", d->vts );
678 return 0;
681 /* Get title first and last blocks */
682 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgcn;
683 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[0].pgn;
684 d->pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
685 d->cell_start = d->pgc->program_map[pgn - 1] - 1;
686 d->cell_end = d->pgc->nr_of_cells - 1;
687 d->title_start = d->pgc->cell_playback[d->cell_start].first_sector;
688 d->title_end = d->pgc->cell_playback[d->cell_end].last_sector;
690 /* Block count */
691 d->title_block_count = 0;
692 for( i = d->cell_start; i <= d->cell_end; i++ )
694 d->title_block_count += d->pgc->cell_playback[i].last_sector + 1 -
695 d->pgc->cell_playback[i].first_sector;
698 /* Get pgc for the current chapter */
699 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgcn;
700 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[chapter-1].pgn;
701 d->pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
703 /* Get the two first cells */
704 d->cell_cur = d->pgc->program_map[pgn-1] - 1;
705 FindNextCell( d );
707 d->block = d->pgc->cell_playback[d->cell_cur].first_sector;
708 d->next_vobu = d->block;
709 d->pack_len = 0;
710 d->cell_overlap = 0;
711 d->in_cell = 0;
712 d->in_sync = 2;
714 return 1;
717 /***********************************************************************
718 * hb_dvdread_stop
719 ***********************************************************************
721 **********************************************************************/
722 static void hb_dvdread_stop( hb_dvd_t * e )
724 hb_dvdread_t *d = &(e->dvdread);
725 if( d->ifo )
727 ifoClose( d->ifo );
728 d->ifo = NULL;
730 if( d->file )
732 DVDCloseFile( d->file );
733 d->file = NULL;
737 /***********************************************************************
738 * hb_dvdread_seek
739 ***********************************************************************
741 **********************************************************************/
742 static int hb_dvdread_seek( hb_dvd_t * e, float f )
744 hb_dvdread_t *d = &(e->dvdread);
745 int count, sizeCell;
746 int i;
748 count = f * d->title_block_count;
750 for( i = d->cell_start; i <= d->cell_end; i++ )
752 sizeCell = d->pgc->cell_playback[i].last_sector + 1 -
753 d->pgc->cell_playback[i].first_sector;
755 if( count < sizeCell )
757 d->cell_cur = i;
758 d->cur_cell_id = 0;
759 FindNextCell( d );
761 /* Now let hb_dvdread_read find the next VOBU */
762 d->next_vobu = d->pgc->cell_playback[i].first_sector + count;
763 d->pack_len = 0;
764 break;
767 count -= sizeCell;
770 if( i > d->cell_end )
772 return 0;
776 * Assume that we are in sync, even if we are not given that it is obvious
777 * that we are out of sync if we have just done a seek.
779 d->in_sync = 2;
781 return 1;
785 /***********************************************************************
786 * is_nav_pack
787 ***********************************************************************/
788 int is_nav_pack( unsigned char *buf )
791 * The NAV Pack is comprised of the PCI Packet and DSI Packet, both
792 * of these start at known offsets and start with a special identifier.
794 * NAV = {
795 * PCI = { 00 00 01 bf # private stream header
796 * ?? ?? # length
797 * 00 # substream
798 * ...
800 * DSI = { 00 00 01 bf # private stream header
801 * ?? ?? # length
802 * 01 # substream
803 * ...
806 * The PCI starts at offset 0x26 into the sector, and the DSI starts at 0x400
808 * This information from: http://dvd.sourceforge.net/dvdinfo/
810 if( ( buf[0x26] == 0x00 && // PCI
811 buf[0x27] == 0x00 &&
812 buf[0x28] == 0x01 &&
813 buf[0x29] == 0xbf &&
814 buf[0x2c] == 0x00 ) &&
815 ( buf[0x400] == 0x00 && // DSI
816 buf[0x401] == 0x00 &&
817 buf[0x402] == 0x01 &&
818 buf[0x403] == 0xbf &&
819 buf[0x406] == 0x01 ) )
821 return ( 1 );
822 } else {
823 return ( 0 );
827 /***********************************************************************
828 * hb_dvdread_read
829 ***********************************************************************
831 **********************************************************************/
832 static hb_buffer_t * hb_dvdread_read( hb_dvd_t * e )
834 hb_dvdread_t *d = &(e->dvdread);
835 hb_buffer_t *b = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
836 top:
837 if( !d->pack_len )
839 /* New pack */
840 dsi_t dsi_pack;
841 int error = 0;
843 // if we've just finished the last cell of the title we don't
844 // want to read another block because our next_vobu pointer
845 // is probably invalid. Just return 'no data' & our caller
846 // should check and discover we're at eof.
847 if ( d->cell_cur > d->cell_end )
849 hb_buffer_close( &b );
850 return NULL;
853 for( ;; )
855 int block, pack_len, next_vobu, read_retry;
857 for( read_retry = 1; read_retry < 1024; read_retry++ )
859 if( DVDReadBlocks( d->file, d->next_vobu, 1, b->data ) == 1 )
862 * Successful read.
864 if( read_retry > 1 && !is_nav_pack( b->data) )
866 // But wasn't a nav pack, so carry on looking
867 read_retry = 1;
868 d->next_vobu++;
869 continue;
871 break;
872 } else {
873 // First retry the same block, then try the next one,
874 // adjust the skip increment upwards so that we can skip
875 // large sections of bad blocks more efficiently (at the
876 // cost of some missed good blocks at the end).
877 hb_log( "dvd: vobu read error blk %d - skipping to next blk incr %d",
878 d->next_vobu, (read_retry * 10));
879 d->next_vobu += (read_retry * 10);
884 if( read_retry == 1024 )
886 // That's too many bad blocks, jump to the start of the
887 // next cell.
888 hb_log( "dvd: vobu read error blk %d - skipping to cell %d",
889 d->next_vobu, d->cell_next );
890 d->cell_cur = d->cell_next;
891 if ( d->cell_cur > d->cell_end )
893 hb_buffer_close( &b );
894 hb_set_work_error(d->h, HB_ERROR_READ);
895 return NULL;
897 d->in_cell = 0;
898 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
899 FindNextCell( d );
900 d->cell_overlap = 1;
901 continue;
904 if ( !is_nav_pack( b->data ) ) {
905 (d->next_vobu)++;
906 if( d->in_sync == 1 ) {
907 hb_log("dvd: Lost sync, searching for NAV pack at blk %d",
908 d->next_vobu);
909 d->in_sync = 0;
911 continue;
914 navRead_DSI( &dsi_pack, &b->data[DSI_START_BYTE] );
916 if ( d->in_sync == 0 && d->cur_cell_id &&
917 (d->cur_vob_id != dsi_pack.dsi_gi.vobu_vob_idn ||
918 d->cur_cell_id != dsi_pack.dsi_gi.vobu_c_idn ) )
920 // We walked out of the cell we're supposed to be in.
921 // If we're not at the start of our next cell go there.
922 hb_log("dvd: left cell %d (%u,%u) for (%u,%u) at block %u",
923 d->cell_cur, d->cur_vob_id, d->cur_cell_id,
924 dsi_pack.dsi_gi.vobu_vob_idn, dsi_pack.dsi_gi.vobu_c_idn,
925 d->next_vobu );
926 if ( d->next_vobu != d->pgc->cell_playback[d->cell_next].first_sector )
928 d->next_vobu = d->pgc->cell_playback[d->cell_next].first_sector;
929 d->cur_cell_id = 0;
930 continue;
934 block = dsi_pack.dsi_gi.nv_pck_lbn;
935 pack_len = dsi_pack.dsi_gi.vobu_ea;
937 // There are a total of 21 next vobu offsets (and 21 prev_vobu
938 // offsets) in the navpack SRI structure. The primary one is
939 // 'next_vobu' which is the offset (in dvd blocks) from the current
940 // block to the start of the next vobu. If the block at 'next_vobu'
941 // can't be read, 'next_video' is the offset to the vobu closest to it.
942 // The other 19 offsets are vobus at successively longer distances from
943 // the current block (this is so that a hardware player can do
944 // adaptive error recovery to skip over a bad spot on the disk). In all
945 // these offsets the high bit is set to indicate when it contains a
946 // valid offset. The next bit (2^30) is set to indicate that there's
947 // another valid offset in the SRI that's closer to the current block.
948 // A hardware player uses these bits to chose the closest valid offset
949 // and uses that as its next vobu. (Some mastering schemes appear to
950 // put a bogus offset in next_vobu with the 2^30 bit set & the
951 // correct offset in next_video. This works fine in hardware players
952 // but will mess up software that doesn't implement the full next
953 // vobu decision logic.) In addition to the flag bits there's a
954 // reserved value of the offset that indicates 'no next vobu' (which
955 // indicates the end of a cell). But having no next vobu pointer with a
956 // 'valid' bit set also indicates end of cell. Different mastering
957 // schemes seem to use all possible combinations of the flag bits
958 // and reserved values to indicate end of cell so we have to check
959 // them all or we'll get a disk read error from following an
960 // invalid offset.
961 uint32_t next_ptr = dsi_pack.vobu_sri.next_vobu;
962 if ( ( next_ptr & ( 1 << 31 ) ) == 0 ||
963 ( next_ptr & ( 1 << 30 ) ) != 0 ||
964 ( next_ptr & 0x3fffffff ) == 0x3fffffff )
966 next_ptr = dsi_pack.vobu_sri.next_video;
967 if ( ( next_ptr & ( 1 << 31 ) ) == 0 ||
968 ( next_ptr & 0x3fffffff ) == 0x3fffffff )
970 // don't have a valid forward pointer - assume end-of-cell
971 d->block = block;
972 d->pack_len = pack_len;
973 break;
976 next_vobu = block + ( next_ptr & 0x3fffffff );
978 if( pack_len > 0 &&
979 pack_len < 1024 &&
980 block >= d->next_vobu &&
981 ( block <= d->title_start + d->title_block_count ||
982 block <= d->title_end ) )
984 d->block = block;
985 d->pack_len = pack_len;
986 d->next_vobu = next_vobu;
987 break;
990 /* Wasn't a valid VOBU, try next block */
991 if( ++error > 1024 )
993 hb_error( "dvd: couldn't find a VOBU after 1024 blocks" );
994 hb_buffer_close( &b );
995 hb_set_work_error(d->h, HB_ERROR_READ);
996 return NULL;
999 (d->next_vobu)++;
1002 if( d->in_sync == 0 || d->in_sync == 2 )
1004 if( d->in_sync == 0 )
1006 hb_log( "dvd: In sync with DVD at block %d", d->block );
1008 d->in_sync = 1;
1011 // Revert the cell overlap, and check for a chapter break
1012 // If this cell is zero length (prev_vobu & next_vobu both
1013 // set to END_OF_CELL) we need to check for beginning of
1014 // cell before checking for end or we'll advance to the next
1015 // cell too early and fail to generate a chapter mark when this
1016 // cell starts a chapter.
1017 if( ( dsi_pack.vobu_sri.prev_vobu & (1 << 31 ) ) == 0 ||
1018 ( dsi_pack.vobu_sri.prev_vobu & 0x3fffffff ) == 0x3fffffff )
1020 // A vobu that's not at the start of a cell can have an
1021 // EOC prev pointer (this seems to be associated with some
1022 // sort of drm). The rest of the content in the cell may be
1023 // booby-trapped so treat this like an end-of-cell rather
1024 // than a beginning of cell.
1025 if ( d->pgc->cell_playback[d->cell_cur].first_sector < dsi_pack.dsi_gi.nv_pck_lbn &&
1026 d->pgc->cell_playback[d->cell_cur].last_sector >= dsi_pack.dsi_gi.nv_pck_lbn )
1028 hb_log( "dvd: null prev_vobu in cell %d at block %d", d->cell_cur,
1029 d->block );
1030 // treat like end-of-cell then go directly to start of next cell.
1031 d->cell_cur = d->cell_next;
1032 d->in_cell = 0;
1033 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1034 FindNextCell( d );
1035 d->cell_overlap = 1;
1036 goto top;
1038 else
1040 if ( d->block != d->pgc->cell_playback[d->cell_cur].first_sector )
1042 hb_log( "dvd: beginning of cell %d at block %d", d->cell_cur,
1043 d->block );
1045 if( d->in_cell )
1047 hb_error( "dvd: assuming missed end of cell %d at block %d", d->cell_cur, d->block );
1048 d->cell_cur = d->cell_next;
1049 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1050 FindNextCell( d );
1051 d->cell_overlap = 1;
1052 d->in_cell = 0;
1053 } else {
1054 d->in_cell = 1;
1056 d->cur_vob_id = dsi_pack.dsi_gi.vobu_vob_idn;
1057 d->cur_cell_id = dsi_pack.dsi_gi.vobu_c_idn;
1059 if( d->cell_overlap )
1061 b->s.new_chap = hb_dvdread_is_break( d );
1062 d->cell_overlap = 0;
1067 if( ( dsi_pack.vobu_sri.next_vobu & (1 << 31 ) ) == 0 ||
1068 ( dsi_pack.vobu_sri.next_vobu & 0x3fffffff ) == 0x3fffffff )
1070 if ( d->block <= d->pgc->cell_playback[d->cell_cur].first_sector ||
1071 d->block > d->pgc->cell_playback[d->cell_cur].last_sector )
1073 hb_log( "dvd: end of cell %d at block %d", d->cell_cur,
1074 d->block );
1076 d->cell_cur = d->cell_next;
1077 d->in_cell = 0;
1078 d->next_vobu = d->pgc->cell_playback[d->cell_cur].first_sector;
1079 FindNextCell( d );
1080 d->cell_overlap = 1;
1084 else
1086 if( DVDReadBlocks( d->file, d->block, 1, b->data ) != 1 )
1088 // this may be a real DVD error or may be DRM. Either way
1089 // we don't want to quit because of one bad block so set
1090 // things up so we'll advance to the next vobu and recurse.
1091 hb_error( "dvd: DVDReadBlocks failed (%d), skipping to vobu %u",
1092 d->block, d->next_vobu );
1093 d->pack_len = 0;
1094 goto top; /* XXX need to restructure this routine & avoid goto */
1096 d->pack_len--;
1099 d->block++;
1101 return b;
1104 /***********************************************************************
1105 * hb_dvdread_chapter
1106 ***********************************************************************
1107 * Returns in which chapter the next block to be read is.
1108 * Chapter numbers start at 1.
1109 **********************************************************************/
1110 static int hb_dvdread_chapter( hb_dvd_t * e )
1112 hb_dvdread_t *d = &(e->dvdread);
1113 int i;
1114 int pgc_id, pgn;
1115 int nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
1116 pgc_t * pgc;
1118 for( i = nr_of_ptts - 1;
1119 i >= 0;
1120 i-- )
1122 /* Get pgc for chapter (i+1) */
1123 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgcn;
1124 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgn;
1125 pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1127 if( d->cell_cur - d->cell_overlap >= pgc->program_map[pgn-1] - 1 &&
1128 d->cell_cur - d->cell_overlap <= pgc->nr_of_cells - 1 )
1130 /* We are in this chapter */
1131 return i + 1;
1135 /* End of title */
1136 return -1;
1139 /***********************************************************************
1140 * hb_dvdread_is_break
1141 ***********************************************************************
1142 * Returns chapter number if the current block is a new chapter start
1143 **********************************************************************/
1144 static int hb_dvdread_is_break( hb_dvdread_t * d )
1146 int i;
1147 int pgc_id, pgn;
1148 int nr_of_ptts = d->ifo->vts_ptt_srpt->title[d->ttn-1].nr_of_ptts;
1149 pgc_t * pgc;
1150 int cell;
1152 for( i = nr_of_ptts - 1;
1153 i > 0;
1154 i-- )
1156 /* Get pgc for chapter (i+1) */
1157 pgc_id = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgcn;
1158 pgn = d->ifo->vts_ptt_srpt->title[d->ttn-1].ptt[i].pgn;
1159 pgc = d->ifo->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1160 cell = pgc->program_map[pgn-1] - 1;
1162 if( cell <= d->cell_start )
1163 break;
1165 // This must not match against the start cell.
1166 if( pgc->cell_playback[cell].first_sector == d->block && cell != d->cell_start )
1168 return i + 1;
1172 return 0;
1175 /***********************************************************************
1176 * hb_dvdread_close
1177 ***********************************************************************
1178 * Closes and frees everything
1179 **********************************************************************/
1180 static void hb_dvdread_close( hb_dvd_t ** _d )
1182 hb_dvdread_t * d = &((*_d)->dvdread);
1184 if( d->vmg )
1186 ifoClose( d->vmg );
1188 if( d->reader )
1190 DVDClose( d->reader );
1193 free( d );
1194 *_d = NULL;
1197 /***********************************************************************
1198 * hb_dvdread_angle_count
1199 ***********************************************************************
1200 * Returns the number of angles supported. We do not support angles
1201 * with dvdread
1202 **********************************************************************/
1203 static int hb_dvdread_angle_count( hb_dvd_t * d )
1205 return 1;
1208 /***********************************************************************
1209 * hb_dvdread_set_angle
1210 ***********************************************************************
1211 * Sets the angle to read. Not supported with dvdread
1212 **********************************************************************/
1213 static void hb_dvdread_set_angle( hb_dvd_t * d, int angle )
1217 /***********************************************************************
1218 * FindNextCell
1219 ***********************************************************************
1220 * Assumes pgc and cell_cur are correctly set, and sets cell_next to the
1221 * cell to be read when we will be done with cell_cur.
1222 **********************************************************************/
1223 static void FindNextCell( hb_dvdread_t * d )
1225 int i = 0;
1227 if( d->pgc->cell_playback[d->cell_cur].block_type ==
1228 BLOCK_TYPE_ANGLE_BLOCK )
1231 while( d->pgc->cell_playback[d->cell_cur+i].block_mode !=
1232 BLOCK_MODE_LAST_CELL )
1234 i++;
1236 d->cell_next = d->cell_cur + i + 1;
1237 hb_log( "dvd: Skipping multi-angle cells %d-%d",
1238 d->cell_cur,
1239 d->cell_next - 1 );
1241 else
1243 d->cell_next = d->cell_cur + 1;
1247 /***********************************************************************
1248 * dvdtime2msec
1249 ***********************************************************************
1250 * From lsdvd
1251 **********************************************************************/
1252 static int dvdtime2msec(dvd_time_t * dt)
1254 double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97};
1255 double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6];
1256 long ms;
1257 ms = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000;
1258 ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
1259 ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;
1261 if( fps > 0 )
1263 ms += (((dt->frame_u & 0x30) >> 3) * 5 +
1264 (dt->frame_u & 0x0f)) * 1000.0 / fps;
1267 return ms;
1270 char * hb_dvd_name( char * path )
1272 return dvd_methods->name(path);
1275 hb_dvd_t * hb_dvd_init( hb_handle_t * h, char * path )
1277 return dvd_methods->init(h, path);
1280 int hb_dvd_title_count( hb_dvd_t * d )
1282 return dvd_methods->title_count(d);
1285 hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t, uint64_t min_duration )
1287 return dvd_methods->title_scan(d, t, min_duration);
1290 int hb_dvd_start( hb_dvd_t * d, hb_title_t *title, int chapter )
1292 return dvd_methods->start(d, title, chapter);
1295 void hb_dvd_stop( hb_dvd_t * d )
1297 dvd_methods->stop(d);
1300 int hb_dvd_seek( hb_dvd_t * d, float f )
1302 return dvd_methods->seek(d, f);
1305 hb_buffer_t * hb_dvd_read( hb_dvd_t * d )
1307 return dvd_methods->read(d);
1310 int hb_dvd_chapter( hb_dvd_t * d )
1312 return dvd_methods->chapter(d);
1315 void hb_dvd_close( hb_dvd_t ** _d )
1317 dvd_methods->close(_d);
1320 int hb_dvd_angle_count( hb_dvd_t * d )
1322 return dvd_methods->angle_count(d);
1325 void hb_dvd_set_angle( hb_dvd_t * d, int angle )
1327 dvd_methods->set_angle(d, angle);
1330 int hb_dvd_main_feature( hb_dvd_t * d, hb_list_t * list_title )
1332 return dvd_methods->main_feature(d, list_title);
1335 // hb_dvd_set_dvdnav must only be called when no dvd source is open
1336 // it rips the rug out from under things so be careful
1337 void hb_dvd_set_dvdnav( int enable )
1339 if (enable)
1340 dvd_methods = hb_dvdnav_methods();
1341 else
1342 dvd_methods = hb_dvdread_methods();