MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / CheckWorkingFrames

Method CheckWorkingFrames

src/FFmpegReader.cpp:2728–2918  ·  view source on GitHub ↗

Check the working queue, and move finished frames to the finished queue

Source from the content-addressed store, hash-verified

2726
2727// Check the working queue, and move finished frames to the finished queue
2728void FFmpegReader::CheckWorkingFrames(int64_t requested_frame) {
2729
2730 // Prevent async calls to the following code
2731 const std::lock_guard<std::recursive_mutex> lock(getFrameMutex);
2732
2733 // Get a list of current working queue frames in the cache (in-progress frames)
2734 std::vector<std::shared_ptr<openshot::Frame>> working_frames = working_cache.GetFrames();
2735 std::vector<std::shared_ptr<openshot::Frame>>::iterator working_itr;
2736
2737 // Loop through all working queue frames (sorted by frame #)
2738 for(working_itr = working_frames.begin(); working_itr != working_frames.end(); ++working_itr)
2739 {
2740 // Get working frame
2741 std::shared_ptr<Frame> f = *working_itr;
2742
2743 // Was a frame found? Is frame requested yet?
2744 if (!f || f->number > requested_frame) {
2745 // If not, skip to next one
2746 continue;
2747 }
2748
2749 // Calculate PTS in seconds (of working frame), and the most recent processed pts value
2750 double frame_pts_seconds = (double(f->number - 1) / info.fps.ToDouble()) + pts_offset_seconds;
2751 double recent_pts_seconds = std::max(video_pts_seconds, audio_pts_seconds);
2752
2753 // Determine if video and audio are ready (based on timestamps)
2754 bool is_video_ready = false;
2755 bool is_audio_ready = false;
2756 double recent_pts_diff = recent_pts_seconds - frame_pts_seconds;
2757 if ((frame_pts_seconds <= video_pts_seconds)
2758 || (recent_pts_diff > 1.5)
2759 || packet_status.video_eof || packet_status.end_of_file) {
2760 // Video stream is past this frame (so it must be done)
2761 // OR video stream is too far behind, missing, or end-of-file
2762 is_video_ready = true;
2763 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckWorkingFrames (video ready)",
2764 "frame_number", f->number,
2765 "frame_pts_seconds", frame_pts_seconds,
2766 "video_pts_seconds", video_pts_seconds,
2767 "recent_pts_diff", recent_pts_diff);
2768 if (info.has_video && !f->has_image_data &&
2769 (packet_status.video_eof || packet_status.end_of_file)) {
2770 // Frame has no image data. Prefer timeline-previous frames to preserve
2771 // visual order, especially when decode/prefetch is out-of-order.
2772 std::shared_ptr<Frame> previous_frame_instance = final_cache.GetFrame(f->number - 1);
2773 if (previous_frame_instance && previous_frame_instance->has_image_data) {
2774 f->AddImage(std::make_shared<QImage>(previous_frame_instance->GetImage()->copy()));
2775 }
2776
2777 // Fall back to last finalized timeline image (survives cache churn).
2778 if (!f->has_image_data
2779 && last_final_video_frame
2780 && last_final_video_frame->has_image_data
2781 && last_final_video_frame->number <= f->number) {
2782 f->AddImage(std::make_shared<QImage>(last_final_video_frame->GetImage()->copy()));
2783 }
2784
2785 // Fall back to the last decoded image only when it is not from the future.

Callers 1

FFmpegReader.cppFile · 0.80

Calls 11

ToDoubleMethod · 0.80
AppendDebugMethodMethod · 0.80
AddImageMethod · 0.80
GetImageMethod · 0.80
AddColorMethod · 0.80
GetFramesMethod · 0.45
GetFrameMethod · 0.45
CountMethod · 0.45
AddMethod · 0.45
RemoveMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected