summaryrefslogtreecommitdiff
path: root/general
diff options
context:
space:
mode:
authorj-leungyy <[email protected]>2021-05-25 09:06:09 -0700
committerGitHub <[email protected]>2021-05-25 09:06:09 -0700
commit4fe5787f122fdfc45253b45f9fad3983f53d86df (patch)
treea11e06f8951d4b7b847f6f5a708f86df87d637db /general
parent53afd12aadb8aff15097f1546d4f80c6074e0bdc (diff)
update simplemediasource sample (#614)
* update simplemediasource wrl to winrtcpp COM, add mediatype NV12 (SimpleFrameGenerator), fix Mediatype missing attribute (bitrate), add IMFActivate, IMFSampleAllocator interface and implementation, update hardcode arg with named variables, cleanup sample for StreamIndex and StreamId, add sample KSControl * address PR-it1 comments * address comment from PR-it2, replace manual define of IKSControl by ksproxy.h * remove unuse header * address comment from PR * fix sdk to latest, add driversign algorithm * remove nudget, use submodule
Diffstat (limited to 'general')
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj76
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters22
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.cpp146
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.h46
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp925
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.h169
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.cpp245
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.h82
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp610
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.h93
-rw-r--r--general/SimpleMediaSource/MediaSource/dllMain.cpp67
-rw-r--r--general/SimpleMediaSource/MediaSource/module.def5
-rw-r--r--general/SimpleMediaSource/MediaSource/pch.cpp26
-rw-r--r--general/SimpleMediaSource/MediaSource/pch.h82
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.cpp11
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.h76
-rw-r--r--general/SimpleMediaSource/SimpleMediaSource.sln4
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj13
18 files changed, 1760 insertions, 938 deletions
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
index 47562ff7..3c5ff0de 100644
--- a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
@@ -53,7 +53,7 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -61,7 +61,7 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
@@ -69,21 +69,20 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</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>
+ <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -91,15 +90,16 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
</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>
+ <CharacterSet>Unicode</CharacterSet>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -171,8 +171,13 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <CallingConvention>Cdecl</CallingConvention>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
@@ -187,8 +192,12 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
@@ -203,8 +212,12 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
@@ -219,8 +232,12 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
@@ -237,8 +254,12 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -258,8 +279,12 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -281,7 +306,11 @@
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -301,7 +330,11 @@
<ConformanceMode>true</ConformanceMode>
<EnablePREfast>false</EnablePREfast>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <ExceptionHandling>false</ExceptionHandling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\..\..\wil\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -316,16 +349,19 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllMain.cpp" />
+ <ClCompile Include="SimpleFrameGenerator.cpp" />
<ClCompile Include="SimpleMediaSource.cpp" />
+ <ClCompile Include="SimpleMediaSourceActivate.cpp" />
<ClCompile Include="SimpleMediaStream.cpp" />
- <ClCompile Include="stdafx.cpp" />
+ <ClCompile Include="pch.cpp" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="SimpleFrameGenerator.h" />
<ClInclude Include="SimpleMediaSource.h" />
+ <ClInclude Include="SimpleMediaSourceActivate.h" />
<ClInclude Include="SimpleMediaStream.h" />
- <ClInclude Include="stdafx.h" />
+ <ClInclude Include="pch.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
+ <ImportGroup Label="ExtensionTargets" />
</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
index ffcc9853..ba0d78a1 100644
--- a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
@@ -26,22 +26,34 @@
<ClCompile Include="SimpleMediaStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="stdafx.cpp">
+ <ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="SimpleMediaSourceActivate.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleFrameGenerator.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SimpleMediaSource.h">
- <Filter>Source Files</Filter>
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleMediaSourceActivate.h">
+ <Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SimpleMediaStream.h">
- <Filter>Source Files</Filter>
+ <Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="stdafx.h">
- <Filter>Source Files</Filter>
+ <ClInclude Include="pch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleFrameGenerator.h">
+ <Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.cpp b/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.cpp
new file mode 100644
index 00000000..6adafb44
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.cpp
@@ -0,0 +1,146 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+#include "pch.h"
+
+HRESULT SimpleFrameGenerator::Initialize(_In_ IMFMediaType* pMediaType)
+{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pMediaType);
+
+ RETURN_IF_FAILED(pMediaType->GetGUID(MF_MT_SUBTYPE, &m_subType));
+ if (m_subType != MFVideoFormat_RGB32 && m_subType != MFVideoFormat_NV12)
+ {
+ RETURN_HR_MSG(MF_E_UNSUPPORTED_FORMAT, "Unsupported format: %s", winrt::to_hstring(m_subType).data());
+ }
+ MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &m_width, &m_height);
+
+ return S_OK;
+}
+
+/*:
+ 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 SimpleFrameGenerator::CreateFrame(
+ _Inout_updates_bytes_(len) BYTE* pBuf,
+ _In_ DWORD len,
+ _In_ LONG pitch,
+ _In_ ULONG rgbMask)
+{
+ if (m_subType == MFVideoFormat_RGB32)
+ {
+ DEBUG_MSG(L"RGB32 frames %s\n", winrt::to_hstring(MFVideoFormat_RGB32).data());
+
+ RETURN_IF_FAILED(_CreateRGB32Frame(pBuf, len, pitch, m_width, m_height, rgbMask));
+ }
+ else if(m_subType == MFVideoFormat_NV12)
+ {
+ DEBUG_MSG(L"NV12 frames %s \n", winrt::to_hstring(MFVideoFormat_NV12).data());
+
+ DWORD frameBuffLen = m_width * m_height * 4;
+ wil::unique_cotaskmem_ptr<BYTE[]> spBuff = wil::make_unique_cotaskmem_nothrow<BYTE[]>(frameBuffLen);
+ RETURN_IF_NULL_ALLOC(spBuff.get());
+
+ RETURN_IF_FAILED(_CreateRGB32Frame(spBuff.get(), frameBuffLen, m_width * 4, m_width, m_height, rgbMask));
+ RETURN_IF_FAILED(RGB32ToNV12Frame(spBuff.get(), frameBuffLen, m_width * 4, m_width, m_height, pBuf, len, pitch));
+ }
+ else
+ {
+ return MF_E_UNSUPPORTED_FORMAT;
+ }
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////
+// private
+
+HRESULT SimpleFrameGenerator::_CreateRGB32Frame(
+ _Inout_updates_bytes_(len) BYTE* pBuf,
+ _In_ DWORD len,
+ _In_ LONG pitch,
+ _In_ DWORD width,
+ _In_ DWORD height,
+ _In_ ULONG rgbMask )
+{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pBuf);
+
+ LONGLONG curSysTimeInS = MFGetSystemTime() / (MFTIME)10000000;
+ int offset = curSysTimeInS % height;
+
+ for (unsigned int r = 0; r < height; r++)
+ {
+ uint32_t* p = (uint32_t*)(pBuf + (r * pitch));
+ for (unsigned int c = 0; c < width; c++)
+ {
+ BYTE gray = (BYTE)r + offset;
+ *p = ((uint32_t)gray << 16 | (uint32_t)gray << 8 | (uint32_t)gray) & rgbMask;
+ p++;
+ }
+ }
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////
+// pixelFormatConverter
+
+void SimpleFrameGenerator::RGB24ToYUY2(int R, int G, int B, BYTE* pY, BYTE* pU, BYTE* pV)
+{
+ *pY = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
+ *pU = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
+ *pV = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
+}
+
+void SimpleFrameGenerator::RGB24ToY(int R, int G, int B, BYTE* pY)
+{
+ *pY = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
+}
+
+void SimpleFrameGenerator::RGB32ToNV12(BYTE RGB1[8], BYTE RGB2[8], BYTE* pY1, BYTE* pY2, BYTE* pUV)
+{
+ RGB24ToYUY2(RGB1[2], RGB1[1], RGB1[0], pY1, pUV, pUV + 1);
+ RGB24ToY(RGB1[6], RGB1[5], RGB1[4], pY1 + 1);
+ RGB24ToYUY2(RGB2[2], RGB2[1], RGB2[0], pY2, pUV, pUV + 1);
+ RGB24ToY(RGB2[6], RGB2[5], RGB2[4], pY2 + 1);
+};
+
+//////////////////////////////////////////////////
+// FrameFormatConverter
+
+HRESULT SimpleFrameGenerator::RGB32ToNV12Frame(_Inout_updates_bytes_(len) BYTE* pbBuff, ULONG cbBuff, long stride, UINT width, UINT height, BYTE* pbBuffOut, ULONG cbBuffOut, long strideOut)
+{
+ do
+ {
+ RETURN_HR_IF(E_UNEXPECTED, width * 4 * height > cbBuff);
+ RETURN_HR_IF(E_UNEXPECTED, width * 1.5 * height > cbBuffOut);
+ RETURN_HR_IF_NULL(E_INVALIDARG, pbBuff);
+
+ RETURN_HR_IF_NULL(E_INVALIDARG, pbBuffOut);
+ for (DWORD h = 0; h < height - 1; h += 2)
+ {
+ BYTE* pRGB1 = h * stride + pbBuff;
+ BYTE* pRGB2 = (h + 1) * stride + pbBuff;
+ BYTE* pY1 = h * strideOut + pbBuffOut;
+ BYTE* pY2 = (h + 1) * strideOut + pbBuffOut;
+ BYTE* pUV = (h / 2 + height) * strideOut + pbBuffOut;
+
+ for (DWORD w = 0; w < width; w += 2)
+ {
+ RGB32ToNV12(pRGB1, pRGB2, pY1, pY2, pUV);
+ pRGB1 += 8;
+ pRGB2 += 8;
+ pY1 += 2;
+ pY2 += 2;
+ pUV += 2;
+ }
+ }
+ } while (FALSE);
+
+ return S_OK;
+}
diff --git a/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.h b/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.h
new file mode 100644
index 00000000..f481ab61
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleFrameGenerator.h
@@ -0,0 +1,46 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+
+#pragma once
+#ifndef SIMPLE_FRAME_GENERATOR_H
+#define SIMPLE_FRAME_GENERATOR_H
+
+class SimpleFrameGenerator
+{
+public:
+ SimpleFrameGenerator() = default;
+ ~SimpleFrameGenerator() {};
+
+ HRESULT Initialize(_In_ IMFMediaType* pMediaType);
+
+ HRESULT CreateFrame(
+ _Inout_updates_bytes_(len) BYTE* pBuf,
+ _In_ DWORD len,
+ _In_ LONG pitch,
+ _In_ ULONG rgbMask);
+
+ // pixel format converter
+ static void RGB24ToYUY2(int R, int G, int B, BYTE* pY, BYTE* pU, BYTE* pV);
+ static void RGB24ToY(int R, int G, int B, BYTE* pY);
+ static void RGB32ToNV12(BYTE RGB1[8], BYTE RGB2[8], BYTE* pY1, BYTE* pY2, BYTE* pUV);
+
+ static HRESULT RGB32ToNV12Frame(_Inout_updates_bytes_(len) BYTE* pbBuff, ULONG cbBuff, long stride, UINT width, UINT height, BYTE* pbBuffOut, ULONG cbBuffOut, long strideOut);
+
+private:
+ HRESULT _CreateRGB32Frame(
+ _Inout_updates_bytes_(len) BYTE* pBuf,
+ _In_ DWORD len,
+ _In_ LONG pitch,
+ _In_ DWORD width,
+ _In_ DWORD height,
+ _In_ ULONG rgbMask);
+
+ UINT32 m_width = 0;
+ UINT32 m_height = 0;
+ GUID m_subType = GUID_NULL;
+
+};
+
+#endif
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
index 162fb1d8..8ff15872 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
@@ -1,526 +1,651 @@
-#include "stdafx.h"
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+#include "pch.h"
-///////////////////////////////////////////////////////////////////////////////
-HRESULT
-SimpleMediaSource::RuntimeClassInitialize(
- )
+namespace winrt::WindowsSample::implementation
{
- HRESULT hr = S_OK;
-
- RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
- RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
- RETURN_IF_FAILED (MakeAndInitialize<SimpleMediaStream>(&_stream, this));
+ /////////////////////////////////////////////////////////////////////////////////
+ HRESULT SimpleMediaSource::Initialize()
{
- ComPtr<IMFStreamDescriptor> streamDescriptor(_stream.Get()->_spStreamDesc.Get());
- RETURN_IF_FAILED (MFCreatePresentationDescriptor(NUM_STREAMS, streamDescriptor.GetAddressOf(), &_spPresentationDescriptor));
- }
+ winrt::slim_lock_guard lock(m_Lock);
- _wasStreamPreviouslySelected = false;
- _sourceState = SourceState::Stopped;
+ RETURN_IF_FAILED(_CreateSourceAttributes());
+ RETURN_IF_FAILED(MFCreateEventQueue(&m_spEventQueue));
- return hr;
-}
+ m_streamList = wilEx::make_unique_cotaskmem_array<wil::com_ptr_nothrow<SimpleMediaStream>>(NUM_STREAMS);
+ RETURN_IF_NULL_ALLOC(m_streamList.get());
-// IMFMediaEventGenerator methods.
-IFACEMETHODIMP
-SimpleMediaSource::BeginGetEvent(
- _In_ IMFAsyncCallback *pCallback,
- _In_ IUnknown *punkState
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ wil::unique_cotaskmem_array_ptr<wil::com_ptr_nothrow<IMFStreamDescriptor>> streamDescriptorList = wilEx::make_unique_cotaskmem_array<wil::com_ptr_nothrow<IMFStreamDescriptor>>(NUM_STREAMS);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+ // This example showcase one stream (i.e. NUM_STREAMS == 1),
+ // it can be extended to multiple streams by changing NUM_STREAMS
+ for (unsigned int i = 0; i < NUM_STREAMS; i++)
+ {
+ auto ptr = winrt::make_self<SimpleMediaStream>();
+ m_streamList[i] = ptr.detach();
+ RETURN_IF_FAILED(m_streamList[i]->Initialize(this, i, MFSampleAllocatorUsage_UsesProvidedAllocator));
- return hr;
-}
+ RETURN_IF_FAILED(m_streamList[i]->GetStreamDescriptor(&streamDescriptorList[i]));
+ }
-IFACEMETHODIMP
-SimpleMediaSource::EndGetEvent(
- _In_ IMFAsyncResult *pResult,
- _COM_Outptr_ IMFMediaEvent **ppEvent
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ RETURN_IF_FAILED(MFCreatePresentationDescriptor(m_streamList.size(), streamDescriptorList.get(), &m_spPresentationDescriptor));
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+ m_sourceState = SourceState::Stopped;
- return hr;
-}
+ return S_OK;
+ }
-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.
+ // IMFMediaEventGenerator methods.
+ IFACEMETHODIMP SimpleMediaSource::BeginGetEvent(
+ _In_ IMFAsyncCallback* pCallback,
+ _In_ IUnknown* punkState )
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- HRESULT hr = S_OK;
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->BeginGetEvent(pCallback, punkState));
- ComPtr<IMFMediaEventQueue> spQueue;
+ return S_OK;
+ }
+ IFACEMETHODIMP SimpleMediaSource::EndGetEvent(
+ _In_ IMFAsyncResult* pResult,
+ _COM_Outptr_ IMFMediaEvent** ppEvent
+ )
{
- auto lock = _critSec.Lock();
+ winrt::slim_lock_guard lock(m_Lock);
+
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->EndGetEvent(pResult, ppEvent));
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- spQueue = _spEventQueue;
+ return S_OK;
}
- // Now get the event.
- RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+ 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.
- return hr;
-}
+ wil::com_ptr_nothrow<IMFMediaEventQueue> spQueue;
-IFACEMETHODIMP
-SimpleMediaSource::QueueEvent(
- MediaEventType eventType,
- REFGUID guidExtendedType,
- HRESULT hrStatus,
- _In_opt_ PROPVARIANT const *pvValue
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ spQueue = m_spEventQueue;
+ }
- return hr;
-}
+ // Now get the event.
+ RETURN_IF_FAILED(spQueue->GetEvent(dwFlags, ppEvent));
-// IMFMediaSource methods
-IFACEMETHODIMP
-SimpleMediaSource::CreatePresentationDescriptor(
- _COM_Outptr_ IMFPresentationDescriptor **ppPresentationDescriptor
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ return S_OK;
+ }
- if (ppPresentationDescriptor == nullptr)
+ IFACEMETHODIMP SimpleMediaSource::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const* pvValue
+ )
{
- return E_POINTER;
- }
- *ppPresentationDescriptor = nullptr;
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spPresentationDescriptor->Clone(ppPresentationDescriptor));
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
- return hr;
-}
-
-IFACEMETHODIMP
-SimpleMediaSource::GetCharacteristics(
- _Out_ DWORD *pdwCharacteristics
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ return S_OK;
+ }
- if (nullptr == pdwCharacteristics)
+ // IMFMediaSource methods
+ IFACEMETHODIMP SimpleMediaSource::CreatePresentationDescriptor(
+ _COM_Outptr_ IMFPresentationDescriptor** ppPresentationDescriptor
+ )
{
- return E_POINTER;
- }
- *pdwCharacteristics = 0;
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
+ RETURN_HR_IF_NULL(E_POINTER, ppPresentationDescriptor);
+ *ppPresentationDescriptor = nullptr;
- return hr;
-}
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spPresentationDescriptor->Clone(ppPresentationDescriptor));
-IFACEMETHODIMP
-SimpleMediaSource::Pause(
- )
-{
- // Pause() not required/needed
- return MF_E_INVALID_STATE_TRANSITION;
-}
+ return S_OK;
+ }
+ IFACEMETHODIMP SimpleMediaSource::GetCharacteristics(
+ _Out_ DWORD* pdwCharacteristics
+ )
+ {
+ winrt::slim_lock_guard lock(m_Lock);
-IFACEMETHODIMP
-SimpleMediaSource::Shutdown(
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ RETURN_HR_IF_NULL(E_POINTER, pdwCharacteristics);
+ *pdwCharacteristics = 0;
- _sourceState = SourceState::Shutdown;
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
- _spAttributes.Reset();
- _spPresentationDescriptor.Reset();
+ return S_OK;
+ }
- if (_spEventQueue != nullptr)
+ IFACEMETHODIMP SimpleMediaSource::Pause()
{
- _spEventQueue->Shutdown();
- _spEventQueue.Reset();
+ // Pause() not required/needed
+ return MF_E_INVALID_STATE_TRANSITION;
}
- if (_stream != nullptr)
+
+ IFACEMETHODIMP SimpleMediaSource::Shutdown()
{
- _stream.Get()->Shutdown();
- _stream.Reset();
- }
+ winrt::slim_lock_guard lock(m_Lock);
- return hr;
-}
+ m_sourceState = SourceState::Shutdown;
-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;
+ m_spAttributes.reset();
+ m_spPresentationDescriptor.reset();
- if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
- {
- return E_INVALIDARG;
+ if (m_spEventQueue != nullptr)
+ {
+ m_spEventQueue->Shutdown();
+ m_spEventQueue.reset();
+ }
+
+ for(unsigned int i = 0; i < m_streamList.size(); i++)
+ {
+ m_streamList[i]->Shutdown();
+ }
+ m_streamList.reset();
+
+ return S_OK;
}
- else if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
+
+ IFACEMETHODIMP SimpleMediaSource::Start(
+ _In_ IMFPresentationDescriptor* pPresentationDescriptor,
+ _In_opt_ const GUID* pguidTimeFormat,
+ _In_ const PROPVARIANT* pvarStartPos
+ )
{
- return MF_E_UNSUPPORTED_TIME_FORMAT;
- }
+ winrt::slim_lock_guard lock(m_Lock);
+ DWORD count = 0;
+ wil::unique_prop_variant startTime;
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
+ {
+ return E_INVALIDARG;
+ }
- if (!(_sourceState != SourceState::Stopped || _sourceState != SourceState::Shutdown))
- {
- return MF_E_INVALID_STATE_TRANSITION;
- }
+ if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
+ {
+ return MF_E_UNSUPPORTED_TIME_FORMAT;
+ }
- _sourceState = SourceState::Started;
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
- // 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));
+ if (!(m_sourceState != SourceState::Stopped || m_sourceState != SourceState::Shutdown))
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+ m_sourceState = SourceState::Started;
- // Send event that the source started. Include error code in case it failed.
- RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStarted,
- GUID_NULL,
- hr,
- &startTime));
+ // 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));
- // 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;
- }
+ // 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.
+ for (unsigned int i = 0; i < count; i++)
+ {
+ BOOL selected = false;
+ wil::com_ptr_nothrow<IMFStreamDescriptor> streamDesc;
+ RETURN_IF_FAILED(pPresentationDescriptor->GetStreamDescriptorByIndex(
+ i,
+ &selected,
+ &streamDesc));
- if (selected)
- {
- ComPtr<IUnknown> spunkStream;
- MediaEventType met = (_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream);
+ DWORD streamId = 0;
+ RETURN_IF_FAILED(streamDesc->GetStreamIdentifier(&streamId));
- // 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));
+ DWORD streamIdx = 0;
+ bool wasSelected = false;
+ wil::com_ptr_nothrow<IMFStreamDescriptor> spLocalStreamDescriptor;
+ RETURN_IF_FAILED(_GetStreamDescriptorByStreamId(streamId, &streamIdx, &wasSelected, &spLocalStreamDescriptor));
+
+ if (selected)
+ {
+ // Update our internal PresentationDescriptor
+ RETURN_IF_FAILED(m_spPresentationDescriptor->SelectStream(streamIdx));
- // Send the MEUpdatedStream/MENewStream to our source event
- // queue.
- RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(met,
- GUID_NULL,
- S_OK,
- spunkStream.Get()));
+ // Update stream state
+ RETURN_IF_FAILED(m_streamList[streamIdx]->SetStreamState(MF_STREAM_STATE_RUNNING));
+ RETURN_IF_FAILED(m_streamList[streamIdx]->Start());
- // 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;
+ // Send the MEUpdatedStream/MENewStream to our source event
+ // queue.
+ wil::com_ptr_nothrow<IUnknown> spunkStream;
+ MediaEventType met = (wasSelected ? MEUpdatedStream : MENewStream);
+ RETURN_IF_FAILED(m_streamList[streamIdx]->QueryInterface(IID_PPV_ARGS(&spunkStream)));
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamUnk(
+ met,
+ GUID_NULL,
+ S_OK,
+ spunkStream.get()));
+ }
+ else if(wasSelected)
+ {
+ // stream was previously selected but not selected this time.
+ RETURN_IF_FAILED(m_spPresentationDescriptor->DeselectStream(streamIdx));
+ }
+ }
- return hr;
-}
+ // Send event that the source started. Include error code in case it failed.
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(
+ MESourceStarted,
+ GUID_NULL,
+ S_OK,
+ &startTime));
-IFACEMETHODIMP
-SimpleMediaSource::Stop(
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
- PROPVARIANT stopTime;
- DWORD count = 0;
- MF_STREAM_STATE state;
+ return S_OK;
+ }
- if (_sourceState != SourceState::Started)
+ HRESULT SimpleMediaSource::_GetStreamDescriptorByStreamId(DWORD dwStreamId, DWORD* pdwStreamIdx, bool* pSelected, IMFStreamDescriptor** ppStreamDescriptor)
{
- return MF_E_INVALID_STATE_TRANSITION;
- }
+ RETURN_HR_IF_NULL(E_POINTER, ppStreamDescriptor);
+ *ppStreamDescriptor = nullptr;
+
+ RETURN_HR_IF_NULL(E_POINTER, pdwStreamIdx);
+ *pdwStreamIdx = 0;
- _sourceState = SourceState::Stopped;
+ RETURN_HR_IF_NULL(E_POINTER, pSelected);
+ *pSelected = false;
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
- RETURN_IF_FAILED (_spPresentationDescriptor->GetStreamDescriptorCount(&count));
+ DWORD streamCount = 0;
+ RETURN_IF_FAILED(m_spPresentationDescriptor->GetStreamDescriptorCount(&streamCount));
+ for (unsigned int i = 0; i < streamCount; i++)
+ {
+ wil::com_ptr_nothrow<IMFStreamDescriptor> spStreamDescriptor;
+ BOOL selected = FALSE;
- // 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_IF_FAILED(m_spPresentationDescriptor->GetStreamDescriptorByIndex(i, &selected, &spStreamDescriptor));
- return hr;
-}
+ DWORD id = 0;
+ RETURN_IF_FAILED(spStreamDescriptor->GetStreamIdentifier(&id));
-// IMFMediaSourceEx
-IFACEMETHODIMP
-SimpleMediaSource::GetSourceAttributes(
- _COM_Outptr_ IMFAttributes** sourceAttributes
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ if (dwStreamId == id)
+ {
+ // Found the streamDescriptor with matching streamId
+ *pdwStreamIdx = i;
+ *pSelected = !!selected;
+ RETURN_IF_FAILED(spStreamDescriptor.copy_to(ppStreamDescriptor));
+ return S_OK;
+ }
+ }
- if (nullptr == sourceAttributes)
- {
- return E_POINTER;
+ return MF_E_NOT_FOUND;
}
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
-
- *sourceAttributes = nullptr;
- if (_spAttributes.Get() == nullptr)
+ IFACEMETHODIMP SimpleMediaSource::Stop()
{
- ComPtr<IMFSensorProfileCollection> profileCollection;
- ComPtr<IMFSensorProfile> profile;
-
- // Create our source attribute store.
- RETURN_IF_FAILED (MFCreateAttributes(_spAttributes.GetAddressOf(), 1));
+ winrt::slim_lock_guard lock(m_Lock);
- // Create an empty profile collection...
- RETURN_IF_FAILED (MFCreateSensorProfileCollection(&profileCollection));
+ if (m_sourceState != SourceState::Started)
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+ m_sourceState = SourceState::Stopped;
- // In this example since we have just one stream, we only have one
- // pin to add: Pin0.
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
- // 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()));
+ wil::unique_prop_variant stopTime;
+ RETURN_IF_FAILED(InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
- // 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()));
+ // Deselect the streams and send the stream stopped events.
+ for (unsigned int i = 0; i < m_streamList.size(); i++)
+ {
+ RETURN_IF_FAILED(m_streamList[i]->SetStreamState(MF_STREAM_STATE_STOPPED));
+ RETURN_IF_FAILED(m_streamList[i]->Stop());
+ RETURN_IF_FAILED(m_spPresentationDescriptor->DeselectStream(i));
+ }
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(MESourceStopped, GUID_NULL, S_OK, &stopTime));
- // Se the profile collection to the attribute store of the IMFTransform.
- RETURN_IF_FAILED (_spAttributes->SetUnknown(MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
- profileCollection.Get()));
+ return S_OK;
}
- return _spAttributes.CopyTo(sourceAttributes);
-}
+ // IMFMediaSourceEx
+ IFACEMETHODIMP SimpleMediaSource::GetSourceAttributes(_COM_Outptr_ IMFAttributes** sourceAttributes)
+ {
+ winrt::slim_lock_guard lock(m_Lock);
+ RETURN_HR_IF_NULL(E_POINTER, sourceAttributes);
+ *sourceAttributes = nullptr;
-IFACEMETHODIMP
-SimpleMediaSource::GetStreamAttributes(
- DWORD dwStreamIdentifier,
- _COM_Outptr_ IMFAttributes **ppAttributes
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
- if (ppAttributes == nullptr)
- {
- return E_POINTER;
+ RETURN_IF_FAILED(MFCreateAttributes(sourceAttributes, 1));
+ RETURN_IF_FAILED(m_spAttributes->CopyAllItems(*sourceAttributes));
+
+ return S_OK;
}
- *ppAttributes = nullptr;
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- if (dwStreamIdentifier >= NUM_STREAMS)
+ IFACEMETHODIMP SimpleMediaSource::GetStreamAttributes(
+ _In_ DWORD dwStreamIdentifier,
+ _COM_Outptr_ IMFAttributes** ppAttributes
+ )
{
- return MF_E_INVALIDSTREAMNUMBER;
+ winrt::slim_lock_guard lock(m_Lock);
+
+ RETURN_HR_IF_NULL(E_POINTER, ppAttributes);
+ *ppAttributes = nullptr;
+
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+
+ wil::com_ptr_nothrow<SimpleMediaStream> spStream;
+ RETURN_IF_FAILED(_GetMediaStreamById(dwStreamIdentifier, &spStream));
+ RETURN_IF_FAILED(spStream->m_spAttributes.copy_to(ppAttributes));
+
+ return S_OK;
}
- else
+
+ IFACEMETHODIMP SimpleMediaSource::SetD3DManager(
+ _In_opt_ IUnknown* /*pManager*/
+ )
{
- *ppAttributes = _stream.Get()->_spAttributes.Get();
- (*ppAttributes)->AddRef();
- }
+ // 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 hr;
-}
+ return E_NOTIMPL;
+ }
-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.
+ // IMFGetService methods
+ _Use_decl_annotations_
+ IFACEMETHODIMP SimpleMediaSource::GetService(
+ _In_ REFGUID guidService,
+ _In_ REFIID riid,
+ _Out_ LPVOID* ppvObject
+ )
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- return E_NOTIMPL;
-}
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
-// 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_HR_IF_NULL(E_POINTER, ppvObject);
+ *ppvObject = nullptr;
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ // We have no supported service, just return
+ // MF_E_UNSUPPORTED_SERVICE for all calls.
+ return MF_E_UNSUPPORTED_SERVICE;
+ }
- if (!ppvObject)
+ // 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
+ )
{
- return E_POINTER;
- }
- *ppvObject = NULL;
+ if (ulPropertyLength < sizeof(KSPROPERTY))
+ {
+ return E_INVALIDARG;
+ }
+
+ // 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.
+ if ((pProperty->Set != PROPSETID_SIMPLEMEDIASOURCE_CUSTOMCONTROL) || (pProperty->Id >= KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_END))
+ {
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+ }
- // We have no supported service, just return
- // MF_E_UNSUPPORTED_SERVICE for all calls.
- return MF_E_UNSUPPORTED_SERVICE;
-}
+ if (pPropertyData == NULL && ulDataLength == 0)
+ {
+ //
+ // If both PropertyData and DataLength, this function needs
+ // to return set BytesReturns to buffer size and
+ // return HRESULT_FROM_WIN32(ERROR_MORE_DATA)
+ // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ks/nf-ks-ikscontrol-ksproperty
+ //
+ RETURN_HR_IF_NULL(E_POINTER, pBytesReturned);
-// 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);
-}
+ switch (pProperty->Id)
+ {
+ case KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE:
+ *pBytesReturned = sizeof(KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S);
+ break;
-_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);
-}
+ default:
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+ break;
+ }
+ return HRESULT_FROM_WIN32(ERROR_MORE_DATA);
+ }
+ else
+ {
+ RETURN_HR_IF_NULL(E_POINTER, pPropertyData);
+ RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), ulDataLength == 0);
+ RETURN_HR_IF_NULL(E_POINTER, pBytesReturned);
-_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);
-}
+ // validate properyData length
+ switch (pProperty->Id)
+ {
+ case KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE:
+ if (ulDataLength < sizeof(KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S))
+ {
+ return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+ }
-/// Internal methods.
-HRESULT
-SimpleMediaSource::_CheckShutdownRequiresLock(
- )
-{
- if (_sourceState == SourceState::Shutdown)
+ // Set operation
+ if (0 != (pProperty->Flags & (KSPROPERTY_TYPE_SET)))
+ {
+ DEBUG_MSG(L"Set filter level KSProperty");
+ *pBytesReturned = 0;
+ for (size_t i = 0; i < m_streamList.size(); i++)
+ {
+ m_streamList[i]->SetRGBMask(((PKSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S)pPropertyData)->ColorMode);
+ *pBytesReturned = sizeof(KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S);
+ }
+ }
+ // Get operation
+ else if (0 != (pProperty->Flags & (KSPROPERTY_TYPE_GET)))
+ {
+ DEBUG_MSG(L"Get filter level KSProperty");
+ ((PKSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S)pPropertyData)->ColorMode = m_streamList[0]->GetRGBMask();
+ *pBytesReturned = sizeof(KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S);
+ }
+ else
+ {
+ return E_INVALIDARG;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return S_OK;
+ }
+
+ _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 MF_E_SHUTDOWN;
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
- if (_spEventQueue == nullptr || _stream == nullptr)
+ _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 E_UNEXPECTED;
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
- return S_OK;
-}
+ IFACEMETHODIMP SimpleMediaSource::SetDefaultAllocator(
+ _In_ DWORD dwOutputStreamID,
+ _In_ IUnknown* pAllocator)
+ {
+ winrt::slim_lock_guard lock(m_Lock);
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
-HRESULT
-SimpleMediaSource::_ValidatePresentationDescriptor(
- _In_ IMFPresentationDescriptor *pPD
- )
-{
- HRESULT hr = S_OK;
- DWORD cStreams = 0;
- bool anySelected = false;
+ wil::com_ptr_nothrow<IMFVideoSampleAllocator> spAllocator;
+ RETURN_IF_FAILED(pAllocator->QueryInterface(IID_PPV_ARGS(&spAllocator)));
+
+ wil::com_ptr_nothrow<SimpleMediaStream> spStream;
+ RETURN_IF_FAILED(_GetMediaStreamById(dwOutputStreamID, &spStream));
+ RETURN_IF_FAILED(spStream->SetSampleAllocator(spAllocator.get()));
- if (pPD == nullptr)
+ return S_OK;
+ }
+
+ IFACEMETHODIMP SimpleMediaSource::GetAllocatorUsage(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ DWORD* pdwInputStreamID,
+ _Out_ MFSampleAllocatorUsage* peUsage)
{
- return E_INVALIDARG;
+ winrt::slim_lock_guard lock(m_Lock);
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+
+ RETURN_HR_IF_NULL(E_POINTER, pdwInputStreamID);
+ RETURN_HR_IF_NULL(E_POINTER, peUsage);
+
+ wil::com_ptr_nothrow<SimpleMediaStream> spStream;
+ RETURN_IF_FAILED(_GetMediaStreamById(dwOutputStreamID, &spStream));
+
+ *peUsage = spStream->SampleAlloactorUsage();
+ *pdwInputStreamID = dwOutputStreamID;
+
+ return S_OK;
}
- // 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))
+ /// Internal methods.
+ HRESULT SimpleMediaSource::_CheckShutdownRequiresLock()
{
- return E_INVALIDARG;
+ if (m_sourceState == SourceState::Shutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (m_spEventQueue == nullptr || m_streamList.get() == nullptr)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
}
- // The caller must select at least one stream.
- for (UINT32 i = 0; i < cStreams; ++i)
+ HRESULT SimpleMediaSource::_ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor* pPD)
{
- ComPtr<IMFStreamDescriptor> spSD;
- BOOL fSelected = FALSE;
- DWORD dwId = 0;
+ DWORD cStreams = 0;
+ bool anySelected = false;
+
+ RETURN_HR_IF_NULL(E_INVALIDARG, pPD);
+
+ // The caller's PD must have the same number of streams as ours.
+ RETURN_IF_FAILED(pPD->GetStreamDescriptorCount(&cStreams));
+ if (cStreams != m_streamList.size())
+ {
+ return E_INVALIDARG;
+ }
- RETURN_IF_FAILED (pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD));
+ // The caller must select at least one stream.
+ for (UINT32 i = 0; i < cStreams; ++i)
+ {
+ wil::com_ptr_nothrow<IMFStreamDescriptor> spSD;
+ BOOL fSelected = FALSE;
- anySelected |= !!fSelected;
+ RETURN_IF_FAILED(pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD));
+ anySelected |= !!fSelected;
+ }
- RETURN_IF_FAILED (spSD->GetStreamIdentifier(&dwId));
- if (dwId >= NUM_STREAMS)
+ if (!anySelected)
{
return E_INVALIDARG;
}
+
+ return S_OK;
}
- if (!anySelected)
+ HRESULT SimpleMediaSource::_CreateSourceAttributes()
{
- return E_INVALIDARG;
+ if (m_spAttributes.get() == nullptr)
+ {
+ // Create our source attribute store.
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spAttributes, 1));
+
+ wil::com_ptr_nothrow<IMFSensorProfileCollection> profileCollection;
+ wil::com_ptr_nothrow<IMFSensorProfile> profile;
+
+ // 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: Pin = STREAM_ID.
+
+ // Legacy profile is mandatory. This is to ensure non-profile
+ // aware applications can still function, but with degraded
+ // feature sets.
+ const DWORD STREAM_ID = 0;
+ RETURN_IF_FAILED(MFCreateSensorProfile(KSCAMERAPROFILE_Legacy, 0 /*ProfileIndex*/, nullptr,
+ &profile));
+ RETURN_IF_FAILED(profile->AddProfileFilter(STREAM_ID, 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 /*ProfileIndex*/, nullptr,
+ &profile));
+ RETURN_IF_FAILED(profile->AddProfileFilter(STREAM_ID, 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(m_spAttributes->SetUnknown(
+ MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
+ profileCollection.get()));
+ }
+
+ return S_OK;
}
- return hr;
-}
+ HRESULT SimpleMediaSource::_GetMediaStreamById(_In_ DWORD dwStreamId, _COM_Outptr_ SimpleMediaStream** ppStream)
+ {
+ RETURN_HR_IF_NULL(E_POINTER, ppStream);
+ *ppStream = nullptr;
+ for (unsigned int i = 0; i < m_streamList.size(); i++)
+ {
+ if (m_streamList[i]->Id() == dwStreamId)
+ {
+ *ppStream = m_streamList[i];
+ (*ppStream)->AddRef();
+ return S_OK;
+ }
+ }
+ return MF_E_NOT_FOUND;
+ }
+}
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
index 019926c8..10ac200b 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
@@ -1,81 +1,120 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
#pragma once
+#ifndef SIMPLEMEDIASOURCE_H
+#define SIMPLEMEDIASOURCE_H
-// Represents a simple media source that only has one stream and outputs a static image
+// Example Custom Property implemented by SimpleMediaSource
+//
+// {0CE2EF73-4800-4F53-9B8E-8C06790FC0C7}
+static const GUID PROPSETID_SIMPLEMEDIASOURCE_CUSTOMCONTROL =
+{ 0xce2ef73, 0x4800, 0x4f53, { 0x9b, 0x8e, 0x8c, 0x6, 0x79, 0xf, 0xc0, 0xc7 } };
-#include "stdafx.h"
+enum
+{
+ KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE = 0,
+ KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_END // all ids must define before this.
+};
-class SimpleMediaStream;
+#define KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_GRAYSCALE 0x00FFFFFFL
+#define KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_RED 0x00FF0000L
+#define KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_GREEN 0x0000FF00L
+#define KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_BLUE 0x000000FFL
-class __declspec(uuid("{9812588D-5CE9-4E4C-ABC1-049138D10DCE}"))
-SimpleMediaSource : public RuntimeClass<
- RuntimeClassFlags<WinRtClassicComMix>,
- IMFMediaEventGenerator,
- IMFMediaSource,
- IMFMediaSourceEx,
- IMFGetService,
- IKsControl>
-{
+typedef struct {
+ ULONG StremID;
+ ULONG ColorMode;
+} KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S, * PKSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_S;
- enum class SourceState
+namespace winrt::WindowsSample::implementation
+{
+ // forward declaration
+ struct SimpleMediaStream;
+
+ struct SimpleMediaSource : winrt::implements<SimpleMediaSource, IMFMediaSourceEx, IMFGetService, IKsControl, IMFSampleAllocatorControl>
{
- Invalid, Stopped, Started, Shutdown
- };
+ SimpleMediaSource() = default;
-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);
+ private:
+ enum class SourceState
+ {
+ Invalid, Stopped, Started, Shutdown
+ };
- // 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)();
+ public:
+ // IMFMediaEventGenerator (inherits by IMFMediaSource)
+ IFACEMETHODIMP BeginGetEvent(_In_ IMFAsyncCallback* pCallback, _In_ IUnknown* punkState) override;
+ IFACEMETHODIMP EndGetEvent(_In_ IMFAsyncResult* pResult, _Out_ IMFMediaEvent** ppEvent) override;
+ IFACEMETHODIMP GetEvent(DWORD dwFlags, _Out_ IMFMediaEvent** ppEvent) override;
+ IFACEMETHODIMP QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, _In_ const PROPVARIANT* pvValue) override;
- // IMFMediaSourceEx
- IFACEMETHOD(GetSourceAttributes)(_COM_Outptr_ IMFAttributes **ppAttributes);
- IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes **ppAttributes);
- IFACEMETHOD(SetD3DManager)(_In_opt_ IUnknown *pManager);
+ // IMFMediaSource (inherits by IMFMediaSourceEx)
+ IFACEMETHODIMP CreatePresentationDescriptor(_Out_ IMFPresentationDescriptor** ppPresentationDescriptor) override;
+ IFACEMETHODIMP GetCharacteristics(_Out_ DWORD* pdwCharacteristics) override;
+ IFACEMETHODIMP Pause() override;
+ IFACEMETHODIMP Shutdown() override;
+ IFACEMETHODIMP Start(_In_ IMFPresentationDescriptor* pPresentationDescriptor, _In_ const GUID* pguidTimeFormat, _In_ const PROPVARIANT* pvarStartPosition) override;
+ IFACEMETHODIMP Stop() override;
- // IMFGetService
- IFACEMETHOD(GetService)(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID *ppvObject);
+ // IMFMediaSourceEx
+ IFACEMETHODIMP GetSourceAttributes(_COM_Outptr_ IMFAttributes** ppAttributes) override;
+ IFACEMETHODIMP GetStreamAttributes(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes** ppAttributes) override;
+ IFACEMETHODIMP SetD3DManager(_In_opt_ IUnknown* pManager) override;
- // 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();
+ // IMFGetService
+ IFACEMETHODIMP GetService(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID* ppvObject) override;
-private:
- HRESULT _CheckShutdownRequiresLock();
- HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor *pPresentationDescriptor);
+ // IKsControl
+ IFACEMETHODIMP KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned) override;
+ IFACEMETHODIMP KsMethod(
+ _In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned) override;
+ IFACEMETHODIMP 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) override;
- CriticalSection _critSec;
- SourceState _sourceState{ SourceState::Invalid };
- ComPtr<IMFMediaEventQueue> _spEventQueue;
- ComPtr<IMFPresentationDescriptor> _spPresentationDescriptor;
- ComPtr<IMFAttributes> _spAttributes;
+ // IMFSampleAllocatorControl
+ IFACEMETHODIMP SetDefaultAllocator(
+ _In_ DWORD dwOutputStreamID,
+ _In_ IUnknown* pAllocator) override;
- bool _wasStreamPreviouslySelected; // maybe makes more sense as a property of the stream
- const DWORD NUM_STREAMS = 1;
- ComPtr<SimpleMediaStream> _stream;
-};
+ IFACEMETHODIMP GetAllocatorUsage(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ DWORD* pdwInputStreamID,
+ _Out_ MFSampleAllocatorUsage* peUsage) override;
+
+ // Non-Interface functions
+ HRESULT Initialize();
+
+ private:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor* pPresentationDescriptor);
+ HRESULT _CreateSourceAttributes();
+ HRESULT _GetStreamDescriptorByStreamId(_In_ DWORD dwStreamId, _Out_ DWORD* pdwStreamIdx, _Out_ bool* pSelected, _COM_Outptr_ IMFStreamDescriptor** ppStreamDescriptor);
+ HRESULT _GetMediaStreamById(_In_ DWORD dwStreamId, _COM_Outptr_ SimpleMediaStream** ppMediaStream);
+
+ winrt::slim_mutex m_Lock;
+ SourceState m_sourceState{ SourceState::Invalid };
+
+ wil::com_ptr_nothrow<IMFMediaEventQueue> m_spEventQueue;
+ wil::com_ptr_nothrow<IMFPresentationDescriptor> m_spPresentationDescriptor;
+ wil::com_ptr_nothrow<IMFAttributes> m_spAttributes;
+ wil::unique_cotaskmem_array_ptr<wil::com_ptr_nothrow<SimpleMediaStream>> m_streamList;
+
+ const DWORD NUM_STREAMS = 1;
+ };
+}
-CoCreatableClass(SimpleMediaSource);
+#endif
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.cpp
new file mode 100644
index 00000000..16abd28d
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.cpp
@@ -0,0 +1,245 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+#include "pch.h"
+
+namespace winrt::WindowsSample::implementation
+{
+ // IMFActivate
+ IFACEMETHODIMP SimpleMediaSourceActivate::ActivateObject(REFIID riid, void** ppv)
+ {
+ RETURN_HR_IF_NULL(E_POINTER, ppv);
+ *ppv = nullptr;
+
+ wil::com_ptr_nothrow<IMFAttributes> spAttributes;
+ RETURN_IF_FAILED(MFCreateAttributes(&spAttributes, 1));
+
+ DEBUG_MSG(L"Activate SimpleMediaSource");
+ m_spSimpleMediaSrc = winrt::make_self<winrt::WindowsSample::implementation::SimpleMediaSource>();
+ RETURN_IF_FAILED(m_spSimpleMediaSrc->Initialize());
+ RETURN_IF_FAILED(m_spSimpleMediaSrc->QueryInterface(riid, ppv));
+
+ return S_OK;
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::ShutdownObject()
+ {
+ return S_OK;
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::DetachObject()
+ {
+ m_spSimpleMediaSrc = nullptr;
+ return S_OK;
+ }
+
+ // IMFAttributes (inherits by IMFActivate)
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetItem(_In_ REFGUID guidKey, _Inout_opt_ PROPVARIANT* pValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetItem(guidKey, pValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetItemType(_In_ REFGUID guidKey, _Out_ MF_ATTRIBUTE_TYPE* pType)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetItemType(guidKey, pType);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::CompareItem(_In_ REFGUID guidKey, _In_ REFPROPVARIANT Value, _Out_ BOOL* pbResult)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->CompareItem(guidKey, Value, pbResult);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::Compare(_In_ IMFAttributes* pTheirs, _In_ MF_ATTRIBUTES_MATCH_TYPE MatchType, _Out_ BOOL* pbResult)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->Compare(pTheirs, MatchType, pbResult);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetUINT32(_In_ REFGUID guidKey, _Out_ UINT32* punValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetUINT32(guidKey, punValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetUINT64(_In_ REFGUID guidKey, _Out_ UINT64* punValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetUINT64(guidKey, punValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetDouble(_In_ REFGUID guidKey, _Out_ double* pfValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetDouble(guidKey, pfValue);
+ }
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetGUID(_In_ REFGUID guidKey, _Out_ GUID* pguidValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetGUID(guidKey, pguidValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetStringLength(_In_ REFGUID guidKey, _Out_ UINT32* pcchLength)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetStringLength(guidKey, pcchLength);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetString(_In_ REFGUID guidKey, _Out_writes_(cchBufSize) LPWSTR pwszValue, _In_ UINT32 cchBufSize, _Inout_opt_ UINT32* pcchLength)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetAllocatedString(_In_ REFGUID guidKey, _Out_writes_(*pcchLength + 1) LPWSTR* ppwszValue, _Inout_ UINT32* pcchLength)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetBlobSize(_In_ REFGUID guidKey, _Out_ UINT32* pcbBlobSize)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetBlobSize(guidKey, pcbBlobSize);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetBlob(_In_ REFGUID guidKey, _Out_writes_(cbBufSize) UINT8* pBuf, UINT32 cbBufSize, _Inout_ UINT32* pcbBlobSize)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetAllocatedBlob(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8** ppBuf, __RPC__out UINT32* pcbSize)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetUnknown(__RPC__in REFGUID guidKey, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppv)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetUnknown(guidKey, riid, ppv);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetItem(_In_ REFGUID guidKey, _In_ REFPROPVARIANT Value)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetItem(guidKey, Value);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::DeleteItem(_In_ REFGUID guidKey)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->DeleteItem(guidKey);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::DeleteAllItems()
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->DeleteAllItems();
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetUINT32(_In_ REFGUID guidKey, _In_ UINT32 unValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetUINT32(guidKey, unValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetUINT64(_In_ REFGUID guidKey, _In_ UINT64 unValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetUINT64(guidKey, unValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetDouble(_In_ REFGUID guidKey, _In_ double fValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetDouble(guidKey, fValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetGUID(_In_ REFGUID guidKey, _In_ REFGUID guidValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetGUID(guidKey, guidValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetString(_In_ REFGUID guidKey, _In_ LPCWSTR wszValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetString(guidKey, wszValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetBlob(_In_ REFGUID guidKey, _In_reads_(cbBufSize) const UINT8* pBuf, UINT32 cbBufSize)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetBlob(guidKey, pBuf, cbBufSize);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::SetUnknown(_In_ REFGUID guidKey, _In_ IUnknown* pUnknown)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->SetUnknown(guidKey, pUnknown);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::LockStore()
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->LockStore();
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::UnlockStore()
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->UnlockStore();
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetCount(_Out_ UINT32* pcItems)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetCount(pcItems);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::GetItemByIndex(UINT32 unIndex, _Out_ GUID* pguidKey, _Inout_ PROPVARIANT* pValue)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->GetItemByIndex(unIndex, pguidKey, pValue);
+ }
+
+ IFACEMETHODIMP SimpleMediaSourceActivate::CopyAllItems(_In_ IMFAttributes* pDest)
+ {
+ if (!m_spActivateAttributes)
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spActivateAttributes, 1));
+ return m_spActivateAttributes->CopyAllItems(pDest);
+ }
+}
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.h b/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.h
new file mode 100644
index 00000000..f206e6d9
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSourceActivate.h
@@ -0,0 +1,82 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+#pragma once
+#ifndef SIMPLEMEDIASOURCEACTIVATE_H
+#define SIMPLEMEDIASOURCEACTIVATE_H
+
+namespace winrt::WindowsSample::implementation
+{
+ struct __declspec(uuid("9812588D-5CE9-4E4C-ABC1-049138D10DCE"))
+ SimpleMediaSourceActivate : winrt::implements<SimpleMediaSourceActivate, IMFActivate>
+ {
+ SimpleMediaSourceActivate() = default;
+
+ public:
+ // IMFActivate
+ IFACEMETHODIMP ActivateObject(REFIID riid, void** ppv) override;
+ IFACEMETHODIMP ShutdownObject() override;
+ IFACEMETHODIMP DetachObject() override;
+
+ // IMFAttributes (inherits by IMFActivate)
+ IFACEMETHODIMP GetItem(_In_ REFGUID guidKey, _Inout_opt_ PROPVARIANT* pValue) override;
+ IFACEMETHODIMP GetItemType(_In_ REFGUID guidKey, _Out_ MF_ATTRIBUTE_TYPE* pType) override;
+ IFACEMETHODIMP CompareItem(_In_ REFGUID guidKey, _In_ REFPROPVARIANT Value, _Out_ BOOL* pbResult) override;
+ IFACEMETHODIMP Compare(_In_ IMFAttributes* pTheirs, _In_ MF_ATTRIBUTES_MATCH_TYPE MatchType, _Out_ BOOL* pbResult) override;
+ IFACEMETHODIMP GetUINT32(_In_ REFGUID guidKey, _Out_ UINT32* punValue) override;
+ IFACEMETHODIMP GetUINT64(_In_ REFGUID guidKey, _Out_ UINT64* punValue) override;
+ IFACEMETHODIMP GetDouble(_In_ REFGUID guidKey, _Out_ double* pfValue) override;
+ IFACEMETHODIMP GetGUID(_In_ REFGUID guidKey, _Out_ GUID* pguidValue) override;
+ IFACEMETHODIMP GetStringLength(_In_ REFGUID guidKey, _Out_ UINT32* pcchLength) override;
+ IFACEMETHODIMP GetString(_In_ REFGUID guidKey, _Out_writes_(cchBufSize) LPWSTR pwszValue, _In_ UINT32 cchBufSize, _Inout_opt_ UINT32* pcchLength) override;
+ IFACEMETHODIMP GetAllocatedString(_In_ REFGUID guidKey, _Out_writes_(*pcchLength + 1) LPWSTR* ppwszValue, _Inout_ UINT32* pcchLength) override;
+ IFACEMETHODIMP GetBlobSize(_In_ REFGUID guidKey, _Out_ UINT32* pcbBlobSize) override;
+ IFACEMETHODIMP GetBlob(_In_ REFGUID guidKey, _Out_writes_(cbBufSize) UINT8* pBuf, UINT32 cbBufSize, _Inout_ UINT32* pcbBlobSize) override;
+ IFACEMETHODIMP GetAllocatedBlob(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8** ppBuf, __RPC__out UINT32* pcbSize) override;
+ IFACEMETHODIMP GetUnknown(__RPC__in REFGUID guidKey, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppv) override;
+ IFACEMETHODIMP SetItem(_In_ REFGUID guidKey, _In_ REFPROPVARIANT Value) override;
+ IFACEMETHODIMP DeleteItem(_In_ REFGUID guidKey) override;
+ IFACEMETHODIMP DeleteAllItems() override;
+ IFACEMETHODIMP SetUINT32(_In_ REFGUID guidKey, _In_ UINT32 unValue) override;
+ IFACEMETHODIMP SetUINT64(_In_ REFGUID guidKey, _In_ UINT64 unValue) override;
+ IFACEMETHODIMP SetDouble(_In_ REFGUID guidKey, _In_ double fValue) override;
+ IFACEMETHODIMP SetGUID(_In_ REFGUID guidKey, _In_ REFGUID guidValue) override;
+ IFACEMETHODIMP SetString(_In_ REFGUID guidKey, _In_ LPCWSTR wszValue) override;
+ IFACEMETHODIMP SetBlob(_In_ REFGUID guidKey, _In_reads_(cbBufSize) const UINT8* pBuf, UINT32 cbBufSize) override;
+ IFACEMETHODIMP SetUnknown(_In_ REFGUID guidKey, _In_ IUnknown* pUnknown) override;
+ IFACEMETHODIMP LockStore() override;
+ IFACEMETHODIMP UnlockStore() override;
+ IFACEMETHODIMP GetCount(_Out_ UINT32* pcItems) override;
+ IFACEMETHODIMP GetItemByIndex(UINT32 unIndex, _Out_ GUID* pguidKey, _Inout_ PROPVARIANT* pValue) override;
+ IFACEMETHODIMP CopyAllItems(_In_ IMFAttributes* pDest) override;
+
+ private:
+ wil::com_ptr_nothrow <IMFAttributes> m_spActivateAttributes;
+ winrt::com_ptr<winrt::WindowsSample::implementation::SimpleMediaSource> m_spSimpleMediaSrc;
+ };
+}
+
+//
+// cocreatable class
+//
+struct SimpleMediaSourceActivateFactory : public winrt::implements<SimpleMediaSourceActivateFactory, IClassFactory>
+{
+public:
+ STDMETHODIMP CreateInstance(_In_ IUnknown*, _In_ REFIID riid, _COM_Outptr_ void** result) noexcept final try
+ {
+ RETURN_HR_IF_NULL(E_POINTER, result);
+ *result = nullptr;
+
+ winrt::com_ptr<winrt::WindowsSample::implementation::SimpleMediaSourceActivate> ptr = winrt::make_self<winrt::WindowsSample::implementation::SimpleMediaSourceActivate>();
+ return ptr->QueryInterface(riid, result);
+ } CATCH_RETURN()
+
+
+ STDMETHODIMP LockServer(BOOL) noexcept final
+ {
+ return S_OK;
+ }
+};
+
+
+#endif
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
index 7685b12e..c22d7421 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
@@ -1,391 +1,403 @@
-#include "stdafx.h"
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
-#define NUM_IMAGE_ROWS 240
-#define NUM_IMAGE_COLS 320
+#include "pch.h"
+
+#define NUM_IMAGE_ROWS 480
+#define NUM_IMAGE_COLS 640
#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
- )
+namespace winrt::WindowsSample::implementation
{
- HRESULT hr = S_OK;
- ComPtr<IMFMediaTypeHandler> spTypeHandler;
- ComPtr<IMFAttributes> attrs;
-
- if (nullptr == pSource)
+ HRESULT SimpleMediaStream::Initialize(
+ _In_ SimpleMediaSource* pSource,
+ _In_ DWORD dwStreamId,
+ _In_ MFSampleAllocatorUsage allocatorUsage
+ )
{
- return E_INVALIDARG;
- }
- RETURN_IF_FAILED (pSource->QueryInterface(IID_PPV_ARGS(&_parent)));
+ wil::com_ptr_nothrow<IMFMediaTypeHandler> spTypeHandler;
+ wil::com_ptr_nothrow<IMFAttributes> attrs;
- // 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_HR_IF_NULL(E_INVALIDARG, pSource);
+ m_parent = pSource;
- RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
- RETURN_IF_FAILED (this->_SetStreamAttributes(_spAttributes.Get()));
- RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+ m_dwStreamId = dwStreamId;
+ m_allocatorUsage = allocatorUsage;
- // Initialize stream descriptors
- RETURN_IF_FAILED (MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc));
+ const uint32_t NUM_MEDIATYPES = 2;
+ wil::unique_cotaskmem_array_ptr<wil::com_ptr_nothrow<IMFMediaType>> mediaTypeList = wilEx::make_unique_cotaskmem_array<wil::com_ptr_nothrow<IMFMediaType>>(NUM_MEDIATYPES);
- RETURN_IF_FAILED (_spStreamDesc->GetMediaTypeHandler(&spTypeHandler));
- RETURN_IF_FAILED (spTypeHandler->SetCurrentMediaType(_spMediaType.Get()));
- RETURN_IF_FAILED (this->_SetStreamDescriptorAttributes(_spStreamDesc.Get()));
-
- return hr;
-}
+ // Initialize media type and set the video output media type.
+ wil::com_ptr_nothrow<IMFMediaType> spMediaType;
+ RETURN_IF_FAILED(MFCreateMediaType(&spMediaType));
+ spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+ spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
+ 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);
+ // frame size * pixle bit size * framerate
+ uint32_t bitrate = (uint32_t)(NUM_IMAGE_COLS * 1.5 * NUM_IMAGE_ROWS * 8* 30);
+ spMediaType->SetUINT32(MF_MT_AVG_BITRATE, bitrate);
+ MFSetAttributeRatio(spMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+ mediaTypeList[0] = spMediaType.detach();
-// IMFMediaEventGenerator
-IFACEMETHODIMP
-SimpleMediaStream::BeginGetEvent(
- _In_ IMFAsyncCallback *pCallback,
- _In_ IUnknown *punkState
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ 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);
+ // frame size * pixle bit size * framerate
+ bitrate = NUM_IMAGE_COLS * NUM_IMAGE_ROWS * 4 * 8* 30;
+ spMediaType->SetUINT32(MF_MT_AVG_BITRATE, bitrate);
+ MFSetAttributeRatio(spMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+ mediaTypeList[1] = spMediaType.detach();
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+ RETURN_IF_FAILED(MFCreateAttributes(&m_spAttributes, 10));
+ RETURN_IF_FAILED(_SetStreamAttributes(m_spAttributes.get()));
- return hr;
-}
+ RETURN_IF_FAILED(MFCreateEventQueue(&m_spEventQueue));
-IFACEMETHODIMP
-SimpleMediaStream::EndGetEvent(
- _In_ IMFAsyncResult *pResult,
- _COM_Outptr_ IMFMediaEvent **ppEvent
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ // Initialize stream descriptors
+ RETURN_IF_FAILED(MFCreateStreamDescriptor(m_dwStreamId /*StreamId*/, NUM_MEDIATYPES /*MT count*/, mediaTypeList.get(), &m_spStreamDesc));
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+ RETURN_IF_FAILED(m_spStreamDesc->GetMediaTypeHandler(&spTypeHandler));
+ RETURN_IF_FAILED(spTypeHandler->SetCurrentMediaType(mediaTypeList[0]));
+ RETURN_IF_FAILED(_SetStreamDescriptorAttributes(m_spStreamDesc.get()));
- return hr;
-}
+ return S_OK;
+ }
-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.
+ // IMFMediaEventGenerator
+ IFACEMETHODIMP SimpleMediaStream::BeginGetEvent(
+ _In_ IMFAsyncCallback* pCallback,
+ _In_ IUnknown* punkState
+ )
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- HRESULT hr = S_OK;
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->BeginGetEvent(pCallback, punkState));
- ComPtr<IMFMediaEventQueue> spQueue;
+ return S_OK;
+ }
+ IFACEMETHODIMP SimpleMediaStream::EndGetEvent(
+ _In_ IMFAsyncResult* pResult,
+ _COM_Outptr_ IMFMediaEvent** ppEvent
+ )
{
- auto lock = _critSec.Lock();
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- spQueue = _spEventQueue;
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->EndGetEvent(pResult, ppEvent));
+
+ return S_OK;
}
- // Now get the event.
- RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+ IFACEMETHODIMP SimpleMediaStream::GetEvent(
+ _In_ 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.
- return hr;
-}
+ wil::com_ptr_nothrow<IMFMediaEventQueue> spQueue;
-IFACEMETHODIMP
-SimpleMediaStream::QueueEvent(
- MediaEventType eventType,
- REFGUID guidExtendedType,
- HRESULT hrStatus,
- _In_opt_ PROPVARIANT const *pvValue
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ spQueue = m_spEventQueue;
+ }
- return hr;
-}
+ // Now get the event.
+ RETURN_IF_FAILED(spQueue->GetEvent(dwFlags, ppEvent));
-// IMFMediaStream
-IFACEMETHODIMP
-SimpleMediaStream::GetMediaSource(
- _COM_Outptr_ IMFMediaSource **ppMediaSource
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ return S_OK;
+ }
- if (ppMediaSource == nullptr)
+ IFACEMETHODIMP SimpleMediaStream::QueueEvent(
+ _In_ MediaEventType eventType,
+ _In_ REFGUID guidExtendedType,
+ _In_ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const* pvValue
+ )
{
- return E_POINTER;
+ winrt::slim_lock_guard lock(m_Lock);
+
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+
+ return S_OK;
}
- *ppMediaSource = nullptr;
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ // IMFMediaStream
+ IFACEMETHODIMP SimpleMediaStream::GetMediaSource(
+ _COM_Outptr_ IMFMediaSource** ppMediaSource
+ )
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- *ppMediaSource = _parent.Get();
- (*ppMediaSource)->AddRef();
+ RETURN_HR_IF_NULL(E_POINTER, ppMediaSource);
+ *ppMediaSource = nullptr;
- return hr;
-}
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED(m_parent.copy_to(ppMediaSource));
-IFACEMETHODIMP
-SimpleMediaStream::GetStreamDescriptor(
- _COM_Outptr_ IMFStreamDescriptor **ppStreamDescriptor
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ return S_OK;
+ }
- if (ppStreamDescriptor == nullptr)
+ IFACEMETHODIMP SimpleMediaStream::GetStreamDescriptor(
+ _COM_Outptr_ IMFStreamDescriptor** ppStreamDescriptor
+ )
{
- return E_POINTER;
- }
- *ppStreamDescriptor = nullptr;
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_HR_IF_NULL(E_POINTER, ppStreamDescriptor);
+ *ppStreamDescriptor = nullptr;
- if (_spStreamDesc != nullptr)
- {
- *ppStreamDescriptor = _spStreamDesc.Get();
- (*ppStreamDescriptor)->AddRef();
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
+
+ if (m_spStreamDesc != nullptr)
+ {
+ RETURN_IF_FAILED(m_spStreamDesc.copy_to(ppStreamDescriptor));
+ }
+ else
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
}
- else
+
+ IFACEMETHODIMP SimpleMediaStream::RequestSample(
+ _In_ IUnknown* pToken
+ )
{
- return E_UNEXPECTED;
- }
+ winrt::slim_lock_guard lock(m_Lock);
+ wil::com_ptr_nothrow<IMFSample> sample;
+ wil::com_ptr_nothrow<IMFMediaBuffer> outputBuffer;
+ LONG pitch = 0;
+ BYTE* bufferStart = nullptr; // not used
+ DWORD bufferLength = 0;
+ BYTE* pbuf = nullptr;
+ wil::com_ptr_nothrow<IMF2DBuffer2> buffer2D;
- return hr;
-}
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
-/*
- Writes to a buffer representing a 2D image.
- Writes a different constant to each line based on row number and current time.
+ if (m_streamState != MF_STREAM_STATE_RUNNING)
+ {
+ RETURN_HR_MSG(MF_E_INVALIDREQUEST, "Stream is not in running state, state:%d", m_streamState);
+ }
- Assumes top down image, no negative stride and pBuf points to the begnning of the buffer of length len.
+ RETURN_IF_FAILED(m_spSampleAllocator->AllocateSample(&sample));
+ RETURN_IF_FAILED(sample->GetBufferByIndex(0, &outputBuffer));
+ RETURN_IF_FAILED(outputBuffer->QueryInterface(IID_PPV_ARGS(&buffer2D)));
+ RETURN_IF_FAILED(buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write,
+ &pbuf,
+ &pitch,
+ &bufferStart,
+ &bufferLength));
+
- 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;
- }
+ RETURN_IF_FAILED(m_spFrameGenerator->CreateFrame(pbuf, bufferLength, pitch, m_rgbMask));
+ RETURN_IF_FAILED(buffer2D->Unlock2D());
- const int NUM_ROWS = len / abs(pitch);
+ 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(m_spEventQueue->QueueEventParamUnk(MEMediaSample,
+ GUID_NULL,
+ S_OK,
+ sample.get()));
- LONGLONG curSysTimeInS = MFGetSystemTime() / (MFTIME)10000000;
- int offset = curSysTimeInS % NUM_ROWS;
+ return S_OK;
+ }
- for (int r = 0; r < NUM_ROWS; r++)
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // IMFMediaStream2
+ IFACEMETHODIMP SimpleMediaStream::SetStreamState(MF_STREAM_STATE state)
{
- int grayColor = r + offset;
- memset(pBuf + (pitch * r), (BYTE)(grayColor % NUM_ROWS), pitch);
- }
+ winrt::slim_lock_guard lock(m_Lock);
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
- return S_OK;
-}
+ switch (state)
+ {
+ case MF_STREAM_STATE_PAUSED:
+ // because not supported
+ break;
-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;
+ case MF_STREAM_STATE_RUNNING:
+ m_streamState = state;
+ break;
- 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()));
+ case MF_STREAM_STATE_STOPPED:
+ m_streamState = state;
- return hr;
-}
+ break;
-//////////////////////////////////////////////////////////////////////////////////////////
-// IMFMediaStream2
-IFACEMETHODIMP
-SimpleMediaStream::SetStreamState(
- MF_STREAM_STATE state
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
- bool runningState = false;
+ default:
+ return MF_E_INVALID_STATE_TRANSITION;
+ break;
+ }
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ return S_OK;
+ }
- switch (state)
+ IFACEMETHODIMP SimpleMediaStream::GetStreamState(
+ _Out_ MF_STREAM_STATE* pState
+ )
{
- 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;
- }
+ winrt::slim_lock_guard lock(m_Lock);
+ RETURN_IF_FAILED(_CheckShutdownRequiresLock());
- _isSelected = runningState;
+ *pState = m_streamState;
-done:
- return hr;
-}
+ return S_OK;
+ }
-IFACEMETHODIMP
-SimpleMediaStream::GetStreamState(
- _Out_ MF_STREAM_STATE *pState
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
- BOOLEAN pauseState = false;
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // Public methods
+ HRESULT SimpleMediaStream::Start()
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ // Create the allocator if one doesn't exist
+ if (m_allocatorUsage == MFSampleAllocatorUsage_UsesProvidedAllocator)
+ {
+ RETURN_HR_IF_NULL_MSG(E_POINTER, m_spSampleAllocator, "Sample allocator is not set");
+ }
+ else
+ {
+ RETURN_IF_FAILED(MFCreateVideoSampleAllocatorEx(IID_PPV_ARGS(&m_spSampleAllocator)));
+ }
- if (SUCCEEDED(hr))
- {
- *pState = (_isSelected ? MF_STREAM_STATE_RUNNING : MF_STREAM_STATE_STOPPED);
- }
+ wil::com_ptr_nothrow<IMFMediaTypeHandler> spMTHandler;
+ RETURN_IF_FAILED(m_spStreamDesc->GetMediaTypeHandler(&spMTHandler));
- return hr;
-}
+ wil::com_ptr_nothrow<IMFMediaType> spMediaType;
+ UINT32 width, height;
+ GUID subType;
+ RETURN_IF_FAILED(spMTHandler->GetCurrentMediaType(&spMediaType));
+ RETURN_IF_FAILED(spMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+ MFGetAttributeSize(spMediaType.get(), MF_MT_FRAME_SIZE, &width, &height);
-HRESULT
-SimpleMediaStream::Shutdown(
- )
-{
- HRESULT hr = S_OK;
- auto lock = _critSec.Lock();
+ DEBUG_MSG(L"Initialize sample allocator for mediatype: %s, %dx%d ", winrt::to_hstring(subType).data(), width, height);
+ RETURN_IF_FAILED(m_spSampleAllocator->InitializeSampleAllocator(10, spMediaType.get()));
+ if (m_spFrameGenerator == nullptr)
+ {
+ m_spFrameGenerator = wil::make_unique_nothrow<SimpleFrameGenerator>();
+ RETURN_IF_NULL_ALLOC_MSG(m_spFrameGenerator, "Fail to create SimpleFrameGenerator");
+ }
+ RETURN_IF_FAILED(m_spFrameGenerator->Initialize(spMediaType.get()));
+
+ // Post MEStreamStarted event to signal stream has started
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(MEStreamStarted, GUID_NULL, S_OK, nullptr));
- _isShutdown = true;
- _parent.Reset();
+ return S_OK;
+ }
- if (_spEventQueue != nullptr)
+ HRESULT SimpleMediaStream::Stop()
{
- hr = _spEventQueue->Shutdown();
- _spEventQueue.Reset();
+ winrt::slim_lock_guard lock(m_Lock);
+
+ // Post MEStreamStopped event to signal stream has stopped
+ RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(MEStreamStopped, GUID_NULL, S_OK, nullptr));
+ return S_OK;
}
- _spAttributes.Reset();
- _spMediaType.Reset();
- _spStreamDesc.Reset();
+ HRESULT SimpleMediaStream::Shutdown()
+ {
+ winrt::slim_lock_guard lock(m_Lock);
- _isSelected = false;
+ m_bIsShutdown = true;
+ m_parent.reset();
- return hr;
-}
+ if (m_spEventQueue != nullptr)
+ {
+ m_spEventQueue->Shutdown();
+ m_spEventQueue.reset();
+ }
-HRESULT
-SimpleMediaStream::_CheckShutdownRequiresLock(
- )
-{
- if (_isShutdown)
- {
- return MF_E_SHUTDOWN;
+ m_spAttributes.reset();
+ m_spStreamDesc.reset();
+
+ m_streamState = MF_STREAM_STATE_STOPPED;
+
+ return S_OK;
}
- if (_spEventQueue == nullptr)
+ HRESULT SimpleMediaStream::SetSampleAllocator(IMFVideoSampleAllocator* pAllocator)
{
- return E_UNEXPECTED;
+ winrt::slim_lock_guard lock(m_Lock);
+
+ if (m_streamState == MF_STREAM_STATE_RUNNING)
+ {
+ RETURN_HR_MSG(MF_E_INVALIDREQUEST, "Cannot update allocator when the stream is streaming");
+ }
+ m_spSampleAllocator.reset();
+ m_spSampleAllocator = pAllocator;
+ return S_OK;
}
- return S_OK;
-}
-HRESULT
-SimpleMediaStream::_SetStreamAttributes(
- _In_ IMFAttributes *pAttributeStore
- )
-{
- HRESULT hr = S_OK;
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // Private methods
- if (nullptr == pAttributeStore)
+ HRESULT SimpleMediaStream::_CheckShutdownRequiresLock()
{
- return E_INVALIDARG;
+ if (m_bIsShutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (m_spEventQueue == nullptr)
+ {
+ return E_UNEXPECTED;
+
+ }
+ return S_OK;
}
- 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));
+ HRESULT SimpleMediaStream::_SetStreamAttributes(
+ _In_ IMFAttributes* pAttributeStore
+ )
+ {
+ RETURN_HR_IF_NULL(E_INVALIDARG, pAttributeStore);
- return hr;
-}
+ RETURN_IF_FAILED(pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, m_dwStreamId));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, MFFrameSourceTypes::MFFrameSourceTypes_Color));
-HRESULT
-SimpleMediaStream::_SetStreamDescriptorAttributes(
- _In_ IMFAttributes *pAttributeStore
- )
-{
- HRESULT hr = S_OK;
+ return S_OK;
+ }
- if (nullptr == pAttributeStore)
+ HRESULT SimpleMediaStream::_SetStreamDescriptorAttributes(
+ _In_ IMFAttributes* pAttributeStore
+ )
{
- return E_INVALIDARG;
+ RETURN_HR_IF_NULL(E_INVALIDARG, pAttributeStore);
+
+ RETURN_IF_FAILED(pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, m_dwStreamId));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, MFFrameSourceTypes::MFFrameSourceTypes_Color));
+
+ return S_OK;
}
- 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
index 56351f47..70d20ec3 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
@@ -1,54 +1,69 @@
-#pragma once
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
-#include "stdafx.h"
+#ifndef SIMPLEMEDIASTREAM_H
+#define SIMPLEMEDIASTREAM_H
-class SimpleMediaSource;
+#include "SimpleMediaSource.h"
-class SimpleMediaStream : public RuntimeClass<
- RuntimeClassFlags<ClassicCom>,
- IMFMediaEventGenerator,
- IMFMediaStream,
- IMFMediaStream2>
+namespace winrt::WindowsSample::implementation
{
- friend class SimpleMediaSource;
+ struct SimpleMediaStream : winrt::implements<SimpleMediaStream, IMFMediaStream2>
+ {
+ friend struct 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);
+ public:
+ // IMFMediaEventGenerator
+ IFACEMETHODIMP BeginGetEvent(IMFAsyncCallback* pCallback, IUnknown* punkState) override;
+ IFACEMETHODIMP EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** ppEvent) override;
+ IFACEMETHODIMP GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent) override;
+ IFACEMETHODIMP QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue) override;
- // IMFMediaStream
- IFACEMETHOD(GetMediaSource)(IMFMediaSource **ppMediaSource);
- IFACEMETHOD(GetStreamDescriptor)(IMFStreamDescriptor **ppStreamDescriptor);
- IFACEMETHOD(RequestSample)(IUnknown *pToken);
+ // IMFMediaStream
+ IFACEMETHODIMP GetMediaSource(IMFMediaSource** ppMediaSource) override;
+ IFACEMETHODIMP GetStreamDescriptor(IMFStreamDescriptor** ppStreamDescriptor) override;
+ IFACEMETHODIMP RequestSample(IUnknown* pToken) override;
- // IMFMediaStream2
- IFACEMETHOD(SetStreamState)(MF_STREAM_STATE state);
- IFACEMETHOD(GetStreamState)(_Out_ MF_STREAM_STATE *pState);
+ // IMFMediaStream2
+ IFACEMETHODIMP SetStreamState(_In_ MF_STREAM_STATE state) override;
+ IFACEMETHODIMP GetStreamState(_Out_ MF_STREAM_STATE* pState) override;
- // Non-interface methods.
- HRESULT RuntimeClassInitialize(_In_ SimpleMediaSource* pSource);
- HRESULT Shutdown();
+ // Non-interface methods.
+ HRESULT Initialize(_In_ SimpleMediaSource* pSource, _In_ DWORD streamId, _In_ MFSampleAllocatorUsage allocatorUsage);
+ HRESULT Start();
+ HRESULT Stop();
+ HRESULT Shutdown();
+ HRESULT SetSampleAllocator(_In_ IMFVideoSampleAllocator* pAllocator);
+ DWORD Id() const { return m_dwStreamId; }
+ MFSampleAllocatorUsage SampleAlloactorUsage() const { return m_allocatorUsage; }
-protected:
- HRESULT _CheckShutdownRequiresLock();
- HRESULT _SetStreamAttributes(IMFAttributes* pAttributeStore);
- HRESULT _SetStreamDescriptorAttributes(IMFAttributes* pAttributeStore);
+ void SetRGBMask(ULONG rgbMask) { winrt::slim_lock_guard lock(m_Lock); m_rgbMask = rgbMask; }
+ ULONG GetRGBMask() { winrt::slim_lock_guard lock(m_Lock); return m_rgbMask; }
+ protected:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _SetStreamAttributes(IMFAttributes* pAttributeStore);
+ HRESULT _SetStreamDescriptorAttributes(IMFAttributes* pAttributeStore);
- CriticalSection _critSec;
+ private:
+ winrt::slim_mutex m_Lock;
- ComPtr<IMFMediaSource> _parent;
- ComPtr<IMFMediaEventQueue> _spEventQueue;
- ComPtr<IMFAttributes> _spAttributes;
- ComPtr<IMFMediaType> _spMediaType;
- ComPtr<IMFStreamDescriptor> _spStreamDesc;
- bool _isShutdown = false;
- bool _isSelected = false;
+ wil::com_ptr_nothrow<IMFMediaSource> m_parent;
+ wil::com_ptr_nothrow<IMFMediaEventQueue> m_spEventQueue;
+ wil::com_ptr_nothrow<IMFAttributes> m_spAttributes;
+ wil::com_ptr_nothrow<IMFStreamDescriptor> m_spStreamDesc;
+ wil::com_ptr_nothrow<IMFVideoSampleAllocator> m_spSampleAllocator;
+ wistd::unique_ptr<SimpleFrameGenerator> m_spFrameGenerator;
- const DWORD STREAMINDEX = 0; // since there is only one stream
-};
+ bool m_bIsShutdown = false;
+ MF_STREAM_STATE m_streamState = MF_STREAM_STATE_STOPPED;
+ ULONG m_rgbMask = KSPROPERTY_SIMPLEMEDIASOURCE_CUSTOMCONTROL_COLORMODE_BLUE;
+ DWORD m_dwStreamId;
+ MFSampleAllocatorUsage m_allocatorUsage;
+ };
+}
+
+#endif
diff --git a/general/SimpleMediaSource/MediaSource/dllMain.cpp b/general/SimpleMediaSource/MediaSource/dllMain.cpp
index aed44eb0..f021b4aa 100644
--- a/general/SimpleMediaSource/MediaSource/dllMain.cpp
+++ b/general/SimpleMediaSource/MediaSource/dllMain.cpp
@@ -1,35 +1,68 @@
-/// <copyright file="dllmain.cpp" company="Microsoft">
-/// Copyright (c) Microsoft Corporation. All rights reserved.
-/// </copyright>
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+
// dllmain.cpp : Defines the entry point for the DLL application.
-#include "stdafx.h"
+#include "pch.h"
-#include <wrl\module.h>
+HINSTANCE g_hInst;
-#if !defined(__WRL_CLASSIC_COM__)
-STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _COM_Outptr_ IActivationFactory** factory)
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
{
- return Module<InProc>::GetModule().GetActivationFactory(activatibleClassId, factory);
-}
+ try
+ {
+ *ppv = nullptr;
+
+ if (rclsid == __uuidof(winrt::WindowsSample::implementation::SimpleMediaSourceActivate))
+ {
+ return winrt::make_self<SimpleMediaSourceActivateFactory>()->QueryInterface(riid, ppv);
+ }
+
+#ifdef _WRL_MODULE_H_
+ return ::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
+#else
+ return winrt::hresult_class_not_available().to_abi();
#endif
+ }
+ catch (...)
+ {
+ return winrt::to_hresult();
+ }
+}
-#if !defined(__WRL_WINRT_STRICT__)
-STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
+bool __stdcall winrt_can_unload_now() noexcept
{
- return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
+ if (winrt::get_module_lock())
+ {
+ return false;
+ }
+
+ winrt::clear_factory_cache();
+ return true;
}
-#endif
-STDAPI DllCanUnloadNow()
+int32_t __stdcall WINRT_CanUnloadNow() noexcept
{
- return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
+#ifdef _WRL_MODULE_H_
+ if (!::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().Terminate())
+ {
+ return 1;
+ }
+#endif
+
+ return winrt_can_unload_now() ? 0 : 1;
}
STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
{
- if (reason == DLL_PROCESS_ATTACH)
+ switch (reason)
{
- DisableThreadLibraryCalls(hinst);
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ g_hInst = hinst;
}
return TRUE;
}
diff --git a/general/SimpleMediaSource/MediaSource/module.def b/general/SimpleMediaSource/MediaSource/module.def
index ddeb3eac..16e9b4fe 100644
--- a/general/SimpleMediaSource/MediaSource/module.def
+++ b/general/SimpleMediaSource/MediaSource/module.def
@@ -1,6 +1,3 @@
-LIBRARY
-
EXPORTS
- DllGetActivationFactory PRIVATE
+ DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
DllGetClassObject PRIVATE
- DllCanUnloadNow PRIVATE
diff --git a/general/SimpleMediaSource/MediaSource/pch.cpp b/general/SimpleMediaSource/MediaSource/pch.cpp
new file mode 100644
index 00000000..e40b6b12
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/pch.cpp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+
+// pch.cpp: source file corresponding to the pre-compiled header
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
+
+namespace winrt
+{
+ template<> bool is_guid_of<IMFMediaSourceEx>(guid const& id) noexcept
+ {
+ return is_guid_of<IMFMediaSourceEx, IMFMediaSource, IMFMediaEventGenerator>(id);
+ }
+
+ template<> bool is_guid_of<IMFMediaStream2>(guid const& id) noexcept
+ {
+ return is_guid_of<IMFMediaStream2, IMFMediaStream, IMFMediaEventGenerator>(id);
+ }
+
+ template<> bool is_guid_of<IMFActivate>(guid const& id) noexcept
+ {
+ return is_guid_of<IMFActivate, IMFAttributes>(id);
+ }
+} \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/pch.h b/general/SimpleMediaSource/MediaSource/pch.h
new file mode 100644
index 00000000..dc59629c
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/pch.h
@@ -0,0 +1,82 @@
+// pch.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 <unknwn.h>
+#include <windows.h>
+#include <propvarutil.h>
+#include <ole2.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksproxy.h>
+#include <ksmedia.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <mfreadwrite.h>
+#include <nserror.h>
+#include <winmeta.h>
+#include <d3d9types.h>
+
+#define RESULT_DIAGNOSTICS_LEVEL 4 // include function name
+
+#include <wil\cppwinrt.h> // must be before the first C++ WinRT header, ref:https://github.com/Microsoft/wil/wiki/Error-handling-helpers
+#include <wil\result.h>
+#include <wil\com.h>
+
+#include "SimpleFrameGenerator.h"
+#include "SimpleMediaStream.h"
+#include "SimpleMediaSource.h"
+#include "SimpleMediaSourceActivate.h"
+
+inline void DebugPrint(LPCWSTR szFormat, ...)
+{
+ WCHAR szBuffer[MAX_PATH] = { 0 };
+
+ va_list pArgs;
+ va_start(pArgs, szFormat);
+ StringCbVPrintf(szBuffer, sizeof(szBuffer), szFormat, pArgs);
+ va_end(pArgs);
+ OutputDebugStringW(szBuffer);
+}
+
+#define DEBUG_MSG(msg,...) \
+{\
+ DebugPrint(L"[%s@%d] ", TEXT(__FUNCTION__), __LINE__);\
+ DebugPrint(msg, __VA_ARGS__);\
+ DebugPrint(L"\n");\
+}\
+
+namespace wilEx
+{
+ //template <typename T>
+ //using make_unique_cotaskmem_array = unique_any_array_ptr<typename details::element_traits<T>::type>;
+
+ template<typename T>
+ wil::unique_cotaskmem_array_ptr<T> make_unique_cotaskmem_array(size_t numOfElements)
+ {
+ wil::unique_cotaskmem_array_ptr<T> arr;
+ size_t cb = sizeof(wil::details::element_traits<T>::type) * numOfElements;
+ void* ptr = ::CoTaskMemAlloc(cb);
+ if (ptr != nullptr)
+ {
+ ZeroMemory(ptr, cb);
+ arr.reset(reinterpret_cast<typename wil::details::element_traits<T>::type*>(ptr), numOfElements);
+ }
+ return arr;
+ }
+};
+
+namespace winrt
+{
+ template<> bool is_guid_of<IMFMediaSourceEx>(guid const& id) noexcept;
+
+ template<> bool is_guid_of<IMFMediaStream2>(guid const& id) noexcept;
+
+ template<> bool is_guid_of<IMFActivate>(guid const& id) noexcept;
+};
+
+
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.cpp b/general/SimpleMediaSource/MediaSource/stdafx.cpp
deleted file mode 100644
index dc97a45b..00000000
--- a/general/SimpleMediaSource/MediaSource/stdafx.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-/// <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
deleted file mode 100644
index 73bec0b4..00000000
--- a/general/SimpleMediaSource/MediaSource/stdafx.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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/SimpleMediaSource.sln b/general/SimpleMediaSource/SimpleMediaSource.sln
index c93b8c42..f6bd620c 100644
--- a/general/SimpleMediaSource/SimpleMediaSource.sln
+++ b/general/SimpleMediaSource/SimpleMediaSource.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27703.2026
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31129.286
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleMediaSource", "MediaSource\MediaSource.vcxproj", "{43AD9BF7-E765-48FE-9826-71A8F2CB12DD}"
EndProject
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
index 38e21ccd..bb32647a 100644
--- a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
@@ -75,6 +75,7 @@
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>SimpleMediaSourceDriver</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
@@ -205,6 +206,9 @@
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
</Link>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -215,6 +219,9 @@
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
</Link>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -225,6 +232,9 @@
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
</Link>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -235,6 +245,9 @@
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
</Link>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>