[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