On Sat, 6 Sep 2014, Mika Raento wrote:
The input file may not be contiguous in time, this produces the right
manifest to keep video and audio in sync.
---
tools/ismindex.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
Ok, so I finally got to crafting a file that triggers this case, and
reading up on what my code actually does, so now I see better what you
think could benefit from sharing with libavformat/smoothstreamingenc.c.
A few further questions though, just to evaluate solutions/workarounds
better...
Which of all these cases did you actually encounter in practice, and which
ones of them are only added for completeness sake? E.g. I can see how
other tools easily could write an ismv file where the first fragment
starts at a time different than zero. But did you run into files with real
discontinuities/missing fragments (e.g. frag N time + duration < frag N+1
time) as well? E.g. is it worth a bigger effort to handle such files
properly, or are they only a constructed case? If there would be e.g.
subtitle tracks in the files I could see that such cases might actually
exist, or are there better explanations for those cases?
Also, for the case when the first timestamp isn't zero - I think the
current normalization (by shifting them to zero) might not be the best
solution. Since the fragments themselves contain the tfxd box which
indicates the timestamp and duration, this would lead to a mismatch, i.e.
when the client requests QualityLevels(42)/Fragments(video=0), but this
fragment actually contains tfxd box saying time=<nonzero>. Wouldn't it be
better to just add the time of the first chunk when setting the duration
of the last chunk? That is, this:
@@ -276,7 +276,7 @@ static int read_tfra(struct Tracks *tracks, int
start_index, AVIOContext *f)
track->offsets[i - 1].time;
}
if (track->chunks > 0)
- track->offsets[track->chunks - 1].duration = track->duration -
+ track->offsets[track->chunks - 1].duration = track->offsets[0].time +
track->duration -
track->offsets[track->chunks - 1].time;
ret = 0;
Also, in general, if we'd hook up proper reading of the tfxd boxes of the
fragments (by reusing parse_fragments from
libavformat/smoothstreamingenc.c), would that make most of the
normalization function go away? Then we'd need much less heuristics and
just more or less print what we read.
Finally, one further question below...
diff --git a/tools/ismindex.c b/tools/ismindex.c
index bc98226..b605c9f 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -280,6 +285,48 @@ fail:
return ret;
}
+static int normalize_track_times(struct Tracks *tracks, int start_index) {
+ // The fragment start times and durations may not match the stream
+ // (track) data, this makes an effort to fix them.
+ int i;
+ int64_t smallest_start_time = INT64_MAX, largest_duration = 0;
+ for (i = start_index; i < tracks->nb_tracks; i++) {
+ smallest_start_time = FFMIN(smallest_start_time,
+ tracks->tracks[i]->offsets[0].time);
+ }
+ if (smallest_start_time > 0) {
+ fprintf(stderr, "Subtracting %"PRId64" from all start times\n",
+ smallest_start_time);
+ for (i = start_index; i < tracks->nb_tracks; i++) {
+ struct Track *track = tracks->tracks[i];
+ int j;
+ for (j = 0; j < track->chunks; j++) {
+ track->offsets[j].time -= smallest_start_time;
+ }
+ }
+ }
+ for (i = start_index; i < tracks->nb_tracks; i++) {
+ struct Track *track = tracks->tracks[i];
+ if (track->offsets[track->chunks - 1].time + 1 > track->duration) {
Why the +1 here? Wouldn't it in princple be enough to have a strict
comparison here? Or is it to give some headroom for odd rounding
somewhere? (I don't think the durations that are summed ever should be
rounded somewhere though.)
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel