]> git.sesse.net Git - casparcg/blob - modules/decklink/decklink_api.h
* Adapted decklink module changes made in Linux to work in Windows as well (including...
[casparcg] / modules / decklink / decklink_api.h
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 * Author: Helge Norberg, helge.norberg@svt.se
20 */
21
22 #pragma once
23
24 #include <common/except.h>
25
26 #if defined(_MSC_VER)
27
28 #include "interop/DeckLinkAPI.h"
29
30 #pragma warning(push)
31 #pragma warning(disable : 4996)
32
33     #include <atlbase.h>
34
35     #include <atlcom.h>
36     #include <atlhost.h>
37
38 #pragma warning(pop)
39
40 namespace caspar { namespace decklink {
41
42 typedef BSTR String;
43 typedef unsigned int UINT32;
44
45 static void com_initialize()
46 {
47         ::CoInitialize(nullptr);
48 }
49
50 static void com_uninitialize()
51 {
52         ::CoUninitialize();
53 }
54
55 struct co_init
56 {
57     co_init(){ ::CoInitialize(nullptr); }
58     ~co_init(){ ::CoUninitialize(); }
59 };
60
61 template<typename T>
62 using com_ptr = CComPtr<T>;
63
64 // MSVC 2013 crashes when this alias template is instantiated
65 /*template<typename T>
66 using com_iface_ptr = CComQIPtr<T>;*/
67
68 template<typename T>
69 class com_iface_ptr : public CComQIPtr<T>
70 {
71 public:
72         template<typename T2>
73         com_iface_ptr(const com_ptr<T2>& lp)
74                 : CComQIPtr<T>(lp)
75         {
76         }
77 };
78
79 template<template<typename> class P, typename T>
80 static P<T> wrap_raw(T* ptr, bool already_referenced = false)
81 {
82     if (already_referenced)
83     {
84         P<T> p;
85         p.Attach(ptr);
86         return p;
87     }
88     else
89         return P<T>(ptr);
90 }
91
92 static com_ptr<IDeckLinkIterator> create_iterator()
93 {
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;
98 }
99
100 template<typename I, typename T>
101 static com_iface_ptr<I> iface_cast(const com_ptr<T>& ptr)
102 {
103     return com_iface_ptr<I>(ptr);
104 }
105
106 template<typename T>
107 T* get_raw(const CComPtr<T>& ptr)
108 {
109         return ptr;
110 }
111
112 }}
113
114 #else
115
116 #include "linux_interop/DeckLinkAPI.h"
117 #include <memory>
118 #include <typeinfo>
119
120 namespace caspar { namespace decklink {
121
122 typedef const char* String;
123 typedef bool BOOL;
124 #define TRUE true
125 #define FALSE false
126 typedef uint32_t UINT32;
127
128 static void com_initialize()
129 {
130 }
131
132 static void com_uninitialize()
133 {
134 }
135
136 struct co_init
137 {
138     co_init(){ }
139     ~co_init(){ }
140 };
141
142 template<typename T>
143 using com_ptr = std::shared_ptr<T>;
144
145 template<typename T>
146 using com_iface_ptr = std::shared_ptr<T>;
147
148 template<template<typename> class P, typename T>
149 static P<T> wrap_raw(T* ptr, bool already_referenced = false)
150 {
151     if (!already_referenced && ptr)
152         ptr->AddRef();
153
154         return P<T>(ptr, [](T* p)
155         {
156                 if (p)
157                 {
158                         auto remaining_refs = p->Release();
159
160                         //CASPAR_LOG(debug) << "Remaining references for " << typeid(p).name() << " = " << remaining_refs;
161                 }
162         });
163 }
164
165 static com_ptr<IDeckLinkIterator> create_iterator()
166 {
167     IDeckLinkIterator* iterator = CreateDeckLinkIteratorInstance();
168
169     if (iterator == nullptr)
170         CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Decklink drivers not found."));
171
172         return wrap_raw<com_ptr>(iterator, true);
173 }
174
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; }
183
184 template<typename I, typename T>
185 static com_iface_ptr<I> iface_cast(com_ptr<T> ptr)
186 {
187     I* iface;
188     ptr->QueryInterface(iface_id<I>(), reinterpret_cast<void**>(&iface));
189
190         return wrap_raw<com_iface_ptr>(iface, true);
191 }
192
193 template<typename T>
194 T* get_raw(const std::shared_ptr<T>& ptr)
195 {
196         return ptr.get();
197 }
198
199 }}
200
201 #endif