Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Seeking and index-related functions | ||
3 | * Copyright (c) 2000, 2001, 2002 Fabrice Bellard | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include <stdint.h> | ||
23 | |||
24 | #include "libavutil/avassert.h" | ||
25 | #include "libavutil/mathematics.h" | ||
26 | #include "libavutil/mem.h" | ||
27 | #include "libavutil/timestamp.h" | ||
28 | |||
29 | #include "libavcodec/avcodec.h" | ||
30 | |||
31 | #include "avformat.h" | ||
32 | #include "avio_internal.h" | ||
33 | #include "demux.h" | ||
34 | #include "internal.h" | ||
35 | |||
36 | 1261 | void avpriv_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) | |
37 | { | ||
38 |
2/2✓ Branch 0 taken 1565 times.
✓ Branch 1 taken 1261 times.
|
2826 | for (unsigned i = 0; i < s->nb_streams; i++) { |
39 | 1565 | AVStream *const st = s->streams[i]; | |
40 | 1565 | FFStream *const sti = ffstream(st); | |
41 | |||
42 | 1565 | sti->cur_dts = | |
43 | 1565 | av_rescale(timestamp, | |
44 | 1565 | st->time_base.den * (int64_t) ref_st->time_base.num, | |
45 | 1565 | st->time_base.num * (int64_t) ref_st->time_base.den); | |
46 | } | ||
47 | 1261 | } | |
48 | |||
49 | 243425 | void ff_reduce_index(AVFormatContext *s, int stream_index) | |
50 | { | ||
51 | 243425 | AVStream *const st = s->streams[stream_index]; | |
52 | 243425 | FFStream *const sti = ffstream(st); | |
53 | 243425 | unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry); | |
54 | |||
55 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 243425 times.
|
243425 | if ((unsigned) sti->nb_index_entries >= max_entries) { |
56 | int i; | ||
57 | ✗ | for (i = 0; 2 * i < sti->nb_index_entries; i++) | |
58 | ✗ | sti->index_entries[i] = sti->index_entries[2 * i]; | |
59 | ✗ | sti->nb_index_entries = i; | |
60 | } | ||
61 | 243425 | } | |
62 | |||
63 | 297790 | int ff_add_index_entry(AVIndexEntry **index_entries, | |
64 | int *nb_index_entries, | ||
65 | unsigned int *index_entries_allocated_size, | ||
66 | int64_t pos, int64_t timestamp, | ||
67 | int size, int distance, int flags) | ||
68 | { | ||
69 | AVIndexEntry *entries, *ie; | ||
70 | int index; | ||
71 | |||
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 297790 times.
|
297790 | if ((unsigned) *nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) |
73 | ✗ | return -1; | |
74 | |||
75 |
2/2✓ Branch 0 taken 3428 times.
✓ Branch 1 taken 294362 times.
|
297790 | if (timestamp == AV_NOPTS_VALUE) |
76 | 3428 | return AVERROR(EINVAL); | |
77 | |||
78 |
2/4✓ Branch 0 taken 294362 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 294362 times.
|
294362 | if (size < 0 || size > 0x3FFFFFFF) |
79 | ✗ | return AVERROR(EINVAL); | |
80 | |||
81 |
2/2✓ Branch 1 taken 105784 times.
✓ Branch 2 taken 188578 times.
|
294362 | if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known |
82 | 105784 | timestamp -= RELATIVE_TS_BASE; | |
83 | |||
84 | 294362 | entries = av_fast_realloc(*index_entries, | |
85 | index_entries_allocated_size, | ||
86 | 294362 | (*nb_index_entries + 1) * | |
87 | sizeof(AVIndexEntry)); | ||
88 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 294362 times.
|
294362 | if (!entries) |
89 | ✗ | return -1; | |
90 | |||
91 | 294362 | *index_entries = entries; | |
92 | |||
93 | 294362 | index = ff_index_search_timestamp(*index_entries, *nb_index_entries, | |
94 | timestamp, AVSEEK_FLAG_ANY); | ||
95 |
2/2✓ Branch 0 taken 207527 times.
✓ Branch 1 taken 86835 times.
|
294362 | if (index < 0) { |
96 | 207527 | index = (*nb_index_entries)++; | |
97 | 207527 | ie = &entries[index]; | |
98 |
3/4✓ Branch 0 taken 202028 times.
✓ Branch 1 taken 5499 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 202028 times.
|
207527 | av_assert0(index == 0 || ie[-1].timestamp < timestamp); |
99 | } else { | ||
100 | 86835 | ie = &entries[index]; | |
101 |
2/2✓ Branch 0 taken 657 times.
✓ Branch 1 taken 86178 times.
|
86835 | if (ie->timestamp != timestamp) { |
102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 657 times.
|
657 | if (ie->timestamp <= timestamp) |
103 | ✗ | return -1; | |
104 | 657 | memmove(entries + index + 1, entries + index, | |
105 | 657 | sizeof(AVIndexEntry) * (*nb_index_entries - index)); | |
106 | 657 | (*nb_index_entries)++; | |
107 |
4/4✓ Branch 0 taken 85747 times.
✓ Branch 1 taken 431 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 85745 times.
|
86178 | } else if (ie->pos == pos && distance < ie->min_distance) |
108 | // do not reduce the distance | ||
109 | 2 | distance = ie->min_distance; | |
110 | } | ||
111 | |||
112 | 294362 | ie->pos = pos; | |
113 | 294362 | ie->timestamp = timestamp; | |
114 | 294362 | ie->min_distance = distance; | |
115 | 294362 | ie->size = size; | |
116 | 294362 | ie->flags = flags; | |
117 | |||
118 | 294362 | return index; | |
119 | } | ||
120 | |||
121 | 297473 | int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, | |
122 | int size, int distance, int flags) | ||
123 | { | ||
124 | 297473 | FFStream *const sti = ffstream(st); | |
125 | 297473 | timestamp = ff_wrap_timestamp(st, timestamp); | |
126 | 297473 | return ff_add_index_entry(&sti->index_entries, &sti->nb_index_entries, | |
127 | &sti->index_entries_allocated_size, pos, | ||
128 | timestamp, size, distance, flags); | ||
129 | } | ||
130 | |||
131 | 327605 | int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries, | |
132 | int64_t wanted_timestamp, int flags) | ||
133 | { | ||
134 | int a, b, m; | ||
135 | int64_t timestamp; | ||
136 | |||
137 | 327605 | a = -1; | |
138 | 327605 | b = nb_entries; | |
139 | |||
140 | // Optimize appending index entries at the end. | ||
141 |
4/4✓ Branch 0 taken 319405 times.
✓ Branch 1 taken 8200 times.
✓ Branch 2 taken 206090 times.
✓ Branch 3 taken 113315 times.
|
327605 | if (b && entries[b - 1].timestamp < wanted_timestamp) |
142 | 206090 | a = b - 1; | |
143 | |||
144 |
2/2✓ Branch 0 taken 682184 times.
✓ Branch 1 taken 327605 times.
|
1009789 | while (b - a > 1) { |
145 | 682184 | m = (a + b) >> 1; | |
146 | |||
147 | // Search for the next non-discarded packet. | ||
148 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 682184 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
682184 | while ((entries[m].flags & AVINDEX_DISCARD_FRAME) && m < b && m < nb_entries - 1) { |
149 | ✗ | m++; | |
150 | ✗ | if (m == b && entries[m].timestamp >= wanted_timestamp) { | |
151 | ✗ | m = b - 1; | |
152 | ✗ | break; | |
153 | } | ||
154 | } | ||
155 | |||
156 | 682184 | timestamp = entries[m].timestamp; | |
157 |
2/2✓ Branch 0 taken 216469 times.
✓ Branch 1 taken 465715 times.
|
682184 | if (timestamp >= wanted_timestamp) |
158 | 216469 | b = m; | |
159 |
2/2✓ Branch 0 taken 575402 times.
✓ Branch 1 taken 106782 times.
|
682184 | if (timestamp <= wanted_timestamp) |
160 | 575402 | a = m; | |
161 | } | ||
162 |
2/2✓ Branch 0 taken 8227 times.
✓ Branch 1 taken 319378 times.
|
327605 | m = (flags & AVSEEK_FLAG_BACKWARD) ? a : b; |
163 | |||
164 |
2/2✓ Branch 0 taken 9966 times.
✓ Branch 1 taken 317639 times.
|
327605 | if (!(flags & AVSEEK_FLAG_ANY)) |
165 |
4/4✓ Branch 0 taken 9541 times.
✓ Branch 1 taken 2990 times.
✓ Branch 2 taken 8432 times.
✓ Branch 3 taken 1109 times.
|
12531 | while (m >= 0 && m < nb_entries && |
166 |
2/2✓ Branch 0 taken 2565 times.
✓ Branch 1 taken 5867 times.
|
8432 | !(entries[m].flags & AVINDEX_KEYFRAME)) |
167 |
2/2✓ Branch 0 taken 1617 times.
✓ Branch 1 taken 948 times.
|
2565 | m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1; |
168 | |||
169 |
2/2✓ Branch 0 taken 208749 times.
✓ Branch 1 taken 118856 times.
|
327605 | if (m == nb_entries) |
170 | 208749 | return -1; | |
171 | 118856 | return m; | |
172 | } | ||
173 | |||
174 | 475 | void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) | |
175 | { | ||
176 | 475 | int64_t pos_delta = 0; | |
177 | 475 | int64_t skip = 0; | |
178 | //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable | ||
179 | 475 | const char *proto = avio_find_protocol_name(s->url); | |
180 | FFIOContext *ctx; | ||
181 | |||
182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
|
475 | av_assert0(time_tolerance >= 0); |
183 | |||
184 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
|
475 | if (!proto) { |
185 | ✗ | av_log(s, AV_LOG_INFO, | |
186 | "Protocol name not provided, cannot determine if input is local or " | ||
187 | "a network protocol, buffers and access patterns cannot be configured " | ||
188 | "optimally without knowing the protocol\n"); | ||
189 | } | ||
190 | |||
191 |
2/8✓ Branch 0 taken 475 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 475 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
475 | if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache"))) |
192 | 475 | return; | |
193 | |||
194 | ✗ | for (unsigned ist1 = 0; ist1 < s->nb_streams; ist1++) { | |
195 | ✗ | AVStream *const st1 = s->streams[ist1]; | |
196 | ✗ | FFStream *const sti1 = ffstream(st1); | |
197 | ✗ | for (unsigned ist2 = 0; ist2 < s->nb_streams; ist2++) { | |
198 | ✗ | AVStream *const st2 = s->streams[ist2]; | |
199 | ✗ | FFStream *const sti2 = ffstream(st2); | |
200 | |||
201 | ✗ | if (ist1 == ist2) | |
202 | ✗ | continue; | |
203 | |||
204 | ✗ | for (int i1 = 0, i2 = 0; i1 < sti1->nb_index_entries; i1++) { | |
205 | ✗ | const AVIndexEntry *const e1 = &sti1->index_entries[i1]; | |
206 | ✗ | int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q); | |
207 | |||
208 | ✗ | if (e1->size < (1 << 23)) | |
209 | ✗ | skip = FFMAX(skip, e1->size); | |
210 | |||
211 | ✗ | for (; i2 < sti2->nb_index_entries; i2++) { | |
212 | ✗ | const AVIndexEntry *const e2 = &sti2->index_entries[i2]; | |
213 | ✗ | int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q); | |
214 | int64_t cur_delta; | ||
215 | ✗ | if (e2_pts < e1_pts || e2_pts - (uint64_t)e1_pts < time_tolerance) | |
216 | ✗ | continue; | |
217 | ✗ | cur_delta = FFABS(e1->pos - e2->pos); | |
218 | ✗ | if (cur_delta < (1 << 23)) | |
219 | ✗ | pos_delta = FFMAX(pos_delta, cur_delta); | |
220 | ✗ | break; | |
221 | } | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | ✗ | pos_delta *= 2; | |
227 | ✗ | ctx = ffiocontext(s->pb); | |
228 | /* XXX This could be adjusted depending on protocol*/ | ||
229 | ✗ | if (s->pb->buffer_size < pos_delta) { | |
230 | ✗ | av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta); | |
231 | |||
232 | /* realloc the buffer and the original data will be retained */ | ||
233 | ✗ | if (ffio_realloc_buf(s->pb, pos_delta)) { | |
234 | ✗ | av_log(s, AV_LOG_ERROR, "Realloc buffer fail.\n"); | |
235 | ✗ | return; | |
236 | } | ||
237 | |||
238 | ✗ | ctx->short_seek_threshold = FFMAX(ctx->short_seek_threshold, pos_delta/2); | |
239 | } | ||
240 | |||
241 | ✗ | ctx->short_seek_threshold = FFMAX(ctx->short_seek_threshold, skip); | |
242 | } | ||
243 | |||
244 | 33163 | int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags) | |
245 | { | ||
246 | 33163 | const FFStream *const sti = ffstream(st); | |
247 | 33163 | return ff_index_search_timestamp(sti->index_entries, sti->nb_index_entries, | |
248 | wanted_timestamp, flags); | ||
249 | } | ||
250 | |||
251 | ✗ | int avformat_index_get_entries_count(const AVStream *st) | |
252 | { | ||
253 | ✗ | return cffstream(st)->nb_index_entries; | |
254 | } | ||
255 | |||
256 | ✗ | const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx) | |
257 | { | ||
258 | ✗ | const FFStream *const sti = ffstream(st); | |
259 | ✗ | if (idx < 0 || idx >= sti->nb_index_entries) | |
260 | ✗ | return NULL; | |
261 | |||
262 | ✗ | return &sti->index_entries[idx]; | |
263 | } | ||
264 | |||
265 | ✗ | const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream *st, | |
266 | int64_t wanted_timestamp, | ||
267 | int flags) | ||
268 | { | ||
269 | ✗ | const FFStream *const sti = ffstream(st); | |
270 | ✗ | int idx = ff_index_search_timestamp(sti->index_entries, | |
271 | ✗ | sti->nb_index_entries, | |
272 | wanted_timestamp, flags); | ||
273 | |||
274 | ✗ | if (idx < 0) | |
275 | ✗ | return NULL; | |
276 | |||
277 | ✗ | return &sti->index_entries[idx]; | |
278 | } | ||
279 | |||
280 | 818 | static int64_t read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit, | |
281 | int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) | ||
282 | { | ||
283 | 818 | int64_t ts = read_timestamp(s, stream_index, ppos, pos_limit); | |
284 |
1/2✓ Branch 0 taken 818 times.
✗ Branch 1 not taken.
|
818 | if (stream_index >= 0) |
285 | 818 | ts = ff_wrap_timestamp(s->streams[stream_index], ts); | |
286 | 818 | return ts; | |
287 | } | ||
288 | |||
289 | 206 | int ff_seek_frame_binary(AVFormatContext *s, int stream_index, | |
290 | int64_t target_ts, int flags) | ||
291 | { | ||
292 | 206 | const FFInputFormat *const avif = ffifmt(s->iformat); | |
293 | 206 | int64_t pos_min = 0, pos_max = 0, pos, pos_limit; | |
294 | int64_t ts_min, ts_max, ts; | ||
295 | int index; | ||
296 | int64_t ret; | ||
297 | AVStream *st; | ||
298 | FFStream *sti; | ||
299 | |||
300 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 206 times.
|
206 | if (stream_index < 0) |
301 | ✗ | return -1; | |
302 | |||
303 | 206 | av_log(s, AV_LOG_TRACE, "read_seek: %d %s\n", stream_index, av_ts2str(target_ts)); | |
304 | |||
305 | 206 | ts_max = | |
306 | 206 | ts_min = AV_NOPTS_VALUE; | |
307 | 206 | pos_limit = -1; // GCC falsely says it may be uninitialized. | |
308 | |||
309 | 206 | st = s->streams[stream_index]; | |
310 | 206 | sti = ffstream(st); | |
311 |
2/2✓ Branch 0 taken 197 times.
✓ Branch 1 taken 9 times.
|
206 | if (sti->index_entries) { |
312 | const AVIndexEntry *e; | ||
313 | |||
314 | /* FIXME: Whole function must be checked for non-keyframe entries in | ||
315 | * index case, especially read_timestamp(). */ | ||
316 | 197 | index = av_index_search_timestamp(st, target_ts, | |
317 | flags | AVSEEK_FLAG_BACKWARD); | ||
318 | 197 | index = FFMAX(index, 0); | |
319 | 197 | e = &sti->index_entries[index]; | |
320 | |||
321 |
3/4✓ Branch 0 taken 71 times.
✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
|
197 | if (e->timestamp <= target_ts || e->pos == e->min_distance) { |
322 | 126 | pos_min = e->pos; | |
323 | 126 | ts_min = e->timestamp; | |
324 | 126 | av_log(s, AV_LOG_TRACE, "using cached pos_min=0x%"PRIx64" dts_min=%s\n", | |
325 | 126 | pos_min, av_ts2str(ts_min)); | |
326 | } else { | ||
327 | av_assert1(index == 0); | ||
328 | } | ||
329 | |||
330 | 197 | index = av_index_search_timestamp(st, target_ts, | |
331 | flags & ~AVSEEK_FLAG_BACKWARD); | ||
332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
|
197 | av_assert0(index < sti->nb_index_entries); |
333 |
2/2✓ Branch 0 taken 124 times.
✓ Branch 1 taken 73 times.
|
197 | if (index >= 0) { |
334 | 124 | e = &sti->index_entries[index]; | |
335 | av_assert1(e->timestamp >= target_ts); | ||
336 | 124 | pos_max = e->pos; | |
337 | 124 | ts_max = e->timestamp; | |
338 | 124 | pos_limit = pos_max - e->min_distance; | |
339 | 124 | av_log(s, AV_LOG_TRACE, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64 | |
340 | 124 | " dts_max=%s\n", pos_max, pos_limit, av_ts2str(ts_max)); | |
341 | } | ||
342 | } | ||
343 | |||
344 | 206 | pos = ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, | |
345 | 206 | ts_min, ts_max, flags, &ts, avif->read_timestamp); | |
346 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 204 times.
|
206 | if (pos < 0) |
347 | 2 | return -1; | |
348 | |||
349 | /* do the seek */ | ||
350 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
|
204 | if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0) |
351 | ✗ | return ret; | |
352 | |||
353 | 204 | ff_read_frame_flush(s); | |
354 | 204 | avpriv_update_cur_dts(s, st, ts); | |
355 | |||
356 | 204 | return 0; | |
357 | } | ||
358 | |||
359 | 81 | int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos, | |
360 | int64_t (*read_timestamp_func)(struct AVFormatContext *, int , int64_t *, int64_t )) | ||
361 | { | ||
362 | 81 | int64_t step = 1024; | |
363 | int64_t limit, ts_max; | ||
364 | 81 | int64_t filesize = avio_size(s->pb); | |
365 | 81 | int64_t pos_max = filesize - 1; | |
366 | do { | ||
367 | 353 | limit = pos_max; | |
368 | 353 | pos_max = FFMAX(0, (pos_max) - step); | |
369 | 353 | ts_max = read_timestamp(s, stream_index, | |
370 | &pos_max, limit, read_timestamp_func); | ||
371 | 353 | step += step; | |
372 |
3/4✓ Branch 0 taken 272 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
|
353 | } while (ts_max == AV_NOPTS_VALUE && 2*limit > step); |
373 |
1/2✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
|
81 | if (ts_max == AV_NOPTS_VALUE) |
374 | ✗ | return -1; | |
375 | |||
376 | 61 | for (;;) { | |
377 | 142 | int64_t tmp_pos = pos_max + 1; | |
378 | 142 | int64_t tmp_ts = read_timestamp(s, stream_index, | |
379 | &tmp_pos, INT64_MAX, read_timestamp_func); | ||
380 |
2/2✓ Branch 0 taken 81 times.
✓ Branch 1 taken 61 times.
|
142 | if (tmp_ts == AV_NOPTS_VALUE) |
381 | 81 | break; | |
382 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
|
61 | av_assert0(tmp_pos > pos_max); |
383 | 61 | ts_max = tmp_ts; | |
384 | 61 | pos_max = tmp_pos; | |
385 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
|
61 | if (tmp_pos >= filesize) |
386 | ✗ | break; | |
387 | } | ||
388 | |||
389 |
1/2✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
|
81 | if (ts) |
390 | 81 | *ts = ts_max; | |
391 |
1/2✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
|
81 | if (pos) |
392 | 81 | *pos = pos_max; | |
393 | |||
394 | 81 | return 0; | |
395 | } | ||
396 | |||
397 | 206 | int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, | |
398 | int64_t pos_min, int64_t pos_max, int64_t pos_limit, | ||
399 | int64_t ts_min, int64_t ts_max, | ||
400 | int flags, int64_t *ts_ret, | ||
401 | int64_t (*read_timestamp_func)(struct AVFormatContext *, | ||
402 | int, int64_t *, int64_t)) | ||
403 | { | ||
404 | 206 | FFFormatContext *const si = ffformatcontext(s); | |
405 | int64_t pos, ts; | ||
406 | int64_t start_pos; | ||
407 | int no_change; | ||
408 | int ret; | ||
409 | |||
410 | 206 | av_log(s, AV_LOG_TRACE, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts)); | |
411 | |||
412 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 126 times.
|
206 | if (ts_min == AV_NOPTS_VALUE) { |
413 | 80 | pos_min = si->data_offset; | |
414 | 80 | ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp_func); | |
415 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
|
80 | if (ts_min == AV_NOPTS_VALUE) |
416 | ✗ | return -1; | |
417 | } | ||
418 | |||
419 |
2/2✓ Branch 0 taken 71 times.
✓ Branch 1 taken 135 times.
|
206 | if (ts_min >= target_ts) { |
420 | 71 | *ts_ret = ts_min; | |
421 | 71 | return pos_min; | |
422 | } | ||
423 | |||
424 |
2/2✓ Branch 0 taken 81 times.
✓ Branch 1 taken 54 times.
|
135 | if (ts_max == AV_NOPTS_VALUE) { |
425 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
|
81 | if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp_func)) < 0) |
426 | ✗ | return ret; | |
427 | 81 | pos_limit = pos_max; | |
428 | } | ||
429 | |||
430 |
2/2✓ Branch 0 taken 71 times.
✓ Branch 1 taken 64 times.
|
135 | if (ts_max <= target_ts) { |
431 | 71 | *ts_ret = ts_max; | |
432 | 71 | return pos_max; | |
433 | } | ||
434 | |||
435 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | av_assert0(ts_min < ts_max); |
436 | |||
437 | 64 | no_change = 0; | |
438 |
2/2✓ Branch 0 taken 243 times.
✓ Branch 1 taken 62 times.
|
305 | while (pos_min < pos_limit) { |
439 | 243 | av_log(s, AV_LOG_TRACE, | |
440 | "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n", | ||
441 | 243 | pos_min, pos_max, av_ts2str(ts_min), av_ts2str(ts_max)); | |
442 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 243 times.
|
243 | av_assert0(pos_limit <= pos_max); |
443 | |||
444 |
2/2✓ Branch 0 taken 141 times.
✓ Branch 1 taken 102 times.
|
243 | if (no_change == 0) { |
445 | 141 | int64_t approximate_keyframe_distance = pos_max - pos_limit; | |
446 | // interpolate position (better than dichotomy) | ||
447 | 141 | pos = av_rescale(target_ts - ts_min, pos_max - pos_min, | |
448 | 141 | ts_max - ts_min) + | |
449 | 141 | pos_min - approximate_keyframe_distance; | |
450 |
2/2✓ Branch 0 taken 62 times.
✓ Branch 1 taken 40 times.
|
102 | } else if (no_change == 1) { |
451 | // bisection if interpolation did not change min / max pos last time | ||
452 | 62 | pos = (pos_min + pos_limit) >> 1; | |
453 | } else { | ||
454 | /* linear search if bisection failed, can only happen if there | ||
455 | * are very few or no keyframes between min/max */ | ||
456 | 40 | pos = pos_min; | |
457 | } | ||
458 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 183 times.
|
243 | if (pos <= pos_min) |
459 | 60 | pos = pos_min + 1; | |
460 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
|
183 | else if (pos > pos_limit) |
461 | ✗ | pos = pos_limit; | |
462 | 243 | start_pos = pos; | |
463 | |||
464 | // May pass pos_limit instead of -1. | ||
465 | 243 | ts = read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp_func); | |
466 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 83 times.
|
243 | if (pos == pos_max) |
467 | 160 | no_change++; | |
468 | else | ||
469 | 83 | no_change = 0; | |
470 | 243 | av_log(s, AV_LOG_TRACE, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s" | |
471 | " target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n", | ||
472 | pos_min, pos, pos_max, | ||
473 | 243 | av_ts2str(ts_min), av_ts2str(ts), av_ts2str(ts_max), av_ts2str(target_ts), | |
474 | pos_limit, start_pos, no_change); | ||
475 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 241 times.
|
243 | if (ts == AV_NOPTS_VALUE) { |
476 | 2 | av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n"); | |
477 | 2 | return -1; | |
478 | } | ||
479 |
2/2✓ Branch 0 taken 199 times.
✓ Branch 1 taken 42 times.
|
241 | if (target_ts <= ts) { |
480 | 199 | pos_limit = start_pos - 1; | |
481 | 199 | pos_max = pos; | |
482 | 199 | ts_max = ts; | |
483 | } | ||
484 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 197 times.
|
241 | if (target_ts >= ts) { |
485 | 44 | pos_min = pos; | |
486 | 44 | ts_min = ts; | |
487 | } | ||
488 | } | ||
489 | |||
490 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
|
62 | pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; |
491 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
|
62 | ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; |
492 | #if 0 | ||
493 | pos_min = pos; | ||
494 | ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp_func); | ||
495 | pos_min++; | ||
496 | ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp_func); | ||
497 | av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" %s<=%s<=%s\n", | ||
498 | pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max)); | ||
499 | #endif | ||
500 | 62 | *ts_ret = ts; | |
501 | 62 | return pos; | |
502 | } | ||
503 | |||
504 | ✗ | static int seek_frame_byte(AVFormatContext *s, int stream_index, | |
505 | int64_t pos, int flags) | ||
506 | { | ||
507 | ✗ | FFFormatContext *const si = ffformatcontext(s); | |
508 | int64_t pos_min, pos_max; | ||
509 | |||
510 | ✗ | pos_min = si->data_offset; | |
511 | ✗ | pos_max = avio_size(s->pb) - 1; | |
512 | |||
513 | ✗ | if (pos < pos_min) | |
514 | ✗ | pos = pos_min; | |
515 | ✗ | else if (pos > pos_max) | |
516 | ✗ | pos = pos_max; | |
517 | |||
518 | ✗ | avio_seek(s->pb, pos, SEEK_SET); | |
519 | |||
520 | ✗ | s->io_repositioned = 1; | |
521 | |||
522 | ✗ | return 0; | |
523 | } | ||
524 | |||
525 | 1145 | static int seek_frame_generic(AVFormatContext *s, int stream_index, | |
526 | int64_t timestamp, int flags) | ||
527 | { | ||
528 | 1145 | FFFormatContext *const si = ffformatcontext(s); | |
529 | 1145 | AVStream *const st = s->streams[stream_index]; | |
530 | 1145 | FFStream *const sti = ffstream(st); | |
531 | const AVIndexEntry *ie; | ||
532 | int index; | ||
533 | int64_t ret; | ||
534 | |||
535 | 1145 | index = av_index_search_timestamp(st, timestamp, flags); | |
536 | |||
537 |
4/4✓ Branch 0 taken 687 times.
✓ Branch 1 taken 458 times.
✓ Branch 2 taken 434 times.
✓ Branch 3 taken 253 times.
|
1145 | if (index < 0 && sti->nb_index_entries && |
538 |
2/2✓ Branch 0 taken 208 times.
✓ Branch 1 taken 226 times.
|
434 | timestamp < sti->index_entries[0].timestamp) |
539 | 208 | return -1; | |
540 | |||
541 |
4/4✓ Branch 0 taken 458 times.
✓ Branch 1 taken 479 times.
✓ Branch 2 taken 161 times.
✓ Branch 3 taken 297 times.
|
937 | if (index < 0 || index == sti->nb_index_entries - 1) { |
542 | 640 | AVPacket *const pkt = si->pkt; | |
543 | 640 | int nonkey = 0; | |
544 | |||
545 |
2/2✓ Branch 0 taken 387 times.
✓ Branch 1 taken 253 times.
|
640 | if (sti->nb_index_entries) { |
546 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 387 times.
|
387 | av_assert0(sti->index_entries); |
547 | 387 | ie = &sti->index_entries[sti->nb_index_entries - 1]; | |
548 |
2/2✓ Branch 1 taken 33 times.
✓ Branch 2 taken 354 times.
|
387 | if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) |
549 | 33 | return ret; | |
550 | 354 | s->io_repositioned = 1; | |
551 | 354 | avpriv_update_cur_dts(s, st, ie->timestamp); | |
552 | } else { | ||
553 |
2/2✓ Branch 1 taken 184 times.
✓ Branch 2 taken 69 times.
|
253 | if ((ret = avio_seek(s->pb, si->data_offset, SEEK_SET)) < 0) |
554 | 184 | return ret; | |
555 | 69 | s->io_repositioned = 1; | |
556 | } | ||
557 | 423 | av_packet_unref(pkt); | |
558 | 3551 | for (;;) { | |
559 | int read_status; | ||
560 | do { | ||
561 | 3974 | read_status = av_read_frame(s, pkt); | |
562 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3974 times.
|
3974 | } while (read_status == AVERROR(EAGAIN)); |
563 |
2/2✓ Branch 0 taken 369 times.
✓ Branch 1 taken 3605 times.
|
3974 | if (read_status < 0) |
564 | 369 | break; | |
565 |
4/4✓ Branch 0 taken 3390 times.
✓ Branch 1 taken 215 times.
✓ Branch 2 taken 487 times.
✓ Branch 3 taken 2903 times.
|
3605 | if (stream_index == pkt->stream_index && pkt->dts > timestamp) { |
566 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 433 times.
|
487 | if (pkt->flags & AV_PKT_FLAG_KEY) { |
567 | 54 | av_packet_unref(pkt); | |
568 | 54 | break; | |
569 | } | ||
570 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 433 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
433 | if (nonkey++ > 1000 && st->codecpar->codec_id != AV_CODEC_ID_CDGRAPHICS) { |
571 | ✗ | av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey); | |
572 | ✗ | av_packet_unref(pkt); | |
573 | ✗ | break; | |
574 | } | ||
575 | } | ||
576 | 3551 | av_packet_unref(pkt); | |
577 | } | ||
578 | 423 | index = av_index_search_timestamp(st, timestamp, flags); | |
579 | } | ||
580 |
2/2✓ Branch 0 taken 275 times.
✓ Branch 1 taken 445 times.
|
720 | if (index < 0) |
581 | 275 | return -1; | |
582 | |||
583 | 445 | ff_read_frame_flush(s); | |
584 |
2/2✓ Branch 1 taken 187 times.
✓ Branch 2 taken 258 times.
|
445 | if (ffifmt(s->iformat)->read_seek) |
585 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 187 times.
|
187 | if (ffifmt(s->iformat)->read_seek(s, stream_index, timestamp, flags) >= 0) |
586 | ✗ | return 0; | |
587 | 445 | ie = &sti->index_entries[index]; | |
588 |
2/2✓ Branch 1 taken 21 times.
✓ Branch 2 taken 424 times.
|
445 | if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) |
589 | 21 | return ret; | |
590 | 424 | s->io_repositioned = 1; | |
591 | 424 | avpriv_update_cur_dts(s, st, ie->timestamp); | |
592 | |||
593 | 424 | return 0; | |
594 | } | ||
595 | |||
596 | 3314 | static int seek_frame_internal(AVFormatContext *s, int stream_index, | |
597 | int64_t timestamp, int flags) | ||
598 | { | ||
599 | AVStream *st; | ||
600 | int ret; | ||
601 | |||
602 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3314 times.
|
3314 | if (flags & AVSEEK_FLAG_BYTE) { |
603 | ✗ | if (s->iformat->flags & AVFMT_NO_BYTE_SEEK) | |
604 | ✗ | return -1; | |
605 | ✗ | ff_read_frame_flush(s); | |
606 | ✗ | return seek_frame_byte(s, stream_index, timestamp, flags); | |
607 | } | ||
608 | |||
609 |
2/2✓ Branch 0 taken 1748 times.
✓ Branch 1 taken 1566 times.
|
3314 | if (stream_index < 0) { |
610 | 1748 | stream_index = av_find_default_stream_index(s); | |
611 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1748 times.
|
1748 | if (stream_index < 0) |
612 | ✗ | return -1; | |
613 | |||
614 | 1748 | st = s->streams[stream_index]; | |
615 | /* timestamp for default must be expressed in AV_TIME_BASE units */ | ||
616 | 1748 | timestamp = av_rescale(timestamp, st->time_base.den, | |
617 | 1748 | AV_TIME_BASE * (int64_t) st->time_base.num); | |
618 | } | ||
619 | |||
620 | /* first, we try the format specific seek */ | ||
621 |
2/2✓ Branch 1 taken 2788 times.
✓ Branch 2 taken 526 times.
|
3314 | if (ffifmt(s->iformat)->read_seek) { |
622 | 2788 | ff_read_frame_flush(s); | |
623 | 2788 | ret = ffifmt(s->iformat)->read_seek(s, stream_index, timestamp, flags); | |
624 | } else | ||
625 | 526 | ret = -1; | |
626 |
2/2✓ Branch 0 taken 2077 times.
✓ Branch 1 taken 1237 times.
|
3314 | if (ret >= 0) |
627 | 2077 | return 0; | |
628 | |||
629 |
2/2✓ Branch 1 taken 92 times.
✓ Branch 2 taken 1145 times.
|
1237 | if (ffifmt(s->iformat)->read_timestamp && |
630 |
1/2✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
|
92 | !(s->iformat->flags & AVFMT_NOBINSEARCH)) { |
631 | 92 | ff_read_frame_flush(s); | |
632 | 92 | return ff_seek_frame_binary(s, stream_index, timestamp, flags); | |
633 |
1/2✓ Branch 0 taken 1145 times.
✗ Branch 1 not taken.
|
1145 | } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) { |
634 | 1145 | ff_read_frame_flush(s); | |
635 | 1145 | return seek_frame_generic(s, stream_index, timestamp, flags); | |
636 | } else | ||
637 | ✗ | return -1; | |
638 | } | ||
639 | |||
640 | 3314 | int av_seek_frame(AVFormatContext *s, int stream_index, | |
641 | int64_t timestamp, int flags) | ||
642 | { | ||
643 | int ret; | ||
644 | |||
645 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 3314 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
3314 | if (ffifmt(s->iformat)->read_seek2 && !ffifmt(s->iformat)->read_seek) { |
646 | ✗ | int64_t min_ts = INT64_MIN, max_ts = INT64_MAX; | |
647 | ✗ | if ((flags & AVSEEK_FLAG_BACKWARD)) | |
648 | ✗ | max_ts = timestamp; | |
649 | else | ||
650 | ✗ | min_ts = timestamp; | |
651 | ✗ | return avformat_seek_file(s, stream_index, min_ts, timestamp, max_ts, | |
652 | flags & ~AVSEEK_FLAG_BACKWARD); | ||
653 | } | ||
654 | |||
655 | 3314 | ret = seek_frame_internal(s, stream_index, timestamp, flags); | |
656 | |||
657 |
2/2✓ Branch 0 taken 2592 times.
✓ Branch 1 taken 722 times.
|
3314 | if (ret >= 0) |
658 | 2592 | ret = avformat_queue_attached_pictures(s); | |
659 | |||
660 | 3314 | return ret; | |
661 | } | ||
662 | |||
663 | 3288 | int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, | |
664 | int64_t ts, int64_t max_ts, int flags) | ||
665 | { | ||
666 |
2/4✓ Branch 0 taken 3288 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3288 times.
|
3288 | if (min_ts > ts || max_ts < ts) |
667 | ✗ | return -1; | |
668 |
2/4✓ Branch 0 taken 3288 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3288 times.
|
3288 | if (stream_index < -1 || stream_index >= (int)s->nb_streams) |
669 | ✗ | return AVERROR(EINVAL); | |
670 | |||
671 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3288 times.
|
3288 | if (s->seek2any > 0) |
672 | ✗ | flags |= AVSEEK_FLAG_ANY; | |
673 | 3288 | flags &= ~AVSEEK_FLAG_BACKWARD; | |
674 | |||
675 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3286 times.
|
3288 | if (ffifmt(s->iformat)->read_seek2) { |
676 | int ret; | ||
677 | 2 | ff_read_frame_flush(s); | |
678 | |||
679 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | if (stream_index == -1 && s->nb_streams == 1) { |
680 | 2 | AVRational time_base = s->streams[0]->time_base; | |
681 | 2 | ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base); | |
682 | 2 | min_ts = av_rescale_rnd(min_ts, time_base.den, | |
683 | 2 | time_base.num * (int64_t)AV_TIME_BASE, | |
684 | AV_ROUND_UP | AV_ROUND_PASS_MINMAX); | ||
685 | 2 | max_ts = av_rescale_rnd(max_ts, time_base.den, | |
686 | 2 | time_base.num * (int64_t)AV_TIME_BASE, | |
687 | AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX); | ||
688 | 2 | stream_index = 0; | |
689 | } | ||
690 | |||
691 | 2 | ret = ffifmt(s->iformat)->read_seek2(s, stream_index, min_ts, | |
692 | ts, max_ts, flags); | ||
693 | |||
694 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (ret >= 0) |
695 | 1 | ret = avformat_queue_attached_pictures(s); | |
696 | 2 | return ret; | |
697 | } | ||
698 | |||
699 | 3286 | if (ffifmt(s->iformat)->read_timestamp) { | |
700 | // try to seek via read_timestamp() | ||
701 | } | ||
702 | |||
703 | // Fall back on old API if new is not implemented but old is. | ||
704 | // Note the old API has somewhat different semantics. | ||
705 | 3286 | if (ffifmt(s->iformat)->read_seek || 1) { | |
706 | 3286 | int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0); | |
707 | 3286 | int ret = av_seek_frame(s, stream_index, ts, flags | dir); | |
708 |
5/6✓ Branch 0 taken 722 times.
✓ Branch 1 taken 2564 times.
✓ Branch 2 taken 358 times.
✓ Branch 3 taken 364 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 358 times.
|
3286 | if (ret < 0 && ts != min_ts && max_ts != ts) { |
709 | ✗ | ret = av_seek_frame(s, stream_index, dir ? max_ts : min_ts, flags | dir); | |
710 | ✗ | if (ret >= 0) | |
711 | ✗ | ret = av_seek_frame(s, stream_index, ts, flags | (dir^AVSEEK_FLAG_BACKWARD)); | |
712 | } | ||
713 | 3286 | return ret; | |
714 | } | ||
715 | |||
716 | // try some generic seek like seek_frame_generic() but with new ts semantics | ||
717 | return -1; //unreachable | ||
718 | } | ||
719 | |||
720 | /** Flush the frame reader. */ | ||
721 | 4789 | void ff_read_frame_flush(AVFormatContext *s) | |
722 | { | ||
723 | 4789 | FFFormatContext *const si = ffformatcontext(s); | |
724 | |||
725 | 4789 | ff_flush_packet_queue(s); | |
726 | |||
727 | /* Reset read state for each stream. */ | ||
728 |
2/2✓ Branch 0 taken 5540 times.
✓ Branch 1 taken 4789 times.
|
10329 | for (unsigned i = 0; i < s->nb_streams; i++) { |
729 | 5540 | AVStream *const st = s->streams[i]; | |
730 | 5540 | FFStream *const sti = ffstream(st); | |
731 | |||
732 |
2/2✓ Branch 0 taken 1163 times.
✓ Branch 1 taken 4377 times.
|
5540 | if (sti->parser) { |
733 | 1163 | av_parser_close(sti->parser); | |
734 | 1163 | sti->parser = NULL; | |
735 | } | ||
736 | 5540 | sti->last_IP_pts = AV_NOPTS_VALUE; | |
737 | 5540 | sti->last_dts_for_order_check = AV_NOPTS_VALUE; | |
738 |
2/2✓ Branch 0 taken 1615 times.
✓ Branch 1 taken 3925 times.
|
5540 | if (sti->first_dts == AV_NOPTS_VALUE) |
739 | 1615 | sti->cur_dts = RELATIVE_TS_BASE; | |
740 | else | ||
741 | /* We set the current DTS to an unspecified origin. */ | ||
742 | 3925 | sti->cur_dts = AV_NOPTS_VALUE; | |
743 | |||
744 | 5540 | sti->probe_packets = s->max_probe_packets; | |
745 | |||
746 |
2/2✓ Branch 0 taken 94180 times.
✓ Branch 1 taken 5540 times.
|
99720 | for (int j = 0; j < MAX_REORDER_DELAY + 1; j++) |
747 | 94180 | sti->pts_buffer[j] = AV_NOPTS_VALUE; | |
748 | |||
749 | #if FF_API_AVSTREAM_SIDE_DATA | ||
750 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5540 times.
|
5540 | if (si->inject_global_side_data) |
751 | ✗ | sti->inject_global_side_data = 1; | |
752 | #endif | ||
753 | |||
754 | 5540 | sti->skip_samples = 0; | |
755 | } | ||
756 | 4789 | } | |
757 | |||
758 | ✗ | int avformat_flush(AVFormatContext *s) | |
759 | { | ||
760 | ✗ | ff_read_frame_flush(s); | |
761 | ✗ | return 0; | |
762 | } | ||
763 | |||
764 | 3 | void ff_rescale_interval(AVRational tb_in, AVRational tb_out, | |
765 | int64_t *min_ts, int64_t *ts, int64_t *max_ts) | ||
766 | { | ||
767 | 3 | *ts = av_rescale_q (* ts, tb_in, tb_out); | |
768 | 3 | *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out, | |
769 | AV_ROUND_UP | AV_ROUND_PASS_MINMAX); | ||
770 | 3 | *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out, | |
771 | AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX); | ||
772 | 3 | } | |
773 |