]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/util/util.h
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / modules / decklink / util / util.h
index d005711a4e05641cd1e9d54ab0008687f0637891..c733a319d1e6753b90d0d832a282aa96bb74c885 100644 (file)
 #pragma once\r
 \r
 #include <common/exception/exceptions.h>\r
+#include <common/log/log.h>\r
 #include <core/video_format.h>\r
 \r
 #include "../interop/DeckLinkAPI_h.h"\r
 \r
+#include <boost/lexical_cast.hpp>\r
+\r
 #include <atlbase.h>\r
 \r
-namespace caspar { \r
+#include <string>\r
+\r
+namespace caspar { namespace decklink {\r
        \r
-static BMDDisplayMode GetDecklinkVideoFormat(core::video_format::type fmt) \r
+static BMDDisplayMode get_decklink_video_format(core::video_format::type fmt) \r
 {\r
        switch(fmt)\r
        {\r
@@ -47,32 +52,67 @@ static BMDDisplayMode GetDecklinkVideoFormat(core::video_format::type fmt)
        case core::video_format::x1080p2500:    return bmdModeHD1080p25;\r
        case core::video_format::x1080p2997:    return bmdModeHD1080p2997;\r
        case core::video_format::x1080p3000:    return bmdModeHD1080p30;\r
-       default:                                                return (BMDDisplayMode)ULONG_MAX;\r
+       case core::video_format::x1080p5000:    return bmdModeHD1080p50;\r
+       default:                                                                return (BMDDisplayMode)ULONG_MAX;\r
        }\r
 }\r
-       \r
-template<typename T>\r
-static IDeckLinkDisplayMode* get_display_mode(const T& output, BMDDisplayMode format)\r
+\r
+static core::video_format::type get_caspar_video_format(BMDDisplayMode fmt) \r
+{\r
+       switch(fmt)\r
+       {\r
+       case bmdModePAL:                                                return core::video_format::pal;         \r
+       case bmdModeNTSC:                                               return core::video_format::ntsc;                \r
+       case bmdModeHD720p50:                                   return core::video_format::x720p5000;   \r
+       case bmdModeHD720p5994:                                 return core::video_format::x720p5994;   \r
+       case bmdModeHD720p60:                                   return core::video_format::x720p6000;   \r
+       case bmdModeHD1080p2398:                                return core::video_format::x1080p2397;  \r
+       case bmdModeHD1080p24:                                  return core::video_format::x1080p2400;  \r
+       case bmdModeHD1080i50:                                  return core::video_format::x1080i5000;  \r
+       case bmdModeHD1080i5994:                                return core::video_format::x1080i5994;  \r
+       case bmdModeHD1080i6000:                                return core::video_format::x1080i6000;  \r
+       case bmdModeHD1080p25:                                  return core::video_format::x1080p2500;  \r
+       case bmdModeHD1080p2997:                                return core::video_format::x1080p2997;  \r
+       case bmdModeHD1080p30:                                  return core::video_format::x1080p3000;  \r
+       case bmdModeHD1080p50:                                  return core::video_format::x1080p5000;  \r
+       default:                                                                return core::video_format::invalid;     \r
+       }\r
+}\r
+\r
+template<typename T, typename F>\r
+BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)\r
 {\r
        CComPtr<IDeckLinkDisplayModeIterator> iterator;\r
-       IDeckLinkDisplayMode*                           mode;\r
+       CComPtr<IDeckLinkDisplayMode>             mode;\r
        \r
-       if(FAILED(output->GetDisplayModeIterator(&iterator)))\r
-               return nullptr;\r
-\r
-       while(SUCCEEDED(iterator->Next(&mode)) && mode != nullptr)\r
-       {       \r
-               if(mode->GetDisplayMode() == format)\r
-                       return mode;\r
+       if(SUCCEEDED(device->GetDisplayModeIterator(&iterator)))\r
+       {\r
+               while(SUCCEEDED(iterator->Next(&mode)) && \r
+                               mode != nullptr && \r
+                               mode->GetDisplayMode() != format){}\r
        }\r
 \r
-       return nullptr;\r
+       if(!mode)\r
+               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device could not find requested video-format.") \r
+                                                                                                << arg_value_info(boost::lexical_cast<std::string>(format))\r
+                                                                                                << arg_name_info("format"));\r
+               \r
+       BMDDisplayModeSupport displayModeSupport;\r
+       if(FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)) || displayModeSupport == bmdDisplayModeNotSupported)\r
+               CASPAR_LOG(warning) << L"Device does not support video-format.";\r
+               //BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device does not support requested video-format.")\r
+               //                                                                               << arg_value_info(boost::lexical_cast<std::string>(format))\r
+               //                                                                               << arg_name_info("format"));\r
+       else if(displayModeSupport == bmdDisplayModeSupportedWithConversion)\r
+               CASPAR_LOG(warning) << L"Device supports video-format with conversion.";\r
+\r
+       return mode->GetDisplayMode();\r
 }\r
 \r
-template<typename T>\r
-static IDeckLinkDisplayMode* get_display_mode(const T& output, core::video_format::type fmt)\r
-{\r
-       return get_display_mode(output, GetDecklinkVideoFormat(fmt));\r
+template<typename T, typename F>\r
+static BMDDisplayMode get_display_mode(const T& device, core::video_format::type fmt, BMDPixelFormat pix_fmt, F flag)\r
+{      \r
+       return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);\r
 }\r
 \r
 template<typename T>\r
@@ -90,17 +130,16 @@ static std::wstring get_version(T& iterator)
 \r
 static CComPtr<IDeckLink> get_device(size_t device_index)\r
 {\r
-       CComPtr<IDeckLink> decklink;\r
-\r
        CComPtr<IDeckLinkIterator> pDecklinkIterator;\r
        if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator)))\r
-               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No Decklink drivers installed."));\r
+               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found."));\r
                \r
        size_t n = 0;\r
+       CComPtr<IDeckLink> decklink;\r
        while(n < device_index && pDecklinkIterator->Next(&decklink) == S_OK){++n;}     \r
 \r
        if(n != device_index || !decklink)\r
-               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink card not found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index)));\r
+               BOOST_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)));\r
                \r
        return decklink;\r
 }\r
@@ -113,4 +152,4 @@ static std::wstring get_model_name(const T& device)
        return std::wstring(pModelName);\r
 }\r
 \r
-}
\ No newline at end of file
+}}
\ No newline at end of file