If resyncing leads to the same position as previously, it will again
lead to a resync attempt, resulting in an infinite loop.
Thus don't seek back beyond the last syncpoint.
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 6b8263b03ab3d16d70525ae1893cb106be7852f1)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -82,6 +82,7 @@ static int ffm_read_data(AVFormatContext *s, |
82 | 82 |
FFMContext *ffm = s->priv_data; |
83 | 83 |
AVIOContext *pb = s->pb; |
84 | 84 |
int len, fill_size, size1, frame_offset, id; |
85 |
+ int64_t last_pos = -1; |
|
85 | 86 |
|
86 | 87 |
size1 = size; |
87 | 88 |
while (size > 0) { |
... | ... |
@@ -101,9 +102,11 @@ static int ffm_read_data(AVFormatContext *s, |
101 | 101 |
avio_seek(pb, tell, SEEK_SET); |
102 | 102 |
} |
103 | 103 |
id = avio_rb16(pb); /* PACKET_ID */ |
104 |
- if (id != PACKET_ID) |
|
104 |
+ if (id != PACKET_ID) { |
|
105 | 105 |
if (ffm_resync(s, id) < 0) |
106 | 106 |
return -1; |
107 |
+ last_pos = avio_tell(pb); |
|
108 |
+ } |
|
107 | 109 |
fill_size = avio_rb16(pb); |
108 | 110 |
ffm->dts = avio_rb64(pb); |
109 | 111 |
frame_offset = avio_rb16(pb); |
... | ... |
@@ -117,7 +120,9 @@ static int ffm_read_data(AVFormatContext *s, |
117 | 117 |
if (!frame_offset) { |
118 | 118 |
/* This packet has no frame headers in it */ |
119 | 119 |
if (avio_tell(pb) >= ffm->packet_size * 3LL) { |
120 |
- avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR); |
|
120 |
+ int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos); |
|
121 |
+ seekback = FFMAX(seekback, 0); |
|
122 |
+ avio_seek(pb, -seekback, SEEK_CUR); |
|
121 | 123 |
goto retry_read; |
122 | 124 |
} |
123 | 125 |
/* This is bad, we cannot find a valid frame header */ |