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> 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> 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: 103 AutoMF() 104 : _bInitialized(false) 105 { 106 CHK(MFStartup(MF_VERSION)); 107 } 108 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> 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 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> 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);