On Sat, 7 Mar 2015, Martin Storsjö wrote:
Even if this is a guess, it is way better than writing a zero duration of the last sample in a fragment (because if the duration is zero, the first sample of the next fragment will have the same timestamp as the last sample in the previous one).Since we normally don't require libavformat muxer users to set the duration field in AVPacket, we probably can't strictly require it here either, so don't log this as a strict warning, only as info. --- libavformat/movenc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ libavformat/movenc.h | 1 + 2 files changed, 43 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 67c7214..dc36d28 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3116,6 +3116,48 @@ static int mov_flush_fragment(AVFormatContext *s) if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) return 0; + for (i = 0; i < mov->nb_streams; i++) { + MOVTrack *track = &mov->tracks[i]; + if (track->entry > 1) { + // Sample durations are calculated as the diff of dts values, + // but for the last sample in a fragment, we don't know the dts + // of the first sample in the next fragment, so we have to rely + // on what was set as duration in the AVPacket. Not all callers + // set this though, so we might want to replace it with an + // estimate if it currently is zero. + if (get_cluster_duration(track, track->entry - 1) == 0) { + int64_t first_sample_dts, last_sample_dts; + int64_t duration, avg_sample_dur; + int n; + if (track->entry > 2) { + // If possible, ignore the first sample as well, since it + // might not be as regular as the other ones + first_sample_dts = track->cluster[1].dts; + n = track->entry - 2; + } else { + first_sample_dts = track->cluster[0].dts; + n = track->entry - 1; + } + last_sample_dts = track->cluster[track->entry - 1].dts; + // Calculate the average duration of the N-1 earlier samples + // in the fragment + duration = last_sample_dts - first_sample_dts; + avg_sample_dur = duration / n; + // Set the duration of the last sample to the average + track->track_duration = last_sample_dts - track->start_dts + + avg_sample_dur; + if (!mov->missing_duration_warned) { + av_log(s, AV_LOG_WARNING, + "Estimating the duration of the last packet in a " + "fragment, consider setting the duration field in " + "AVPacket instead.\n"); + mov->missing_duration_warned = 1; + } + } + break;
This break was a stray line and shouldn't be there of course, removed locally. And locally inverted the if conditions to reduce the indentation by two levels.
// Martin _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
