[vlc-commits] [Git][videolan/vlc][master] 3 commits: demux: mkv: process the block duration once we have read the whole BlockGroup

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Aug 21 11:02:55 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
2494e66a by Steve Lhomme at 2026-08-21T10:50:47+00:00
demux: mkv: process the block duration once we have read the whole BlockGroup

The order of elements doesn't guarantee we get the BlockDuration before the DiscardPadding.

- - - - -
144d5345 by Steve Lhomme at 2026-08-21T10:50:47+00:00
demux: mkv: ignore negative DiscardPadding

A negative value means we have to pad the decoded data with silence
at the beginning [^1]. But VLC doesn't support that feature.

Co-authored-by: zhengjianfeng <jianfeng.zheng at mthreads.dev>

[^1]: https://www.rfc-editor.org/info/rfc9559/#section-5.1.3.5.7

- - - - -
a35c3723 by Steve Lhomme at 2026-08-21T10:50:47+00:00
demux: mkv: handle the block duration as always unsigned

- - - - -


6 changed files:

- modules/demux/mkv/matroska_segment.cpp
- modules/demux/mkv/matroska_segment.hpp
- modules/demux/mkv/matroska_segment_seeker.cpp
- modules/demux/mkv/mkv.cpp
- modules/demux/mkv/util.cpp
- modules/demux/mkv/util.hpp


Changes:

=====================================
modules/demux/mkv/matroska_segment.cpp
=====================================
@@ -1158,7 +1158,7 @@ void matroska_segment_c::ESDestroy( )
 int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock,
                                   KaxBlockAdditions * & pp_additions,
                                   bool *pb_key_picture, bool *pb_discardable_picture,
-                                  int64_t *pi_duration )
+                                  uint64_t *pi_duration )
 {
     pp_simpleblock = NULL;
     pp_block = NULL;
@@ -1168,6 +1168,9 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
     *pb_discardable_picture = false;
     *pi_duration = 0;
 
+    uint64_t duration = 0;
+    int64_t duration_padding = 0;
+
     struct BlockPayload {
         matroska_segment_c * const obj;
         EbmlParser         * const ep;
@@ -1176,14 +1179,15 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
         KaxSimpleBlock    *& simpleblock;
         KaxBlockAdditions *& additions;
 
-        int64_t            & i_duration;
+        uint64_t           & i_duration;
+        int64_t            & duration_padding;
         bool               & b_key_picture;
         bool               & b_discardable_picture;
         bool                 b_cluster_timecode;
 
     } payload = {
         this, &ep, &sys.demuxer, pp_block, pp_simpleblock, pp_additions,
-        *pi_duration, *pb_key_picture, *pb_discardable_picture, true
+        duration, duration_padding, *pb_key_picture, *pb_discardable_picture, true
     };
 
     MKV_SWITCH_CREATE( EbmlTypeDispatcher, BlockGetHandler_l1, BlockPayload )
@@ -1325,12 +1329,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
         E_CASE( KaxDiscardPadding, kdiscardp )
         {
             kdiscardp.ReadData( vars.obj->es.I_O() );
-            int64_t i_duration = static_cast<int64_t>( kdiscardp );
-
-            if( vars.i_duration < i_duration )
-                vars.i_duration = 0;
-            else
-                vars.i_duration -= i_duration;
+            vars.duration_padding = static_cast<int64_t>( kdiscardp );
         }
 #endif
         E_CASE_DEFAULT( element )
@@ -1388,6 +1387,20 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
                 }
             }
 
+            /* A negative DiscardPadding designates padding at the start of
+             * the block, which we don't handle; some files in the wild also
+             * carry bogus negative values due to encoder bugs. Never let it
+             * extend the block duration. */
+            if ( duration_padding < 0)
+            {
+                msg_Warn( &sys.demuxer, "ignoring negative DiscardPadding (%" PRId64 ")", duration_padding );
+                *pi_duration = duration;
+            }
+            else if( duration < (uint64_t)duration_padding )
+                *pi_duration = 0;
+            else
+                *pi_duration = duration - duration_padding;
+
             return VLC_SUCCESS;
         }
 


=====================================
modules/demux/mkv/matroska_segment.hpp
=====================================
@@ -147,7 +147,7 @@ public:
     bool Seek( demux_t &, vlc_tick_t i_mk_date, vlc_tick_t i_mk_time_offset, bool b_accurate );
 
     int BlockGet( KaxBlock * &, KaxSimpleBlock * &, KaxBlockAdditions * &,
-                  bool *, bool *, int64_t *);
+                  bool *, bool *, uint64_t *);
 
     mkv_track_t * FindTrackByBlock(const KaxBlock *, const KaxSimpleBlock * );
 


=====================================
modules/demux/mkv/matroska_segment_seeker.cpp
=====================================
@@ -368,7 +368,7 @@ SegmentSeeker::index_unsearched_range( matroska_segment_c& ms, Range search_area
 
         bool     b_key_picture;
         bool     b_discardable_picture;
-        int64_t  i_block_duration;
+        uint64_t  i_block_duration;
         track_id_t track_id;
 
         if( ms.BlockGet( block, simpleblock, additions,


=====================================
modules/demux/mkv/mkv.cpp
=====================================
@@ -539,7 +539,7 @@ static void ReleaseVpxAlpha(void *opaque)
 /* Needed by matroska_segment::Seek() and Seek */
 static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock,
                   const KaxBlockAdditions *additions,
-                  vlc_tick_t i_pts, int64_t i_duration, bool b_key_picture,
+                  vlc_tick_t i_pts, uint64_t i_duration, bool b_key_picture,
                   bool b_discardable_picture )
 {
     demux_sys_t *p_sys = (demux_sys_t *)p_demux->p_sys;
@@ -833,7 +833,7 @@ static int Demux( demux_t *p_demux)
     KaxBlock *block;
     KaxSimpleBlock *simpleblock;
     KaxBlockAdditions *additions;
-    int64_t i_block_duration = 0;
+    uint64_t i_block_duration = 0;
     bool b_key_picture;
     bool b_discardable_picture;
 


=====================================
modules/demux/mkv/util.cpp
=====================================
@@ -426,7 +426,7 @@ int UpdatePCR( demux_t * p_demux )
     return VLC_SUCCESS;
 }
 
-void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, int64_t i_duration )
+void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, uint64_t i_duration )
 {
     demux_sys_t *p_sys = (demux_sys_t *)p_demux->p_sys;
     matroska_segment_c *p_segment = p_sys->GetCurrentVSegment()->CurrentSegment();


=====================================
modules/demux/mkv/util.hpp
=====================================
@@ -37,7 +37,7 @@ block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset);
 void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, vlc_tick_t i_pts);
 block_t *WEBVTT_Repack_Sample(block_t *p_block, bool b_webm = false,
                               const uint8_t * = NULL, size_t = 0);
-void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, int64_t i_duration );
+void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, uint64_t i_duration );
 int UpdatePCR( demux_t * p_demux );
 
 class ByteReader



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8c2b88db9ac5157d11ca4d3592c3efec715c7623...a35c3723f0c8423df4e9711abbb8fa0941e655f4

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8c2b88db9ac5157d11ca4d3592c3efec715c7623...a35c3723f0c8423df4e9711abbb8fa0941e655f4
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