]> git.sesse.net Git - nageru/commitdiff
Make drivers capable of delivering a list of modes, and setting them.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 3 Mar 2016 23:22:00 +0000 (00:22 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 3 Mar 2016 23:45:16 +0000 (00:45 +0100)
bmusb
decklink_capture.cpp
decklink_capture.h

diff --git a/bmusb b/bmusb
index 862d8ccf3a3d48602427eb2bfb319b2fc7181fe0..753cbaf5cec7411bdfe5171404c8586b8015faec 160000 (submodule)
--- a/bmusb
+++ b/bmusb
@@ -1 +1 @@
-Subproject commit 862d8ccf3a3d48602427eb2bfb319b2fc7181fe0
+Subproject commit 753cbaf5cec7411bdfe5171404c8586b8015faec
index 62af1c0b558b54b0e5615c19771c42f62506c3dd..701675b84cb61cc27bd6268d0a16301b4ec278a9 100644 (file)
@@ -134,6 +134,7 @@ size_t memcpy_interleaved_fastpath(uint8_t *dest1, uint8_t *dest2, const uint8_t
 }  // namespace
 
 DeckLinkCapture::DeckLinkCapture(IDeckLink *card, int card_index)
+       : card_index(card_index)
 {
        {
                const char *model_name;
@@ -168,29 +169,44 @@ DeckLinkCapture::DeckLinkCapture(IDeckLink *card, int card_index)
                exit(1);
        }
 
-       // TODO: Make the user mode selectable.
-       BMDDisplayModeSupport support;
-       IDeckLinkDisplayMode *display_mode;
-       if (input->DoesSupportVideoMode(bmdModeHD720p5994, bmdFormat8BitYUV, /*flags=*/0, &support, &display_mode)) {
-               fprintf(stderr, "Failed to query display mode for card %d\n", card_index);
+       IDeckLinkDisplayModeIterator *mode_it;
+       if (input->GetDisplayModeIterator(&mode_it) != S_OK) {
+               fprintf(stderr, "Failed to enumerate display modes for card %d\n", card_index);
                exit(1);
        }
 
-       if (support == bmdDisplayModeNotSupported) {
-               fprintf(stderr, "Card %d does not support display mode\n", card_index);
-               exit(1);
-       }
+       for (IDeckLinkDisplayMode *mode_ptr; mode_it->Next(&mode_ptr) == S_OK; mode_ptr->Release()) {
+               VideoMode mode;
+               mode.id = mode_ptr->GetDisplayMode();
 
-       if (display_mode->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
-               fprintf(stderr, "Could not get frame rate for card %d\n", card_index);
-               exit(1);
-       }
+               const char *mode_name;
+               if (mode_ptr->GetName(&mode_name) != S_OK) {
+                       mode.name = "Unknown mode";
+               } else {
+                       mode.name = mode_name;
+               }
 
-       if (input->EnableVideoInput(bmdModeHD720p5994, bmdFormat8BitYUV, 0) != S_OK) {
-               fprintf(stderr, "Failed to set 720p59.94 connection for card %d\n", card_index);
-               exit(1);
+               mode.autodetect = false;
+
+               mode.width = mode_ptr->GetWidth();
+               mode.height = mode_ptr->GetHeight();
+
+               BMDTimeScale frame_rate_num;
+               BMDTimeValue frame_rate_den;
+               if (mode_ptr->GetFrameRate(&frame_rate_den, &frame_rate_num) != S_OK) {
+                       fprintf(stderr, "Could not get frame rate for mode '%s' on card %d\n", mode.name.c_str(), card_index);
+                       exit(1);
+               }
+               mode.frame_rate_num = frame_rate_num;
+               mode.frame_rate_den = frame_rate_den;
+
+               // TODO: Respect the TFF/BFF flag.
+               mode.interlaced = (mode_ptr->GetFieldDominance() == bmdLowerFieldFirst || mode_ptr->GetFieldDominance() == bmdUpperFieldFirst);
        }
 
+       // TODO: Make the user mode selectable.
+       set_video_mode(bmdModeHD720p5994);
+
        if (input->EnableAudioInput(48000, bmdAudioSampleType32bitInteger, 2) != S_OK) {
                fprintf(stderr, "Failed to enable audio input for card %d\n", card_index);
                exit(1);
@@ -346,3 +362,29 @@ void DeckLinkCapture::stop_dequeue_thread()
        }
 }
 
+void DeckLinkCapture::set_video_mode(uint32_t video_mode_id)
+{
+       BMDDisplayModeSupport support;
+       IDeckLinkDisplayMode *display_mode;
+       if (input->DoesSupportVideoMode(video_mode_id, bmdFormat8BitYUV, /*flags=*/0, &support, &display_mode)) {
+               fprintf(stderr, "Failed to query display mode for card %d\n", card_index);
+               exit(1);
+       }
+
+       if (support == bmdDisplayModeNotSupported) {
+               fprintf(stderr, "Card %d does not support display mode\n", card_index);
+               exit(1);
+       }
+
+       if (display_mode->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
+               fprintf(stderr, "Could not get frame rate for card %d\n", card_index);
+               exit(1);
+       }
+
+       if (input->EnableVideoInput(video_mode_id, bmdFormat8BitYUV, 0) != S_OK) {
+               fprintf(stderr, "Failed to set 720p59.94 connection for card %d\n", card_index);
+               exit(1);
+       }
+
+       current_video_mode = video_mode_id;
+}
index 695f9d376325c9729f64956109d784072f52dea8..62723bcee7c73c425bdbffbeab7ec07f1a2e03fd 100644 (file)
@@ -75,11 +75,15 @@ public:
        void start_bm_capture() override;
        void stop_dequeue_thread() override;
 
+       std::vector<VideoMode> get_available_video_modes() const override { return video_modes; }
+       void set_video_mode(uint32_t video_mode_id) override;
+
 private:
        std::atomic<int> refcount{1};
        bool done_init = false;
        std::string description;
        uint16_t timecode = 0;
+       int card_index;
 
        bool has_dequeue_callbacks = false;
        std::function<void()> dequeue_init_callback = nullptr;
@@ -92,6 +96,9 @@ private:
        IDeckLinkInput *input = nullptr;
        BMDTimeValue frame_duration;
        BMDTimeScale time_scale;
+
+       std::vector<VideoMode> video_modes;
+       BMDDisplayMode current_video_mode;
 };
 
 #endif  // !defined(_DECKLINK_CAPTURE_H)