diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-09-15 22:31:43 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-09-15 22:39:31 +0200 |
commit | 21561610560fbde5a398d467b6d061ab3ac1c62e (patch) | |
tree | 58a99f6b7420f288266df26e5f458745551069fd | |
parent | f685f7d7a8386365f452cc38c546327f7df20296 (diff) | |
parent | 00431bf874e1044b01e09a2266ef85d4ff8d44cc (diff) | |
download | ffmpeg-21561610560fbde5a398d467b6d061ab3ac1c62e.tar.gz |
Merge commit '00431bf874e1044b01e09a2266ef85d4ff8d44cc'
* commit '00431bf874e1044b01e09a2266ef85d4ff8d44cc':
ismindex: handle time discontinuities and nonzero start time
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | tools/ismindex.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/tools/ismindex.c b/tools/ismindex.c index d66a389e0e..734419b1c9 100644 --- a/tools/ismindex.c +++ b/tools/ismindex.c @@ -254,6 +254,13 @@ static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f) ret = AVERROR(ENOMEM); goto fail; } + // The duration here is always the difference between consecutive + // start times and doesn't even try to read the actual duration of the + // media fragments. This is what other smooth streaming tools tend to + // do too, but cannot express missing fragments, and the start times + // may not match the stream metadata we get from libavformat. Correct + // calculation would require parsing the tfxd atom (if present, it's + // not mandatory) or parsing the full moof atoms separately. for (i = 0; i < track->chunks; i++) { if (version == 1) { track->offsets[i].time = avio_rb64(f); @@ -272,9 +279,30 @@ static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f) track->offsets[i - 1].duration = track->offsets[i].time - track->offsets[i - 1].time; } - if (track->chunks > 0) - track->offsets[track->chunks - 1].duration = track->duration - + if (track->chunks > 0) { + track->offsets[track->chunks - 1].duration = track->offsets[0].time + + track->duration - track->offsets[track->chunks - 1].time; + if (track->offsets[track->chunks - 1].duration <= 0) { + fprintf(stderr, "Calculated last chunk duration for track %d " + "was non-positive (%"PRId64"), probably due to missing " + "fragments ", track->track_id, + track->offsets[track->chunks - 1].duration); + if (track->chunks > 1) { + track->offsets[track->chunks - 1].duration = + track->offsets[track->chunks - 2].duration; + } else { + track->offsets[track->chunks - 1].duration = 1; + } + fprintf(stderr, "corrected to %"PRId64"\n", + track->offsets[track->chunks - 1].duration); + track->duration = track->offsets[track->chunks - 1].time + + track->offsets[track->chunks - 1].duration - + track->offsets[0].time; + fprintf(stderr, "Track duration corrected to %"PRId64"\n", + track->duration); + } + } ret = 0; fail: @@ -526,6 +554,7 @@ static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, const char *type) { int i, j; + int64_t pos = 0; struct Track *track = tracks->tracks[main]; int should_print_time_mismatch = 1; @@ -545,8 +574,18 @@ static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, } } } - fprintf(out, "\t\t<c n=\"%d\" d=\"%"PRId64"\" />\n", + fprintf(out, "\t\t<c n=\"%d\" d=\"%"PRId64"\" ", i, track->offsets[i].duration); + if (pos != track->offsets[i].time) { + // With the current logic for calculation of durations from + // chunk start times, this branch can only be hit on the first + // chunk - but that's still useful and this will keep working + // if the duration calculation is improved. + fprintf(out, "t=\"%"PRId64"\" ", track->offsets[i].time); + pos = track->offsets[i].time; + } + pos += track->offsets[i].duration; + fprintf(out, "/>\n"); } } |