From: Steinar H. Gunderson Date: Sun, 30 Aug 2020 17:23:43 +0000 (+0200) Subject: In DeckLinkOutput, keep a list of all the scheduled frames instead of just a count. X-Git-Tag: 2.0.2~15 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=cd1b6b6b8dd3d4d6f52d917cec3e5a152f87e822 In DeckLinkOutput, keep a list of all the scheduled frames instead of just a count. This will be important when we want to track frames the driver inserts on our behalf; we'll need to be able to adjust their estimated pts then. --- diff --git a/nageru/decklink_output.cpp b/nageru/decklink_output.cpp index 00d8043..da172af 100644 --- a/nageru/decklink_output.cpp +++ b/nageru/decklink_output.cpp @@ -255,7 +255,7 @@ void DeckLinkOutput::end_output() // Wait until all frames are accounted for, and free them. { unique_lock lock(frame_queue_mutex); - while (!(frame_freelist.empty() && num_frames_in_flight == 0)) { + while (!(frame_freelist.empty() && scheduled_frames.empty())) { frame_queues_changed.wait(lock, [this]{ return !frame_freelist.empty(); }); frame_freelist.pop(); } @@ -503,7 +503,8 @@ HRESULT DeckLinkOutput::ScheduledFrameCompleted(/* in */ IDeckLinkVideoFrame *co { lock_guard lock(frame_queue_mutex); frame_freelist.push(unique_ptr(frame)); - --num_frames_in_flight; + assert(scheduled_frames.front() == frame); + scheduled_frames.pop_front(); --metric_decklink_output_inflight_frames; } @@ -573,8 +574,6 @@ void DeckLinkOutput::present_thread_func() } frame = move(pending_video_frames.front()); pending_video_frames.pop(); - ++num_frames_in_flight; - ++metric_decklink_output_inflight_frames; } for ( ;; ) { @@ -601,15 +600,14 @@ void DeckLinkOutput::present_thread_func() BMDTimeValue pts = frame->pts; BMDTimeValue duration = frame->duration; HRESULT res = output->ScheduleVideoFrame(frame.get(), pts, duration, TIMEBASE); + lock_guard lock(frame_queue_mutex); if (res == S_OK) { - frame.release(); // Owned by the driver now. + scheduled_frames.push_back(frame.release()); // Owned by the driver now. + ++metric_decklink_output_inflight_frames; } else { fprintf(stderr, "Could not schedule video frame! (error=0x%08x)\n", res); - lock_guard lock(frame_queue_mutex); frame_freelist.push(move(frame)); - --num_frames_in_flight; - --metric_decklink_output_inflight_frames; } } } diff --git a/nageru/decklink_output.h b/nageru/decklink_output.h index 2c07bc7..f1b40f4 100644 --- a/nageru/decklink_output.h +++ b/nageru/decklink_output.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +134,8 @@ private: std::mutex frame_queue_mutex; std::queue> pending_video_frames; // Under . std::queue> frame_freelist; // Under . - int num_frames_in_flight = 0; // Number of frames allocated but not on the freelist. Under . + std::deque scheduled_frames; // Owned by the driver, so no unique_ptr. Under . + std::condition_variable frame_queues_changed; bool playback_initiated = false, playback_started = false; int64_t base_pts, frame_duration;