]> granicus.if.org Git - handbrake/commitdiff
libav: gracefully handle a broken AVI index
authorJohn Stebbins <jstebbins.hb@gmail.com>
Mon, 27 Feb 2017 19:01:35 +0000 (12:01 -0700)
committerJohn Stebbins <jstebbins.hb@gmail.com>
Mon, 27 Feb 2017 19:02:42 +0000 (12:02 -0700)
Fixes https://github.com/HandBrake/HandBrake/issues/439

(cherry picked from commit 40b86f9ad509db29be0babb335e96f62b0b1c230)

contrib/ffmpeg/A18-avi-broken-index.patch [new file with mode: 0644]

diff --git a/contrib/ffmpeg/A18-avi-broken-index.patch b/contrib/ffmpeg/A18-avi-broken-index.patch
new file mode 100644 (file)
index 0000000..281a0b6
--- /dev/null
@@ -0,0 +1,42 @@
+From c03b7f91b1ae407cb777ff4d18a8513c0030bf57 Mon Sep 17 00:00:00 2001
+From: John Stebbins <stebbins@jetheaddev.com>
+Date: Mon, 27 Feb 2017 11:53:11 -0700
+Subject: [PATCH] avidec: handle broken AVI index better
+
+A broken index that causes non-interleaved access and has a packet size
+of 0 causes an infinite loop reading 0 bytes.  Switch to assuming file
+is interleaved if a broken index is detected.
+---
+ libavformat/avidec.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/libavformat/avidec.c b/libavformat/avidec.c
+index 870066e..a44ad87 100644
+--- a/libavformat/avidec.c
++++ b/libavformat/avidec.c
+@@ -1146,7 +1146,6 @@ static int ni_prepare_read(AVFormatContext *s)
+     if (i >= 0) {
+         int64_t pos = best_st->index_entries[i].pos;
+         pos += best_ast->packet_size - best_ast->remaining;
+-        avio_seek(s->pb, pos + 8, SEEK_SET);
+         assert(best_ast->remaining <= best_ast->packet_size);
+@@ -1154,6 +1153,14 @@ static int ni_prepare_read(AVFormatContext *s)
+         if (!best_ast->remaining)
+             best_ast->packet_size =
+             best_ast->remaining   = best_st->index_entries[i].size;
++        if (!best_ast->remaining) {
++            /* broken index, assume the rest is non-interleaved */
++            av_log(s, AV_LOG_ERROR, "Broken AVI index.\n");
++            avi->stream_index = -1;
++            avi->non_interleaved = 0;
++        } else {
++            avio_seek(s->pb, pos + 8, SEEK_SET);
++        }
+     }
+     return 0;
+-- 
+2.9.3
+