diff --git a/modules/demux/mpeg/timestamps.h b/modules/demux/mpeg/timestamps.h index b30dd007c0..93897069cc 100644 --- a/modules/demux/mpeg/timestamps.h +++ b/modules/demux/mpeg/timestamps.h @@ -33,11 +33,17 @@ typedef int64_t ts_90khz_t; static inline vlc_tick_t TimeStampWrapAround( vlc_tick_t i_past_pcr, vlc_tick_t i_time ) { - vlc_tick_t i_adjust = 0; - if( i_past_pcr > TS_33BITS_HALF_ROLL_NZ && i_time < TS_33BITS_HALF_ROLL_NZ ) - i_adjust = TS_33BITS_ROLL_NZ; + if( i_past_pcr == VLC_TICK_INVALID || i_time >= i_past_pcr ) + return i_time; - return i_time + i_adjust; + vlc_tick_t delta = i_past_pcr - i_time; + if( delta >= TS_33BITS_HALF_ROLL_NZ ) + { + vlc_tick_t rolls = (delta + TS_33BITS_ROLL_NZ - 1) / TS_33BITS_ROLL_NZ; + i_time += rolls * TS_33BITS_ROLL_NZ; + } + + return i_time; } #endif diff --git a/test/modules/demux/timestamps.c b/test/modules/demux/timestamps.c index f4329562d6..6b4e659eb4 100644 --- a/test/modules/demux/timestamps.c +++ b/test/modules/demux/timestamps.c @@ -82,5 +82,16 @@ int main(void) ts2 = TimeStampWrapAround(VLC_TICK_0 + TS_33BITS_ROLL_NZ, ts1); ASSERT(ts2 == ts1 + TS_33BITS_ROLL_NZ); + /* Should wrap multiple times */ + ts1 = VLC_TICK_0; + ts2 = TimeStampWrapAround(VLC_TICK_0 + TS_33BITS_ROLL_NZ * 2, ts1); + ASSERT(ts2 > ts1); + ASSERT(ts2 == ts1 + TS_33BITS_ROLL_NZ * 2); + + ts1 = VLC_TICK_0 + TS_33BITS_HALF_ROLL_NZ; + ts2 = TimeStampWrapAround(VLC_TICK_0 + TS_33BITS_ROLL_NZ * 5, ts1); + ASSERT(ts2 > ts1); + ASSERT(ts2 == ts1 + TS_33BITS_ROLL_NZ * 5); + return 0; }