vlc | branch: master | Francois Cartegnie <[email protected]> | Fri Oct 26 17:19:57 2018 +0200| [2c31eec409b72c9e54c4dab86b19fb37f993d446] | committer: Francois Cartegnie
mux: mp4: rework fast start > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2c31eec409b72c9e54c4dab86b19fb37f993d446 --- modules/mux/mp4/libmp4mux.c | 18 ++++++++--- modules/mux/mp4/libmp4mux.h | 6 +--- modules/mux/mp4/mp4.c | 79 ++++++++++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/modules/mux/mp4/libmp4mux.c b/modules/mux/mp4/libmp4mux.c index 7cfea5dde3..88dfaa348c 100644 --- a/modules/mux/mp4/libmp4mux.c +++ b/modules/mux/mp4/libmp4mux.c @@ -139,6 +139,19 @@ mp4mux_sample_t *mp4mux_track_GetLastSample(mp4mux_trackinfo_t *t) else return NULL; } +void mp4mux_ShiftSamples(mp4mux_handle_t *h, int64_t offset) +{ + for(size_t i_track = 0; i_track < vlc_array_count(&h->tracks); i_track++) + { + mp4mux_trackinfo_t *t = vlc_array_item_at_index(&h->tracks, i_track); + for (unsigned i = 0; i < t->i_samples_count; i++) + { + mp4mux_sample_t *sample = t->samples; + sample[i].i_pos += offset; + } + } +} + mp4mux_handle_t * mp4mux_New(enum mp4mux_options options) { mp4mux_handle_t *h = malloc(sizeof(*h)); @@ -1560,7 +1573,6 @@ static bo_t *GetStblBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b box_gather(stbl, ctts); box_gather(stbl, stsc); box_gather(stbl, stsz); - p_track->i_stco_pos = bo_size(stbl) + 16; box_gather(stbl, stco); return stbl; @@ -1935,19 +1947,15 @@ bo_t * mp4mux_GetMoov(mp4mux_handle_t *h, vlc_object_t *p_obj, vlc_tick_t i_dura stbl = GetStblBox(p_obj, p_stream, h->options & QUICKTIME, h->options & USE64BITEXT); /* append stbl to minf */ - p_stream->i_stco_pos += bo_size(minf); box_gather(minf, stbl); /* append minf to mdia */ - p_stream->i_stco_pos += bo_size(mdia); box_gather(mdia, minf); /* append mdia to trak */ - p_stream->i_stco_pos += bo_size(trak); box_gather(trak, mdia); /* append trak to moov */ - p_stream->i_stco_pos += bo_size(moov); box_gather(moov, trak); } diff --git a/modules/mux/mp4/libmp4mux.h b/modules/mux/mp4/libmp4mux.h index 6a45bc3fa2..1da7e88e1b 100644 --- a/modules/mux/mp4/libmp4mux.h +++ b/modules/mux/mp4/libmp4mux.h @@ -62,10 +62,6 @@ typedef struct vlc_tick_t i_firstdts; /* the really first packet */ bool b_hasbframes; - /* temp stuff */ - /* for later stco fix-up (fast start files) */ - uint64_t i_stco_pos; - /* frags */ vlc_tick_t i_trex_default_length; uint32_t i_trex_default_size; @@ -98,8 +94,8 @@ void mp4mux_track_DebugEdits(vlc_object_t *, const mp4mux_trackinfo_t *); bool mp4mux_track_AddSample(mp4mux_trackinfo_t *, const mp4mux_sample_t *); mp4mux_sample_t *mp4mux_track_GetLastSample(mp4mux_trackinfo_t *); - bo_t *mp4mux_GetMoov(mp4mux_handle_t *, vlc_object_t *, vlc_tick_t i_movie_duration); +void mp4mux_ShiftSamples(mp4mux_handle_t *, int64_t offset); /* old */ diff --git a/modules/mux/mp4/mp4.c b/modules/mux/mp4/mp4.c index 5799245486..1961cc7ca4 100644 --- a/modules/mux/mp4/mp4.c +++ b/modules/mux/mp4/mp4.c @@ -297,65 +297,78 @@ static void Close(vlc_object_t *p_this) sout_AccessOutWrite(p_mux->p_access, bo.b); /* Create MOOV header */ - const bool b_64bitext = (p_sys->i_pos >= (((uint64_t)0x1) << 32)); + bool b_64bitext = (p_sys->i_pos > UINT32_MAX); if(b_64bitext) mp4mux_Set64BitExt(p_sys->muxh); + uint64_t i_moov_pos = p_sys->i_pos; bo_t *moov = mp4mux_GetMoov(p_sys->muxh, VLC_OBJECT(p_mux), 0); /* Check we need to create "fast start" files */ p_sys->b_fast_start = var_GetBool(p_this, SOUT_CFG_PREFIX "faststart"); - while (p_sys->b_fast_start && moov && moov->b) { + while (p_sys->b_fast_start && moov && moov->b) + { /* Move data to the end of the file so we can fit the moov header * at the start */ - int64_t i_size = p_sys->i_pos - p_sys->i_mdat_pos; - int i_moov_size = bo_size(moov); + uint64_t i_mdatsize = p_sys->i_pos - p_sys->i_mdat_pos; + + /* moving samples will need new moov with 64bit atoms ? */ + if(!b_64bitext && p_sys->i_pos + bo_size(moov) > UINT32_MAX) + { + mp4mux_Set64BitExt(p_sys->muxh); + b_64bitext = true; + /* generate a new moov */ + bo_t *moov64 = mp4mux_GetMoov(p_sys->muxh, VLC_OBJECT(p_mux), 0); + if(moov64) + { + bo_free(moov); + moov = moov64; + } + } + /* We now know our final MOOV size */ + + /* Fix-up samples to chunks table in MOOV header to they point to next MDAT location */ + mp4mux_ShiftSamples(p_sys->muxh, bo_size(moov)); + msg_Dbg(p_this,"Moving data by %"PRIu64, (uint64_t)bo_size(moov)); + bo_t *shifted = mp4mux_GetMoov(p_sys->muxh, VLC_OBJECT(p_mux), 0); + if(!shifted) + { + /* fail */ + p_sys->b_fast_start = false; + continue; + } + assert(bo_size(shifted) == bo_size(moov)); + bo_free(moov); + moov = shifted; - while (i_size > 0) { - int64_t i_chunk = __MIN(32768, i_size); + /* Make space, move MDAT data by moov size towards the end */ + while (i_mdatsize > 0) + { + size_t i_chunk = __MIN(32768, i_mdatsize); block_t *p_buf = block_Alloc(i_chunk); sout_AccessOutSeek(p_mux->p_access, - p_sys->i_mdat_pos + i_size - i_chunk); - if (sout_AccessOutRead(p_mux->p_access, p_buf) < i_chunk) { + p_sys->i_mdat_pos + i_mdatsize - i_chunk); + ssize_t i_read = sout_AccessOutRead(p_mux->p_access, p_buf); + if (i_read < 0 || (size_t) i_read < i_chunk) { msg_Warn(p_this, "read() not supported by access output, " "won't create a fast start file"); p_sys->b_fast_start = false; block_Release(p_buf); break; } - sout_AccessOutSeek(p_mux->p_access, p_sys->i_mdat_pos + i_size + - i_moov_size - i_chunk); + sout_AccessOutSeek(p_mux->p_access, p_sys->i_mdat_pos + i_mdatsize + + bo_size(moov) - i_chunk); sout_AccessOutWrite(p_mux->p_access, p_buf); - i_size -= i_chunk; + i_mdatsize -= i_chunk; } - if (!p_sys->b_fast_start) - break; + if (!p_sys->b_fast_start) /* failed above */ + continue; /* Update pos pointers */ i_moov_pos = p_sys->i_mdat_pos; p_sys->i_mdat_pos += bo_size(moov); - /* Fix-up samples to chunks table in MOOV header */ - for (unsigned int i_trak = 0; i_trak < p_sys->i_nb_streams; i_trak++) { - mp4_stream_t *p_stream = p_sys->pp_streams[i_trak]; - unsigned i_written = 0; - for (unsigned i = 0; i < p_stream->tinfo->i_samples_count; ) { - mp4mux_sample_t *entry = p_stream->tinfo->samples; - if (b_64bitext) - bo_set_64be(moov, p_stream->tinfo->i_stco_pos + i_written++ * 8, entry[i].i_pos + p_sys->i_mdat_pos - i_moov_pos); - else - bo_set_32be(moov, p_stream->tinfo->i_stco_pos + i_written++ * 4, entry[i].i_pos + p_sys->i_mdat_pos - i_moov_pos); - - for (; i < p_stream->tinfo->i_samples_count; i++) - if (i >= p_stream->tinfo->i_samples_count - 1 || - entry[i].i_pos + entry[i].i_size != entry[i+1].i_pos) { - i++; - break; - } - } - } - p_sys->b_fast_start = false; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
