diff options
| author | Adonais Romero González <[email protected]> | 2019-01-09 15:40:48 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-01-09 15:40:48 -0800 |
| commit | 0e4c634898f02a512046957bf92adb49f03dd02c (patch) | |
| tree | c733905bcf562e27a7245b6799317eae3f01e582 /general/SimpleMediaSource/MediaSource | |
| parent | 693d7cc6da06e374a0931123f0b5d8c29c945b97 (diff) | |
| parent | 94f38da770fd3c00e4ee62c983d92c769c80c6c9 (diff) | |
Merge pull request #326 from BenPYeh/custom_media_source
Custom media source
Diffstat (limited to 'general/SimpleMediaSource/MediaSource')
10 files changed, 1558 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 + |
