summaryrefslogtreecommitdiff
path: root/libavformat/wtvdec.c
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2014-08-29 16:42:04 +1000
committerMichael Niedermayer <michaelni@gmx.at>2014-08-29 14:00:58 +0200
commit9b8eedd736ea443c4829baaca1ede4e146ebc024 (patch)
tree12ddb81865d934da2f9be52126a1bfd003206bc1 /libavformat/wtvdec.c
parent72732f2dddabae1d943ce617e0a27e32d13416fb (diff)
downloadffmpeg-9b8eedd736ea443c4829baaca1ede4e146ebc024.tar.gz
avformat/wtvdec: seek over broken chunks
Fixes ticket #3898 Signed-off-by: Peter Ross <pross@xvid.org> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/wtvdec.c')
-rw-r--r--libavformat/wtvdec.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index c70057ce27..4cb3295464 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -751,6 +751,26 @@ enum {
};
/**
+ * Try to seek over a broken chunk
+ * @return <0 on error
+ */
+static int recover(WtvContext *wtv, uint64_t broken_pos)
+{
+ AVIOContext *pb = wtv->pb;
+ int i;
+ for (i = 0; i < wtv->nb_index_entries; i++) {
+ if (wtv->index_entries[i].pos > broken_pos) {
+ int ret = avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET);
+ if (ret < 0)
+ return ret;
+ wtv->pts = wtv->index_entries[i].timestamp;
+ return 0;
+ }
+ }
+ return AVERROR(EIO);
+}
+
+/**
* Parse WTV chunks
* @param mode SEEK_TO_DATA or SEEK_TO_PTS
* @param seekts timestamp
@@ -767,8 +787,13 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
ff_get_guid(pb, &g);
len = avio_rl32(pb);
- if (len < 32)
- break;
+ if (len < 32) {
+ int ret;
+ av_log(s, AV_LOG_WARNING, "encountered broken chunk\n");
+ if ((ret = recover(wtv, avio_tell(pb) - 20)) < 0)
+ return ret;
+ continue;
+ }
sid = avio_rl32(pb) & 0x7FFF;
avio_skip(pb, 8);
consumed = 32;