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>
This commit is contained in:
parent
0f9eb9165b
commit
2d9d6afb8d
@ -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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user