1 // Header for standard system include files.
2
3 // Copyright (c) Microsoft. All rights reserved.
4 //
5 // The MIT License (MIT)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files(the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions :
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 // THE SOFTWARE.
24
25 #pragma once
26
27 #include <collection.h>
28 #include <ppltasks.h>
29
30 #include <wrl\implements.h>
31 #include <wrl\wrappers\corewrappers.h>
32 #include <Roerrorapi.h>
33
34 #include <queue>
35 #include <sstream>
36
37 #include <robuffer.h>
38
39 #include <mfapi.h>
40 #include <mfidl.h>
41 #include <Mferror.h>
42
43 #include <windows.media.h>
44 #include <windows.media.mediaproperties.h>
45
46 namespace AWM = ::ABI::Windows::Media;
47 namespace AWMMp = ::ABI::Windows::Media::MediaProperties;
48 namespace AWFC = ::ABI::Windows::Foundation::Collections;
49 namespace MW = ::Microsoft::WRL;
50 namespace MWD = ::Microsoft::WRL::Details;
51 namespace MWW = ::Microsoft::WRL::Wrappers;
52 namespace WMC = ::Windows::Media::Capture;
53 namespace WF = ::Windows::Foundation;
54 namespace WMMp = ::Windows::Media::MediaProperties;
55 namespace WSS = ::Windows::Storage::Streams;
56
57 // Exception-based error handling
58 #define CHK(statement) {HRESULT _hr = (statement); if (FAILED(_hr)) { throw ref new Platform::COMException(_hr); };}
59 #define CHKNULL(p) {if ((p) == nullptr) { throw ref new Platform::NullReferenceException(L#p); };}
60
61 // Exception-free error handling
62 #define CHK_RETURN(statement) {hr = (statement); if (FAILED(hr)) { return hr; };}
63
64 // Cast a C++/CX msartpointer to an ABI smartpointer
65 template<typename T, typename U>
66 MW::ComPtr<T> As(U^ in)
67 {
68 MW::ComPtr<T> out;
69 CHK(reinterpret_cast<IInspectable*>(in)->QueryInterface(IID_PPV_ARGS(&out)));
70 return out;
71 }
72
73 // Cast an ABI smartpointer
74 template<typename T, typename U>
As(const Microsoft::WRL::ComPtr<U> & in)75 Microsoft::WRL::ComPtr<T> As(const Microsoft::WRL::ComPtr<U>& in)
76 {
77 Microsoft::WRL::ComPtr<T> out;
78 CHK(in.As(&out));
79 return out;
80 }
81
82 // Cast an ABI smartpointer
83 template<typename T, typename U>
As(U * in)84 Microsoft::WRL::ComPtr<T> As(U* in)
85 {
86 Microsoft::WRL::ComPtr<T> out;
87 CHK(in->QueryInterface(IID_PPV_ARGS(&out)));
88 return out;
89 }
90
91 // Get access to bytes in IBuffer
92 inline unsigned char* GetData(_In_ WSS::IBuffer^ buffer)
93 {
94 unsigned char* bytes = nullptr;
95 CHK(As<WSS::IBufferByteAccess>(buffer)->Buffer(&bytes));
96 return bytes;
97 }
98
99 // Class to start and shutdown Media Foundation
100 class AutoMF
101 {
102 public:
AutoMF()103 AutoMF()
104 : _bInitialized(false)
105 {
106 CHK(MFStartup(MF_VERSION));
107 }
108
~AutoMF()109 ~AutoMF()
110 {
111 if (_bInitialized)
112 {
113 (void)MFShutdown();
114 }
115 }
116
117 private:
118 bool _bInitialized;
119 };
120
121 // Class to track error origin
122 template <size_t N>
OriginateError(__in HRESULT hr,__in wchar_t const (& str)[N])123 HRESULT OriginateError(__in HRESULT hr, __in wchar_t const (&str)[N])
124 {
125 if (FAILED(hr))
126 {
127 ::RoOriginateErrorW(hr, N - 1, str);
128 }
129 return hr;
130 }
131
132 // Class to track error origin
OriginateError(__in HRESULT hr)133 inline HRESULT OriginateError(__in HRESULT hr)
134 {
135 if (FAILED(hr))
136 {
137 ::RoOriginateErrorW(hr, 0, nullptr);
138 }
139 return hr;
140 }
141
142 // Converts exceptions into HRESULTs
143 template <typename Lambda>
ExceptionBoundary(Lambda && lambda)144 HRESULT ExceptionBoundary(Lambda&& lambda)
145 {
146 try
147 {
148 lambda();
149 return S_OK;
150 }
151 catch (Platform::Exception^ e)
152 {
153 return e->HResult;
154 }
155 catch (const std::bad_alloc&)
156 {
157 return E_OUTOFMEMORY;
158 }
159 catch (const std::exception&)
160 {
161 return E_FAIL;
162 }
163 }
164
165 // Wraps an IMFSample in a C++/CX class to be able to define a callback delegate
166 ref class MediaSample sealed
167 {
168 internal:
169 MW::ComPtr<IMFSample> Sample;
170 };
171
172 delegate void MediaSampleHandler(MediaSample^ sample);