vlc | branch: master | Francois Cartegnie <[email protected]> | 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); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
