X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fdecklink_output.h;h=9c994a8eb2c59c971af9a2e03858dbf0a8b05a3f;hb=896b8bb8e44409738aef56ba7d7b7f300c22d2ce;hp=2c07bc72ccae0c32c8300081d473eebaf6bc7af9;hpb=9a0f617093e7cde02a824b90f82f129c47193939;p=nageru diff --git a/nageru/decklink_output.h b/nageru/decklink_output.h index 2c07bc7..9c994a8 100644 --- a/nageru/decklink_output.h +++ b/nageru/decklink_output.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -19,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" @@ -39,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 &input_frames, int64_t pts, int64_t duration); void send_audio(int64_t pts, const std::vector &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 @@ -121,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 refcount{1}; @@ -130,10 +135,16 @@ private: std::thread present_thread; QuittableSleeper should_quit; - 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::mutex frame_queue_mutex; // Protects all members in this block. + std::queue> pending_video_frames; + std::queue> frame_freelist; + std::deque 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; int64_t base_pts, frame_duration;