[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