FFmpeg
vsrc_gfxcapture_winrt.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #ifndef AVFILTER_VSRC_GFXCAPTURE_WINRT_H
20 #define AVFILTER_VSRC_GFXCAPTURE_WINRT_H
21 
22 extern "C" {
23 #include "config.h"
24 }
25 
26 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0A00
27 #undef _WIN32_WINNT
28 #define _WIN32_WINNT 0x0A00
29 #endif
30 
31 #define WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION 0x130000
32 
33 // work around bug in mingw double-defining IReference<unsigned char> (BYTE == boolean)
34 #define ____FIReference_1_boolean_INTERFACE_DEFINED__
35 
36 #include <windows.h>
37 #include <initguid.h>
38 #include <wrl.h>
39 #include <roapi.h>
40 #include <windows.foundation.h>
41 
42 #include <atomic>
43 #include <functional>
44 #include <memory>
45 
46 // Forward-declare IDirect3DDxgiInterfaceAccess if headers too old
47 #if !HAVE_IDIRECT3DDXGIINTERFACEACCESS
49  MIDL_INTERFACE("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")
50  IDirect3DDxgiInterfaceAccess : public IUnknown
51  {
52  public:
53  IFACEMETHOD(GetInterface)(REFIID iid, _COM_Outptr_ void** p) = 0;
54  };
55 }
56 #ifdef __MINGW32__
57 __CRT_UUID_DECL(Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess,
58  0xa9b3d012, 0x3df2, 0x4ee3, 0xb8, 0xd1, 0x86, 0x95, 0xf4, 0x57, 0xd3, 0xc1)
59 #endif
60 #endif /* !HAVE_IDIRECT3DDXGIINTERFACEACCESS */
61 
62 // Forward-declare IGraphicsCaptureSession5 if headers too old
63 #if !HAVE___X_ABI_CWINDOWS_CGRAPHICS_CCAPTURE_CIGRAPHICSCAPTURESESSION5
64 namespace ABI::Windows ::Graphics::Capture {
65  MIDL_INTERFACE("67C0EA62-1F85-5061-925A-239BE0AC09CB")
66  IGraphicsCaptureSession5 : public IInspectable
67  {
68  public:
69  IFACEMETHOD(get_MinUpdateInterval)(ABI::Windows::Foundation::TimeSpan* value) = 0;
70  IFACEMETHOD(put_MinUpdateInterval)(ABI::Windows::Foundation::TimeSpan value) = 0;
71  };
72 }
73 #ifdef __MINGW32__
74 __CRT_UUID_DECL(ABI::Windows ::Graphics::Capture::IGraphicsCaptureSession5,
75  0x67c0ea62, 0x1f85, 0x5061, 0x92, 0x5a, 0x23, 0x9b, 0xe0, 0xac, 0x09, 0xcb)
76 #endif
77 #endif /* !HAVE___X_ABI_CWINDOWS_CGRAPHICS_CCAPTURE_CIGRAPHICSCAPTURESESSION5 */
78 
79 /****************************************************
80  * Helper class to implement refcounted COM objects *
81  ****************************************************/
82 template<typename... Interfaces>
83 struct FFComObject : Interfaces...
84 {
85  virtual ~FFComObject() = default;
86 
87  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
88  {
89  if (!ppvObject)
90  return E_POINTER;
91 
92  if (query_all<Interfaces...>(riid, ppvObject))
93  {
94  AddRef();
95  return S_OK;
96  }
97 
98  *ppvObject = nullptr;
99  return E_NOINTERFACE;
100  }
101 
102  ULONG STDMETHODCALLTYPE AddRef() override
103  {
104  return ++ref_count;
105  }
106 
107  ULONG STDMETHODCALLTYPE Release() override
108  {
109  ULONG rc = --ref_count;
110  if (rc == 0)
111  delete this;
112  return rc;
113  }
114 
115 private:
116  template <typename Iface, typename... IFaces>
117  bool query_all(REFIID riid, void** ppvObject)
118  {
119  if (riid == __uuidof(Iface)) {
120  *ppvObject = static_cast<Iface*>(this);
121  return true;
122  }
123  if constexpr (sizeof...(IFaces)) {
124  return query_all<IFaces...>(riid, ppvObject);
125  } else if (riid == __uuidof(IUnknown)) {
126  *ppvObject = static_cast<IUnknown*>(static_cast<Iface*>(this));
127  return true;
128  }
129  return false;
130  }
131 
132  std::atomic<ULONG> ref_count { 1 };
133 };
134 
135 /*******************************************
136  * Helper to implement COM/WinRT callbacks *
137  *******************************************/
138 template<class Iface, typename F, typename... Args>
139 struct FFTypedCBHandler : FFComObject<Iface, IAgileObject>
140 {
141  using Func = std::decay_t<F>;
142 
143  explicit FFTypedCBHandler(F&& f) : cb_func(std::forward<F>(f)) {}
144 
145  std::invoke_result_t<Func&, Args...> STDMETHODCALLTYPE Invoke(Args... args) override
146  {
147  if constexpr (std::is_same_v<std::invoke_result_t<Func&, Args...>, HRESULT>) {
148  return cb_func(std::forward<Args>(args)...);
149  } else {
150  cb_func(std::forward<Args>(args)...);
151  return S_OK;
152  }
153  }
154 
155 private:
156  Func cb_func;
157 };
158 
159 template<class Iface, typename... Args, typename F>
160 static Microsoft::WRL::ComPtr<Iface> create_cb_handler(F&& cb_func)
161 {
162  return Microsoft::WRL::ComPtr<Iface>(
163  new FFTypedCBHandler<Iface, F, Args...>(std::forward<F>(cb_func))
164  );
165 }
166 
167 /******************************************
168  * Helpers to implement C style callbacks *
169  ******************************************/
170 template <typename Ret, typename... Args>
172  std::function<Ret(Args...)> fn;
173  static Ret CALLBACK thunk(Args... args, LPARAM lparam) {
174  auto self = reinterpret_cast<Win32Callback*>(lparam);
175  return self->fn(std::forward<Args>(args)...);
176  }
178  LPARAM lparam = 0;
179 };
180 
181 template <typename Ret, typename... Args>
182 auto make_win32_callback(const std::function<Ret(Args...)> &&fn) {
183  using T = Win32Callback<Ret, Args...>;
184  auto res = std::make_unique<T>(T{ std::forward<decltype(fn)>(fn) });
185  res->lparam = reinterpret_cast<LPARAM>(res.get());
186  return res;
187 }
188 #define make_win32_callback(...) make_win32_callback(std::function(__VA_ARGS__))
189 
190 /*****************************
191  * Small convenience helpers *
192  *****************************/
194  typedef HMODULE pointer;
195  void operator()(HMODULE handle) const {
196  if (handle)
197  FreeLibrary(handle);
198  }
199 };
200 typedef std::unique_ptr<HMODULE, HMODULEDeleter> hmodule_ptr_t;
201 
203  typedef HANDLE pointer;
204  void operator()(HANDLE handle) const {
205  if (handle && handle != INVALID_HANDLE_VALUE)
206  CloseHandle(handle);
207  }
208 };
209 typedef std::unique_ptr<HANDLE, HANDLEDeleter> handle_ptr_t;
210 
211 #define HLSL(shader) #shader
212 
213 #endif /* AVFILTER_VSRC_GFXCAPTURE_WINRT_H */
FFTypedCBHandler::Invoke
std::invoke_result_t< Func &, Args... > STDMETHODCALLTYPE Invoke(Args... args) override
Definition: vsrc_gfxcapture_winrt.hpp:147
create_cb_handler
static Microsoft::WRL::ComPtr< Iface > create_cb_handler(F &&cb_func)
Definition: vsrc_gfxcapture_winrt.hpp:160
FFComObject::AddRef
ULONG STDMETHODCALLTYPE AddRef() override
Definition: vsrc_gfxcapture_winrt.hpp:104
FFComObject::query_all
bool query_all(REFIID riid, void **ppvObject)
Definition: vsrc_gfxcapture_winrt.hpp:119
FFTypedCBHandler::Func
std::decay_t< F > Func
Definition: vsrc_gfxcapture_winrt.hpp:143
HANDLEDeleter::pointer
HANDLE pointer
Definition: vsrc_gfxcapture_winrt.hpp:203
F
#define F(x)
HMODULEDeleter::pointer
HMODULE pointer
Definition: vsrc_gfxcapture_winrt.hpp:196
Win32Callback::thunk
static Ret CALLBACK thunk(Args... args, LPARAM lparam)
Definition: vsrc_gfxcapture_winrt.hpp:175
Windows::Graphics::DirectX::Direct3D11
Definition: vsrc_gfxcapture_winrt.hpp:48
Win32Callback::proc
decltype(&Win32Callback::thunk) proc
Definition: vsrc_gfxcapture_winrt.hpp:179
Win32Callback
Definition: vsrc_gfxcapture_winrt.hpp:171
fn
Definition: ops_tmpl_float.c:116
FFTypedCBHandler::FFTypedCBHandler
FFTypedCBHandler(F &&f)
Definition: vsrc_gfxcapture_winrt.hpp:145
T
#define T(x)
Definition: vpx_arith.h:29
Win32Callback::lparam
LPARAM lparam
Definition: vsrc_gfxcapture_winrt.hpp:180
Win32Callback::fn
std::function< Ret(Args...)> fn
Definition: vsrc_gfxcapture_winrt.hpp:174
FFComObject::Release
ULONG STDMETHODCALLTYPE Release() override
Definition: vsrc_gfxcapture_winrt.hpp:109
f
f
Definition: af_crystalizer.c:122
FFComObject::QueryInterface
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override
Definition: vsrc_gfxcapture_winrt.hpp:89
FFTypedCBHandler
Definition: vsrc_gfxcapture_winrt.hpp:139
HMODULEDeleter
Definition: vsrc_gfxcapture_winrt.hpp:193
HANDLEDeleter::operator()
void operator()(HANDLE handle) const
Definition: vsrc_gfxcapture_winrt.hpp:204
handle_ptr_t
std::unique_ptr< HANDLE, HANDLEDeleter > handle_ptr_t
Definition: vsrc_gfxcapture_winrt.hpp:209
forward
static int forward(AudioFWTDNContext *s, const double *in, int in_length, double **out, int *out_length, int ch, uint64_t sn)
Definition: af_afwtdn.c:620
hmodule_ptr_t
std::unique_ptr< HMODULE, HMODULEDeleter > hmodule_ptr_t
Definition: vsrc_gfxcapture_winrt.hpp:200
FFComObject::~FFComObject
virtual ~FFComObject()=default
HANDLEDeleter
Definition: vsrc_gfxcapture_winrt.hpp:202
make_win32_callback
#define make_win32_callback(...)
Definition: vsrc_gfxcapture_winrt.hpp:188
ABI::Windows ::Graphics::Capture::put_MinUpdateInterval
IFACEMETHOD() put_MinUpdateInterval(ABI::Windows::Foundation::TimeSpan value)=0
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFComObject::ref_count
std::atomic< ULONG > ref_count
Definition: vsrc_gfxcapture_winrt.hpp:134
FFComObject
Definition: vsrc_gfxcapture_winrt.hpp:83
HMODULEDeleter::operator()
void operator()(HMODULE handle) const
Definition: vsrc_gfxcapture_winrt.hpp:197
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
FFTypedCBHandler::cb_func
Func cb_func
Definition: vsrc_gfxcapture_winrt.hpp:158