├── FrameProviderSample ├── DefaultResource.rc ├── FrameManager.cpp ├── FrameManager.h ├── FrameProvider.cpp ├── FrameProvider.h ├── FrameProviderSample.reg ├── FrameProviderSample.sln ├── FrameProviderSample.vcxproj ├── FrameProviderSample.vcxproj.filters ├── MFT0 │ ├── FrameProviderMft0.cpp │ ├── FrameProviderMft0.h │ ├── FrameProviderSampleMft0.cpp │ ├── FrameProviderSampleMft0.def │ ├── FrameProviderSampleMft0.idl │ ├── FrameProviderSampleMft0.rc │ ├── FrameProviderSampleMft0.rgs │ ├── FrameProviderSampleMft0.vcxproj │ ├── FrameProviderSampleMft0.vcxproj.Filters │ ├── FrameProviderSampleMft0_h.h │ ├── FrameProviderSampleMft0_i.c │ ├── FrameProviderSampleMft0_p.c │ ├── Mft0.rgs │ ├── SampleHelpers.h │ ├── dlldata.c │ ├── dllmain.cpp │ ├── dllmain.h │ ├── resource.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── MediaDeviceManager.cpp ├── MediaDeviceManager.h ├── MediaFoundationWrapper.cpp ├── MediaFoundationWrapper.h ├── MemoryBufferAccess.h ├── Readme.txt ├── VideoSourceDescription.cpp ├── VideoSourceDescription.h ├── pch.cpp └── pch.h ├── ProviderTest ├── FaceAlignmentTestApi.dll ├── FaceVerificationTestApi.dll ├── FrameProviderToolHelper.dll ├── WindowsHelloFPV.exe └── WindowsHelloFrameProviderValidation.dll ├── README.md └── SECURITY.md /FrameProviderSample/DefaultResource.rc: -------------------------------------------------------------------------------- 1 | //Autogenerated file name + version resource file for Device Guard whitelisting effort 2 | 3 | #include 4 | #include 5 | 6 | #define VER_FILETYPE VFT_UNKNOWN 7 | #define VER_FILESUBTYPE VFT2_UNKNOWN 8 | #define VER_FILEDESCRIPTION_STR ___TARGETNAME 9 | #define VER_INTERNALNAME_STR ___TARGETNAME 10 | #define VER_ORIGINALFILENAME_STR ___TARGETNAME 11 | 12 | #include "common.ver" 13 | -------------------------------------------------------------------------------- /FrameProviderSample/FrameManager.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "pch.h" 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | SampleFrameProviderManager::SampleFrameProviderManager() : 17 | _providerMap(ref new Platform::Collections::Map(std::less())), 18 | _controlGroup(nullptr), 19 | _faceAuthGroup(nullptr), 20 | _deviceWatcher(nullptr), 21 | _destructorCalled(false) 22 | 23 | { 24 | // Create a DeviceWatcher to enumerate and select the target video device and also signal when changes to this device occur 25 | // A different query method is used for DEBUG and RELEASE build configurations 26 | 27 | #if _DEBUG 28 | 29 | // Here a general device query to is used to select the first available device according to the following modes: 30 | // 31 | // - Default mode: Enumerates all available "webcam" devices (KSCATEGORY_VIDEO_CAMERA) on the PC and selects the first available device 32 | // This mode is intended for development and testing when a driver INF for the device isn't available, i.e. using the default UVC driver 33 | // Set SampleFrameProvider::_requiredKsSensorDevice = false to select this mode 34 | // 35 | // - Sensor mode: Enumerates only KSCATEGORY_SENSOR_CAMERA devices and selects the first available device 36 | // This mode requires the device to be registered under KSCATEGORY_SENSOR_CAMERA DeviceClass in order to be selected 37 | // Set SampleFrameProvider::_requiredKsSensorDevice = true to select this mode 38 | // 39 | 40 | if (SampleFrameProvider::_requiredKsSensorDevice) 41 | { 42 | Platform::Guid sensorCameraClassGuid = KSCATEGORY_SENSOR_CAMERA; 43 | Platform::String^ queryString = L"System.Devices.InterfaceClassGuid:=\"" + sensorCameraClassGuid.ToString() + "\""; 44 | _deviceWatcher = Windows::Devices::Enumeration::DeviceInformation::CreateWatcher(queryString); 45 | } 46 | else 47 | { 48 | _deviceWatcher = Windows::Devices::Enumeration::DeviceInformation::CreateWatcher(Windows::Devices::Enumeration::DeviceClass::VideoCapture); 49 | } 50 | 51 | #else 52 | 53 | // The RELEASE configuration requires a specific device query string 54 | // 55 | // *** IMPORTANT *** 56 | // 57 | // The actual implementation of your IFrameProvider must query for and connect to a single device on the system. This means the 58 | // enumeration performed by this sample is inadequate and must be replaced with an Advance Query Syntax string that returns your 59 | // IR sensor camera and nothing else 60 | // 61 | 62 | Platform::String^ vendorId = L"1234"; // Replace with your own Vendor ID number 63 | Platform::String^ productId = L"5678"; // Replace with this sensor's Product ID number 64 | Platform::Guid sensorCameraClassGuid = KSCATEGORY_SENSOR_CAMERA; 65 | 66 | Platform::String^ queryString = L"System.Devices.InterfaceClassGuid:=\"" + sensorCameraClassGuid.ToString() + "\"" + 67 | L" AND System.DeviceInterface.WinUsb.UsbVendorId:=" + vendorId + 68 | L" AND System.DeviceInterface.WinUsb.UsbProductId:=" + productId; 69 | 70 | _deviceWatcher = Windows::Devices::Enumeration::DeviceInformation::CreateWatcher(queryString); 71 | 72 | #endif // #if _DEBUG 73 | 74 | _deviceAddedRegToken = _deviceWatcher->Added += 75 | ref new Windows::Foundation::TypedEventHandler 76 | (this, &SampleFrameProviderManager::DeviceAddedEventHandler); 77 | 78 | _deviceRemovedRegToken = _deviceWatcher->Removed += 79 | ref new Windows::Foundation::TypedEventHandler 80 | (this, &SampleFrameProviderManager::DeviceRemovedEventHandler); 81 | 82 | _deviceWatcher->Start(); 83 | } 84 | 85 | SampleFrameProviderManager::~SampleFrameProviderManager() 86 | { 87 | auto lock = _destructionLocker.Lock(); 88 | 89 | _destructorCalled = true; 90 | 91 | if (_deviceWatcher != nullptr) 92 | { 93 | _deviceWatcher->Stop(); 94 | 95 | _deviceWatcher->Added -= _deviceAddedRegToken; 96 | _deviceWatcher->Removed -= _deviceRemovedRegToken; 97 | _deviceWatcher = nullptr; 98 | } 99 | 100 | ReleaseProvider(); 101 | } 102 | 103 | WDPP::IPerceptionFrameProvider^ SampleFrameProviderManager::GetFrameProvider(WDPP::PerceptionFrameProviderInfo^ providerInfo) 104 | { 105 | if (providerInfo != nullptr && _providerMap->HasKey(providerInfo->Id)) 106 | { 107 | return _providerMap->Lookup(providerInfo->Id); 108 | } 109 | return nullptr; 110 | } 111 | 112 | void SampleFrameProviderManager::DeviceAddedEventHandler(WDE::DeviceWatcher^ sender, WDE::DeviceInformation^ args) 113 | { 114 | auto lock = _destructionLocker.Lock(); 115 | 116 | // Do NOT create the FrameProvider if this object's destructor has been invoked 117 | if (!_destructorCalled) 118 | { 119 | CreateProvider(args->Id); 120 | } 121 | } 122 | 123 | void SampleFrameProviderManager::DeviceRemovedEventHandler(WDE::DeviceWatcher^ sender, WDE::DeviceInformationUpdate^ args) 124 | { 125 | auto lock = _destructionLocker.Lock(); 126 | 127 | ReleaseProvider(); 128 | } 129 | 130 | void SampleFrameProviderManager::CreateProvider(Platform::String^ targetDeviceId) 131 | { 132 | auto lock = _connectionLocker.Lock(); 133 | 134 | try 135 | { 136 | // Initialize our IFrameProvider object and add it to the Manager's internal map 137 | SampleFrameProvider^ provider = ref new SampleFrameProvider(targetDeviceId); 138 | _providerMap->Insert(provider->FrameProviderInfo->Id, provider); 139 | 140 | // Register our Provider object with the service 141 | WDPP::PerceptionFrameProviderManagerService::RegisterFrameProviderInfo(this, provider->FrameProviderInfo); 142 | 143 | // Initialize a ControlGroup object which allows the clients to set/change properties on the Provider 144 | auto controllerModeIds = ref new Platform::Collections::Vector(); 145 | controllerModeIds->Append(provider->FrameProviderInfo->Id); 146 | _controlGroup = ref new WDPP::PerceptionControlGroup(controllerModeIds->GetView()); 147 | WDPP::PerceptionFrameProviderManagerService::RegisterControlGroup(this, _controlGroup); 148 | 149 | // Perform the steps necessary to register our Provider for FaceAuthentication 150 | // Create a list of all Providers that can support FaceAuthentication; only a single Provider in this implementation 151 | auto faceAuthProviderIds = ref new Platform::Collections::Vector(); 152 | faceAuthProviderIds->Append(provider->FrameProviderInfo->Id); 153 | 154 | // Create handlers for the "Start" and "Stop" FaceAuthentication events 155 | auto startFaceAuthHandler = ref new WDPP::PerceptionStartFaceAuthenticationHandler( 156 | this, 157 | &SampleFrameProviderManager::StartFaceAuthentication); 158 | 159 | auto stopFaceAuthHandler = ref new WDPP::PerceptionStopFaceAuthenticationHandler( 160 | this, 161 | &SampleFrameProviderManager::StopFaceAuthentication); 162 | 163 | // Create a FaceAuthentication group containing our Providers list and event handlers 164 | _faceAuthGroup = ref new WDPP::PerceptionFaceAuthenticationGroup( 165 | faceAuthProviderIds->GetView(), 166 | startFaceAuthHandler, 167 | stopFaceAuthHandler); 168 | 169 | // Finally register our FaceAuthentication group with the service 170 | WDPP::PerceptionFrameProviderManagerService::RegisterFaceAuthenticationGroup(this, _faceAuthGroup); 171 | } 172 | catch (Platform::Exception^ ex) 173 | { 174 | // Clean up Provider and Group objects if something goes wrong 175 | ReleaseProvider(); 176 | } 177 | } 178 | 179 | void SampleFrameProviderManager::ReleaseProvider() 180 | { 181 | auto lock = _connectionLocker.Lock(); 182 | 183 | // NOTE: When SensorDataService unloads a given FrameProvider, it directly Closes (aka Disposes) the IPerceptionFrameProvider object before 184 | // Closing the IPerceptionFrameProviderManager object that created it. This means, any references to the FrameProvider object are now invalid 185 | // and any API calls made using this Provider, e.g. UnregisterControlGroup, will throw an InvalidArgumentException. 186 | 187 | // Do not attempt to Unregister control groups or release the FrameProvider when this manager is being destroyed 188 | if (!_destructorCalled) 189 | { 190 | // Unregister the FaceAuthentication group 191 | if (_faceAuthGroup != nullptr) 192 | { 193 | WDPP::PerceptionFrameProviderManagerService::UnregisterFaceAuthenticationGroup(this, _faceAuthGroup); 194 | _faceAuthGroup = nullptr; 195 | } 196 | 197 | // Unregister the ControlGroup 198 | if (_controlGroup != nullptr) 199 | { 200 | WDPP::PerceptionFrameProviderManagerService::UnregisterControlGroup(this, _controlGroup); 201 | _controlGroup = nullptr; 202 | } 203 | 204 | // Unregister our Provider object and release it 205 | if (_providerMap->Size > 0) 206 | { 207 | auto firstItem = _providerMap->First(); 208 | WDPP::PerceptionFrameProviderInfo^ providerInfo = firstItem->Current->Value->FrameProviderInfo; 209 | if (providerInfo != nullptr) 210 | { 211 | WDPP::PerceptionFrameProviderManagerService::UnregisterFrameProviderInfo(this, providerInfo); 212 | } 213 | 214 | _providerMap->Clear(); 215 | } 216 | } 217 | else 218 | { 219 | _faceAuthGroup = nullptr; 220 | _controlGroup = nullptr; 221 | _providerMap->Clear(); 222 | } 223 | 224 | // 225 | // TODO: Add any other device specific shutdown code 226 | // 227 | } 228 | 229 | bool SampleFrameProviderManager::StartFaceAuthentication(WDPP::PerceptionFaceAuthenticationGroup^ group) 230 | { 231 | // Sensor specific functionality 232 | // Toggle whatever settings are needed to make your Provider meet the FaceAuthentication spec 233 | // For example, setting exposure, changing framerate, etc. 234 | 235 | // Return true when the Provider is fully prepared to handle FaceAuthentication frames 236 | // If false is returned, FaceAuthentication will fail all the way to the client 237 | return true; 238 | } 239 | 240 | void SampleFrameProviderManager::StopFaceAuthentication(WDPP::PerceptionFaceAuthenticationGroup^ group) 241 | { 242 | // Sensor specific functionality 243 | // Undo any changes that were made in EnterFaceAuthentication 244 | } 245 | 246 | } // end namespace 247 | 248 | 249 | -------------------------------------------------------------------------------- /FrameProviderSample/FrameManager.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | public ref class SampleFrameProviderManager sealed : public WDPP::IPerceptionFrameProviderManager 17 | { 18 | public: 19 | 20 | SampleFrameProviderManager(); 21 | virtual ~SampleFrameProviderManager(); 22 | 23 | // IFrameProviderManager interface methods 24 | virtual WDPP::IPerceptionFrameProvider^ GetFrameProvider(WDPP::PerceptionFrameProviderInfo^ frameProviderInfo); 25 | 26 | private: 27 | 28 | // Internal methods 29 | void CreateProvider(Platform::String^ targetDeviceId); 30 | void ReleaseProvider(); 31 | 32 | // Face Authentication event handlers 33 | bool StartFaceAuthentication(WDPP::PerceptionFaceAuthenticationGroup^ group); 34 | void StopFaceAuthentication(WDPP::PerceptionFaceAuthenticationGroup^ group); 35 | 36 | // DeviceWatcher event handlers 37 | void DeviceAddedEventHandler(WDE::DeviceWatcher^ sender, WDE::DeviceInformation^ args); 38 | void DeviceRemovedEventHandler(WDE::DeviceWatcher^ sender, WDE::DeviceInformationUpdate^ args); 39 | 40 | // Class fields 41 | Platform::Collections::Map^ _providerMap; 42 | WDPP::PerceptionControlGroup^ _controlGroup; 43 | WDPP::PerceptionFaceAuthenticationGroup^ _faceAuthGroup; 44 | WDE::DeviceWatcher^ _deviceWatcher; 45 | WRLW::CriticalSection _connectionLocker; 46 | WRLW::CriticalSection _destructionLocker; 47 | 48 | bool _destructorCalled; 49 | 50 | Windows::Foundation::EventRegistrationToken _deviceAddedRegToken; 51 | Windows::Foundation::EventRegistrationToken _deviceRemovedRegToken; 52 | }; 53 | 54 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/FrameProvider.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/FrameProviderSample/FrameProvider.cpp -------------------------------------------------------------------------------- /FrameProviderSample/FrameProvider.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | // Defines the basic types of IR illumination types sensors FaceAuthentication sensors can produce 17 | // SampleFrameProvider specifies one of these types to determine which Provider flags to set 18 | enum class SensorIRIlluminationTypes 19 | { 20 | // The sensor's IR illuminator flashes on/off every other frame and ambient light 21 | // subtraction is not performed by the device or driver; the service performs this task 22 | InterleavedIllumination_UncleanedIR, 23 | 24 | // The sensor's IR illuminator flashes on/off every other frame but ambient light subtraction 25 | // is performed by the device or driver and "clean IR" frames are submitted to the service 26 | InterleavedIllumination_CleanIR, 27 | 28 | // The sensor's IR illuminator remains on for every frame; ambient light subtraction 29 | // is performed by the device or driver to produce "clean IR" 30 | ContinuousIllumination_CleanIR, 31 | }; 32 | 33 | ref class SampleFrameProvider : public WDPP::IPerceptionFrameProvider 34 | { 35 | internal: 36 | 37 | SampleFrameProvider(Platform::String^ targetDeviceId); 38 | 39 | // Specify the IR illumination type for this provider's sensor; change if type doesn't match your device 40 | // This type dictates the Properties set by the provider 41 | const SensorIRIlluminationTypes _sensorIRIllumination = SensorIRIlluminationTypes::InterleavedIllumination_UncleanedIR; 42 | 43 | public: 44 | 45 | virtual ~SampleFrameProvider(); 46 | 47 | // IFrameProvider interface properties 48 | virtual property bool Available { bool get(); } 49 | virtual property WDPP::PerceptionFrameProviderInfo^ FrameProviderInfo{ WDPP::PerceptionFrameProviderInfo^ get(); } 50 | virtual property WFC::IPropertySet^ Properties { WFC::IPropertySet^ get(); } 51 | 52 | // IFrameProvider interface methods 53 | virtual void Start(); 54 | virtual void Stop(); 55 | virtual void SetProperty(WDPP::PerceptionPropertyChangeRequest^ propertyValue); 56 | 57 | internal: 58 | 59 | static const bool _requiredKsSensorDevice = false; // If set limits enumeration to devices with KSCATEGORY_SENSOR_CAMERA attribute 60 | 61 | private: 62 | 63 | // Internal methods 64 | WDPP::PerceptionFrame^ CopyMediaSampleToPerceptionFrame(); 65 | VideoSourceDescription^ CreateVideoDescriptionFromMediaSource(); 66 | bool IsExposureCompensationSupported(); 67 | bool SetExposureCompensation(_Inout_ float& newValue); 68 | void InitializeSourceVideoProperties(); 69 | void UpdateSourceVideoProperties(); 70 | 71 | // Class fields 72 | MediaFoundationWrapper _mediaWrapper; 73 | EventRegistrationToken _readFrameCallbackToken; 74 | EventRegistrationToken _availablityChangedCallbackToken; 75 | 76 | WFC::IPropertySet^ _properties; 77 | WDPP::PerceptionFrameProviderInfo^ _providerInfo; 78 | WDPP::PerceptionVideoFrameAllocator^ _frameAllocator; 79 | Platform::Agile _mediaCapture; 80 | }; 81 | 82 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/FrameProviderSample.reg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/FrameProviderSample/FrameProviderSample.reg -------------------------------------------------------------------------------- /FrameProviderSample/FrameProviderSample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.22823.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FrameProviderSample", "FrameProviderSample.vcxproj", "{A23C5DA9-A596-492B-A866-0E53F64809CB}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FrameProviderSampleMft0", "MFT0\FrameProviderSampleMft0.vcxproj", "{9DE02487-876A-4DD8-BC75-E6B5980B7461}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{95093790-C3FD-4F98-9C7C-FADFD9BBDF50}" 11 | ProjectSection(SolutionItems) = preProject 12 | FrameProviderSample.reg = FrameProviderSample.reg 13 | Readme.txt = Readme.txt 14 | EndProjectSection 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Win32 = Debug|Win32 19 | Debug|x64 = Debug|x64 20 | Release|Win32 = Release|Win32 21 | Release|x64 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Debug|Win32.Build.0 = Debug|Win32 26 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Debug|x64.ActiveCfg = Debug|x64 27 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Debug|x64.Build.0 = Debug|x64 28 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Release|Win32.ActiveCfg = Release|Win32 29 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Release|Win32.Build.0 = Release|Win32 30 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Release|x64.ActiveCfg = Release|x64 31 | {A23C5DA9-A596-492B-A866-0E53F64809CB}.Release|x64.Build.0 = Release|x64 32 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Debug|Win32.Build.0 = Debug|Win32 34 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Debug|x64.ActiveCfg = Debug|x64 35 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Debug|x64.Build.0 = Debug|x64 36 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Release|Win32.ActiveCfg = Release|Win32 37 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Release|Win32.Build.0 = Release|Win32 38 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Release|x64.ActiveCfg = Release|x64 39 | {9DE02487-876A-4DD8-BC75-E6B5980B7461}.Release|x64.Build.0 = Release|x64 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /FrameProviderSample/FrameProviderSample.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {A23C5DA9-A596-492B-A866-0E53F64809CB} 23 | Win32Proj 24 | FrameProviderSample 25 | 10.0.10240.0 26 | 10.0.10240.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v140 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | true 38 | v140 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | false 44 | v140 45 | true 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v140 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | SampleFrameProvider 76 | 77 | 78 | true 79 | SampleFrameProvider 80 | 81 | 82 | false 83 | SampleFrameProvider 84 | 85 | 86 | false 87 | SampleFrameProvider 88 | 89 | 90 | 91 | Use 92 | Level3 93 | Disabled 94 | _DEBUG;_WINRT_DLL;%(PreprocessorDefinitions) 95 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;%(AdditionalUsingDirectories) 96 | true 97 | false 98 | pch.h 99 | 4447;%(DisableSpecificWarnings) 100 | 101 | 102 | Windows 103 | true 104 | 105 | 106 | 107 | 108 | Use 109 | Level3 110 | Disabled 111 | _DEBUG;_WINRT_DLL;%(PreprocessorDefinitions) 112 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;%(AdditionalUsingDirectories) 113 | true 114 | false 115 | pch.h 116 | 4447;%(DisableSpecificWarnings) 117 | 118 | 119 | Windows 120 | true 121 | 122 | 123 | 124 | 125 | Level3 126 | Use 127 | MaxSpeed 128 | true 129 | true 130 | NDEBUG;_WINRT_DLL;%(PreprocessorDefinitions) 131 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;%(AdditionalUsingDirectories) 132 | true 133 | pch.h 134 | 4447;%(DisableSpecificWarnings) 135 | 136 | 137 | Windows 138 | true 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | Level3 146 | Use 147 | MaxSpeed 148 | true 149 | true 150 | NDEBUG;_WINRT_DLL;%(PreprocessorDefinitions) 151 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;%(AdditionalUsingDirectories) 152 | true 153 | pch.h 154 | 4447;%(DisableSpecificWarnings) 155 | 156 | 157 | Windows 158 | true 159 | true 160 | true 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | Create 179 | Create 180 | Create 181 | Create 182 | 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /FrameProviderSample/FrameProviderSample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | Source Files 18 | 19 | 20 | Source Files 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | 47 | 48 | {075a6fb6-1802-4fdf-894a-ac1f9c5fcd0b} 49 | 50 | 51 | {17a91279-4ea5-41f4-9f1c-618e20c7f10a} 52 | 53 | 54 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderMft0.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // FrameProviderMft0.cpp : Implementation of CFrameProviderMft0 13 | 14 | #include "stdafx.h" 15 | #include "FrameProviderMft0.h" 16 | #include "SampleHelpers.h" 17 | #include 18 | 19 | // CFrameProviderMft0 20 | 21 | STDMETHODIMP CFrameProviderMft0::GetIids( 22 | /* [out] */ _Out_ ULONG *iidCount, 23 | /* [size_is][size_is][out] */ _Outptr_result_buffer_maybenull_(*iidCount) IID **iids) 24 | { 25 | HRESULT hr = S_OK; 26 | do { 27 | CHK_NULL_PTR_BRK(iidCount); 28 | CHK_NULL_PTR_BRK(iids); 29 | *iids = NULL; 30 | *iidCount = 0; 31 | } while (FALSE); 32 | 33 | return hr; 34 | } 35 | 36 | STDMETHODIMP CFrameProviderMft0::GetRuntimeClassName( 37 | /* [out] */ _Outptr_result_maybenull_ HSTRING *className) 38 | { 39 | HRESULT hr = S_OK; 40 | if(className != nullptr) 41 | { 42 | hr = WindowsCreateString(NULL, 0, className); 43 | if(FAILED(hr)){ 44 | hr = E_OUTOFMEMORY; 45 | } 46 | }else { 47 | hr = E_INVALIDARG; 48 | } 49 | return hr; 50 | } 51 | 52 | STDMETHODIMP CFrameProviderMft0::GetTrustLevel( 53 | /* [out] */ _Out_ TrustLevel *trustLevel) 54 | { 55 | HRESULT hr = S_OK; 56 | do { 57 | CHK_NULL_PTR_BRK(trustLevel); 58 | *trustLevel = TrustLevel::BaseTrust; 59 | } while (FALSE); 60 | 61 | return hr; 62 | } 63 | 64 | 65 | STDMETHODIMP CFrameProviderMft0::GetStreamLimits( 66 | /* [out] */ _Out_ DWORD *pdwInputMinimum, 67 | /* [out] */ _Out_ DWORD *pdwInputMaximum, 68 | /* [out] */ _Out_ DWORD *pdwOutputMinimum, 69 | /* [out] */ _Out_ DWORD *pdwOutputMaximum) 70 | { 71 | HRESULT hr = S_OK; 72 | do { 73 | if ((pdwInputMinimum == NULL) || 74 | (pdwInputMaximum == NULL) || 75 | (pdwOutputMinimum == NULL) || 76 | (pdwOutputMaximum == NULL)) 77 | { 78 | hr = E_POINTER; 79 | break; 80 | } 81 | 82 | // This MFT has a fixed number of streams. 83 | *pdwInputMinimum = 1; 84 | *pdwInputMaximum = 1; 85 | *pdwOutputMinimum = 1; 86 | *pdwOutputMaximum = 1; 87 | } while (FALSE); 88 | 89 | return hr; 90 | } 91 | 92 | 93 | STDMETHODIMP CFrameProviderMft0::GetStreamCount( 94 | /* [out] */ _Out_ DWORD *pcInputStreams, 95 | /* [out] */ _Out_ DWORD *pcOutputStreams) 96 | { 97 | HRESULT hr = S_OK; 98 | 99 | do { 100 | if ((pcInputStreams == NULL) || (pcOutputStreams == NULL)) 101 | 102 | { 103 | hr = E_POINTER; 104 | break; 105 | } 106 | 107 | // This MFT has a fixed number of streams. 108 | *pcInputStreams = 1; 109 | *pcOutputStreams = 1; 110 | } while (FALSE); 111 | 112 | return hr; 113 | } 114 | STDMETHODIMP CFrameProviderMft0::GetStreamIDs( 115 | DWORD dwInputIDArraySize, 116 | /* [size_is][out] */ _Out_writes_(dwInputIDArraySize) DWORD *pdwInputIDs, 117 | DWORD dwOutputIDArraySize, 118 | /* [size_is][out] */ _Out_writes_(dwOutputIDArraySize) DWORD *pdwOutputIDs) 119 | { 120 | dwOutputIDArraySize = 0; 121 | dwInputIDArraySize = 0; 122 | pdwInputIDs = NULL; 123 | pdwOutputIDs = NULL; 124 | return E_NOTIMPL; 125 | } 126 | 127 | STDMETHODIMP CFrameProviderMft0::GetInputStreamInfo( 128 | DWORD dwInputStreamID, 129 | /* [out] */ _Out_ MFT_INPUT_STREAM_INFO *pStreamInfo) 130 | { 131 | HRESULT hr = S_OK; 132 | EnterCriticalSection(&m_critSec); 133 | 134 | do { 135 | CHK_NULL_BRK(pStreamInfo); 136 | if (!IsValidInputStream(dwInputStreamID)) 137 | { 138 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 139 | } 140 | if(m_pInputType) { 141 | pStreamInfo->cbAlignment = 0; 142 | pStreamInfo->cbSize = 0; 143 | pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER ; 144 | pStreamInfo->hnsMaxLatency = 0; 145 | } else { 146 | hr = MF_E_TRANSFORM_TYPE_NOT_SET; 147 | } 148 | } while (FALSE); 149 | 150 | LeaveCriticalSection(&m_critSec); 151 | return hr; 152 | } 153 | 154 | 155 | STDMETHODIMP CFrameProviderMft0::GetOutputStreamInfo( 156 | DWORD dwOutputStreamID, 157 | /* [out] */ _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo) 158 | { 159 | HRESULT hr = S_OK; 160 | EnterCriticalSection(&m_critSec); 161 | 162 | do { 163 | CHK_NULL_BRK(pStreamInfo); 164 | if (!IsValidInputStream(dwOutputStreamID)) 165 | { 166 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 167 | } 168 | if(m_pOutputType) { 169 | pStreamInfo->cbAlignment = 0; 170 | pStreamInfo->cbSize = 0; 171 | pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE; 172 | } else { 173 | hr = MF_E_TRANSFORM_TYPE_NOT_SET; 174 | } 175 | 176 | } while (FALSE); 177 | 178 | LeaveCriticalSection(&m_critSec); 179 | return hr; 180 | } 181 | 182 | STDMETHODIMP CFrameProviderMft0::GetAttributes( 183 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) 184 | { 185 | HRESULT hr = S_OK; 186 | 187 | do { 188 | CHK_NULL_PTR_BRK(ppAttributes); 189 | if(!m_pGlobalAttributes) { 190 | CHK_LOG_BRK(MFCreateAttributes(&m_pGlobalAttributes, 3)); 191 | CHK_LOG_BRK(m_pGlobalAttributes->SetUINT32(MF_TRANSFORM_ASYNC, FALSE)); 192 | CHK_LOG_BRK(m_pGlobalAttributes->SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft")); 193 | CHK_LOG_BRK(m_pGlobalAttributes->SetUINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE)); 194 | } 195 | *ppAttributes = m_pGlobalAttributes; 196 | (*ppAttributes)->AddRef(); 197 | } while (FALSE); 198 | 199 | return hr; 200 | } 201 | 202 | STDMETHODIMP CFrameProviderMft0::GetInputStreamAttributes( 203 | DWORD dwInputStreamID, 204 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) 205 | { 206 | HRESULT hr = S_OK; 207 | 208 | do { 209 | if(dwInputStreamID > 0) { 210 | hr = MF_E_INVALIDSTREAMNUMBER; 211 | break; 212 | } 213 | CHK_NULL_PTR_BRK(ppAttributes); 214 | if(!m_pInputAttributes){ 215 | CHK_LOG_BRK(MFCreateAttributes(&m_pInputAttributes, 2)); 216 | CHK_LOG_BRK(m_pInputAttributes->SetUINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE)); 217 | CHK_LOG_BRK(m_pInputAttributes->SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft")); 218 | } 219 | *ppAttributes = m_pInputAttributes; 220 | (*ppAttributes)->AddRef(); 221 | } while (FALSE); 222 | 223 | return hr; 224 | } 225 | 226 | STDMETHODIMP CFrameProviderMft0::GetOutputStreamAttributes( 227 | DWORD dwOutputStreamID, 228 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) 229 | { 230 | HRESULT hr = S_OK; 231 | 232 | do { 233 | if(dwOutputStreamID > 0) { 234 | hr = MF_E_INVALIDSTREAMNUMBER; 235 | break; 236 | } 237 | CHK_NULL_PTR_BRK(ppAttributes); 238 | CHK_NULL_PTR_BRK(m_pInputAttributes); 239 | 240 | *ppAttributes = m_pInputAttributes; 241 | (*ppAttributes)->AddRef(); 242 | } while (FALSE); 243 | 244 | return hr; 245 | } 246 | 247 | STDMETHODIMP CFrameProviderMft0::DeleteInputStream( 248 | DWORD dwStreamID) 249 | { 250 | HRESULT hr = S_OK; 251 | if(dwStreamID > 0) { 252 | hr = MF_E_INVALIDSTREAMNUMBER; 253 | } else { 254 | hr = E_NOTIMPL; 255 | } 256 | return hr; 257 | } 258 | 259 | STDMETHODIMP CFrameProviderMft0::AddInputStreams( 260 | DWORD cStreams, 261 | /* [in] */ _In_ DWORD *adwStreamIDs) 262 | { 263 | HRESULT hr = S_OK; 264 | 265 | if( !adwStreamIDs || cStreams > 0) { 266 | hr = E_INVALIDARG; 267 | } else { 268 | hr = E_NOTIMPL; 269 | } 270 | return hr; 271 | } 272 | 273 | STDMETHODIMP CFrameProviderMft0::GetInputAvailableType( 274 | DWORD dwInputStreamID, 275 | DWORD dwTypeIndex, 276 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) 277 | { 278 | HRESULT hr = S_OK; 279 | IUnknown *pUnk = NULL; 280 | IMFAttributes *pSourceAttributes = NULL; 281 | wchar_t *pszName; 282 | 283 | EnterCriticalSection(&m_critSec); 284 | 285 | do { 286 | CHK_BOOL_BRK(IsValidInputStream(dwInputStreamID)); 287 | 288 | if(!m_pSourceTransform && m_pInputAttributes) { 289 | CHK_LOG_BRK(m_pInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(&pSourceAttributes))); 290 | CHK_LOG_BRK(pSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(&pUnk))); 291 | CHK_LOG_BRK(pUnk->QueryInterface(__uuidof(IMFTransform), (void**)&m_pSourceTransform)); 292 | CHK_LOG_BRK(pSourceAttributes->GetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType)); 293 | 294 | if(m_stStreamType == PINNAME_VIDEO_CAPTURE) { 295 | wprintf(L"Stream type: PINNAME_VIDEO_CAPTURE\n"); 296 | } else if(m_stStreamType == PINNAME_VIDEO_PREVIEW) { 297 | wprintf(L"Stream type: PINNAME_VIDEO_PREVIEW\n"); 298 | } else if(m_stStreamType == PINNAME_VIDEO_STILL) { 299 | wprintf(L"Stream type: PINNAME_VIDEO_STILL\n"); 300 | } else if(m_stStreamType == PINNAME_IMAGE) { 301 | wprintf(L"Stream type: PINNAME_IMAGE\n"); 302 | } else { 303 | StringFromCLSID(m_stStreamType, &pszName); 304 | if(pszName){ 305 | wprintf(L"Stream type: %s\n", pszName); 306 | CoTaskMemFree(pszName); 307 | } 308 | } 309 | CHK_LOG_BRK((m_stStreamType == PINNAME_VIDEO_PREVIEW || m_stStreamType == PINNAME_VIDEO_CAPTURE) ? S_OK : E_UNEXPECTED); 310 | CHK_LOG_BRK(GenerateMFMediaTypeListFromDevice(dwInputStreamID)); 311 | } 312 | 313 | CHK_LOG_BRK(GetMediaType(dwInputStreamID, dwTypeIndex, ppType)); 314 | } while (FALSE); 315 | 316 | LeaveCriticalSection(&m_critSec); 317 | SAFERELEASE(pUnk); 318 | SAFERELEASE(pSourceAttributes); 319 | return hr; 320 | } 321 | 322 | STDMETHODIMP CFrameProviderMft0::GetOutputAvailableType( 323 | DWORD dwOutputStreamID, 324 | DWORD dwTypeIndex, 325 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) 326 | { 327 | HRESULT hr = S_OK; 328 | IUnknown *pUnk = NULL; 329 | IMFAttributes *pSourceAttributes = NULL; 330 | wchar_t *pszName; 331 | 332 | EnterCriticalSection(&m_critSec); 333 | 334 | do { 335 | CHK_BOOL_BRK(IsValidOutputStream(dwOutputStreamID)); 336 | if(!m_pSourceTransform && m_pInputAttributes) { 337 | CHK_LOG_BRK(m_pInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(&pSourceAttributes))); 338 | CHK_LOG_BRK(pSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(&pUnk))); 339 | CHK_LOG_BRK(pUnk->QueryInterface(__uuidof(IMFTransform), (void**)&m_pSourceTransform)); 340 | CHK_LOG_BRK(pSourceAttributes->GetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType)); 341 | if(m_stStreamType == PINNAME_VIDEO_CAPTURE) { 342 | wprintf(L"Stream type: PINNAME_VIDEO_CAPTURE\n"); 343 | } else if(m_stStreamType == PINNAME_VIDEO_PREVIEW) { 344 | wprintf(L"Stream type: PINNAME_VIDEO_PREVIEW\n"); 345 | } else if(m_stStreamType == PINNAME_VIDEO_STILL) { 346 | wprintf(L"Stream type: PINNAME_VIDEO_STILL\n"); 347 | } else if(m_stStreamType == PINNAME_IMAGE) { 348 | wprintf(L"Stream type: PINNAME_IMAGE\n"); 349 | } else { 350 | StringFromCLSID(m_stStreamType, &pszName); 351 | wprintf(L"Stream type: %s\n", pszName); 352 | } 353 | CHK_LOG_BRK((m_stStreamType == PINNAME_VIDEO_PREVIEW || m_stStreamType == PINNAME_VIDEO_CAPTURE) ? S_OK : E_UNEXPECTED); 354 | CHK_LOG_BRK(GenerateMFMediaTypeListFromDevice(dwOutputStreamID)); 355 | } 356 | 357 | CHK_LOG_BRK(GetMediaType(dwOutputStreamID, dwTypeIndex, ppType)); 358 | } while (FALSE); 359 | 360 | LeaveCriticalSection(&m_critSec); 361 | SAFERELEASE(pUnk); 362 | SAFERELEASE(pSourceAttributes); 363 | return hr; 364 | } 365 | 366 | STDMETHODIMP CFrameProviderMft0::SetInputType( 367 | DWORD dwInputStreamID, 368 | /* [in] */ _In_opt_ IMFMediaType *pType, 369 | DWORD dwFlags) 370 | { 371 | HRESULT hr = S_OK; 372 | 373 | EnterCriticalSection(&m_critSec); 374 | 375 | BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0); 376 | // Validate flags. 377 | do { 378 | if(bReallySet) { 379 | CComPtr pFullType; 380 | CHK_LOG_BRK(IsMediaTypeSupported(dwInputStreamID, pType, &pFullType)); 381 | SAFERELEASE(m_pInputType); 382 | SAFERELEASE(m_pOutputType); 383 | m_pOutputType = pFullType; 384 | m_pOutputType->AddRef(); 385 | m_pInputType = pFullType; 386 | m_pInputType->AddRef(); 387 | } else { 388 | CHK_LOG_BRK(IsMediaTypeSupported(dwInputStreamID, pType)); 389 | } 390 | } while(FALSE); 391 | 392 | LeaveCriticalSection(&m_critSec); 393 | return hr; 394 | } 395 | 396 | STDMETHODIMP CFrameProviderMft0::SetOutputType( 397 | DWORD dwOutputStreamID, 398 | /* [in] */ _In_opt_ IMFMediaType *pType, 399 | DWORD dwFlags) 400 | { 401 | HRESULT hr = S_OK; 402 | 403 | do { 404 | CHK_LOG_BRK(SetInputType(dwOutputStreamID, pType, dwFlags)); 405 | } while (FALSE); 406 | 407 | return hr; 408 | } 409 | 410 | STDMETHODIMP CFrameProviderMft0::GetInputCurrentType( 411 | DWORD dwInputStreamID, 412 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) 413 | { 414 | HRESULT hr = S_OK; 415 | 416 | EnterCriticalSection(&m_critSec); 417 | 418 | do { 419 | CHK_NULL_BRK(ppType); 420 | 421 | if (!IsValidInputStream(dwInputStreamID)) 422 | { 423 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 424 | } 425 | else if(m_pInputType) 426 | { 427 | *ppType = m_pInputType; 428 | (*ppType)->AddRef(); 429 | } 430 | else 431 | { 432 | CHK_LOG_BRK(MF_E_TRANSFORM_TYPE_NOT_SET); 433 | } 434 | } while (FALSE); 435 | 436 | LeaveCriticalSection(&m_critSec); 437 | return hr; 438 | } 439 | 440 | STDMETHODIMP CFrameProviderMft0::GetOutputCurrentType( 441 | DWORD dwOutputStreamID, 442 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) 443 | { 444 | HRESULT hr = S_OK; 445 | 446 | EnterCriticalSection(&m_critSec); 447 | 448 | do { 449 | CHK_NULL_BRK(ppType); 450 | 451 | if (!IsValidOutputStream(dwOutputStreamID)) 452 | { 453 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 454 | } 455 | else if(m_pOutputType) 456 | { 457 | *ppType = m_pOutputType; 458 | (*ppType)->AddRef(); 459 | } 460 | else 461 | { 462 | CHK_LOG_BRK(MF_E_TRANSFORM_TYPE_NOT_SET); 463 | } 464 | } while (FALSE); 465 | 466 | LeaveCriticalSection(&m_critSec); 467 | return hr; 468 | } 469 | 470 | STDMETHODIMP CFrameProviderMft0::GetInputStatus( 471 | DWORD dwInputStreamID, 472 | /* [out] */ _Out_ DWORD *pdwFlags) 473 | { 474 | HRESULT hr = S_OK; 475 | 476 | EnterCriticalSection(&m_critSec); 477 | 478 | do { 479 | CHK_BOOL_BRK(pdwFlags); 480 | 481 | if (!IsValidInputStream(dwInputStreamID)) 482 | { 483 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 484 | } 485 | 486 | // If we already have an input sample, we don't accept 487 | // another one until the client calls ProcessOutput or Flush. 488 | if (m_pSample == NULL) 489 | { 490 | *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA; 491 | } 492 | else 493 | { 494 | *pdwFlags = 0; 495 | } 496 | } while (FALSE); 497 | 498 | LeaveCriticalSection(&m_critSec); 499 | return hr; 500 | } 501 | 502 | STDMETHODIMP CFrameProviderMft0::GetOutputStatus( 503 | /* [out] */ _Out_ DWORD *pdwFlags) 504 | { 505 | HRESULT hr = S_OK; 506 | 507 | EnterCriticalSection(&m_critSec); 508 | 509 | do { 510 | CHK_NULL_BRK(pdwFlags); 511 | // We can produce an output sample if (and only if) 512 | // we have an input sample. 513 | if (m_pSample != NULL) 514 | { 515 | *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY; 516 | } 517 | else 518 | { 519 | *pdwFlags = 0; 520 | } 521 | } while (FALSE); 522 | 523 | LeaveCriticalSection(&m_critSec); 524 | return hr; 525 | } 526 | 527 | STDMETHODIMP CFrameProviderMft0::SetOutputBounds( 528 | LONGLONG hnsLowerBound, 529 | LONGLONG hnsUpperBound) 530 | { 531 | UNREFERENCED_PARAMETER(hnsLowerBound); 532 | UNREFERENCED_PARAMETER(hnsUpperBound); 533 | return S_OK; 534 | } 535 | 536 | STDMETHODIMP CFrameProviderMft0::ProcessEvent( 537 | DWORD dwInputStreamID, 538 | /* [in] */ _In_opt_ IMFMediaEvent *pEvent) 539 | { 540 | UNREFERENCED_PARAMETER(dwInputStreamID); 541 | UNREFERENCED_PARAMETER(pEvent); 542 | return E_NOTIMPL; 543 | } 544 | 545 | STDMETHODIMP CFrameProviderMft0::ProcessMessage( 546 | MFT_MESSAGE_TYPE eMessage, 547 | ULONG_PTR ulParam) 548 | { 549 | UNREFERENCED_PARAMETER(ulParam); 550 | HRESULT hr = S_OK; 551 | 552 | EnterCriticalSection(&m_critSec); 553 | 554 | switch (eMessage) 555 | { 556 | case MFT_MESSAGE_COMMAND_FLUSH: 557 | // Flush the MFT. 558 | hr = OnFlush(); 559 | break; 560 | 561 | case MFT_MESSAGE_COMMAND_DRAIN: 562 | // Drain: Tells the MFT not to accept any more input until 563 | // all of the pending output has been processed. That is our 564 | // default behevior already, so there is nothing to do. 565 | break; 566 | 567 | case MFT_MESSAGE_SET_D3D_MANAGER: 568 | // The pipeline should never send this message unless the MFT 569 | // has the MF_SA_D3D_AWARE attribute set to TRUE. However, if we 570 | // do get this message, it's invalid and we don't implement it. 571 | hr = E_NOTIMPL; 572 | break; 573 | 574 | // The remaining messages do not require any action from this MFT. 575 | case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: 576 | case MFT_MESSAGE_NOTIFY_END_STREAMING: 577 | case MFT_MESSAGE_NOTIFY_END_OF_STREAM: 578 | case MFT_MESSAGE_NOTIFY_START_OF_STREAM: 579 | break; 580 | } 581 | 582 | LeaveCriticalSection(&m_critSec); 583 | return hr; 584 | } 585 | 586 | STDMETHODIMP CFrameProviderMft0::ProcessInput( 587 | DWORD dwInputStreamID, 588 | IMFSample *pSample, 589 | DWORD dwFlags) 590 | { 591 | HRESULT hr = S_OK; 592 | 593 | EnterCriticalSection(&m_critSec); 594 | 595 | do { 596 | CHK_NULL_BRK(pSample); 597 | 598 | CHK_BOOL_BRK(dwFlags == 0) 599 | 600 | DWORD dwBufferCount = 0; 601 | 602 | if (!IsValidInputStream(dwInputStreamID)) 603 | { 604 | CHK_LOG_BRK(hr = MF_E_INVALIDSTREAMNUMBER); 605 | } 606 | 607 | if (!m_pInputType || !m_pOutputType) 608 | { 609 | CHK_LOG_BRK(MF_E_NOTACCEPTING); // Client must set input and output types. 610 | } 611 | 612 | if (m_pSample != NULL) 613 | { 614 | CHK_LOG_BRK(MF_E_NOTACCEPTING); // We already have an input sample. 615 | } 616 | 617 | // Validate the number of buffers. There should only be a single buffer to hold the video frame. 618 | CHK_LOG_BRK(pSample->GetBufferCount(&dwBufferCount)); 619 | 620 | if (dwBufferCount == 0) 621 | { 622 | CHK_LOG_BRK(E_FAIL); 623 | } 624 | if (dwBufferCount > 1) 625 | { 626 | CHK_LOG_BRK(MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS); 627 | } 628 | 629 | // Cache the sample. We do the actual work in ProcessOutput. 630 | m_pSample = pSample; 631 | pSample->AddRef(); // Hold a reference count on the sample. 632 | } while (FALSE); 633 | 634 | LeaveCriticalSection(&m_critSec); 635 | return hr; 636 | } 637 | 638 | STDMETHODIMP CFrameProviderMft0::ProcessOutput( 639 | DWORD dwFlags, 640 | DWORD cOutputBufferCount, 641 | /* [size_is][out][in] */ MFT_OUTPUT_DATA_BUFFER *pOutputSamples, 642 | /* [out] */ DWORD *pdwStatus) 643 | { 644 | HRESULT hr = S_OK; 645 | 646 | EnterCriticalSection(&m_critSec); 647 | 648 | do { 649 | CHK_BOOL_BRK(dwFlags == 0); 650 | CHK_NULL_BRK(pOutputSamples); 651 | CHK_NULL_BRK(pdwStatus); 652 | 653 | // Must be exactly one output buffer. 654 | CHK_BOOL_BRK(cOutputBufferCount == 1); 655 | 656 | // If we don't have an input sample, we need some input before 657 | // we can generate any output. 658 | if (m_pSample == NULL) 659 | { 660 | hr = MF_E_TRANSFORM_NEED_MORE_INPUT; 661 | break; 662 | } 663 | 664 | // In this case we're not performing any processing on the image buffer itself 665 | // Just assign the input sample object to the output parameter 666 | pOutputSamples[0].pSample = m_pSample; 667 | pOutputSamples[0].pSample->AddRef(); 668 | pOutputSamples[0].dwStatus = 0; 669 | *pdwStatus = 0; 670 | 671 | // 672 | // *** IMPORTANT *** 673 | // 674 | // TODO: Acquire the IR illumination state of the IR sensor for the current frame 675 | // This is a device specific operation that cannot be performed in the Sample 676 | // 677 | 678 | // TEMP CODE - replace with actual illumination polling code 679 | static bool dummyIlluminationEnabled = false; 680 | dummyIlluminationEnabled = !dummyIlluminationEnabled; 681 | 682 | // Add the custom "illumination enabled" attribute holding current illumination value to the media sample 683 | // This value is read from IFrameProvider to set the corresponding Property on the PerceptionFrame 684 | m_pSample->SetUINT32(WDPP_ACTIVE_ILLUMINATION_ENABLED, dummyIlluminationEnabled); 685 | 686 | } while (FALSE); 687 | 688 | SAFERELEASE(m_pSample); // Release our input sample. 689 | LeaveCriticalSection(&m_critSec); 690 | return hr; 691 | } 692 | 693 | BOOL CFrameProviderMft0::IsValidInputStream(DWORD dwInputStreamID) 694 | { 695 | return dwInputStreamID == 0; 696 | } 697 | 698 | // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier. 699 | BOOL CFrameProviderMft0::IsValidOutputStream(DWORD dwOutputStreamID) 700 | { 701 | //update 702 | return dwOutputStreamID == 0; 703 | } 704 | 705 | STDMETHODIMP CFrameProviderMft0::GetDefaultStride(LONG *plStride) 706 | { 707 | LONG lStride = 0; 708 | 709 | // Try to get the default stride from the media type. 710 | HRESULT hr = m_pInputType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride); 711 | if (FAILED(hr)) 712 | { 713 | // Attribute not set. Try to calculate the default stride. 714 | GUID subtype = GUID_NULL; 715 | UINT32 width = 0; 716 | UINT32 height = 0; 717 | 718 | // Get the subtype and the image size. 719 | hr = m_pInputType->GetGUID(MF_MT_SUBTYPE, &subtype); 720 | if (SUCCEEDED(hr)) 721 | { 722 | hr = MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &width, &height); 723 | } 724 | if (SUCCEEDED(hr)) 725 | { 726 | hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride); 727 | } 728 | 729 | // Set the attribute for later reference. 730 | if (SUCCEEDED(hr)) 731 | { 732 | (void)m_pInputType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride)); 733 | } 734 | } 735 | 736 | if (SUCCEEDED(hr)) 737 | { 738 | *plStride = lStride; 739 | } 740 | 741 | return hr; 742 | } 743 | 744 | STDMETHODIMP CFrameProviderMft0::OnFlush() 745 | { 746 | HRESULT hr = S_OK; 747 | 748 | // For this MFT, flushing just means releasing the input sample. 749 | SAFERELEASE(m_pSample); 750 | 751 | return hr; 752 | } 753 | 754 | STDMETHODIMP CFrameProviderMft0::GetMediaType( DWORD dwStreamId, DWORD dwTypeIndex, IMFMediaType **ppType) 755 | { 756 | HRESULT hr = S_OK; 757 | 758 | do { 759 | CHK_NULL_PTR_BRK(ppType); 760 | if(dwStreamId != 0) 761 | CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); 762 | if(dwTypeIndex >= m_listOfMediaTypes.GetCount()) 763 | CHK_LOG_BRK(MF_E_NO_MORE_TYPES); 764 | 765 | *ppType = m_listOfMediaTypes[dwTypeIndex]; 766 | (*ppType)->AddRef(); 767 | } while (FALSE); 768 | 769 | return hr; 770 | } 771 | 772 | STDMETHODIMP CFrameProviderMft0::IsMediaTypeSupported(UINT uiStreamId, IMFMediaType *pIMFMediaType, IMFMediaType **ppIMFMediaTypeFull) 773 | { 774 | HRESULT hr = S_OK; 775 | 776 | do { 777 | CHK_NULL_PTR_BRK(pIMFMediaType); 778 | 779 | if(uiStreamId != 0) 780 | { 781 | CHK_LOG_BRK(MF_E_INVALIDINDEX); 782 | } 783 | BOOL bFound = FALSE; 784 | for(UINT i = 0; i < m_listOfMediaTypes.GetCount(); i++) 785 | { 786 | DWORD dwResult = 0; 787 | hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult); 788 | if(hr == S_FALSE) 789 | { 790 | 791 | if((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) && 792 | (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_TYPES) && 793 | (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_DATA)) 794 | { 795 | hr = S_OK; 796 | } 797 | } 798 | if(hr == S_OK) 799 | { 800 | bFound = TRUE; 801 | if(ppIMFMediaTypeFull) { 802 | *ppIMFMediaTypeFull = m_listOfMediaTypes[i]; 803 | (*ppIMFMediaTypeFull)->AddRef(); 804 | } 805 | break; 806 | } 807 | else if(FAILED(hr)) 808 | { 809 | CHK_LOG_BRK(hr); 810 | } 811 | 812 | } 813 | if(bFound == FALSE) 814 | { 815 | CHK_LOG_BRK(MF_E_INVALIDMEDIATYPE); 816 | } 817 | } while (FALSE); 818 | 819 | return hr; 820 | } 821 | 822 | STDMETHODIMP CFrameProviderMft0::GenerateMFMediaTypeListFromDevice(UINT uiStreamId) 823 | { 824 | HRESULT hr = S_OK; 825 | GUID stSubType = {0}; 826 | 827 | do { 828 | CHK_NULL_PTR_BRK(m_pSourceTransform); 829 | 830 | m_listOfMediaTypes.RemoveAll(); 831 | for(UINT iMediaType = 0; TRUE; iMediaType++) 832 | { 833 | CComPtr pMediaType; 834 | hr = m_pSourceTransform->GetOutputAvailableType(uiStreamId, iMediaType, &pMediaType); 835 | if(hr != S_OK) 836 | break; 837 | CHK_LOG_BRK(pMediaType->GetGUID(MF_MT_SUBTYPE, &stSubType)); 838 | 839 | if(((stSubType == MFVideoFormat_RGB8) || (stSubType == MFVideoFormat_RGB555) || 840 | (stSubType == MFVideoFormat_RGB565) || (stSubType == MFVideoFormat_RGB24) || 841 | (stSubType == MFVideoFormat_RGB32) || (stSubType == MFVideoFormat_ARGB32) || 842 | (stSubType == MFVideoFormat_AI44) || (stSubType == MFVideoFormat_AYUV) || 843 | (stSubType == MFVideoFormat_I420) || (stSubType == MFVideoFormat_IYUV) || 844 | (stSubType == MFVideoFormat_NV11) || (stSubType == MFVideoFormat_NV12) || 845 | (stSubType == MFVideoFormat_UYVY) || (stSubType == MFVideoFormat_Y41P) || 846 | (stSubType == MFVideoFormat_Y41T) || (stSubType == MFVideoFormat_Y42T) || 847 | (stSubType == MFVideoFormat_YUY2) || (stSubType == MFVideoFormat_YV12) || 848 | (stSubType == MFVideoFormat_P010) || (stSubType == MFVideoFormat_P016) || 849 | (stSubType == MFVideoFormat_P210) || (stSubType == MFVideoFormat_P216) || 850 | (stSubType == MFVideoFormat_v210) || (stSubType == MFVideoFormat_v216) || 851 | (stSubType == MFVideoFormat_v410) || (stSubType == MFVideoFormat_Y210) || 852 | (stSubType == MFVideoFormat_Y216) || (stSubType == MFVideoFormat_Y410) || 853 | (stSubType == MFVideoFormat_Y416)) ) 854 | { 855 | m_listOfMediaTypes[(ULONG)(m_listOfMediaTypes.GetCount())] = pMediaType; 856 | } 857 | } 858 | 859 | } while (FALSE); 860 | 861 | if(hr == MF_E_NO_MORE_TYPES) { 862 | hr = S_OK; 863 | } 864 | 865 | return hr; 866 | } -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderMft0.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // FrameProviderMft0.h : Declaration of the CFrameProviderMft0 13 | 14 | #pragma once 15 | #include "resource.h" // main symbols 16 | #include "FrameProviderSampleMft0.h" 17 | #include "SampleHelpers.h" 18 | 19 | #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) 20 | #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." 21 | #endif 22 | 23 | using namespace ATL; 24 | 25 | // Define GUID for our custom MediaFoundation attribute indicating if LED illumination is on for the current media sample 26 | // {24AE8CD8-117D-41B4-88F6-2AE46EF9AF58} 27 | static const GUID WDPP_ACTIVE_ILLUMINATION_ENABLED = { 0x24ae8cd8, 0x117d, 0x41b4,{ 0x88, 0xf6, 0x2a, 0xe4, 0x6e, 0xf9, 0xaf, 0x58 } }; 28 | 29 | 30 | // CFrameProviderMft0 31 | 32 | class ATL_NO_VTABLE CFrameProviderMft0 : 33 | public CComObjectRootEx, 34 | public CComCoClass, 35 | public IFrameProviderMft0, 36 | public IMFTransform, 37 | public IInspectable 38 | { 39 | public: 40 | CFrameProviderMft0() : m_pSample(NULL), 41 | m_pInputType(NULL), 42 | m_pOutputType(NULL), 43 | m_pInputAttributes(0), 44 | m_pGlobalAttributes(0), 45 | m_pSourceTransform(0), 46 | m_uiStreamId(0), 47 | m_nRefCount(1) 48 | { 49 | InitializeCriticalSection(&m_critSec); 50 | } 51 | 52 | DECLARE_REGISTRY_RESOURCEID(IDR_MFT0) 53 | 54 | DECLARE_NOT_AGGREGATABLE(CFrameProviderMft0) 55 | 56 | BEGIN_COM_MAP(CFrameProviderMft0) 57 | COM_INTERFACE_ENTRY(IFrameProviderMft0) 58 | COM_INTERFACE_ENTRY(IMFTransform) 59 | COM_INTERFACE_ENTRY(IInspectable) 60 | END_COM_MAP() 61 | 62 | DECLARE_PROTECT_FINAL_CONSTRUCT() 63 | 64 | HRESULT FinalConstruct() 65 | { 66 | return S_OK; 67 | } 68 | 69 | void FinalRelease() 70 | { 71 | } 72 | 73 | public: 74 | 75 | STDMETHODIMP GetIids( 76 | /* [out] */ _Out_ ULONG *iidCount, 77 | /* [size_is][size_is][out] */ _Outptr_result_buffer_maybenull_(*iidCount) IID **iids); 78 | 79 | STDMETHODIMP GetRuntimeClassName( 80 | /* [out] */ _Outptr_result_maybenull_ HSTRING *className); 81 | 82 | STDMETHODIMP GetTrustLevel( 83 | /* [out] */ _Out_ TrustLevel *trustLevel); 84 | 85 | STDMETHODIMP GetStreamLimits( 86 | /* [out] */ _Out_ DWORD *pdwInputMinimum, 87 | /* [out] */ _Out_ DWORD *pdwInputMaximum, 88 | /* [out] */ _Out_ DWORD *pdwOutputMinimum, 89 | /* [out] */ _Out_ DWORD *pdwOutputMaximum); 90 | 91 | STDMETHODIMP GetStreamCount( 92 | /* [out] */ _Out_ DWORD *pcInputStreams, 93 | /* [out] */ _Out_ DWORD *pcOutputStreams); 94 | 95 | STDMETHODIMP GetStreamIDs( 96 | DWORD dwInputIDArraySize, 97 | /* [size_is][out] */ _Out_writes_(dwInputIDArraySize) DWORD *pdwInputIDs, 98 | DWORD dwOutputIDArraySize, 99 | /* [size_is][out] */ _Out_writes_(dwOutputIDArraySize) DWORD *pdwOutputIDs); 100 | 101 | STDMETHODIMP GetInputStreamInfo( 102 | DWORD dwInputStreamID, 103 | /* [out] */ _Out_ MFT_INPUT_STREAM_INFO *pStreamInfo); 104 | 105 | STDMETHODIMP GetOutputStreamInfo( 106 | DWORD dwOutputStreamID, 107 | /* [out] */ _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo); 108 | 109 | STDMETHODIMP GetAttributes( 110 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **pAttributes); 111 | 112 | STDMETHODIMP GetInputStreamAttributes( 113 | DWORD dwInputStreamID, 114 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **pAttributes); 115 | 116 | STDMETHODIMP GetOutputStreamAttributes( 117 | DWORD dwOutputStreamID, 118 | /* [out] */ _Outptr_result_maybenull_ IMFAttributes **pAttributes); 119 | 120 | STDMETHODIMP DeleteInputStream( 121 | DWORD dwStreamID); 122 | 123 | STDMETHODIMP AddInputStreams( 124 | DWORD cStreams, 125 | /* [in] */ _In_ DWORD *adwStreamIDs); 126 | 127 | STDMETHODIMP GetInputAvailableType( 128 | DWORD dwInputStreamID, 129 | DWORD dwTypeIndex, 130 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType); 131 | 132 | STDMETHODIMP GetOutputAvailableType( 133 | DWORD dwOutputStreamID, 134 | DWORD dwTypeIndex, 135 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType); 136 | 137 | STDMETHODIMP SetInputType( 138 | DWORD dwInputStreamID, 139 | /* [in] */ _In_opt_ IMFMediaType *pType, 140 | DWORD dwFlags); 141 | 142 | STDMETHODIMP SetOutputType( 143 | DWORD dwOutputStreamID, 144 | /* [in] */ _In_opt_ IMFMediaType *pType, 145 | DWORD dwFlags); 146 | 147 | STDMETHODIMP GetInputCurrentType( 148 | DWORD dwInputStreamID, 149 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType); 150 | 151 | STDMETHODIMP GetOutputCurrentType( 152 | DWORD dwOutputStreamID, 153 | /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType); 154 | 155 | STDMETHODIMP GetInputStatus( 156 | DWORD dwInputStreamID, 157 | /* [out] */ _Out_ DWORD *pdwFlags); 158 | 159 | STDMETHODIMP GetOutputStatus( 160 | /* [out] */ _Out_ DWORD *pdwFlags); 161 | 162 | STDMETHODIMP SetOutputBounds( 163 | LONGLONG hnsLowerBound, 164 | LONGLONG hnsUpperBound); 165 | 166 | STDMETHODIMP ProcessEvent( 167 | DWORD dwInputStreamID, 168 | /* [in] */ _In_opt_ IMFMediaEvent *pEvent); 169 | 170 | STDMETHODIMP ProcessMessage( 171 | MFT_MESSAGE_TYPE eMessage, 172 | ULONG_PTR ulParam); 173 | 174 | STDMETHODIMP ProcessInput( 175 | DWORD dwInputStreamID, 176 | IMFSample *pSample, 177 | DWORD dwFlags); 178 | 179 | STDMETHODIMP ProcessOutput( 180 | DWORD dwFlags, 181 | DWORD cOutputBufferCount, 182 | /* [size_is][out][in] */ MFT_OUTPUT_DATA_BUFFER *pOutputSamples, 183 | /* [out] */ DWORD *pdwStatus); 184 | 185 | protected: 186 | virtual ~CFrameProviderMft0() 187 | { 188 | SAFERELEASE(m_pInputAttributes); 189 | SAFERELEASE(m_pGlobalAttributes); 190 | SAFERELEASE(m_pSourceTransform); 191 | SAFERELEASE(m_pInputType); 192 | SAFERELEASE(m_pOutputType); 193 | SAFERELEASE(m_pSample); 194 | DeleteCriticalSection(&m_critSec); 195 | } 196 | 197 | STDMETHODIMP GetMediaType(DWORD dwStreamID, DWORD dwTypeIndex, IMFMediaType **ppType); 198 | STDMETHODIMP IsMediaTypeSupported(UINT uiStreamId, IMFMediaType *pIMFMediaType, IMFMediaType **ppIMFMediaTypeFull = NULL); 199 | STDMETHODIMP GenerateMFMediaTypeListFromDevice(UINT uiStreamId); 200 | 201 | // HasPendingOutput: Returns TRUE if the MFT is holding an input sample. 202 | BOOL HasPendingOutput() const { return m_pSample != NULL; } 203 | 204 | // IsValidInputStream: Returns TRUE if dwInputStreamID is a valid input stream identifier. 205 | BOOL IsValidInputStream(DWORD dwInputStreamID); 206 | 207 | // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier. 208 | BOOL IsValidOutputStream(DWORD dwOutputStreamID); 209 | 210 | STDMETHODIMP GetDefaultStride(LONG *plStride); 211 | 212 | STDMETHODIMP OnFlush(); 213 | 214 | CRITICAL_SECTION m_critSec; 215 | 216 | IMFSample *m_pSample; // Input sample. 217 | IMFMediaType *m_pInputType; // Input media type. 218 | IMFMediaType *m_pOutputType; // Output media type. 219 | 220 | // Image transform function. (Changes based on the media type.) 221 | IMFAttributes *m_pInputAttributes; 222 | IMFAttributes *m_pGlobalAttributes; 223 | GUID m_stStreamType; 224 | IMFTransform *m_pSourceTransform; 225 | UINT m_uiStreamId; 226 | UINT m_nRefCount; 227 | CAtlMap> m_listOfMediaTypes; 228 | }; 229 | 230 | OBJECT_ENTRY_AUTO(__uuidof(FrameProviderMft0), CFrameProviderMft0) 231 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // FrameProviderSampleMft0.cpp : Implementation of DLL Exports. 13 | 14 | #include "stdafx.h" 15 | #include "resource.h" 16 | #include "FrameProviderSampleMft0.h" 17 | #include "dllmain.h" 18 | 19 | 20 | // Used to determine whether the DLL can be unloaded by OLE. 21 | STDAPI DllCanUnloadNow(void) 22 | { 23 | #ifdef _MERGE_PROXYSTUB 24 | HRESULT hr = PrxDllCanUnloadNow(); 25 | if (hr != S_OK) 26 | return hr; 27 | #endif 28 | return _AtlModule.DllCanUnloadNow(); 29 | } 30 | 31 | // Returns a class factory to create an object of the requested type. 32 | STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv) 33 | { 34 | #ifdef _MERGE_PROXYSTUB 35 | if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK) 36 | return S_OK; 37 | #endif 38 | return _AtlModule.DllGetClassObject(rclsid, riid, ppv); 39 | } 40 | 41 | // DllRegisterServer - Adds entries to the system registry. 42 | STDAPI DllRegisterServer(void) 43 | { 44 | // registers object, typelib and all interfaces in typelib 45 | HRESULT hr = _AtlModule.DllRegisterServer(); 46 | #ifdef _MERGE_PROXYSTUB 47 | if (FAILED(hr)) 48 | return hr; 49 | hr = PrxDllRegisterServer(); 50 | #endif 51 | return hr; 52 | } 53 | 54 | // DllUnregisterServer - Removes entries from the system registry. 55 | STDAPI DllUnregisterServer(void) 56 | { 57 | HRESULT hr = _AtlModule.DllUnregisterServer(); 58 | #ifdef _MERGE_PROXYSTUB 59 | if (FAILED(hr)) 60 | return hr; 61 | hr = PrxDllRegisterServer(); 62 | if (FAILED(hr)) 63 | return hr; 64 | hr = PrxDllUnregisterServer(); 65 | #endif 66 | return hr; 67 | } 68 | 69 | // DllInstall - Adds/Removes entries to the system registry per user per machine. 70 | STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine) 71 | { 72 | UNREFERENCED_PARAMETER(pszCmdLine); 73 | HRESULT hr = E_FAIL; 74 | static const wchar_t szUserSwitch[] = L"user"; 75 | 76 | 77 | if (bInstall) 78 | { 79 | hr = DllRegisterServer(); 80 | if (FAILED(hr)) 81 | { 82 | DllUnregisterServer(); 83 | } 84 | } 85 | else 86 | { 87 | hr = DllUnregisterServer(); 88 | } 89 | 90 | return hr; 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.def: -------------------------------------------------------------------------------- 1 | ; Copyright (c) Microsoft. All rights reserved. 2 | ; This code is licensed under the MIT License (MIT). 3 | ; THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 4 | ; ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 5 | ; IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 6 | ; PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 7 | 8 | ; FrameProviderSampleMft0.def : Declares the module parameters. 9 | 10 | LIBRARY 11 | 12 | EXPORTS 13 | DllCanUnloadNow PRIVATE 14 | DllGetClassObject PRIVATE 15 | DllRegisterServer PRIVATE 16 | DllUnregisterServer PRIVATE 17 | DllInstall PRIVATE 18 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.idl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // FrameProviderSampleMft0.idl : IDL source for MFT0 13 | // 14 | 15 | // This file will be processed by the MIDL tool to 16 | // produce the type library (FrameProviderSampleMft0.tlb) and marshalling code. 17 | 18 | import "oaidl.idl"; 19 | import "ocidl.idl"; 20 | import "Inspectable.idl"; 21 | import "mftransform.idl"; 22 | [ 23 | object, 24 | uuid(805222A9-54D6-4D89-B581-CB074097FE01), 25 | oleautomation, 26 | nonextensible, 27 | pointer_default(unique) 28 | ] 29 | interface IFrameProviderMft0 : IUnknown{ 30 | 31 | }; 32 | [ 33 | uuid(6BD93230-BACB-4421-87CD-CC7A7816ED4A), 34 | version(1.0), 35 | ] 36 | library FrameProviderSampleMft0Lib 37 | { 38 | importlib("stdole2.tlb"); 39 | [ 40 | uuid(DDBE4BC1-541F-4D43-A25B-1F23E7AF4505) 41 | ] 42 | coclass FrameProviderMft0 43 | { 44 | [default] interface IFrameProviderMft0; 45 | interface IInspectable; 46 | interface IMFTransform; 47 | }; 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/FrameProviderSample/MFT0/FrameProviderSampleMft0.rc -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.rgs: -------------------------------------------------------------------------------- 1 | HKCR 2 | { 3 | } 4 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {9DE02487-876A-4DD8-BC75-E6B5980B7461} 23 | $(MSBuildProjectName) 24 | Win8.1 Debug 25 | Win32 26 | {0E54608E-D9AB-4A4E-85E3-F4BCA58584AD} 27 | 10.0.10240.0 28 | 29 | 30 | 31 | WindowsV6.3 32 | False 33 | 34 | WindowsApplicationForDrivers10.0 35 | DynamicLibrary 36 | 37 | 38 | WindowsV6.3 39 | True 40 | 41 | WindowsApplicationForDrivers10.0 42 | DynamicLibrary 43 | 44 | 45 | WindowsV6.3 46 | False 47 | 48 | WindowsApplicationForDrivers10.0 49 | DynamicLibrary 50 | 51 | 52 | WindowsV6.3 53 | True 54 | 55 | WindowsApplicationForDrivers10.0 56 | DynamicLibrary 57 | 58 | 59 | 60 | $(IntDir) 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | FrameProviderSampleMft0 77 | 78 | 79 | FrameProviderSampleMft0 80 | 81 | 82 | FrameProviderSampleMft0 83 | 84 | 85 | FrameProviderSampleMft0 86 | 87 | 88 | 89 | MultiThreaded 90 | MultiThreadedDebug 91 | 92 | 93 | 94 | 95 | MultiThreaded 96 | MultiThreadedDebug 97 | 98 | 99 | 100 | 101 | MultiThreaded 102 | MultiThreadedDebug 103 | 104 | 105 | 106 | 107 | MultiThreaded 108 | MultiThreadedDebug 109 | 110 | 111 | 112 | Static 113 | 114 | 115 | Static 116 | 117 | 118 | Static 119 | 120 | 121 | Static 122 | 123 | 124 | 125 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 126 | 127 | 128 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 129 | 130 | 131 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 132 | 133 | 134 | 135 | 136 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 137 | 138 | 139 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 140 | 141 | 142 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 143 | 144 | 145 | 146 | 147 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 148 | 149 | 150 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 151 | 152 | 153 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 154 | 155 | 156 | 157 | 158 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 159 | 160 | 161 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 162 | 163 | 164 | %(AdditionalIncludeDirectories);$(SDK_INC_PATH);$(IntDir) 165 | 166 | 167 | 168 | 169 | %(AdditionalDependencies);kernel32.lib;gdi32.lib;ntdll.lib;user32.lib;advapi32.lib;ole32.lib;uuid.lib;version.lib;winmm.lib;comdlg32.lib;Oleaut32.lib;Shlwapi.lib;comctl32.lib;mfuuid.lib;mf.lib;mfplat.lib;runtimeobject.lib 170 | FrameProviderSampleMft0.def 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | %(AdditionalDependencies);kernel32.lib;gdi32.lib;ntdll.lib;user32.lib;advapi32.lib;ole32.lib;uuid.lib;version.lib;winmm.lib;comdlg32.lib;Oleaut32.lib;Shlwapi.lib;comctl32.lib;mfuuid.lib;mf.lib;mfplat.lib;runtimeobject.lib 180 | FrameProviderSampleMft0.def 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | %(AdditionalDependencies);kernel32.lib;gdi32.lib;ntdll.lib;user32.lib;advapi32.lib;ole32.lib;uuid.lib;version.lib;winmm.lib;comdlg32.lib;Oleaut32.lib;Shlwapi.lib;comctl32.lib;mfuuid.lib;mf.lib;mfplat.lib;runtimeobject.lib 190 | FrameProviderSampleMft0.def 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | %(AdditionalDependencies);kernel32.lib;gdi32.lib;ntdll.lib;user32.lib;advapi32.lib;ole32.lib;uuid.lib;version.lib;winmm.lib;comdlg32.lib;Oleaut32.lib;Shlwapi.lib;comctl32.lib;mfuuid.lib;mf.lib;mfplat.lib;runtimeobject.lib 200 | FrameProviderSampleMft0.def 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | ;%(AdditionalIncludeDirectories) 211 | stdafx.h 212 | Use 213 | $(IntDir)\stdafx.h.pch 214 | 215 | 216 | ;%(AdditionalIncludeDirectories) 217 | stdafx.h 218 | Use 219 | $(IntDir)\stdafx.h.pch 220 | 221 | 222 | ;%(AdditionalIncludeDirectories) 223 | stdafx.h 224 | Use 225 | $(IntDir)\stdafx.h.pch 226 | 227 | 228 | ;%(AdditionalIncludeDirectories) 229 | stdafx.h 230 | Create 231 | $(IntDir)\stdafx.h.pch 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0.vcxproj.Filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* 6 | {F4B727D6-CC51-4954-BD30-D466E835773E} 7 | 8 | 9 | h;hpp;hxx;hm;inl;inc;xsd 10 | {C0B93556-8DA4-44C8-928F-90BE5E27C3A9} 11 | 12 | 13 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml 14 | {44B38E43-69C6-425A-B38E-9B2BB23715F2} 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | 55 | 56 | 57 | Header Files 58 | 59 | 60 | 61 | 62 | 63 | Header Files 64 | 65 | 66 | 67 | 68 | 69 | Header Files 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Header Files 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Header Files 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Header Files 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Header Files 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | Header Files 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files 130 | 131 | 132 | Header Files 133 | 134 | 135 | Header Files 136 | 137 | 138 | Header Files 139 | 140 | 141 | Header Files 142 | 143 | 144 | Header Files 145 | 146 | 147 | Header Files 148 | 149 | 150 | Header Files 151 | 152 | 153 | Header Files 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | Header Files 166 | 167 | 168 | Header Files 169 | 170 | 171 | Header Files 172 | 173 | 174 | Header Files 175 | 176 | 177 | Header Files 178 | 179 | 180 | Header Files 181 | 182 | 183 | Header Files 184 | 185 | 186 | 187 | 188 | Resource Files 189 | 190 | 191 | 192 | 193 | Source Files 194 | 195 | 196 | 197 | 198 | Source Files 199 | 200 | 201 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0_h.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the definitions for the interfaces */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.00.0613 */ 7 | /* at Mon Jan 18 19:14:07 2038 8 | */ 9 | /* Compiler settings for FrameProviderSampleMft0.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0613 11 | protocol : dce , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 20 | 21 | 22 | /* verify that the version is high enough to compile this file*/ 23 | #ifndef __REQUIRED_RPCNDR_H_VERSION__ 24 | #define __REQUIRED_RPCNDR_H_VERSION__ 475 25 | #endif 26 | 27 | #include "rpc.h" 28 | #include "rpcndr.h" 29 | 30 | #ifndef __RPCNDR_H_VERSION__ 31 | #error this stub requires an updated version of 32 | #endif /* __RPCNDR_H_VERSION__ */ 33 | 34 | #ifndef COM_NO_WINDOWS_H 35 | #include "windows.h" 36 | #include "ole2.h" 37 | #endif /*COM_NO_WINDOWS_H*/ 38 | 39 | #ifndef __FrameProviderSampleMft0_h_h__ 40 | #define __FrameProviderSampleMft0_h_h__ 41 | 42 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 43 | #pragma once 44 | #endif 45 | 46 | /* Forward Declarations */ 47 | 48 | #ifndef __IFrameProviderMft0_FWD_DEFINED__ 49 | #define __IFrameProviderMft0_FWD_DEFINED__ 50 | typedef interface IFrameProviderMft0 IFrameProviderMft0; 51 | 52 | #endif /* __IFrameProviderMft0_FWD_DEFINED__ */ 53 | 54 | 55 | #ifndef __FrameProviderMft0_FWD_DEFINED__ 56 | #define __FrameProviderMft0_FWD_DEFINED__ 57 | 58 | #ifdef __cplusplus 59 | typedef class FrameProviderMft0 FrameProviderMft0; 60 | #else 61 | typedef struct FrameProviderMft0 FrameProviderMft0; 62 | #endif /* __cplusplus */ 63 | 64 | #endif /* __FrameProviderMft0_FWD_DEFINED__ */ 65 | 66 | 67 | /* header files for imported files */ 68 | #include "oaidl.h" 69 | #include "ocidl.h" 70 | #include "Inspectable.h" 71 | #include "mftransform.h" 72 | 73 | #ifdef __cplusplus 74 | extern "C"{ 75 | #endif 76 | 77 | 78 | #ifndef __IFrameProviderMft0_INTERFACE_DEFINED__ 79 | #define __IFrameProviderMft0_INTERFACE_DEFINED__ 80 | 81 | /* interface IFrameProviderMft0 */ 82 | /* [unique][nonextensible][oleautomation][uuid][object] */ 83 | 84 | 85 | EXTERN_C const IID IID_IFrameProviderMft0; 86 | 87 | #if defined(__cplusplus) && !defined(CINTERFACE) 88 | 89 | MIDL_INTERFACE("805222A9-54D6-4D89-B581-CB074097FE01") 90 | IFrameProviderMft0 : public IUnknown 91 | { 92 | public: 93 | }; 94 | 95 | 96 | #else /* C style interface */ 97 | 98 | typedef struct IFrameProviderMft0Vtbl 99 | { 100 | BEGIN_INTERFACE 101 | 102 | HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 103 | IFrameProviderMft0 * This, 104 | /* [in] */ REFIID riid, 105 | /* [annotation][iid_is][out] */ 106 | _COM_Outptr_ void **ppvObject); 107 | 108 | ULONG ( STDMETHODCALLTYPE *AddRef )( 109 | IFrameProviderMft0 * This); 110 | 111 | ULONG ( STDMETHODCALLTYPE *Release )( 112 | IFrameProviderMft0 * This); 113 | 114 | END_INTERFACE 115 | } IFrameProviderMft0Vtbl; 116 | 117 | interface IFrameProviderMft0 118 | { 119 | CONST_VTBL struct IFrameProviderMft0Vtbl *lpVtbl; 120 | }; 121 | 122 | 123 | 124 | #ifdef COBJMACROS 125 | 126 | 127 | #define IFrameProviderMft0_QueryInterface(This,riid,ppvObject) \ 128 | ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 129 | 130 | #define IFrameProviderMft0_AddRef(This) \ 131 | ( (This)->lpVtbl -> AddRef(This) ) 132 | 133 | #define IFrameProviderMft0_Release(This) \ 134 | ( (This)->lpVtbl -> Release(This) ) 135 | 136 | 137 | #endif /* COBJMACROS */ 138 | 139 | 140 | #endif /* C style interface */ 141 | 142 | 143 | 144 | 145 | #endif /* __IFrameProviderMft0_INTERFACE_DEFINED__ */ 146 | 147 | 148 | 149 | #ifndef __FrameProviderSampleMft0Lib_LIBRARY_DEFINED__ 150 | #define __FrameProviderSampleMft0Lib_LIBRARY_DEFINED__ 151 | 152 | /* library FrameProviderSampleMft0Lib */ 153 | /* [version][uuid] */ 154 | 155 | 156 | EXTERN_C const IID LIBID_FrameProviderSampleMft0Lib; 157 | 158 | EXTERN_C const CLSID CLSID_FrameProviderMft0; 159 | 160 | #ifdef __cplusplus 161 | 162 | class DECLSPEC_UUID("DDBE4BC1-541F-4D43-A25B-1F23E7AF4505") 163 | FrameProviderMft0; 164 | #endif 165 | #endif /* __FrameProviderSampleMft0Lib_LIBRARY_DEFINED__ */ 166 | 167 | /* Additional Prototypes for ALL interfaces */ 168 | 169 | /* end of Additional Prototypes */ 170 | 171 | #ifdef __cplusplus 172 | } 173 | #endif 174 | 175 | #endif 176 | 177 | 178 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0_i.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ 4 | 5 | /* link this file in with the server and any clients */ 6 | 7 | 8 | /* File created by MIDL compiler version 8.00.0613 */ 9 | /* at Mon Jan 18 19:14:07 2038 10 | */ 11 | /* Compiler settings for FrameProviderSampleMft0.idl: 12 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0613 13 | protocol : dce , ms_ext, c_ext, robust 14 | error checks: allocation ref bounds_check enum stub_data 15 | VC __declspec() decoration level: 16 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 17 | DECLSPEC_UUID(), MIDL_INTERFACE() 18 | */ 19 | /* @@MIDL_FILE_HEADING( ) */ 20 | 21 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 22 | 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | 29 | #include 30 | #include 31 | 32 | #ifdef _MIDL_USE_GUIDDEF_ 33 | 34 | #ifndef INITGUID 35 | #define INITGUID 36 | #include 37 | #undef INITGUID 38 | #else 39 | #include 40 | #endif 41 | 42 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 43 | DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) 44 | 45 | #else // !_MIDL_USE_GUIDDEF_ 46 | 47 | #ifndef __IID_DEFINED__ 48 | #define __IID_DEFINED__ 49 | 50 | typedef struct _IID 51 | { 52 | unsigned long x; 53 | unsigned short s1; 54 | unsigned short s2; 55 | unsigned char c[8]; 56 | } IID; 57 | 58 | #endif // __IID_DEFINED__ 59 | 60 | #ifndef CLSID_DEFINED 61 | #define CLSID_DEFINED 62 | typedef IID CLSID; 63 | #endif // CLSID_DEFINED 64 | 65 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 66 | const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} 67 | 68 | #endif !_MIDL_USE_GUIDDEF_ 69 | 70 | MIDL_DEFINE_GUID(IID, IID_IFrameProviderMft0,0x805222A9,0x54D6,0x4D89,0xB5,0x81,0xCB,0x07,0x40,0x97,0xFE,0x01); 71 | 72 | 73 | MIDL_DEFINE_GUID(IID, LIBID_FrameProviderSampleMft0Lib,0x6BD93230,0xBACB,0x4421,0x87,0xCD,0xCC,0x7A,0x78,0x16,0xED,0x4A); 74 | 75 | 76 | MIDL_DEFINE_GUID(CLSID, CLSID_FrameProviderMft0,0xDDBE4BC1,0x541F,0x4D43,0xA2,0x5B,0x1F,0x23,0xE7,0xAF,0x45,0x05); 77 | 78 | #undef MIDL_DEFINE_GUID 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/FrameProviderSampleMft0_p.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the proxy stub code */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.00.0613 */ 7 | /* at Mon Jan 18 19:14:07 2038 8 | */ 9 | /* Compiler settings for FrameProviderSampleMft0.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0613 11 | protocol : dce , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | #if defined(_M_AMD64) 20 | 21 | 22 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 23 | #if _MSC_VER >= 1200 24 | #pragma warning(push) 25 | #endif 26 | 27 | #pragma warning( disable: 4211 ) /* redefine extern to static */ 28 | #pragma warning( disable: 4232 ) /* dllimport identity*/ 29 | #pragma warning( disable: 4024 ) /* array to pointer mapping*/ 30 | #pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */ 31 | 32 | #define USE_STUBLESS_PROXY 33 | 34 | 35 | /* verify that the version is high enough to compile this file*/ 36 | #ifndef __REDQ_RPCPROXY_H_VERSION__ 37 | #define __REQUIRED_RPCPROXY_H_VERSION__ 475 38 | #endif 39 | 40 | 41 | #include "rpcproxy.h" 42 | #ifndef __RPCPROXY_H_VERSION__ 43 | #error this stub requires an updated version of 44 | #endif /* __RPCPROXY_H_VERSION__ */ 45 | 46 | 47 | #include "FrameProviderSampleMft0_h.h" 48 | 49 | #define TYPE_FORMAT_STRING_SIZE 3 50 | #define PROC_FORMAT_STRING_SIZE 1 51 | #define EXPR_FORMAT_STRING_SIZE 1 52 | #define TRANSMIT_AS_TABLE_SIZE 0 53 | #define WIRE_MARSHAL_TABLE_SIZE 0 54 | 55 | typedef struct _FrameProviderSampleMft0_MIDL_TYPE_FORMAT_STRING 56 | { 57 | short Pad; 58 | unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; 59 | } FrameProviderSampleMft0_MIDL_TYPE_FORMAT_STRING; 60 | 61 | typedef struct _FrameProviderSampleMft0_MIDL_PROC_FORMAT_STRING 62 | { 63 | short Pad; 64 | unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; 65 | } FrameProviderSampleMft0_MIDL_PROC_FORMAT_STRING; 66 | 67 | typedef struct _FrameProviderSampleMft0_MIDL_EXPR_FORMAT_STRING 68 | { 69 | long Pad; 70 | unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; 71 | } FrameProviderSampleMft0_MIDL_EXPR_FORMAT_STRING; 72 | 73 | 74 | static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = 75 | {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; 76 | 77 | 78 | extern const FrameProviderSampleMft0_MIDL_TYPE_FORMAT_STRING FrameProviderSampleMft0__MIDL_TypeFormatString; 79 | extern const FrameProviderSampleMft0_MIDL_PROC_FORMAT_STRING FrameProviderSampleMft0__MIDL_ProcFormatString; 80 | extern const FrameProviderSampleMft0_MIDL_EXPR_FORMAT_STRING FrameProviderSampleMft0__MIDL_ExprFormatString; 81 | 82 | 83 | extern const MIDL_STUB_DESC Object_StubDesc; 84 | 85 | 86 | extern const MIDL_SERVER_INFO IFrameProviderMft0_ServerInfo; 87 | extern const MIDL_STUBLESS_PROXY_INFO IFrameProviderMft0_ProxyInfo; 88 | 89 | 90 | 91 | #if !defined(__RPC_WIN64__) 92 | #error Invalid build platform for this stub. 93 | #endif 94 | 95 | static const FrameProviderSampleMft0_MIDL_PROC_FORMAT_STRING FrameProviderSampleMft0__MIDL_ProcFormatString = 96 | { 97 | 0, 98 | { 99 | 100 | 0x0 101 | } 102 | }; 103 | 104 | static const FrameProviderSampleMft0_MIDL_TYPE_FORMAT_STRING FrameProviderSampleMft0__MIDL_TypeFormatString = 105 | { 106 | 0, 107 | { 108 | NdrFcShort( 0x0 ), /* 0 */ 109 | 110 | 0x0 111 | } 112 | }; 113 | 114 | 115 | /* Object interface: IUnknown, ver. 0.0, 116 | GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ 117 | 118 | 119 | /* Object interface: IFrameProviderMft0, ver. 0.0, 120 | GUID={0x805222A9,0x54D6,0x4D89,{0xB5,0x81,0xCB,0x07,0x40,0x97,0xFE,0x01}} */ 121 | 122 | #pragma code_seg(".orpc") 123 | static const unsigned short IFrameProviderMft0_FormatStringOffsetTable[] = 124 | { 125 | 0 126 | }; 127 | 128 | static const MIDL_STUBLESS_PROXY_INFO IFrameProviderMft0_ProxyInfo = 129 | { 130 | &Object_StubDesc, 131 | FrameProviderSampleMft0__MIDL_ProcFormatString.Format, 132 | &IFrameProviderMft0_FormatStringOffsetTable[-3], 133 | 0, 134 | 0, 135 | 0 136 | }; 137 | 138 | 139 | static const MIDL_SERVER_INFO IFrameProviderMft0_ServerInfo = 140 | { 141 | &Object_StubDesc, 142 | 0, 143 | FrameProviderSampleMft0__MIDL_ProcFormatString.Format, 144 | &IFrameProviderMft0_FormatStringOffsetTable[-3], 145 | 0, 146 | 0, 147 | 0, 148 | 0}; 149 | CINTERFACE_PROXY_VTABLE(3) _IFrameProviderMft0ProxyVtbl = 150 | { 151 | 0, 152 | &IID_IFrameProviderMft0, 153 | IUnknown_QueryInterface_Proxy, 154 | IUnknown_AddRef_Proxy, 155 | IUnknown_Release_Proxy 156 | }; 157 | 158 | const CInterfaceStubVtbl _IFrameProviderMft0StubVtbl = 159 | { 160 | &IID_IFrameProviderMft0, 161 | &IFrameProviderMft0_ServerInfo, 162 | 3, 163 | 0, /* pure interpreted */ 164 | CStdStubBuffer_METHODS 165 | }; 166 | 167 | static const MIDL_STUB_DESC Object_StubDesc = 168 | { 169 | 0, 170 | NdrOleAllocate, 171 | NdrOleFree, 172 | 0, 173 | 0, 174 | 0, 175 | 0, 176 | 0, 177 | FrameProviderSampleMft0__MIDL_TypeFormatString.Format, 178 | 1, /* -error bounds_check flag */ 179 | 0x50002, /* Ndr library version */ 180 | 0, 181 | 0x8000265, /* MIDL Version 8.0.613 */ 182 | 0, 183 | 0, 184 | 0, /* notify & notify_flag routine table */ 185 | 0x1, /* MIDL flag */ 186 | 0, /* cs routines */ 187 | 0, /* proxy/server info */ 188 | 0 189 | }; 190 | 191 | const CInterfaceProxyVtbl * const _FrameProviderSampleMft0_ProxyVtblList[] = 192 | { 193 | ( CInterfaceProxyVtbl *) &_IFrameProviderMft0ProxyVtbl, 194 | 0 195 | }; 196 | 197 | const CInterfaceStubVtbl * const _FrameProviderSampleMft0_StubVtblList[] = 198 | { 199 | ( CInterfaceStubVtbl *) &_IFrameProviderMft0StubVtbl, 200 | 0 201 | }; 202 | 203 | PCInterfaceName const _FrameProviderSampleMft0_InterfaceNamesList[] = 204 | { 205 | "IFrameProviderMft0", 206 | 0 207 | }; 208 | 209 | 210 | #define _FrameProviderSampleMft0_CHECK_IID(n) IID_GENERIC_CHECK_IID( _FrameProviderSampleMft0, pIID, n) 211 | 212 | int __stdcall _FrameProviderSampleMft0_IID_Lookup( const IID * pIID, int * pIndex ) 213 | { 214 | 215 | if(!_FrameProviderSampleMft0_CHECK_IID(0)) 216 | { 217 | *pIndex = 0; 218 | return 1; 219 | } 220 | 221 | return 0; 222 | } 223 | 224 | const ExtendedProxyFileInfo FrameProviderSampleMft0_ProxyFileInfo = 225 | { 226 | (PCInterfaceProxyVtblList *) & _FrameProviderSampleMft0_ProxyVtblList, 227 | (PCInterfaceStubVtblList *) & _FrameProviderSampleMft0_StubVtblList, 228 | (const PCInterfaceName * ) & _FrameProviderSampleMft0_InterfaceNamesList, 229 | 0, /* no delegation */ 230 | & _FrameProviderSampleMft0_IID_Lookup, 231 | 1, 232 | 2, 233 | 0, /* table of [async_uuid] interfaces */ 234 | 0, /* Filler1 */ 235 | 0, /* Filler2 */ 236 | 0 /* Filler3 */ 237 | }; 238 | #if _MSC_VER >= 1200 239 | #pragma warning(pop) 240 | #endif 241 | 242 | 243 | #endif /* defined(_M_AMD64)*/ 244 | 245 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/Mft0.rgs: -------------------------------------------------------------------------------- 1 | HKCR 2 | { 3 | NoRemove CLSID 4 | { 5 | ForceRemove {6BD93230-BACB-4421-87CD-CC7A7816ED4A} = s 'FrameProviderMft0 Class' 6 | { 7 | InprocServer32 = s '%MODULE%' 8 | { 9 | val ThreadingModel = s 'Both' 10 | } 11 | TypeLib = s '{DE05674A-C564-4C0E-9B7C-E1519F7AA767}' 12 | Version = s '1.0' 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/SampleHelpers.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | #include "stdafx.h" 14 | 15 | #define WIDEN2(x) L ## x 16 | #define WIDEN(x) WIDEN2(x) 17 | #define __WFILE__ WIDEN(__FILE__) 18 | 19 | 20 | #define WPP_CONTROL_GUIDS \ 21 | WPP_DEFINE_CONTROL_GUID(WPPCameraExtensionMFt_Sample, \ 22 | (31A88041,BBF0,4D2C,A752,16EB1E51859C), \ 23 | WPP_DEFINE_BIT(AllMessages) \ 24 | ) 25 | 26 | #define SAFEFREE(x) \ 27 | if(x) { \ 28 | free(x); \ 29 | x = NULL; \ 30 | } 31 | #define SAFERELEASE(x) \ 32 | if(x) { \ 33 | x->Release(); \ 34 | x = NULL; \ 35 | } 36 | 37 | #define CHK_LOG_BRK(exp) \ 38 | if(FAILED(hr = (exp))) { \ 39 | wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \ 40 | break; \ 41 | } 42 | 43 | #define CHK_NULL_BRK(exp) \ 44 | if((exp) == NULL) { \ 45 | hr = E_OUTOFMEMORY; \ 46 | wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \ 47 | break; \ 48 | } 49 | #define CHK_NULL_PTR_BRK(exp) \ 50 | if((exp) == NULL) { \ 51 | hr = E_INVALIDARG; \ 52 | wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \ 53 | break; \ 54 | } 55 | 56 | #define CHK_BOOL_BRK(exp) \ 57 | if(!exp) { \ 58 | hr = E_FAIL; \ 59 | wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \ 60 | break; \ 61 | } 62 | 63 | 64 | class VideoBufferLock 65 | { 66 | public: 67 | VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL) 68 | { 69 | m_pBuffer = pBuffer; 70 | m_pBuffer->AddRef(); 71 | 72 | // Query for the 2-D buffer interface. OK if this fails. 73 | m_pBuffer->QueryInterface(IID_IMF2DBuffer, (void**)&m_p2DBuffer); 74 | } 75 | 76 | ~VideoBufferLock() 77 | { 78 | UnlockBuffer(); 79 | SAFERELEASE(m_pBuffer); 80 | SAFERELEASE(m_p2DBuffer); 81 | } 82 | 83 | // LockBuffer: 84 | // Locks the buffer. Returns a pointer to scan line 0 and returns the stride. 85 | 86 | // The caller must provide the default stride as an input parameter, in case 87 | // the buffer does not expose IMF2DBuffer. You can calculate the default stride 88 | // from the media type. 89 | 90 | HRESULT LockBuffer( 91 | LONG lDefaultStride, // Minimum stride (with no padding). 92 | DWORD dwHeightInPixels, // Height of the image, in pixels. 93 | BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0. 94 | LONG *plStride // Receives the actual stride. 95 | ) 96 | { 97 | HRESULT hr = S_OK; 98 | 99 | // Use the 2-D version if available. 100 | if (m_p2DBuffer) 101 | { 102 | hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride); 103 | } 104 | else 105 | { 106 | // Use non-2D version. 107 | BYTE *pData = NULL; 108 | 109 | hr = m_pBuffer->Lock(&pData, NULL, NULL); 110 | if (SUCCEEDED(hr)) 111 | { 112 | *plStride = lDefaultStride; 113 | if (lDefaultStride < 0) 114 | { 115 | // Bottom-up orientation. Return a pointer to the start of the 116 | // last row *in memory* which is the top row of the image. 117 | *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1); 118 | } 119 | else 120 | { 121 | // Top-down orientation. Return a pointer to the start of the 122 | // buffer. 123 | *ppbScanLine0 = pData; 124 | } 125 | } 126 | } 127 | return hr; 128 | } 129 | 130 | HRESULT UnlockBuffer() 131 | { 132 | if (m_p2DBuffer) 133 | { 134 | return m_p2DBuffer->Unlock2D(); 135 | } 136 | else 137 | { 138 | return m_pBuffer->Unlock(); 139 | } 140 | } 141 | 142 | private: 143 | IMFMediaBuffer *m_pBuffer; 144 | IMF2DBuffer *m_p2DBuffer; 145 | }; 146 | 147 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/dlldata.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | DllData file -- generated by MIDL compiler 3 | 4 | DO NOT ALTER THIS FILE 5 | 6 | This file is regenerated by MIDL on every IDL file compile. 7 | 8 | To completely reconstruct this file, delete it and rerun MIDL 9 | on all the IDL files in this DLL, specifying this file for the 10 | /dlldata command line option 11 | 12 | *********************************************************/ 13 | 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | EXTERN_PROXY_FILE( FrameProviderSampleMft0 ) 22 | 23 | 24 | PROXYFILE_LIST_START 25 | /* Start of list */ 26 | REFERENCE_PROXY_FILE( FrameProviderSampleMft0 ), 27 | /* End of list */ 28 | PROXYFILE_LIST_END 29 | 30 | 31 | DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) 32 | 33 | #ifdef __cplusplus 34 | } /*extern "C" */ 35 | #endif 36 | 37 | /* end of generated dlldata file */ 38 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/dllmain.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // dllmain.cpp : Implementation of DllMain. 13 | 14 | #include "stdafx.h" 15 | #include "resource.h" 16 | #include "FrameProviderSampleMft0.h" 17 | #include "dllmain.h" 18 | 19 | CFrameProviderSampleMft0Module _AtlModule; 20 | 21 | // DLL Entry Point 22 | extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 23 | { 24 | #ifdef _MERGE_PROXYSTUB 25 | if (!PrxDllMain(hInstance, dwReason, lpReserved)) 26 | return FALSE; 27 | #endif 28 | hInstance; 29 | return _AtlModule.DllMain(dwReason, lpReserved); 30 | } 31 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/dllmain.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // dllmain.h : Declaration of module class. 13 | 14 | class CFrameProviderSampleMft0Module : public ATL::CAtlDllModuleT< CFrameProviderSampleMft0Module > 15 | { 16 | public : 17 | DECLARE_LIBID(LIBID_FrameProviderSampleMft0Lib) 18 | DECLARE_REGISTRY_APPID_RESOURCEID(IDR_FRAMEPROVIDERSAMPLEMFT0, "{9DA12F8B-54A4-4C67-A3D2-AD09F1A79102}") 19 | }; 20 | 21 | extern class CFrameProviderSampleMft0Module _AtlModule; 22 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/FrameProviderSample/MFT0/resource.h -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 2 | //// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 3 | //// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 4 | //// PARTICULAR PURPOSE. 5 | //// 6 | //// Copyright (c) Microsoft Corporation. All rights reserved 7 | 8 | 9 | // stdafx.cpp : source file that includes just the standard includes 10 | // SampleMft0.pch will be the pre-compiled header 11 | // stdafx.obj will contain the pre-compiled type information 12 | 13 | #include "stdafx.h" 14 | -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/stdafx.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // stdafx.h : include file for standard system include files, 13 | // or project specific include files that are used frequently, 14 | // but are changed infrequently 15 | 16 | #pragma once 17 | 18 | #ifndef STRICT 19 | #define STRICT 20 | #endif 21 | 22 | #include "targetver.h" 23 | 24 | #define _ATL_APARTMENT_THREADED 25 | 26 | #define _ATL_NO_AUTOMATIC_NAMESPACE 27 | 28 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 29 | 30 | 31 | #define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW 32 | 33 | #include "resource.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include -------------------------------------------------------------------------------- /FrameProviderSample/MFT0/targetver.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | // Including SDKDDKVer.h defines the highest available Windows platform. 15 | 16 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 17 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 18 | 19 | #include 20 | -------------------------------------------------------------------------------- /FrameProviderSample/MediaDeviceManager.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "pch.h" 13 | #include "MediaFoundationWrapper.h" 14 | 15 | using namespace ABI::Windows::System::Threading; 16 | using namespace ABI::Windows::System::Threading::Core; 17 | 18 | using namespace Microsoft::WRL; 19 | using namespace Microsoft::WRL::Wrappers; 20 | 21 | namespace MediaFoundationProvider 22 | { 23 | 24 | MediaDeviceManager::MediaDeviceManager() : 25 | _uniqueSourceID(nullptr), 26 | _friendlySourceName(nullptr), 27 | _streamIndex(static_cast(-1)), 28 | _cachedIsMirrored(false) 29 | { 30 | } 31 | 32 | MediaDeviceManager::~MediaDeviceManager() 33 | { 34 | Shutdown(); 35 | } 36 | 37 | HRESULT MediaDeviceManager::Initialize(_In_ LPCWSTR targetDeviceId) 38 | { 39 | auto lock = _threadLocker.Lock(); 40 | 41 | HRESULT hr = S_OK; 42 | if (!IsInitialized()) 43 | { 44 | hr = InitializeSourceDevice(targetDeviceId); 45 | } 46 | 47 | return hr; 48 | } 49 | 50 | HRESULT MediaDeviceManager::Shutdown() 51 | { 52 | auto lock = _threadLocker.Lock(); 53 | 54 | _sourceAttributes.Reset(); 55 | _sourceReader.Reset(); 56 | 57 | // Safe to pass in NULL pointers 58 | CoTaskMemFree(_uniqueSourceID); 59 | CoTaskMemFree(_friendlySourceName); 60 | 61 | _uniqueSourceID = nullptr; 62 | _friendlySourceName = nullptr; 63 | _streamIndex = static_cast(-1); 64 | 65 | return S_OK; 66 | } 67 | 68 | HRESULT MediaDeviceManager::ActivateStream(bool newActiveState) 69 | { 70 | auto lock = _threadLocker.Lock(); 71 | 72 | // Don't return an error if we're attempting to deactivate the stream after reader has been shutdown 73 | if (_sourceReader == nullptr && !newActiveState) 74 | { 75 | return S_OK; 76 | } 77 | else if (_sourceReader == nullptr) 78 | { 79 | return E_NOT_VALID_STATE; 80 | } 81 | 82 | return _sourceReader->SetStreamSelection(_streamIndex, newActiveState); 83 | } 84 | 85 | HRESULT MediaDeviceManager::ReadSample(ComPtr& sampleData, _Out_ bool* readerStillValid) 86 | { 87 | auto lock = _threadLocker.Lock(); 88 | 89 | sampleData.Reset(); 90 | 91 | bool readerValidLocal = false; 92 | HRESULT hr = E_NOT_VALID_STATE; 93 | 94 | if (_sourceReader != nullptr) 95 | { 96 | BOOL currActiveState; 97 | 98 | // Check if the stream is currently selected, if not don't attempt to read a frame (it'll fail) 99 | hr = _sourceReader->GetStreamSelection(_streamIndex, &currActiveState); 100 | if (SUCCEEDED(hr)) 101 | { 102 | if (currActiveState) 103 | { 104 | DWORD dummy; 105 | DWORD flags; 106 | LONGLONG timeStamp; 107 | 108 | // Call ReadSample to try and acquire the next video frame from the capture device 109 | // A failed HR usually means the capture device is no longer available, i.e. camera was unplugged, 110 | // however the call may still "succeed" but not return a valid sample, need to check both cases. 111 | hr = _sourceReader->ReadSample(_streamIndex, 0, &dummy, &flags, &timeStamp, sampleData.GetAddressOf()); 112 | if (FAILED(hr) || ((flags & MF_SOURCE_READERF_ERROR) != 0)) 113 | { 114 | readerValidLocal = false; // Reader is no longer valid; need to call ReleaseConnection 115 | } 116 | else if (sampleData == nullptr) 117 | { 118 | readerValidLocal = true; // Didn't get a sample (return failed) but reader itself is still valid 119 | hr = E_NOT_SET; 120 | } 121 | else 122 | { 123 | readerValidLocal = true; // Received a valid sample; everything is good 124 | } 125 | } 126 | else 127 | { 128 | // The stream is deselected but reader object is still valid 129 | readerValidLocal = true; 130 | hr = E_NOT_VALID_STATE; 131 | } 132 | } 133 | } 134 | 135 | if (readerStillValid != nullptr) 136 | { 137 | *readerStillValid = readerValidLocal; 138 | } 139 | return hr; 140 | } 141 | 142 | HRESULT MediaDeviceManager::RefreshStreamPropertyCache() 143 | { 144 | auto lock = _threadLocker.Lock(); 145 | 146 | if (_sourceReader == nullptr) return E_NOT_VALID_STATE; 147 | 148 | // Update the "mirrored" state of the video stream 149 | bool isMirrored = false; 150 | HRESULT hr = QueryIsMirroredState(&isMirrored); 151 | 152 | _cachedIsMirrored = SUCCEEDED(hr) ? isMirrored : false; 153 | 154 | return S_OK; 155 | } 156 | 157 | HRESULT MediaDeviceManager::InitializeSourceDevice(_In_ LPCWSTR targetDeviceId) 158 | { 159 | ComPtr enumAttributes; 160 | ComPtr sourceActivation; 161 | ComPtr sourceReader; 162 | DWORD streamIndex = static_cast(-1); 163 | 164 | // Create an attribute store to specify the enumeration parameters 165 | // Specify "VIDCAP" devices as the major type to enumerate 166 | HRESULT hr = MFCreateAttributes(enumAttributes.GetAddressOf(), 1); 167 | if (SUCCEEDED(hr)) 168 | { 169 | hr = enumAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); 170 | 171 | // 172 | // TODO: If appropriate, restrict enumeration to KSCATEGORY_SENSOR_CAMERA devices (set SampleFrameProvider::_requiredKsSensorDevice in FrameProvider.h) 173 | // This will eliminate any device that does not have the attribute set from our enumeration 174 | // 175 | if (SUCCEEDED(hr) && SampleFrameProvider::_requiredKsSensorDevice) 176 | { 177 | hr = enumAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY, KSCATEGORY_SENSOR_CAMERA); 178 | } 179 | } 180 | 181 | // Use the enumAttributes to find a compatible device on the system; receive a MediaSource activator 182 | if (SUCCEEDED(hr)) 183 | { 184 | hr = EnumMediaCaptureDevices(targetDeviceId, enumAttributes, sourceActivation); 185 | } 186 | 187 | // Use the returned activator to create a MediaSourceReader object and identify the stream index we'll read frames 188 | if (SUCCEEDED(hr)) 189 | { 190 | hr = InitializeMediaSourceReader(sourceActivation, sourceReader, &streamIndex); 191 | } 192 | 193 | // Acquire an ID and Friendly Name strings from the Activation attributes 194 | if (SUCCEEDED(hr)) 195 | { 196 | hr = AcquireIdentificationStrings(sourceActivation); 197 | } 198 | 199 | // If all went well, save the key object references and tag the class as Initialized 200 | if (SUCCEEDED(hr)) 201 | { 202 | _sourceReader = sourceReader; 203 | _streamIndex = streamIndex; 204 | } 205 | 206 | // Read device properties and save them to cached values 207 | if (SUCCEEDED(hr)) 208 | { 209 | RefreshStreamPropertyCache(); 210 | } 211 | 212 | return hr; 213 | } 214 | 215 | HRESULT MediaDeviceManager::AcquireIdentificationStrings(_In_ const ComPtr& sourceActivation) 216 | { 217 | LPWSTR sourceID = nullptr; 218 | LPWSTR friendlyName = nullptr; 219 | UINT32 stringLength; 220 | 221 | HRESULT hr = sourceActivation->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &sourceID, &stringLength); 222 | if (SUCCEEDED(hr)) 223 | { 224 | hr = sourceActivation->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &friendlyName, &stringLength); 225 | } 226 | 227 | if (SUCCEEDED(hr)) 228 | { 229 | _uniqueSourceID = sourceID; 230 | _friendlySourceName = friendlyName; 231 | } 232 | else 233 | { 234 | // Safe to pass in NULL pointers 235 | CoTaskMemFree(sourceID); 236 | CoTaskMemFree(friendlyName); 237 | } 238 | 239 | return hr; 240 | } 241 | 242 | HRESULT MediaDeviceManager::EnumMediaCaptureDevices(_In_ LPCWSTR targetDeviceId, _In_ const ComPtr& enumAtributes, _Out_ ComPtr& mediaSourceActivate) 243 | { 244 | IMFActivate **ppDevices = NULL; 245 | UINT32 deviceCount; 246 | 247 | // Enumerate devices; FAIL if we're unable to find any devices 248 | // NOTE: We must still release each IMFActivate object and free the memory for the array 249 | HRESULT hr = MFEnumDeviceSources(enumAtributes.Get(), &ppDevices, &deviceCount); 250 | if (SUCCEEDED(hr) && deviceCount == 0) 251 | { 252 | hr = E_NOT_SET; 253 | } 254 | 255 | // Select the media source that matches the passed in targetDeviceId 256 | if (SUCCEEDED(hr)) 257 | { 258 | bool foundDevice = false; 259 | for (UINT32 i = 0; i < deviceCount && !foundDevice; i++) 260 | { 261 | ComPtr currDevice = ppDevices[i]; 262 | LPWSTR sourceID = nullptr; 263 | UINT32 stringLength; 264 | 265 | // The "symbolic link" is actually the unique device interface ID 266 | if (SUCCEEDED(currDevice->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &sourceID, &stringLength))) 267 | { 268 | // Compare the current source ID string against our target device 269 | // If it matches we'll return it's Activation object 270 | if (_wcsnicmp(targetDeviceId, sourceID, stringLength) == 0) 271 | { 272 | mediaSourceActivate = ppDevices[i]; 273 | foundDevice = true; 274 | } 275 | CoTaskMemFree(sourceID); 276 | } 277 | } 278 | 279 | // If a device matching targetDeviceId wasn't found then fail 280 | if (!foundDevice) 281 | { 282 | hr = E_NOT_SET; 283 | } 284 | } 285 | 286 | // Each device object returned and the containing array must be released 287 | for (UINT32 i = 0; i < deviceCount; i++) 288 | { 289 | ppDevices[i]->Release(); 290 | } 291 | CoTaskMemFree(ppDevices); 292 | 293 | if (FAILED(hr)) 294 | { 295 | mediaSourceActivate.Reset(); 296 | } 297 | return hr; 298 | } 299 | 300 | HRESULT MediaDeviceManager::InitializeMediaSourceReader(_In_ const ComPtr& mediaSourceActivate, _Out_ ComPtr& sourceReader, _Out_ DWORD* streamIndex) 301 | { 302 | // Create a MediaSource object from the passed in Activator 303 | ComPtr mediaSource; 304 | HRESULT hr = mediaSourceActivate->ActivateObject(IID_PPV_ARGS(mediaSource.GetAddressOf())); 305 | 306 | // Create a MediaSourceReader object from the activated MediaSource 307 | if (SUCCEEDED(hr)) 308 | { 309 | ComPtr readerAttributes; 310 | 311 | hr = MFCreateAttributes(readerAttributes.GetAddressOf(), 1); 312 | if (SUCCEEDED(hr)) 313 | { 314 | hr = readerAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE); 315 | } 316 | if (SUCCEEDED(hr)) 317 | { 318 | hr = MFCreateSourceReaderFromMediaSource(mediaSource.Get(), readerAttributes.Get(), sourceReader.GetAddressOf()); 319 | } 320 | } 321 | 322 | // Examine the media types available from the reader and select one that best matches our needs (if any) 323 | // Set the choosen MediaType and Stream index to the reader object 324 | if (SUCCEEDED(hr)) 325 | { 326 | ComPtr chosenProfile; 327 | hr = FindCompatibleMediaProfile(sourceReader, chosenProfile.GetAddressOf(), streamIndex); 328 | 329 | if (SUCCEEDED(hr)) 330 | { 331 | hr = sourceReader->SetCurrentMediaType(*streamIndex, NULL, chosenProfile.Get()); 332 | } 333 | if (SUCCEEDED(hr)) 334 | { 335 | // Make sure stream is not selected at this point, it'll be enabled when Start is called by the service 336 | hr = sourceReader->SetStreamSelection(*streamIndex, FALSE); 337 | } 338 | if (SUCCEEDED(hr)) 339 | { 340 | _sourceAttributes = chosenProfile; 341 | } 342 | } 343 | 344 | if (FAILED(hr)) 345 | { 346 | sourceReader.Reset(); 347 | *streamIndex = static_cast(-1); 348 | } 349 | 350 | return hr; 351 | } 352 | 353 | HRESULT MediaDeviceManager::FindCompatibleMediaProfile(_In_ const ComPtr& sourceReader, _Outptr_ IMFMediaType** chosenType, _Out_ DWORD* chosenStreamIndex) 354 | { 355 | std::vector> mediaCandidates; 356 | HRESULT hr; 357 | 358 | *chosenStreamIndex = static_cast(-1); 359 | 360 | for (UINT32 streamIndex = 0;; streamIndex++) 361 | { 362 | for (UINT32 typeIndex = 0;; typeIndex++) 363 | { 364 | ComPtr mediaType; 365 | 366 | hr = sourceReader->GetNativeMediaType(streamIndex, typeIndex, mediaType.ReleaseAndGetAddressOf()); 367 | if (SUCCEEDED(hr)) 368 | { 369 | // Check the sample meets our minimum requirements and if 370 | // it passes, add it to the list of types we'll consider 371 | if (IsMediaProfileValid(mediaType)) 372 | { 373 | mediaCandidates.push_back(mediaType); 374 | } 375 | } 376 | else if (hr == MF_E_NO_MORE_TYPES || hr == MF_E_INVALIDSTREAMNUMBER) break; 377 | } 378 | 379 | // If we've found at least 1 valid media type from this stream we don't need to continue enumerating media types 380 | // Otherwise if no valid media types were found, continue to the next stream (if any more) 381 | if (!mediaCandidates.empty()) 382 | { 383 | *chosenStreamIndex = streamIndex; 384 | break; 385 | } 386 | else if (hr == MF_E_INVALIDSTREAMNUMBER) break; 387 | } 388 | 389 | // Simply select the first valid device 390 | if (!mediaCandidates.empty()) 391 | { 392 | *chosenType = mediaCandidates[0].Get(); 393 | (*chosenType)->AddRef(); 394 | hr = S_OK; 395 | } 396 | else 397 | { 398 | hr = E_NOT_SET; 399 | } 400 | 401 | return hr; 402 | } 403 | 404 | HRESULT MediaDeviceManager::QueryIsMirroredState(_Out_ bool* isMirrored) 405 | { 406 | if (isMirrored == nullptr) 407 | { 408 | return E_INVALIDARG; 409 | } 410 | 411 | *isMirrored = false; 412 | 413 | ComPtr mediaSource; 414 | ComPtr ksControl; 415 | HRESULT hr = _sourceReader->GetServiceForStream(static_cast(MF_SOURCE_READER_MEDIASOURCE), GUID_NULL, IID_PPV_ARGS(&mediaSource)); 416 | if (SUCCEEDED(hr)) 417 | { 418 | hr = mediaSource.As(&ksControl); 419 | } 420 | 421 | // First check if device supports this property 422 | if (SUCCEEDED(hr)) 423 | { 424 | KSPROPERTY_VIDEOCONTROL_CAPS_S capsQ = { 0 }; 425 | KSPROPERTY_VIDEOCONTROL_CAPS_S capsR = { 0 }; 426 | 427 | capsQ.Property.Set = PROPSETID_VIDCAP_VIDEOCONTROL; 428 | capsQ.Property.Id = KSPROPERTY_VIDEOCONTROL_CAPS; 429 | capsQ.Property.Flags = KSPROPERTY_TYPE_GET; 430 | capsQ.StreamIndex = _streamIndex; 431 | 432 | ULONG bytesReturned = 0; 433 | hr = ksControl->KsProperty((PKSPROPERTY)&capsQ, sizeof(capsQ), &capsR, sizeof(capsR), &bytesReturned); 434 | if (SUCCEEDED(hr)) 435 | { 436 | // Fail if mirroring isn't supported on this device 437 | if ((capsR.VideoControlCaps & KS_VideoControlFlag_FlipHorizontal) == 0) 438 | { 439 | hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); 440 | } 441 | } 442 | } 443 | 444 | // Query the current mirroring state from the device 445 | if (SUCCEEDED(hr)) 446 | { 447 | KSPROPERTY_VIDEOCONTROL_MODE_S mode = { 0 }; 448 | 449 | mode.Property.Set = PROPSETID_VIDCAP_VIDEOCONTROL; 450 | mode.Property.Id = KSPROPERTY_VIDEOCONTROL_MODE; 451 | mode.Property.Flags = KSPROPERTY_TYPE_GET; 452 | mode.StreamIndex = _streamIndex; 453 | mode.Mode = 0; 454 | 455 | ULONG bytesReturned = 0; 456 | hr = ksControl->KsProperty((PKSPROPERTY)&mode, sizeof(mode), &mode, sizeof(mode), &bytesReturned); 457 | if (SUCCEEDED(hr)) 458 | { 459 | *isMirrored = (mode.Mode & KS_VideoControlFlag_FlipHorizontal) != 0; 460 | } 461 | } 462 | 463 | return hr; 464 | } 465 | 466 | bool MediaDeviceManager::IsMediaProfileValid(_In_ const ComPtr& workingProfile) 467 | { 468 | GUID guidType; 469 | UINT32 uintType; 470 | 471 | // Verify media is VIDEO 472 | HRESULT hr = workingProfile->GetGUID(MF_MT_MAJOR_TYPE, &guidType); 473 | if (SUCCEEDED(hr)) 474 | { 475 | if (!IsEqualGUID(guidType, MFMediaType_Video)) { hr = E_FAIL; } 476 | } 477 | 478 | // Must natively supporty YUY2 video format 479 | if (SUCCEEDED(hr)) 480 | { 481 | hr = workingProfile->GetGUID(MF_MT_SUBTYPE, &guidType); 482 | if (SUCCEEDED(hr)) 483 | { 484 | if (!IsEqualGUID(MFVideoFormat_YUY2, guidType)) { hr = E_FAIL; } 485 | } 486 | } 487 | 488 | // Sample sizes must be fixed 489 | if (SUCCEEDED(hr)) 490 | { 491 | hr = workingProfile->GetUINT32(MF_MT_FIXED_SIZE_SAMPLES, &uintType); 492 | if (SUCCEEDED(hr)) 493 | { 494 | if (!uintType) { hr = E_FAIL; } 495 | } 496 | } 497 | 498 | // Video frames cannot be interlaced 499 | if (SUCCEEDED(hr)) 500 | { 501 | hr = workingProfile->GetUINT32(MF_MT_INTERLACE_MODE, &uintType); 502 | if (SUCCEEDED(hr)) 503 | { 504 | if (uintType != MFVideoInterlace_Progressive) { hr = E_FAIL; } 505 | } 506 | } 507 | 508 | // Use the !! trick to safely convert the int value returned by SUCCEEDED macro to a bool value 509 | return !!SUCCEEDED(hr); 510 | } 511 | 512 | } // end namespace 513 | -------------------------------------------------------------------------------- /FrameProviderSample/MediaDeviceManager.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | namespace MediaFoundationProvider 15 | { 16 | 17 | class MediaDeviceManager 18 | { 19 | public: 20 | 21 | MediaDeviceManager(); 22 | virtual ~MediaDeviceManager(); 23 | 24 | WRL::ComPtr GetSourceAttributes() { _threadLocker.Lock(); return _sourceAttributes; } 25 | LPWSTR GetUniqueSourceID() { _threadLocker.Lock(); return _uniqueSourceID; } 26 | LPWSTR GetFriendSourceName() { _threadLocker.Lock(); return _friendlySourceName; } 27 | bool IsInitialized() { _threadLocker.Lock(); return _sourceReader != nullptr; } 28 | bool IsMirrored() { _threadLocker.Lock(); return _cachedIsMirrored; } 29 | 30 | HRESULT Initialize(_In_ LPCWSTR targetDeviceId); 31 | HRESULT Shutdown(); 32 | HRESULT ActivateStream(bool newActiveState); 33 | HRESULT ReadSample(WRL::ComPtr& sampleData, _Out_ bool* readerStillValid); 34 | HRESULT RefreshStreamPropertyCache(); 35 | 36 | private: 37 | 38 | HRESULT InitializeSourceDevice(_In_ LPCWSTR targetDeviceId); 39 | HRESULT EnumMediaCaptureDevices(_In_ LPCWSTR targetDeviceId, _In_ const WRL::ComPtr& enumAtributes, _Out_ WRL::ComPtr& mediaSourceActivate); 40 | HRESULT InitializeMediaSourceReader(_In_ const WRL::ComPtr& mediaSourceActivate, _Out_ WRL::ComPtr& sourceReader, _Out_ DWORD* streamIndex); 41 | HRESULT FindCompatibleMediaProfile(_In_ const WRL::ComPtr& sourceReader, _Outptr_ IMFMediaType** chosenType, _Out_ DWORD* chosesStreamIndex); 42 | HRESULT AcquireIdentificationStrings(_In_ const WRL::ComPtr& sourceActivation); 43 | HRESULT QueryIsMirroredState(_Out_ bool* isMirrored); 44 | bool IsMediaProfileValid(_In_ const WRL::ComPtr& workingProfile); 45 | 46 | WRL::ComPtr _sourceReader; 47 | WRL::ComPtr _sourceAttributes; 48 | 49 | WRLW::CriticalSection _threadLocker; 50 | LPWSTR _uniqueSourceID; 51 | LPWSTR _friendlySourceName; 52 | DWORD _streamIndex; 53 | bool _cachedIsMirrored; 54 | }; 55 | 56 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/MediaFoundationWrapper.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "pch.h" 13 | #include "MediaFoundationWrapper.h" 14 | 15 | using namespace ABI::Windows::Foundation; 16 | using namespace ABI::Windows::System::Threading; 17 | using namespace ABI::Windows::System::Threading::Core; 18 | 19 | using namespace Microsoft::WRL; 20 | using namespace Microsoft::WRL::Wrappers; 21 | 22 | namespace MediaFoundationProvider { 23 | 24 | MediaFoundationWrapper::MediaFoundationWrapper() : 25 | _readFrameFinished(NULL), 26 | _stopReadingFrames(NULL), 27 | _currentFrameResult(0), 28 | _running(false) 29 | { 30 | RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); 31 | MFStartup(MF_VERSION, MFSTARTUP_NOSOCKET); 32 | 33 | _stopReadingFrames = CreateEvent(NULL, TRUE, FALSE, L"MediaWrapper_StopReadingFrames"); 34 | _readFrameFinished = CreateEvent(NULL, FALSE, FALSE, L"MediaWrapper_ReadFrameFinished"); 35 | } 36 | 37 | MediaFoundationWrapper::~MediaFoundationWrapper() 38 | { 39 | Shutdown(); 40 | 41 | CloseHandle(_readFrameFinished); 42 | CloseHandle(_stopReadingFrames); 43 | 44 | MFShutdown(); 45 | RoUninitialize(); 46 | } 47 | 48 | HRESULT MediaFoundationWrapper::Initialize(_In_ LPCWSTR targetDeviceId) 49 | { 50 | HRESULT hr; 51 | 52 | if (IsInitialized()) return E_ABORT; 53 | 54 | // Attempt to connect to our source device and initialize the frame reader. 55 | hr = _deviceManager.Initialize(targetDeviceId); 56 | if (SUCCEEDED(hr)) 57 | { 58 | hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), &_threadPool); 59 | } 60 | 61 | return hr; 62 | } 63 | 64 | HRESULT MediaFoundationWrapper::Shutdown() 65 | { 66 | // We must wait for ReadFrameProc to complete before shutting down MediaFoundation, etc. or bad stuff may happen 67 | // ReadFrameProc should exit within 1 frame (typically 33 ms) or less 68 | Stop(true); 69 | 70 | _deviceManager.Shutdown(); 71 | _threadPool.Reset(); 72 | return S_OK; 73 | } 74 | 75 | HRESULT MediaFoundationWrapper::Start() 76 | { 77 | HRESULT hr; 78 | 79 | if (!IsInitialized()) return E_ABORT; 80 | if (_running) return E_ACCESSDENIED; 81 | 82 | // Check if we're still in the "stopping" state: _stopReadingFrames is signaled 83 | // Must wait for prior session to exit before starting a new one 84 | if (WaitForSingleObject(_stopReadingFrames, 0) == WAIT_OBJECT_0) 85 | { 86 | return E_ACCESSDENIED; 87 | } 88 | 89 | hr = CreateReadFrameAsyncTask(); 90 | if (SUCCEEDED(hr)) 91 | { 92 | hr = _deviceManager.ActivateStream(true); 93 | if (SUCCEEDED(hr)) 94 | { 95 | _running = true; 96 | } 97 | 98 | // Update cached values of device properties 99 | if (SUCCEEDED(hr)) 100 | { 101 | _deviceManager.RefreshStreamPropertyCache(); 102 | } 103 | } 104 | return hr; 105 | } 106 | 107 | HRESULT MediaFoundationWrapper::Stop(bool waitForStop) 108 | { 109 | if (!IsInitialized()) return E_ABORT; 110 | if (!_running) return E_ACCESSDENIED; 111 | 112 | // Signal ReadFrameProc to stop running, i.e. exit immediately and don't spawn a new task 113 | if (!SetEvent(_stopReadingFrames)) 114 | { 115 | return E_UNEXPECTED; 116 | } 117 | 118 | // Deactivating the stream in MediaFoundation is what actually stops the session 119 | HRESULT hr = _deviceManager.ActivateStream(false); 120 | if (FAILED(hr)) 121 | { 122 | return hr; 123 | } 124 | 125 | _running = false; 126 | 127 | // Block according to waitForStop parameter to wait a short time for current task to exit 128 | // If we don't wait, ReadFrameProc may continue running for a short time after Stop returns 129 | // NOTE: Start will FAIL if called before current task completes 130 | WaitForSingleObject(_readFrameFinished, waitForStop ? 100 : 0); 131 | 132 | // Reset internal Running state and clear out current Frame Data 133 | { 134 | auto lock = _readFrameLock.Lock(); 135 | 136 | _currentFrameResult = 0; 137 | _currentFrame.Reset(); 138 | } 139 | 140 | return S_OK; 141 | } 142 | 143 | HRESULT MediaFoundationWrapper::SubscribeReadFrame(const ComPtr& readFrameCallback, EventRegistrationToken* pEventToken) 144 | { 145 | if (!IsInitialized()) return E_ABORT; 146 | if (_running) return E_ACCESSDENIED; 147 | 148 | if (readFrameCallback == nullptr) return E_INVALIDARG; 149 | if (pEventToken == nullptr) return E_POINTER; 150 | 151 | return _readFrameEvents.Add(readFrameCallback.Get(), pEventToken); 152 | } 153 | 154 | HRESULT MediaFoundationWrapper::SubscribeAvailableChanged(const ComPtr& availableChangedCallback, EventRegistrationToken* pEventToken) 155 | { 156 | if (!IsInitialized()) return E_ABORT; 157 | if (_running) return E_ACCESSDENIED; 158 | 159 | if (availableChangedCallback == nullptr) return E_INVALIDARG; 160 | if (pEventToken == nullptr) return E_POINTER; 161 | 162 | return _availableChangedEvents.Add(availableChangedCallback.Get(), pEventToken); 163 | } 164 | 165 | HRESULT MediaFoundationWrapper::UnsubscribeReadFrame(EventRegistrationToken eventToken) 166 | { 167 | if (!IsInitialized()) return E_ABORT; 168 | if (_running) return E_ACCESSDENIED; 169 | 170 | return _readFrameEvents.Remove(eventToken); 171 | } 172 | 173 | HRESULT MediaFoundationWrapper::UnsubscribeAvailableChanged(EventRegistrationToken eventToken) 174 | { 175 | if (!IsInitialized()) return E_ABORT; 176 | if (_running) return E_ACCESSDENIED; 177 | 178 | return _availableChangedEvents.Remove(eventToken); 179 | } 180 | 181 | HRESULT MediaFoundationWrapper::CreateReadFrameAsyncTask() 182 | { 183 | HRESULT hr; 184 | 185 | // Since we're about to start a new ReadFrame task, ensure _readFrameFinished event is not signaled 186 | // NOTE: We don't keep the reference to IAsyncAction since only one task runs at a time and running 187 | // status and errors are communicated through member variables. 188 | ResetEvent(_readFrameFinished); 189 | 190 | ComPtr asyncAction; 191 | hr = _threadPool->RunAsync(Callback([this](IAsyncAction* asyncAction) -> HRESULT 192 | { 193 | UNREFERENCED_PARAMETER(asyncAction); 194 | 195 | this->ReadFrameProc(); 196 | return S_OK; 197 | }).Get(), &asyncAction); 198 | 199 | return hr; 200 | } 201 | 202 | void MediaFoundationWrapper::ReadFrameProc() 203 | { 204 | bool availablityChanged = false; 205 | HRESULT hr = S_OK; 206 | 207 | // At each stage of the task, check that _stopReadingFrames is not signalled 208 | // Otherwise, exit the proc as quickly as possible 209 | if (CheckIfKeepRunning()) 210 | { 211 | auto lock = _readFrameLock.Lock(); 212 | 213 | // If the device is connected, attempt to read the next frame from the device 214 | // If this fails, we'll assume device is no longer available and signal this to ISourceProvider. 215 | ComPtr sampleData; 216 | bool readerStillValid; 217 | 218 | if (_deviceManager.IsInitialized()) 219 | { 220 | hr = _deviceManager.ReadSample(sampleData, &readerStillValid); 221 | if (!readerStillValid) 222 | { 223 | _deviceManager.Shutdown(); // Device objects are no longer valid so get rid of them 224 | availablityChanged = true; 225 | } 226 | } 227 | else hr = E_NOT_SET; 228 | 229 | // Don't update current results if we've been signaled to exit; Stop() will reset the values 230 | if (CheckIfKeepRunning()) 231 | { 232 | // If ReadFrame succeeded and produce a valid sample save it to current results 233 | // Else if we failed because availabity changed clear frame data (it's invalid) but save HR 234 | // Otherwise do nothing 235 | if (SUCCEEDED(hr)) 236 | { 237 | _currentFrame = sampleData; 238 | _currentFrameResult = hr; 239 | } 240 | else if (availablityChanged) 241 | { 242 | _currentFrame.Reset(); 243 | _currentFrameResult = hr; 244 | } 245 | } 246 | } // Leave CriticalSection 247 | 248 | // If availablity of the sensor has changed, call event handlers 249 | if (CheckIfKeepRunning()) 250 | { 251 | if (availablityChanged) 252 | { 253 | if (FAILED(_availableChangedEvents.InvokeAll(nullptr))) 254 | { 255 | // This doesn't impact ReadFrame functionality so we can ignore failures 256 | } 257 | } 258 | } 259 | 260 | // If succesfully acquired new frame data, call event handlers 261 | if (CheckIfKeepRunning()) 262 | { 263 | if (SUCCEEDED(hr)) 264 | { 265 | if (FAILED(_readFrameEvents.InvokeAll(nullptr))) 266 | { 267 | // This doesn't impact ReadFrame functionality so we can ignore failures 268 | } 269 | } 270 | } 271 | 272 | // If we're still running, queue up another ReadFrameProc task 273 | // NOTE: Once we've committed to spawning a new task don't check the event again 274 | bool commitedToKeepRunning = CheckIfKeepRunning(); 275 | if (commitedToKeepRunning) 276 | { 277 | CreateReadFrameAsyncTask(); 278 | } 279 | 280 | // If we've been signaled to Stop, set _stopReadingFrames indicating we're exiting the 281 | // ReadFrame proc and Manually reset _stopReadingFrames 282 | // 283 | // NOTE: Reset _stopReadingFrames event BEFORE signaling _readFrameFinished, this should 284 | // prevent a possible race condition where immediately calling Start() after Stop() fails 285 | // because the _stopReadingFrames was still signaled 286 | if (!commitedToKeepRunning) 287 | { 288 | ResetEvent(_stopReadingFrames); 289 | SetEvent(_readFrameFinished); 290 | } 291 | } 292 | 293 | inline bool MediaFoundationWrapper::CheckIfKeepRunning() 294 | { 295 | return WaitForSingleObject(_stopReadingFrames, 0) != WAIT_OBJECT_0; 296 | } 297 | 298 | bool MediaFoundationWrapper::CheckIfAvailable() 299 | { 300 | bool currentlyAvailable = _deviceManager.IsInitialized(); 301 | 302 | // We must poll IMFSourceReader to see if the source device is still connected, 303 | // basically if ReadSample succeeds we're good but otherwise the device isn't available. 304 | // If we're "Running" (reading frames) we simply return the connection status of the device, 305 | // otherwise we have to try and read a frame to make sure the device is still available. 306 | if (!_running) 307 | { 308 | if (currentlyAvailable) 309 | { 310 | ComPtr dummyData; 311 | bool availablityChanged = false; 312 | 313 | _deviceManager.ReadSample(dummyData, ¤tlyAvailable); 314 | if (!currentlyAvailable) 315 | { 316 | _deviceManager.Shutdown(); // Device objects are no longer valid so get rid of them 317 | availablityChanged = true; 318 | } 319 | 320 | if (availablityChanged) 321 | { 322 | if (FAILED(_availableChangedEvents.InvokeAll(nullptr))) 323 | { 324 | // This doesn't impact function so we can ignore failures 325 | } 326 | } 327 | } 328 | } 329 | 330 | return currentlyAvailable; 331 | } 332 | 333 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/MediaFoundationWrapper.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | class MediaFoundationWrapper 17 | { 18 | public: 19 | 20 | MediaFoundationWrapper(); 21 | virtual ~MediaFoundationWrapper(); 22 | 23 | HRESULT Initialize(_In_ LPCWSTR targetDeviceId); 24 | HRESULT Shutdown(); 25 | HRESULT Start(); 26 | HRESULT Stop(bool waitForStop); 27 | 28 | HRESULT SubscribeReadFrame(const WRL::ComPtr& readFrameCallback, EventRegistrationToken* pEventToken); 29 | HRESULT SubscribeAvailableChanged(const WRL::ComPtr& availableChangedCallback, EventRegistrationToken* pEventToken); 30 | HRESULT UnsubscribeReadFrame(EventRegistrationToken eventToken); 31 | HRESULT UnsubscribeAvailableChanged(EventRegistrationToken eventToken); 32 | 33 | WRL::ComPtr GetSourceAttributes() { return _deviceManager.GetSourceAttributes(); } 34 | WRL::ComPtr GetCurrentFrame() { _readFrameLock.Lock(); { return _currentFrame; } } 35 | HRESULT GetCurrentFrameResult() { _readFrameLock.Lock(); { return _currentFrameResult; } } 36 | LPWSTR GetUniqueSourceID() { return _deviceManager.GetUniqueSourceID(); } 37 | LPWSTR GetFriendSourceName() { return _deviceManager.GetFriendSourceName(); } 38 | bool IsInitialized() { return _threadPool != nullptr; } 39 | bool IsRunning() { return _running; } 40 | bool IsAvailable() { return CheckIfAvailable(); } 41 | bool IsMirrored() { return _deviceManager.IsMirrored(); } 42 | 43 | private: 44 | 45 | HRESULT CreateReadFrameAsyncTask(); 46 | void ReadFrameProc(); 47 | inline bool CheckIfKeepRunning(); 48 | bool CheckIfAvailable(); 49 | 50 | MediaDeviceManager _deviceManager; 51 | 52 | WRL::ComPtr _threadPool; 53 | WRL::ComPtr _currentFrame; 54 | 55 | WRL::EventSource _readFrameEvents; 56 | WRL::EventSource _availableChangedEvents; 57 | 58 | HANDLE _readFrameFinished; 59 | HANDLE _stopReadingFrames; 60 | WRLW::CriticalSection _readFrameLock; 61 | 62 | HRESULT _currentFrameResult; 63 | bool _running; 64 | }; 65 | 66 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/MemoryBufferAccess.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | #include "pch.h" 15 | 16 | // 17 | // 18 | // Helper class to retrieve byte* and capacity from an IMemoryBuffer 19 | // The class guarantees the validity of the byte* for entire object lifetime. 20 | // 21 | // ex: 22 | // MemoryBufferByteAccess byteAccess; 23 | // unsigned char *pData = nullptr; 24 | // unsigned int capacity; 25 | // HRESULT hr = byteAccess.GetBuffer(spBuffer.Get(), &pData, &capacity); 26 | // 27 | class MemoryBufferByteAccess 28 | { 29 | public: 30 | 31 | HRESULT GetBuffer(_In_ IInspectable *pBuffer, _Outptr_result_bytebuffer_(*pCapacity) BYTE **ppData, _Out_ UINT32 *pCapacity) 32 | { 33 | #ifdef ____x_Windows_CFoundation_CIMemoryBuffer_FWD_DEFINED__ 34 | Microsoft::WRL::ComPtr spMemoryBuffer; 35 | Microsoft::WRL::ComPtr spBufferReference; 36 | #else 37 | Microsoft::WRL::ComPtr spMemoryBuffer; 38 | Microsoft::WRL::ComPtr spBufferReference; 39 | #endif 40 | 41 | *ppData = nullptr; 42 | *pCapacity = 0; 43 | 44 | HRESULT hr = pBuffer->QueryInterface(IID_PPV_ARGS(&spMemoryBuffer)); 45 | 46 | if (SUCCEEDED(hr)) 47 | { 48 | hr = spMemoryBuffer->CreateReference(&spBufferReference); 49 | } 50 | 51 | if (SUCCEEDED(hr)) 52 | { 53 | hr = spBufferReference.As(&m_spByteAccess); 54 | } 55 | 56 | if (SUCCEEDED(hr)) 57 | { 58 | hr = m_spByteAccess->GetBuffer(ppData, pCapacity); 59 | } 60 | 61 | return hr; 62 | } 63 | 64 | private: 65 | 66 | Microsoft::WRL::ComPtr m_spByteAccess; 67 | }; 68 | -------------------------------------------------------------------------------- /FrameProviderSample/Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/FrameProviderSample/Readme.txt -------------------------------------------------------------------------------- /FrameProviderSample/VideoSourceDescription.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "pch.h" 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | VideoSourceDescription::VideoSourceDescription( 17 | Windows::Graphics::Imaging::BitmapPixelFormat format, 18 | Windows::Graphics::Imaging::BitmapAlphaMode alpha, 19 | int width, 20 | int height, 21 | double pixelAspectRatio, 22 | Windows::Foundation::TimeSpan frameDuration) : 23 | _bitmapPixelFormat(format), 24 | _bitmapAlphaMode(alpha), 25 | _pixelWidth(width), 26 | _pixelHeight(height), 27 | _pixelAspectRatio(pixelAspectRatio), 28 | _frameDuration(frameDuration) 29 | { 30 | } 31 | 32 | VideoSourceDescription::VideoSourceDescription(Windows::Foundation::Collections::IPropertySet^ propertySet) : 33 | _bitmapPixelFormat(), 34 | _bitmapAlphaMode(), 35 | _pixelWidth(), 36 | _pixelHeight(), 37 | _pixelAspectRatio(), 38 | _frameDuration() 39 | { 40 | if (propertySet == nullptr) 41 | { 42 | throw ref new Platform::NullReferenceException("VideoSourceDescription ctor requires a valid IPropertySet parameter"); 43 | } 44 | 45 | Platform::Object^ returnValue; 46 | 47 | returnValue = propertySet->Lookup(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::BitmapPixelFormat); 48 | _bitmapPixelFormat = (Windows::Graphics::Imaging::BitmapPixelFormat)safe_cast(returnValue); 49 | 50 | returnValue = propertySet->Lookup(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::BitmapAlphaMode); 51 | _bitmapAlphaMode = (Windows::Graphics::Imaging::BitmapAlphaMode)safe_cast(returnValue); 52 | 53 | returnValue = propertySet->Lookup(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::Width); 54 | _pixelWidth = safe_cast(returnValue); 55 | 56 | returnValue = propertySet->Lookup(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::Height); 57 | _pixelHeight = safe_cast(returnValue); 58 | 59 | returnValue = propertySet->Lookup(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::FrameDuration); 60 | _frameDuration = safe_cast(returnValue); 61 | } 62 | 63 | Windows::Graphics::Imaging::BitmapPixelFormat VideoSourceDescription::BitmapPixelFormat::get() 64 | { 65 | return _bitmapPixelFormat; 66 | } 67 | 68 | Windows::Graphics::Imaging::BitmapAlphaMode VideoSourceDescription::BitmapAlphaMode::get() 69 | { 70 | return _bitmapAlphaMode; 71 | } 72 | 73 | int VideoSourceDescription::PixelWidth::get() 74 | { 75 | return _pixelWidth; 76 | } 77 | 78 | int VideoSourceDescription::PixelHeight::get() 79 | { 80 | return _pixelHeight; 81 | } 82 | 83 | Windows::Foundation::Size VideoSourceDescription::PixelSize::get() 84 | { 85 | return Windows::Foundation::Size(static_cast(_pixelWidth), static_cast(_pixelHeight)); 86 | } 87 | 88 | double VideoSourceDescription::PixelAspectRatio::get() 89 | { 90 | return _pixelAspectRatio; 91 | } 92 | 93 | Windows::Foundation::TimeSpan VideoSourceDescription::FrameDuration::get() 94 | { 95 | return _frameDuration; 96 | } 97 | 98 | 99 | Windows::Foundation::Collections::IPropertySet^ VideoSourceDescription::AsPropertySet() 100 | { 101 | Windows::Foundation::Collections::PropertySet^ propSet = ref new Windows::Foundation::Collections::PropertySet(); 102 | 103 | propSet->Insert(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::BitmapPixelFormat, (UINT32)_bitmapPixelFormat); 104 | propSet->Insert(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::BitmapAlphaMode, (UINT32)_bitmapAlphaMode); 105 | propSet->Insert(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::Width, _pixelWidth); 106 | propSet->Insert(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::Height, _pixelHeight); 107 | propSet->Insert(Windows::Devices::Perception::KnownPerceptionVideoProfileProperties::FrameDuration, _frameDuration); 108 | 109 | return propSet; 110 | } 111 | 112 | bool VideoSourceDescription::IsEqual(VideoSourceDescription^ videoDescription) 113 | { 114 | return (videoDescription != nullptr) && 115 | (_bitmapPixelFormat == videoDescription->BitmapPixelFormat) && 116 | (_bitmapAlphaMode == videoDescription->BitmapAlphaMode) && 117 | (_pixelWidth == videoDescription->_pixelWidth) && 118 | (_pixelHeight == videoDescription->_pixelHeight) && 119 | (_pixelAspectRatio == videoDescription->PixelAspectRatio) && 120 | (_frameDuration.Duration == videoDescription->FrameDuration.Duration); 121 | } 122 | 123 | } // end namespace -------------------------------------------------------------------------------- /FrameProviderSample/VideoSourceDescription.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | namespace MediaFoundationProvider { 15 | 16 | ref class VideoSourceDescription sealed : Platform::Object 17 | { 18 | public: 19 | 20 | VideoSourceDescription( 21 | Windows::Graphics::Imaging::BitmapPixelFormat format, 22 | Windows::Graphics::Imaging::BitmapAlphaMode alpha, 23 | int width, 24 | int height, 25 | double pixelAspectRatio, 26 | Windows::Foundation::TimeSpan frameDuration); 27 | 28 | VideoSourceDescription(Windows::Foundation::Collections::IPropertySet^ propertySet); 29 | 30 | property Windows::Graphics::Imaging::BitmapPixelFormat BitmapPixelFormat { Windows::Graphics::Imaging::BitmapPixelFormat get(); } 31 | property Windows::Graphics::Imaging::BitmapAlphaMode BitmapAlphaMode { Windows::Graphics::Imaging::BitmapAlphaMode get(); } 32 | property int PixelWidth { int get(); } 33 | property int PixelHeight { int get(); } 34 | property Windows::Foundation::Size PixelSize { Windows::Foundation::Size get(); } 35 | property double PixelAspectRatio { double get(); } 36 | property Windows::Foundation::TimeSpan FrameDuration { Windows::Foundation::TimeSpan get(); } 37 | 38 | internal: 39 | 40 | bool IsEqual(VideoSourceDescription^ videoDescription); 41 | Windows::Foundation::Collections::IPropertySet^ AsPropertySet(); 42 | 43 | private: 44 | 45 | Windows::Graphics::Imaging::BitmapPixelFormat _bitmapPixelFormat; 46 | Windows::Graphics::Imaging::BitmapAlphaMode _bitmapAlphaMode; 47 | int _pixelWidth; 48 | int _pixelHeight; 49 | double _pixelAspectRatio; 50 | Windows::Foundation::TimeSpan _frameDuration; 51 | }; 52 | 53 | } // end namespace 54 | -------------------------------------------------------------------------------- /FrameProviderSample/pch.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "pch.h" 13 | -------------------------------------------------------------------------------- /FrameProviderSample/pch.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #pragma comment(lib, "mfplat.lib") 24 | #pragma comment(lib, "mf.lib") 25 | #pragma comment(lib, "mfreadwrite.lib") 26 | #pragma comment(lib, "Mfuuid.lib") 27 | #pragma comment(lib, "runtimeobject.lib") 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | // Disable false code analysis warnings 41 | #pragma warning(disable: 26110) // Caller failing to hold lock 42 | #pragma warning(disable: 26165) // Possibly failing to release lock 43 | #pragma warning(disable: 26135) // Missing annotation _Acquires_exclusive_lock_/_Acquires_shared_lock_ 44 | #pragma warning(disable: 4127) // Conditional expression is constant - const flag used to demonstrate different behavior 45 | 46 | // Define abbreviations for long namespace names 47 | namespace WDE = Windows::Devices::Enumeration; 48 | namespace WDP = Windows::Devices::Perception; 49 | namespace WDPP = Windows::Devices::Perception::Provider; 50 | namespace WFC = Windows::Foundation::Collections; 51 | namespace WST = Windows::System::Threading; 52 | namespace WMD = Windows::Media::Devices; 53 | namespace WMC = Windows::Media::Capture; 54 | 55 | namespace WRL = Microsoft::WRL; 56 | namespace WRLW = Microsoft::WRL::Wrappers; 57 | namespace AWST = ABI::Windows::System::Threading; 58 | 59 | namespace MediaFoundationProvider { 60 | 61 | // Define GUID for our custom MediaFoundation attribute indicating if LED illumination is on for the current media sample 62 | // {24AE8CD8-117D-41B4-88F6-2AE46EF9AF58} 63 | static const GUID WDPP_ACTIVE_ILLUMINATION_ENABLED = { 0x24ae8cd8, 0x117d, 0x41b4, { 0x88, 0xf6, 0x2a, 0xe4, 0x6e, 0xf9, 0xaf, 0x58 } }; 64 | 65 | EXTERN_GUID(MF_INTERNAL_CAPTURESOURCE_DEVICECONTROL_COOKIE, 0xA612CDFD, 0xDC58, 0x43CC, 0x9C, 0x0B, 0x81, 0x6B, 0x69, 0x07, 0x50, 0x4F); 66 | 67 | 68 | inline void ThrowIfFailed(HRESULT hr) 69 | { 70 | if (FAILED(hr)) 71 | { 72 | throw Platform::Exception::CreateException(hr); 73 | } 74 | } 75 | 76 | inline void ThrowIfFailed(HRESULT hr, Platform::String^ message) 77 | { 78 | if (FAILED(hr)) 79 | { 80 | throw Platform::Exception::CreateException(hr, message); 81 | } 82 | } 83 | 84 | } // end namespace 85 | 86 | #include "VideoSourceDescription.h" 87 | #include "MediaDeviceManager.h" 88 | #include "MediaFoundationWrapper.h" 89 | #include "FrameProvider.h" 90 | #include "FrameManager.h" 91 | -------------------------------------------------------------------------------- /ProviderTest/FaceAlignmentTestApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/ProviderTest/FaceAlignmentTestApi.dll -------------------------------------------------------------------------------- /ProviderTest/FaceVerificationTestApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/ProviderTest/FaceVerificationTestApi.dll -------------------------------------------------------------------------------- /ProviderTest/FrameProviderToolHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/ProviderTest/FrameProviderToolHelper.dll -------------------------------------------------------------------------------- /ProviderTest/WindowsHelloFPV.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/ProviderTest/WindowsHelloFPV.exe -------------------------------------------------------------------------------- /ProviderTest/WindowsHelloFrameProviderValidation.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Partner-app-development/ed9a92f47dfd85fc3e2194c7d5b046620d88e515/ProviderTest/WindowsHelloFrameProviderValidation.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Partner-app-development 2 | This repo contains samples written by Microsoft to demonstrate features that Partners can use in their application development. Specifically, you will find samples written to show you how to use and test Windows Hello with Windows 10 (1511). The first sample is "Windows Hello infrared camera sample", also known as "FrameProviderSample". You can find the documentation for this sample on MSDN at https://msdn.microsoft.com/en-us/library/windows/hardware/mt608301(v=vs.85).aspx. The second sample is a tool for testing your Frame Providers, called "Windows Hello Frame Provider verification tool", also known as ProviderTest. 3 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | --------------------------------------------------------------------------------