]> git.sesse.net Git - nageru/blobdiff - nageru/decklink_output.cpp
In DeckLinkOutput, keep a list of all the scheduled frames instead of just a count.
[nageru] / nageru / decklink_output.cpp
index 00d80432564c569f437a0817e3dafc22a9a3c37d..da172af686acbc3ff7acf489a7befd01a2efb2f7 100644 (file)
@@ -255,7 +255,7 @@ void DeckLinkOutput::end_output()
        // Wait until all frames are accounted for, and free them.
        {
                unique_lock<mutex> 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<mutex> lock(frame_queue_mutex);
                frame_freelist.push(unique_ptr<Frame>(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<mutex> 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<mutex> lock(frame_queue_mutex);
                        frame_freelist.push(move(frame));
-                       --num_frames_in_flight;
-                       --metric_decklink_output_inflight_frames;
                }
        }
 }