X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mixer.h;h=6f04c67844113d53010fa3ca93a451c0f6fcb821;hb=f006b5b162841dbc764fb620025b87a3272ac79a;hp=e27d2299bae5d2746b0478491a450c7421f8dabb;hpb=a43cd0787ec6042f24ee6bea7d9cbc8ce0579f17;p=nageru diff --git a/mixer.h b/mixer.h index e27d229..6f04c67 100644 --- a/mixer.h +++ b/mixer.h @@ -71,10 +71,12 @@ class QSurfaceFormat; // // N is reduced as follows: If the queue has had at least one spare frame for // at least 50 (master) frames (ie., it's been too conservative for a second), -// we reduce N by 1 and reset the timers. +// we reduce N by 1 and reset the timers. TODO: Only do this if N ever actually +// touched the limit. // -// Whenever the queue is starved (we needed a frame but there was none), N was -// obviously too low, so we increment N. We will never set N above 5, though. +// Whenever the queue is starved (we needed a frame but there was none), +// and we've been at N since the last starvation, N was obviously too low, +// so we increment it. We will never set N above 5, though. class QueueLengthPolicy { public: QueueLengthPolicy() {} @@ -82,6 +84,7 @@ public: this->card_index = card_index; safe_queue_length = 0; frames_with_at_least_one = 0; + been_at_safe_point_since_last_starvation = false; } void update_policy(int queue_length); // Give in -1 for starvation. @@ -91,6 +94,7 @@ private: unsigned card_index; // For debugging only. unsigned safe_queue_length = 0; // Called N in the comments. unsigned frames_with_at_least_one = 0; + bool been_at_safe_point_since_last_starvation = false; }; class Mixer { @@ -167,6 +171,11 @@ public: return theme->get_channel_name(channel); } + std::string get_channel_color(unsigned channel) const + { + return theme->get_channel_color(channel); + } + int get_channel_signal(unsigned channel) const { return theme->get_channel_signal(channel); @@ -187,6 +196,16 @@ public: audio_source_channel = channel; } + unsigned get_master_clock() const + { + return master_clock_channel; + } + + void set_master_clock(unsigned channel) + { + master_clock_channel = channel; + } + void set_signal_mapping(int signal, int card) { return theme->set_signal_mapping(signal, card); @@ -336,7 +355,9 @@ private: FrameAllocator::Frame audio_frame, size_t audio_offset, AudioFormat audio_format); void place_rectangle(movit::Effect *resample_effect, movit::Effect *padding_effect, float x0, float y0, float x1, float y1); void thread_func(); + void schedule_audio_resampling_tasks(unsigned dropped_frames, int num_samples_per_frame, int length_per_frame); void render_one_frame(); + void send_audio_level_callback(); void audio_thread_func(); void process_audio_one_frame(int64_t frame_pts_int, int num_samples); void subsample_chroma(GLuint src_tex, GLuint dst_dst); @@ -350,6 +371,7 @@ private: std::unique_ptr resource_pool; std::unique_ptr theme; std::atomic audio_source_channel{0}; + std::atomic master_clock_channel{0}; std::unique_ptr display_chain; GLuint cbcr_program_num; // Owned by . GLuint cbcr_vbo; // Holds position and texcoord data. @@ -375,7 +397,7 @@ private: int64_t length; // In TIMEBASE units. bool interlaced; unsigned field; // Which field (0 or 1) of the frame to use. Always 0 for progressive. - GLsync ready_fence; // Whether frame is ready for rendering. + RefCountedGLsync ready_fence; // Whether frame is ready for rendering. unsigned dropped_frames = 0; // Number of dropped frames before this one. }; std::queue new_frames; @@ -394,6 +416,7 @@ private: int64_t next_local_pts = 0; // Beginning of next frame, in TIMEBASE units. }; CaptureCard cards[MAX_CARDS]; // protected by + void get_one_frame_from_each_card(unsigned master_card_index, CaptureCard::NewFrame new_frames[MAX_CARDS], bool has_new_frame[MAX_CARDS], int num_samples[MAX_CARDS]); InputState input_state;