diff options
author | Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> | 2015-05-20 01:06:05 +0300 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2015-07-20 05:43:39 +0300 |
commit | d4d8c3553d086fd8755d7535367b2e6a8dbb41af (patch) | |
tree | 2366b3c897f66f0342de14e5272c0f01b0cd5a5d | |
parent | bd9313d9f840ea4d96b36547e42014f0fba6cfa8 (diff) |
nutdec: fix infinite resync loops
nut->last_syncpoint_pos doesn't necessarily change between resync
attempts, so find_any_startcode can return the same startcode again.
Thus remember where the last resync happened and don't try to resync
before that.
This can't be done locally in nut_read_packet, because this wouldn't
prevent infinite resync loops, where after the resync a packet is
returned and while reading a following packet the resync happens again.
Reviewed-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
(cherry picked from commit 37e679881d364b6da817d829d35869d657218ab3)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavformat/nut.h | 1 | ||||
-rw-r--r-- | libavformat/nutdec.c | 5 |
2 files changed, 5 insertions, 1 deletions
diff --git a/libavformat/nut.h b/libavformat/nut.h index 943081caf6..0c678a51b9 100644 --- a/libavformat/nut.h +++ b/libavformat/nut.h @@ -102,6 +102,7 @@ typedef struct NUTContext { unsigned int max_distance; unsigned int time_base_count; int64_t last_syncpoint_pos; + int64_t last_resync_pos; int header_count; AVRational *time_base; struct AVTreeNode *syncpoints; diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 596dd5c608..eb86c2d15e 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -1119,7 +1119,8 @@ static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) default: resync: av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos); - tmp = find_any_startcode(bc, nut->last_syncpoint_pos + 1); + tmp = find_any_startcode(bc, FFMAX(nut->last_syncpoint_pos, nut->last_resync_pos) + 1); + nut->last_resync_pos = avio_tell(bc); if (tmp == 0) return AVERROR_INVALIDDATA; av_log(s, AV_LOG_DEBUG, "sync\n"); @@ -1220,6 +1221,8 @@ static int read_seek(AVFormatContext *s, int stream_index, for (i = 0; i < s->nb_streams; i++) nut->stream[i].skip_until_key_frame = 1; + nut->last_resync_pos = 0; + return 0; } |