summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdonais Romero González <[email protected]>2019-01-09 15:40:48 -0800
committerGitHub <[email protected]>2019-01-09 15:40:48 -0800
commit0e4c634898f02a512046957bf92adb49f03dd02c (patch)
treec733905bcf562e27a7245b6799317eae3f01e582
parent693d7cc6da06e374a0931123f0b5d8c29c945b97 (diff)
parent94f38da770fd3c00e4ee62c983d92c769c80c6c9 (diff)
Merge pull request #326 from BenPYeh/custom_media_source
Custom media source
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj331
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters47
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp526
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.h81
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp391
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.h54
-rw-r--r--general/SimpleMediaSource/MediaSource/dllMain.cpp35
-rw-r--r--general/SimpleMediaSource/MediaSource/module.def6
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.cpp11
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.h76
-rw-r--r--general/SimpleMediaSource/README.md33
-rw-r--r--general/SimpleMediaSource/SimpleMediaSource.sln67
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c109
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h46
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c167
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h37
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h24
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c193
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h42
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt33
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.infbin0 -> 8500 bytes
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj282
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters57
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h62
-rw-r--r--general/SimpleMediaSource/general-SimpleMediaSource.yaml10
25 files changed, 2720 insertions, 0 deletions
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
new file mode 100644
index 00000000..47562ff7
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{43AD9BF7-E765-48FE-9826-71A8F2CB12DD}</ProjectGuid>
+ <RootNamespace>MediaSource</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <ProjectName>SimpleMediaSource</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <ImageHasSafeExceptionHandlers />
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <ImageHasSafeExceptionHandlers>
+ </ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="module.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dllMain.cpp" />
+ <ClCompile Include="SimpleMediaSource.cpp" />
+ <ClCompile Include="SimpleMediaStream.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="SimpleMediaSource.h" />
+ <ClInclude Include="SimpleMediaStream.h" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
new file mode 100644
index 00000000..ffcc9853
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="module.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="SimpleMediaSource.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleMediaStream.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllMain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="SimpleMediaSource.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleMediaStream.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
new file mode 100644
index 00000000..162fb1d8
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
@@ -0,0 +1,526 @@
+#include "stdafx.h"
+
+///////////////////////////////////////////////////////////////////////////////
+HRESULT
+SimpleMediaSource::RuntimeClassInitialize(
+ )
+{
+ HRESULT hr = S_OK;
+
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+ RETURN_IF_FAILED (MakeAndInitialize<SimpleMediaStream>(&_stream, this));
+ {
+ ComPtr<IMFStreamDescriptor> streamDescriptor(_stream.Get()->_spStreamDesc.Get());
+ RETURN_IF_FAILED (MFCreatePresentationDescriptor(NUM_STREAMS, streamDescriptor.GetAddressOf(), &_spPresentationDescriptor));
+ }
+
+ _wasStreamPreviouslySelected = false;
+ _sourceState = SourceState::Stopped;
+
+ return hr;
+}
+
+// IMFMediaEventGenerator methods.
+IFACEMETHODIMP
+SimpleMediaSource::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ // NOTE:
+ // GetEvent can block indefinitely, so we don't hold the lock.
+ // This requires some juggling with the event queue pointer.
+
+ HRESULT hr = S_OK;
+
+ ComPtr<IMFMediaEventQueue> spQueue;
+
+ {
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
+ }
+
+ // Now get the event.
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const *pvValue
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+
+ return hr;
+}
+
+// IMFMediaSource methods
+IFACEMETHODIMP
+SimpleMediaSource::CreatePresentationDescriptor(
+ _COM_Outptr_ IMFPresentationDescriptor **ppPresentationDescriptor
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppPresentationDescriptor == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppPresentationDescriptor = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spPresentationDescriptor->Clone(ppPresentationDescriptor));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::GetCharacteristics(
+ _Out_ DWORD *pdwCharacteristics
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (nullptr == pdwCharacteristics)
+ {
+ return E_POINTER;
+ }
+ *pdwCharacteristics = 0;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Pause(
+ )
+{
+ // Pause() not required/needed
+ return MF_E_INVALID_STATE_TRANSITION;
+}
+
+
+IFACEMETHODIMP
+SimpleMediaSource::Shutdown(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ _sourceState = SourceState::Shutdown;
+
+ _spAttributes.Reset();
+ _spPresentationDescriptor.Reset();
+
+ if (_spEventQueue != nullptr)
+ {
+ _spEventQueue->Shutdown();
+ _spEventQueue.Reset();
+ }
+
+ if (_stream != nullptr)
+ {
+ _stream.Get()->Shutdown();
+ _stream.Reset();
+ }
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Start(
+ _In_ IMFPresentationDescriptor *pPresentationDescriptor,
+ _In_opt_ const GUID *pguidTimeFormat,
+ _In_ const PROPVARIANT *pvarStartPos
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ DWORD count = 0;
+ PROPVARIANT startTime;
+ BOOL selected = false;
+ ComPtr<IMFStreamDescriptor> streamDesc;
+ DWORD streamIndex = 0;
+
+ if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ else if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
+ {
+ return MF_E_UNSUPPORTED_TIME_FORMAT;
+ }
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (!(_sourceState != SourceState::Stopped || _sourceState != SourceState::Shutdown))
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+
+ _sourceState = SourceState::Started;
+
+ // This checks the passed in PresentationDescriptor matches the member of streams we
+ // have defined internally and that at least one stream is selected
+ RETURN_IF_FAILED (_ValidatePresentationDescriptor(pPresentationDescriptor));
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorCount(&count));
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &startTime));
+
+ // Send event that the source started. Include error code in case it failed.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStarted,
+ GUID_NULL,
+ hr,
+ &startTime));
+
+ // We're hardcoding this to the first descriptor
+ // since this sample is a single stream sample. For
+ // multiple streams, we need to walk the list of streams
+ // and for each selected stream, send the MEUpdatedStream
+ // or MENewStream event along with the MEStreamStarted
+ // event.
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorByIndex(0,
+ &selected,
+ &streamDesc));
+ RETURN_IF_FAILED (streamDesc->GetStreamIdentifier(&streamIndex));
+ if (streamIndex >= NUM_STREAMS)
+ {
+ return MF_E_INVALIDSTREAMNUMBER;
+ }
+
+ if (selected)
+ {
+ ComPtr<IUnknown> spunkStream;
+ MediaEventType met = (_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream);
+
+ // Update our internal PresentationDescriptor
+ RETURN_IF_FAILED (_spPresentationDescriptor->SelectStream(streamIndex));
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_RUNNING));
+ RETURN_IF_FAILED (_stream.As(&spunkStream));
+
+ // Send the MEUpdatedStream/MENewStream to our source event
+ // queue.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(met,
+ GUID_NULL,
+ S_OK,
+ spunkStream.Get()));
+
+ // But for our stream started (MEStreamStarted), we post to our
+ // stream event queue.
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStarted,
+ GUID_NULL,
+ S_OK,
+ &startTime));
+ }
+ _wasStreamPreviouslySelected = selected;
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Stop(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ PROPVARIANT stopTime;
+ DWORD count = 0;
+ MF_STREAM_STATE state;
+
+ if (_sourceState != SourceState::Started)
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+
+ _sourceState = SourceState::Stopped;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
+ RETURN_IF_FAILED (_spPresentationDescriptor->GetStreamDescriptorCount(&count));
+
+ // Deselect the streams and send the stream stopped events.
+ RETURN_IF_FAILED (_stream.Get()->GetStreamState(&state));
+ _wasStreamPreviouslySelected = (state == MF_STREAM_STATE_RUNNING);
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_STOPPED));
+ _spPresentationDescriptor->DeselectStream(0);
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStopped, GUID_NULL, hr, &stopTime));
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStopped, GUID_NULL, hr, &stopTime));
+
+ return hr;
+}
+
+// IMFMediaSourceEx
+IFACEMETHODIMP
+SimpleMediaSource::GetSourceAttributes(
+ _COM_Outptr_ IMFAttributes** sourceAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (nullptr == sourceAttributes)
+ {
+ return E_POINTER;
+ }
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ *sourceAttributes = nullptr;
+ if (_spAttributes.Get() == nullptr)
+ {
+ ComPtr<IMFSensorProfileCollection> profileCollection;
+ ComPtr<IMFSensorProfile> profile;
+
+ // Create our source attribute store.
+ RETURN_IF_FAILED (MFCreateAttributes(_spAttributes.GetAddressOf(), 1));
+
+ // Create an empty profile collection...
+ RETURN_IF_FAILED (MFCreateSensorProfileCollection(&profileCollection));
+
+ // In this example since we have just one stream, we only have one
+ // pin to add: Pin0.
+
+ // Legacy profile is mandatory. This is to ensure non-profile
+ // aware applications can still function, but with degraded
+ // feature sets.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_Legacy, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT<=30,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+ // High Frame Rate profile will only allow >=60fps.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_HighFrameRate, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT>=60,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+
+ // Se the profile collection to the attribute store of the IMFTransform.
+ RETURN_IF_FAILED (_spAttributes->SetUnknown(MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
+ profileCollection.Get()));
+ }
+
+ return _spAttributes.CopyTo(sourceAttributes);
+}
+
+
+IFACEMETHODIMP
+SimpleMediaSource::GetStreamAttributes(
+ DWORD dwStreamIdentifier,
+ _COM_Outptr_ IMFAttributes **ppAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppAttributes == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppAttributes = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ if (dwStreamIdentifier >= NUM_STREAMS)
+ {
+ return MF_E_INVALIDSTREAMNUMBER;
+ }
+ else
+ {
+ *ppAttributes = _stream.Get()->_spAttributes.Get();
+ (*ppAttributes)->AddRef();
+ }
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::SetD3DManager(
+ _In_opt_ IUnknown* /*pManager*/
+ )
+{
+ // Return code is ignored by the frame work, this is a
+ // best effort attempt to inform the media source of the
+ // DXGI manager to use if DX surface support is available.
+
+ return E_NOTIMPL;
+}
+
+// IMFGetService methods
+_Use_decl_annotations_
+IFACEMETHODIMP
+SimpleMediaSource::GetService(
+ _In_ REFGUID guidService,
+ _In_ REFIID riid,
+ _Out_ LPVOID * ppvObject
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (!ppvObject)
+ {
+ return E_POINTER;
+ }
+ *ppvObject = NULL;
+
+ // We have no supported service, just return
+ // MF_E_UNSUPPORTED_SERVICE for all calls.
+
+ return MF_E_UNSUPPORTED_SERVICE;
+}
+
+// IKsControl methods
+_Use_decl_annotations_
+IFACEMETHODIMP
+SimpleMediaSource::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
+{
+ // ERROR_SET_NOT_FOUND is the standard error code returned
+ // by the AV Stream driver framework when a miniport
+ // driver does not register a handler for a KS operation.
+ // We want to mimic the driver behavior here if we don't
+ // support controls.
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+_Use_decl_annotations_
+IFACEMETHODIMP SimpleMediaSource::KsMethod(
+ _In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
+{
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+_Use_decl_annotations_
+IFACEMETHODIMP SimpleMediaSource::KsEvent(
+ _In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+{
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+/// Internal methods.
+HRESULT
+SimpleMediaSource::_CheckShutdownRequiresLock(
+ )
+{
+ if (_sourceState == SourceState::Shutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (_spEventQueue == nullptr || _stream == nullptr)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
+}
+
+HRESULT
+SimpleMediaSource::_ValidatePresentationDescriptor(
+ _In_ IMFPresentationDescriptor *pPD
+ )
+{
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0;
+ bool anySelected = false;
+
+ if (pPD == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ // The caller's PD must have the same number of streams as ours.
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorCount(&cStreams));
+ if (SUCCEEDED(hr) && (cStreams != NUM_STREAMS))
+ {
+ return E_INVALIDARG;
+ }
+
+ // The caller must select at least one stream.
+ for (UINT32 i = 0; i < cStreams; ++i)
+ {
+ ComPtr<IMFStreamDescriptor> spSD;
+ BOOL fSelected = FALSE;
+ DWORD dwId = 0;
+
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD));
+
+ anySelected |= !!fSelected;
+
+ RETURN_IF_FAILED (spSD->GetStreamIdentifier(&dwId));
+ if (dwId >= NUM_STREAMS)
+ {
+ return E_INVALIDARG;
+ }
+ }
+
+ if (!anySelected)
+ {
+ return E_INVALIDARG;
+ }
+
+ return hr;
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
new file mode 100644
index 00000000..019926c8
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
@@ -0,0 +1,81 @@
+#pragma once
+
+// Represents a simple media source that only has one stream and outputs a static image
+
+#include "stdafx.h"
+
+class SimpleMediaStream;
+
+class __declspec(uuid("{9812588D-5CE9-4E4C-ABC1-049138D10DCE}"))
+SimpleMediaSource : public RuntimeClass<
+ RuntimeClassFlags<WinRtClassicComMix>,
+ IMFMediaEventGenerator,
+ IMFMediaSource,
+ IMFMediaSourceEx,
+ IMFGetService,
+ IKsControl>
+{
+
+ enum class SourceState
+ {
+ Invalid, Stopped, Started, Shutdown
+ };
+
+public:
+ // IMFMediaEventGenerator
+ IFACEMETHOD(BeginGetEvent)(_In_ IMFAsyncCallback *pCallback, _In_ IUnknown *punkState);
+ IFACEMETHOD(EndGetEvent)(_In_ IMFAsyncResult *pResult, _Out_ IMFMediaEvent **ppEvent);
+ IFACEMETHOD(GetEvent)(DWORD dwFlags, _Out_ IMFMediaEvent **ppEvent);
+ IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, _In_ const PROPVARIANT *pvValue);
+
+ // IMFMediaSource
+ IFACEMETHOD(CreatePresentationDescriptor)(_Out_ IMFPresentationDescriptor **ppPresentationDescriptor);
+ IFACEMETHOD(GetCharacteristics)(_Out_ DWORD *pdwCharacteristics);
+ IFACEMETHOD(Pause)();
+ IFACEMETHOD(Shutdown)();
+ IFACEMETHOD(Start)(_In_ IMFPresentationDescriptor *pPresentationDescriptor, _In_ const GUID *pguidTimeFormat, _In_ const PROPVARIANT *pvarStartPosition);
+ IFACEMETHOD(Stop)();
+
+ // IMFMediaSourceEx
+ IFACEMETHOD(GetSourceAttributes)(_COM_Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(SetD3DManager)(_In_opt_ IUnknown *pManager);
+
+ // IMFGetService
+ IFACEMETHOD(GetService)(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID *ppvObject);
+
+ // IKsControl
+ IFACEMETHOD(KsProperty)(_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsMethod)(_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsEvent)(_In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned);
+public:
+ HRESULT RuntimeClassInitialize();
+
+private:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor *pPresentationDescriptor);
+
+ CriticalSection _critSec;
+ SourceState _sourceState{ SourceState::Invalid };
+ ComPtr<IMFMediaEventQueue> _spEventQueue;
+ ComPtr<IMFPresentationDescriptor> _spPresentationDescriptor;
+ ComPtr<IMFAttributes> _spAttributes;
+
+ bool _wasStreamPreviouslySelected; // maybe makes more sense as a property of the stream
+ const DWORD NUM_STREAMS = 1;
+ ComPtr<SimpleMediaStream> _stream;
+};
+
+CoCreatableClass(SimpleMediaSource);
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
new file mode 100644
index 00000000..7685b12e
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
@@ -0,0 +1,391 @@
+#include "stdafx.h"
+
+#define NUM_IMAGE_ROWS 240
+#define NUM_IMAGE_COLS 320
+#define BYTES_PER_PIXEL 4
+#define IMAGE_BUFFER_SIZE_BYTES (NUM_IMAGE_ROWS * NUM_IMAGE_COLS * BYTES_PER_PIXEL)
+#define IMAGE_ROW_SIZE_BYTES (NUM_IMAGE_COLS * BYTES_PER_PIXEL)
+
+HRESULT
+SimpleMediaStream::RuntimeClassInitialize(
+ _In_ SimpleMediaSource *pSource
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFMediaTypeHandler> spTypeHandler;
+ ComPtr<IMFAttributes> attrs;
+
+ if (nullptr == pSource)
+ {
+ return E_INVALIDARG;
+ }
+ RETURN_IF_FAILED (pSource->QueryInterface(IID_PPV_ARGS(&_parent)));
+
+ // Initialize media type and set the video output media type.
+ RETURN_IF_FAILED (MFCreateMediaType(&_spMediaType));
+ _spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+ _spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
+ _spMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
+ _spMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+ MFSetAttributeSize(_spMediaType.Get(), MF_MT_FRAME_SIZE, NUM_IMAGE_COLS, NUM_IMAGE_ROWS);
+ MFSetAttributeRatio(_spMediaType.Get(), MF_MT_FRAME_RATE, 30, 1);
+ MFSetAttributeRatio(_spMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (this->_SetStreamAttributes(_spAttributes.Get()));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+
+ // Initialize stream descriptors
+ RETURN_IF_FAILED (MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc));
+
+ RETURN_IF_FAILED (_spStreamDesc->GetMediaTypeHandler(&spTypeHandler));
+ RETURN_IF_FAILED (spTypeHandler->SetCurrentMediaType(_spMediaType.Get()));
+ RETURN_IF_FAILED (this->_SetStreamDescriptorAttributes(_spStreamDesc.Get()));
+
+ return hr;
+}
+
+// IMFMediaEventGenerator
+IFACEMETHODIMP
+SimpleMediaStream::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ // NOTE:
+ // GetEvent can block indefinitely, so we don't hold the lock.
+ // This requires some juggling with the event queue pointer.
+
+ HRESULT hr = S_OK;
+
+ ComPtr<IMFMediaEventQueue> spQueue;
+
+ {
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
+ }
+
+ // Now get the event.
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const *pvValue
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+
+ return hr;
+}
+
+// IMFMediaStream
+IFACEMETHODIMP
+SimpleMediaStream::GetMediaSource(
+ _COM_Outptr_ IMFMediaSource **ppMediaSource
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppMediaSource == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppMediaSource = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ *ppMediaSource = _parent.Get();
+ (*ppMediaSource)->AddRef();
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamDescriptor(
+ _COM_Outptr_ IMFStreamDescriptor **ppStreamDescriptor
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppStreamDescriptor == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppStreamDescriptor = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (_spStreamDesc != nullptr)
+ {
+ *ppStreamDescriptor = _spStreamDesc.Get();
+ (*ppStreamDescriptor)->AddRef();
+ }
+ else
+ {
+ return E_UNEXPECTED;
+ }
+
+ return hr;
+}
+
+/*
+ Writes to a buffer representing a 2D image.
+ Writes a different constant to each line based on row number and current time.
+
+ Assumes top down image, no negative stride and pBuf points to the begnning of the buffer of length len.
+
+ Param:
+ pBuf - pointer to beginning of buffer
+ pitch - line length in bytes
+ len - length of buffer in bytes
+*/
+HRESULT
+WriteSampleData(
+ _Inout_updates_bytes_(len) BYTE *pBuf,
+ _In_ LONG pitch,
+ _In_ DWORD len
+ )
+{
+ if (pBuf == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ const int NUM_ROWS = len / abs(pitch);
+
+ LONGLONG curSysTimeInS = MFGetSystemTime() / (MFTIME)10000000;
+ int offset = curSysTimeInS % NUM_ROWS;
+
+ for (int r = 0; r < NUM_ROWS; r++)
+ {
+ int grayColor = r + offset;
+ memset(pBuf + (pitch * r), (BYTE)(grayColor % NUM_ROWS), pitch);
+ }
+
+ return S_OK;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::RequestSample(
+ _In_ IUnknown *pToken
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ ComPtr<IMFSample> sample;
+ ComPtr<IMFMediaBuffer> outputBuffer;
+ LONG pitch = IMAGE_ROW_SIZE_BYTES;
+ BYTE *bufferStart = nullptr; // not used
+ DWORD bufferLength = 0;
+ BYTE *pbuf = nullptr;
+ ComPtr<IMF2DBuffer2> buffer2D;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (MFCreateSample(&sample));
+ RETURN_IF_FAILED (MFCreate2DMediaBuffer(NUM_IMAGE_COLS,
+ NUM_IMAGE_ROWS,
+ D3DFMT_X8R8G8B8,
+ false,
+ &outputBuffer));
+ RETURN_IF_FAILED (outputBuffer.As(&buffer2D));
+ RETURN_IF_FAILED (buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write,
+ &pbuf,
+ &pitch,
+ &bufferStart,
+ &bufferLength));
+ RETURN_IF_FAILED (WriteSampleData(pbuf, pitch, bufferLength));
+ RETURN_IF_FAILED (buffer2D->Unlock2D());
+ RETURN_IF_FAILED (sample->AddBuffer(outputBuffer.Get()));
+ RETURN_IF_FAILED (sample->SetSampleTime(MFGetSystemTime()));
+ RETURN_IF_FAILED (sample->SetSampleDuration(333333));
+ if (pToken != nullptr)
+ {
+ RETURN_IF_FAILED (sample->SetUnknown(MFSampleExtension_Token, pToken));
+ }
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(MEMediaSample,
+ GUID_NULL,
+ S_OK,
+ sample.Get()));
+
+ return hr;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// IMFMediaStream2
+IFACEMETHODIMP
+SimpleMediaStream::SetStreamState(
+ MF_STREAM_STATE state
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ bool runningState = false;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ switch (state)
+ {
+ case MF_STREAM_STATE_PAUSED:
+ goto done; // because not supported
+ case MF_STREAM_STATE_RUNNING:
+ runningState = true;
+ break;
+ case MF_STREAM_STATE_STOPPED:
+ runningState = false;
+ break;
+ default:
+ hr = MF_E_INVALID_STATE_TRANSITION;
+ break;
+ }
+
+ _isSelected = runningState;
+
+done:
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamState(
+ _Out_ MF_STREAM_STATE *pState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ BOOLEAN pauseState = false;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (SUCCEEDED(hr))
+ {
+ *pState = (_isSelected ? MF_STREAM_STATE_RUNNING : MF_STREAM_STATE_STOPPED);
+ }
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::Shutdown(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ _isShutdown = true;
+ _parent.Reset();
+
+ if (_spEventQueue != nullptr)
+ {
+ hr = _spEventQueue->Shutdown();
+ _spEventQueue.Reset();
+ }
+
+ _spAttributes.Reset();
+ _spMediaType.Reset();
+ _spStreamDesc.Reset();
+
+ _isSelected = false;
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::_CheckShutdownRequiresLock(
+ )
+{
+ if (_isShutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (_spEventQueue == nullptr)
+ {
+ return E_UNEXPECTED;
+
+ }
+ return S_OK;
+}
+
+HRESULT
+SimpleMediaStream::_SetStreamAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
+
+ RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color));
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::_SetStreamDescriptorAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
+
+ RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color));
+
+ return hr;
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
new file mode 100644
index 00000000..56351f47
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "stdafx.h"
+
+class SimpleMediaSource;
+
+class SimpleMediaStream : public RuntimeClass<
+ RuntimeClassFlags<ClassicCom>,
+ IMFMediaEventGenerator,
+ IMFMediaStream,
+ IMFMediaStream2>
+{
+ friend class SimpleMediaSource;
+
+public:
+ // IMFMediaEventGenerator
+ IFACEMETHOD(BeginGetEvent)(IMFAsyncCallback *pCallback, IUnknown *punkState);
+ IFACEMETHOD(EndGetEvent)(IMFAsyncResult *pResult, IMFMediaEvent **ppEvent);
+ IFACEMETHOD(GetEvent)(DWORD dwFlags, IMFMediaEvent **ppEvent);
+ IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT *pvValue);
+
+ // IMFMediaStream
+ IFACEMETHOD(GetMediaSource)(IMFMediaSource **ppMediaSource);
+ IFACEMETHOD(GetStreamDescriptor)(IMFStreamDescriptor **ppStreamDescriptor);
+ IFACEMETHOD(RequestSample)(IUnknown *pToken);
+
+ // IMFMediaStream2
+ IFACEMETHOD(SetStreamState)(MF_STREAM_STATE state);
+ IFACEMETHOD(GetStreamState)(_Out_ MF_STREAM_STATE *pState);
+
+ // Non-interface methods.
+ HRESULT RuntimeClassInitialize(_In_ SimpleMediaSource* pSource);
+ HRESULT Shutdown();
+
+
+protected:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _SetStreamAttributes(IMFAttributes* pAttributeStore);
+ HRESULT _SetStreamDescriptorAttributes(IMFAttributes* pAttributeStore);
+
+
+ CriticalSection _critSec;
+
+ ComPtr<IMFMediaSource> _parent;
+ ComPtr<IMFMediaEventQueue> _spEventQueue;
+ ComPtr<IMFAttributes> _spAttributes;
+ ComPtr<IMFMediaType> _spMediaType;
+ ComPtr<IMFStreamDescriptor> _spStreamDesc;
+ bool _isShutdown = false;
+ bool _isSelected = false;
+
+ const DWORD STREAMINDEX = 0; // since there is only one stream
+};
+
diff --git a/general/SimpleMediaSource/MediaSource/dllMain.cpp b/general/SimpleMediaSource/MediaSource/dllMain.cpp
new file mode 100644
index 00000000..aed44eb0
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/dllMain.cpp
@@ -0,0 +1,35 @@
+/// <copyright file="dllmain.cpp" company="Microsoft">
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+/// </copyright>
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "stdafx.h"
+
+#include <wrl\module.h>
+
+#if !defined(__WRL_CLASSIC_COM__)
+STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _COM_Outptr_ IActivationFactory** factory)
+{
+ return Module<InProc>::GetModule().GetActivationFactory(activatibleClassId, factory);
+}
+#endif
+
+#if !defined(__WRL_WINRT_STRICT__)
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
+{
+ return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
+}
+#endif
+
+STDAPI DllCanUnloadNow()
+{
+ return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
+}
+
+STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinst);
+ }
+ return TRUE;
+}
diff --git a/general/SimpleMediaSource/MediaSource/module.def b/general/SimpleMediaSource/MediaSource/module.def
new file mode 100644
index 00000000..ddeb3eac
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/module.def
@@ -0,0 +1,6 @@
+LIBRARY
+
+EXPORTS
+ DllGetActivationFactory PRIVATE
+ DllGetClassObject PRIVATE
+ DllCanUnloadNow PRIVATE
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.cpp b/general/SimpleMediaSource/MediaSource/stdafx.cpp
new file mode 100644
index 00000000..dc97a45b
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/stdafx.cpp
@@ -0,0 +1,11 @@
+/// <copyright file="stdafx.cpp" company="Microsoft">
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+/// </copyright>
+// stdafx.cpp : source file that includes just the standard includes
+// KinectMFMediaSource.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.h b/general/SimpleMediaSource/MediaSource/stdafx.h
new file mode 100644
index 00000000..73bec0b4
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/stdafx.h
@@ -0,0 +1,76 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Windows Header Files:
+#include <windows.h>
+#include <propvarutil.h>
+//#include <mfstd.h> // Must be included before <initguid.h>, or else DirectDraw GUIDs will be defined twice. See the comment in <uuids.h>.
+#include <ole2.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <mfreadwrite.h>
+#include <nserror.h>
+#include <winmeta.h>
+#include <wrl.h>
+#include <d3d9types.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+#if !defined(_IKsControl_)
+#define _IKsControl_
+interface DECLSPEC_UUID("28F54685-06FD-11D2-B27A-00A0C9223196") IKsControl;
+#undef INTERFACE
+#define INTERFACE IKsControl
+DECLARE_INTERFACE_(IKsControl, IUnknown)
+{
+ STDMETHOD(KsProperty)(
+ THIS_
+ IN PKSPROPERTY Property,
+ IN ULONG PropertyLength,
+ IN OUT LPVOID PropertyData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsMethod)(
+ THIS_
+ IN PKSMETHOD Method,
+ IN ULONG MethodLength,
+ IN OUT LPVOID MethodData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsEvent)(
+ THIS_
+ IN PKSEVENT Event OPTIONAL,
+ IN ULONG EventLength,
+ IN OUT LPVOID EventData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+};
+#endif // _IKsControl_
+
+#include "SimpleMediaStream.h"
+#include "SimpleMediaSource.h"
+
+
+// Basic macros to handle HRESULT checks.
+// Recommend adding implementation specific logging within the failure case.
+#ifndef RETURN_IF_FAILED
+#define RETURN_IF_FAILED( val ) \
+ hr = (val); \
+ if ( FAILED( hr ) ) \
+ { \
+ return hr; \
+ }
+#endif
+
diff --git a/general/SimpleMediaSource/README.md b/general/SimpleMediaSource/README.md
new file mode 100644
index 00000000..ca8e85da
--- /dev/null
+++ b/general/SimpleMediaSource/README.md
@@ -0,0 +1,33 @@
+<!---
+ name: SimpleMediaSource Sample
+ platform: UMDF2
+ language: cpp
+ category: general
+ description: Demonstrates how to write a custom media source and driver package.
+ samplefwlink:
+--->
+
+SimpleMediaSource Sample
+========================
+This sample demonstrates how to create a custom media source and driver package that can be installed as a Camera and produce frames.
+
+This sample has accompanying documentation here: https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/frame-server-custom-media-source
+
+
+Contents
+--------
+MediaSource - COM DLL project for the custom media source
+SimpleMediaSourceDriver - UMDF driver install package
+
+Installation
+------------------
+
+1. Build the solution.
+
+2. Navigate to the output folder, e.g. Windows-driver-samples\general\SimpleMediaSource\x64\Release, and the driver package will be in a directory also called SimpleMediaSourceDriver. Check that the folder has `SimpleMediaSource.dll`, `simplemediasourcedriver.cat`, `SimpleMediaSourceDriver.dll`, and `SimpleMediaSourceDriver.inf`.
+
+3. Deploy the driver package with
+
+`devcon dp_add SimpleMediaSourceDriver.inf`
+
+4. In Device Manager, locate **SimpleMediaSource Capture Source**, under the Camera category. Open the Microsoft Camera App, switch cameras if necessary until the camera is streaming from the SimpleMediaSource. You should see a scrolling black and white gradient. \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSource.sln b/general/SimpleMediaSource/SimpleMediaSource.sln
new file mode 100644
index 00000000..c93b8c42
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSource.sln
@@ -0,0 +1,67 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2026
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleMediaSource", "MediaSource\MediaSource.vcxproj", "{43AD9BF7-E765-48FE-9826-71A8F2CB12DD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleMediaSourceDriver", "SimpleMediaSourceDriver\SimpleMediaSourceDriver.vcxproj", "{3098C6BF-E96E-4793-A70E-FB09B741580A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|ARM.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x64.ActiveCfg = Debug|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x64.Build.0 = Debug|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x86.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x86.Build.0 = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM.ActiveCfg = Release|ARM
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM.Build.0 = Release|ARM
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM64.Build.0 = Release|ARM64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x64.ActiveCfg = Release|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x64.Build.0 = Release|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x86.ActiveCfg = Release|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x86.Build.0 = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.ActiveCfg = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.Build.0 = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.Deploy.0 = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.ActiveCfg = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.Build.0 = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.Deploy.0 = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.ActiveCfg = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.Build.0 = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.Deploy.0 = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.ActiveCfg = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.Build.0 = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.Deploy.0 = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.Build.0 = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.Deploy.0 = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.ActiveCfg = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.Build.0 = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.Deploy.0 = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.ActiveCfg = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.Build.0 = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2205BF4A-ACC2-4A73-8C1E-C3D9AF0F8B24}
+ EndGlobalSection
+EndGlobal
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c
new file mode 100644
index 00000000..083cf3c7
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c
@@ -0,0 +1,109 @@
+/*++
+
+Module Name:
+
+ device.c - Device handling events for example driver.
+
+Abstract:
+
+ This file contains the device entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "device.tmh"
+
+GUID CAMERA_CATEGORY = { STATIC_KSCATEGORY_VIDEO_CAMERA };
+GUID CAPTURE_CATEGORY = { STATIC_KSCATEGORY_CAPTURE };
+GUID VIDEO_CATEGORY = { STATIC_KSCATEGORY_VIDEO };
+
+NTSTATUS
+SimpleMediaSourceDriverCreateDevice(
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+
+Routine Description:
+
+ Worker routine called to create a device and its software resources.
+
+Arguments:
+
+ DeviceInit - Pointer to an opaque init structure. Memory for this
+ structure will be freed by the framework when the WdfDeviceCreate
+ succeeds. So don't access the structure after that point.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ WDF_OBJECT_ATTRIBUTES deviceAttributes;
+ PDEVICE_CONTEXT deviceContext;
+ WDFDEVICE device;
+ NTSTATUS status;
+ UNICODE_STRING szReference;
+ RtlInitUnicodeString(&szReference, L"CustomCameraSource"); // Needs to match the ReferenceString in INF
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
+
+ status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
+
+ if (NT_SUCCESS(status)) {
+ //
+ // Get a pointer to the device context structure that we just associated
+ // with the device object. We define this structure in the device.h
+ // header file. DeviceGetContext is an inline function generated by
+ // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.
+ // This function will do the type checking and return the device context.
+ // If you pass a wrong object handle it will return NULL and assert if
+ // run under framework verifier mode.
+ //
+ deviceContext = DeviceGetContext(device);
+
+ //
+ // Initialize the context.
+ //
+ deviceContext->PrivateDeviceData = 0;
+
+ //
+ // Create a device interface so that applications can find and talk
+ // to us.
+ //
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &CAMERA_CATEGORY,
+ &szReference // ReferenceString
+ );
+
+ if (NT_SUCCESS(status)) {
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &CAPTURE_CATEGORY,
+ &szReference // ReferenceString
+ );
+ }
+
+ if (NT_SUCCESS(status)) {
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &VIDEO_CATEGORY,
+ &szReference // ReferenceString
+ );
+ }
+
+ if (NT_SUCCESS(status)) {
+ //
+ // Initialize the I/O Package and any Queues
+ //
+ status = SimpleMediaSourceDriverQueueInitialize(device);
+ }
+ }
+
+ return status;
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h
new file mode 100644
index 00000000..6c2da5e4
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h
@@ -0,0 +1,46 @@
+/*++
+
+Module Name:
+
+ device.h
+
+Abstract:
+
+ This file contains the device definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "public.h"
+
+EXTERN_C_START
+
+//
+// The device context performs the same job as
+// a WDM device extension in the driver frameworks
+//
+typedef struct _DEVICE_CONTEXT
+{
+ ULONG PrivateDeviceData; // just a placeholder
+
+} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
+
+//
+// This macro will generate an inline function called DeviceGetContext
+// which will be used to get a pointer to the device context memory
+// in a type safe manner.
+//
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)
+
+//
+// Function to initialize the device and its callbacks
+//
+NTSTATUS
+SimpleMediaSourceDriverCreateDevice(
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ );
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c
new file mode 100644
index 00000000..94ee0fa9
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c
@@ -0,0 +1,167 @@
+/*++
+
+Module Name:
+
+ driver.c
+
+Abstract:
+
+ This file contains the driver entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "driver.tmh"
+
+NTSTATUS
+DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry specifies the other entry
+ points in the function driver, such as EvtDevice and DriverUnload.
+
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverEntry must initialize members of DriverObject before it
+ returns to the caller. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ WDF_DRIVER_CONFIG config;
+ NTSTATUS status;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ //
+ // Initialize WPP Tracing
+ //
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_INIT_TRACING(MYDRIVER_TRACING_ID);
+#else
+ WPP_INIT_TRACING( DriverObject, RegistryPath );
+#endif
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ //
+ // Register a cleanup callback so that we can call WPP_CLEANUP when
+ // the framework driver object is deleted during driver unload.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.EvtCleanupCallback = SimpleMediaSourceDriverEvtDriverContextCleanup;
+
+ WDF_DRIVER_CONFIG_INIT(&config,
+ SimpleMediaSourceDriverEvtDeviceAdd
+ );
+
+ status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ &attributes,
+ &config,
+ WDF_NO_HANDLE
+ );
+
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_CLEANUP();
+#else
+ WPP_CLEANUP(DriverObject);
+#endif
+ return status;
+ }
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
+
+ return status;
+}
+
+NTSTATUS
+SimpleMediaSourceDriverEvtDeviceAdd(
+ _In_ WDFDRIVER Driver,
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a device object to
+ represent a new instance of the device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ status = SimpleMediaSourceDriverCreateDevice(DeviceInit);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
+
+ return status;
+}
+
+VOID
+SimpleMediaSourceDriverEvtDriverContextCleanup(
+ _In_ WDFOBJECT DriverObject
+ )
+/*++
+Routine Description:
+
+ Free all the resources allocated in DriverEntry.
+
+Arguments:
+
+ DriverObject - handle to a WDF Driver object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ //
+ // Stop WPP Tracing
+ //
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_CLEANUP();
+#else
+ WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
+#endif
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h
new file mode 100644
index 00000000..1e19eec9
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h
@@ -0,0 +1,37 @@
+/*++
+
+Module Name:
+
+ driver.h
+
+Abstract:
+
+ This file contains the driver definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include <windows.h>
+#include <wdf.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
+
+#include "device.h"
+#include "queue.h"
+#include "trace.h"
+
+EXTERN_C_START
+
+//
+// WDFDRIVER Events
+//
+
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_DEVICE_ADD SimpleMediaSourceDriverEvtDeviceAdd;
+EVT_WDF_OBJECT_CONTEXT_CLEANUP SimpleMediaSourceDriverEvtDriverContextCleanup;
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h
new file mode 100644
index 00000000..f3d4964b
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h
@@ -0,0 +1,24 @@
+/*++
+
+Module Name:
+
+ public.h
+
+Abstract:
+
+ This module contains the common declarations shared by driver
+ and user applications.
+
+Environment:
+
+ driver and application
+
+--*/
+
+//
+// Define an Interface Guid so that apps can find the device and talk to it.
+//
+
+DEFINE_GUID (GUID_DEVINTERFACE_SimpleMediaSourceDriver,
+ 0xb5036295,0xf041,0x4506,0x88,0xdc,0xcb,0x16,0x5c,0x4d,0x67,0x8c);
+// {b5036295-f041-4506-88dc-cb165c4d678c}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c
new file mode 100644
index 00000000..6ea51781
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c
@@ -0,0 +1,193 @@
+/*++
+
+Module Name:
+
+ queue.c
+
+Abstract:
+
+ This file contains the queue entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "queue.tmh"
+
+NTSTATUS
+SimpleMediaSourceDriverQueueInitialize(
+ _In_ WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ The I/O dispatch callbacks for the frameworks device object
+ are configured in this function.
+
+ A single default I/O Queue is configured for parallel request
+ processing, and a driver context memory allocation is created
+ to hold our structure QUEUE_CONTEXT.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ WDFQUEUE queue;
+ NTSTATUS status;
+ WDF_IO_QUEUE_CONFIG queueConfig;
+
+ //
+ // Configure a default queue so that requests that are not
+ // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
+ // other queues get dispatched here.
+ //
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
+ &queueConfig,
+ WdfIoQueueDispatchParallel
+ );
+
+ queueConfig.EvtIoDeviceControl = SimpleMediaSourceDriverEvtIoDeviceControl;
+ queueConfig.EvtIoStop = SimpleMediaSourceDriverEvtIoStop;
+
+ status = WdfIoQueueCreate(
+ Device,
+ &queueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &queue
+ );
+
+ if(!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status);
+ return status;
+ }
+
+ return status;
+}
+
+VOID
+SimpleMediaSourceDriverEvtIoDeviceControl(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode
+ )
+/*++
+
+Routine Description:
+
+ This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - Size of the output buffer in bytes
+
+ InputBufferLength - Size of the input buffer in bytes
+
+ IoControlCode - I/O control code.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ TraceEvents(TRACE_LEVEL_INFORMATION,
+ TRACE_QUEUE,
+ "%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d",
+ Queue, Request, (int) OutputBufferLength, (int) InputBufferLength, IoControlCode);
+
+ WdfRequestComplete(Request, STATUS_SUCCESS);
+
+ return;
+}
+
+VOID
+SimpleMediaSourceDriverEvtIoStop(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ ULONG ActionFlags
+)
+/*++
+
+Routine Description:
+
+ This event is invoked for a power-managed queue before the device leaves the working state (D0).
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+
+ Request - Handle to a framework request object.
+
+ ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags
+ that identify the reason that the callback function is being called
+ and whether the request is cancelable.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ TraceEvents(TRACE_LEVEL_INFORMATION,
+ TRACE_QUEUE,
+ "%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d",
+ Queue, Request, ActionFlags);
+
+ //
+ // In most cases, the EvtIoStop callback function completes, cancels, or postpones
+ // further processing of the I/O request.
+ //
+ // Typically, the driver uses the following rules:
+ //
+ // - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable
+ // (if the request is cancelable) and either calls WdfRequestStopAcknowledge
+ // with a Requeue value of TRUE, or it calls WdfRequestComplete with a
+ // completion status value of STATUS_SUCCESS or STATUS_CANCELLED.
+ //
+ // Before it can call these methods safely, the driver must make sure that
+ // its implementation of EvtIoStop has exclusive access to the request.
+ //
+ // In order to do that, the driver must synchronize access to the request
+ // to prevent other threads from manipulating the request concurrently.
+ // The synchronization method you choose will depend on your driver's design.
+ //
+ // For example, if the request is held in a shared context, the EvtIoStop callback
+ // might acquire an internal driver lock, take the request from the shared context,
+ // and then release the lock. At this point, the EvtIoStop callback owns the request
+ // and can safely complete or requeue the request.
+ //
+ // - If the driver has forwarded the I/O request to an I/O target, it either calls
+ // WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones
+ // further processing of the request and calls WdfRequestStopAcknowledge with
+ // a Requeue value of FALSE.
+ //
+ // A driver might choose to take no action in EvtIoStop for requests that are
+ // guaranteed to complete in a small amount of time.
+ //
+ // In this case, the framework waits until the specified request is complete
+ // before moving the device (or system) to a lower power state or removing the device.
+ // Potentially, this inaction can prevent a system from entering its hibernation state
+ // or another low system power state. In extreme cases, it can cause the system
+ // to crash with bugcheck code 9F.
+ //
+
+ return;
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h
new file mode 100644
index 00000000..e0c01283
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h
@@ -0,0 +1,42 @@
+/*++
+
+Module Name:
+
+ queue.h
+
+Abstract:
+
+ This file contains the queue definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+EXTERN_C_START
+
+//
+// This is the context that can be placed per queue
+// and would contain per queue information.
+//
+typedef struct _QUEUE_CONTEXT {
+
+ ULONG PrivateDeviceData; // just a placeholder
+
+} QUEUE_CONTEXT, *PQUEUE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)
+
+NTSTATUS
+SimpleMediaSourceDriverQueueInitialize(
+ _In_ WDFDEVICE Device
+ );
+
+//
+// Events from the IoQueue object
+//
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL SimpleMediaSourceDriverEvtIoDeviceControl;
+EVT_WDF_IO_QUEUE_IO_STOP SimpleMediaSourceDriverEvtIoStop;
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt b/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt
new file mode 100644
index 00000000..55d9dadd
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt
@@ -0,0 +1,33 @@
+========================================================================
+ SimpleMediaSourceDriver Project Overview
+========================================================================
+
+This file contains a summary of what you will find in each of the files that make up your project.
+
+SimpleMediaSourceDriver.vcxproj
+ This is the main project file for projects generated using an Application Wizard.
+ It contains information about the version of the product that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+SimpleMediaSourceDriver.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+Public.h
+ Header file to be shared with applications.
+
+Driver.c & Driver.h
+ DriverEntry and WDFDRIVER related functionality and callbacks.
+
+Device.c & Device.h
+ WDFDEVICE related functionality and callbacks.
+
+Queue.c & Queue.h
+ WDFQUEUE related functionality and callbacks.
+
+Trace.h
+ Definitions for WPP tracing.
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf
new file mode 100644
index 00000000..dabb3237
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf
Binary files differ
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
new file mode 100644
index 00000000..38e21ccd
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.c" />
+ <ClCompile Include="Driver.c" />
+ <ClCompile Include="Queue.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h" />
+ <ClInclude Include="Driver.h" />
+ <ClInclude Include="Public.h" />
+ <ClInclude Include="Queue.h" />
+ <ClInclude Include="Trace.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="SimpleMediaSourceDriver.inf" />
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(OutDir)\SimpleMediaSource.dll">
+ <PackageRelativeDirectory>
+ </PackageRelativeDirectory>
+ </FilesToPackage>
+ <FilesToPackage Include="$(OutDir)\SimpleMediaSourceDriver.dll">
+ <PackageRelativeDirectory>
+ </PackageRelativeDirectory>
+ </FilesToPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaSource\MediaSource.vcxproj">
+ <Project>{43ad9bf7-e765-48fe-9826-71a8f2cb12dd}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3098C6BF-E96E-4793-A70E-FB09B741580A}</ProjectGuid>
+ <TemplateGuid>{32909489-7be5-497b-aafa-db6669d9b44b}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>SimpleMediaSourceDriver</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <EnableInf2cat>false</EnableInf2cat>
+ <Inf2CatWindowsVersionList>
+ </Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <EnableInf2cat>false</EnableInf2cat>
+ <Inf2CatWindowsVersionList>
+ </Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <Inf2CatWindowsVersionList>Server10_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <Inf2CatWindowsVersionList>Server10_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters
new file mode 100644
index 00000000..6f2263ef
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Driver Files">
+ <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="SimpleMediaSourceDriver.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Driver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Public.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Queue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Trace.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Driver.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Queue.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h
new file mode 100644
index 00000000..0180b817
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h
@@ -0,0 +1,62 @@
+/*++
+
+Module Name:
+
+ Internal.h
+
+Abstract:
+
+ This module contains the local type definitions for the
+ driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework 2
+
+--*/
+
+//
+// Define the tracing flags.
+//
+// Tracing GUID - a9ae54d8-0a84-4b05-b9ae-faff98267b7e
+//
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID( \
+ MyDriver1TraceGuid, (a9ae54d8,0a84,4b05,b9ae,faff98267b7e), \
+ \
+ WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
+ WPP_DEFINE_BIT(TRACE_DRIVER) \
+ WPP_DEFINE_BIT(TRACE_DEVICE) \
+ WPP_DEFINE_BIT(TRACE_QUEUE) \
+ )
+
+#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
+ WPP_LEVEL_LOGGER(flag)
+
+#define WPP_FLAG_LEVEL_ENABLED(flag, level) \
+ (WPP_LEVEL_ENABLED(flag) && \
+ WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
+
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
+ WPP_LEVEL_LOGGER(flags)
+
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
+ (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+
+//
+// This comment block is scanned by the trace preprocessor to define our
+// Trace function.
+//
+// begin_wpp config
+// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
+// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
+// end_wpp
+
+//
+//
+// Driver specific #defines
+//
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ #define MYDRIVER_TRACING_ID L"Microsoft\\UMDF2.0\\SimpleMediaSourceDriver V1.0"
+#endif \ No newline at end of file
diff --git a/general/SimpleMediaSource/general-SimpleMediaSource.yaml b/general/SimpleMediaSource/general-SimpleMediaSource.yaml
new file mode 100644
index 00000000..88e2d839
--- /dev/null
+++ b/general/SimpleMediaSource/general-SimpleMediaSource.yaml
@@ -0,0 +1,10 @@
+### YamlMime:Sample
+sample:
+- name: SimpleMediaSource Sample
+ description: Demonstrates how to write a custom media source and driver package.
+ generateZip: true
+ author: windows-driver-samples
+ languages:
+ - cpp
+ technologies:
+ - windows