summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavformat/movenc.c77
-rw-r--r--libavformat/movenc.h1
2 files changed, 49 insertions, 29 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);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 8349a18c1d..1df5a5cb96 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -120,7 +120,6 @@ typedef struct MOVTrack {
AVIOContext *mdat_buf;
int64_t data_offset;
int64_t frag_start;
- int64_t tfrf_offset;
int nb_frag_info;
MOVFragmentInfo *frag_info;