Seek to a specific frame. This is not always frame accurate, it's more of an estimation on many codecs.
| 2326 | |
| 2327 | // Seek to a specific frame. This is not always frame accurate, it's more of an estimation on many codecs. |
| 2328 | void FFmpegReader::Seek(int64_t requested_frame) { |
| 2329 | // Adjust for a requested frame that is too small or too large |
| 2330 | if (requested_frame < 1) |
| 2331 | requested_frame = 1; |
| 2332 | if (requested_frame > info.video_length) |
| 2333 | requested_frame = info.video_length; |
| 2334 | if (requested_frame > largest_frame_processed && packet_status.end_of_file) { |
| 2335 | // Not possible to search past largest_frame once EOF is reached (no more packets) |
| 2336 | return; |
| 2337 | } |
| 2338 | |
| 2339 | // Debug output |
| 2340 | ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::Seek", |
| 2341 | "requested_frame", requested_frame, |
| 2342 | "seek_count", seek_count, |
| 2343 | "last_frame", last_frame); |
| 2344 | |
| 2345 | // Clear working cache (since we are seeking to another location in the file) |
| 2346 | working_cache.Clear(); |
| 2347 | |
| 2348 | // Reset the last frame variable |
| 2349 | video_pts = 0.0; |
| 2350 | video_pts_seconds = NO_PTS_OFFSET; |
| 2351 | audio_pts = 0.0; |
| 2352 | audio_pts_seconds = NO_PTS_OFFSET; |
| 2353 | hold_packet = false; |
| 2354 | last_frame = 0; |
| 2355 | current_video_frame = 0; |
| 2356 | largest_frame_processed = 0; |
| 2357 | last_final_video_frame.reset(); |
| 2358 | bool has_audio_override = info.has_audio; |
| 2359 | bool has_video_override = info.has_video; |
| 2360 | |
| 2361 | // Init end-of-file detection variables |
| 2362 | packet_status.reset(false); |
| 2363 | |
| 2364 | // Increment seek count |
| 2365 | seek_count++; |
| 2366 | |
| 2367 | // If seeking near frame 1, we need to close and re-open the file (this is more reliable than seeking) |
| 2368 | int buffer_amount = 12; |
| 2369 | if (requested_frame - buffer_amount < 20) { |
| 2370 | // prevent Open() from seeking again |
| 2371 | is_seeking = true; |
| 2372 | |
| 2373 | // Close and re-open file (basically seeking to frame 1) |
| 2374 | Close(); |
| 2375 | Open(); |
| 2376 | |
| 2377 | // Update overrides (since closing and re-opening might update these) |
| 2378 | info.has_audio = has_audio_override; |
| 2379 | info.has_video = has_video_override; |
| 2380 | |
| 2381 | // Not actually seeking, so clear these flags |
| 2382 | is_seeking = false; |
| 2383 | if (seek_count == 1) { |
| 2384 | // Don't redefine this on multiple seek attempts for a specific frame |
| 2385 | seeking_frame = 1; |
nothing calls this directly
no test coverage detected