|
|
@@ -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); |
|
|
|