]> git.sesse.net Git - ffmpeg/commitdiff
nutdec: fix infinite resync loops
authorAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Tue, 19 May 2015 22:06:05 +0000 (00:06 +0200)
committerAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Wed, 20 May 2015 17:07:26 +0000 (19:07 +0200)
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>
libavformat/nut.h
libavformat/nutdec.c

index 943081caf6f5304958ab846b6282849eff7625d0..0c678a51b99723c6db053b056755509f51a62552 100644 (file)
@@ -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;
index afe19ffa75609c1d1a12cd3b9176747e1902db41..6742ee9bdfdc127091876665d7cffce20068869a 100644 (file)
@@ -1126,7 +1126,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");
@@ -1227,6 +1228,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;
 }