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>
... | ... |
@@ -77,6 +77,7 @@ static int ffm_read_data(AVFormatContext *s, |
77 | 77 |
FFMContext *ffm = s->priv_data; |
78 | 78 |
AVIOContext *pb = s->pb; |
79 | 79 |
int len, fill_size, size1, frame_offset, id; |
80 |
+ int64_t last_pos = -1; |
|
80 | 81 |
|
81 | 82 |
size1 = size; |
82 | 83 |
while (size > 0) { |
... | ... |
@@ -96,9 +97,11 @@ static int ffm_read_data(AVFormatContext *s, |
96 | 96 |
avio_seek(pb, tell, SEEK_SET); |
97 | 97 |
} |
98 | 98 |
id = avio_rb16(pb); /* PACKET_ID */ |
99 |
- if (id != PACKET_ID) |
|
99 |
+ if (id != PACKET_ID) { |
|
100 | 100 |
if (ffm_resync(s, id) < 0) |
101 | 101 |
return -1; |
102 |
+ last_pos = avio_tell(pb); |
|
103 |
+ } |
|
102 | 104 |
fill_size = avio_rb16(pb); |
103 | 105 |
ffm->dts = avio_rb64(pb); |
104 | 106 |
frame_offset = avio_rb16(pb); |
... | ... |
@@ -112,7 +115,9 @@ static int ffm_read_data(AVFormatContext *s, |
112 | 112 |
if (!frame_offset) { |
113 | 113 |
/* This packet has no frame headers in it */ |
114 | 114 |
if (avio_tell(pb) >= ffm->packet_size * 3LL) { |
115 |
- avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR); |
|
115 |
+ int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos); |
|
116 |
+ seekback = FFMAX(seekback, 0); |
|
117 |
+ avio_seek(pb, -seekback, SEEK_CUR); |
|
116 | 118 |
goto retry_read; |
117 | 119 |
} |
118 | 120 |
/* This is bad, we cannot find a valid frame header */ |