On 10/09/14 09:58, "Raento Mika" <[email protected]> wrote:
>On 10/09/14 00:43, "Martin Storsjö" <[email protected]> wrote: > >>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... > >Great comments. > >> >>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? > >I'll have to check. > >Definitely missing chunks are to be expected when capturing broadcast >video - >there are always dropped/corrupt parts in the stream, and not all >packagers >fill those with empty frames themselves. > >> >>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: > >Right. I'll check this and get back to you. Maybe it isn't the best >solution. Ah, my mp4 parser doesn't know about Tfxd boxes, that's why I didn't realize this. > > Mika > >> >>@@ -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
