]> git.sesse.net Git - casparcg/blob - modules/decklink/util/util.h
2.0. decklink: Improved error messages.
[casparcg] / modules / decklink / util / util.h
1 /*\r
2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 *  This file is part of CasparCG.\r
5 *\r
6 *    CasparCG is free software: you can redistribute it and/or modify\r
7 *    it under the terms of the GNU General Public License as published by\r
8 *    the Free Software Foundation, either version 3 of the License, or\r
9 *    (at your option) any later version.\r
10 *\r
11 *    CasparCG is distributed in the hope that it will be useful,\r
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 *    GNU General Public License for more details.\r
15 \r
16 *    You should have received a copy of the GNU General Public License\r
17 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 */\r
20 #pragma once\r
21 \r
22 #include <common/exception/exceptions.h>\r
23 #include <core/video_format.h>\r
24 \r
25 #include "../interop/DeckLinkAPI_h.h"\r
26 \r
27 #include <atlbase.h>\r
28 \r
29 namespace caspar { \r
30         \r
31 static BMDDisplayMode get_decklink_video_format(core::video_format::type fmt) \r
32 {\r
33         switch(fmt)\r
34         {\r
35         case core::video_format::pal:                   return bmdModePAL;\r
36         case core::video_format::ntsc:                  return bmdModeNTSC;\r
37         case core::video_format::x576p2500:             return (BMDDisplayMode)ULONG_MAX;\r
38         case core::video_format::x720p2500:             return (BMDDisplayMode)ULONG_MAX;\r
39         case core::video_format::x720p5000:             return bmdModeHD720p50;\r
40         case core::video_format::x720p5994:             return bmdModeHD720p5994;\r
41         case core::video_format::x720p6000:             return bmdModeHD720p60;\r
42         case core::video_format::x1080p2397:    return bmdModeHD1080p2398;\r
43         case core::video_format::x1080p2400:    return bmdModeHD1080p24;\r
44         case core::video_format::x1080i5000:    return bmdModeHD1080i50;\r
45         case core::video_format::x1080i5994:    return bmdModeHD1080i5994;\r
46         case core::video_format::x1080i6000:    return bmdModeHD1080i6000;\r
47         case core::video_format::x1080p2500:    return bmdModeHD1080p25;\r
48         case core::video_format::x1080p2997:    return bmdModeHD1080p2997;\r
49         case core::video_format::x1080p3000:    return bmdModeHD1080p30;\r
50         default:                                                                return (BMDDisplayMode)ULONG_MAX;\r
51         }\r
52 }\r
53 \r
54 static core::video_format::type get_caspar_video_format(BMDDisplayMode fmt) \r
55 {\r
56         switch(fmt)\r
57         {\r
58         case bmdModePAL:                                                return core::video_format::pal;         \r
59         case bmdModeNTSC:                                               return core::video_format::ntsc;                \r
60         case bmdModeHD720p50:                                   return core::video_format::x720p5000;   \r
61         case bmdModeHD720p5994:                                 return core::video_format::x720p5994;   \r
62         case bmdModeHD720p60:                                   return core::video_format::x720p6000;   \r
63         case bmdModeHD1080p2398:                                return core::video_format::x1080p2397;  \r
64         case bmdModeHD1080p24:                                  return core::video_format::x1080p2400;  \r
65         case bmdModeHD1080i50:                                  return core::video_format::x1080i5000;  \r
66         case bmdModeHD1080i5994:                                return core::video_format::x1080i5994;  \r
67         case bmdModeHD1080i6000:                                return core::video_format::x1080i6000;  \r
68         case bmdModeHD1080p25:                                  return core::video_format::x1080p2500;  \r
69         case bmdModeHD1080p2997:                                return core::video_format::x1080p2997;  \r
70         case bmdModeHD1080p30:                                  return core::video_format::x1080p3000;  \r
71         default:                                                                return core::video_format::invalid;     \r
72         }\r
73 }\r
74 \r
75 template<typename T, typename F>\r
76 BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)\r
77 {\r
78         CComPtr<IDeckLinkDisplayModeIterator> iterator;\r
79         CComPtr<IDeckLinkDisplayMode>             mode;\r
80         \r
81         if(SUCCEEDED(device->GetDisplayModeIterator(&iterator)))\r
82         {\r
83                 while(SUCCEEDED(iterator->Next(&mode)) && \r
84                                 mode != nullptr && \r
85                                 mode->GetDisplayMode() != format){}\r
86         }\r
87 \r
88         if(!mode)\r
89                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device could not find requested video-format.") \r
90                                                                                                  << arg_value_info(boost::lexical_cast<std::string>(format))\r
91                                                                                                  << arg_name_info("format"));\r
92                 \r
93         BMDDisplayModeSupport displayModeSupport;\r
94         if(FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)) || displayModeSupport == bmdDisplayModeNotSupported)\r
95                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device does not support requested video-format.")\r
96                                                                                                  << arg_value_info(boost::lexical_cast<std::string>(format))\r
97                                                                                                  << arg_name_info("format"));\r
98         else if(displayModeSupport == bmdDisplayModeSupportedWithConversion)\r
99                 CASPAR_LOG(warning) << L"Device supports video-format with conversion.";\r
100 \r
101         return mode->GetDisplayMode();\r
102 }\r
103 \r
104 template<typename T, typename F>\r
105 static BMDDisplayMode get_display_mode(const T& device, core::video_format::type fmt, BMDPixelFormat pix_fmt, F flag)\r
106 {       \r
107         return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);\r
108 }\r
109 \r
110 template<typename T>\r
111 static std::wstring get_version(T& iterator)\r
112 {\r
113         CComQIPtr<IDeckLinkAPIInformation> info = iterator;\r
114         if (!info)\r
115                 return L"Unknown";\r
116         \r
117         BSTR ver;               \r
118         info->GetString(BMDDeckLinkAPIVersion, &ver);\r
119                 \r
120         return ver;                                     \r
121 }\r
122 \r
123 static CComPtr<IDeckLink> get_device(size_t device_index)\r
124 {\r
125         CComPtr<IDeckLinkIterator> pDecklinkIterator;\r
126         if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator)))\r
127                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No Decklink drivers installed."));\r
128                 \r
129         size_t n = 0;\r
130         CComPtr<IDeckLink> decklink;\r
131         while(n < device_index && pDecklinkIterator->Next(&decklink) == S_OK){++n;}     \r
132 \r
133         if(n != device_index || !decklink)\r
134                 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
135                 \r
136         return decklink;\r
137 }\r
138 \r
139 template <typename T>\r
140 static std::wstring get_model_name(const T& device)\r
141 {       \r
142         BSTR pModelName;\r
143         device->GetModelName(&pModelName);\r
144         return std::wstring(pModelName);\r
145 }\r
146 \r
147 }