]> git.sesse.net Git - nageru/blobdiff - nageru/decklink_output.h
WIP patch for async output.
[nageru] / nageru / decklink_output.h
index f1b40f468abdd703eb8df9c1e0410d3a78696d29..9c994a8eb2c59c971af9a2e03858dbf0a8b05a3f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "shared/context.h"
 #include "print_latency.h"
+#include "queue_length_policy.h"
 #include "quittable_sleeper.h"
 #include "ref_counted_frame.h"
 #include "shared/ref_counted_gl_sync.h"
@@ -40,12 +41,14 @@ 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().
+       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);
        void send_audio(int64_t pts, const std::vector<float> &samples);
 
+       // Only makes sense if is_master_card is true.
+       //
        // NOTE: The returned timestamp is undefined for preroll.
        // Otherwise, it is the timestamp of the output frame as it should have been,
        // even if we're overshooting. E.g. at 50 fps (0.02 spf), assuming the
@@ -122,6 +125,7 @@ private:
        void create_uyvy(GLuint y_tex, GLuint cbcr_tex, GLuint dst_tex);
 
        void present_thread_func();
+       double PTSToTime(int64_t pts);
 
        std::atomic<int> refcount{1};
 
@@ -131,10 +135,15 @@ private:
        std::thread present_thread;
        QuittableSleeper should_quit;
 
-       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>.
-       std::deque<Frame *> scheduled_frames;  // Owned by the driver, so no unique_ptr. Under <frame_queue_mutex>.
+       std::mutex frame_queue_mutex;  // Protects all members in this block.
+       std::queue<std::unique_ptr<Frame>> pending_video_frames;
+       std::queue<std::unique_ptr<Frame>> frame_freelist;
+       std::deque<Frame *> scheduled_frames;  // Owned by the driver, so no unique_ptr.
+       unsigned num_safe_frames = 1;
+       int64_t next_output_pts = 0;
+       JitterHistory input_jitter_history, output_jitter_history;
+       QueueLengthPolicy queue_length_policy;
+       // End of variables protected by frame_queue_mutex.
 
        std::condition_variable frame_queues_changed;
        bool playback_initiated = false, playback_started = false;