]> git.sesse.net Git - casparcg/blobdiff - modules/decklink/util/util.h
2.0. Updated namespaces.
[casparcg] / modules / decklink / util / util.h
index 803ffe2e9e7b27861790d6f74da7254073da4613..09bca51967ca77e19e1f19d2e0c71570f3bdc3da 100644 (file)
@@ -1,12 +1,39 @@
+/*\r
+* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+*\r
+*  This file is part of CasparCG.\r
+*\r
+*    CasparCG is free software: you can redistribute it and/or modify\r
+*    it under the terms of the GNU General Public License as published by\r
+*    the Free Software Foundation, either version 3 of the License, or\r
+*    (at your option) any later version.\r
+*\r
+*    CasparCG is distributed in the hope that it will be useful,\r
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+*    GNU General Public License for more details.\r
+\r
+*    You should have received a copy of the GNU General Public License\r
+*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
 #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
-namespace caspar { \r
+#include <boost/lexical_cast.hpp>\r
+\r
+#include <atlbase.h>\r
+\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
@@ -25,44 +52,104 @@ 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
-static IDeckLinkDisplayMode* get_display_mode(IDeckLinkOutput* output, BMDDisplayMode format)\r
-{\r
-       IDeckLinkDisplayModeIterator*           iterator;\r
-       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
+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
-       iterator->Release();\r
-       return nullptr;\r
 }\r
 \r
-static IDeckLinkDisplayMode* get_display_mode(IDeckLinkOutput* output, core::video_format::type fmt)\r
+template<typename T, typename F>\r
+BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)\r
 {\r
-       return get_display_mode(output, GetDecklinkVideoFormat(fmt));\r
+       CComPtr<IDeckLinkDisplayModeIterator> iterator;\r
+       CComPtr<IDeckLinkDisplayMode>             mode;\r
+       \r
+       if(SUCCEEDED(device->GetDisplayModeIterator(&iterator)))\r
+       {\r
+               while(SUCCEEDED(iterator->Next(&mode)) && \r
+                               mode != nullptr && \r
+                               mode->GetDisplayMode() != format){}\r
+       }\r
+\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, 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
-static std::wstring get_version(T& deckLinkIterator)\r
+static std::wstring get_version(T& iterator)\r
 {\r
-       IDeckLinkAPIInformation* deckLinkAPIInformation;\r
-       if (FAILED(deckLinkIterator->QueryInterface(IID_IDeckLinkAPIInformation, (void**)&deckLinkAPIInformation)))\r
+       CComQIPtr<IDeckLinkAPIInformation> info = iterator;\r
+       if (!info)\r
                return L"Unknown";\r
        \r
        BSTR ver;               \r
-       deckLinkAPIInformation->GetString(BMDDeckLinkAPIVersion, &ver);\r
-       deckLinkAPIInformation->Release();      \r
+       info->GetString(BMDDeckLinkAPIVersion, &ver);\r
                \r
        return ver;                                     \r
 }\r
 \r
-}
\ No newline at end of file
+static CComPtr<IDeckLink> get_device(size_t device_index)\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
+               \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 device not found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index)));\r
+               \r
+       return decklink;\r
+}\r
+\r
+template <typename T>\r
+static std::wstring get_model_name(const T& device)\r
+{      \r
+       BSTR pModelName;\r
+       device->GetModelName(&pModelName);\r
+       return std::wstring(pModelName);\r
+}\r
+\r
+}}
\ No newline at end of file