[vlc-commits] [Git][videolan/vlc][master] 5 commits: demux: mp4: search lowest bframe pts in next chunks as well

François Cartegnie (@fcartegnie) gitlab at videolan.org
Tue Mar 28 16:48:05 UTC 2023



François Cartegnie pushed to branch master at VideoLAN / VLC


Commits:
813f8e1c by Francois Cartegnie at 2023-03-28T16:26:46+00:00
demux: mp4: search lowest bframe pts in next chunks as well

- - - - -
1bedf263 by Francois Cartegnie at 2023-03-28T16:26:46+00:00
demux: mp4: constify

- - - - -
96325dda by Francois Cartegnie at 2023-03-28T16:26:46+00:00
demux: mp4: cache pointer var and disambiguate

- - - - -
c3821c5e by Francois Cartegnie at 2023-03-28T16:26:46+00:00
demux: mp4: zero timescale is rejected in open

- - - - -
2f7f5f32 by Francois Cartegnie at 2023-03-28T16:26:46+00:00
demux: mp4: store max pts shift to offset other tracks

- - - - -


2 changed files:

- modules/demux/mp4/mp4.c
- modules/demux/mp4/mp4.h


Changes:

=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -110,6 +110,7 @@ typedef struct
     uint64_t     i_cumulated_duration; /* Same as above, but not from probing, (movie time scale) */
     uint32_t     i_timescale;          /* movie time scale */
     vlc_tick_t   i_nztime;             /* time position of the presentation (CLOCK_FREQ timescale) */
+    vlc_tick_t   i_max_pts_offset;
     unsigned int i_tracks;       /* number of tracks */
     mp4_track_t  *track;         /* array of track */
     float        f_fps;          /* number of frame per seconds */
@@ -167,7 +168,7 @@ typedef struct
 /*****************************************************************************
  * Declaration of local function
  *****************************************************************************/
-static void MP4_TrackSetup( demux_t *, mp4_track_t *, MP4_Box_t  *, bool, bool );
+static void MP4_TrackSetup( demux_t *, mp4_track_t *, const MP4_Box_t  *, bool, bool );
 static void MP4_TrackInit( mp4_track_t *, const MP4_Box_t * );
 static void MP4_TrackClean( es_out_t *, mp4_track_t * );
 
@@ -485,20 +486,6 @@ static void MP4_ChunkDestroy( mp4_chunk_t *ck )
         free( ck->p_sample_count_pts );
 }
 
-static const mp4_chunk_t * MP4_TrackChunkForSample( const mp4_track_t *p_track,
-                                                    uint32_t i_sample )
-{
-    if( i_sample >= p_track->i_sample_count )
-        return NULL;
-    for( uint32_t i=0; i<p_track->i_chunk_count; i++ )
-    {
-        if( i_sample >= p_track->chunk[i].i_sample_first &&
-            i_sample - p_track->chunk[i].i_sample_first < p_track->chunk[i].i_sample_count )
-            return &p_track->chunk[i];
-    }
-    return NULL;
-}
-
 static stime_t MP4_MapTrackTimeIntoTimeline( const mp4_track_t *p_track,
                                              uint32_t i_movie_timescale,
                                              stime_t i_time )
@@ -611,6 +598,13 @@ static vlc_tick_t MP4_TrackGetDTSPTS( demux_t *p_demux, const mp4_track_t *p_tra
         else *pi_nzpts = i_dts;
     }
 
+    if( p_track->i_pts_offset )
+    {
+        if( pi_nzpts && *pi_nzpts != INVALID_PTS )
+            *pi_nzpts += p_track->i_pts_offset;
+        i_dts += p_track->i_pts_offset;
+    }
+
     return i_dts;
 }
 
@@ -1272,13 +1266,14 @@ static int Open( vlc_object_t * p_this )
     /* now process each track and extract all useful information */
     for( unsigned i = 0; i < p_sys->i_tracks; i++ )
     {
-        MP4_Box_t *p_trak = MP4_BoxGet( p_sys->p_root, "/moov/trak[%u]", i );
-        MP4_TrackSetup( p_demux, &p_sys->track[i], p_trak, true, !b_enabled_es );
+        const MP4_Box_t *p_trakbox = MP4_BoxGet( p_sys->p_root, "/moov/trak[%u]", i );
+        MP4_TrackSetup( p_demux, &p_sys->track[i], p_trakbox, true, !b_enabled_es );
+        mp4_track_t *p_track = &p_sys->track[i];
 
-        if( p_sys->track[i].b_ok && ! MP4_isMetadata(&p_sys->track[i]) )
+        if( p_track->b_ok && ! MP4_isMetadata(p_track) )
         {
             const char *psz_cat;
-            switch( p_sys->track[i].fmt.i_cat )
+            switch( p_track->fmt.i_cat )
             {
                 case( VIDEO_ES ):
                     psz_cat = "video";
@@ -1296,25 +1291,41 @@ static int Open( vlc_object_t * p_this )
             }
 
             msg_Dbg( p_demux, "adding track[Id 0x%x] %s (%s) language %s",
-                     p_sys->track[i].i_track_ID, psz_cat,
-                     p_sys->track[i].b_enable ? "enable":"disable",
-                     p_sys->track[i].fmt.psz_language ?
-                     p_sys->track[i].fmt.psz_language : "undef" );
+                     p_track->i_track_ID, psz_cat,
+                     p_track->b_enable ? "enable":"disable",
+                     p_track->fmt.psz_language ?
+                     p_track->fmt.psz_language : "undef" );
         }
-        else if( p_sys->track[i].b_ok && (p_sys->track[i].i_use_flags & USEAS_CHAPTERS) )
+        else if( p_track->b_ok && (p_track->i_use_flags & USEAS_CHAPTERS) )
         {
             msg_Dbg( p_demux, "using track[Id 0x%x] for chapter language %s",
-                     p_sys->track[i].i_track_ID,
-                     p_sys->track[i].fmt.psz_language ?
-                     p_sys->track[i].fmt.psz_language : "undef" );
+                     p_track->i_track_ID,
+                     p_track->fmt.psz_language ?
+                     p_track->fmt.psz_language : "undef" );
         }
         else
         {
             msg_Dbg( p_demux, "ignoring track[Id 0x%x] %d refs %x",
-                     p_sys->track[i].i_track_ID, p_sys->track[i].b_ok, p_sys->track[i].i_use_flags );
+                     p_track->i_track_ID, p_track->b_ok, p_track->i_use_flags );
+        }
+
+        if( p_track->b_ok && p_track->i_cts_shift ) /* PTS shift handling pass 1 */
+        {
+            p_track->i_pts_offset = MP4_rescale_mtime( p_track->i_cts_shift,
+                                                       p_track->i_timescale );
+            if( p_track->i_pts_offset > p_sys->i_max_pts_offset )
+                p_sys->i_max_pts_offset = p_track->i_pts_offset;
         }
     }
 
+    for( unsigned i = 0; i < p_sys->i_tracks; i++ ) /* PTS shift handling pass 2 */
+    {
+        mp4_track_t *p_track = &p_sys->track[i];
+        if( !p_track->b_ok )
+            continue;
+        p_track->i_pts_offset = p_sys->i_max_pts_offset - p_track->i_pts_offset;
+    }
+
     p_mvex = MP4_BoxGet( p_sys->p_moov, "mvex" );
     if( p_mvex != NULL )
     {
@@ -2229,7 +2240,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             else return VLC_EGENERIC;
 
         case DEMUX_GET_TIME:
-            *va_arg( args, vlc_tick_t * ) = p_sys->i_timescale > 0 ? p_sys->i_nztime : 0;
+            *va_arg( args, vlc_tick_t * ) = (p_sys->i_max_pts_offset < p_sys->i_nztime)
+                                          ? p_sys->i_nztime - p_sys->i_max_pts_offset : 0;
             return VLC_SUCCESS;
 
         case DEMUX_SET_TIME:
@@ -2902,6 +2914,7 @@ static int TrackCreateSamplesIndex( demux_t *p_demux,
                     i_cts_shift = -ctts->pi_sample_offset[i];
             }
         }
+        p_demux_track->i_cts_shift = i_cts_shift;
 
         /* Create pts-dts table per chunk */
         uint32_t i_index = 0;
@@ -3519,28 +3532,38 @@ static void TrackUpdateStarttimes( mp4_track_t *p_track )
     p_track->i_start_delta = p_track->i_next_delta;
 
     /* Probe the 16 first B frames */
-    const mp4_chunk_t *p_chunk = &p_track->chunk[p_track->i_chunk];
-    if( p_chunk->i_entries_pts )
+    uint32_t i_chunk = p_track->i_chunk;
+    if( !p_track->chunk[i_chunk].i_entries_pts )
+        return;
+
+    stime_t lowest = p_track->i_start_dts;
+    if( p_track->i_start_delta != UNKNOWN_DELTA )
+        lowest += p_track->i_start_delta;
+
+    for( uint32_t i=1; i<16; i++ )
     {
-        for( uint32_t i=1; i<16; i++ )
+        uint32_t i_nextsample = p_track->i_sample + i;
+        if( i_nextsample >= p_track->i_sample_count )
+            break;
+        const mp4_chunk_t *ck = NULL;
+        for( ; i_chunk < p_track->i_chunk_count; i_chunk++ )
         {
-            uint32_t i_nextsample = p_track->i_sample + i;
-            const mp4_chunk_t *ck = MP4_TrackChunkForSample( p_track, i_nextsample );
-            if(!ck)
+            ck = &p_track->chunk[i_chunk];
+            if( i_nextsample < ck->i_sample_first + ck->i_sample_count )
                 break;
-            stime_t pts;
-            stime_t dts = pts = MP4_ChunkGetSampleDTS( ck, i_nextsample - ck->i_sample_first );
-            stime_t delta = UNKNOWN_DELTA;
-            if( MP4_ChunkGetSampleCTSDelta( ck, i_nextsample - ck->i_sample_first, &delta ) )
-                pts += delta;
-            stime_t lowest = p_track->i_start_dts;
-            if( p_track->i_start_delta != UNKNOWN_DELTA )
-                lowest += p_track->i_start_delta;
-            if( pts < lowest )
-            {
-                p_track->i_start_dts = dts;
-                p_track->i_start_delta = delta;
-            }
+        }
+        if( !ck )
+            break;
+        assert(i_nextsample >= ck->i_sample_first);
+        stime_t pts;
+        stime_t dts = pts = MP4_ChunkGetSampleDTS( ck, i_nextsample - ck->i_sample_first );
+        stime_t delta = UNKNOWN_DELTA;
+        if( MP4_ChunkGetSampleCTSDelta( ck, i_nextsample - ck->i_sample_first, &delta ) )
+            pts += delta;
+        if( pts < lowest )
+        {
+            p_track->i_start_dts = dts;
+            p_track->i_start_delta = delta;
         }
     }
 }
@@ -3566,7 +3589,7 @@ static void TrackUpdateSampleAndTimes( mp4_track_t *p_track )
  * If it succeed b_ok is set to 1 else to 0
  ****************************************************************************/
 static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
-                             MP4_Box_t *p_box_trak,
+                             const MP4_Box_t *p_box_trak,
                              bool b_create_es, bool b_force_enable )
 {
     demux_sys_t *p_sys = p_demux->p_sys;


=====================================
modules/demux/mp4/mp4.h
=====================================
@@ -135,6 +135,8 @@ typedef struct
     uint32_t         i_next_delta;
     stime_t          i_start_dts;
     stime_t          i_next_dts;
+    int64_t          i_cts_shift;
+    vlc_tick_t       i_pts_offset;
     /* give the next sample to read, i_chunk is to find quickly where
       the sample is located */
     uint32_t         i_sample;       /* next sample to read */



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8ef1866ab184d5007b78e537d732553f0bf8c483...2f7f5f32ad91eaecdc68d836be1e94ad2112f8c0

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