| 2283 | } |
| 2284 | |
| 2285 | static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t seek_pos_msec, int flags, int dry_run) |
| 2286 | { |
| 2287 | int ret = 0; |
| 2288 | int i = 0; |
| 2289 | int j = 0; |
| 2290 | int64_t duration = 0; |
| 2291 | |
| 2292 | av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms] %s\n", |
| 2293 | seek_pos_msec, dry_run ? " (dry)" : ""); |
| 2294 | |
| 2295 | // single fragment mode |
| 2296 | if (pls->n_fragments == 1) { |
| 2297 | pls->cur_timestamp = 0; |
| 2298 | pls->cur_seg_offset = 0; |
| 2299 | if (dry_run) |
| 2300 | return 0; |
| 2301 | ff_read_frame_flush(pls->ctx); |
| 2302 | return av_seek_frame(pls->ctx, -1, seek_pos_msec * 1000, flags); |
| 2303 | } |
| 2304 | |
| 2305 | ff_format_io_close(pls->parent, &pls->input); |
| 2306 | |
| 2307 | // find the nearest fragment |
| 2308 | if (pls->n_timelines > 0 && pls->fragment_timescale > 0) { |
| 2309 | int64_t num = pls->first_seq_no; |
| 2310 | av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline start n_timelines[%d] " |
| 2311 | "last_seq_no[%"PRId64"].\n", |
| 2312 | (int)pls->n_timelines, (int64_t)pls->last_seq_no); |
| 2313 | for (i = 0; i < pls->n_timelines; i++) { |
| 2314 | if (pls->timelines[i]->starttime > 0) { |
| 2315 | duration = pls->timelines[i]->starttime; |
| 2316 | } |
| 2317 | duration += pls->timelines[i]->duration; |
| 2318 | if (seek_pos_msec < ((duration * 1000) / pls->fragment_timescale)) { |
| 2319 | goto set_seq_num; |
| 2320 | } |
| 2321 | for (j = 0; j < pls->timelines[i]->repeat; j++) { |
| 2322 | duration += pls->timelines[i]->duration; |
| 2323 | num++; |
| 2324 | if (seek_pos_msec < ((duration * 1000) / pls->fragment_timescale)) { |
| 2325 | goto set_seq_num; |
| 2326 | } |
| 2327 | } |
| 2328 | num++; |
| 2329 | } |
| 2330 | |
| 2331 | set_seq_num: |
| 2332 | pls->cur_seq_no = num > pls->last_seq_no ? pls->last_seq_no : num; |
| 2333 | av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline end cur_seq_no[%"PRId64"].\n", |
| 2334 | (int64_t)pls->cur_seq_no); |
| 2335 | } else if (pls->fragment_duration > 0) { |
| 2336 | pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000; |
| 2337 | } else { |
| 2338 | av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing timeline or fragment_duration\n"); |
| 2339 | pls->cur_seq_no = pls->first_seq_no; |
| 2340 | } |
| 2341 | pls->cur_timestamp = 0; |
| 2342 | pls->cur_seg_offset = 0; |
no test coverage detected