[vlc-commits] mux: mp4: compute duration incrementally (fix #11558)
Francois Cartegnie
git at videolan.org
Wed Jun 11 19:12:21 CEST 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Jun 9 16:31:37 2014 +0200| [d697973a47d3bf5bb3ee6bdd39be1c72b5661e90] | committer: Francois Cartegnie
mux: mp4: compute duration incrementally (fix #11558)
and use discontinuities as boundaries
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d697973a47d3bf5bb3ee6bdd39be1c72b5661e90
---
modules/mux/mp4.c | 54 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 23 deletions(-)
diff --git a/modules/mux/mp4.c b/modules/mux/mp4.c
index 370ce91..0f7444f 100644
--- a/modules/mux/mp4.c
+++ b/modules/mux/mp4.c
@@ -108,8 +108,9 @@ typedef struct
int64_t i_length_neg;
/* stats */
- int64_t i_dts_start;
+ int64_t i_dts_start; /* applies to current segment only */
int64_t i_duration;
+ mtime_t i_starttime; /* the really first packet */
bool b_hasbframes;
/* for later stco fix-up (fast start files) */
@@ -117,7 +118,7 @@ typedef struct
bool b_stco64;
/* for spu */
- int64_t i_last_dts;
+ int64_t i_last_dts; /* applies to current segment only */
} mp4_stream_t;
@@ -130,8 +131,7 @@ struct sout_mux_sys_t
uint64_t i_mdat_pos;
uint64_t i_pos;
-
- int64_t i_dts_start;
+ mtime_t i_duration;
int i_nb_streams;
mp4_stream_t **pp_streams;
@@ -194,8 +194,7 @@ static int Open(vlc_object_t *p_this)
p_sys->i_mdat_pos = 0;
p_sys->b_mov = p_mux->psz_mux && !strcmp(p_mux->psz_mux, "mov");
p_sys->b_3gp = p_mux->psz_mux && !strcmp(p_mux->psz_mux, "3gp");
- p_sys->i_dts_start = 0;
-
+ p_sys->i_duration = 0;
if (!p_sys->b_mov) {
/* Now add ftyp header */
@@ -414,8 +413,11 @@ static int AddStream(sout_mux_t *p_mux, sout_input_t *p_input)
calloc(p_stream->i_entry_max, sizeof(mp4_entry_t));
p_stream->i_dts_start = 0;
p_stream->i_duration = 0;
+ p_stream->i_starttime = p_sys->i_duration;
p_stream->b_hasbframes = false;
+ p_stream->i_last_dts = 0;
+
p_input->p_sys = p_stream;
msg_Dbg(p_mux, "adding input");
@@ -459,12 +461,19 @@ static int Mux(sout_mux_t *p_mux)
p_data = ConvertSUBT(p_data);
} while (!p_data);
+ /* Reset reference dts in case of discontinuity (ex: gather sout) */
+ if ( p_stream->i_entry_count == 0 || p_data->i_flags & BLOCK_FLAG_DISCONTINUITY )
+ {
+ p_stream->i_dts_start = p_data->i_dts;
+ p_stream->i_last_dts = p_data->i_dts;
+ p_stream->i_length_neg = 0;
+ }
+
if (p_stream->fmt.i_cat != SPU_ES) {
/* Fix length of the sample */
if (block_FifoCount(p_input->p_fifo) > 0) {
block_t *p_next = block_FifoShow(p_input->p_fifo);
int64_t i_diff = p_next->i_dts - p_data->i_dts;
-
if (i_diff < CLOCK_FREQ) /* protection */
p_data->i_length = i_diff;
}
@@ -480,15 +489,6 @@ static int Mux(sout_mux_t *p_mux)
}
}
- /* Save starting time */
- if (p_stream->i_entry_count == 0) {
- p_stream->i_dts_start = p_data->i_dts;
-
- /* Update global dts_start */
- if (p_sys->i_dts_start <= 0 || p_stream->i_dts_start < p_sys->i_dts_start)
- p_sys->i_dts_start = p_stream->i_dts_start;
- }
-
if (p_stream->fmt.i_cat == SPU_ES && p_stream->i_entry_count > 0) {
int64_t i_length = p_data->i_dts - p_stream->i_last_dts;
@@ -525,15 +525,16 @@ static int Mux(sout_mux_t *p_mux)
}
/* update */
- p_stream->i_duration = p_stream->i_last_dts - p_stream->i_dts_start + p_data->i_length;
+ p_stream->i_duration += __MAX( 0, p_data->i_length );
p_sys->i_pos += p_data->i_buffer;
- /* Save the DTS */
+ /* Save the DTS for SPU */
p_stream->i_last_dts = p_data->i_dts;
/* write data */
sout_AccessOutWrite(p_mux->p_access, p_data);
+ /* close subtitle with empty frame */
if (p_stream->fmt.i_cat == SPU_ES) {
int64_t i_length = p_stream->entry[p_stream->i_entry_count-1].i_length;
@@ -567,11 +568,18 @@ static int Mux(sout_mux_t *p_mux)
sout_AccessOutWrite(p_mux->p_access, p_data);
}
- /* Fix duration */
- p_stream->i_duration = p_stream->i_last_dts - p_stream->i_dts_start;
+ /* Fix duration = current segment starttime + duration within */
+ p_stream->i_duration = p_stream->i_starttime + ( p_stream->i_last_dts - p_stream->i_dts_start );
}
}
+ /* Update the global segment/media duration */
+ for ( int i=0; i<p_sys->i_nb_streams; i++ )
+ {
+ if ( p_sys->pp_streams[i]->i_duration > p_sys->i_duration )
+ p_sys->i_duration = p_sys->pp_streams[i]->i_duration;
+ }
+
return(VLC_SUCCESS);
}
@@ -1657,15 +1665,15 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
/* *** add /moov/trak/edts and elst */
bo_t *edts = box_new("edts");
bo_t *elst = box_full_new("elst", p_sys->b_64_ext ? 1 : 0, 0);
- if (p_stream->i_dts_start > p_sys->i_dts_start) {
+ if (p_stream->i_starttime > 0) {
bo_add_32be(elst, 2);
if (p_sys->b_64_ext) {
- bo_add_64be(elst, (p_stream->i_dts_start-p_sys->i_dts_start) *
+ bo_add_64be(elst, p_stream->i_starttime *
i_movie_timescale / CLOCK_FREQ);
bo_add_64be(elst, -1);
} else {
- bo_add_32be(elst, (p_stream->i_dts_start-p_sys->i_dts_start) *
+ bo_add_32be(elst, p_stream->i_starttime *
i_movie_timescale / CLOCK_FREQ);
bo_add_32be(elst, -1);
}
More information about the vlc-commits
mailing list