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);
}
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<QVariant> selected = selected_item->data().toList();
if (selected[0].toString() == "video_mode") {
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);
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());
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);
std::unique_ptr<movit::ResourcePool> resource_pool;
std::unique_ptr<Theme> theme;
std::atomic<unsigned> audio_source_channel{0};
+ std::atomic<unsigned> master_clock_channel{0};
std::unique_ptr<movit::EffectChain> display_chain;
GLuint cbcr_program_num; // Owned by <resource_pool>.
GLuint cbcr_vbo; // Holds position and texcoord data.