[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