2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Helge Norberg, helge.norberg@svt.se
24 #include <common/except.h>
28 #include "interop/DeckLinkAPI.h"
31 #pragma warning(disable : 4996)
40 namespace caspar { namespace decklink {
43 typedef unsigned int UINT32;
45 static void com_initialize()
47 ::CoInitialize(nullptr);
50 static void com_uninitialize()
57 co_init(){ ::CoInitialize(nullptr); }
58 ~co_init(){ ::CoUninitialize(); }
62 using com_ptr = CComPtr<T>;
64 // MSVC 2013 crashes when this alias template is instantiated
65 /*template<typename T>
66 using com_iface_ptr = CComQIPtr<T>;*/
69 class com_iface_ptr : public CComQIPtr<T>
73 com_iface_ptr(const com_ptr<T2>& lp)
79 template<template<typename> class P, typename T>
80 static P<T> wrap_raw(T* ptr, bool already_referenced = false)
82 if (already_referenced)
92 static com_ptr<IDeckLinkIterator> create_iterator()
94 CComPtr<IDeckLinkIterator> pDecklinkIterator;
95 if(FAILED(pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator)))
96 CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found."));
97 return pDecklinkIterator;
100 template<typename I, typename T>
101 static com_iface_ptr<I> iface_cast(const com_ptr<T>& ptr)
103 return com_iface_ptr<I>(ptr);
107 T* get_raw(const CComPtr<T>& ptr)
116 #include "linux_interop/DeckLinkAPI.h"
120 namespace caspar { namespace decklink {
122 typedef const char* String;
126 typedef uint32_t UINT32;
128 static void com_initialize()
132 static void com_uninitialize()
143 using com_ptr = std::shared_ptr<T>;
146 using com_iface_ptr = std::shared_ptr<T>;
148 template<template<typename> class P, typename T>
149 static P<T> wrap_raw(T* ptr, bool already_referenced = false)
151 if (!already_referenced && ptr)
154 return P<T>(ptr, [](T* p)
158 auto remaining_refs = p->Release();
160 //CASPAR_LOG(debug) << "Remaining references for " << typeid(p).name() << " = " << remaining_refs;
165 static com_ptr<IDeckLinkIterator> create_iterator()
167 IDeckLinkIterator* iterator = CreateDeckLinkIteratorInstance();
169 if (iterator == nullptr)
170 CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found."));
172 return wrap_raw<com_ptr>(iterator, true);
175 template<typename T> static REFIID iface_id() { return T::REFID; }
176 template<> REFIID iface_id<IDeckLink>() { return IID_IDeckLink; }
177 template<> REFIID iface_id<IDeckLinkOutput>() { return IID_IDeckLinkOutput; }
178 template<> REFIID iface_id<IDeckLinkAPIInformation>() { return IID_IDeckLinkAPIInformation; }
179 template<> REFIID iface_id<IDeckLinkConfiguration>() { return IID_IDeckLinkConfiguration; }
180 template<> REFIID iface_id<IDeckLinkKeyer>() { return IID_IDeckLinkKeyer; }
181 template<> REFIID iface_id<IDeckLinkAttributes>() { return IID_IDeckLinkAttributes; }
182 template<> REFIID iface_id<IDeckLinkInput>() { return IID_IDeckLinkInput; }
184 template<typename I, typename T>
185 static com_iface_ptr<I> iface_cast(com_ptr<T> ptr)
188 ptr->QueryInterface(iface_id<I>(), reinterpret_cast<void**>(&iface));
190 return wrap_raw<com_iface_ptr>(iface, true);
194 T* get_raw(const std::shared_ptr<T>& ptr)