// 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();
}
{
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;
}
}
frame = move(pending_video_frames.front());
pending_video_frames.pop();
- ++num_frames_in_flight;
- ++metric_decklink_output_inflight_frames;
}
for ( ;; ) {
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;
}
}
}