]> git.sesse.net Git - nageru/commitdiff
Add a menu option where the user can change the input resolution.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 4 Mar 2016 22:02:10 +0000 (23:02 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 4 Mar 2016 22:02:10 +0000 (23:02 +0100)
decklink_capture.cpp
decklink_capture.h
glwidget.cpp
mixer.h

index f2731acae422c9dbe9d259b77917ebe679a30621..80aedc18664336506b77695db05f5cedb247876a 100644 (file)
@@ -206,8 +206,7 @@ DeckLinkCapture::DeckLinkCapture(IDeckLink *card, int card_index)
                video_modes.insert(make_pair(id, mode));
        }
 
-       // TODO: Make the user mode selectable.
-       set_video_mode(bmdModeHD720p5994);
+       set_video_mode_no_restart(bmdModeHD720p5994);
 
        if (input->EnableAudioInput(48000, bmdAudioSampleType32bitInteger, 2) != S_OK) {
                fprintf(stderr, "Failed to enable audio input for card %d\n", card_index);
@@ -365,6 +364,21 @@ void DeckLinkCapture::stop_dequeue_thread()
 }
 
 void DeckLinkCapture::set_video_mode(uint32_t video_mode_id)
+{
+       if (input->StopStreams() != S_OK) {
+               fprintf(stderr, "StopStreams failed\n");
+               exit(1);
+       }
+
+       set_video_mode_no_restart(video_mode_id);
+
+       if (input->StartStreams() != S_OK) {
+               fprintf(stderr, "StartStreams failed\n");
+               exit(1);
+       }
+}
+
+void DeckLinkCapture::set_video_mode_no_restart(uint32_t video_mode_id)
 {
        BMDDisplayModeSupport support;
        IDeckLinkDisplayMode *display_mode;
@@ -384,7 +398,7 @@ void DeckLinkCapture::set_video_mode(uint32_t video_mode_id)
        }
 
        if (input->EnableVideoInput(video_mode_id, bmdFormat8BitYUV, 0) != S_OK) {
-               fprintf(stderr, "Failed to set 720p59.94 connection for card %d\n", card_index);
+               fprintf(stderr, "Failed to set video mode 0x%04x for card %d\n", video_mode_id, card_index);
                exit(1);
        }
 
index ad13a938dfe55ce0af55734fd4da22a1a8684a64..322adb5b0d6c62352f0397c4a357c7c66fc837ec 100644 (file)
@@ -80,6 +80,8 @@ public:
        uint32_t get_current_video_mode() const override { return current_video_mode; }
 
 private:
+       void set_video_mode_no_restart(uint32_t video_mode_id);
+
        std::atomic<int> refcount{1};
        bool done_init = false;
        std::string description;
index c57d645c61acd9ef1d288a058d6cfdda9f1dfa23..9215fcad2219360a047e5878d61b0b77b0335c62 100644 (file)
@@ -118,23 +118,45 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos)
 
        QMenu menu;
 
-       // Add an action for each card.
-       QActionGroup group(&menu);
+       // Add a submenu for selecting input card, with an action for each card.
+       QMenu card_submenu;
+       QActionGroup card_group(&card_submenu);
 
        unsigned num_cards = global_mixer->get_num_cards();
        unsigned current_card = global_mixer->map_signal(signal_num);
        for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
                QString description(QString::fromStdString(global_mixer->get_card_description(card_index)));
-               QAction *action = new QAction(description, &group);
+               QAction *action = new QAction(description, &card_group);
                action->setCheckable(true);
                if (current_card == card_index) {
                        action->setChecked(true);
                }
-               action->setData(card_index);
-               menu.addAction(action);
+               action->setData(QList<QVariant>{"card", card_index});
+               card_submenu.addAction(action);
        }
 
-       menu.addSeparator();
+       card_submenu.setTitle("Input source");
+       menu.addMenu(&card_submenu);
+
+       // Add a submenu for selecting resolution, with an action for each resolution.
+       // Note that the choice depends a lot on which card is active.
+       QMenu mode_submenu;
+       QActionGroup mode_group(&mode_submenu);
+       std::map<uint32_t, VideoMode> video_modes = global_mixer->get_available_video_modes(current_card);
+       uint32_t current_video_mode = global_mixer->get_current_video_mode(current_card);
+       for (const auto &mode : video_modes) {
+               QString description(QString::fromStdString(mode.second.name));
+               QAction *action = new QAction(description, &mode_group);
+               action->setCheckable(true);
+               if (mode.first == current_video_mode) {
+                       action->setChecked(true);
+               }
+               action->setData(QList<QVariant>{"video_mode", mode.first});
+               mode_submenu.addAction(action);
+       }
+
+       mode_submenu.setTitle("Input mode");
+       menu.addMenu(&mode_submenu);
 
        // Add an audio source selector.
        QAction *audio_source_action = new QAction("Use as audio source", &menu);
@@ -145,11 +167,20 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos)
        }
        menu.addAction(audio_source_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 != nullptr) {
-               unsigned card_index = selected_item->data().toInt(nullptr);
-               global_mixer->set_signal_mapping(signal_num, card_index);
+               QList<QVariant> selected = selected_item->data().toList();
+               if (selected[0].toString() == "video_mode") {
+                       uint32_t mode = selected[1].toUInt(nullptr);
+                       global_mixer->set_video_mode(current_card, mode);
+               } else if (selected[0].toString() == "card") {
+                       unsigned card_index = selected[1].toUInt(nullptr);
+                       global_mixer->set_signal_mapping(signal_num, card_index);
+               } else {
+                       assert(false);
+               }
        }
 }
diff --git a/mixer.h b/mixer.h
index 00b10f8c5a056ee77ed5c7e13000f83ec32414e8..27ba586a7837b646e3933221d430f417d44ec157 100644 (file)
--- a/mixer.h
+++ b/mixer.h
@@ -241,6 +241,21 @@ public:
                return cards[card_index].capture->get_description();
        }
 
+       std::map<uint32_t, VideoMode> get_available_video_modes(unsigned card_index) const {
+               assert(card_index < num_cards);
+               return cards[card_index].capture->get_available_video_modes();
+       }
+
+       uint32_t get_current_video_mode(unsigned card_index) const {
+               assert(card_index < num_cards);
+               return cards[card_index].capture->get_current_video_mode();
+       }
+
+       void set_video_mode(unsigned card_index, uint32_t mode) {
+               assert(card_index < num_cards);
+               cards[card_index].capture->set_video_mode(mode);
+       }
+
 private:
        void configure_card(unsigned card_index, const QSurfaceFormat &format, CaptureInterface *capture);
        void bm_frame(unsigned card_index, uint16_t timecode,