[FFmpeg-cvslog] avformat/mov: fix hang while seek on a kind of fragmented mp4
Charles Liu
git at videolan.org
Mon Feb 11 23:16:45 EET 2019
ffmpeg | branch: release/4.1 | Charles Liu <liuchh83 at gmail.com> | Sun Feb 3 23:09:06 2019 +0800| [53f3f5233f38aef0b544ebfbb2c450134aae0639] | committer: Marton Balint
avformat/mov: fix hang while seek on a kind of fragmented mp4
Binary searching would hang if the fragment items do NOT have timestamp for the
specified stream.
For example, a fmp4 consists of separated 'moof' boxes for each track, and
separated 'sidx' for each segment, but no 'mfra' box. Then every fragment item
only have the timestamp for one of its tracks.
Example:
ffmpeg -f lavfi -i testsrc -f lavfi -i sine -movflags dash+frag_keyframe+skip_trailer+separate_moof -t 1 out.mp4
ffmpeg -ss 0.5 -i out.mp4 -f null none
Also fixes the hang in ticket #7572, but not the reason for having
AV_NOPTS_VALUE timestamps there.
Signed-off-by: Charles Liu <liuchh83 at gmail.com>
Signed-off-by: Marton Balint <cus at passwd.hu>
(cherry picked from commit aa25198f1b925a464bdfa83a98476f08d26c9209)
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=53f3f5233f38aef0b544ebfbb2c450134aae0639
---
libavformat/mov.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 38c1d9b7eb..3491d680db 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1270,7 +1270,7 @@ static int64_t get_frag_time(MOVFragmentIndex *frag_index,
static int search_frag_timestamp(MOVFragmentIndex *frag_index,
AVStream *st, int64_t timestamp)
{
- int a, b, m;
+ int a, b, m, m0;
int64_t frag_time;
int id = -1;
@@ -1286,15 +1286,18 @@ static int search_frag_timestamp(MOVFragmentIndex *frag_index,
b = frag_index->nb_items;
while (b - a > 1) {
- m = (a + b) >> 1;
- frag_time = get_frag_time(frag_index, m, id);
- if (frag_time != AV_NOPTS_VALUE) {
- if (frag_time >= timestamp)
- b = m;
- if (frag_time <= timestamp)
- a = m;
- }
+ m0 = m = (a + b) >> 1;
+
+ while (m < b &&
+ (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
+ m++;
+
+ if (m < b && frag_time <= timestamp)
+ a = m;
+ else
+ b = m0;
}
+
return a;
}
More information about the ffmpeg-cvslog
mailing list