]> git.sesse.net Git - casparcg/blob - modules/decklink/util/util.h
2.1.0: Reverted utf8. To complicated to fully fix for now.
[casparcg] / modules / decklink / util / util.h
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\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 * Author: Robert Nagy, ronag89@gmail.com\r
20 */\r
21 \r
22 #pragma once\r
23 \r
24 #include <common/exception/exceptions.h>\r
25 #include <common/log/log.h>\r
26 #include <core/video_format.h>\r
27 \r
28 #include "../interop/DeckLinkAPI_h.h"\r
29 \r
30 #include <boost/lexical_cast.hpp>\r
31 \r
32 #include <atlbase.h>\r
33 \r
34 #include <string>\r
35 \r
36 namespace caspar { namespace decklink {\r
37         \r
38 static BMDDisplayMode get_decklink_video_format(core::video_format::type fmt) \r
39 {\r
40         switch(fmt)\r
41         {\r
42         case core::video_format::pal:                   return bmdModePAL;\r
43         case core::video_format::ntsc:                  return bmdModeNTSC;\r
44         case core::video_format::x576p2500:             return (BMDDisplayMode)ULONG_MAX;\r
45         case core::video_format::x720p2500:             return (BMDDisplayMode)ULONG_MAX;\r
46         case core::video_format::x720p5000:             return bmdModeHD720p50;\r
47         case core::video_format::x720p5994:             return bmdModeHD720p5994;\r
48         case core::video_format::x720p6000:             return bmdModeHD720p60;\r
49         case core::video_format::x1080p2397:    return bmdModeHD1080p2398;\r
50         case core::video_format::x1080p2400:    return bmdModeHD1080p24;\r
51         case core::video_format::x1080i5000:    return bmdModeHD1080i50;\r
52         case core::video_format::x1080i5994:    return bmdModeHD1080i5994;\r
53         case core::video_format::x1080i6000:    return bmdModeHD1080i6000;\r
54         case core::video_format::x1080p2500:    return bmdModeHD1080p25;\r
55         case core::video_format::x1080p2997:    return bmdModeHD1080p2997;\r
56         case core::video_format::x1080p3000:    return bmdModeHD1080p30;\r
57         case core::video_format::x1080p5000:    return bmdModeHD1080p50;\r
58         default:                                                                return (BMDDisplayMode)ULONG_MAX;\r
59         }\r
60 }\r
61 \r
62 static core::video_format::type get_caspar_video_format(BMDDisplayMode fmt) \r
63 {\r
64         switch(fmt)\r
65         {\r
66         case bmdModePAL:                                                return core::video_format::pal;         \r
67         case bmdModeNTSC:                                               return core::video_format::ntsc;                \r
68         case bmdModeHD720p50:                                   return core::video_format::x720p5000;   \r
69         case bmdModeHD720p5994:                                 return core::video_format::x720p5994;   \r
70         case bmdModeHD720p60:                                   return core::video_format::x720p6000;   \r
71         case bmdModeHD1080p2398:                                return core::video_format::x1080p2397;  \r
72         case bmdModeHD1080p24:                                  return core::video_format::x1080p2400;  \r
73         case bmdModeHD1080i50:                                  return core::video_format::x1080i5000;  \r
74         case bmdModeHD1080i5994:                                return core::video_format::x1080i5994;  \r
75         case bmdModeHD1080i6000:                                return core::video_format::x1080i6000;  \r
76         case bmdModeHD1080p25:                                  return core::video_format::x1080p2500;  \r
77         case bmdModeHD1080p2997:                                return core::video_format::x1080p2997;  \r
78         case bmdModeHD1080p30:                                  return core::video_format::x1080p3000;  \r
79         case bmdModeHD1080p50:                                  return core::video_format::x1080p5000;  \r
80         default:                                                                return core::video_format::invalid;     \r
81         }\r
82 }\r
83 \r
84 template<typename T, typename F>\r
85 BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)\r
86 {\r
87         CComPtr<IDeckLinkDisplayModeIterator> iterator;\r
88         CComPtr<IDeckLinkDisplayMode>             mode;\r
89         \r
90         if(SUCCEEDED(device->GetDisplayModeIterator(&iterator)))\r
91         {\r
92                 while(SUCCEEDED(iterator->Next(&mode)) && \r
93                                 mode != nullptr && \r
94                                 mode->GetDisplayMode() != format){}\r
95         }\r
96 \r
97         if(!mode)\r
98                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device could not find requested video-format.") \r
99                                                                                                  << arg_value_info(boost::lexical_cast<std::string>(format))\r
100                                                                                                  << arg_name_info("format"));\r
101                 \r
102         BMDDisplayModeSupport displayModeSupport;\r
103         if(FAILED(device->DoesSupportVideoMode(mode->GetDisplayMode(), pix_fmt, flag, &displayModeSupport, nullptr)) || displayModeSupport == bmdDisplayModeNotSupported)\r
104                 CASPAR_LOG(warning) << L"Device does not support video-format: " << mode->GetDisplayMode();\r
105                 //BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Device does not support requested video-format.")\r
106                 //                                                                               << arg_value_info(boost::lexical_cast<std::string>(format))\r
107                 //                                                                               << arg_name_info("format"));\r
108         else if(displayModeSupport == bmdDisplayModeSupportedWithConversion)\r
109                 CASPAR_LOG(warning) << L"Device supports video-format with conversion: " << mode->GetDisplayMode();\r
110 \r
111         return mode->GetDisplayMode();\r
112 }\r
113 \r
114 template<typename T, typename F>\r
115 static BMDDisplayMode get_display_mode(const T& device, core::video_format::type fmt, BMDPixelFormat pix_fmt, F flag)\r
116 {       \r
117         return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);\r
118 }\r
119 \r
120 template<typename T>\r
121 static std::wstring get_version(T& iterator)\r
122 {\r
123         CComQIPtr<IDeckLinkAPIInformation> info = iterator;\r
124         if (!info)\r
125                 return L"Unknown";\r
126         \r
127         BSTR ver;               \r
128         info->GetString(BMDDeckLinkAPIVersion, &ver);\r
129                 \r
130         return ver;                                     \r
131 }\r
132 \r
133 static CComPtr<IDeckLink> get_device(size_t device_index)\r
134 {\r
135         CComPtr<IDeckLinkIterator> pDecklinkIterator;\r
136         if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator)))\r
137                 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found."));\r
138                 \r
139         size_t n = 0;\r
140         CComPtr<IDeckLink> decklink;\r
141         while(n < device_index && pDecklinkIterator->Next(&decklink) == S_OK){++n;}     \r
142 \r
143         if(n != device_index || !decklink)\r
144                 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
145                 \r
146         return decklink;\r
147 }\r
148 \r
149 template <typename T>\r
150 static std::wstring get_model_name(const T& device)\r
151 {       \r
152         BSTR pModelName;\r
153         device->GetModelName(&pModelName);\r
154         return std::wstring(pModelName);\r
155 }\r
156 \r
157 }}