[vlc-commits] mux: mp4: split stream muxing

Francois Cartegnie git at videolan.org
Mon Jan 8 12:10:56 CET 2018


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jan  5 11:43:11 2018 +0100| [da89718506869106733970b15239d985a23f6b5c] | committer: Francois Cartegnie

mux: mp4: split stream muxing

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=da89718506869106733970b15239d985a23f6b5c
---

 modules/mux/mp4/mp4.c | 297 ++++++++++++++++++++++++++------------------------
 1 file changed, 155 insertions(+), 142 deletions(-)

diff --git a/modules/mux/mp4/mp4.c b/modules/mux/mp4/mp4.c
index eb1c659baf..6dc41da696 100644
--- a/modules/mux/mp4/mp4.c
+++ b/modules/mux/mp4/mp4.c
@@ -583,111 +583,105 @@ static inline mtime_t dts_fb_pts( const block_t *p_data )
     return p_data->i_dts > VLC_TS_INVALID ? p_data->i_dts: p_data->i_pts;
 }
 
-static int Mux(sout_mux_t *p_mux)
+static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_stream)
 {
     sout_mux_sys_t *p_sys = p_mux->p_sys;
 
-    for (;;) {
-        int i_stream = sout_MuxGetStream(p_mux, 2, NULL);
-        if (i_stream < 0)
-            return(VLC_SUCCESS);
-
-        sout_input_t *p_input  = p_mux->pp_inputs[i_stream];
-        mp4_stream_t *p_stream = (mp4_stream_t*)p_input->p_sys;
-
-        block_t *p_data = BlockDequeue(p_input, p_stream);
-        if(!p_data)
-            return VLC_SUCCESS;
+    block_t *p_data = BlockDequeue(p_input, p_stream);
+    if(!p_data)
+        return VLC_SUCCESS;
 
-        /* Reset reference dts in case of discontinuity (ex: gather sout) */
-        if (p_data->i_flags & BLOCK_FLAG_DISCONTINUITY && p_stream->mux.i_entry_count)
+    /* Reset reference dts in case of discontinuity (ex: gather sout) */
+    if (p_data->i_flags & BLOCK_FLAG_DISCONTINUITY && p_stream->mux.i_entry_count)
+    {
+        if(p_stream->i_first_dts != VLC_TS_INVALID)
         {
-            if(p_stream->i_first_dts != VLC_TS_INVALID)
+            if(!CreateCurrentEdit(p_stream, p_sys->i_start_dts, p_sys->b_fragmented))
             {
-                if(!CreateCurrentEdit(p_stream, p_sys->i_start_dts, p_sys->b_fragmented))
-                {
-                    block_Release( p_data );
-                    return VLC_ENOMEM;
-                }
+                block_Release( p_data );
+                return VLC_ENOMEM;
             }
-
-            p_stream->i_length_neg = 0;
-            p_stream->i_first_dts = VLC_TS_INVALID;
-            p_stream->i_last_dts = VLC_TS_INVALID;
-            p_stream->i_last_pts = VLC_TS_INVALID;
         }
 
-        /* XXX: -1 to always have 2 entry for easy adding of empty SPU */
-        if (p_stream->mux.i_entry_count >= p_stream->mux.i_entry_max - 2) {
-            p_stream->mux.i_entry_max += 1000;
-            p_stream->mux.entry = xrealloc(p_stream->mux.entry,
-                         p_stream->mux.i_entry_max * sizeof(mp4mux_entry_t));
-        }
+        p_stream->i_length_neg = 0;
+        p_stream->i_first_dts = VLC_TS_INVALID;
+        p_stream->i_last_dts = VLC_TS_INVALID;
+        p_stream->i_last_pts = VLC_TS_INVALID;
+    }
 
-        /* Set current segment ranges */
-        if( p_stream->i_first_dts == VLC_TS_INVALID )
-        {
-            p_stream->i_first_dts = dts_fb_pts( p_data );
-            if( p_sys->i_start_dts == VLC_TS_INVALID )
-                p_sys->i_start_dts = p_stream->i_first_dts;
-        }
+    /* XXX: -1 to always have 2 entry for easy adding of empty SPU */
+    if (p_stream->mux.i_entry_count >= p_stream->mux.i_entry_max - 2) {
+        p_stream->mux.i_entry_max += 1000;
+        p_stream->mux.entry = xrealloc(p_stream->mux.entry,
+                                       p_stream->mux.i_entry_max * sizeof(mp4mux_entry_t));
+    }
 
-        if (p_stream->mux.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);
-                if ( p_next->i_flags & BLOCK_FLAG_DISCONTINUITY )
-                { /* we have no way to know real length except by decoding */
-                    if ( p_stream->mux.fmt.i_cat == VIDEO_ES )
-                    {
-                        p_data->i_length = CLOCK_FREQ *
-                                           p_stream->mux.fmt.video.i_frame_rate_base /
-                                           p_stream->mux.fmt.video.i_frame_rate;
-                        if( p_data->i_flags & BLOCK_FLAG_SINGLE_FIELD )
-                            p_data->i_length >>= 1;
-                        msg_Dbg( p_mux, "video track %u fixup to %"PRId64" for sample %u",
-                                 p_stream->mux.i_track_id, p_data->i_length, p_stream->mux.i_entry_count );
-                    }
-                    else if ( p_stream->mux.fmt.i_cat == AUDIO_ES &&
-                              p_stream->mux.fmt.audio.i_rate &&
-                              p_data->i_nb_samples )
-                    {
-                        p_data->i_length = CLOCK_FREQ * p_data->i_nb_samples /
-                                           p_stream->mux.fmt.audio.i_rate;
-                        msg_Dbg( p_mux, "audio track %u fixup to %"PRId64" for sample %u",
-                                 p_stream->mux.i_track_id, p_data->i_length, p_stream->mux.i_entry_count );
-                    }
-                    else if ( p_data->i_length <= 0 )
-                    {
-                        msg_Warn( p_mux, "unknown length for track %u sample %u",
-                                  p_stream->mux.i_track_id, p_stream->mux.i_entry_count );
-                        p_data->i_length = 1;
-                    }
+    /* Set current segment ranges */
+    if( p_stream->i_first_dts == VLC_TS_INVALID )
+    {
+        p_stream->i_first_dts = dts_fb_pts( p_data );
+        if( p_sys->i_start_dts == VLC_TS_INVALID )
+            p_sys->i_start_dts = p_stream->i_first_dts;
+    }
+
+    if (p_stream->mux.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);
+            if ( p_next->i_flags & BLOCK_FLAG_DISCONTINUITY )
+            { /* we have no way to know real length except by decoding */
+                if ( p_stream->mux.fmt.i_cat == VIDEO_ES )
+                {
+                    p_data->i_length = CLOCK_FREQ *
+                            p_stream->mux.fmt.video.i_frame_rate_base /
+                            p_stream->mux.fmt.video.i_frame_rate;
+                    if( p_data->i_flags & BLOCK_FLAG_SINGLE_FIELD )
+                        p_data->i_length >>= 1;
+                    msg_Dbg( p_mux, "video track %u fixup to %"PRId64" for sample %u",
+                             p_stream->mux.i_track_id, p_data->i_length, p_stream->mux.i_entry_count );
                 }
-                else
+                else if ( p_stream->mux.fmt.i_cat == AUDIO_ES &&
+                          p_stream->mux.fmt.audio.i_rate &&
+                          p_data->i_nb_samples )
                 {
-                    int64_t i_diff  = dts_fb_pts( p_next ) - dts_fb_pts( p_data );
-                    if (i_diff < CLOCK_FREQ) /* protection */
-                        p_data->i_length = i_diff;
+                    p_data->i_length = CLOCK_FREQ * p_data->i_nb_samples /
+                            p_stream->mux.fmt.audio.i_rate;
+                    msg_Dbg( p_mux, "audio track %u fixup to %"PRId64" for sample %u",
+                             p_stream->mux.i_track_id, p_data->i_length, p_stream->mux.i_entry_count );
+                }
+                else if ( p_data->i_length <= 0 )
+                {
+                    msg_Warn( p_mux, "unknown length for track %u sample %u",
+                              p_stream->mux.i_track_id, p_stream->mux.i_entry_count );
+                    p_data->i_length = 1;
                 }
             }
-            if (p_data->i_length <= 0) {
-                msg_Warn(p_mux, "i_length <= 0");
-                p_stream->i_length_neg += p_data->i_length - 1;
-                p_data->i_length = 1;
-            } else if (p_stream->i_length_neg < 0) {
-                int64_t i_recover = __MIN(p_data->i_length / 4, - p_stream->i_length_neg);
-
-                p_data->i_length -= i_recover;
-                p_stream->i_length_neg += i_recover;
+            else
+            {
+                int64_t i_diff  = dts_fb_pts( p_next ) - dts_fb_pts( p_data );
+                if (i_diff < CLOCK_FREQ) /* protection */
+                    p_data->i_length = i_diff;
             }
         }
-
-        if (p_stream->mux.fmt.i_cat == SPU_ES &&
-            p_stream->mux.i_entry_count > 0 &&
+        if (p_data->i_length <= 0) {
+            msg_Warn(p_mux, "i_length <= 0");
+            p_stream->i_length_neg += p_data->i_length - 1;
+            p_data->i_length = 1;
+        } else if (p_stream->i_length_neg < 0) {
+            int64_t i_recover = __MIN(p_data->i_length / 4, - p_stream->i_length_neg);
+
+            p_data->i_length -= i_recover;
+            p_stream->i_length_neg += i_recover;
+        }
+    }
+    else /* SPU_ES */
+    {
+        if (p_stream->mux.i_entry_count > 0 &&
             p_stream->mux.entry[p_stream->mux.i_entry_count-1].i_length == 0)
         {
-             /* length of previous spu, stored in spu clearer */
+            /* length of previous spu, stored in spu clearer */
             int64_t i_length = dts_fb_pts( p_data ) - p_stream->i_last_dts;
             if(i_length < 0)
                 i_length = 0;
@@ -695,77 +689,96 @@ static int Mux(sout_mux_t *p_mux)
             p_stream->mux.entry[p_stream->mux.i_entry_count-1].i_length = i_length;
             p_stream->mux.i_read_duration += i_length;
         }
+    }
 
-        /* Update (Not earlier for SPU!) */
-        p_stream->i_last_dts = dts_fb_pts( p_data );
-        if( p_data->i_pts > p_stream->i_last_pts )
-            p_stream->i_last_pts = p_data->i_pts;
+    /* Update (Not earlier for SPU!) */
+    p_stream->i_last_dts = dts_fb_pts( p_data );
+    if( p_data->i_pts > p_stream->i_last_pts )
+        p_stream->i_last_pts = p_data->i_pts;
 
-        /* add index entry */
-        mp4mux_entry_t *e = &p_stream->mux.entry[p_stream->mux.i_entry_count++];
-        e->i_pos    = p_sys->i_pos;
-        e->i_size   = p_data->i_buffer;
+    /* add index entry */
+    mp4mux_entry_t *e = &p_stream->mux.entry[p_stream->mux.i_entry_count++];
+    e->i_pos    = p_sys->i_pos;
+    e->i_size   = p_data->i_buffer;
 
-        if ( p_data->i_dts > VLC_TS_INVALID && p_data->i_pts > p_data->i_dts )
-        {
-            e->i_pts_dts = p_data->i_pts - p_data->i_dts;
-            if ( !p_stream->mux.b_hasbframes )
-                p_stream->mux.b_hasbframes = true;
-        }
-        else e->i_pts_dts = 0;
+    if ( p_data->i_dts > VLC_TS_INVALID && p_data->i_pts > p_data->i_dts )
+    {
+        e->i_pts_dts = p_data->i_pts - p_data->i_dts;
+        if ( !p_stream->mux.b_hasbframes )
+            p_stream->mux.b_hasbframes = true;
+    }
+    else e->i_pts_dts = 0;
 
-        e->i_length = p_data->i_length;
-        e->i_flags  = p_data->i_flags;
+    e->i_length = p_data->i_length;
+    e->i_flags  = p_data->i_flags;
 
-        /* update */
-        p_stream->mux.i_read_duration += __MAX( 0, p_data->i_length );
-        p_stream->i_last_dts = dts_fb_pts( p_data );
+    /* update */
+    p_stream->mux.i_read_duration += __MAX( 0, p_data->i_length );
+    p_stream->i_last_dts = dts_fb_pts( p_data );
 
-        /* write data */
-        p_sys->i_pos += p_data->i_buffer;
-        sout_AccessOutWrite(p_mux->p_access, p_data);
+    /* write data */
+    p_sys->i_pos += p_data->i_buffer;
+    sout_AccessOutWrite(p_mux->p_access, p_data);
 
-        /* Add SPU clearing tag (duration tb fixed on next SPU or stream end )*/
-        if (p_stream->mux.fmt.i_cat == SPU_ES)
+    /* Add SPU clearing tag (duration tb fixed on next SPU or stream end )*/
+    if (p_stream->mux.fmt.i_cat == SPU_ES )
+    {
+        block_t *p_empty = NULL;
+        if(p_stream->mux.fmt.i_codec == VLC_CODEC_SUBT)
         {
-            block_t *p_empty = NULL;
-            if(p_stream->mux.fmt.i_codec == VLC_CODEC_SUBT)
-            {
-                p_empty = block_Alloc(3);
-                if (p_empty)
-                {
-                    /* point to start of our empty */
-                    p_stream->i_last_dts += e->i_length;
-
-                    /* Write a " " */
-                    p_empty->p_buffer[0] = 0;
-                    p_empty->p_buffer[1] = 1;
-                    p_empty->p_buffer[2] = ' ';
-                }
-            }
-
+            p_empty = block_Alloc(3);
             if(p_empty)
             {
-                /* Append a idx entry */
-                /* XXX: No need to grow the entry here */
-                mp4mux_entry_t *e_empty = &p_stream->mux.entry[p_stream->mux.i_entry_count++];
-                e_empty->i_pos    = p_sys->i_pos;
-                e_empty->i_size   = p_empty->i_buffer;
-                e_empty->i_pts_dts= 0;
-                e_empty->i_length = 0; /* will add dts diff later*/
-                e_empty->i_flags  = 0;
-
-                p_sys->i_pos += p_empty->i_buffer;
-                sout_AccessOutWrite(p_mux->p_access, p_empty);
+                /* point to start of our empty */
+                p_stream->i_last_dts += e->i_length;
+
+                /* Write a " " */
+                p_empty->p_buffer[0] = 0;
+                p_empty->p_buffer[1] = 1;
+                p_empty->p_buffer[2] = ' ';
             }
         }
 
-        /* Update the global segment/media duration */
-        if( p_stream->mux.i_read_duration > p_sys->i_read_duration )
-            p_sys->i_read_duration = p_stream->mux.i_read_duration;
+        if(p_empty)
+        {
+            /* Append a idx entry */
+            /* XXX: No need to grow the entry here */
+            mp4mux_entry_t *e_empty = &p_stream->mux.entry[p_stream->mux.i_entry_count++];
+            e_empty->i_pos    = p_sys->i_pos;
+            e_empty->i_size   = p_empty->i_buffer;
+            e_empty->i_pts_dts= 0;
+            e_empty->i_length = 0; /* will add dts diff later*/
+            e_empty->i_flags  = 0;
+
+            p_sys->i_pos += p_empty->i_buffer;
+            sout_AccessOutWrite(p_mux->p_access, p_empty);
+        }
     }
 
-    return(VLC_SUCCESS);
+    /* Update the global segment/media duration */
+    if( p_stream->mux.i_read_duration > p_sys->i_read_duration )
+        p_sys->i_read_duration = p_stream->mux.i_read_duration;
+
+    return VLC_SUCCESS;
+}
+
+static int Mux(sout_mux_t *p_mux)
+{
+    int i_ret = VLC_SUCCESS;
+
+    do
+    {
+        int i_stream = sout_MuxGetStream(p_mux, 2, NULL);
+        if (i_stream < 0)
+            break;
+
+        sout_input_t *p_input  = p_mux->pp_inputs[i_stream];
+        mp4_stream_t *p_stream = (mp4_stream_t*)p_input->p_sys;
+
+        i_ret = MuxStream(p_mux, p_input, p_stream);
+    } while( i_ret == VLC_SUCCESS );
+
+    return i_ret;
 }
 
 /*****************************************************************************



More information about the vlc-commits mailing list