diff options
author | Martin Storsjö <martin@martin.st> | 2014-10-12 23:37:17 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2014-11-17 16:13:02 +0200 |
commit | 2d9d6afb8d2f284f5e620ecc19f643d5cd3facb8 (patch) | |
tree | 67c34e88e63fdaa7f6cd1ac210da949895e169c5 /libavformat/movenc.c | |
parent | 0f9eb9165bb7d7982fdedf64f6bcec856f1bedd6 (diff) | |
download | ffmpeg-2d9d6afb8d2f284f5e620ecc19f643d5cd3facb8.tar.gz |
movenc: Factorize adding fragment info into a separate function
By calling this after writing the moof the first time (for
calculating the moof size), we can avoid intermediate storage
of tfrf_offset in MOVTrack.
Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r-- | libavformat/movenc.c | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 359716dfc3..8d378c4357 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2567,6 +2567,46 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, return 0; } +static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks) +{ + int i; + for (i = 0; i < mov->nb_streams; i++) { + MOVTrack *track = &mov->tracks[i]; + MOVFragmentInfo *info; + if ((tracks >= 0 && i != tracks) || !track->entry) + continue; + track->nb_frag_info++; + if (track->nb_frag_info >= track->frag_info_capacity) { + unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT; + if (av_reallocp_array(&track->frag_info, + new_capacity, + sizeof(*track->frag_info))) + return AVERROR(ENOMEM); + track->frag_info_capacity = new_capacity; + } + info = &track->frag_info[track->nb_frag_info - 1]; + info->offset = avio_tell(pb); + // Try to recreate the original pts for the first packet + // from the fields we have stored + info->time = track->start_dts + track->frag_start + + track->cluster[0].cts; + // If the pts is less than zero, we will have trimmed + // away parts of the media track using an edit list, + // and the corresponding start presentation time is zero. + if (info->time < 0) + info->time = 0; + info->duration = track->start_dts + track->track_duration - + track->cluster[0].dts; + info->tfrf_offset = 0; + mov_write_tfrf_tags(pb, mov, track); + // If writing all tracks, we currently only add a tfra entry for + // the first track (that actually has data to be written). + if (tracks < 0) + break; + } + return 0; +} + static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track) { int64_t pos = avio_tell(pb); @@ -2597,7 +2637,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, if (mov->ism_lookahead) { int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead; - track->tfrf_offset = avio_tell(pb); + if (track->nb_frag_info > 0) { + MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1]; + if (!info->tfrf_offset) + info->tfrf_offset = avio_tell(pb); + } avio_wb32(pb, 8 + size); ffio_wfourcc(pb, "free"); for (i = 0; i < size; i++) @@ -2640,6 +2684,10 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) return ret; mov_write_moof_tag_internal(avio_buf, mov, tracks, 0); moof_size = ffio_close_null_buf(avio_buf); + + if ((ret = mov_add_tfra_entries(pb, mov, tracks)) < 0) + return ret; + return mov_write_moof_tag_internal(pb, mov, tracks, moof_size); } @@ -3004,36 +3052,9 @@ static int mov_flush_fragment(AVFormatContext *s) } if (write_moof) { - MOVFragmentInfo *info; avio_flush(s->pb); - track->nb_frag_info++; - if (track->nb_frag_info >= track->frag_info_capacity) { - unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT; - if (av_reallocp_array(&track->frag_info, - new_capacity, - sizeof(*track->frag_info))) - return AVERROR(ENOMEM); - track->frag_info_capacity = new_capacity; - } - info = &track->frag_info[track->nb_frag_info - 1]; - info->offset = avio_tell(s->pb); - info->time = track->frag_start; - if (track->entry) { - // Try to recreate the original pts for the first packet - // from the fields we have stored - info->time = track->start_dts + track->frag_start + - track->cluster[0].cts; - // If the pts is less than zero, we will have trimmed - // away parts of the media track using an edit list, - // and the corresponding start presentation time is zero. - if (info->time < 0) - info->time = 0; - } - info->duration = duration; - mov_write_tfrf_tags(s->pb, mov, track); mov_write_moof_tag(s->pb, mov, moof_tracks); - info->tfrf_offset = track->tfrf_offset; mov->fragments++; avio_wb32(s->pb, mdat_size + 8); |