2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
\r
4 * This file is part of CasparCG (www.casparcg.com).
\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
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
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
19 * Author: Robert Nagy, ronag89@gmail.com
\r
24 #include <common/exception/exceptions.h>
\r
25 #include <common/log/log.h>
\r
26 #include <core/video_format.h>
\r
28 #include "../interop/DeckLinkAPI_h.h"
\r
30 #include <boost/lexical_cast.hpp>
\r
32 #include <atlbase.h>
\r
36 namespace caspar { namespace decklink {
\r
38 static BMDDisplayMode get_decklink_video_format(core::video_format::type fmt)
\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
62 static core::video_format::type get_caspar_video_format(BMDDisplayMode fmt)
\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
84 template<typename T, typename F>
\r
85 BMDDisplayMode get_display_mode(const T& device, BMDDisplayMode format, BMDPixelFormat pix_fmt, F flag)
\r
87 CComPtr<IDeckLinkDisplayModeIterator> iterator;
\r
88 CComPtr<IDeckLinkDisplayMode> mode;
\r
90 if(SUCCEEDED(device->GetDisplayModeIterator(&iterator)))
\r
92 while(SUCCEEDED(iterator->Next(&mode)) &&
\r
94 mode->GetDisplayMode() != format){}
\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
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
111 return mode->GetDisplayMode();
\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
117 return get_display_mode(device, get_decklink_video_format(fmt), pix_fmt, flag);
\r
120 template<typename T>
\r
121 static std::wstring get_version(T& iterator)
\r
123 CComQIPtr<IDeckLinkAPIInformation> info = iterator;
\r
128 info->GetString(BMDDeckLinkAPIVersion, &ver);
\r
133 static CComPtr<IDeckLink> get_device(size_t device_index)
\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
140 CComPtr<IDeckLink> decklink;
\r
141 while(n < device_index && pDecklinkIterator->Next(&decklink) == S_OK){++n;}
\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
149 template <typename T>
\r
150 static std::wstring get_model_name(const T& device)
\r
153 device->GetModelName(&pModelName);
\r
154 return std::wstring(pModelName);
\r