FFmpeg
Loading...
Searching...
No Matches
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
22extern "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
64namespace 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 ****************************************************/
82template<typename... Interfaces>
83struct 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
115private:
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 *******************************************/
138template<class Iface, typename F, typename... Args>
139struct 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
155private:
157};
158
159template<class Iface, typename... Args, typename F>
160static Microsoft::WRL::ComPtr<Iface> create_cb_handler(F&& cb_func)
161{
162 Microsoft::WRL::ComPtr<Iface> res;
163 res.Attach(new FFTypedCBHandler<Iface, F, Args...>(std::forward<F>(cb_func)));
164 return res;
165}
166
167/******************************************
168 * Helpers to implement C style callbacks *
169 ******************************************/
170template <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
181template <typename Ret, typename... Args>
182auto 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};
200typedef 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};
209typedef std::unique_ptr<HANDLE, HANDLEDeleter> handle_ptr_t;
210
211#define HLSL(shader) #shader
212
213#endif /* AVFILTER_VSRC_GFXCAPTURE_WINRT_H */
#define fn(a)
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
#define T(x)
Definition vpx_arith.h:29
#define f(width, name)
Definition cbs_vp8.c:236
#define F(x)
double value
Definition eval.c:102
IFACEMETHOD put_MinUpdateInterval(ABI::Windows::Foundation::TimeSpan value)=0
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
bool query_all(REFIID riid, void **ppvObject)
ULONG STDMETHODCALLTYPE AddRef() override
ULONG STDMETHODCALLTYPE Release() override
virtual ~FFComObject()=default
std::atomic< ULONG > ref_count
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override
std::invoke_result_t< Func &, Args... > STDMETHODCALLTYPE Invoke(Args... args) override
void operator()(HANDLE handle) const
void operator()(HMODULE handle) const
static Ret CALLBACK thunk(Args... args, LPARAM lparam)
std::function< Ret(Args...)> fn
decltype(&Win32Callback::thunk) proc
std::unique_ptr< HMODULE, HMODULEDeleter > hmodule_ptr_t
static Microsoft::WRL::ComPtr< Iface > create_cb_handler(F &&cb_func)
std::unique_ptr< HANDLE, HANDLEDeleter > handle_ptr_t
#define make_win32_callback(...)