aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mov.c
diff options
context:
space:
mode:
authorCharles Liu <liuchh83@gmail.com>2019-02-03 23:09:06 +0800
committerMarton Balint <cus@passwd.hu>2019-02-11 22:01:06 +0100
commitaa25198f1b925a464bdfa83a98476f08d26c9209 (patch)
tree8ffbd7988eb92177d25d3abaa3086c2ac194f1d2 /libavformat/mov.c
parent00fd38f1846a3c889b6ec645107eaea415b99840 (diff)
downloadffmpeg-aa25198f1b925a464bdfa83a98476f08d26c9209.tar.gz
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@gmail.com> Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r--libavformat/mov.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index d889c26b78..73a5ec240e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1266,7 +1266,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;
@@ -1282,15 +1282,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;
}