[vlc-commits] demux: mp4: unify getting sample timings
Francois Cartegnie
git at videolan.org
Tue Feb 9 19:41:56 UTC 2021
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Feb 9 10:45:48 2021 +0100| [7acbebf3eca9b01eeb5b5cdd200ed0771fc3f947] | committer: Francois Cartegnie
demux: mp4: unify getting sample timings
and avoid negative offsets
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7acbebf3eca9b01eeb5b5cdd200ed0771fc3f947
---
modules/demux/mp4/mp4.c | 104 +++++++++++++++++++++++-------------------------
1 file changed, 50 insertions(+), 54 deletions(-)
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index 78b8b47b7a..fe739f0893 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -155,6 +155,7 @@ typedef struct
#define INVALID_PRELOAD UINT_MAX
#define UNKNOWN_DELTA UINT32_MAX
+#define INVALID_PTS INT64_MIN
#define VLC_DEMUXER_EOS (VLC_DEMUXER_EGENERIC - 1)
#define VLC_DEMUXER_FATAL (VLC_DEMUXER_EGENERIC - 2)
@@ -398,49 +399,49 @@ static bool MP4_ChunkGetSampleCTSDelta( const mp4_chunk_t *p_chunk,
return false;
}
-static void MP4_TrackTimeApplyELST( const mp4_track_t *p_track,
- stime_t *pi_dts )
+static vlc_tick_t MP4_TrackGetDTSPTS( demux_t *p_demux, const mp4_track_t *p_track,
+ vlc_tick_t *pi_nzpts )
{
- if( !p_track->p_elst || !p_track->BOXDATA(p_elst)->i_entry_count )
- return;
+ demux_sys_t *p_sys = p_demux->p_sys;
- const MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
+ stime_t sdts = p_track->i_next_dts;
+ uint32_t delta = p_track->i_next_delta;
- /* 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 ) )
+ /* now handle elst */
+ if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count )
{
- *pi_dts -= elst->i_media_time[p_track->i_elst];
+ 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];
+ }
+ }
}
+ vlc_tick_t i_dts = MP4_rescale_mtime( sdts, p_track->i_timescale);
/* add i_elst_time */
- *pi_dts += p_track->i_elst_time;
-
- if( *pi_dts < 0 ) *pi_dts = 0;
-}
+ i_dts += MP4_rescale_mtime( p_track->i_elst_time, p_sys->i_timescale );
-/* Return time in microsecond of a track */
-static inline vlc_tick_t MP4_TrackGetDTS( demux_t *p_demux, mp4_track_t *p_track )
-{
- VLC_UNUSED(p_demux);
- stime_t sdts = p_track->i_next_dts;
-
- /* now handle elst */
- MP4_TrackTimeApplyELST( p_track, &sdts );
+ if( pi_nzpts )
+ {
+ if( delta != UNKNOWN_DELTA )
+ {
+ *pi_nzpts = i_dts + MP4_rescale_mtime( delta, p_track->i_timescale );
+ }
+ else if( p_track->fmt.i_cat == VIDEO_ES )
+ {
+ *pi_nzpts = INVALID_PTS;
+ }
+ else *pi_nzpts = i_dts;
+ }
- return MP4_rescale_mtime( sdts, p_track->i_timescale );
-}
-
-static inline bool MP4_TrackGetPTSDelta( demux_t *p_demux, const mp4_track_t *p_track,
- vlc_tick_t *pi_delta )
-{
- VLC_UNUSED( p_demux );
- uint32_t delta = p_track->i_next_delta;
- if( delta == UNKNOWN_DELTA )
- return false;
- *pi_delta = MP4_rescale_mtime( delta, p_track->i_timescale );
- return true;
+ return i_dts;
}
static inline vlc_tick_t MP4_GetSamplesDuration( demux_t *p_demux, mp4_track_t *p_track,
@@ -1398,7 +1399,8 @@ static int DemuxTrack( demux_t *p_demux, mp4_track_t *tk, uint64_t i_readpos,
return VLC_DEMUXER_SUCCESS;
uint32_t i_run_seq = MP4_TrackGetRunSeq( tk );
- vlc_tick_t i_current_nzdts = MP4_TrackGetDTS( p_demux, tk );
+ vlc_tick_t i_current_nzpts;
+ vlc_tick_t i_current_nzdts = MP4_TrackGetDTSPTS( p_demux, tk, &i_current_nzpts );
const vlc_tick_t i_demux_max_nzdts =i_max_preload < INVALID_PRELOAD
? i_current_nzdts + i_max_preload
: INT64_MAX;
@@ -1418,7 +1420,6 @@ static int DemuxTrack( demux_t *p_demux, mp4_track_t *tk, uint64_t i_readpos,
if( i_samplessize > 0 )
{
block_t *p_block;
- vlc_tick_t i_delta;
if( vlc_stream_Tell( p_demux->s ) != i_readpos )
{
@@ -1454,12 +1455,9 @@ static int DemuxTrack( demux_t *p_demux, mp4_track_t *tk, uint64_t i_readpos,
/* dts */
p_block->i_dts = VLC_TICK_0 + i_current_nzdts;
/* pts */
- if( MP4_TrackGetPTSDelta( p_demux, tk, &i_delta ) )
- p_block->i_pts = p_block->i_dts + i_delta;
- else if( tk->fmt.i_cat != VIDEO_ES )
- p_block->i_pts = p_block->i_dts;
- else
- p_block->i_pts = VLC_TICK_INVALID;
+ p_block->i_pts = i_current_nzpts != INVALID_PTS
+ ? VLC_TICK_0 + i_current_nzpts
+ : VLC_TICK_INVALID;
p_block->i_length = MP4_GetSamplesDuration( p_demux, tk, i_nb_samples );
@@ -1475,7 +1473,7 @@ static int DemuxTrack( demux_t *p_demux, mp4_track_t *tk, uint64_t i_readpos,
if( i_next_run_seq != i_run_seq )
break;
- i_current_nzdts = MP4_TrackGetDTS( p_demux, tk );
+ i_current_nzdts = MP4_TrackGetDTSPTS( p_demux, tk, &i_current_nzpts );
i_readpos = MP4_TrackGetPos( tk );
}
@@ -1527,7 +1525,7 @@ static int DemuxMoov( demux_t *p_demux )
if( !tk->b_ok || MP4_isMetadata( tk ) || tk->i_sample >= tk->i_sample_count )
continue;
/* Test for EOF on each track (samples count, edit list) */
- b_eof &= ( i_nztime > MP4_TrackGetDTS( p_demux, tk ) );
+ b_eof &= ( i_nztime > MP4_TrackGetDTSPTS( p_demux, tk, NULL ) );
}
if( b_eof )
return VLC_DEMUXER_EOS;
@@ -1553,7 +1551,7 @@ static int DemuxMoov( demux_t *p_demux )
/* At least still have data to demux on this or next turns */
i_status = VLC_DEMUXER_SUCCESS;
- if ( MP4_TrackGetDTS( p_demux, tk_tmp ) <= i_nztime + DEMUX_INCREMENT )
+ if ( MP4_TrackGetDTSPTS( p_demux, tk_tmp, NULL ) <= i_nztime + DEMUX_INCREMENT )
{
if( tk == NULL || MP4_TrackGetPos( tk_tmp ) < MP4_TrackGetPos( tk ) )
tk = tk_tmp;
@@ -1574,7 +1572,7 @@ static int DemuxMoov( demux_t *p_demux )
tk_tmp->i_sample >= tk_tmp->i_sample_count )
continue;
- vlc_tick_t i_nzdts = MP4_TrackGetDTS( p_demux, tk_tmp );
+ vlc_tick_t i_nzdts = MP4_TrackGetDTSPTS( p_demux, tk_tmp, NULL );
if ( i_nzdts <= i_nztime + DEMUX_TRACK_MAX_PRELOAD )
{
/* Found a better candidate to avoid seeking */
@@ -1660,7 +1658,7 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, bool b_accurate )
continue;
if( MP4_TrackSeek( p_demux, tk, i_date ) == VLC_SUCCESS )
{
- vlc_tick_t i_seeked = MP4_TrackGetDTS( p_demux, tk );
+ vlc_tick_t i_seeked = MP4_TrackGetDTSPTS( p_demux, tk, NULL );
if( i_seeked < i_start )
i_start = i_seeked;
}
@@ -2281,10 +2279,8 @@ static void LoadChapterApple( demux_t *p_demux, mp4_track_t *tk )
for( tk->i_sample = 0; tk->i_sample < tk->i_sample_count; tk->i_sample++ )
{
- const vlc_tick_t i_dts = MP4_TrackGetDTS( p_demux, tk );
- vlc_tick_t i_pts_delta;
- if ( !MP4_TrackGetPTSDelta( p_demux, tk, &i_pts_delta ) )
- i_pts_delta = 0;
+ vlc_tick_t i_pts;
+ MP4_TrackGetDTSPTS( p_demux, tk, &i_pts );
uint32_t i_nb_samples = 0;
const uint32_t i_size = MP4_TrackGetReadSize( tk, &i_nb_samples );
@@ -2313,7 +2309,7 @@ static void LoadChapterApple( demux_t *p_demux, mp4_track_t *tk )
}
EnsureUTF8( s->psz_name );
- s->i_time_offset = i_dts + __MAX( i_pts_delta, 0 );
+ s->i_time_offset = i_pts;
if( !p_sys->p_title )
p_sys->p_title = vlc_input_title_New();
@@ -4084,14 +4080,14 @@ static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track, uint32_t
{
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_TrackGetDTS( p_demux, p_track ),
+ 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_TrackGetDTS( p_demux, p_track ) );
+ MP4_TrackGetDTSPTS( p_demux, p_track, NULL ) );
}
}
More information about the vlc-commits
mailing list