[vlc-commits] [Git][videolan/vlc][master] 3 commits: access: dvdread: fill title/chapter timing metadata in setArea
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat May 2 13:27:32 UTC 2026
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
be4c928e by Saifelden Mohamed Ismail at 2026-05-02T14:32:25+02:00
access: dvdread: fill title/chapter timing metadata in setArea
- - - - -
229465f6 by Saifelden Mohamed Ismail at 2026-05-02T14:32:25+02:00
access: dvdread: fix dvd-video and dvd-audio seek block mapping
- - - - -
384b26e0 by Saifelden Mohamed Ismail at 2026-05-02T14:32:25+02:00
access: dvdread: use size_t for DvdReadSeek vobu index
- - - - -
1 changed file:
- modules/access/dvdread.c
Changes:
=====================================
modules/access/dvdread.c
=====================================
@@ -1053,9 +1053,8 @@ static int Demux( demux_t *p_demux )
#if defined(DVDREAD_HAS_DVDAUDIO)
if( !p_sys->i_pack_len && type == DVD_A )
{
- p_sys->i_pack_len = p_sys->i_title_blocks;
- p_sys->i_cur_block = p_sys->p_title_table->atsi_track_pointer_rows[p_sys->i_chapter].start_sector;
-
+ if( p_sys->i_cur_block <= p_sys->i_title_end_block )
+ p_sys->i_pack_len = p_sys->i_title_end_block - p_sys->i_cur_block + 1;
}
else
#endif
@@ -1447,6 +1446,50 @@ static int DvdReadSetArea( demux_t *p_demux, int i_title, int i_chapter,
p_sys->i_cur_cell = p_pgc->program_map[pgn - 1] - 1;
DvdReadFindCell( p_demux );
+ /* walk ptts accumulating per-cell durations to set each seekpoint's i_time_offset */
+ if( p_sys->i_chapters > 0 )
+ {
+ input_title_t *p_title = p_sys->titles[i_title];
+ if( p_title->seekpoint )
+ {
+ const int max_sp = __MIN( p_title->i_seekpoint,
+ p_sys->i_chapters );
+ const int max_ptt = p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].nr_of_ptts;
+ const pgc_t *p_pgc_seek = p_sys->p_cur_pgc;
+ int cell = p_sys->i_title_start_cell;
+ vlc_tick_t t = 0;
+ for( int sj = 0; sj < max_sp && sj < max_ptt; sj++ )
+ {
+ const uint16_t sj_pgc_id =
+ p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1]
+ .ptt[sj].pgcn;
+ const uint16_t sj_pgn =
+ p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1]
+ .ptt[sj].pgn;
+
+ /* cells are pgc-local, stop on pgc mismatch */
+ if( sj_pgc_id != pgc_id || sj_pgn == 0 )
+ break;
+ if( sj_pgn > p_pgc_seek->nr_of_programs )
+ break;
+
+ const int chapter_cell =
+ p_pgc_seek->program_map[sj_pgn - 1] - 1;
+ while( cell < chapter_cell &&
+ cell <= p_sys->i_title_end_cell )
+ {
+ t += dvdtime_to_time( &p_pgc_seek->cell_playback[cell]
+ .playback_time );
+ cell++;
+ }
+ p_title->seekpoint[sj]->i_time_offset = t;
+ }
+ p_title->i_length = DvdReadGetTitleDuration( p_sys );
+ }
+ }
+
+ DvdReadResetCellTs( p_sys );
+
p_sys->i_next_vobu = p_sys->i_cur_block =
p_pgc->cell_playback[p_sys->i_cur_cell].first_sector;
@@ -1694,6 +1737,7 @@ static int DvdAudioReadSetArea( demux_t *p_demux, int i_title, int i_track,
p_sys->p_title = NULL;
}
p_sys->i_title = i_title;
+ DvdReadResetCellTs( p_sys );
/* reusing p_vmg variable for p_amg */
const ifo_handle_t *p_vmg = p_sys->p_vmg_file;
@@ -1737,6 +1781,41 @@ static int DvdAudioReadSetArea( demux_t *p_demux, int i_title, int i_track,
p_sys->i_title_start_block, p_sys->i_title_end_block,
p_sys->i_title_blocks );
+ if( p_sys->i_chapters > 0 )
+ {
+ input_title_t *p_title = p_sys->titles[i_title];
+ if( p_title->seekpoint && p_sys->i_title_blocks > 0 )
+ {
+ const vlc_tick_t title_length = FROM_SCALE_NZ(
+ p_sys->p_title_table->length_pts );
+ const uint32_t first_sector =
+ p_sys->p_title_table->atsi_track_pointer_rows[0].start_sector;
+
+ p_title->i_length = title_length;
+
+ const int max_sp = __MIN( p_title->i_seekpoint,
+ p_sys->i_chapters );
+ /* offset relative to title start */
+ for( int sj = 0; sj < max_sp; sj++ )
+ {
+ const uint32_t sj_sector =
+ p_sys->p_title_table->atsi_track_pointer_rows[sj].start_sector;
+ const uint32_t offset = sj_sector > first_sector
+ ? sj_sector - first_sector : 0;
+ if( title_length > 0 &&
+ offset > UINT64_MAX / (uint64_t)title_length )
+ {
+ msg_Err( p_demux, "chapter offset multiply overflow" );
+ return VLC_EGENERIC;
+ }
+ /* widen for the multiply, product fits uint64_t */
+ p_title->seekpoint[sj]->i_time_offset =
+ (vlc_tick_t)( (uint64_t)offset * title_length /
+ p_sys->i_title_blocks );
+ }
+ }
+ }
+
/* The structure of DVD-A discs seems to be the following
* each ATS IFO-> is a GROUP -> Contains multiple titles, Span across one or more AOBs -> each title contains multiple tracks or "Trackpoints",
*
@@ -1805,6 +1884,7 @@ static int DvdAudioReadSetArea( demux_t *p_demux, int i_title, int i_track,
p_sys->i_pack_len = 0;
/* current block relative to start of title*/
p_sys->i_cur_block=p_sys->p_title_table->atsi_track_pointer_rows[i_track].start_sector;
+ DvdReadResetCellTs( p_sys );
if( p_sys->cur_chapter != i_track)
{
@@ -2138,10 +2218,16 @@ static int DvdReadSeek( demux_t *p_demux, uint32_t i_block_offset )
/* Find vobu */
/* see ifo_read.c / ifoRead_VOBU_ADMAP_internal for index count */
- int i_vobu = 1;
+ if( unlikely( p_vts->vts_vobu_admap == NULL ||
+ p_vts->vts_vobu_admap->last_byte < VOBU_ADMAP_SIZE ) )
+ return VLC_EGENERIC;
+
+ size_t i_vobu = 1;
const size_t i_vobu_sect_index_count =
(p_vts->vts_vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE) /
sizeof(*p_vts->vts_vobu_admap->vobu_start_sectors);
+ if( unlikely( i_vobu_sect_index_count == 0 ) )
+ return VLC_EGENERIC;
for( size_t i=0; i<i_vobu_sect_index_count; i++ )
{
if( p_vts->vts_vobu_admap->vobu_start_sectors[i] > i_block )
@@ -2162,24 +2248,32 @@ static int DvdReadSeek( demux_t *p_demux, uint32_t i_block_offset )
i_sub_cell = i + 1;
}
- msg_Dbg( p_demux, "cell %d i_sub_cell %d chapter %d vobu %d "
+ /* i_vobu reaches count when no entry exceeds i_block, guard the debug peek */
+ const size_t i_vobu_dbg_next = i_vobu < i_vobu_sect_index_count
+ ? i_vobu : i_vobu_sect_index_count - 1;
+ msg_Dbg( p_demux, "cell %d i_sub_cell %d chapter %d vobu %zu "
"cell_sector %d vobu_sector %d sub_cell_sector %d",
i_cell, i_sub_cell, i_chapter, i_vobu,
p_sys->p_cur_pgc->cell_playback[i_cell].first_sector,
- p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu],
+ p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu_dbg_next],
p_vts->vts_c_adt->cell_adr_table[i_sub_cell - 1].start_sector);
#endif
- p_sys->i_cur_block = i_block;
- if(likely( (size_t)i_vobu < i_vobu_sect_index_count ))
- p_sys->i_next_vobu = p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu];
- else
- p_sys->i_next_vobu = i_block;
- p_sys->i_pack_len = p_sys->i_next_vobu - i_block;
+ /* snap to vobu start, nav packet only at vobu head */
+ const uint32_t vobu_start_sector_snap =
+ p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu - 1];
+
+ p_sys->i_cur_block = vobu_start_sector_snap;
+ p_sys->i_next_vobu = vobu_start_sector_snap;
+ /* len set by DvdReadHandleDSI from dsi */
+ p_sys->i_pack_len = 0;
p_sys->i_cur_cell = i_cell;
p_sys->i_chapter = i_chapter;
DvdReadFindCell( p_demux );
+ DvdReadResetCellTs( p_sys );
+ es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
+
return VLC_SUCCESS;
}
@@ -2216,10 +2310,19 @@ static int DvdAudioReadSeek( demux_t *p_demux, uint32_t i_block_offset )
p_sys->cur_chapter = i_chapter;
}
- p_sys->i_cur_block = p_sys->p_title_table->atsi_track_pointer_rows[i_chapter].start_sector;
- p_sys->i_pack_len = 4;
+ const uint32_t start_sector =
+ p_sys->p_title_table->atsi_track_pointer_rows[i_chapter].start_sector;
+ /* i_block_offset title-relative, i_seek_blocks is chapter start */
+ const uint32_t within_chapter = i_block_offset - i_seek_blocks;
+ p_sys->i_cur_block = start_sector + within_chapter;
+
+ if( p_sys->i_cur_block <= p_sys->i_title_end_block )
+ p_sys->i_pack_len = p_sys->i_title_end_block - p_sys->i_cur_block + 1;
+ else
+ p_sys->i_pack_len = 0;
p_sys->i_title_offset = i_block_offset;
p_sys->i_chapter = i_chapter;
+ DvdReadResetCellTs( p_sys );
return VLC_SUCCESS;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/83f6a75a17904013ac3df1da9f8d3baf8293a8f8...384b26e0f973afd5548f4e1a485f65675b858553
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/83f6a75a17904013ac3df1da9f8d3baf8293a8f8...384b26e0f973afd5548f4e1a485f65675b858553
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list