[vlc-commits] [Git][videolan/vlc][3.0.x] 9 commits: vlc_tick: add helper macros to convert microseconds to/from vlc_tick_t

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Mar 20 12:25:02 UTC 2026



Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC


Commits:
b0fb96f9 by Steve Lhomme at 2026-03-20T11:44:23+00:00
vlc_tick: add helper macros to convert microseconds to/from vlc_tick_t

(cherry picked from commit 0fc429197c726ccf5692f5802034aed60e5cd3e7) (edited)
edited:
- in 3.0 it's still called vlc_mtime.h

- - - - -
3a73a105 by Steve Lhomme at 2026-03-20T11:44:23+00:00
vlc_tick: add helper macros to convert nanoseconds to/from vlc_tick_t

(cherry picked from commit 1d3482ef4e3031cc1dab24d21d194e9591c0cb17) (edited)
edited:
- in 3.0 it's still called vlc_mtime.h

- - - - -
6f5a426e by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: use vlc_tick_t to store chapter start/end timestamps

(cherry picked from commit 56340bc86f4ba2d1a730b7b6aea4b9052b502eac) (edited)
edited:
- i_start_time/i_end_time already have a default value set

- - - - -
8eb68118 by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: read the codec delay as an vlc_tick_t

(cherry picked from commit 3f49b42aa70e72342697af939230e447f5951fe1)

- - - - -
6acc4708 by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: read the seek preroll as an vlc_tick_t

(cherry picked from commit ab2cd200bab8c35519350927d21ac46b40184289)

- - - - -
00930afb by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv clean the cue time conversion to vlc_tick_t

(cherry picked from commit a195bb78b0e7e461923025cfbf2e0c066c0c4ece)

- - - - -
114fbff3 by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: convert libmatroska timestamps using VLC_TICK_FROM_NS()

(cherry picked from commit 723ee20e4c82f3a030d760eb7269ede8d59554d4)

- - - - -
efffa44e by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: virtual chapter timestamps are in vlc_tick_t

(cherry picked from commit 40eadf4c1e8832de8ec39c67c8c7884ea685ce0e)

- - - - -
2c79769f by Steve Lhomme at 2026-03-20T11:44:23+00:00
demux:mkv: read the default duration directly in vlc_tick_t

(cherry picked from commit a16b04541ffa5b672926f2b539e8db0a81da83c8)

- - - - -


9 changed files:

- include/vlc_mtime.h
- modules/demux/mkv/chapters.hpp
- modules/demux/mkv/matroska_segment.cpp
- modules/demux/mkv/matroska_segment_parse.cpp
- modules/demux/mkv/matroska_segment_seeker.cpp
- modules/demux/mkv/mkv.cpp
- modules/demux/mkv/mkv.hpp
- modules/demux/mkv/virtual_segment.cpp
- modules/demux/mkv/virtual_segment.hpp


Changes:

=====================================
include/vlc_mtime.h
=====================================
@@ -57,6 +57,36 @@
 #endif /* CLOCK_FREQ / 1000 */
 
 
+/*
+ * vlc_tick_t <> microseconds (us) conversions
+ */
+#if (CLOCK_FREQ % 1000000) == 0
+#define VLC_TICK_FROM_US(us)    ((CLOCK_FREQ / INT64_C(1000000)) * (us))
+#define US_FROM_VLC_TICK(vtk)   ((vtk) / (CLOCK_FREQ / INT64_C(1000000)))
+#elif (1000000 % CLOCK_FREQ) == 0
+#define VLC_TICK_FROM_US(us)    ((us)  / (INT64_C(1000000) / CLOCK_FREQ))
+#define US_FROM_VLC_TICK(vtk)   ((vtk) * (INT64_C(1000000) / CLOCK_FREQ))
+#else /* rounded overflowing conversion */
+#define VLC_TICK_FROM_US(us)    (CLOCK_FREQ * (us) / INT64_C(1000000))
+#define US_FROM_VLC_TICK(vtk)   ((vtk) * INT64_C(1000000) / CLOCK_FREQ)
+#endif /* CLOCK_FREQ / 1000000 */
+
+
+/*
+ * vlc_tick_t <> nanoseconds (ns) conversions
+ */
+#if (CLOCK_FREQ % 1000000000) == 0
+#define VLC_TICK_FROM_NS(ns)    ((ns)  * (CLOCK_FREQ / (INT64_C(1000000000))))
+#define NS_FROM_VLC_TICK(vtk)   ((vtk) / (CLOCK_FREQ / (INT64_C(1000000000))))
+#elif (1000000000 % CLOCK_FREQ) == 0
+#define VLC_TICK_FROM_NS(ns)    ((ns)  / (INT64_C(1000000000) / CLOCK_FREQ))
+#define NS_FROM_VLC_TICK(vtk)   ((vtk) * (INT64_C(1000000000) / CLOCK_FREQ))
+#else /* rounded overflowing conversion */
+#define VLC_TICK_FROM_NS(ns)    (CLOCK_FREQ * (ns) / INT64_C(1000000000))
+#define NS_FROM_VLC_TICK(vtk)   ((vtk) * INT64_C(1000000000) / CLOCK_FREQ)
+#endif /* CLOCK_FREQ / 1000000000 */
+
+
 /*
  * vlc_tick_t <> seconds (sec) conversions
  */


=====================================
modules/demux/mkv/chapters.hpp
=====================================
@@ -64,8 +64,8 @@ public:
     bool                        ParentOf( const chapter_item_c & item ) const;
     int16                       GetTitleNumber( ) const;
 
-    int64_t                     i_start_time = 0;
-    int64_t                     i_end_time = -1;
+    vlc_tick_t                  i_start_time = 0;
+    vlc_tick_t                  i_end_time = -1;
     std::vector<chapter_item_c*> sub_chapters;
     KaxChapterSegmentUID        *p_segment_uid = nullptr;
     KaxChapterSegmentEditionUID *p_segment_edition_uid = nullptr;


=====================================
modules/demux/mkv/matroska_segment.cpp
=====================================
@@ -133,7 +133,7 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
                         b_invalid_cue = true;
                         break;
                     }
-                    cue_mk_time = static_cast<uint64>( *kct_ptr ) * i_timescale / INT64_C(1000);
+                    cue_mk_time = VLC_TICK_FROM_NS(static_cast<uint64>( *kct_ptr ) * i_timescale);
                 }
                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
                 {
@@ -1277,7 +1277,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
                 bool const b_valid_track = vars.obj->FindTrackByBlock( NULL, &ksblock ) != NULL;
                 if (b_valid_track)
                     vars.obj->_seeker.add_seekpoint( ksblock.TrackNum(),
-                        SegmentSeeker::Seekpoint( ksblock.GetElementPosition(), ksblock.GlobalTimecode() / 1000 ) );
+                        SegmentSeeker::Seekpoint( ksblock.GetElementPosition(), VLC_TICK_FROM_NS(ksblock.GlobalTimecode()) ) );
             }
         }
     };
@@ -1305,7 +1305,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
             if( p_track != NULL && p_track->fmt.i_cat == SPU_ES )
             {
                 vars.obj->_seeker.add_seekpoint( kblock.TrackNum(),
-                    SegmentSeeker::Seekpoint( kblock.GetElementPosition(), kblock.GlobalTimecode() / 1000 ) );
+                    SegmentSeeker::Seekpoint( kblock.GetElementPosition(), VLC_TICK_FROM_NS(kblock.GlobalTimecode()) ) );
             }
 
             vars.ep->Keep ();


=====================================
modules/demux/mkv/matroska_segment_parse.cpp
=====================================
@@ -332,9 +332,8 @@ void matroska_segment_c::ParseTrackEntry( const KaxTrackEntry *m )
         }
         E_CASE( KaxTrackDefaultDuration, defd )
         {
-            vars.tk->i_default_duration = static_cast<uint64>(defd);
+            vars.tk->i_default_duration = VLC_TICK_FROM_NS(static_cast<uint64>(defd));
             debug( vars, "Track Default Duration=%" PRId64, vars.tk->i_default_duration );
-            vars.tk->i_default_duration /= 1000;
         }
         E_CASE( KaxTrackTimecodeScale, ttcs )
         {
@@ -409,13 +408,13 @@ void matroska_segment_c::ParseTrackEntry( const KaxTrackEntry *m )
 #if LIBMATROSKA_VERSION >= 0x010401
         E_CASE( KaxCodecDelay, codecdelay )
         {
-            vars.tk->i_codec_delay = static_cast<uint64_t>( codecdelay ) / 1000;
+            vars.tk->i_codec_delay = VLC_TICK_FROM_NS(static_cast<uint64_t>( codecdelay ));
             msg_Dbg( vars.p_demuxer, "|   |   |   + Track Codec Delay=%" PRIu64,
                      vars.tk->i_codec_delay );
         }
         E_CASE( KaxSeekPreRoll, spr )
         {
-            vars.tk->i_seek_preroll = static_cast<uint64_t>( spr ) / 1000;
+            vars.tk->i_seek_preroll = VLC_TICK_FROM_NS(static_cast<uint64_t>( spr ));
             debug( vars, "Track Seek Preroll=%" PRIu64, vars.tk->i_seek_preroll );
         }
 #endif
@@ -1209,12 +1208,12 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap
         }
         E_CASE( KaxChapterTimeStart, start )
         {
-            vars.chapters.i_start_time = static_cast<uint64>( start ) / (INT64_C(1000000000) / CLOCK_FREQ);
+            vars.chapters.i_start_time = VLC_TICK_FROM_NS(static_cast<uint64>( start ));
             debug( vars, "ChapterTimeStart=%" PRId64, vars.chapters.i_start_time );
         }
         E_CASE( KaxChapterTimeEnd, end )
         {
-            vars.chapters.i_end_time = static_cast<uint64>( end ) / (INT64_C(1000000000) / CLOCK_FREQ);
+            vars.chapters.i_end_time = VLC_TICK_FROM_NS(static_cast<uint64>( end ));
             debug( vars, "ChapterTimeEnd=%" PRId64, vars.chapters.i_end_time );
         }
         E_CASE( KaxChapterDisplay, chapter_display )
@@ -1447,7 +1446,7 @@ bool matroska_segment_c::ParseCluster( KaxCluster *cluster, bool b_update_start_
     }
 
     if( b_update_start_time )
-        i_mk_start_time = cluster->GlobalTimecode() / INT64_C( 1000 );
+        i_mk_start_time = VLC_TICK_FROM_NS( cluster->GlobalTimecode() );
 
     return true;
 }


=====================================
modules/demux/mkv/matroska_segment_seeker.cpp
=====================================
@@ -66,7 +66,7 @@ SegmentSeeker::add_cluster( KaxCluster * const p_cluster )
 {
     Cluster cinfo = {
         /* fpos     */ p_cluster->GetElementPosition(),
-        /* pts      */ vlc_tick_t( p_cluster->GlobalTimecode() / INT64_C( 1000 ) ),
+        /* pts      */ vlc_tick_t( VLC_TICK_FROM_NS( p_cluster->GlobalTimecode() ) ),
         /* duration */ vlc_tick_t( -1 ),
         /* size     */ p_cluster->IsFiniteSize()
             ? p_cluster->GetEndPosition() - p_cluster->GetElementPosition()
@@ -377,7 +377,7 @@ SegmentSeeker::index_unsearched_range( matroska_segment_c& ms, Range search_area
             : static_cast<KaxInternalBlock&>( *block );
 
         block_pos = internal_block.GetElementPosition();
-        block_pts = internal_block.GlobalTimecode() / 1000;
+        block_pts = VLC_TICK_FROM_NS(internal_block.GlobalTimecode());
         track_id  = internal_block.TrackNum();
 
         bool const b_valid_track = ms.FindTrackByBlock( block, simpleblock ) != NULL;


=====================================
modules/demux/mkv/mkv.cpp
=====================================
@@ -591,7 +591,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simp
             handle_real_audio(p_demux, &track, p_block, i_pts);
             block_Release(p_block);
             i_pts = ( track.i_default_duration )?
-                i_pts + ( vlc_tick_t )track.i_default_duration:
+                i_pts + track.i_default_duration:
                 VLC_TICK_INVALID;
             continue;
          }
@@ -685,7 +685,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simp
                 else if ( track.i_last_dts == VLC_TICK_INVALID )
                     p_block->i_dts = i_pts;
                 else
-                    p_block->i_dts = std::min( i_pts, track.i_last_dts + ( vlc_tick_t )track.i_default_duration );
+                    p_block->i_dts = std::min( i_pts, track.i_last_dts + track.i_default_duration );
             }
         }
 
@@ -693,7 +693,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simp
 
         /* use time stamp only for first block */
         i_pts = ( track.i_default_duration )?
-                 i_pts + ( vlc_tick_t )track.i_default_duration:
+                 i_pts + track.i_default_duration:
                  ( track.fmt.b_packetized ) ? VLC_TICK_INVALID : i_pts + 1;
     }
 }
@@ -793,7 +793,7 @@ static int Demux( demux_t *p_demux)
     /* set pts */
     {
         p_sys->i_pts = p_sys->i_mk_chapter_time + VLC_TICK_0;
-        p_sys->i_pts += internal_block.GlobalTimecode() / INT64_C( 1000 );
+        p_sys->i_pts += VLC_TICK_FROM_NS(internal_block.GlobalTimecode());
     }
 
     if ( p_vsegment->CurrentEdition() &&


=====================================
modules/demux/mkv/mkv.hpp
=====================================
@@ -226,7 +226,7 @@ class mkv_track_t
         bool         b_pts_only;
 
         bool         b_no_duration;
-        uint64_t     i_default_duration;
+        vlc_tick_t   i_default_duration;
         float        f_timecodescale;
         vlc_tick_t   i_last_dts;
         uint64_t     i_skip_until_fpos; /*< any block before this fpos should be ignored */


=====================================
modules/demux/mkv/virtual_segment.cpp
=====================================
@@ -42,7 +42,7 @@ matroska_segment_c * getSegmentbyUID( KaxSegmentUID * p_uid, std::vector<matrosk
 virtual_chapter_c * virtual_chapter_c::CreateVirtualChapter( chapter_item_c * p_chap,
                                                              matroska_segment_c & main_segment,
                                                              std::vector<matroska_segment_c*> & segments,
-                                                             int64_t & usertime_offset, bool b_ordered)
+                                                             vlc_tick_t & usertime_offset, bool b_ordered)
 {
     std::vector<virtual_chapter_c *> sub_chapters;
     if( !p_chap )
@@ -65,8 +65,8 @@ virtual_chapter_c * virtual_chapter_c::CreateVirtualChapter( chapter_item_c * p_
     if ( !p_segment->b_preloaded )
         p_segment->Preload();
 
-    int64_t start = ( b_ordered )? usertime_offset : p_chap->i_start_time;
-    int64_t tmp = usertime_offset;
+    vlc_tick_t start = ( b_ordered )? usertime_offset : p_chap->i_start_time;
+    vlc_tick_t tmp = usertime_offset;
 
     for( size_t i = 0; i < p_chap->sub_chapters.size(); i++ )
     {
@@ -75,7 +75,7 @@ virtual_chapter_c * virtual_chapter_c::CreateVirtualChapter( chapter_item_c * p_
         if( p_vsubchap )
             sub_chapters.push_back( p_vsubchap );
     }
-    int64_t stop = ( b_ordered )?
+    vlc_tick_t stop = ( b_ordered )?
             (((p_chap->i_end_time == -1 ||
                (p_chap->i_end_time - p_chap->i_start_time) < (tmp - usertime_offset) )) ? tmp :
              p_chap->i_end_time - p_chap->i_start_time + usertime_offset )
@@ -114,7 +114,7 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, matroska_segme
     p_edition = p_edit;
     b_ordered = false;
 
-    int64_t usertime_offset = 0; // microseconds
+    vlc_tick_t usertime_offset = 0; // microseconds
 
     /* ordered chapters */
     if( p_edition && p_edition->b_ordered )
@@ -137,7 +137,7 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, matroska_segme
     {
         matroska_segment_c * p_cur = &main_segment;
         virtual_chapter_c * p_vchap = NULL;
-        int64_t tmp = 0;
+        vlc_tick_t tmp = 0;
 
         /* check for prev linked segments */
         /* FIXME to avoid infinite recursion we limit to 10 prev should be better as parameter */


=====================================
modules/demux/mkv/virtual_segment.hpp
=====================================
@@ -36,7 +36,7 @@
 class virtual_chapter_c
 {
 public:
-    virtual_chapter_c( matroska_segment_c &seg, chapter_item_c *p_chap, int64_t start, int64_t stop, std::vector<virtual_chapter_c *> & sub_chaps ):
+    virtual_chapter_c( matroska_segment_c &seg, chapter_item_c *p_chap, vlc_tick_t start, vlc_tick_t stop, std::vector<virtual_chapter_c *> & sub_chaps ):
         segment(seg), p_chapter(p_chap),
         i_mk_virtual_start_time(start), i_mk_virtual_stop_time(stop),
         sub_vchapters(sub_chaps)
@@ -46,7 +46,7 @@ public:
     static virtual_chapter_c * CreateVirtualChapter( chapter_item_c * p_chap,
                                                      matroska_segment_c & main_segment,
                                                      std::vector<matroska_segment_c*> & segments,
-                                                     int64_t & usertime_offset, bool b_ordered );
+                                                     vlc_tick_t & usertime_offset, bool b_ordered );
 
     virtual_chapter_c* getSubChapterbyTimecode( int64_t time );
     bool Leave( );



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1535de2aa147695dd114e1e396f9285baaf54145...2c79769f27caa2adc935b2bb618dc5845db01543

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1535de2aa147695dd114e1e396f9285baaf54145...2c79769f27caa2adc935b2bb618dc5845db01543
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list