On 15/09/14 00:38, "Martin Storsjö" <[email protected]> wrote:

>From: Mika Raento <[email protected]>
>
>The input file may not have consistent start times, stream durations and
>chunk durations. This patch at least removes negative durations that
>make chromecast unhappy, and correctly sets starting time on chunks so
>that the split (or .ismf) outputs match the manifest.
>---
>Updated the comments slightly, clarifying the situation further,
>taking a nonzero start time into account (handling continuous files
>with a nonzero start time correctly), and fixed setting the track
>duration.
>---
> tools/ismindex.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 42 insertions(+), 3 deletions(-)
>
>diff --git a/tools/ismindex.c b/tools/ismindex.c
>index aa862f8..02c90a2 100644
>--- a/tools/ismindex.c
>+++ b/tools/ismindex.c
>@@ -252,6 +252,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 each individual moof separately.
>     for (i = 0; i < track->chunks; i++) {
>         if (version == 1) {
>             track->offsets[i].time   = avio_rb64(f);
>@@ -270,9 +277,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:
>@@ -524,6 +552,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;
> 
>@@ -543,8 +572,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");
>     }
> }
> 
>-- 
>1.8.5.2 (Apple Git-48)
>
>

LGTM. Thanks.

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to