*/\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
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("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 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