From 71228817c10497e60bcea5b836c79e462f2d32fb Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 2 Apr 2016 19:27:01 +0200 Subject: [PATCH] Make it possible to choose which card is the master clock. --- glwidget.cpp | 12 ++++++++++++ mixer.cpp | 12 +++++++++--- mixer.h | 11 +++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/glwidget.cpp b/glwidget.cpp index e8c2416..bf3ac13 100644 --- a/glwidget.cpp +++ b/glwidget.cpp @@ -211,6 +211,7 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos) mode_submenu.setTitle("Input mode"); menu.addMenu(&mode_submenu); + // --- End of card-dependent choices --- // Add an audio source selector. QAction *audio_source_action = new QAction("Use as audio source", &menu); @@ -221,10 +222,21 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos) } menu.addAction(audio_source_action); + // And a master clock selector. + QAction *master_clock_action = new QAction("Use as master clock", &menu); + master_clock_action->setCheckable(true); + if (global_mixer->get_master_clock() == signal_num) { + master_clock_action->setChecked(true); + master_clock_action->setEnabled(false); + } + menu.addAction(master_clock_action); + // Show the menu and look at the result. QAction *selected_item = menu.exec(global_pos); if (selected_item == audio_source_action) { global_mixer->set_audio_source(signal_num); + } else if (selected_item == master_clock_action) { + global_mixer->set_master_clock(signal_num); } else if (selected_item != nullptr) { QList selected = selected_item->data().toList(); if (selected[0].toString() == "video_mode") { diff --git a/mixer.cpp b/mixer.cpp index 50c93e8..2802329 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -605,8 +605,9 @@ void Mixer::thread_func() bool has_new_frame[MAX_CARDS] = { false }; int num_samples[MAX_CARDS] = { 0 }; - // TODO: Make configurable, and with a timeout. - unsigned master_card_index = 0; + // TODO: Add a timeout. + unsigned master_card_index = theme->map_signal(master_clock_channel); + assert(master_card_index < num_cards); get_one_frame_from_each_card(master_card_index, new_frames, has_new_frame, num_samples); schedule_audio_resampling_tasks(new_frames[master_card_index].dropped_frames, num_samples[master_card_index], new_frames[master_card_index].length); @@ -715,7 +716,12 @@ void Mixer::get_one_frame_from_each_card(unsigned master_card_index, CaptureCard card->fractional_samples = num_samples_times_timebase % TIMEBASE; assert(num_samples[card_index] >= 0); - if (card_index != master_card_index) { + if (card_index == master_card_index) { + // We don't use the queue length policy for the master card, + // but we will if it stops being the master. Thus, clear out + // the policy in case we switch in the future. + card->queue_length_policy.reset(card_index); + } else { // If we have excess frames compared to the policy for this card, // drop frames from the head. card->queue_length_policy.update_policy(card->new_frames.size()); diff --git a/mixer.h b/mixer.h index c68ad1b..2b00682 100644 --- a/mixer.h +++ b/mixer.h @@ -187,6 +187,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); @@ -352,6 +362,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. -- 2.39.2