| ARX 1.0 The next-generation open source augmented reality toolkit.

Loading...
Searching...
No Matches
MediaSink.h
Go to the documentation of this file.
1//*@@@+++@@@@******************************************************************
2//
3// Microsoft Windows Media Foundation
4// Copyright (C) Microsoft Corporation. All rights reserved.
5//
6//*@@@---@@@@******************************************************************
7
8#pragma once
9
10 namespace Media {
11
12 const unsigned int c_audioStreamSinkId = 0;
13 const unsigned int c_videoStreamSinkId = 1;
14
15 class MediaSink WrlSealed
16 : public MW::RuntimeClass<
17 MW::RuntimeClassFlags<
18 MW::RuntimeClassType::WinRtClassicComMix>
19 , AWM::IMediaExtension
20 , IMFMediaSink
21 , IMFClockStateSink
22 , MW::FtmBase
23 >
24{
25 InspectableClass(L"MediaSink", BaseTrust)
26
27 public:
28
29 MediaSink(
30 _In_opt_ WMMp::AudioEncodingProperties^ audioProps,
31 _In_opt_ WMMp::VideoEncodingProperties^ videoProps,
32 _In_opt_ MediaSampleHandler^ audioSampleHandler,
33 _In_opt_ MediaSampleHandler^ videoSampleHandler
34 )
35 : _shutdown(false)
36 {
37 MW::ComPtr<IMFMediaType> audioMT;
38 if (audioProps != nullptr)
39 {
40 CHK(MFCreateMediaTypeFromProperties(As<IUnknown>(audioProps).Get(), &audioMT));
41 _audioStreamSink = MW::Make<MediaStreamSink>(
42 this,
43 c_audioStreamSinkId,
44 audioMT,
45 audioSampleHandler
46 );
47 }
48
49 MW::ComPtr<IMFMediaType> videoMT;
50 if (videoProps != nullptr)
51 {
52 CHK(MFCreateMediaTypeFromProperties(As<IUnknown>(videoProps).Get(), &videoMT));
53 _videoStreamSink = MW::Make<MediaStreamSink>(
54 this,
55 c_videoStreamSinkId,
56 videoMT,
57 videoSampleHandler
58 );
59 }
60 }
61
62 void RequestAudioSample()
63 {
64 auto lock = _lock.LockExclusive();
65
66 _VerifyNotShutdown();
67
68 _audioStreamSink->RequestSample();
69 }
70
71 void RequestVideoSample()
72 {
73 auto lock = _lock.LockExclusive();
74
75 _VerifyNotShutdown();
76
77 _videoStreamSink->RequestSample();
78 }
79
80 void SetCurrentAudioMediaType(_In_ IMFMediaType* mt)
81 {
82 auto lock = _lock.LockExclusive();
83
84 _VerifyNotShutdown();
85
86 _audioStreamSink->InternalSetCurrentMediaType(mt);
87 }
88
89 void SetCurrentVideoMediaType(_In_ IMFMediaType* mt)
90 {
91 auto lock = _lock.LockExclusive();
92
93 _VerifyNotShutdown();
94
95 _videoStreamSink->InternalSetCurrentMediaType(mt);
96 }
97
98 //
99 // IMediaExtension
100 //
101
102 IFACEMETHODIMP SetProperties(_In_ AWFC::IPropertySet * /*configuration*/)
103 {
104 return ExceptionBoundary([this]()
105 {
106 auto lock = _lock.LockExclusive();
107
108 _VerifyNotShutdown();
109 });
110 }
111
112 //
113 // IMFMediaSink
114 //
115
116 IFACEMETHODIMP GetCharacteristics(_Out_ DWORD *characteristics)
117 {
118 return ExceptionBoundary([this, characteristics]()
119 {
120 _VerifyNotShutdown();
121
122 CHKNULL(characteristics);
123 *characteristics = MEDIASINK_RATELESS | MEDIASINK_FIXED_STREAMS;
124 });
125 }
126
127 IFACEMETHODIMP AddStreamSink(
128 DWORD /*streamSinkIdentifier*/,
129 _In_ IMFMediaType * /*mediaType*/,
130 _COM_Outptr_ IMFStreamSink **streamSink
131 )
132 {
133 return ExceptionBoundary([this, streamSink]()
134 {
135 _VerifyNotShutdown();
136
137 CHKNULL(streamSink);
138 *streamSink = nullptr;
139
140 CHK(MF_E_STREAMSINKS_FIXED);
141 });
142 }
143
144 IFACEMETHODIMP RemoveStreamSink(DWORD /*streamSinkIdentifier*/)
145 {
146 return ExceptionBoundary([this]()
147 {
148 _VerifyNotShutdown();
149
150 CHK(MF_E_STREAMSINKS_FIXED);
151 });
152 }
153
154 IFACEMETHODIMP GetStreamSinkCount(_Out_ DWORD *streamSinkCount)
155 {
156 return ExceptionBoundary([this, streamSinkCount]()
157 {
158 CHKNULL(streamSinkCount);
159
160 _VerifyNotShutdown();
161
162 *streamSinkCount = (_audioStreamSink != nullptr) + (_videoStreamSink != nullptr);
163 });
164 }
165
166 IFACEMETHODIMP GetStreamSinkByIndex(DWORD index, _COM_Outptr_ IMFStreamSink **streamSink)
167 {
168 return ExceptionBoundary([this, index, streamSink]()
169 {
170 auto lock = _lock.LockExclusive();
171
172 CHKNULL(streamSink);
173 *streamSink = nullptr;
174
175 _VerifyNotShutdown();
176
177 switch (index)
178 {
179 case 0:
180 if (_audioStreamSink != nullptr)
181 {
182 CHK(_audioStreamSink.CopyTo(streamSink));
183 }
184 else
185 {
186 CHK(_videoStreamSink.CopyTo(streamSink));
187 }
188 break;
189
190 case 1:
191 if ((_audioStreamSink != nullptr) && (_videoStreamSink != nullptr))
192 {
193 CHK(_videoStreamSink.CopyTo(streamSink));
194 }
195 else
196 {
197 CHK(E_INVALIDARG);
198 }
199 break;
200
201 default:
202 CHK(E_INVALIDARG);
203 }
204 });
205 }
206
207 IFACEMETHODIMP GetStreamSinkById(DWORD identifier, _COM_Outptr_ IMFStreamSink **streamSink)
208 {
209 return ExceptionBoundary([this, identifier, streamSink]()
210 {
211 auto lock = _lock.LockExclusive();
212
213 CHKNULL(streamSink);
214 *streamSink = nullptr;
215
216 _VerifyNotShutdown();
217
218 if ((identifier == 0) && (_audioStreamSink != nullptr))
219 {
220 CHK(_audioStreamSink.CopyTo(streamSink));
221 }
222 else if ((identifier == 1) && (_videoStreamSink != nullptr))
223 {
224 CHK(_videoStreamSink.CopyTo(streamSink));
225 }
226 else
227 {
228 CHK(E_INVALIDARG);
229 }
230 });
231 }
232
233 IFACEMETHODIMP SetPresentationClock(_In_ IMFPresentationClock *clock)
234 {
235 return ExceptionBoundary([this, clock]()
236 {
237 auto lock = _lock.LockExclusive();
238
239 _VerifyNotShutdown();
240
241 if (_clock != nullptr)
242 {
243 CHK(_clock->RemoveClockStateSink(this));
244 _clock = nullptr;
245 }
246
247 if (clock != nullptr)
248 {
249 CHK(clock->AddClockStateSink(this));
250 _clock = clock;
251 }
252 });
253 }
254
255 IFACEMETHODIMP GetPresentationClock(_COM_Outptr_ IMFPresentationClock **clock)
256 {
257 return ExceptionBoundary([this, clock]()
258 {
259 auto lock = _lock.LockExclusive();
260
261 CHKNULL(clock);
262 *clock = nullptr;
263
264 _VerifyNotShutdown();
265
266 if (_clock != nullptr)
267 {
268 CHK(_clock.CopyTo(clock))
269 }
270 });
271 }
272
273 IFACEMETHODIMP Shutdown()
274 {
275 return ExceptionBoundary([this]()
276 {
277 auto lock = _lock.LockExclusive();
278
279 if (_shutdown)
280 {
281 return;
282 }
283 _shutdown = true;
284
285 if (_audioStreamSink != nullptr)
286 {
287 _audioStreamSink->Shutdown();
288 _audioStreamSink = nullptr;
289 }
290
291 if (_videoStreamSink != nullptr)
292 {
293 _videoStreamSink->Shutdown();
294 _videoStreamSink = nullptr;
295 }
296
297 if (_clock != nullptr)
298 {
299 (void)_clock->RemoveClockStateSink(this);
300 _clock = nullptr;
301 }
302 });
303 }
304
305 //
306 // IMFClockStateSink methods
307 //
308
309 IFACEMETHODIMP OnClockStart(MFTIME /*hnsSystemTime*/, LONGLONG /*llClockStartOffset*/)
310 {
311 return ExceptionBoundary([this]()
312 {
313 auto lock = _lock.LockExclusive();
314
315 _VerifyNotShutdown();
316 });
317 }
318
319 IFACEMETHODIMP OnClockStop(MFTIME /*hnsSystemTime*/)
320 {
321 return ExceptionBoundary([this]()
322 {
323 auto lock = _lock.LockExclusive();
324
325 _VerifyNotShutdown();
326 });
327 }
328
329 IFACEMETHODIMP OnClockPause(MFTIME /*hnsSystemTime*/)
330 {
331 return ExceptionBoundary([this]()
332 {
333 auto lock = _lock.LockExclusive();
334
335 _VerifyNotShutdown();
336 });
337 }
338
339 IFACEMETHODIMP OnClockRestart(MFTIME /*hnsSystemTime*/)
340 {
341 return ExceptionBoundary([this]()
342 {
343 auto lock = _lock.LockExclusive();
344
345 _VerifyNotShutdown();
346 });
347 }
348
349 IFACEMETHODIMP OnClockSetRate(MFTIME /*hnsSystemTime*/, float /*flRate*/)
350 {
351 return ExceptionBoundary([this]()
352 {
353 auto lock = _lock.LockExclusive();
354
355 _VerifyNotShutdown();
356 });
357 }
358
359 private:
360
361 bool _shutdown;
362
363 void _VerifyNotShutdown()
364 {
365 if (_shutdown)
366 {
367 CHK(MF_E_SHUTDOWN);
368 }
369 }
370
371 MW::ComPtr<MediaStreamSink> _audioStreamSink;
372 MW::ComPtr<MediaStreamSink> _videoStreamSink;
373 MW::ComPtr<IMFPresentationClock> _clock;
374
375 MWW::SRWLock _lock;
376};
377
378}
CHKNULL
#define CHKNULL(p)
Definition: MFIncludes.h:40
ExceptionBoundary
HRESULT ExceptionBoundary(Lambda &&lambda)
Definition: MFIncludes.h:125
CHK
#define CHK(statement)
Definition: MFIncludes.h:39
Media::WrlSealed
Definition: MediaSink.h:24
Media
Definition: CaptureFrameGrabber.h:15
Media::c_audioStreamSinkId
const unsigned int c_audioStreamSinkId
Definition: MediaSink.h:12
Media::c_videoStreamSinkId
const unsigned int c_videoStreamSinkId
Definition: MediaSink.h:13
Media::MediaSampleHandler
delegate void MediaSampleHandler(MediaSample^ sample)