]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/util/util.h
Only memcpy on Linux if the decklink card will attempt DMA directly from BGRA buffer...
[casparcg] / modules / decklink / util / util.h
index 73988088eb3b3c2c29246ad4b0eb620368bfb98e..e91a42e2babe374a80b68442305ca315c7940ae9 100644 (file)
@@ -115,8 +115,15 @@ static core::video_format get_caspar_video_format(BMDDisplayMode fmt)
        }
 }
 
+static std::wstring get_mode_name(const com_ptr<IDeckLinkDisplayMode>& mode)
+{
+       String mode_name;
+       mode->GetName(&mode_name);
+       return u16(mode_name);
+}
+
 template<typename T, typename F>
-BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)
+BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag, bool& will_attempt_dma)
 {
     IDeckLinkDisplayMode* m = nullptr;
     IDeckLinkDisplayModeIterator* iter;
@@ -132,28 +139,29 @@ BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixel
        }
 
     if(!m)
-               CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Device could not find requested video-format.") 
-                                                                                                << arg_value_info(boost::lexical_cast<std::string>(format))
-                                                                                                << arg_name_info("format"));
+               CASPAR_THROW_EXCEPTION(user_error() << msg_info("Device could not find requested video-format: " + boost::lexical_cast<std::string>(format)));
 
        com_ptr<IDeckLinkDisplayMode> mode = wrap_raw<com_ptr>(m, true);
 
        BMDDisplayModeSupport displayModeSupport;
-       if(FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)) || displayModeSupport == bmdDisplayModeNotSupported)
-               CASPAR_LOG(warning) << L"Device does not support video-format: " << mode->GetDisplayMode();
-               //CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Device does not support requested video-format.")
-               //                                                                               << arg_value_info(boost::lexical_cast<std::string>(format))
-               //                                                                               << arg_name_info("format"));
-       else if(displayModeSupport == bmdDisplayModeSupportedWithConversion)
-               CASPAR_LOG(warning) << L"Device supports video-format with conversion: " << mode->GetDisplayMode();
+       will_attempt_dma = false;
+
+       if (FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)))
+               CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info(L"Could not determine whether device supports requested video format: " + get_mode_name(mode)));
+       else if (displayModeSupport == bmdDisplayModeNotSupported)
+               CASPAR_LOG(warning) << L"Device does not support video-format: " << get_mode_name(mode);
+       else if (displayModeSupport == bmdDisplayModeSupportedWithConversion)
+               CASPAR_LOG(warning) << L"Device supports video-format with conversion: " << get_mode_name(mode);
+       else
+               will_attempt_dma = true;
 
        return mode->GetDisplayMode();
 }
 
 template<typename T, typename F>
-static BMDDisplayMode get_display_mode(const T& device, core::video_format fmt, BMDPixelFormat pix_fmt, F flag)
+static BMDDisplayMode get_display_mode(const T& device, core::video_format fmt, BMDPixelFormat pix_fmt, F flag, bool& will_attempt_dma)
 {      
-       return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);
+       return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag, will_attempt_dma);
 }
 
 template<typename T>
@@ -184,7 +192,7 @@ static com_ptr<IDeckLink> get_device(size_t device_index)
     }
 
        if(n != device_index || !decklink)
-               CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink device not found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index)));
+               CASPAR_THROW_EXCEPTION(user_error() << msg_info("Decklink device " + boost::lexical_cast<std::string>(device_index) + " not found."));
                
        return decklink;
 }
@@ -197,4 +205,39 @@ static std::wstring get_model_name(const T& device)
     return u16(pModelName);
 }
 
+class reference_signal_detector
+{
+       com_iface_ptr<IDeckLinkOutput>  output_;
+       BMDReferenceStatus                              last_reference_status_  = static_cast<BMDReferenceStatus>(-1);
+public:
+       reference_signal_detector(const com_iface_ptr<IDeckLinkOutput>& output)
+               : output_(output)
+       {
+       }
+
+       template<typename Print>
+       void detect_change(const Print& print)
+       {
+               BMDReferenceStatus reference_status;
+
+               if (output_->GetReferenceStatus(&reference_status) != S_OK)
+               {
+                       CASPAR_LOG(error) << print() << L" Reference signal: failed while querying status";
+               }
+               else if (reference_status != last_reference_status_)
+               {
+                       last_reference_status_ = reference_status;
+
+                       if (reference_status == 0)
+                               CASPAR_LOG(info) << print() << L" Reference signal: not detected.";
+                       else if (reference_status & bmdReferenceNotSupportedByHardware)
+                               CASPAR_LOG(info) << print() << L" Reference signal: not supported by hardware.";
+                       else if (reference_status & bmdReferenceLocked)
+                               CASPAR_LOG(info) << print() << L" Reference signal: locked.";
+                       else
+                               CASPAR_LOG(info) << print() << L" Reference signal: Unhandled enum bitfield: " << reference_status;
+               }
+       }
+};
+
 }}