[vlc-commits] [Git][videolan/vlc][master] 7 commits: demux: mp4: return only last sample dts

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Mar 24 01:27:04 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
7c94acd1 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: mp4: return only last sample dts

- - - - -
413ffdd3 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: libmp4: do not store elst version

- - - - -
90811de8 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: libmp4: restrict to known elst versions

- - - - -
3ef970a5 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: libmp4: rework edit list storage

- - - - -
06ce45c7 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: mp4: fix wrong edit list offset regression

- - - - -
bde20986 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: mp4: move edit list mapping to own functions

- - - - -
f7bb59d9 by Francois Cartegnie at 2023-03-24T01:04:39+00:00
demux: mp4: always check and use next edit list

directly skips empty edits and avoids stopping
on last track sample (fixes loop playback)

- - - - -


4 changed files:

- modules/demux/mp4/libmp4.c
- modules/demux/mp4/libmp4.h
- modules/demux/mp4/mp4.c
- src/input/input.c


Changes:

=====================================
modules/demux/mp4/libmp4.c
=====================================
@@ -3291,10 +3291,7 @@ static int MP4_ReadBox_stdp( stream_t *p_stream, MP4_Box_t *p_box )
 
 static void MP4_FreeBox_elst( MP4_Box_t *p_box )
 {
-    free( p_box->data.p_elst->i_segment_duration );
-    free( p_box->data.p_elst->i_media_time );
-    free( p_box->data.p_elst->i_media_rate_integer );
-    free( p_box->data.p_elst->i_media_rate_fraction );
+    free( p_box->data.p_elst->entries );
 }
 
 static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
@@ -3302,39 +3299,36 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
     uint32_t count;
 
     MP4_READBOX_ENTER( MP4_Box_data_elst_t, MP4_FreeBox_elst );
+    MP4_Box_data_elst_t *p_elst = p_box->data.p_elst;
 
-    MP4_GETVERSIONFLAGS( p_box->data.p_elst );
-    MP4_GET4BYTES( count );
+    uint8_t i_version;
+    uint32_t dummy;
+    MP4_GET1BYTE( i_version );
+    MP4_GET3BYTES( dummy ); VLC_UNUSED(dummy);
+
+    if( i_version > 1 )
+        MP4_READBOX_EXIT( 0 );
 
+    MP4_GET4BYTES( count );
     if( count == 0 )
         MP4_READBOX_EXIT( 1 );
 
-    uint32_t i_entries_max = i_read / ((p_box->data.p_elst->i_version == 1) ? 20 : 12);
+    uint32_t i_entries_max = i_read / ((i_version == 1) ? 20 : 12);
     if( count > i_entries_max )
         count = i_entries_max;
 
-    p_box->data.p_elst->i_segment_duration = vlc_alloc( count,
-                                                        sizeof(uint64_t) );
-    p_box->data.p_elst->i_media_time = vlc_alloc( count, sizeof(int64_t) );
-    p_box->data.p_elst->i_media_rate_integer = vlc_alloc( count,
-                                                          sizeof(uint16_t) );
-    p_box->data.p_elst->i_media_rate_fraction = vlc_alloc( count,
-                                                           sizeof(uint16_t) );
-    if( p_box->data.p_elst->i_segment_duration == NULL
-     || p_box->data.p_elst->i_media_time == NULL
-     || p_box->data.p_elst->i_media_rate_integer == NULL
-     || p_box->data.p_elst->i_media_rate_fraction == NULL )
-    {
+    p_elst->entries = vlc_alloc( count, sizeof(*p_elst->entries) );
+    if( !p_elst->entries )
         MP4_READBOX_EXIT( 0 );
-    }
-    p_box->data.p_elst->i_entry_count = count;
+
+    p_elst->i_entry_count = count;
 
     for( uint32_t i = 0; i < count; i++ )
     {
         uint64_t segment_duration;
         int64_t media_time;
 
-        if( p_box->data.p_elst->i_version == 1 )
+        if( i_version == 1 )
         {
             union { int64_t s; uint64_t u; } u;
 
@@ -3351,15 +3345,15 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
             media_time = u.s;
         }
 
-        p_box->data.p_elst->i_segment_duration[i] = segment_duration;
-        p_box->data.p_elst->i_media_time[i] = media_time;
-        MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_integer[i] );
-        MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_fraction[i] );
+        p_elst->entries[i].i_segment_duration = segment_duration;
+        p_elst->entries[i].i_media_time = media_time;
+        MP4_GET2BYTES( p_elst->entries[i].i_media_rate_integer );
+        MP4_GET2BYTES( p_elst->entries[i].i_media_rate_fraction );
     }
 
 #ifdef MP4_VERBOSE
     msg_Dbg( p_stream, "read box: \"elst\" entry-count %" PRIu32,
-             p_box->data.p_elst->i_entry_count );
+             p_elst->i_entry_count );
 #endif
     MP4_READBOX_EXIT( 1 );
 }


=====================================
modules/demux/mp4/libmp4.h
=====================================
@@ -984,18 +984,19 @@ typedef struct MP4_Box_data_stdp_s
 
 } MP4_Box_data_stdp_t;
 
-typedef struct MP4_Box_data_elst_s
+typedef struct
 {
-    uint8_t  i_version;
-    uint32_t i_flags;
+    uint64_t i_segment_duration; /* movie timescale */
+    int64_t  i_media_time; /* media(track) timescale */
+    uint16_t i_media_rate_integer;
+    uint16_t i_media_rate_fraction;
+} MP4_Box_data_elst_entry_t;
 
+typedef struct MP4_Box_data_elst_s
+{
     uint32_t i_entry_count;
 
-    uint64_t *i_segment_duration; /* movie timescale */
-    int64_t  *i_media_time; /* media(track) timescale */
-    uint16_t *i_media_rate_integer;
-    uint16_t *i_media_rate_fraction;
-
+    MP4_Box_data_elst_entry_t *entries;
 
 } MP4_Box_data_elst_t;
 


=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -499,6 +499,52 @@ static const mp4_chunk_t * MP4_TrackChunkForSample( const mp4_track_t *p_track,
     return NULL;
 }
 
+static stime_t MP4_MapTrackTimeIntoTimeline( const mp4_track_t *p_track,
+                                             uint32_t i_movie_timescale,
+                                             stime_t i_time )
+{
+    if( !p_track->p_elst || p_track->BOXDATA(p_elst)->i_entry_count == 0 )
+        return i_time;
+
+    const MP4_Box_data_elst_entry_t *edit =
+            &p_track->BOXDATA(p_elst)->entries[p_track->i_elst];
+
+    /* convert to offset in our current edit */
+    if( edit->i_media_time > 0 && p_track->i_start_dts >= edit->i_media_time )
+        i_time -= edit->i_media_time;
+
+    /* convert media timeline to track timescale */
+    stime_t i_media_elst_start = MP4_rescale( p_track->i_elst_time,
+                                              i_movie_timescale,
+                                              p_track->i_timescale );
+    /* add to timeline start in current edit */
+    i_time += i_media_elst_start;
+
+    return i_time;
+}
+
+static stime_t MP4_MapMediaTimelineToTrackTime( const mp4_track_t *p_track,
+                                                uint32_t i_movie_timescale,
+                                                stime_t i_time )
+{
+    if( !p_track->p_elst || p_track->BOXDATA(p_elst)->i_entry_count == 0 )
+        return i_time;
+
+    const MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
+    /* convert media timeline to track timescale */
+    stime_t i_media_elst_start = MP4_rescale( p_track->i_elst_time,
+                                              i_movie_timescale,
+                                              p_track->i_timescale );
+    /* convert to timeline offset in current edit */
+    i_time -= i_media_elst_start;
+
+    /* add edit start in track samples time to get track sample time */
+    if( elst->entries[p_track->i_elst].i_media_time > 0 )
+        i_time += elst->entries[p_track->i_elst].i_media_time;
+
+    return i_time;
+}
+
 static stime_t MP4_ChunkGetSampleDTS( const mp4_chunk_t *p_chunk,
                                       uint32_t i_sample )
 {
@@ -548,25 +594,9 @@ static vlc_tick_t MP4_TrackGetDTSPTS( demux_t *p_demux, const mp4_track_t *p_tra
     uint32_t delta = p_track->i_next_delta;
 
     /* now handle elst */
-    if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count )
-    {
-        const MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
-
-        /* convert to offset */
-        if( elst->i_media_time[p_track->i_elst] > 0 &&
-           ( elst->i_media_rate_integer[p_track->i_elst] > 0 ||
-             elst->i_media_rate_fraction[p_track->i_elst] > 0 ) )
-        {
-            if( p_track->i_start_dts >= elst->i_media_time[p_track->i_elst] )
-            {
-                sdts -= elst->i_media_time[p_track->i_elst];
-            }
-        }
-    }
+    sdts = MP4_MapTrackTimeIntoTimeline( p_track, p_sys->i_timescale, sdts );
 
     vlc_tick_t i_dts = MP4_rescale_mtime( sdts, p_track->i_timescale);
-    /* add i_elst_time */
-    i_dts += MP4_rescale_mtime( p_track->i_elst_time, p_sys->i_timescale );
 
     if( pi_nzpts )
     {
@@ -1813,8 +1843,8 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, bool b_accurate )
         }
     }
 
-    msg_Dbg( p_demux, "seeking with %"PRId64 "ms %s", MS_FROM_VLC_TICK(i_date - i_start),
-            !b_accurate ? "alignment" : "preroll (use input-fast-seek to avoid)" );
+    msg_Dbg( p_demux, "seeking with %"PRId64 "ms %s to %ld", MS_FROM_VLC_TICK(i_date - i_start),
+            !b_accurate ? "alignment" : "preroll (use input-fast-seek to avoid)", i_date );
 
     for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )
     {
@@ -3315,9 +3345,6 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
     MP4_TrackSetELST( p_demux, p_track, start );
     if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count > 0 )
     {
-        MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
-        int64_t i_mvt= MP4_rescale_qtime( start, p_sys->i_timescale );
-
         /* now calculate i_start for this elst */
         /* offset */
         if( start < MP4_rescale_mtime( p_track->i_elst_time, p_sys->i_timescale ) )
@@ -3328,18 +3355,13 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
             return VLC_SUCCESS;
         }
         /* to track time scale */
-        i_start  = MP4_rescale_qtime( start, p_track->i_timescale );
-        /* add elst offset */
-        if( ( elst->i_media_rate_integer[p_track->i_elst] > 0 ||
-             elst->i_media_rate_fraction[p_track->i_elst] > 0 ) &&
-            elst->i_media_time[p_track->i_elst] > 0 )
-        {
-            i_start += elst->i_media_time[p_track->i_elst];
-        }
+        i_start = MP4_rescale_qtime( start, p_track->i_timescale );
+        /* map through elst offset */
+        i_start = MP4_MapMediaTimelineToTrackTime( p_track, p_sys->i_timescale, i_start );
 
         msg_Dbg( p_demux, "elst (%d) gives %"PRId64"ms (movie)-> %"PRId64
                  "ms (track)", p_track->i_elst,
-                 MP4_rescale( i_mvt, p_sys->i_timescale, 1000 ),
+                 MS_FROM_VLC_TICK(start),
                  MP4_rescale( i_start, p_track->i_timescale, 1000 ) );
     }
     else
@@ -3411,12 +3433,14 @@ static bool FormatIsCompatible( const es_format_t *p_fmt1, const es_format_t *p_
     return es_format_IsSimilar( p_fmt1, p_fmt2 );
 }
 
-static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_chunk )
+static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track,
+                              uint32_t i_previous_chunk )
 {
+    uint32_t i_chunk = p_track->i_chunk;
     /* now see if actual es is ok */
-    if( p_track->i_chunk >= p_track->i_chunk_count ||
-        (p_track->chunk[p_track->i_chunk].i_sample_description_index !=
-         p_track->chunk[i_chunk].i_sample_description_index ) )
+    if( i_previous_chunk != i_chunk &&
+        p_track->chunk[i_previous_chunk].i_sample_description_index !=
+        p_track->chunk[i_chunk].i_sample_description_index )
     {
         msg_Warn( p_demux, "recreate ES for track[Id 0x%x]",
                   p_track->i_track_ID );
@@ -3478,7 +3502,7 @@ static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track, uint32_t i
 static int TrackGotoChunkSample( demux_t *p_demux, mp4_track_t *p_track,
                                  uint32_t i_chunk, uint32_t i_sample )
 {
-    if( TrackUpdateFormat( p_demux, p_track, i_chunk ) != VLC_SUCCESS )
+    if( TrackUpdateFormat( p_demux, p_track, p_track->i_chunk ) != VLC_SUCCESS )
         return VLC_EGENERIC;
 
     p_track->i_chunk    = i_chunk;
@@ -3525,6 +3549,8 @@ static void TrackUpdateSampleAndTimes( mp4_track_t *p_track )
 {
     const mp4_chunk_t *p_chunk = &p_track->chunk[p_track->i_chunk];
     uint32_t i_chunk_sample = p_track->i_sample - p_chunk->i_sample_first;
+    if( i_chunk_sample > p_chunk->i_sample_count && p_chunk->i_sample_count )
+        i_chunk_sample = p_chunk->i_sample_count - 1;
     p_track->i_next_dts = MP4_ChunkGetSampleDTS( p_chunk, i_chunk_sample );
     stime_t i_next_delta;
     if( !MP4_ChunkGetSampleCTSDelta( p_chunk, i_chunk_sample, &i_next_delta ) )
@@ -3668,14 +3694,15 @@ static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
         msg_Warn( p_demux, "elst box found" );
         for( i = 0; i < elst->i_entry_count; i++ )
         {
+            const MP4_Box_data_elst_entry_t *edit = &elst->entries[i];
             msg_Dbg( p_demux, "   - [%d] duration=%"PRId64"ms media time=%"PRId64
                      "ms) rate=%d.%d", i,
-                     MP4_rescale( elst->i_segment_duration[i], p_sys->i_timescale, 1000 ),
-                     elst->i_media_time[i] >= 0 ?
-                        MP4_rescale( elst->i_media_time[i], p_track->i_timescale, 1000 ) :
+                     MP4_rescale( edit->i_segment_duration, p_sys->i_timescale, 1000 ),
+                     edit->i_media_time >= 0 ?
+                        MP4_rescale( edit->i_media_time, p_track->i_timescale, 1000 ) :
                         INT64_C(-1),
-                     elst->i_media_rate_integer[i],
-                     elst->i_media_rate_fraction[i] );
+                     edit->i_media_rate_integer,
+                     edit->i_media_rate_fraction );
         }
 
         if( var_InheritBool( p_demux, CFG_PREFIX"editlist" ) )
@@ -3776,12 +3803,12 @@ static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
 #define MAX_SELECTABLE (INT_MAX - ES_PRIORITY_SELECTABLE_MIN)
         for ( uint32_t i=0; i<p_track->BOXDATA(p_elst)->i_entry_count; i++ )
         {
-            if ( p_track->BOXDATA(p_elst)->i_media_time[i] >= 0 &&
-                 p_track->BOXDATA(p_elst)->i_segment_duration[i] )
+            const MP4_Box_data_elst_entry_t *edit = &p_track->BOXDATA(p_elst)->entries[i];
+            if ( edit->i_media_time >= 0 && edit->i_segment_duration )
             {
                 /* We do selection by inverting start time into priority.
                    The track with earliest edit will have the highest prio */
-                const int i_time = __MIN( MAX_SELECTABLE, p_track->BOXDATA(p_elst)->i_media_time[i] );
+                const int i_time = __MIN( MAX_SELECTABLE, edit->i_media_time );
                 p_track->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + MAX_SELECTABLE - i_time;
                 break;
             }
@@ -4195,52 +4222,99 @@ static uint64_t MP4_TrackGetPos( mp4_track_t *p_track )
     return i_pos;
 }
 
-static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_samples )
+
+static int MP4_TrackSetNextELST( mp4_track_t *tk )
 {
-    if ( UINT32_MAX - p_track->i_sample < i_samples )
-    {
-        p_track->i_sample = UINT32_MAX;
+    if( !tk->p_elst ||
+         tk->i_elst == UINT32_MAX - 1 ||
+         tk->i_elst + 1 >= tk->BOXDATA(p_elst)->i_entry_count )
         return VLC_EGENERIC;
+
+    tk->i_elst_time += tk->BOXDATA(p_elst)->entries[tk->i_elst++].i_segment_duration;
+
+    return VLC_SUCCESS;
+}
+
+static int MP4_TrackUpdateELST( mp4_track_t *tk, uint32_t i_movie_timescale,
+                                stime_t i_track_time, uint32_t i_track_sample )
+{
+    if( !tk->p_elst || tk->BOXDATA(p_elst)->i_entry_count == 0 )
+        return VLC_SUCCESS;
+
+    if( i_track_sample >= tk->i_sample_count )
+        return MP4_TrackSetNextELST( tk );
+
+    vlc_tick_t i_time = MP4_rescale_mtime( i_track_time, tk->i_timescale );
+    for(;;)
+    {
+        const MP4_Box_data_elst_entry_t *edit = &tk->BOXDATA(p_elst)->entries[tk->i_elst];
+        vlc_tick_t i_end = MP4_rescale_mtime( edit->i_media_time, tk->i_timescale ) +
+                           MP4_rescale_mtime( edit->i_segment_duration, i_movie_timescale );
+        if ( i_time < i_end || MP4_TrackSetNextELST( tk ) )
+            break;
     }
 
-    p_track->i_sample += i_samples;
+    return VLC_SUCCESS;
+}
 
-    if( p_track->i_sample >= p_track->i_sample_count )
-        return VLC_EGENERIC;
+static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_samples )
+{
+    demux_sys_t *p_sys = p_demux->p_sys;
 
-    /* Have we changed chunk ? */
-    if( p_track->i_sample >=
-            p_track->chunk[p_track->i_chunk].i_sample_first +
-            p_track->chunk[p_track->i_chunk].i_sample_count )
+    if ( UINT32_MAX - p_track->i_sample < i_samples )
+        i_samples = UINT32_MAX - p_track->i_sample; /* Ensure we won't overflow next add */
+
+    p_track->i_sample += i_samples;
+    const uint32_t i_previous_chunk = p_track->i_chunk;
+
+    if( p_track->i_sample < p_track->i_sample_count )
     {
-        if( TrackGotoChunkSample( p_demux, p_track, p_track->i_chunk + 1,
-                                  p_track->i_sample ) )
+        /* Have we changed chunk ? */
+        while( p_track->i_sample >=
+               p_track->chunk[p_track->i_chunk].i_sample_first +
+               p_track->chunk[p_track->i_chunk].i_sample_count &&
+               p_track->i_chunk < p_track->i_chunk_count - 1 )
         {
-            msg_Warn( p_demux, "track[0x%x] will be disabled "
-                      "(cannot restart decoder)", p_track->i_track_ID );
-            MP4_TrackSelect( p_demux, p_track, false );
-            return VLC_EGENERIC;
+            p_track->i_chunk++;
+        }
+    }
+
+    if( p_track->p_elst ) /* Update */
+    {
+        uint32_t i_prev_elst = p_track->i_elst;
+        TrackUpdateSampleAndTimes( p_track );
+        MP4_TrackUpdateELST( p_track, p_sys->i_timescale, p_track->i_next_dts, p_track->i_sample);
+        if( p_track->i_elst != i_prev_elst )
+        {
+            msg_Dbg( p_demux, "changed elst %u -> %u", i_prev_elst, p_track->i_elst);
+            /* *** find good chunk *** */
+            uint32_t i_sample, i_chunk;
+            stime_t i_start = p_track->BOXDATA(p_elst)->entries[p_track->i_elst].i_media_time;
+            if( STTSToSampleChunk( p_track, i_start, &i_chunk, &i_sample ) != VLC_SUCCESS )
+            {
+                msg_Warn( p_demux, "track[Id 0x%x] will be disabled "
+                          "(seeking too far) chunk=%"PRIu32" sample=%"PRIu32,
+                          p_track->i_track_ID, i_chunk, i_sample );
+                return VLC_EGENERIC;
+            }
+            p_track->i_chunk = i_chunk;
+            p_track->i_sample = i_sample;
         }
     }
 
     TrackUpdateSampleAndTimes( p_track );
 
-    /* Have we changed elst */
-    if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count > 0 )
+    if( TrackUpdateFormat( p_demux, p_track, i_previous_chunk ) != VLC_SUCCESS )
     {
-        demux_sys_t *p_sys = p_demux->p_sys;
-        MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
-        uint64_t i_mvt = MP4_rescale_qtime( MP4_TrackGetDTSPTS( p_demux, p_track, NULL ),
-                                            p_sys->i_timescale );
-        if( p_track->i_elst < elst->i_entry_count &&
-            i_mvt >= p_track->i_elst_time +
-                     elst->i_segment_duration[p_track->i_elst] )
-        {
-            MP4_TrackSetELST( p_demux, p_track,
-                              MP4_TrackGetDTSPTS( p_demux, p_track, NULL ) );
-        }
+        msg_Warn( p_demux, "track[0x%x] will be disabled "
+                  "(cannot restart decoder)", p_track->i_track_ID );
+        MP4_TrackSelect( p_demux, p_track, false );
+        return VLC_EGENERIC;
     }
 
+    if( !p_track->b_selected || p_track->i_sample >= p_track->i_sample_count )
+        return VLC_EGENERIC;
+
     return VLC_SUCCESS;
 }
 
@@ -4260,10 +4334,11 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
 
         for( tk->i_elst = 0; tk->i_elst < elst->i_entry_count; tk->i_elst++ )
         {
-            uint64_t i_dur = elst->i_segment_duration[tk->i_elst];
+            uint64_t i_dur = elst->entries[tk->i_elst].i_segment_duration;
 
-            if( tk->i_elst_time <= i_mvt
-             && i_mvt < (int64_t)(tk->i_elst_time + i_dur) )
+            if( elst->entries[tk->i_elst].i_media_time >=0 &&
+                tk->i_elst_time <= i_mvt &&
+                i_mvt < (int64_t)(tk->i_elst_time + i_dur) )
             {
                 break;
             }
@@ -4274,20 +4349,14 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
         {
             /* msg_Dbg( p_demux, "invalid number of entry in elst" ); */
             tk->i_elst = elst->i_entry_count - 1;
-            tk->i_elst_time -= elst->i_segment_duration[tk->i_elst];
-        }
-
-        if( elst->i_media_time[tk->i_elst] < 0 )
-        {
-            /* track offset */
-            tk->i_elst_time += elst->i_segment_duration[tk->i_elst];
+            tk->i_elst_time -= elst->entries[tk->i_elst].i_segment_duration;
         }
 
         if( i_elst_last != tk->i_elst )
         {
             msg_Warn( p_demux, "elst old=%d new=%"PRIu32, i_elst_last, tk->i_elst );
             if( i_elst_last < elst->i_entry_count &&
-                elst->i_media_time[i_elst_last] >= 0 )
+                elst->entries[i_elst_last].i_media_time >= 0 )
                 tk->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
         }
     }


=====================================
src/input/input.c
=====================================
@@ -2707,7 +2707,7 @@ static int InputSourceInit( input_source_t *in, input_thread_t *p_input,
     if( in->p_demux == NULL )
     {
         if( !b_in_can_fail && !input_Stopped( p_input ) )
-            vlc_dialog_display_error( p_input, _("Your input can't be opened"),
+            vlc_dialog_display_error( p_input, _("Your media can't be opened"),
                                       _("VLC is unable to open the MRL '%s'."
                                       " Check the log for details."), psz_mrl );
         if( in->p_slave_es_out )



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/199de0535b7e53a90ba087a2918746df88e3d72d...f7bb59d9f51cc10b25ff86d34a3eff744e60c46e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/199de0535b7e53a90ba087a2918746df88e3d72d...f7bb59d9f51cc10b25ff86d34a3eff744e60c46e
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list