Commit 2d9d6afb authored by Martin Storsjö's avatar Martin Storsjö

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: 's avatarMartin Storsjö <martin@martin.st>
parent 0f9eb916
...@@ -2567,6 +2567,46 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, ...@@ -2567,6 +2567,46 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
return 0; 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) static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
{ {
int64_t pos = avio_tell(pb); int64_t pos = avio_tell(pb);
...@@ -2597,7 +2637,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, ...@@ -2597,7 +2637,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
if (mov->ism_lookahead) { if (mov->ism_lookahead) {
int i, size = 16 + 4 + 1 + 16 * 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); avio_wb32(pb, 8 + size);
ffio_wfourcc(pb, "free"); ffio_wfourcc(pb, "free");
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
...@@ -2640,6 +2684,10 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) ...@@ -2640,6 +2684,10 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
return ret; return ret;
mov_write_moof_tag_internal(avio_buf, mov, tracks, 0); mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
moof_size = ffio_close_null_buf(avio_buf); 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); return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
} }
...@@ -3004,36 +3052,9 @@ static int mov_flush_fragment(AVFormatContext *s) ...@@ -3004,36 +3052,9 @@ static int mov_flush_fragment(AVFormatContext *s)
} }
if (write_moof) { if (write_moof) {
MOVFragmentInfo *info;
avio_flush(s->pb); 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); mov_write_moof_tag(s->pb, mov, moof_tracks);
info->tfrf_offset = track->tfrf_offset;
mov->fragments++; mov->fragments++;
avio_wb32(s->pb, mdat_size + 8); avio_wb32(s->pb, mdat_size + 8);
......
...@@ -120,7 +120,6 @@ typedef struct MOVTrack { ...@@ -120,7 +120,6 @@ typedef struct MOVTrack {
AVIOContext *mdat_buf; AVIOContext *mdat_buf;
int64_t data_offset; int64_t data_offset;
int64_t frag_start; int64_t frag_start;
int64_t tfrf_offset;
int nb_frag_info; int nb_frag_info;
MOVFragmentInfo *frag_info; MOVFragmentInfo *frag_info;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment