[vlc-commits] [Git][videolan/vlc][master] 3 commits: access: dvdread: fix dvd-video seek accuracy

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sun May 24 14:04:38 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
1e02df57 by Saifelden Mohamed Ismail at 2026-05-24T15:53:49+02:00
access: dvdread: fix dvd-video seek accuracy

- - - - -
cc323ab2 by Saifelden Mohamed Ismail at 2026-05-24T15:53:49+02:00
access: dvdread: advance dvd-vr title when seeking past the end

- - - - -
d781b84d by Saifelden Mohamed Ismail at 2026-05-24T15:53:49+02:00
dvdnav: route position seeks through time for accuracy

- - - - -


3 changed files:

- modules/access/dvdnav.c
- modules/access/dvdread_video.c
- modules/access/dvdread_vr.c


Changes:

=====================================
modules/access/dvdnav.c
=====================================
@@ -632,7 +632,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 return VLC_SUCCESS;
 
             case DEMUX_SET_POSITION:
-                pos = va_arg( args, double ) * len;
+            {
+                const double f = va_arg( args, double );
+                if( p_sys->i_pgc_length > 0 &&
+                    dvdnav_jump_to_sector_by_time( p_sys->dvdnav,
+                        TO_SCALE_NZ((vlc_tick_t)( f * p_sys->i_pgc_length )),
+                        SEEK_SET ) == DVDNAV_STATUS_OK )
+                    return VLC_SUCCESS;
+                pos = (uint32_t)( f * len );
                 if( dvdnav_sector_search( p_sys->dvdnav, pos, SEEK_SET ) ==
                       DVDNAV_STATUS_OK )
                 {
@@ -640,6 +647,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 }
                 RandomAccessCleanup( p_sys );
                 break;
+            }
 
             case DEMUX_GET_LENGTH:
                 if( p_sys->i_pgc_length > 0 )


=====================================
modules/access/dvdread_video.c
=====================================
@@ -132,6 +132,50 @@ static uint32_t DvdReadTimeToSeekOffset( const demux_sys_t *p_sys, vlc_tick_t ti
     return i_block_offset;
 }
 
+static uint32_t DvdReadCellAwareBlock( const demux_sys_t *p_sys,
+                                       uint32_t i_block_offset )
+{
+    const pgc_t *p_pgc = p_sys->p_cur_pgc;
+    if( !p_pgc || !p_pgc->cell_playback ||
+        p_sys->i_title_start_cell > p_sys->i_title_end_cell ||
+        p_sys->i_title_blocks == 0 )
+        return i_block_offset;
+
+    const vlc_tick_t length = DvdReadVideoTitleDuration( p_sys );
+    vlc_tick_t product;
+    if( ckd_mul( &product, i_block_offset, length ) )
+        return i_block_offset;
+    const vlc_tick_t t = product / p_sys->i_title_blocks;
+
+    vlc_tick_t acc = 0;
+    uint32_t block_acc = 0;
+    for( int ci = p_sys->i_title_start_cell; ci <= p_sys->i_title_end_cell; ci++ )
+    {
+        const cell_playback_t *cell = &p_pgc->cell_playback[ci];
+        const vlc_tick_t dur = dvdtime_to_time( &cell->playback_time );
+        if( dur == 0 )
+            continue;
+        const uint32_t blocks = cell->last_sector - cell->first_sector + 1;
+
+        vlc_tick_t next_acc;
+        uint32_t next_block_acc;
+        if( ckd_add( &next_acc, acc, dur ) ||
+            ckd_add( &next_block_acc, block_acc, blocks ) )
+            return i_block_offset;
+
+        if( next_acc > t )
+        {
+            vlc_tick_t scaled;
+            if( !ckd_mul( &scaled, t - acc, blocks ) )
+                return block_acc + (uint32_t)( scaled / dur );
+            return i_block_offset;
+        }
+        acc = next_acc;
+        block_acc = next_block_acc;
+    }
+    return i_block_offset;
+}
+
 static int DvdReadPsSource( void )
 {
     return PS_SOURCE_VOB;
@@ -332,6 +376,8 @@ static int DvdReadSeek( demux_t *p_demux, uint32_t i_block_offset )
     const pgc_t *p_pgc = p_sys->p_cur_pgc;
     const ifo_handle_t *p_vts = p_sys->p_vts_file;
 
+    i_block_offset = DvdReadCellAwareBlock( p_sys, i_block_offset );
+
     /* Find cell */
     i_block = i_block_offset;
     for( i_cell = p_sys->i_title_start_cell;


=====================================
modules/access/dvdread_vr.c
=====================================
@@ -119,7 +119,7 @@ static uint32_t DvdVRReadTimeToVobuOffset( const demux_sys_t *p_sys, vlc_tick_t
         const vlc_tick_t dur = DvdVRProgramDuration( pgi );
         if( dur == 0 )
             continue;
-        if( acc + dur > t )
+        if( acc + dur >= t )
         {
             const vlc_tick_t within = t - acc;
             const uint32_t within_vobu = (uint32_t)(within * vobus / dur);
@@ -463,20 +463,15 @@ static int DvdVRReadSeek( demux_t *p_demux, uint32_t i_block_offset )
                    ? p_sys->ud_pgcit->m_c_gi[cell_idx].c_epi_n : 1;
     }
 
-    /* seek past title end: snap to last cell */
-    if( !found_cell && nr > 0 )
+    /* seek past title end: flag end so demux advances to the next title */
+    if( !found_cell )
     {
-        const int last_cell_idx = cell_base + nr - 1;
-        uint16_t srpn = p_sys->ud_pgcit->m_c_gi[last_cell_idx].m_vobi_srpn;
-        if( unlikely( srpn == 0 || srpn > p_sys->pgc_gi->nr_of_programs ) )
-            return VLC_EGENERIC;
-
-        const uint16_t last_vobus = p_sys->pgc_gi->pgi[srpn - 1].map.nr_of_vobu_info;
-        p_sys->i_cur_cell = last_cell_idx;
-        if( last_vobus > 0 && vobu_accum >= last_vobus )
-            vobu_accum -= last_vobus;
-        else
-            vobu_accum = 0;
+        p_sys->i_cur_cell = p_sys->i_title_end_cell;
+        p_sys->i_pack_len = 0;
+        p_sys->i_title_offset = p_sys->i_title_blocks;
+        DvdReadResetCellTs( p_sys );
+        es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
+        return VLC_SUCCESS;
     }
 
     if( i_chapter < p_sys->i_chapters &&



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4f465d43d84c53469c493737402bd2a44a2b6fb6...d781b84d59c89636f7150f6d5ced2e2304445d0f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4f465d43d84c53469c493737402bd2a44a2b6fb6...d781b84d59c89636f7150f6d5ced2e2304445d0f
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list