Browse Source

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 37e679881d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
tags/n2.4.10
Andreas Cadhalpun Michael Niedermayer 10 years ago
parent
commit
936a5dd2c5
2 changed files with 5 additions and 1 deletions
  1. +1
    -0
      libavformat/nut.h
  2. +4
    -1
      libavformat/nutdec.c

+ 1
- 0
libavformat/nut.h View 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;


+ 4
- 1
libavformat/nutdec.c View File

@@ -1129,7 +1129,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");
@@ -1230,6 +1231,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;
}



Loading…
Cancel
Save