• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2020 Seungha Yang <seungha@centricular.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef __GST_MEDIA_CAPTURE_WRAPPER_H__
21 #define __GST_MEDIA_CAPTURE_WRAPPER_H__
22 
23 #include <gst/gst.h>
24 #include <wrl.h>
25 #include <wrl/wrappers/corewrappers.h>
26 #include <windows.media.capture.h>
27 #include <vector>
28 #include <memory>
29 #include <string>
30 #include <functional>
31 #include <mutex>
32 #include <condition_variable>
33 
34 using namespace Microsoft::WRL;
35 using namespace Microsoft::WRL::Wrappers;
36 
37 using namespace ABI::Windows::Foundation;
38 using namespace ABI::Windows::UI::Core;
39 using namespace ABI::Windows::Media::Capture;
40 using namespace ABI::Windows::Media::Capture::Frames;
41 using namespace ABI::Windows::Graphics::Imaging;
42 
43 /* Store Format info and its caps representation */
44 class GstWinRTMediaDescription
45 {
46 public:
47   GstWinRTMediaDescription();
48   GstWinRTMediaDescription(const GstWinRTMediaDescription& other);
49   ~GstWinRTMediaDescription();
50   void Release();
51   bool IsValid() const;
52   HRESULT Fill(HString &source_id,
53                const ComPtr<IMediaCaptureVideoProfileMediaDescription>& desc,
54                unsigned int info_index,
55                unsigned int desc_index);
56 
57   GstWinRTMediaDescription& operator=(const GstWinRTMediaDescription& rhs)
58   {
59     if (this == &rhs)
60       return *this;
61 
62     Release();
63     if (rhs.source_id_.IsValid())
64       rhs.source_id_.CopyTo(source_id_.GetAddressOf());
65     if (rhs.subtype_.IsValid())
66       rhs.subtype_.CopyTo(subtype_.GetAddressOf());
67     gst_caps_replace (&caps_, rhs.caps_);
68 
69     return *this;
70   }
71 
72 public:
73   HString source_id_;
74   /* TODO: need to cover audio too */
75   HString subtype_;
76   /* Source ID which is mapped to MediaFormatSource */
77   GstCaps *caps_;
78 };
79 
80 /* holds GstWinRTMediaFrameSourceInfo, corresponding to per device info */
81 class GstWinRTMediaFrameSourceGroup
82 {
83 public:
84   GstWinRTMediaFrameSourceGroup();
85   GstWinRTMediaFrameSourceGroup(const GstWinRTMediaFrameSourceGroup& other);
86   ~GstWinRTMediaFrameSourceGroup();
87   void Release();
88   bool Contain(const GstWinRTMediaDescription &desc);
89   HRESULT Fill(const ComPtr<IMediaFrameSourceGroup> &source_group,
90                unsigned int index);
91 
92   GstWinRTMediaFrameSourceGroup& operator=(const GstWinRTMediaFrameSourceGroup& rhs)
93   {
94     if (this == &rhs)
95       return *this;
96 
97     Release();
98     id_ = rhs.id_;
99     display_name_ = rhs.display_name_;
100     source_group_ = rhs.source_group_;
101     source_list_ = rhs.source_list_;
102 
103     return *this;
104   }
105 
106 public:
107   std::string id_;
108   std::string display_name_;
109   ComPtr<IMediaFrameSourceGroup> source_group_;
110   std::vector<GstWinRTMediaDescription> source_list_;
111 };
112 
113 typedef struct
114 {
115   HRESULT (*frame_arrived) (IMediaFrameReference * frame,
116                             void * user_data);
117   HRESULT (*failed)        (const std::string &error,
118                             UINT32 error_code,
119                             void * user_data);
120 } MediaCaptureWrapperCallbacks;
121 class MediaCaptureWrapper
122 {
123 public:
124   MediaCaptureWrapper(gpointer dispatcher);
125   ~MediaCaptureWrapper();
126 
127   void RegisterCb(const MediaCaptureWrapperCallbacks &cb,
128                   void * user_data);
129 
130   /* Enumerating available source devices */
131   /* Fill enumerated device infos into list */
132   HRESULT EnumrateFrameSourceGroup(std::vector<GstWinRTMediaFrameSourceGroup> &group_list);
133   /* Select target device which should be one of enumerated be fore */
134   HRESULT SetSourceGroup(const GstWinRTMediaFrameSourceGroup &group);
135   /* Select target format (resolution, video format) to use */
136   HRESULT SetMediaDescription(const GstWinRTMediaDescription &desc);
137 
138   /* Start and Stop capturing operation */
139   HRESULT StartCapture();
140   HRESULT StopCapture();
141   HRESULT GetAvailableDescriptions(std::vector<GstWinRTMediaDescription> &desc_list);
142 
143 private:
144   ComPtr<IMediaCapture> media_capture_;
145   ComPtr<IMediaFrameReader> frame_reader_;
146   ComPtr<ICoreDispatcher> dispatcher_;
147   bool init_done_;
148   std::mutex lock_;
149   std::condition_variable cond_;
150 
151   EventRegistrationToken token_frame_arrived_;
152   EventRegistrationToken token_capture_failed_;
153 
154   std::unique_ptr<GstWinRTMediaFrameSourceGroup> source_group_;
155   std::unique_ptr<GstWinRTMediaDescription> media_desc_;
156   MediaCaptureWrapperCallbacks user_cb_;
157   void *user_data_;
158 
159 private:
160   HRESULT openMediaCapture();
161   HRESULT mediaCaptureInitPre();
162   HRESULT mediaCaptureInitPost(ComPtr<IAsyncAction> init_async,
163                                ComPtr<IMediaCapture> media_capture);
164   HRESULT startCapture();
165   HRESULT stopCapture();
166   HRESULT onFrameArrived(IMediaFrameReader *reader,
167                          IMediaFrameArrivedEventArgs *args);
168   HRESULT onCaptureFailed(IMediaCapture *capture,
169                           IMediaCaptureFailedEventArgs *args);
170   static HRESULT enumrateFrameSourceGroup(std::vector<GstWinRTMediaFrameSourceGroup> &list);
171 };
172 
173 HRESULT
174 FindCoreDispatcherForCurrentThread(ICoreDispatcher ** dispatcher);
175 
176 bool
177 WinRTCapsCompareFunc(const GstWinRTMediaDescription & a,
178                      const GstWinRTMediaDescription & b);
179 
180 #endif /* __GST_MEDIA_CAPTURE_WRAPPER_H__ */