#include <atomic>
#include <chrono>
#include <condition_variable>
+#include <deque>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
+#include <unordered_set>
#include <vector>
#include "DeckLinkAPI.h"
class DeckLinkOutput : public IDeckLinkVideoOutputCallback {
public:
DeckLinkOutput(movit::ResourcePool *resource_pool, QSurface *surface, unsigned width, unsigned height, unsigned card_index);
-
- bool set_device(IDeckLink *output);
- void start_output(uint32_t mode, int64_t base_pts); // Mode comes from get_available_video_modes().
+ ~DeckLinkOutput();
+
+ // The IDecklinkInput argument is to work around a bug
+ // in the 11.7 and newer drivers against older SDKs,
+ // where you get a freeze if querying an IDeckLinkInput interface
+ // on an already-started card.
+ bool set_device(IDeckLink *decklink, IDeckLinkInput *input_arg);
+ void start_output(uint32_t mode, int64_t base_pts, bool is_master_card); // Mode comes from get_available_video_modes().
void end_output();
void send_frame(GLuint y_tex, GLuint cbcr_tex, movit::YCbCrLumaCoefficients ycbcr_coefficients, const std::vector<RefCountedFrame> &input_frames, int64_t pts, int64_t duration);
std::mutex frame_queue_mutex;
std::queue<std::unique_ptr<Frame>> pending_video_frames; // Under <frame_queue_mutex>.
std::queue<std::unique_ptr<Frame>> frame_freelist; // Under <frame_queue_mutex>.
- int num_frames_in_flight = 0; // Number of frames allocated but not on the freelist. Under <frame_queue_mutex>.
+ std::unordered_set<Frame *> scheduled_frames; // Owned by the driver, so no unique_ptr. Under <frame_queue_mutex>.
+
std::condition_variable frame_queues_changed;
- bool playback_initiated = false, playback_started = false;
+ bool playback_initiated = false, playback_started = false, is_master_card = false;
int64_t base_pts, frame_duration;
BMDDisplayModeFlags current_mode_flags = 0;
bool last_frame_had_mode_mismatch = false;
movit::ResourcePool *resource_pool;
+ IDeckLinkInput *input = nullptr;
IDeckLinkOutput *output = nullptr;
BMDVideoConnection video_connection;
QSurface *surface;