diff mbox

[FFmpeg-devel,mov] Fix trampling of ctts during seeks when sidx support is enabled.

Message ID CAPUDrwegXtqR_Vs5tMPLTy9FMBMSc58aG3v6ArCnY1hZPHNepw@mail.gmail.com
State Superseded
Headers show

Commit Message

Dale Curtis Aug. 7, 2017, 7:31 p.m. UTC
On Fri, Aug 4, 2017 at 4:40 PM, Rodger Combs <rodger.combs@gmail.com> wrote:

> +            sc->ctts_data = av_fast_realloc(sc->ctts_data,
> &sc->ctts_allocated_size, request_size);
> ^ this line is incorrect; setting realloc's first arg to its return value
> leaks the existing allocation in the OOM case. Since you're doing your own
> calculation for the desired new size here, you may want to use av_reallocp
> (which frees the original allocation on failure).
>

Thanks, fixed; kept av_fast_realloc() for size setting simplicity, but
reused function-scope ctts_data as temporary.


>
> When reading a trun that requires this sort of realloc, is it common for
> there to be any existing entries in the range we're writing? Would it be
> safe to remove+replace them? Could we do a single realloc + single memmove,
> and then fill the newly-opened space, rather than repeating the memmove for
> each entry?
>

Yes it's common for their to be existing entries. To be clear this occurs
with standard files that are of sufficient length that a seek can occur
before all trun boxes are read. We could speculatively move all entries
based on the first insert and total entries count, but their are several
conditionals in av_add_index_entry() which may cause a bail out and such
failure would be unrecoverable (maybe painfully?) if we moved everything
ahead of time.

- dale
diff mbox

Patch

From 4938dac2d9f3b40c62822d9129046edbde44468d Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 17 Jul 2017 17:38:09 -0700
Subject: [PATCH] Fix trampling of ctts during seeks when sidx support is
 enabled.

When sidx box support is enabled, the code will skip reading all
trun boxes (each containing ctts entries for samples inthat box).

If seeks are attempted before all ctts values are known, the old
code would dump ctts entries into the wrong location. These are
then used to compute pts values which leads to out of order and
incorrectly timestamped packets.

This patch fixes ctts processing by always using the index returned
by av_add_index_entry() as the ctts_data index. When the index gains
new entries old values are reshuffled as appropriate.

This approach makes sense since the mov demuxer is already relying
on the mapping of AVIndex entries to samples for correct demuxing.

As a result of this all ctts entries are now 1-count. A followup
change will be submitted to remove support for > 1 count entries
which will simplify seeking.

Notes for future improvement:
Probably there are other boxes (stts, stsc, etc) that are impacted
by this issue... this patch only attempts to fix ctts since it
completely breaks packet timestamping.

This patch continues using an array for the ctts data, which is not
the most ideal given the rearrangement that needs to happen (via
memmove as new entries are read in). Ideally AVIndex and the ctts
data would be set-type structures so addition is always worst case
O(lg(n)) instead of the O(n^2) that exists now; this slowdown is
noticeable during seeks.

Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
---
 libavformat/isom.h       |   1 +
 libavformat/mov.c        |  79 ++++++++++++++++++----------
 tests/fate/seek.mak      |   3 ++
 tests/ref/seek/extra-mp4 | 134 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 28 deletions(-)
 create mode 100644 tests/ref/seek/extra-mp4

diff --git a/libavformat/isom.h b/libavformat/isom.h
index ff009b0896..fdd98c28f5 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -137,6 +137,7 @@  typedef struct MOVStreamContext {
     unsigned int stts_count;
     MOVStts *stts_data;
     unsigned int ctts_count;
+    unsigned int ctts_allocated_size;
     MOVStts *ctts_data;
     unsigned int stsc_count;
     MOVStsc *stsc_data;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 63f84be782..85377f39a9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -74,6 +74,8 @@  typedef struct MOVParseTableEntry {
 
 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
+static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
+                              int count, int duration);
 
 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
                                              unsigned len, const char *key)
@@ -2708,7 +2710,7 @@  static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
     MOVStreamContext *sc;
-    unsigned int i, entries, ctts_count = 0;
+    unsigned int i, j, entries, ctts_count = 0;
 
     if (c->fc->nb_streams < 1)
         return 0;
@@ -2726,7 +2728,7 @@  static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
         return AVERROR_INVALIDDATA;
     av_freep(&sc->ctts_data);
-    sc->ctts_data = av_realloc(NULL, entries * sizeof(*sc->ctts_data));
+    sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
     if (!sc->ctts_data)
         return AVERROR(ENOMEM);
 
@@ -2741,9 +2743,9 @@  static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             continue;
         }
 
-        sc->ctts_data[ctts_count].count    = count;
-        sc->ctts_data[ctts_count].duration = duration;
-        ctts_count++;
+        /* Expand entries such that we have a 1-1 mapping with samples. */
+        for (j = 0; j < count; j++)
+            add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, 1, duration);
 
         av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
                 count, duration);
@@ -3046,7 +3048,6 @@  static void mov_fix_index(MOVContext *mov, AVStream *st)
     int64_t index;
     int64_t index_ctts_count;
     int flags;
-    unsigned int ctts_allocated_size = 0;
     int64_t start_dts = 0;
     int64_t edit_list_media_time_dts = 0;
     int64_t edit_list_start_encountered = 0;
@@ -3081,6 +3082,7 @@  static void mov_fix_index(MOVContext *mov, AVStream *st)
     msc->ctts_count = 0;
     msc->ctts_index = 0;
     msc->ctts_sample = 0;
+    msc->ctts_allocated_size = 0;
 
     // If the dts_shift is positive (in case of negative ctts values in mov),
     // then negate the DTS by dts_shift
@@ -3190,7 +3192,7 @@  static void mov_fix_index(MOVContext *mov, AVStream *st)
                 ctts_sample_old++;
                 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
                     if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
-                                       &ctts_allocated_size,
+                                       &msc->ctts_allocated_size,
                                        ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
                                        ctts_data_old[ctts_index_old].duration) == -1) {
                         av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
@@ -3289,7 +3291,7 @@  static void mov_fix_index(MOVContext *mov, AVStream *st)
 
                 if (ctts_data_old && ctts_sample_old != 0) {
                     if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
-                                       &ctts_allocated_size,
+                                       &msc->ctts_allocated_size,
                                        ctts_sample_old - edit_list_start_ctts_sample,
                                        ctts_data_old[ctts_index_old].duration) == -1) {
                         av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
@@ -4259,7 +4261,7 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     int64_t dts;
     int data_offset = 0;
     unsigned entries, first_sample_flags = frag->flags;
-    int flags, distance, i, err;
+    int flags, distance, i;
 
     for (i = 0; i < c->fc->nb_streams; i++) {
         if (c->fc->streams[i]->id == frag->track_id) {
@@ -4287,21 +4289,20 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (!sc->ctts_count && sc->sample_count)
     {
         /* Complement ctts table if moov atom doesn't have ctts atom. */
-        ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data));
+        ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, sizeof(*sc->ctts_data) * sc->sample_count);
         if (!ctts_data)
             return AVERROR(ENOMEM);
+        /* Don't use a count greater than 1 here since it will leave a gap in
+         * the ctts index which the code below relies on being sequential. */
         sc->ctts_data = ctts_data;
-        sc->ctts_data[sc->ctts_count].count = sc->sample_count;
-        sc->ctts_data[sc->ctts_count].duration = 0;
-        sc->ctts_count++;
+        for (i = 0; i < sc->sample_count; i++) {
+            sc->ctts_data[sc->ctts_count].count = 1;
+            sc->ctts_data[sc->ctts_count].duration = 0;
+            sc->ctts_count++;
+        }
     }
     if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
         return AVERROR_INVALIDDATA;
-    if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count,
-                                 sizeof(*sc->ctts_data))) < 0) {
-        sc->ctts_count = 0;
-        return err;
-    }
     if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
     dts    = sc->track_end - sc->time_offset;
@@ -4312,26 +4313,28 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         unsigned sample_size = frag->size;
         int sample_flags = i ? frag->flags : first_sample_flags;
         unsigned sample_duration = frag->duration;
+        unsigned ctts_duration = 0;
         int keyframe = 0;
+        int ctts_index = 0;
+        int old_nb_index_entries = st->nb_index_entries;
 
         if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
         if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
         if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
-        sc->ctts_data[sc->ctts_count].count = 1;
-        sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
-                                                  avio_rb32(pb) : 0;
-        mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
+        if (flags & MOV_TRUN_SAMPLE_CTS)      ctts_duration   = avio_rb32(pb);
+
+        mov_update_dts_shift(sc, ctts_duration);
         if (frag->time != AV_NOPTS_VALUE) {
             if (c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
                 int64_t pts = frag->time;
                 av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
                         " sc->dts_shift %d ctts.duration %d"
                         " sc->time_offset %"PRId64" flags & MOV_TRUN_SAMPLE_CTS %d\n", pts,
-                        sc->dts_shift, sc->ctts_data[sc->ctts_count].duration,
+                        sc->dts_shift, ctts_duration,
                         sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
                 dts = pts - sc->dts_shift;
                 if (flags & MOV_TRUN_SAMPLE_CTS) {
-                    dts -= sc->ctts_data[sc->ctts_count].duration;
+                    dts -= ctts_duration;
                 } else {
                     dts -= sc->time_offset;
                 }
@@ -4343,7 +4346,7 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             }
             frag->time = AV_NOPTS_VALUE;
         }
-        sc->ctts_count++;
+
         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
             keyframe = 1;
         else
@@ -4352,11 +4355,31 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
                                   MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
         if (keyframe)
             distance = 0;
-        err = av_add_index_entry(st, offset, dts, sample_size, distance,
-                                 keyframe ? AVINDEX_KEYFRAME : 0);
-        if (err < 0) {
+        ctts_index = av_add_index_entry(st, offset, dts, sample_size, distance,
+                                        keyframe ? AVINDEX_KEYFRAME : 0);
+        if (ctts_index >= 0 && old_nb_index_entries < st->nb_index_entries) {
+            unsigned int size_needed = st->nb_index_entries * sizeof(*sc->ctts_data);
+            unsigned int request_size = size_needed > sc->ctts_allocated_size ?
+                FFMAX(size_needed, 2 * sc->ctts_allocated_size) : size_needed;
+            ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size);
+            if (!ctts_data) {
+                av_freep(&sc->ctts_data);
+                return AVERROR(ENOMEM);
+            }
+
+            sc->ctts_data = ctts_data;
+            if (ctts_index != old_nb_index_entries) {
+                memmove(sc->ctts_data + ctts_index + 1, sc->ctts_data + ctts_index,
+                        sizeof(*sc->ctts_data) * (sc->ctts_count - ctts_index));
+            }
+
+            sc->ctts_data[ctts_index].count = 1;
+            sc->ctts_data[ctts_index].duration = ctts_duration;
+            sc->ctts_count++;
+        } else {
             av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
         }
+
         av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
                 "size %u, distance %d, keyframe %d\n", st->index, sc->sample_count+i,
                 offset, dts, sample_size, distance, keyframe);
diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak
index f835da5226..1a6e584987 100644
--- a/tests/fate/seek.mak
+++ b/tests/fate/seek.mak
@@ -248,7 +248,10 @@  FATE_SEEK += $(FATE_SEEK_LAVF-yes:%=fate-seek-lavf-%)
 FATE_SEEK_EXTRA-$(CONFIG_MP3_DEMUXER)   += fate-seek-extra-mp3
 FATE_SEEK_EXTRA-$(call ALLYES, CACHE_PROTOCOL PIPE_PROTOCOL MP3_DEMUXER) += fate-seek-cache-pipe
 FATE_SEEK_EXTRA-$(CONFIG_MATROSKA_DEMUXER) += fate-seek-mkv-codec-delay
+FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-extra-mp4
+
 fate-seek-extra-mp3:  CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/gapless/gapless.mp3 -fastseek 1
+fate-seek-extra-mp4:  CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/buck480p30_na.mp4 -duration 180 -frames 4
 fate-seek-cache-pipe: CMD = cat $(TARGET_SAMPLES)/gapless/gapless.mp3 | run libavformat/tests/seek$(EXESUF) cache:pipe:0 -read_ahead_limit -1
 fate-seek-mkv-codec-delay:   CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mkv/codec_delay_opus.mkv
 
diff --git a/tests/ref/seek/extra-mp4 b/tests/ref/seek/extra-mp4
new file mode 100644
index 0000000000..960f2dfad8
--- /dev/null
+++ b/tests/ref/seek/extra-mp4
@@ -0,0 +1,134 @@ 
+ret: 0         st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos:   4174 size:   147
+ret: 0         st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos:   4321 size:    24
+ret: 0         st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos:   4345 size:  6779
+ret: 0         st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos:  11124 size: 11041
+ret: 0         st:-1 flags:0  ts:-1.000000
+ret: 0         st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos:   4174 size:   147
+ret: 0         st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos:   4321 size:    24
+ret: 0         st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos:   4345 size:  6779
+ret: 0         st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos:  11124 size: 11041
+ret: 0         st:-1 flags:1  ts: 101.894167
+ret: 0         st: 0 flags:1 dts: 101.300000 pts: 101.333333 pos:10974394 size: 67201
+ret: 0         st: 0 flags:0 dts: 101.333333 pts: 101.433333 pos:11041595 size:  3524
+ret: 0         st: 0 flags:0 dts: 101.366667 pts: 101.366667 pos:11045119 size:   562
+ret: 0         st: 0 flags:0 dts: 101.400000 pts: 101.400000 pos:11045681 size:   599
+ret: 0         st: 0 flags:0  ts: 24.788333
+ret: 0         st: 0 flags:1 dts: 25.300000 pts: 25.333333 pos:2607665 size: 40237
+ret: 0         st: 0 flags:0 dts: 25.333333 pts: 25.433333 pos:2647902 size:  2959
+ret: 0         st: 0 flags:0 dts: 25.366667 pts: 25.366667 pos:2650861 size:   197
+ret: 0         st: 0 flags:0 dts: 25.400000 pts: 25.400000 pos:2651058 size:   230
+ret: 0         st: 0 flags:1  ts: 127.682500
+ret: 0         st: 0 flags:1 dts: 126.633333 pts: 126.666667 pos:13349318 size: 68705
+ret: 0         st: 0 flags:0 dts: 126.666667 pts: 126.766667 pos:13418023 size:  2914
+ret: 0         st: 0 flags:0 dts: 126.700000 pts: 126.700000 pos:13420937 size:   781
+ret: 0         st: 0 flags:0 dts: 126.733333 pts: 126.733333 pos:13421718 size:   817
+ret: 0         st:-1 flags:0  ts: 50.576668
+ret: 0         st: 0 flags:1 dts: 50.633333 pts: 50.666667 pos:5856029 size: 67867
+ret: 0         st: 0 flags:0 dts: 50.666667 pts: 50.766667 pos:5923896 size:  1307
+ret: 0         st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5925203 size:   150
+ret: 0         st: 0 flags:0 dts: 50.733333 pts: 50.733333 pos:5925353 size:   176
+ret: 0         st:-1 flags:1  ts: 153.470835
+ret: 0         st: 0 flags:1 dts: 153.466667 pts: 153.500000 pos:15853683 size: 96133
+ret: 0         st: 0 flags:0 dts: 153.500000 pts: 153.533333 pos:15949816 size:   785
+ret: 0         st: 0 flags:0 dts: 153.533333 pts: 153.633333 pos:15950601 size:  3135
+ret: 0         st: 0 flags:0 dts: 153.566667 pts: 153.566667 pos:15953736 size:   859
+ret: 0         st: 0 flags:0  ts: 76.365000
+ret: 0         st: 0 flags:1 dts: 77.833333 pts: 77.866667 pos:8653728 size: 41146
+ret: 0         st: 0 flags:0 dts: 77.866667 pts: 77.966667 pos:8694874 size:  4197
+ret: 0         st: 0 flags:0 dts: 77.900000 pts: 77.900000 pos:8699071 size:   653
+ret: 0         st: 0 flags:0 dts: 77.933333 pts: 77.933333 pos:8699724 size:   751
+ret: 0         st: 0 flags:1  ts:-0.740833
+ret: 0         st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos:   4174 size:   147
+ret: 0         st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos:   4321 size:    24
+ret: 0         st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos:   4345 size:  6779
+ret: 0         st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos:  11124 size: 11041
+ret: 0         st:-1 flags:0  ts: 102.153336
+ret: 0         st: 0 flags:0 dts: 83.833333 pts: 83.900000 pos:9584397 size:  8129
+ret: 0         st: 0 flags:0 dts: 83.866667 pts: 83.866667 pos:9592526 size:  2247
+ret: 0         st: 0 flags:0 dts: 83.900000 pts: 83.966667 pos:9594773 size:  8990
+ret: 0         st: 0 flags:0 dts: 83.933333 pts: 83.933333 pos:9603763 size:  2386
+ret: 0         st:-1 flags:1  ts: 25.047503
+ret: 0         st: 0 flags:1 dts: 20.233333 pts: 20.266667 pos:2224826 size: 51787
+ret: 0         st: 0 flags:0 dts: 20.266667 pts: 20.300000 pos:2276613 size:   488
+ret: 0         st: 0 flags:0 dts: 20.300000 pts: 20.400000 pos:2277101 size:   670
+ret: 0         st: 0 flags:0 dts: 20.333333 pts: 20.333333 pos:2277771 size:    84
+ret: 0         st: 0 flags:0  ts: 127.941667
+ret: 0         st: 0 flags:1 dts: 95.766667 pts: 95.800000 pos:10533174 size: 54642
+ret: 0         st: 0 flags:0 dts: 95.800000 pts: 95.833333 pos:10587816 size:   278
+ret: 0         st: 0 flags:0 dts: 95.833333 pts: 95.866667 pos:10588094 size:   101
+ret: 0         st: 0 flags:0 dts: 95.866667 pts: 95.900000 pos:10588195 size:    87
+ret: 0         st: 0 flags:1  ts: 50.835833
+ret: 0         st: 0 flags:1 dts: 50.633333 pts: 50.666667 pos:5856029 size: 67867
+ret: 0         st: 0 flags:0 dts: 50.666667 pts: 50.766667 pos:5923896 size:  1307
+ret: 0         st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5925203 size:   150
+ret: 0         st: 0 flags:0 dts: 50.733333 pts: 50.733333 pos:5925353 size:   176
+ret: 0         st:-1 flags:0  ts: 153.730004
+ret: 0         st: 0 flags:1 dts: 157.033333 pts: 157.066667 pos:16211536 size: 82702
+ret: 0         st: 0 flags:0 dts: 157.066667 pts: 157.166667 pos:16294238 size:  2273
+ret: 0         st: 0 flags:0 dts: 157.100000 pts: 157.100000 pos:16296511 size:   350
+ret: 0         st: 0 flags:0 dts: 157.133333 pts: 157.133333 pos:16296861 size:   337
+ret: 0         st:-1 flags:1  ts: 76.624171
+ret: 0         st: 0 flags:1 dts: 75.966667 pts: 76.000000 pos:8514981 size: 94359
+ret: 0         st: 0 flags:0 dts: 76.000000 pts: 76.100000 pos:8609340 size:   483
+ret: 0         st: 0 flags:0 dts: 76.033333 pts: 76.033333 pos:8609823 size:    37
+ret: 0         st: 0 flags:0 dts: 76.066667 pts: 76.066667 pos:8609860 size:    56
+ret: 0         st: 0 flags:0  ts:-0.481667
+ret: 0         st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos:   4174 size:   147
+ret: 0         st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos:   4321 size:    24
+ret: 0         st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos:   4345 size:  6779
+ret: 0         st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos:  11124 size: 11041
+ret: 0         st: 0 flags:1  ts: 102.412500
+ret: 0         st: 0 flags:1 dts: 101.300000 pts: 101.333333 pos:10974394 size: 67201
+ret: 0         st: 0 flags:0 dts: 101.333333 pts: 101.433333 pos:11041595 size:  3524
+ret: 0         st: 0 flags:0 dts: 101.366667 pts: 101.366667 pos:11045119 size:   562
+ret: 0         st: 0 flags:0 dts: 101.400000 pts: 101.400000 pos:11045681 size:   599
+ret: 0         st:-1 flags:0  ts: 25.306672
+ret: 0         st: 0 flags:1 dts: 27.400000 pts: 27.433333 pos:2674080 size:127347
+ret: 0         st: 0 flags:0 dts: 27.433333 pts: 27.466667 pos:2801427 size:    68
+ret: 0         st: 0 flags:0 dts: 27.466667 pts: 27.500000 pos:2801495 size:  1754
+ret: 0         st: 0 flags:0 dts: 27.500000 pts: 27.533333 pos:2803249 size:  4071
+ret: 0         st:-1 flags:1  ts: 128.200839
+ret: 0         st: 0 flags:1 dts: 127.833333 pts: 127.866667 pos:13502895 size: 67346
+ret: 0         st: 0 flags:0 dts: 127.866667 pts: 127.966667 pos:13570241 size:  2936
+ret: 0         st: 0 flags:0 dts: 127.900000 pts: 127.900000 pos:13573177 size:   451
+ret: 0         st: 0 flags:0 dts: 127.933333 pts: 127.933333 pos:13573628 size:   537
+ret: 0         st: 0 flags:0  ts: 51.095011
+ret: 0         st: 0 flags:1 dts: 52.066667 pts: 52.100000 pos:6025093 size:115773
+ret: 0         st: 0 flags:0 dts: 52.100000 pts: 52.200000 pos:6140866 size:  1620
+ret: 0         st: 0 flags:0 dts: 52.133333 pts: 52.133333 pos:6142486 size:    92
+ret: 0         st: 0 flags:0 dts: 52.166667 pts: 52.166667 pos:6142578 size:   533
+ret: 0         st: 0 flags:1  ts: 153.989178
+ret: 0         st: 0 flags:1 dts: 153.466667 pts: 153.500000 pos:15853683 size: 96133
+ret: 0         st: 0 flags:0 dts: 153.500000 pts: 153.533333 pos:15949816 size:   785
+ret: 0         st: 0 flags:0 dts: 153.533333 pts: 153.633333 pos:15950601 size:  3135
+ret: 0         st: 0 flags:0 dts: 153.566667 pts: 153.566667 pos:15953736 size:   859
+ret: 0         st:-1 flags:0  ts: 76.883340
+ret: 0         st: 0 flags:1 dts: 77.833333 pts: 77.866667 pos:8653728 size: 41146
+ret: 0         st: 0 flags:0 dts: 77.866667 pts: 77.966667 pos:8694874 size:  4197
+ret: 0         st: 0 flags:0 dts: 77.900000 pts: 77.900000 pos:8699071 size:   653
+ret: 0         st: 0 flags:0 dts: 77.933333 pts: 77.933333 pos:8699724 size:   751
+ret: 0         st:-1 flags:1  ts:-0.222493
+ret: 0         st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos:   4174 size:   147
+ret: 0         st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos:   4321 size:    24
+ret: 0         st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos:   4345 size:  6779
+ret: 0         st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos:  11124 size: 11041
+ret: 0         st: 0 flags:0  ts: 102.671678
+ret: 0         st: 0 flags:1 dts: 104.100000 pts: 104.133333 pos:11107176 size:112893
+ret: 0         st: 0 flags:0 dts: 104.133333 pts: 104.166667 pos:11220069 size:   585
+ret: 0         st: 0 flags:0 dts: 104.166667 pts: 104.200000 pos:11220654 size:   797
+ret: 0         st: 0 flags:0 dts: 104.200000 pts: 104.233333 pos:11221451 size:   810
+ret: 0         st: 0 flags:1  ts: 25.565844
+ret: 0         st: 0 flags:1 dts: 25.300000 pts: 25.333333 pos:2607665 size: 40237
+ret: 0         st: 0 flags:0 dts: 25.333333 pts: 25.433333 pos:2647902 size:  2959
+ret: 0         st: 0 flags:0 dts: 25.366667 pts: 25.366667 pos:2650861 size:   197
+ret: 0         st: 0 flags:0 dts: 25.400000 pts: 25.400000 pos:2651058 size:   230
+ret: 0         st:-1 flags:0  ts: 128.460008
+ret: 0         st: 0 flags:1 dts: 131.233333 pts: 131.266667 pos:13715044 size: 62193
+ret: 0         st: 0 flags:0 dts: 131.266667 pts: 131.366667 pos:13777237 size:  2349
+ret: 0         st: 0 flags:0 dts: 131.300000 pts: 131.300000 pos:13779586 size:   571
+ret: 0         st: 0 flags:0 dts: 131.333333 pts: 131.333333 pos:13780157 size:  1190
+ret: 0         st:-1 flags:1  ts: 51.354175
+ret: 0         st: 0 flags:1 dts: 50.633333 pts: 50.666667 pos:5856029 size: 67867
+ret: 0         st: 0 flags:0 dts: 50.666667 pts: 50.766667 pos:5923896 size:  1307
+ret: 0         st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5925203 size:   150
+ret: 0         st: 0 flags:0 dts: 50.733333 pts: 50.733333 pos:5925353 size:   176
-- 
2.14.0.rc1.383.gd1ce394fe2-goog