[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