On 20.05.2015 02:00, Michael Niedermayer wrote:
> On Wed, May 20, 2015 at 12:49:49AM +0200, Andreas Cadhalpun wrote:
>> 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.
>>
>> Signed-off-by: Andreas Cadhalpun <andreas.cadhal...@googlemail.com>
>> ---
>>  libavformat/nut.h    | 1 +
>>  libavformat/nutdec.c | 3 ++-
>>  2 files changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavformat/nut.h b/libavformat/nut.h
>> index 943081c..0c678a5 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;
> 
> i think this and possibly some other fields must be reset on seeking
> otherwise resync after seeking could break

Attached patch resets last_resync_pos in read_seek.
I'm not sure if last_syncpoint_pos also has to be reset or if the
syncpoint handling at the end of read_seek is already enough.

Best regards,
Andreas

>From 0b000f4463cfb8d40571fd0620ec5f536296ea1b Mon Sep 17 00:00:00 2001
From: Andreas Cadhalpun <andreas.cadhal...@googlemail.com>
Date: Wed, 20 May 2015 00:06:05 +0200
Subject: [PATCH 1/3] 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.

Signed-off-by: Andreas Cadhalpun <andreas.cadhal...@googlemail.com>
---
 libavformat/nut.h    | 1 +
 libavformat/nutdec.c | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/nut.h b/libavformat/nut.h
index 943081c..0c678a5 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 2762db2..9b227c6 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -1124,7 +1124,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");
@@ -1224,6 +1225,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;
 }
 
-- 
2.1.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to