[FFmpeg-cvslog] avformat/mov: See if mfra makes up the difference for an incomplete sidx.

Dale Curtis git at videolan.org
Fri Aug 28 17:59:17 EEST 2020


ffmpeg | branch: master | Dale Curtis <dalecurtis at chromium.org> | Thu Aug 13 15:02:02 2020 -0700| [2ff3c466eca66bb8eb32bb41a4ce70fe285e3ea0] | committer: Derek Buitenhuis

avformat/mov: See if mfra makes up the difference for an incomplete sidx.

A few popular sites have started generating MP4 files which have a
sidx plus an mfra. The sidx accounts for all size except the mfra,
so the old code did not mark the fragment index as complete.

Instead we can just check if there's an mfra and if its size makes
up the difference we can mark the index as complete.

Bug: https://crbug.com/1107130
Signed-off-by: Dale Curtis <dalecurtis at chromium.org>
Signed-off-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2ff3c466eca66bb8eb32bb41a4ce70fe285e3ea0
---

 libavformat/mov.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 4c8598c992..dcec74662d 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -5017,8 +5017,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
+    int64_t stream_size = avio_size(pb);
     int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
-    uint8_t version;
+    uint8_t version, is_complete;
     unsigned i, j, track_id, item_count;
     AVStream *st = NULL;
     AVStream *ref_st = NULL;
@@ -5091,7 +5092,22 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     sc->has_sidx = 1;
 
-    if (offset == avio_size(pb)) {
+    // See if the remaining bytes are just an mfra which we can ignore.
+    is_complete = offset == stream_size;
+    if (!is_complete) {
+        int ret;
+        int64_t original_pos = avio_tell(pb);
+        int32_t mfra_size;
+        if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
+            return ret;
+        mfra_size = avio_rb32(pb);
+        if (offset + mfra_size == stream_size)
+            is_complete = 1;
+        if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
+            return ret;
+    }
+
+    if (is_complete) {
         // Find first entry in fragment index that came from an sidx.
         // This will pretty much always be the first entry.
         for (i = 0; i < c->frag_index.nb_items; i++) {



More information about the ffmpeg-cvslog mailing list