summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2019-06-28 09:44:24 -0700
committerJohn Stebbins <[email protected]>2019-07-12 14:18:37 -0700
commitb5e18d605105b646e27558352dbf561117431970 (patch)
tree0fb256f24b8c7f2ebf41117c06d4f3362f0676d8 /libhb
parent206df6267e8065366f2df18252b22030462b9436 (diff)
dvd: remove dvd specific details from hb_title_t
This information isn't needed by the frontends and pollutes the API
Diffstat (limited to 'libhb')
-rw-r--r--libhb/bd.c10
-rw-r--r--libhb/common.h14
-rw-r--r--libhb/dvd.c86
-rw-r--r--libhb/dvd.h19
-rw-r--r--libhb/dvdnav.c450
5 files changed, 286 insertions, 293 deletions
diff --git a/libhb/bd.c b/libhb/bd.c
index 39178f6b8..7eac359bf 100644
--- a/libhb/bd.c
+++ b/libhb/bd.c
@@ -306,9 +306,6 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
*dot_term = '\0';
}
- title->vts = 0;
- title->ttn = 0;
-
if (tt <= d->title_count)
{
ti = d->title_info[tt - 1];
@@ -337,9 +334,6 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
{
pkt_count += ti->clips[ii].pkt_count;
}
- title->block_start = 0;
- title->block_end = pkt_count;
- title->block_count = pkt_count;
title->angle_count = ti->angle_count;
@@ -572,7 +566,6 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
hb_chapter_set_title( chapter, chapter_title );
chapter->duration = ti->chapters[ii].duration;
- chapter->block_start = ti->chapters[ii].offset;
// Sanity check chapter duration and start times
// Have seen some invalid durations in the wild
@@ -610,9 +603,8 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
chapter->minutes = ( seconds % 3600 ) / 60;
chapter->seconds = ( seconds % 60 );
- hb_log( "bd: chap %d packet=%"PRIu64", %"PRIu64" ms",
+ hb_log( "bd: chap %d, %"PRIu64" ms",
chapter->index,
- chapter->block_start,
chapter->duration / 90 );
hb_list_add( title->list_chapter, chapter );
diff --git a/libhb/common.h b/libhb/common.h
index a5127bc66..5b77cbed4 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -893,13 +893,6 @@ struct hb_audio_s
struct hb_chapter_s
{
int index;
- int pgcn;
- int pgn;
- int cell_start;
- int cell_end;
- uint64_t block_start;
- uint64_t block_end;
- uint64_t block_count;
/* Visual-friendly duration */
int hours;
@@ -1052,13 +1045,6 @@ struct hb_title_s
char name[1024];
int index;
int playlist;
- int vts;
- int ttn;
- int cell_start;
- int cell_end;
- uint64_t block_start;
- uint64_t block_end;
- uint64_t block_count;
int angle_count;
void * opaque_priv;
diff --git a/libhb/dvd.c b/libhb/dvd.c
index 12611d397..bc21248c3 100644
--- a/libhb/dvd.c
+++ b/libhb/dvd.c
@@ -323,17 +323,17 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
}
/* VTS which our title is in */
- title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
+ int title_vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
- if ( !title->vts )
+ if ( !title_vts )
{
/* A VTS of 0 means the title wasn't found in the title set */
- hb_log("Invalid VTS (title set) number: %i", title->vts);
+ hb_log("Invalid VTS (title set) number: %i", title_vts);
goto fail;
}
- hb_log( "scan: opening IFO for VTS %d", title->vts );
- if( !( vts = ifoOpen( d->reader, title->vts ) ) )
+ hb_log( "scan: opening IFO for VTS %d", title_vts );
+ if( !( vts = ifoOpen( d->reader, title_vts ) ) )
{
hb_log( "scan: ifoOpen failed" );
goto fail;
@@ -372,25 +372,25 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
if( global_verbosity_level == 3 )
{
- ifo_print( d->reader, title->vts );
+ ifo_print( d->reader, title_vts );
}
/* Position of the title in the VTS */
- title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
- if ( title->ttn < 1 || title->ttn > vts->vts_ptt_srpt->nr_of_srpts )
+ int title_ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
+ if ( title_ttn < 1 || title_ttn > vts->vts_ptt_srpt->nr_of_srpts )
{
- hb_log( "invalid VTS PTT offset %d for title %d, skipping", title->ttn, t );
+ hb_log( "invalid VTS PTT offset %d for title %d, skipping", title_ttn, t );
goto fail;
}
/* Get pgc */
- pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgcn;
+ pgc_id = vts->vts_ptt_srpt->title[title_ttn-1].ptt[0].pgcn;
if ( pgc_id < 1 || pgc_id > vts->vts_pgcit->nr_of_pgci_srp )
{
hb_log( "invalid PGC ID %d for title %d, skipping", pgc_id, t );
goto fail;
}
- pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[0].pgn;
+ pgn = vts->vts_ptt_srpt->title[title_ttn-1].ptt[0].pgn;
d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
hb_log("pgc_id: %d, pgn: %d: pgc: %p", pgc_id, pgn, d->pgc);
@@ -413,31 +413,6 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
goto fail;
}
- /* Start cell */
- title->cell_start = d->pgc->program_map[pgn-1] - 1;
- title->block_start = d->pgc->cell_playback[title->cell_start].first_sector;
-
- /* End cell */
- title->cell_end = d->pgc->nr_of_cells - 1;
- title->block_end = d->pgc->cell_playback[title->cell_end].last_sector;
-
- /* Block count */
- title->block_count = 0;
- d->cell_cur = title->cell_start;
- while( d->cell_cur <= title->cell_end )
- {
-#define cp d->pgc->cell_playback[d->cell_cur]
- title->block_count += cp.last_sector + 1 - cp.first_sector;
-#undef cp
- FindNextCell( d );
- d->cell_cur = d->cell_next;
- }
-
- hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
- "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
- title->cell_end, title->block_start, title->block_end,
- title->block_count );
-
/* Get duration */
title->duration = 90LL * dvdtime2msec( &d->pgc->playback_time );
title->hours = title->duration / 90000 / 3600;
@@ -651,9 +626,9 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
/* Chapters */
hb_log( "scan: title %d has %d chapters", t,
- vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts );
+ vts->vts_ptt_srpt->title[title_ttn-1].nr_of_ptts );
for( i = 0;
- i < vts->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
+ i < vts->vts_ptt_srpt->title[title_ttn-1].nr_of_ptts; i++ )
{
char chapter_title[80];
chapter = calloc( sizeof( hb_chapter_t ), 1 );
@@ -663,37 +638,34 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
sprintf( chapter_title, "Chapter %d", chapter->index );
hb_chapter_set_title( chapter, chapter_title );
- pgc_id = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
- pgn = vts->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
+ pgc_id = vts->vts_ptt_srpt->title[title_ttn-1].ptt[i].pgcn;
+ pgn = vts->vts_ptt_srpt->title[title_ttn-1].ptt[i].pgn;
d->pgc = vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
/* Start cell */
- chapter->cell_start = d->pgc->program_map[pgn-1] - 1;
- chapter->block_start =
- d->pgc->cell_playback[chapter->cell_start].first_sector;
+ int cell_start, cell_end;
+
+ cell_start = d->pgc->program_map[pgn-1] - 1;
// if there are no more programs in this pgc, the end cell is the
// last cell. Otherwise it's the cell before the start cell of the
// next program.
if ( pgn == d->pgc->nr_of_programs )
{
- chapter->cell_end = d->pgc->nr_of_cells - 1;
+ cell_end = d->pgc->nr_of_cells - 1;
}
else
{
- chapter->cell_end = d->pgc->program_map[pgn] - 2;;
+ cell_end = d->pgc->program_map[pgn] - 2;;
}
- chapter->block_end = d->pgc->cell_playback[chapter->cell_end].last_sector;
/* Block count, duration */
- chapter->block_count = 0;
chapter->duration = 0;
- d->cell_cur = chapter->cell_start;
- while( d->cell_cur <= chapter->cell_end )
+ d->cell_cur = cell_start;
+ while( d->cell_cur <= cell_end )
{
#define cp d->pgc->cell_playback[d->cell_cur]
- chapter->block_count += cp.last_sector + 1 - cp.first_sector;
chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
#undef cp
FindNextCell( d );
@@ -712,10 +684,8 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
chapter->minutes = ( seconds % 3600 ) / 60;
chapter->seconds = ( seconds % 60 );
- hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
- chapter->index, chapter->cell_start, chapter->cell_end,
- chapter->block_start, chapter->block_end,
- chapter->block_count, chapter->duration / 90 );
+ hb_log( "scan: chap %d, %"PRId64" ms",
+ chapter->index, chapter->duration / 90 );
}
/* Get aspect. We don't get width/height/rate infos here as
@@ -1156,8 +1126,8 @@ static hb_buffer_t * hb_dvdread_read( hb_dvd_t * e )
{
if ( d->block != d->pgc->cell_playback[d->cell_cur].first_sector )
{
- hb_log( "dvd: beginning of cell %d at block %d", d->cell_cur,
- d->block );
+ hb_deep_log(3, "dvd: beginning of cell %d at block %d", d->cell_cur,
+ d->block);
}
if( d->in_cell )
{
@@ -1183,8 +1153,8 @@ static hb_buffer_t * hb_dvdread_read( hb_dvd_t * e )
if ( d->block <= d->pgc->cell_playback[d->cell_cur].first_sector ||
d->block > d->pgc->cell_playback[d->cell_cur].last_sector )
{
- hb_log( "dvd: end of cell %d at block %d", d->cell_cur,
- d->block );
+ hb_deep_log(3, "dvd: end of cell %d at block %d", d->cell_cur,
+ d->block);
}
d->cell_cur = d->cell_next;
d->in_cell = 0;
diff --git a/libhb/dvd.h b/libhb/dvd.h
index c5be684a1..338c8da89 100644
--- a/libhb/dvd.h
+++ b/libhb/dvd.h
@@ -19,6 +19,16 @@
#define HB_VOBSUB_STYLE_LETTERBOX 2
#define HB_VOBSUB_STYLE_PANSCAN 3
+struct hb_dvd_chapter_s
+{
+ int index;
+ int64_t duration;
+ int pgn;
+ int pgcn;
+ int block_start;
+ int block_end;
+};
+
struct hb_dvdread_s
{
char * path;
@@ -62,11 +72,18 @@ struct hb_dvdnav_s
int title_block_count;
int chapter;
int cell;
- hb_list_t * list_chapter;
int stopped;
hb_handle_t * h;
+
+ ifo_handle_t * ifo;
+ int vts;
+ int pgcn;
+ int pgn;
+ int64_t duration;
+ hb_list_t * list_dvd_chapter;
};
+typedef struct hb_dvd_chapter_s hb_dvd_chapter_t;
typedef struct hb_dvdnav_s hb_dvdnav_t;
typedef struct hb_dvdread_s hb_dvdread_t;
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index 6e165024b..03a86e906 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -61,6 +61,8 @@ static int FindChapterIndex( hb_list_t * list, int pgcn, int pgn );
static int NextPgcn( ifo_handle_t *ifo, int pgcn, uint32_t pgcn_map[MAX_PGCN/32] );
static int FindNextCell( pgc_t *pgc, int cell_cur );
static int dvdtime2msec( dvd_time_t * );
+static int TitleOpenIfo(hb_dvdnav_t * d, int t);
+static void TitleCloseIfo(hb_dvdnav_t * d);
hb_dvd_func_t * hb_dvdnav_methods( void )
{
@@ -436,20 +438,16 @@ static void add_subtitle( hb_list_t * list_subtitle, int position,
static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_duration )
{
- hb_dvdnav_t * d = &(e->dvdnav);
- hb_title_t * title;
- ifo_handle_t * ifo = NULL;
- int pgcn, pgn, pgcn_end, i, c;
- int title_pgcn;
- pgc_t * pgc;
- int cell_cur;
- hb_chapter_t * chapter;
- int count;
- uint64_t duration, longest;
- int longest_pgcn, longest_pgn, longest_pgcn_end;
- const char * name;
- unsigned char unused[1024];
- const char * codec_name;
+ hb_dvdnav_t * d = &(e->dvdnav);
+ hb_title_t * title;
+ int pgcn, i;
+ pgc_t * pgc;
+ hb_chapter_t * chapter;
+ hb_dvd_chapter_t * dvd_chapter;
+ int count;
+ const char * name;
+ unsigned char unused[1024];
+ const char * codec_name;
hb_log( "scan: scanning title %d", t );
@@ -482,90 +480,44 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
}
}
- /* VTS which our title is in */
- title->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
-
- if ( !title->vts )
- {
- /* A VTS of 0 means the title wasn't found in the title set */
- hb_log("Invalid VTS (title set) number: %i", title->vts);
- goto fail;
- }
-
- hb_log( "scan: opening IFO for VTS %d", title->vts );
- if( !( ifo = ifoOpen( d->reader, title->vts ) ) )
+ if (!TitleOpenIfo(d, t))
{
- hb_log( "scan: ifoOpen failed" );
goto fail;
}
/* ignore titles with bogus cell addresses so we don't abort later
** in libdvdread. */
- for ( i = 0; i < ifo->vts_c_adt->nr_of_vobs; ++i)
+ for ( i = 0; i < d->ifo->vts_c_adt->nr_of_vobs; ++i)
{
- if( (ifo->vts_c_adt->cell_adr_table[i].start_sector & 0xffffff ) ==
+ if( (d->ifo->vts_c_adt->cell_adr_table[i].start_sector & 0xffffff ) ==
0xffffff )
{
hb_log( "scan: cell_adr_table[%d].start_sector invalid (0x%x) "
"- skipping title", i,
- ifo->vts_c_adt->cell_adr_table[i].start_sector );
+ d->ifo->vts_c_adt->cell_adr_table[i].start_sector );
goto fail;
}
- if( (ifo->vts_c_adt->cell_adr_table[i].last_sector & 0xffffff ) ==
+ if( (d->ifo->vts_c_adt->cell_adr_table[i].last_sector & 0xffffff ) ==
0xffffff )
{
hb_log( "scan: cell_adr_table[%d].last_sector invalid (0x%x) "
"- skipping title", i,
- ifo->vts_c_adt->cell_adr_table[i].last_sector );
+ d->ifo->vts_c_adt->cell_adr_table[i].last_sector );
goto fail;
}
}
- if( global_verbosity_level == 3 )
+ if (global_verbosity_level == 4)
{
- ifo_print( d->reader, title->vts );
- }
-
- /* Position of the title in the VTS */
- title->ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
- if ( title->ttn < 1 || title->ttn > ifo->vts_ptt_srpt->nr_of_srpts )
- {
- hb_log( "invalid VTS PTT offset %d for title %d, skipping", title->ttn, t );
- goto fail;
- }
-
- longest = 0LL;
- longest_pgcn = -1;
- longest_pgn = 1;
- longest_pgcn_end = -1;
- pgcn_end = -1;
- for( i = 0; i < ifo->vts_ptt_srpt->title[title->ttn-1].nr_of_ptts; i++ )
- {
- int blocks = 0;
-
- duration = PttDuration(ifo, title->ttn, i+1, &blocks, &pgcn_end);
- pgcn = ifo->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgcn;
- pgn = ifo->vts_ptt_srpt->title[title->ttn-1].ptt[i].pgn;
- if( duration > longest )
- {
- longest_pgcn = pgcn;
- longest_pgn = pgn;
- longest_pgcn_end = pgcn_end;
- longest = duration;
- title->block_count = blocks;
- }
- else if (pgcn == longest_pgcn && pgn < longest_pgn)
- {
- longest_pgn = pgn;
- title->block_count = blocks;
- }
+ ifo_print( d->reader, d->vts );
}
/* Get duration */
- title->duration = longest;
- title->hours = title->duration / 90000 / 3600;
- title->minutes = ( ( title->duration / 90000 ) % 3600 ) / 60;
- title->seconds = ( title->duration / 90000 ) % 60;
+ title->duration = d->duration;
+ title->hours = title->duration / 90000 / 3600;
+ title->minutes = ((title->duration / 90000) % 3600) / 60;
+ title->seconds = ( title->duration / 90000) % 60;
+
hb_log( "scan: duration is %02d:%02d:%02d (%"PRId64" ms)",
title->hours, title->minutes, title->seconds,
title->duration / 90 );
@@ -573,33 +525,30 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
/* ignore titles under 10 seconds because they're often stills or
* clips with no audio & our preview code doesn't currently handle
* either of these. */
- if( longest < min_duration )
+ if (title->duration < min_duration)
{
hb_log( "scan: ignoring title (too short)" );
goto fail;
}
- pgcn = longest_pgcn;
- pgcn_end = longest_pgcn_end;
- pgn = longest_pgn;;
- title_pgcn = pgcn;
-
-
/* Get pgc */
- if ( pgcn < 1 || pgcn > ifo->vts_pgcit->nr_of_pgci_srp || pgcn >= MAX_PGCN)
+ if (d->pgcn < 1 ||
+ d->pgcn > d->ifo->vts_pgcit->nr_of_pgci_srp ||
+ d->pgcn >= MAX_PGCN)
{
- hb_log( "invalid PGC ID %d for title %d, skipping", pgcn, t );
+ hb_log( "invalid PGC ID %d for title %d, skipping", d->pgcn, t );
goto fail;
}
// Check all pgc's for validity
uint32_t pgcn_map[MAX_PGCN/32];
+ pgcn = d->pgcn;
PgcWalkInit( pgcn_map );
do
{
- pgc = ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
+ pgc = d->ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
- if( !pgc || !pgc->program_map )
+ if (!pgc || !pgc->program_map)
{
hb_log( "scan: pgc not valid, skipping" );
goto fail;
@@ -610,35 +559,19 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
hb_log( "invalid PGC cell_playback table for title %d, skipping", t );
goto fail;
}
- } while ((pgcn = NextPgcn(ifo, pgcn, pgcn_map)) != 0);
+ } while ((pgcn = NextPgcn(d->ifo, pgcn, pgcn_map)) != 0);
- pgcn = longest_pgcn;
- pgc = ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
+ pgc = d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc;
- hb_log("pgc_id: %d, pgn: %d: pgc: %p", pgcn, pgn, pgc);
- if (pgn > pgc->nr_of_programs)
+ hb_log("pgc_id: %d, pgn: %d: pgc: %p", d->pgcn, d->pgn, pgc);
+ if (d->pgn > pgc->nr_of_programs)
{
- hb_log( "invalid PGN %d for title %d, skipping", pgn, t );
+ hb_log( "invalid PGN %d for title %d, skipping", d->pgn, t );
goto fail;
}
- /* Title start */
- title->cell_start = pgc->program_map[pgn-1] - 1;
- title->block_start = pgc->cell_playback[title->cell_start].first_sector;
-
- pgc = ifo->vts_pgcit->pgci_srp[pgcn_end-1].pgc;
-
- /* Title end */
- title->cell_end = pgc->nr_of_cells - 1;
- title->block_end = pgc->cell_playback[title->cell_end].last_sector;
-
- hb_log( "scan: vts=%d, ttn=%d, cells=%d->%d, blocks=%"PRIu64"->%"PRIu64", "
- "%"PRIu64" blocks", title->vts, title->ttn, title->cell_start,
- title->cell_end, title->block_start, title->block_end,
- title->block_count );
-
/* Detect languages */
- for( i = 0; i < ifo->vtsi_mat->nr_of_vts_audio_streams; i++ )
+ for (i = 0; i < d->ifo->vtsi_mat->nr_of_vts_audio_streams; i++)
{
int audio_format, lang_code, lang_extension, audio_control, position, j;
hb_audio_t * audio, * audio_tmp;
@@ -648,13 +581,13 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
audio = calloc( sizeof( hb_audio_t ), 1 );
- audio_format = ifo->vtsi_mat->vts_audio_attr[i].audio_format;
- lang_code = ifo->vtsi_mat->vts_audio_attr[i].lang_code;
- lang_extension = ifo->vtsi_mat->vts_audio_attr[i].code_extension;
- audio_control =
- ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->audio_control[i];
+ audio_format = d->ifo->vtsi_mat->vts_audio_attr[i].audio_format;
+ lang_code = d->ifo->vtsi_mat->vts_audio_attr[i].lang_code;
+ lang_extension = d->ifo->vtsi_mat->vts_audio_attr[i].code_extension;
+ audio_control =
+ d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->audio_control[i];
- if( !( audio_control & 0x8000 ) )
+ if (!(audio_control & 0x8000))
{
hb_log( "scan: audio channel is not active" );
free( audio );
@@ -763,7 +696,7 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
}
/* Check for subtitles */
- for( i = 0; i < ifo->vtsi_mat->nr_of_vts_subp_streams; i++ )
+ for( i = 0; i < d->ifo->vtsi_mat->nr_of_vts_subp_streams; i++ )
{
int spu_control, pos, lang_ext = 0;
iso639_lang_t * lang;
@@ -777,7 +710,7 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
// 0x00001f00 - Position mask for Letterbox subtitle track
// 0x0000001f - Position mask for Pan&Scan subtitle track
spu_control =
- ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->subp_control[i];
+ d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->subp_control[i];
if( !( spu_control & 0x80000000 ) )
{
@@ -785,39 +718,39 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
continue;
}
- lang_ext = ifo->vtsi_mat->vts_subp_attr[i].code_extension;
- lang = lang_for_code(ifo->vtsi_mat->vts_subp_attr[i].lang_code);
+ lang_ext = d->ifo->vtsi_mat->vts_subp_attr[i].code_extension;
+ lang = lang_for_code(d->ifo->vtsi_mat->vts_subp_attr[i].lang_code);
// display_aspect_ratio
// 0 = 4:3
// 3 = 16:9
// other = invalid
- if (ifo->vtsi_mat->vts_video_attr.display_aspect_ratio)
+ if (d->ifo->vtsi_mat->vts_video_attr.display_aspect_ratio)
{
// Add Wide Screen subtitle.
pos = (spu_control >> 16) & 0x1F;
add_subtitle(title->list_subtitle, pos, lang, lang_ext,
- (uint8_t*)ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->palette,
+ (uint8_t*)d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->palette,
HB_VOBSUB_STYLE_WIDE);
// permitted_df
// 1 - Letterbox not permitted
// 2 - Pan&Scan not permitted
// 3 - Letterbox and Pan&Scan not permitted
- if (!(ifo->vtsi_mat->vts_video_attr.permitted_df & 1))
+ if (!(d->ifo->vtsi_mat->vts_video_attr.permitted_df & 1))
{
// Letterbox permitted. Add Letterbox subtitle.
pos = (spu_control >> 8) & 0x1F;
add_subtitle(title->list_subtitle, pos, lang, lang_ext,
- (uint8_t*)ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->palette,
+ (uint8_t*)d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->palette,
HB_VOBSUB_STYLE_LETTERBOX);
}
- if (!(ifo->vtsi_mat->vts_video_attr.permitted_df & 2))
+ if (!(d->ifo->vtsi_mat->vts_video_attr.permitted_df & 2))
{
// Pan&Scan permitted. Add Pan&Scan subtitle.
pos = spu_control & 0x1F;
add_subtitle(title->list_subtitle, pos, lang, lang_ext,
- (uint8_t*)ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->palette,
+ (uint8_t*)d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->palette,
HB_VOBSUB_STYLE_PANSCAN);
}
}
@@ -825,96 +758,40 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
{
pos = (spu_control >> 24) & 0x1F;
add_subtitle(title->list_subtitle, pos, lang, lang_ext,
- (uint8_t*)ifo->vts_pgcit->pgci_srp[title_pgcn-1].pgc->palette,
+ (uint8_t*)d->ifo->vts_pgcit->pgci_srp[d->pgcn-1].pgc->palette,
HB_VOBSUB_STYLE_4_3);
}
}
/* Chapters */
- PgcWalkInit( pgcn_map );
- c = 0;
- do
- {
- pgc = ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
-
- for (i = pgn; i <= pgc->nr_of_programs; i++)
- {
- char chapter_title[80];
- chapter = calloc( sizeof( hb_chapter_t ), 1 );
-
- chapter->pgcn = pgcn;
- chapter->pgn = i;
- chapter->index = c + 1;
- sprintf( chapter_title, "Chapter %d", chapter->index );
- hb_chapter_set_title( chapter, chapter_title );
-
- hb_list_add( title->list_chapter, chapter );
- c++;
- }
-
- pgn = 1;
- } while ((pgcn = NextPgcn(ifo, pgcn, pgcn_map)) != 0);
-
- hb_log( "scan: title %d has %d chapters", t, c );
-
- count = hb_list_count( title->list_chapter );
+ count = hb_list_count(d->list_dvd_chapter);
+ hb_log( "scan: title %d has %d chapters", t, count );
for (i = 0; i < count; i++)
{
- chapter = hb_list_item( title->list_chapter, i );
-
- pgcn = chapter->pgcn;
- pgn = chapter->pgn;
- pgc = ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
-
- /* Start cell */
- chapter->cell_start = pgc->program_map[pgn-1] - 1;
- chapter->block_start = pgc->cell_playback[chapter->cell_start].first_sector;
- // if there are no more programs in this pgc, the end cell is the
- // last cell. Otherwise it's the cell before the start cell of the
- // next program.
- if ( pgn == pgc->nr_of_programs )
- {
- chapter->cell_end = pgc->nr_of_cells - 1;
- }
- else
- {
- chapter->cell_end = pgc->program_map[pgn] - 2;;
- }
- chapter->block_end = pgc->cell_playback[chapter->cell_end].last_sector;
+ char chapter_title[80];
- /* Block count, duration */
- chapter->block_count = 0;
- chapter->duration = 0;
+ dvd_chapter = hb_list_item(d->list_dvd_chapter, i);
+ chapter = calloc(sizeof( hb_chapter_t ), 1);
+ chapter->index = i + 1;
+ chapter->duration = dvd_chapter->duration;
- cell_cur = chapter->cell_start;
- while( cell_cur <= chapter->cell_end )
- {
-#define cp pgc->cell_playback[cell_cur]
- chapter->block_count += cp.last_sector + 1 - cp.first_sector;
- chapter->duration += 90LL * dvdtime2msec( &cp.playback_time );
-#undef cp
- cell_cur = FindNextCell( pgc, cell_cur );
- }
- }
+ sprintf(chapter_title, "Chapter %d", chapter->index);
+ hb_chapter_set_title(chapter, chapter_title);
- for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
- {
- chapter = hb_list_item( title->list_chapter, i );
+ hb_list_add( title->list_chapter, chapter );
int seconds = ( chapter->duration + 45000 ) / 90000;
chapter->hours = ( seconds / 3600 );
chapter->minutes = ( seconds % 3600 ) / 60;
chapter->seconds = ( seconds % 60 );
- hb_log( "scan: chap %d c=%d->%d, b=%"PRIu64"->%"PRIu64" (%"PRIu64"), %"PRId64" ms",
- chapter->index, chapter->cell_start, chapter->cell_end,
- chapter->block_start, chapter->block_end,
- chapter->block_count, chapter->duration / 90 );
+ hb_log( "scan: chap %d, %"PRId64" ms",
+ chapter->index, chapter->duration / 90 );
}
/* Get aspect. We don't get width/height/rate infos here as
they tend to be wrong */
- switch( ifo->vtsi_mat->vts_video_attr.display_aspect_ratio )
+ switch (d->ifo->vtsi_mat->vts_video_attr.display_aspect_ratio)
{
case 0:
title->container_dar.num = 4;
@@ -929,7 +806,7 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
goto fail;
}
- switch( ifo->vtsi_mat->vts_video_attr.mpeg_version )
+ switch (d->ifo->vtsi_mat->vts_video_attr.mpeg_version)
{
case 0:
title->video_codec = WORK_DECAVCODECV;
@@ -941,7 +818,7 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
break;
default:
hb_log("scan: unknown/reserved MPEG version %d",
- ifo->vtsi_mat->vts_video_attr.mpeg_version);
+ d->ifo->vtsi_mat->vts_video_attr.mpeg_version);
title->video_codec = WORK_DECAVCODECV;
title->video_codec_param = AV_CODEC_ID_MPEG2VIDEO;
break;
@@ -957,7 +834,7 @@ fail:
hb_title_close( &title );
cleanup:
- if( ifo ) ifoClose( ifo );
+ TitleCloseIfo(d);
return title;
}
@@ -1560,18 +1437,19 @@ static int hb_dvdnav_start( hb_dvd_t * e, hb_title_t *title, int c )
{
hb_dvdnav_t * d = &(e->dvdnav);
int t = title->index;
- hb_chapter_t *chapter;
+ hb_dvd_chapter_t *chapter;
dvdnav_status_t result;
- d->title_block_count = title->block_count;
- d->list_chapter = title->list_chapter;
-
if ( d->stopped && !hb_dvdnav_reset(d) )
{
return 0;
}
+ if (!TitleOpenIfo(d, t))
+ {
+ return 0;
+ }
dvdnav_reset( d->dvdnav );
- chapter = hb_list_item( title->list_chapter, c - 1);
+ chapter = hb_list_item( d->list_dvd_chapter, c - 1);
if (chapter != NULL)
result = dvdnav_program_play(d->dvdnav, t, chapter->pgcn, chapter->pgn);
else
@@ -1582,7 +1460,6 @@ static int hb_dvdnav_start( hb_dvd_t * e, hb_title_t *title, int c )
dvdnav_err_to_string(d->dvdnav) );
return 0;
}
- d->title = t;
d->stopped = 0;
d->chapter = 0;
d->cell = 0;
@@ -1621,10 +1498,10 @@ static int hb_dvdnav_seek( hb_dvd_t * e, float f )
// PGC. Position there & adjust the offset if so.
uint64_t pgc_offset = 0;
uint64_t chap_offset = 0;
- hb_chapter_t *pgc_change = hb_list_item(d->list_chapter, 0 );
- for ( ii = 0; ii < hb_list_count( d->list_chapter ); ++ii )
+ hb_dvd_chapter_t *pgc_change = hb_list_item(d->list_dvd_chapter, 0 );
+ for ( ii = 0; ii < hb_list_count( d->list_dvd_chapter ); ++ii )
{
- hb_chapter_t *chapter = hb_list_item( d->list_chapter, ii );
+ hb_dvd_chapter_t *chapter = hb_list_item( d->list_dvd_chapter, ii );
uint64_t chap_len = chapter->block_end - chapter->block_start + 1;
if ( chapter->pgcn != pgc_change->pgcn )
@@ -1870,7 +1747,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e )
hb_deep_log(2, "dvdnav: cell change, found next title");
return NULL;
}
- c = FindChapterIndex(d->list_chapter, pgcn, pgn);
+ c = FindChapterIndex(d->list_dvd_chapter, pgcn, pgn);
if (c != d->chapter)
{
if (c < d->chapter)
@@ -1951,7 +1828,7 @@ static int hb_dvdnav_chapter( hb_dvd_t * e )
{
return -1;
}
- c = FindChapterIndex( d->list_chapter, pgcn, pgn );
+ c = FindChapterIndex( d->list_dvd_chapter, pgcn, pgn );
return c;
}
@@ -1962,14 +1839,16 @@ static int hb_dvdnav_chapter( hb_dvd_t * e )
**********************************************************************/
static void hb_dvdnav_close( hb_dvd_t ** _d )
{
- hb_dvdnav_t * d = &((*_d)->dvdnav);
+ hb_dvdnav_t * d = &((*_d)->dvdnav);
- if( d->dvdnav ) dvdnav_close( d->dvdnav );
- if( d->vmg ) ifoClose( d->vmg );
- if( d->reader ) DVDClose( d->reader );
+ if (d->dvdnav) dvdnav_close( d->dvdnav );
+ if (d->vmg) ifoClose( d->vmg );
+ if (d->reader) DVDClose( d->reader );
free(d->path);
+ TitleCloseIfo(d);
+
free( d );
*_d = NULL;
}
@@ -2016,7 +1895,7 @@ static void hb_dvdnav_set_angle( hb_dvd_t * e, int angle )
static int FindChapterIndex( hb_list_t * list, int pgcn, int pgn )
{
int count, ii;
- hb_chapter_t *chapter;
+ hb_dvd_chapter_t * chapter;
count = hb_list_count( list );
for (ii = 0; ii < count; ii++)
@@ -2116,3 +1995,152 @@ static int dvdtime2msec(dvd_time_t * dt)
return ms;
}
+
+static int TitleOpenIfo(hb_dvdnav_t * d, int t)
+{
+ int pgcn, pgn, pgcn_end, i, c;
+ pgc_t * pgc;
+ int cell_cur;
+ hb_dvd_chapter_t * dvd_chapter;
+ uint64_t duration;
+
+ if (d->title == t && d->ifo != NULL)
+ {
+ // Already opened
+ return 0;
+ }
+
+ // Close previous if open
+ TitleCloseIfo(d);
+
+ /* VTS which our title is in */
+ d->vts = d->vmg->tt_srpt->title[t-1].title_set_nr;
+
+ if (!d->vts)
+ {
+ /* A VTS of 0 means the title wasn't found in the title set */
+ hb_log("Invalid VTS (title set) number: %i", d->vts);
+ goto fail;
+ }
+
+ if(!(d->ifo = ifoOpen(d->reader, d->vts)))
+ {
+ hb_log( "ifoOpen failed" );
+ goto fail;
+ }
+
+ int title_ttn = d->vmg->tt_srpt->title[t-1].vts_ttn;
+ if ( title_ttn < 1 || title_ttn > d->ifo->vts_ptt_srpt->nr_of_srpts )
+ {
+ hb_log( "invalid VTS PTT offset %d for title %d, skipping", title_ttn, t );
+ goto fail;
+ }
+
+ d->duration = 0LL;
+ d->pgcn = -1;
+ d->pgn = 1;
+ for (i = 0; i < d->ifo->vts_ptt_srpt->title[title_ttn-1].nr_of_ptts; i++)
+ {
+ int blocks = 0;
+
+ duration = PttDuration(d->ifo, title_ttn, i+1, &blocks, &pgcn_end);
+ pgcn = d->ifo->vts_ptt_srpt->title[title_ttn-1].ptt[i].pgcn;
+ pgn = d->ifo->vts_ptt_srpt->title[title_ttn-1].ptt[i].pgn;
+ if (duration > d->duration)
+ {
+ d->pgcn = pgcn;
+ d->pgn = pgn;
+ d->duration = duration;
+ d->title_block_count = blocks;
+ }
+ else if (pgcn == d->pgcn && pgn < d->pgn)
+ {
+ d->pgn = pgn;
+ d->title_block_count = blocks;
+ }
+ }
+
+
+ /* Chapters */
+ d->list_dvd_chapter = hb_list_init();
+
+ uint32_t pgcn_map[MAX_PGCN/32];
+ PgcWalkInit( pgcn_map );
+ pgcn = d->pgcn;
+ pgn = d->pgn;
+ c = 0;
+ do
+ {
+ pgc = d->ifo->vts_pgcit->pgci_srp[pgcn-1].pgc;
+
+ for (i = pgn; i <= pgc->nr_of_programs; i++)
+ {
+ int cell_start, cell_end;
+
+ dvd_chapter = calloc(sizeof(hb_dvd_chapter_t), 1);
+
+ dvd_chapter->pgcn = pgcn;
+ dvd_chapter->pgn = i;
+ dvd_chapter->index = c + 1;
+
+ cell_start = pgc->program_map[i-1] - 1;
+ dvd_chapter->block_start = pgc->cell_playback[cell_start].first_sector;
+
+ // if there are no more programs in this pgc, the end cell is the
+ // last cell. Otherwise it's the cell before the start cell of the
+ // next program.
+ if (i == pgc->nr_of_programs)
+ {
+ cell_end = pgc->nr_of_cells - 1;
+ }
+ else
+ {
+ cell_end = pgc->program_map[i] - 2;
+ }
+ dvd_chapter->block_end = pgc->cell_playback[cell_end].last_sector;
+
+ /* duration */
+ dvd_chapter->duration = 0;
+
+ cell_cur = cell_start;
+ while( cell_cur <= cell_end )
+ {
+#define cp pgc->cell_playback[cell_cur]
+ dvd_chapter->duration += 90LL * dvdtime2msec(&cp.playback_time);
+#undef cp
+ cell_cur = FindNextCell( pgc, cell_cur );
+ }
+ hb_list_add(d->list_dvd_chapter, dvd_chapter);
+ c++;
+ }
+ pgn = 1;
+ } while ((pgcn = NextPgcn(d->ifo, pgcn, pgcn_map)) != 0);
+
+ d->title = t;
+ return 1;
+
+fail:
+ TitleCloseIfo(d);
+ return 0;
+}
+
+static void TitleCloseIfo(hb_dvdnav_t * d)
+{
+ hb_dvd_chapter_t * chapter;
+ while ((chapter = hb_list_item(d->list_dvd_chapter, 0)))
+ {
+ hb_list_rem(d->list_dvd_chapter, chapter );
+ free(chapter);
+ }
+ hb_list_close(&d->list_dvd_chapter);
+
+ if (d->ifo)
+ {
+ ifoClose(d->ifo);
+ }
+ d->ifo = NULL;
+ d->title = 0;
+ d->vts = 0;
+ d->pgcn = 0;
+ d->pgn = 0;
+}