summaryrefslogtreecommitdiff
path: root/avstream
diff options
context:
space:
mode:
authorAdonais Romero González <[email protected]>2024-05-06 16:21:31 -0700
committerGitHub <[email protected]>2024-05-06 16:21:31 -0700
commita74a241c664c4e1d7c0838287b34076c19d9858a (patch)
tree6ff7562612967b122acf8acf8a69c4dcfd5905db /avstream
parentdef8e8e34ed2b7b1deb2fc9112ac4255f1a0f2ba (diff)
parent15477ce52bbb6b42ca591ecdfb484cac089f89ab (diff)
Merge develop changes prior to upcoming WDK release (May 2024)
Diffstat (limited to 'avstream')
-rw-r--r--avstream/avscamera/DMFT/AvsCameraDMFT.cpp1311
-rw-r--r--avstream/avscamera/DMFT/AvsCameraDMFT.h334
-rw-r--r--avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj250
-rw-r--r--avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj.Filters57
-rw-r--r--avstream/avscamera/DMFT/AvsCameraDMFTutils.cpp805
-rw-r--r--avstream/avscamera/DMFT/Source.def5
-rw-r--r--avstream/avscamera/DMFT/basepin.cpp625
-rw-r--r--avstream/avscamera/DMFT/basepin.h568
-rw-r--r--avstream/avscamera/DMFT/common.h360
-rw-r--r--avstream/avscamera/DMFT/dllmain.cpp354
-rw-r--r--avstream/avscamera/DMFT/mftpeventgenerator.cpp234
-rw-r--r--avstream/avscamera/DMFT/mftpeventgenerator.h94
-rw-r--r--avstream/avscamera/DMFT/packages.config4
-rw-r--r--avstream/avscamera/DMFT/stdafx.h47
-rw-r--r--avstream/avscamera/DMFT/stdafxsrc.cpp4
-rw-r--r--avstream/avscamera/Package/package.VcxProj32
-rw-r--r--avstream/avscamera/README.md4
-rw-r--r--avstream/avscamera/avscamera.sln58
-rw-r--r--avstream/avscamera/mft0/AvsCameraMFT0.rc13
-rw-r--r--avstream/avscamera/mft0/AvsCameraMft0.vcxproj216
-rw-r--r--avstream/avscamera/mft0/MFT0.def13
-rw-r--r--avstream/avscamera/mft0/MFT0.idl46
-rw-r--r--avstream/avscamera/mft0/MFT0Impl.cpp2083
-rw-r--r--avstream/avscamera/mft0/MFT0Impl.h316
-rw-r--r--avstream/avscamera/mft0/MFT0clsid.h26
-rw-r--r--avstream/avscamera/mft0/SampleHelpers.h106
-rw-r--r--avstream/avscamera/mft0/dllmain.cpp192
-rw-r--r--avstream/avscamera/mft0/stdafx.h39
-rw-r--r--avstream/avscamera/mft0/stdafxsrc.cpp1
-rw-r--r--avstream/avscamera/mft0/targetver.h15
-rw-r--r--avstream/avscamera/sys/AvsCamera.vcxproj60
-rw-r--r--avstream/avscamera/sys/AvsCamera.vcxproj.Filters15
-rw-r--r--avstream/avscamera/sys/Capture.cpp1
-rw-r--r--avstream/avscamera/sys/Device.cpp1
-rw-r--r--avstream/avscamera/sys/avscamera.inxbin25260 -> 25172 bytes
-rw-r--r--avstream/avscamera/sys/hwsim.cpp3
-rw-r--r--avstream/avshws/avshws.inxbin5974 -> 6028 bytes
-rw-r--r--avstream/avshws/avshws.sln16
-rw-r--r--avstream/avshws/avshws.vcxproj160
-rw-r--r--avstream/avshws/avshws.vcxproj.Filters12
-rw-r--r--avstream/avssamp/avssamp.inxbin3256 -> 3278 bytes
-rw-r--r--avstream/avssamp/avssamp.sln14
-rw-r--r--avstream/avssamp/avssamp.vcxproj46
-rw-r--r--avstream/avssamp/avssamp.vcxproj.Filters20
-rw-r--r--avstream/sampledevicemft/SampleDeviceMft.sln14
-rw-r--r--avstream/sampledevicemft/SampleSocDeviceMFT.cpp1533
-rw-r--r--avstream/sampledevicemft/SampleSocDeviceMFT.h374
-rw-r--r--avstream/sampledevicemft/SampleSocDeviceMFTutils.cpp1320
-rw-r--r--avstream/sampledevicemft/multipinmft.vcxproj54
-rw-r--r--avstream/samplemft0/Package/package.vcxproj22
-rw-r--r--avstream/samplemft0/SampleMft0.sln22
-rw-r--r--avstream/samplemft0/SampleMft0.vcxproj28
52 files changed, 8496 insertions, 3431 deletions
diff --git a/avstream/avscamera/DMFT/AvsCameraDMFT.cpp b/avstream/avscamera/DMFT/AvsCameraDMFT.cpp
new file mode 100644
index 00000000..e12cff65
--- /dev/null
+++ b/avstream/avscamera/DMFT/AvsCameraDMFT.cpp
@@ -0,0 +1,1311 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+
+#include "stdafx.h"
+#ifdef MF_WPP
+#include "AvsCameraDMFT.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+//
+// This DeviceMFT is a stripped down implementation of the device MFT Sample present in the sample Repo
+// The original DMFT is present at https://github.com/microsoft/Windows-driver-samples/tree/main/avstream/sampledevicemft
+//
+CMultipinMft::CMultipinMft()
+: m_nRefCount( 0 ),
+ m_InputPinCount( 0 ),
+ m_OutputPinCount( 0 ),
+ m_dwWorkQueueId ( MFASYNC_CALLBACK_QUEUE_MULTITHREADED ),
+ m_lWorkQueuePriority ( 0 ),
+ m_spAttributes( nullptr ),
+ m_spSourceTransform( nullptr ),
+ m_SymbolicLink(nullptr)
+
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFAttributes> pAttributes = nullptr;
+ MFCreateAttributes( &pAttributes, 0 );
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_TRANSFORM_ASYNC, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_SA_D3D_AWARE, TRUE ), done);
+ DMFTCHECKHR_GOTO(pAttributes->SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"SampleMultiPinMft" ),done);
+ m_spAttributes = pAttributes;
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+}
+
+CMultipinMft::~CMultipinMft( )
+{
+ m_OutPins.clear();
+ SAFE_ARRAYDELETE(m_SymbolicLink);
+ m_spSourceTransform = nullptr;
+
+}
+
+IFACEMETHODIMP_(ULONG) CMultipinMft::AddRef(
+ void
+ )
+{
+ return InterlockedIncrement(&m_nRefCount);
+}
+
+IFACEMETHODIMP_(ULONG) CMultipinMft::Release(
+ void
+ )
+{
+ ULONG uCount = InterlockedDecrement(&m_nRefCount);
+
+ if ( uCount == 0 )
+ {
+ delete this;
+ }
+ return uCount;
+}
+
+IFACEMETHODIMP CMultipinMft::QueryInterface(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv
+ )
+{
+
+ HRESULT hr = S_OK;
+ *ppv = NULL;
+
+ if ((iid == __uuidof(IMFDeviceTransform)) || (iid == __uuidof(IUnknown)))
+ {
+ *ppv = static_cast< IMFDeviceTransform* >(this);
+ }
+ else if ( iid == __uuidof( IMFMediaEventGenerator ) )
+ {
+ *ppv = static_cast< IMFMediaEventGenerator* >(this);
+ }
+ else if ( iid == __uuidof( IMFShutdown ) )
+ {
+ *ppv = static_cast< IMFShutdown* >( this );
+ }
+ else if ( iid == __uuidof( IKsControl ) )
+ {
+ *ppv = static_cast< IKsControl* >( this );
+ }
+ else if ( iid == __uuidof( IMFRealTimeClientEx ) )
+ {
+ *ppv = static_cast< IMFRealTimeClientEx* >( this );
+ }
+ else
+ {
+ hr = E_NOINTERFACE;
+ goto done;
+ }
+ AddRef();
+done:
+ return hr;
+}
+
+/*++
+ Description:
+ This function is the entry point of the transform
+ The following things may be initialized here
+ 1) Query for MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL on the attributes supplied
+ 2) From the IUnknown acquired get the IMFTransform interface.
+ 3) Get the stream count.. The output streams are of consequence to the tranform.
+ The input streams should correspond to the output streams exposed by the source transform
+ acquired from the Attributes supplied.
+ 4) Get the IKSControl which is used to send KSPROPERTIES, KSEVENTS and KSMETHODS to the driver for the filer level. Store it in your filter class
+ 5) Get the OutPutStreamAttributes for the output pins of the source transform. This can further be used to QI and acquire
+ the IKSControl related to the specific pin. This can be used to send PIN level KSPROPERTIES, EVENTS and METHODS to the pins
+ 6) Create the output pins
+
+--*/
+
+IFACEMETHODIMP CMultipinMft::InitializeTransform (
+ _In_ IMFAttributes *pAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IUnknown> spFilterUnk = nullptr;
+ DWORD *pcInputStreams = NULL, *pcOutputStreams = NULL;
+ DWORD inputStreams = 0;
+ DWORD outputStreams = 0;
+ GUID* outGuids = NULL;
+ GUID streamCategory = GUID_NULL;
+ ULONG ulOutPinIndex = 0;
+ UINT32 uiSymLinkLen = 0;
+ DMFTCHECKNULL_GOTO( pAttributes, done, E_INVALIDARG );
+ //
+ // The attribute passed with MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL is the source transform. This generally represents a filter
+ // This needs to be stored so that we know the device properties. We cache it. We query for the IKSControl which is used to send
+ // controls to the driver.
+ //
+ DMFTCHECKHR_GOTO( pAttributes->GetUnknown( MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL,IID_PPV_ARGS( &spFilterUnk ) ),done );
+
+ if (SUCCEEDED(pAttributes->GetStringLength(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &uiSymLinkLen))) // Not available prior to RS5
+ {
+ m_SymbolicLink = new (std::nothrow) WCHAR[++uiSymLinkLen];
+ DMFTCHECKNULL_GOTO(m_SymbolicLink, done, E_OUTOFMEMORY);
+ DMFTCHECKHR_GOTO(pAttributes->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, m_SymbolicLink, uiSymLinkLen, &uiSymLinkLen), done);
+ }
+
+ DMFTCHECKHR_GOTO( spFilterUnk.As( &m_spSourceTransform ), done );
+
+ DMFTCHECKHR_GOTO( m_spSourceTransform.As( &m_spIkscontrol ), done );
+
+ DMFTCHECKHR_GOTO(m_spSourceTransform->GetStreamCount(&inputStreams, &outputStreams), done);
+
+ spFilterUnk = nullptr;
+
+ //
+ //The number of input pins created by the device transform should match the pins exposed by
+ //the source transform i.e. outputStreams from SourceTransform or DevProxy = Input pins of the Device MFT
+ //
+
+ if ( inputStreams > 0 || outputStreams > 0 )
+ {
+ pcInputStreams = new (std::nothrow) DWORD[ inputStreams ];
+ DMFTCHECKNULL_GOTO( pcInputStreams, done, E_OUTOFMEMORY);
+
+ pcOutputStreams = new (std::nothrow) DWORD[ outputStreams ];
+ DMFTCHECKNULL_GOTO( pcOutputStreams, done, E_OUTOFMEMORY );
+
+ DMFTCHECKHR_GOTO( m_spSourceTransform->GetStreamIDs( inputStreams, pcInputStreams,
+ outputStreams,
+ pcOutputStreams ),done );
+
+ for ( ULONG ulIndex = 0; ulIndex < outputStreams; ulIndex++ )
+ {
+ ComPtr<IMFAttributes> spInAttributes;
+ ComPtr<CInPin> spInPin;
+
+ DMFTCHECKHR_GOTO(m_spSourceTransform->GetOutputStreamAttributes(ulIndex, &spInAttributes),done);
+ spInPin = new (std::nothrow) CInPin(spInAttributes.Get(), ulIndex, this);
+ DMFTCHECKNULL_GOTO(spInPin.Get(), done, E_OUTOFMEMORY);
+
+ hr = ExceptionBoundary([&]()
+ {
+ m_InPins.push_back(spInPin.Get());
+ });
+ DMFTCHECKHR_GOTO(hr, done);
+ DMFTCHECKHR_GOTO(spInPin->Init(m_spSourceTransform.Get()), done);
+ }
+
+ //
+ // Create one on one mapping
+ //
+ for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
+ {
+
+ ComPtr<CInPin> spInPin = (CInPin*)m_InPins[ulIndex].Get();
+
+ if (spInPin.Get())
+ {
+ ComPtr<COutPin> spOutPin;
+ ComPtr<IKsControl> spKscontrol;
+ GUID pinGuid = GUID_NULL;
+ UINT32 uiFrameSourceType = 0;
+
+ DMFTCHECKHR_GOTO(spInPin.As(&spKscontrol), done); // Grab the IKSControl off the input pin
+ DMFTCHECKHR_GOTO(spInPin->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinGuid), done); // Get the Stream Category. Advertise on the output pin
+
+
+ spOutPin = new (std::nothrow) COutPin(
+ ulIndex,
+ this,
+ spKscontrol.Get()); // Create the output pin
+ DMFTCHECKNULL_GOTO(spOutPin.Get(), done, E_OUTOFMEMORY);
+
+ DMFTCHECKHR_GOTO(spOutPin->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, pinGuid), done); // Advertise the Stream category to the Pipeline
+ DMFTCHECKHR_GOTO(spOutPin->SetUINT32(MF_DEVICESTREAM_STREAM_ID, ulIndex), done);
+ if (SUCCEEDED(spInPin->GetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, &uiFrameSourceType)))
+ {
+ DMFTCHECKHR_GOTO(spOutPin->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, uiFrameSourceType), done);
+ }
+
+ hr = BridgeInputPinOutputPin(spInPin.Get(), spOutPin.Get());
+ if (SUCCEEDED(hr))
+ {
+ DMFTCHECKHR_GOTO(ExceptionBoundary([&]()
+ {
+ m_OutPins.push_back(spOutPin.Get());
+ }), done);
+ ulOutPinIndex++;
+ }
+ DMFTCHECKHR_GOTO(hr, done);
+ }
+ }
+
+ }
+
+ m_InputPinCount = ULONG ( m_InPins.size() );
+ m_OutputPinCount = ULONG ( m_OutPins.size() );
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!",hr,hr);
+
+ if ( pcInputStreams )
+ {
+ delete[ ] ( pcInputStreams );
+ }
+ if ( pcOutputStreams )
+ {
+ delete[ ] ( pcOutputStreams );
+ }
+ if ( outGuids )
+ {
+ delete [] ( outGuids );
+ }
+ if ( FAILED( hr ) )
+ {
+ //Release the pins and the resources acquired
+ m_InPins.clear();
+ m_OutPins.clear();
+ //
+ // Simply clear the custom pins since the input pins must have deleted the pin
+ //
+ m_spSourceTransform = nullptr;
+ m_spIkscontrol = nullptr;
+ }
+ return hr;
+}
+
+
+IFACEMETHODIMP CMultipinMft::SetWorkQueueEx(
+ _In_ DWORD dwWorkQueueId,
+ _In_ LONG lWorkItemBasePriority
+ )
+/*++
+ Description:
+
+ Implements IMFRealTimeClientEx::SetWorkQueueEx function
+
+--*/
+{
+ CAutoLock lock( m_critSec );
+ //
+ // Cache the WorkQueuId and WorkItemBasePriority. This is called once soon after the device MFT is initialized
+ //
+ m_dwWorkQueueId = dwWorkQueueId;
+ m_lWorkQueuePriority = lWorkItemBasePriority;
+ // Set it on the pins
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_InPins.size(); dwIndex++)
+ {
+ m_InPins[dwIndex]->SetWorkQueue(dwWorkQueueId);
+ }
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_OutPins.size(); dwIndex++)
+ {
+ m_OutPins[dwIndex]->SetWorkQueue(dwWorkQueueId);
+ }
+ return S_OK;
+
+}
+
+//
+// IMFDeviceTransform functions
+//
+IFACEMETHODIMP CMultipinMft::GetStreamCount(
+ _Inout_ DWORD *pdwInputStreams,
+ _Inout_ DWORD *pdwOutputStreams
+ )
+/*++
+ Description: Implements IMFTransform::GetStreamCount function
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+ DMFTCHECKNULL_GOTO(pdwInputStreams, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pdwOutputStreams, done, E_INVALIDARG);
+ *pdwInputStreams = m_InputPinCount;
+ *pdwOutputStreams = m_OutputPinCount;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+done:
+ return hr;
+}
+
+//
+//Doesn't strictly conform to the GetStreamIDs on IMFTransform Interface!
+//
+IFACEMETHODIMP CMultipinMft::GetStreamIDs(
+ _In_ DWORD dwInputIDArraySize,
+ _When_(dwInputIDArraySize >= m_InputPinCount, _Out_writes_(dwInputIDArraySize)) DWORD* pdwInputIDs,
+ _In_ DWORD dwOutputIDArraySize,
+ _When_(dwOutputIDArraySize >= m_OutputPinCount && (pdwInputIDs && (dwInputIDArraySize > 0)),
+ _Out_writes_(dwOutputIDArraySize)) _On_failure_(_Valid_) DWORD* pdwOutputIDs
+ )
+/*++
+ Description:
+ Implements IMFTransform::GetStreamIDs function
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+ if ( ( dwInputIDArraySize < m_InputPinCount ) && ( dwOutputIDArraySize < m_OutputPinCount ) )
+ {
+ hr = MF_E_BUFFERTOOSMALL;
+ goto done;
+ }
+
+ if ( dwInputIDArraySize )
+ {
+ DMFTCHECKNULL_GOTO( pdwInputIDs, done, E_POINTER );
+ for ( DWORD dwIndex = 0; dwIndex < ((dwInputIDArraySize > m_InputPinCount) ? m_InputPinCount:
+ dwInputIDArraySize); dwIndex++ )
+ {
+ pdwInputIDs[ dwIndex ] = ( m_InPins[dwIndex] )->streamId();
+ }
+ }
+
+ if ( dwOutputIDArraySize )
+ {
+ DMFTCHECKNULL_GOTO( pdwOutputIDs, done, E_POINTER );
+ for ( DWORD dwIndex = 0; dwIndex < ((dwOutputIDArraySize > m_OutputPinCount)? m_OutputPinCount:
+ dwOutputIDArraySize); dwIndex++ )
+ {
+ pdwOutputIDs[ dwIndex ] = (m_OutPins[ dwIndex ])->streamId();
+ }
+ }
+done:
+ return hr;
+}
+
+/*++
+Name: CMultipinMft::GetInputAvailableType
+Description:
+Implements IMFTransform::GetInputAvailableType function. This function
+gets the media type supported by the specified stream based on the
+index dwTypeIndex.
+--*/
+IFACEMETHODIMP CMultipinMft::GetInputAvailableType(
+ _In_ DWORD dwInputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType
+ )
+{
+ HRESULT hr = S_OK;
+
+ ComPtr<CInPin> spiPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO( spiPin, done, MF_E_INVALIDSTREAMNUMBER );
+
+ *ppMediaType = nullptr;
+
+ hr = spiPin->GetOutputAvailableType( dwTypeIndex,ppMediaType );
+
+ if (FAILED(hr))
+ {
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Pin: %d Index: %d exiting %!HRESULT!",
+ dwInputStreamID,
+ dwTypeIndex,
+ hr);
+ }
+
+done:
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetOutputAvailableType(
+ _In_ DWORD dwOutputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputAvailableType function. This function
+ gets the media type supported by the specified stream based on the
+ index dwTypeIndex.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin( dwOutputStreamID );
+
+ DMFTCHECKNULL_GOTO( spoPin.Get(), done, MF_E_INVALIDSTREAMNUMBER );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+
+ *ppMediaType = nullptr;
+
+ hr = spoPin->GetOutputAvailableType( dwTypeIndex, ppMediaType );
+
+ if ( FAILED( hr ) )
+ {
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Pin: %d Index: %d exiting %!HRESULT!",
+ dwOutputStreamID,
+ dwTypeIndex,
+ hr );
+ }
+
+done:
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetInputCurrentType(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+ Implements IMFTransform::GetInputCurrentType function. This function
+ returns the current media type set on the specified stream.
+--*/
+{
+ //
+ // The input current types will not come to this transform.
+ // The outputs of this transform matter. The DTM manages the
+ // output of this transform and the inptuts of the source transform
+ //
+ UNREFERENCED_PARAMETER(dwInputStreamID);
+ UNREFERENCED_PARAMETER(ppMediaType);
+ return S_OK;
+}
+
+IFACEMETHODIMP CMultipinMft::GetOutputCurrentType(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputCurrentType function. This function
+ returns the current media type set on the specified stream.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin;
+ CAutoLock lock( m_critSec );
+
+ DMFTCHECKNULL_GOTO( ppMediaType, done, E_INVALIDARG );
+
+ *ppMediaType = nullptr;
+
+ spoPin = GetOutPin( dwOutputStreamID );
+
+ DMFTCHECKNULL_GOTO(spoPin, done, MF_E_INVALIDSTREAMNUMBER );
+
+ DMFTCHECKHR_GOTO(spoPin->getMediaType( ppMediaType ),done );
+
+ DMFTCHECKNULL_GOTO( *ppMediaType, done, MF_E_TRANSFORM_TYPE_NOT_SET );
+
+done:
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ return hr;
+}
+
+
+IFACEMETHODIMP CMultipinMft::ProcessEvent(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFMediaEvent* pEvent
+ )
+ /*++
+ Description:
+
+ Implements IMFTransform::ProcessEvent function. This function
+ processes events that come to the MFT.
+
+ --*/
+{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
+ UNREFERENCED_PARAMETER(pEvent);
+ return S_OK;
+}
+
+
+
+IFACEMETHODIMP CMultipinMft::ProcessMessage(
+ _In_ MFT_MESSAGE_TYPE eMessage,
+ _In_ ULONG_PTR ulParam
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::ProcessMessage function. This function
+ processes messages coming to the MFT.
+
+--*/
+{
+ HRESULT hr = S_OK;
+
+ UNREFERENCED_PARAMETER(ulParam);
+
+ CAutoLock _lock( m_critSec );
+
+ switch ( eMessage )
+ {
+ case MFT_MESSAGE_COMMAND_FLUSH:
+ //
+ // This is MFT wide flush.. Flush all output pins
+ //
+ (VOID)FlushAllStreams();
+ break;
+ case MFT_MESSAGE_COMMAND_DRAIN:
+ //
+ // There is no draining for Device MFT. Just kept here for reference
+ //
+ break;
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
+ //
+ // No op for device MFTs
+ //
+ break;
+ case MFT_MESSAGE_SET_D3D_MANAGER:
+ {
+ if ( ulParam )
+ {
+ ComPtr< IDirect3DDeviceManager9 > spD3D9Manager;
+ ComPtr< IMFDXGIDeviceManager > spDXGIManager;
+
+ hr = ( ( IUnknown* ) ulParam )->QueryInterface( IID_PPV_ARGS( &spD3D9Manager ) );
+ if ( SUCCEEDED( hr ) )
+ {
+ m_spDeviceManagerUnk = ( IUnknown* )ulParam;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! IDirect3DDeviceManager9 %p, is passed", spD3D9Manager.Get() );
+ }
+ else
+ {
+ hr = ( ( IUnknown* ) ulParam )->QueryInterface( IID_PPV_ARGS( &spDXGIManager ) );
+ if ( SUCCEEDED(hr) )
+ {
+ m_spDeviceManagerUnk = (IUnknown*)ulParam;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! IMFDXGIDeviceManager %p, is passed", spDXGIManager.Get());
+ }
+ }
+ }
+ else
+ {
+ m_spDeviceManagerUnk = nullptr;
+ hr = S_OK;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC!IDirect3DDeviceManager9 was not passed in");
+ }
+ //
+ // set it on the pins. Can happen anytime
+ //
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_InPins.size(); dwIndex++)
+ {
+ m_InPins[dwIndex]->SetD3DManager(m_spDeviceManagerUnk.Get());
+ }
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_OutPins.size(); dwIndex++)
+ {
+ m_OutPins[dwIndex]->SetD3DManager(m_spDeviceManagerUnk.Get());
+ }
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
+ {
+ SetStreamingState( DeviceStreamState_Run );
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_END_STREAMING:
+ {
+ SetStreamingState(DeviceStreamState_Stop);
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
+ {
+ SetStreamingState(DeviceStreamState_Stop);
+ }
+ break;
+ default:
+ ;
+ }
+
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::ProcessInput(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFSample* pSample,
+ _In_ DWORD dwFlags
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::ProcessInput function.This function is called
+ when the sourcetransform has input to feed. the pins will try to deliver the
+ samples to the active output pins conencted. if none are connected then just
+ returns the sample back to the source transform
+
+--*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER( dwFlags );
+ CAutoLock lock(m_critSec);
+
+ ComPtr<CInPin> spInPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO(spInPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ if ( !IsStreaming() )
+ {
+ goto done;
+ }
+
+ DMFTCHECKHR_GOTO(spInPin->SendSample( pSample ), done );
+done:
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ //
+ //@@@@ README : There is a bug in the sample that the device transform manager which manages the
+ // device MFT does not release the sample after passing it to Device MFT in processInput like it should. The
+ // Device MFT therefore unfortunately has to make sure that the sample that leaves processoutput has a reference count of 1
+ //
+ SAFE_RELEASE(pSample);
+ return hr;
+
+}
+
+IFACEMETHODIMP CMultipinMft::ProcessOutput(
+ _In_ DWORD dwFlags,
+ _In_ DWORD cOutputBufferCount,
+ _Inout_updates_(cOutputBufferCount) MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
+ _Out_ DWORD *pdwStatus
+)
+/*++
+Description:
+
+Implements IMFTransform::ProcessOutput function. This is called by the DTM when
+the DT indicates it has samples to give. The DTM will send enough MFT_OUTPUT_DATA_BUFFER
+pointers to be filled up as is the number of output pins available. The DT should traverse its
+output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the samples available
+
+--*/
+{
+ HRESULT hr = S_OK;
+ BOOL gotOne = false;
+ ComPtr<COutPin> spOpin;
+ UNREFERENCED_PARAMETER( dwFlags );
+
+ if (cOutputBufferCount > m_OutputPinCount )
+ {
+ DMFTCHECKHR_GOTO( E_INVALIDARG, done );
+ }
+ *pdwStatus = 0;
+
+ for ( DWORD i = 0; i < cOutputBufferCount; i++ )
+ {
+ DWORD dwStreamID = pOutputSamples[i].dwStreamID;
+ {
+ CAutoLock _lock(m_critSec);
+ spOpin = nullptr;
+ spOpin = GetOutPin(dwStreamID);
+ GUID pinGuid = GUID_NULL;
+ DMFTCHECKNULL_GOTO(spOpin.Get(), done, E_INVALIDARG);
+ }
+ if ( SUCCEEDED(spOpin->ProcessOutput( dwFlags, &pOutputSamples[i],
+ pdwStatus ) ) )
+ {
+ if (pOutputSamples[i].pSample)
+ {
+ ProcessMetadata(pOutputSamples[i].pSample);
+ }
+ gotOne = true;
+ }
+ }
+ if (gotOne)
+ {
+ hr = S_OK;
+ }
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetInputStreamAttributes(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFAttributes** ppAttributes
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetInputStreamAttributes function. This function
+ gets the specified input stream's attributes.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> spIPin;
+ CAutoLock Lock(m_critSec);
+
+ DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG );
+ *ppAttributes = nullptr;
+
+ spIPin = GetInPin( dwInputStreamID );
+
+ DMFTCHECKNULL_GOTO(spIPin, done, E_INVALIDARG );
+
+ hr = spIPin->getPinAttributes(ppAttributes);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetOutputStreamAttributes(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFAttributes** ppAttributes
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputStreamAttributes function. This function
+ gets the specified output stream's attributes.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin;
+ CAutoLock Lock(m_critSec);
+
+ DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
+
+ *ppAttributes = nullptr;
+
+ spoPin = GetOutPin(dwOutputStreamID);
+
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG );
+
+ DMFTCHECKHR_GOTO(spoPin->getPinAttributes(ppAttributes), done );
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+_Requires_no_locks_held_
+IFACEMETHODIMP CMultipinMft::SetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::SetInputStreamState function.
+ Sets the input stream state.
+
+ The control lock is not taken here. The lock is taken for operations on
+ output pins. This operation is a result of the DT notifying the DTM that
+ output pin change has resulted in the need for the input to be changed. In
+ this case the DTM sends a getpreferredinputstate and then this call
+
+ --*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> spiPin = GetInPin(dwStreamID);
+ CAutoLock Lock(m_critSec);
+
+ DMFTCHECKNULL_GOTO(spiPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ DMFTCHECKHR_GOTO(spiPin->SetInputStreamState(pMediaType, value, dwFlags),done);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> piPin = GetInPin(dwStreamID);
+
+ DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ *value = piPin->GetState();
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+IFACEMETHODIMP CMultipinMft::SetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState state,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::SetOutputStreamState function.
+ Sets the output stream state. This is called whenever the stream
+ is selected or deslected i.e. started or stopped.
+
+ The control lock taken here and this operation should be atomic.
+ This function should check the input pins connected to the output pin
+ switch off the state of the input pin. Check if any other Pin connected
+ to the input pin is in a conflicting state with the state requested on this
+ output pin. Accordinly it calculates the media type to be set on the input pin
+ and the state to transition into. It then might recreate the other output pins
+ connected to it
+ --*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwFlags);
+ CAutoLock Lock(m_critSec);
+
+ DMFTCHECKHR_GOTO(ChangeMediaTypeEx(dwStreamID, pMediaType, state),done);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *pState
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::GetOutputStreamState function.
+ Gets the output stream state.
+ Called by the DTM to checks states. Atomic operation. needs a lock
+ --*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(pState, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(spoPin, done, MF_E_INVALIDSTREAMNUMBER);
+ *pState = spoPin->GetState();
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::GetInputStreamPreferredState(
+ _In_ DWORD dwStreamID,
+ _Inout_ DeviceStreamState *value,
+ _Outptr_opt_result_maybenull_ IMFMediaType **ppMediaType
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::GetInputStreamPreferredState function.
+ Gets the preferred state and the media type to be set on the input pin.
+ The lock is not held as this will always be called only when we notify
+ DTM to call us. We notify DTM only from the context on operations
+ happening on the output pin
+ --*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+ ComPtr<CInPin> spiPin = GetInPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(spiPin, done, MF_E_INVALIDSTREAMNUMBER);
+ hr = spiPin->GetInputStreamPreferredState(value, ppMediaType);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::FlushInputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::FlushInputStream function.
+ --*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwStreamIndex);
+ UNREFERENCED_PARAMETER(dwFlags);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::FlushOutputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::FlushOutputStream function.
+ Called by the DTM to flush streams
+ --*/
+{
+
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwFlags);
+ CAutoLock Lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin(dwStreamIndex);
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG);
+ DeviceStreamState oldState = spoPin->SetState(DeviceStreamState_Disabled);
+ DMFTCHECKHR_GOTO(spoPin->FlushQueues(),done);
+ spoPin->SetState(oldState);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+/*++
+ Description:
+
+ Called when the Device Transform gets a MFT_MESSAGE_COMMAND_FLUSH. We drain all the queues.
+ This is called in device source when the source gets end of streaming.
+ --*/
+IFACEMETHODIMP_(VOID) CMultipinMft::FlushAllStreams(
+ VOID
+ )
+{
+ DeviceStreamState oldState;
+ CAutoLock Lock(m_critSec);
+ for ( DWORD dwIndex = 0, dwSize = (DWORD)m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
+ {
+ ComPtr<COutPin> spoPin = (COutPin *)m_OutPins[dwIndex].Get();
+ oldState = spoPin->SetState(DeviceStreamState_Disabled);
+ spoPin->FlushQueues();
+ //
+ //Restore state
+ //
+ spoPin->SetState(oldState);
+ }
+}
+
+//
+// IKsControl interface functions
+//
+IFACEMETHODIMP CMultipinMft::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pvPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pulBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsProperty function.
+ used to pass control commands to the driver (generally)
+ This can be used to intercepted the control to figure out
+ if it needs to be propogated to the driver or not
+ --*/
+{
+ HRESULT hr = S_OK;
+
+ DMFTCHECKHR_GOTO(m_spIkscontrol->KsProperty(pProperty,
+ ulPropertyLength,
+ pvPropertyData,
+ ulDataLength,
+ pulBytesReturned),done);
+done:
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::KsMethod(
+ _In_reads_bytes_(ulPropertyLength) PKSMETHOD pMethod,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pvPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pulBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsMethod function. We can trap ksmethod calls here.
+ --*/
+{
+ HRESULT hr = S_OK;
+
+ DMFTCHECKHR_GOTO(m_spIkscontrol->KsMethod(
+ pMethod,
+ ulPropertyLength,
+ pvPropertyData,
+ ulDataLength,
+ pulBytesReturned
+ ), done);
+done:
+ return hr;
+}
+
+IFACEMETHODIMP CMultipinMft::KsEvent(
+ _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsEvent function.
+ --*/
+{
+
+ HRESULT hr = S_OK;
+ // Handle the events here if you want, This sample passes the events to the driver
+ DMFTCHECKHR_GOTO(m_spIkscontrol->KsEvent(pEvent,
+ ulEventLength,
+ pEventData,
+ ulDataLength,
+ pBytesReturned), done);
+done:
+ return hr;
+}
+
+//
+// HELPER FUNCTIONS
+//
+
+//
+// A lock here could mean a deadlock because this will be called when the lock is already held
+// in another thread.
+//
+CInPin* CMultipinMft::GetInPin(
+ _In_ DWORD dwStreamId
+)
+{
+ CInPin *inPin = NULL;
+ for (DWORD dwIndex = 0, dwSize = (DWORD)m_InPins.size(); dwIndex < dwSize; dwIndex++)
+ {
+ inPin = (CInPin *)m_InPins[dwIndex].Get();
+ if (dwStreamId == inPin->streamId())
+ {
+ break;
+ }
+ inPin = NULL;
+ }
+ return inPin;
+}
+
+COutPin* CMultipinMft::GetOutPin(
+ _In_ DWORD dwStreamId
+ )
+{
+ COutPin *outPin = NULL;
+ for ( DWORD dwIndex = 0, dwSize = (DWORD) m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
+ {
+ outPin = ( COutPin * )m_OutPins[ dwIndex ].Get();
+
+ if ( dwStreamId == outPin->streamId() )
+ {
+ break;
+ }
+
+ outPin = NULL;
+ }
+
+ return outPin;
+}
+_Requires_lock_held_(m_Critsec)
+HRESULT CMultipinMft::GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin)
+{
+ HRESULT hr = S_OK;
+ map<int, int>::iterator it = m_outputPinMap.find(ulOutpin);
+ if (it != m_outputPinMap.end())
+ {
+ ulInPin = it->second;
+ }
+ else
+ {
+ hr = MF_E_INVALIDSTREAMNUMBER;
+ }
+ return hr;
+}
+
+//
+// The Below function changes media type on the pins exposed by device MFT
+//
+__requires_lock_held(m_critSec)
+HRESULT CMultipinMft::ChangeMediaTypeEx(
+ _In_ ULONG pinId,
+ _In_opt_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState reqState
+)
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin = GetOutPin(pinId);
+ ComPtr<CInPin> spinPin;
+ DeviceStreamState oldOutPinState, oldInputStreamState, newOutStreamState, newRequestedInPinState;
+ ComPtr<IMFMediaType> pFullType, pInputMediaType;
+ ULONG ulInPinId = 0;
+ DWORD dwFlags = 0;
+
+
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG);
+
+ if (pMediaType)
+ {
+ if (!spoPin->IsMediaTypeSupported(pMediaType, &pFullType))
+ {
+ DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
+ }
+ }
+
+ DMFTCHECKHR_GOTO(GetConnectedInpin(pinId, ulInPinId), done);
+ spinPin = GetInPin(ulInPinId); // Get the input pin
+
+ (VOID)spinPin->getMediaType(&pInputMediaType);
+ oldInputStreamState = spinPin->SetState(DeviceStreamState_Disabled); // Disable input pin
+ oldOutPinState = spoPin->SetState(DeviceStreamState_Disabled); // Disable output pin
+ (void)spoPin->FlushQueues(); // Flush the output queues
+ (void)spinPin->FlushQueues(); // Flush the input queues
+ newOutStreamState = pinStateTransition[oldOutPinState][reqState]; // New state needed
+
+ // The Old input and the output pin states should be the same
+ newRequestedInPinState = newOutStreamState;
+
+ if ((newOutStreamState != oldOutPinState) /*State change*/
+ ||((pFullType.Get() != nullptr) && (pInputMediaType.Get()!=nullptr) && (S_OK != (pFullType->IsEqual(pInputMediaType.Get(), &dwFlags)))) /*Media Types dont match*/
+ ||((pFullType == nullptr)||(pInputMediaType == nullptr))/*Either one of the mediatypes is null*/
+ )
+ {
+ //
+ // State has change or media type has changed so we need to change the media type on the
+ // underlying kernel pin
+ //
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Changing Mediatype on the input ");
+ spinPin->setPreferredMediaType(pFullType.Get());
+ spinPin->setPreferredStreamState(newRequestedInPinState);
+ // Let the pipline know that the input needs to be changed.
+ SendEventToManager(METransformInputStreamStateChanged, GUID_NULL, spinPin->streamId());
+ //
+ // The media type will be set on the input pin by the time we return from the wait
+ //
+ m_critSec.Unlock();
+ hr = spinPin->WaitForSetInputPinMediaChange();
+ m_critSec.Lock();
+ // Change the media type on the output..
+ DMFTCHECKHR_GOTO(spoPin->ChangeMediaTypeFromInpin( pMediaType , reqState), done);
+ //
+ // Notify the pipeline that the output stream media type has changed
+ //
+ DMFTCHECKHR_GOTO(SendEventToManager(MEUnknown, MEDeviceStreamCreated, spoPin->streamId()), done);
+ spoPin->SetFirstSample(TRUE);
+ }
+ else
+ {
+ // Restore back old states as we have nothing to do
+ spinPin->SetState(oldInputStreamState);
+ spoPin->SetState(oldOutPinState);
+ }
+
+
+done:
+ return hr;
+}
+
+//
+// The below function sends events to the pipeline.
+//
+
+HRESULT CMultipinMft::SendEventToManager(
+ _In_ MediaEventType eventType,
+ _In_ REFGUID pGuid,
+ _In_ UINT32 context
+ )
+ /*++
+ Description:
+ Used to send the event to DTM.
+ --*/
+ {
+ HRESULT hr = S_OK;
+ ComPtr<IMFMediaEvent> pEvent = nullptr;
+
+ DMFTCHECKHR_GOTO(MFCreateMediaEvent(eventType, pGuid, S_OK, NULL, &pEvent ),done);
+ DMFTCHECKHR_GOTO(pEvent->SetUINT32(MF_EVENT_MFT_INPUT_STREAM_ID, (ULONG)context),done);
+ DMFTCHECKHR_GOTO(QueueEvent(pEvent.Get()),done);
+ done:
+
+ return hr;
+ }
+/*++
+Description:
+This function connects the input and output pins.
+Any media type filtering can happen here
+--*/
+HRESULT CMultipinMft::BridgeInputPinOutputPin(
+ _In_ CInPin* piPin,
+ _In_ COutPin* poPin
+ )
+{
+ HRESULT hr = S_OK;
+ ULONG ulIndex = 0;
+ ULONG ulAddedMediaTypeCount = 0;
+ ComPtr<IMFMediaType> spMediaType;
+
+ DMFTCHECKNULL_GOTO( piPin, done, E_INVALIDARG );
+ DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
+
+ while ( SUCCEEDED( hr = piPin->GetMediaTypeAt( ulIndex++, spMediaType.ReleaseAndGetAddressOf() )))
+ {
+ DMFTCHECKHR_GOTO(hr = poPin->AddMediaType(NULL, spMediaType.Get() ), done );
+ ulAddedMediaTypeCount++;
+ }
+
+ if (ulAddedMediaTypeCount == 0)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Make Sure Pin %d has one media type exposed ", piPin->streamId());
+ DMFTCHECKHR_GOTO( MF_E_INVALID_STREAM_DATA, done );
+ }
+ //
+ //Add the Input Pin to the output Pin
+ //
+ DMFTCHECKHR_GOTO(poPin->AddPin(piPin->streamId()), done);
+ hr = ExceptionBoundary([&](){
+ //
+ // Add the output pin to the input pin.
+ // Create the pin map. So that we know which pin input pin is connected to which output pin
+ //
+ piPin->ConnectPin(poPin);
+ m_outputPinMap.insert(std::pair< int, int >(poPin->streamId(), piPin->streamId()));
+ });
+done:
+ //
+ //Failed adding media types
+ //
+ if (FAILED(hr))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_ERROR, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ }
+ return hr;
+}
+
+//
+// IMFShutdown interface functions
+//
+
+/*++
+Description:
+Implements the Shutdown from IMFShutdown
+--*/
+IFACEMETHODIMP CMultipinMft::Shutdown(
+ void
+ )
+{
+ CAutoLock Lock(m_critSec);
+
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_InPins.size(); ulIndex < ulSize; ulIndex++ )
+ {
+ CInPin *pInPin = static_cast<CInPin *>(m_InPins[ulIndex].Get());
+
+ // Deref on the connected outpins to break reference loop
+ (VOID)pInPin->ShutdownPin();
+ }
+ return ShutdownEventGenerator();
+}
+
+//
+// Static method to create an instance of the MFT.
+//
+HRESULT CMultipinMft::CreateInstance(REFIID iid, void **ppMFT)
+{
+ HRESULT hr = S_OK;
+ ComPtr<CMultipinMft> spMFT;
+ DMFTCHECKNULL_GOTO(ppMFT, done, E_POINTER);
+ spMFT = new (std::nothrow) CMultipinMft();
+ DMFTCHECKNULL_GOTO(spMFT.Get(), done, E_OUTOFMEMORY);
+
+ DMFTCHECKHR_GOTO(spMFT->QueryInterface(iid, ppMFT), done);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
diff --git a/avstream/avscamera/DMFT/AvsCameraDMFT.h b/avstream/avscamera/DMFT/AvsCameraDMFT.h
new file mode 100644
index 00000000..27b8607b
--- /dev/null
+++ b/avstream/avscamera/DMFT/AvsCameraDMFT.h
@@ -0,0 +1,334 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+
+#pragma once
+#include "common.h"
+#include "mftpeventgenerator.h"
+#include "basepin.h"
+
+//
+// The Below GUID is needed to transfer photoconfirmation sample successfully in the pipeline
+// It is used to propagate the mediatype of the sample to the pipeline which will consume the sample
+// This attribute is known to the OS, but not publicly defined.
+//
+
+DEFINE_GUID(MFSourceReader_SampleAttribute_MediaType_priv,
+ 0x0ea5c1e8, 0x9845, 0x41e0, 0xa2, 0x43, 0x72, 0x32, 0x07, 0xfc, 0x78, 0x1f);
+
+
+interface IDirect3DDeviceManager9;
+
+//
+// Forward declarations
+//
+class CMFAttributes;
+class CPinCreationFactory;
+//
+// CMultipinMft class:
+// Implements a device proxy MFT.
+//
+class CMultipinMft :
+ public IMFDeviceTransform
+ , public IMFShutdown
+ , public CMediaEventGenerator
+ , public IMFRealTimeClientEx
+ , public IKsControl
+ , public CDMFTModuleLifeTimeManager
+{
+ friend class CPinCreationFactory;
+public:
+ CMultipinMft(
+ void );
+
+ virtual ~CMultipinMft();
+
+ //
+ // IUnknown
+ //
+ IFACEMETHODIMP_(ULONG) AddRef(
+ void );
+
+ IFACEMETHODIMP_(ULONG) Release(
+ void );
+
+ IFACEMETHODIMP QueryInterface(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv);
+
+
+ //
+ // IMFDeviceTransform functions
+ //
+ IFACEMETHODIMP GetStreamCount (
+ _Inout_ DWORD *pdwInputStreams,
+ _Inout_ DWORD *pdwOutputStreams);
+
+
+ IFACEMETHODIMP GetStreamIDs (
+ _In_ DWORD dwInputIDArraySize,
+ _When_(dwInputIDArraySize >= m_InputPinCount, _Out_writes_(dwInputIDArraySize)) DWORD* pdwInputIDs,
+ _In_ DWORD dwOutputIDArraySize,
+ _When_(dwOutputIDArraySize >= m_OutputPinCount && (pdwInputIDs && (dwInputIDArraySize > 0)),
+ _Out_writes_(dwOutputIDArraySize)) _On_failure_(_Valid_) DWORD* pdwOutputIDs
+ );
+
+ IFACEMETHODIMP GetInputStreamAttributes(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFAttributes** ppAttributes);
+
+ IFACEMETHODIMP GetOutputStreamAttributes(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFAttributes** ppAttributes);
+
+ IFACEMETHODIMP GetInputAvailableType(
+ _In_ DWORD dwInputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppType);
+
+ IFACEMETHODIMP GetOutputAvailableType(
+ _In_ DWORD dwOutputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType);
+
+ IFACEMETHODIMP GetInputCurrentType(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFMediaType** ppMediaType);
+
+ IFACEMETHODIMP GetOutputCurrentType(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFMediaType** ppMediaType);
+
+ IFACEMETHODIMP ProcessMessage(
+ _In_ MFT_MESSAGE_TYPE eMessage,
+ _In_ ULONG_PTR ulParam );
+
+ IFACEMETHODIMP ProcessEvent(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFMediaEvent *pEvent);
+
+
+ IFACEMETHODIMP ProcessInput(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFSample* pSample,
+ _In_ DWORD dwFlags );
+
+ IFACEMETHODIMP ProcessOutput(
+ _In_ DWORD dwFlags,
+ _In_ DWORD cOutputBufferCount,
+ _Inout_updates_(cOutputBufferCount) MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
+ _Out_ DWORD *pdwStatus );
+
+ //
+ // IMFRealTimeClientEx
+ //
+ IFACEMETHODIMP RegisterThreadsEx(
+ _Inout_ DWORD* pdwTaskIndex,
+ _In_ LPCWSTR wszClassName,
+ _In_ LONG lBasePriority )
+ {
+ UNREFERENCED_PARAMETER(pdwTaskIndex);
+ UNREFERENCED_PARAMETER(wszClassName);
+ UNREFERENCED_PARAMETER(lBasePriority);
+ return S_OK;
+ }
+
+ IFACEMETHODIMP UnregisterThreads()
+ {
+ return S_OK;
+ }
+
+ IFACEMETHODIMP SetWorkQueueEx(
+ _In_ DWORD dwWorkQueueId,
+ _In_ LONG lWorkItemBasePriority );
+
+ //
+ // IMFShutdown
+ //
+ IFACEMETHODIMP Shutdown(
+ void );
+
+ IFACEMETHODIMP GetShutdownStatus(
+ MFSHUTDOWN_STATUS *pStatus)
+ {
+ UNREFERENCED_PARAMETER(pStatus);
+ return(m_eShutdownStatus);
+ };
+
+ //
+ // IMFDeviceTransform function declarations
+ //
+ IFACEMETHODIMP InitializeTransform(
+ _In_ IMFAttributes *pAttributes );
+
+ _Requires_no_locks_held_
+ IFACEMETHODIMP SetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags );
+
+ IFACEMETHODIMP GetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value );
+
+ IFACEMETHODIMP SetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags );
+
+ IFACEMETHODIMP GetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value );
+
+ IFACEMETHODIMP GetInputStreamPreferredState(
+ _In_ DWORD dwStreamID,
+ _Inout_ DeviceStreamState *value,
+ _Outptr_opt_result_maybenull_ IMFMediaType **ppMediaType );
+
+ IFACEMETHODIMP FlushInputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags );
+
+ IFACEMETHODIMP FlushOutputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags );
+
+ IFACEMETHODIMP_(VOID) FlushAllStreams(
+ VOID
+ );
+
+ //
+ //IKSControl Inferface function declarations
+ //
+ IFACEMETHODIMP KsEvent(
+ _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+ IFACEMETHODIMP KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+ IFACEMETHODIMP KsMethod(
+ _In_reads_bytes_(ulPropertyLength) PKSMETHOD pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+
+ static HRESULT CreateInstance(
+ REFIID iid, void **ppMFT);
+
+ __inline BOOL isPhotoModePhotoSequence()
+ {
+ return m_PhotoModeIsPhotoSequence;
+ }
+
+ __inline DWORD GetQueueId()
+ {
+ return m_dwWorkQueueId;
+ }
+
+ //
+ //Will be used from Pins to get the D3D manager once set!!!
+ //
+ __inline IFACEMETHODIMP_(VOID) GetD3DDeviceManager(
+ IUnknown** ppDeviceManagerUnk
+ )
+ {
+ m_spDeviceManagerUnk.CopyTo( ppDeviceManagerUnk );
+ }
+
+ HRESULT SendEventToManager(
+ _In_ MediaEventType,
+ _In_ REFGUID,
+ _In_ UINT32
+ );
+
+protected:
+
+ //
+ //Helper functions
+ //
+
+ CInPin* GetInPin(
+ _In_ DWORD dwStreamID
+ );
+
+ COutPin* GetOutPin(
+ _In_ DWORD dwStreamID
+ );
+
+ HRESULT GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin);
+
+ __requires_lock_held(m_critSec)
+ HRESULT ChangeMediaTypeEx(
+ _In_ ULONG pinId,
+ _In_opt_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState newState
+ );
+ HRESULT BridgeInputPinOutputPin(
+ _In_ CInPin* pInPin,
+ _In_ COutPin* pOutPin);
+ //
+ //Inline functions
+ //
+
+ __inline IMFDeviceTransform* Parent()
+ {
+ return m_spSourceTransform.Get();
+ }
+
+ __inline VOID SetStreamingState(DeviceStreamState state)
+ {
+ InterlockedExchange((LONG*)&m_StreamingState, state);
+ }
+
+ __inline DeviceStreamState GetStreamingState()
+ {
+ return (DeviceStreamState)InterlockedCompareExchange((LONG*)&m_StreamingState, 0L, 0L);
+ }
+
+ __inline BOOL IsStreaming()
+ {
+ return (InterlockedCompareExchange((LONG*)&m_StreamingState, DeviceStreamState_Run, DeviceStreamState_Run) == DeviceStreamState_Run);
+ }
+
+private:
+ ULONG m_InputPinCount;
+ ULONG m_OutputPinCount;
+ ULONG m_CustomPinCount;
+ DeviceStreamState m_StreamingState;
+ CBasePinArray m_OutPins;
+ CBasePinArray m_InPins;
+ BOOL m_PhotoModeIsPhotoSequence; // used to store if the filter is in photo sequence or not
+ long m_nRefCount; // Reference count
+ CCritSec m_critSec; // Control lock.. taken only durign state change operations
+ ComPtr <IUnknown> m_spDeviceManagerUnk; // D3D Manager set, when MFT_MESSAGE_SET_D3D_MANAGER is called through ProcessMessage
+ ComPtr<IMFDeviceTransform> m_spSourceTransform; // The sources transform. This is the pipeline DevProxy
+ MFSHUTDOWN_STATUS m_eShutdownStatus;
+ DWORD m_dwWorkQueueId;
+ LONG m_lWorkQueuePriority;
+ UINT32 m_punValue;
+ ComPtr<IKsControl> m_spIkscontrol;
+ ComPtr<IMFAttributes> m_spAttributes;
+ map<int, int> m_outputPinMap; // How output pins are connected to input pins i-><0..outpins>
+ PWCHAR m_SymbolicLink;
+};
+
+
+
+inline HRESULT MFT_CreateInstance(REFIID riid, void **ppv)
+{
+ return CMultipinMft::CreateInstance(riid, ppv);
+}
+
+
diff --git a/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj b/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj
new file mode 100644
index 00000000..3f6180f2
--- /dev/null
+++ b/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E77657CD-A270-49E1-823A-8A14FF8596C8}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <SupportsPackaging>false</SupportsPackaging>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{D6CB33D6-DEF2-497E-A72D-6E6E29C67F48}</SampleGuid>
+ <ProjectName>AvsCameraDMFT</ProjectName>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <ClCompile Include="mftpeventgenerator.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppTraceFunction>DMFTRACE(FLAG,LEVEL,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
+ </ClCompile>
+ <ClCompile Include="AvsCameraDMFT.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppTraceFunction>DMFTRACE(FLAG,LEVEL,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
+ </ClCompile>
+ <ClCompile Include="basepin.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppTraceFunction>DMFTRACE(FLAG,LEVEL,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
+ </ClCompile>
+ <ClCompile Include="AvsCameraDMFTutils.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppTraceFunction>DMFTRACE(FLAG,LEVEL,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
+ </ClCompile>
+ <ClCompile Include="dllmain.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppTraceFunction>DMFTRACE(FLAG,LEVEL,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
+ </ClCompile>
+ </ItemGroup>
+ <PropertyGroup>
+ <TargetName>AvsCameraDMFT</TargetName>
+ <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\wil\include</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafxsrc.cpp">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Include="Source.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="basepin.h" />
+ <ClInclude Include="common.h" />
+ <ClInclude Include="mftpeventgenerator.h" />
+ <ClInclude Include="AvsCameraDMFT.h" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj.Filters b/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj.Filters
new file mode 100644
index 00000000..c3679c84
--- /dev/null
+++ b/avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj.Filters
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{39379DB7-5CE0-407A-A6D4-F2F23BB3BF3C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{05E63691-6953-4F79-BEC2-1CF881B618BA}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{B10F4398-9892-4AA8-8653-E5A7F4726726}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="basepin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllmain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="mftpeventgenerator.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="AvsCameraDMFT.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="AvsCameraDMFTutils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafxsrc.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <None Include="Source.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="basepin.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="mftpeventgenerator.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="AvsCameraDMFT.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/avstream/avscamera/DMFT/AvsCameraDMFTutils.cpp b/avstream/avscamera/DMFT/AvsCameraDMFTutils.cpp
new file mode 100644
index 00000000..4a4c75fc
--- /dev/null
+++ b/avstream/avscamera/DMFT/AvsCameraDMFTutils.cpp
@@ -0,0 +1,805 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#include "stdafx.h"
+
+#pragma comment(lib, "d2d1")
+#ifdef MF_WPP
+#include "AvsCameraDMFTutils.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+
+// Critical sections
+
+CCritSec::CCritSec()
+{
+ InitializeCriticalSection(&m_criticalSection);
+}
+
+CCritSec::~CCritSec()
+{
+ DeleteCriticalSection(&m_criticalSection);
+}
+
+_Requires_lock_not_held_(m_criticalSection) _Acquires_lock_(m_criticalSection)
+void CCritSec::Lock()
+{
+ EnterCriticalSection(&m_criticalSection);
+}
+
+_Requires_lock_held_(m_criticalSection) _Releases_lock_(m_criticalSection)
+void CCritSec::Unlock()
+{
+ LeaveCriticalSection(&m_criticalSection);
+}
+
+
+_Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::CAutoLock(CCritSec& crit)
+{
+ m_pCriticalSection = &crit;
+ m_pCriticalSection->Lock();
+}
+_Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::CAutoLock(CCritSec* crit)
+{
+ m_pCriticalSection = crit;
+ m_pCriticalSection->Lock();
+}
+_Releases_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::~CAutoLock()
+{
+ m_pCriticalSection->Unlock();
+}
+
+//
+//Some utility functions..
+/*++
+ Description:
+ Helper function to return back if the Pin is in stopped stateo or not
+--*/
+STDMETHODIMP_(BOOL) IsPinStateInActive( _In_ DeviceStreamState state)
+{
+ if ((state == DeviceStreamState_Disabled) ||
+ (state == DeviceStreamState_Stop))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+#ifndef IF_EQUAL_RETURN
+#define IF_EQUAL_RETURN(param, val) if(val == param) return #val
+#endif
+
+#define checkAdjustBufferCap(a,len){\
+ char* tStore = NULL; \
+if (a && strlen(a) > ((len * 7) / 10)){\
+ tStore = a; \
+ len *= 2; \
+ a = new (std::nothrow) char[len]; \
+if (!a){\
+goto done;}\
+ a[0] = 0; \
+ strcat_s(a, len, tStore); \
+ delete(tStore); }\
+}
+
+//
+// Queue implementation
+//
+CPinQueue::CPinQueue(_In_ DWORD dwPinId, _In_ IMFDeviceTransform* pParent) :
+ m_dwInPinId(dwPinId), m_pTransform(pParent), m_cRef(1)
+
+/*
+Description
+dwPinId is the input pin Id to which this queue corresponds
+*/
+{
+ m_streamCategory = GUID_NULL;
+}
+CPinQueue::~CPinQueue()
+{
+}
+
+/*++
+Description:
+ Insert sample into the list once we reach the open queue
+--*/
+STDMETHODIMP CPinQueue::Insert(_In_ IMFSample* pSample)
+{
+ HRESULT hr = ExceptionBoundary([&]() {
+ m_sampleList.push_back(pSample);
+ });
+
+ if (SUCCEEDED(hr) && m_pTransform)
+ {
+ hr = reinterpret_cast<CMultipinMft*>(m_pTransform)->QueueEvent(METransformHaveOutput, GUID_NULL, S_OK, NULL);
+ }
+
+ if (FAILED(hr))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ // There is a bug in the pipeline that doesn't release the sample fed from processinput. We have to explicitly release the sample here
+ SAFE_RELEASE(pSample);
+ }
+ return hr;
+}
+
+
+/*++
+Description:
+ This extracts the first sample from the queue. called from Pin's ProcessOutput
+--*/
+
+STDMETHODIMP CPinQueue::Remove(_Outptr_result_maybenull_ IMFSample** ppSample)
+{
+ HRESULT hr = S_OK;
+ DMFTCHECKNULL_GOTO(ppSample, done, E_INVALIDARG);
+ *ppSample = nullptr;
+
+ if (!m_sampleList.empty())
+ {
+ *ppSample = m_sampleList.front().Detach();
+ }
+
+ DMFTCHECKNULL_GOTO(*ppSample, done, MF_E_TRANSFORM_NEED_MORE_INPUT);
+ m_sampleList.erase(m_sampleList.begin());
+done:
+ return hr;
+}
+
+/*++
+Description:
+ Empties the Queue. used by the flush
+--*/
+VOID CPinQueue::Clear()
+{
+ while (!Empty())
+ {
+ ComPtr<IMFSample> spSample;
+ Remove(spSample.GetAddressOf());
+ }
+}
+
+// Handle Metadata
+
+#if (NTDDI_VERSION >= NTDDI_WINBLUE)
+/////////////////////////////////////////////////////////////////////
+//
+// Handle the Metadata with the buffer
+//
+
+HRESULT ParseMetadata_FaceDetection(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+);
+
+HRESULT ParseMetadata_PreviewAggregation(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+);
+
+HRESULT ParseMetadata_ImageAggregation(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+);
+
+HRESULT ParseMetadata_Histogram(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+);
+
+HRESULT ProcessMetadata(_In_ IMFSample* pSample)
+{
+ ComPtr<IMFAttributes> spMetadata;
+ ComPtr<IMFSample> spSample = pSample;
+ HRESULT hr = spSample->GetUnknown(MFSampleExtension_CaptureMetadata, IID_PPV_ARGS(spMetadata.ReleaseAndGetAddressOf()));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ ComPtr<IMFMediaBuffer> spBuffer;
+ hr = spMetadata->GetUnknown(MF_CAPTURE_METADATA_FRAME_RAWSTREAM, IID_PPV_ARGS(spBuffer.ReleaseAndGetAddressOf()));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ MediaBufferLock bufferLock(spBuffer.Get());
+ BYTE* pData = NULL;
+ DWORD dwLength = 0;
+ hr = bufferLock.LockBuffer(&pData, NULL, &dwLength);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ // OEM put meta data passing logic here,
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ LONG lBufferLeft = static_cast<LONG>(dwLength);
+ if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
+ {
+ return E_UNEXPECTED;
+ }
+
+ PKSCAMERA_METADATA_ITEMHEADER pItem = (PKSCAMERA_METADATA_ITEMHEADER)pData;
+
+ while (lBufferLeft > 0)
+ {
+ switch (pItem->MetadataId)
+ {
+ case MetadataId_Custom_PreviewAggregation:
+ hr = ParseMetadata_PreviewAggregation(pItem, spMetadata.Get());
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ break;
+ case MetadataId_Custom_ImageAggregation:
+ hr = ParseMetadata_ImageAggregation(pItem, spMetadata.Get());
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ break;
+ case MetadataId_Custom_Histogram:
+ hr = ParseMetadata_Histogram(pItem, spMetadata.Get());
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ break;
+ case MetadataId_Custom_FaceDetection:
+ hr = ParseMetadata_FaceDetection(pItem, spMetadata.Get());
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (!pItem->Size)
+ {
+ // 0 size item will cause the loop to break and
+ // we will report buffer malformated
+ break;
+ }
+ lBufferLeft -= (LONG)pItem->Size;
+ if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
+ {
+ break;
+ }
+ pItem = reinterpret_cast<PKSCAMERA_METADATA_ITEMHEADER>
+ (reinterpret_cast<PBYTE>(pItem) + pItem->Size);
+ }
+
+ if (lBufferLeft != 0)
+ {
+ //Check and log for malformated data
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
+}
+
+HRESULT ParseMetadata_PreviewAggregation(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+)
+{
+ HRESULT hr = S_OK;
+ if (pItem->Size < sizeof(CAMERA_METADATA_PREVIEWAGGREGATION))
+ {
+ return E_UNEXPECTED;
+ }
+
+ PCAMERA_METADATA_PREVIEWAGGREGATION pFixedStruct =
+ (PCAMERA_METADATA_PREVIEWAGGREGATION)pItem;
+
+ if (pFixedStruct->Data.FocusState.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_FOCUSSTATE,
+ pFixedStruct->Data.FocusState.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.ExposureTime.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT64(
+ MF_CAPTURE_METADATA_EXPOSURE_TIME,
+ pFixedStruct->Data.ExposureTime.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.ISOSpeed.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_ISO_SPEED,
+ pFixedStruct->Data.ISOSpeed.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.LensPosition.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_LENS_POSITION,
+ pFixedStruct->Data.LensPosition.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.FlashOn.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_FLASH,
+ pFixedStruct->Data.FlashOn.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.WhiteBalanceMode.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_WHITEBALANCE,
+ pFixedStruct->Data.WhiteBalanceMode.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.EVCompensation.Set)
+ {
+ CapturedMetadataExposureCompensation EVCompensation;
+
+ EVCompensation.Flags = pFixedStruct->Data.EVCompensation.Flags;
+ EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
+
+ hr = pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
+ (const UINT8*)&EVCompensation,
+ sizeof(EVCompensation));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.SensorFrameRate.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT64(
+ MF_CAPTURE_METADATA_SENSORFRAMERATE,
+ pFixedStruct->Data.SensorFrameRate.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.IsoAnalogGain.Set ||
+ pFixedStruct->Data.IsoDigitalGain.Set)
+ {
+ CapturedMetadataISOGains IsoGains;
+
+ if (pFixedStruct->Data.IsoAnalogGain.Set)
+ {
+ IsoGains.AnalogGain =
+ FLOAT(pFixedStruct->Data.IsoAnalogGain.Numerator) /
+ FLOAT(pFixedStruct->Data.IsoAnalogGain.Denominator);
+ }
+ if (pFixedStruct->Data.IsoDigitalGain.Set)
+ {
+ IsoGains.DigitalGain =
+ FLOAT(pFixedStruct->Data.IsoDigitalGain.Numerator) /
+ FLOAT(pFixedStruct->Data.IsoDigitalGain.Denominator);
+ }
+
+ hr = pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_ISO_GAINS,
+ (const UINT8*)&IsoGains,
+ sizeof(IsoGains));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.WhiteBalanceGain_R.Set ||
+ pFixedStruct->Data.WhiteBalanceGain_G.Set ||
+ pFixedStruct->Data.WhiteBalanceGain_B.Set)
+ {
+ CapturedMetadataWhiteBalanceGains WhiteBalanceGains;
+
+ if (pFixedStruct->Data.WhiteBalanceGain_R.Set)
+ {
+ WhiteBalanceGains.R =
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Denominator);
+ }
+ if (pFixedStruct->Data.WhiteBalanceGain_G.Set)
+ {
+ WhiteBalanceGains.G =
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Denominator);
+ }
+ if (pFixedStruct->Data.WhiteBalanceGain_B.Set)
+ {
+ WhiteBalanceGains.B =
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Denominator);
+ }
+
+ hr = pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_WHITEBALANCE_GAINS,
+ (const UINT8*)&WhiteBalanceGains,
+ sizeof(WhiteBalanceGains));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT ParseMetadata_ImageAggregation(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+)
+{
+ HRESULT hr = S_OK;
+ if (pItem->Size < sizeof(CAMERA_METADATA_IMAGEAGGREGATION))
+ {
+ return E_UNEXPECTED;
+ }
+
+ PCAMERA_METADATA_IMAGEAGGREGATION pFixedStruct =
+ (PCAMERA_METADATA_IMAGEAGGREGATION)pItem;
+
+ if (pFixedStruct->Data.FrameId.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_REQUESTED_FRAME_SETTING_ID,
+ pFixedStruct->Data.FrameId.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.ExposureTime.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT64(
+ MF_CAPTURE_METADATA_EXPOSURE_TIME,
+ pFixedStruct->Data.ExposureTime.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.ISOSpeed.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_ISO_SPEED,
+ pFixedStruct->Data.ISOSpeed.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.LensPosition.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_LENS_POSITION,
+ pFixedStruct->Data.LensPosition.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.SceneMode.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT64(
+ MF_CAPTURE_METADATA_SCENE_MODE,
+ pFixedStruct->Data.SceneMode.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.FlashOn.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_FLASH,
+ pFixedStruct->Data.FlashOn.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.FlashPower.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_FLASH_POWER,
+ pFixedStruct->Data.FlashPower.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.WhiteBalanceMode.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_WHITEBALANCE,
+ pFixedStruct->Data.WhiteBalanceMode.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.ZoomFactor.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_ZOOMFACTOR,
+ pFixedStruct->Data.ZoomFactor.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.EVCompensation.Set)
+ {
+ CapturedMetadataExposureCompensation EVCompensation;
+
+ EVCompensation.Flags = pFixedStruct->Data.EVCompensation.Flags;
+ EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
+
+ hr = pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
+ (const UINT8*)&EVCompensation,
+ sizeof(EVCompensation));
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+
+ if (pFixedStruct->Data.FocusState.Set)
+ {
+ hr = pMetaDataAttributes->SetUINT32(
+ MF_CAPTURE_METADATA_FOCUSSTATE,
+ pFixedStruct->Data.FocusState.Value);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ }
+ return S_OK;
+}
+#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
+struct HistogramData
+{
+ HistogramDataHeader Header;
+ ULONG Color[256];
+
+ HistogramData()
+ {
+ Header.Size = sizeof(*this);
+ Header.ChannelMask = 0;
+ Header.Linear = 1;
+ RtlZeroMemory(Color, sizeof(Color));
+ }
+};
+
+// This is the blob we pass back every time.
+template <ULONG I>
+struct Histogram
+{
+ HistogramBlobHeader Blob;
+ // RGB or YUV Histograms.
+ HistogramHeader Header;
+ HistogramData Data[I];
+
+ Histogram(
+ _In_ ULONG Width = 0,
+ _In_ ULONG Height = 0
+ )
+ {
+ Blob.Histograms = 1;
+ Blob.Size = sizeof(*this);
+
+ Header.Size = sizeof(Header) + sizeof(Data);
+ Header.Bins = 256;
+ Header.Grid.Height = Height;
+ Header.Grid.Width = Width;
+ Header.Grid.Region.top = 0;
+ Header.Grid.Region.left = 0;
+ Header.Grid.Region.bottom = Height - 1;
+ Header.Grid.Region.right = Width - 1;
+ }
+};
+
+#if (NTDDI_VERSION >= NTDDI_WINBLUE)
+#define MF_HISTOGRAM_RGB (MF_HISTOGRAM_CHANNEL_R | MF_HISTOGRAM_CHANNEL_G | MF_HISTOGRAM_CHANNEL_B )
+#define MF_HISTOGRAM_YCrCb (MF_HISTOGRAM_CHANNEL_Y | MF_HISTOGRAM_CHANNEL_Cr | MF_HISTOGRAM_CHANNEL_Cb)
+
+HRESULT ParseMetadata_Histogram(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+)
+{
+ if (pItem->Size < sizeof(CAMERA_METADATA_HISTOGRAM))
+ {
+ return E_UNEXPECTED;
+ }
+
+ PCAMERA_METADATA_HISTOGRAM pHistogram = (PCAMERA_METADATA_HISTOGRAM)pItem;
+
+ if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_RGB) == MF_HISTOGRAM_RGB)
+ {
+ Histogram<4> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
+
+ Blob.Header.FourCC = pHistogram->Data.FourCC;
+ Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
+
+ // For a RGB Histogram, we fake the Y channel by copying the G channel.
+ Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
+ RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[0].Color));
+
+ // Now just copy the RGB channels normally.
+ Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_R;
+ RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[1].Color));
+ Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_G;
+ RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[2].Color));
+ Blob.Data[3].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_B;
+ RtlCopyMemory(Blob.Data[3].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[3].Color));
+
+ return pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_HISTOGRAM,
+ (PBYTE)&Blob,
+ sizeof(Blob)
+ );
+ }
+ else if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_YCrCb) == MF_HISTOGRAM_YCrCb)
+ {
+ Histogram<3> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
+
+ Blob.Header.FourCC = pHistogram->Data.FourCC;
+ Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
+
+ Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
+ RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[0].Color));
+ Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cr;
+ RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[1].Color));
+ Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cb;
+ RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[2].Color));
+
+ //TODO:
+ return pMetaDataAttributes->SetBlob(
+ MF_CAPTURE_METADATA_HISTOGRAM,
+ (PBYTE)&Blob,
+ sizeof(Blob)
+ );
+ }
+ return E_UNEXPECTED;
+}
+
+HRESULT ParseMetadata_FaceDetection(
+ _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
+ _In_ IMFAttributes* pMetaDataAttributes
+)
+{
+ HRESULT hr = S_OK;
+
+ if (pItem->Size < sizeof(CAMERA_METADATA_FACEHEADER))
+ {
+ return E_UNEXPECTED;
+ }
+
+ PCAMERA_METADATA_FACEHEADER pFaceHeader = (PCAMERA_METADATA_FACEHEADER)pItem;
+
+ if (pItem->Size < (sizeof(CAMERA_METADATA_FACEHEADER) + (sizeof(METADATA_FACEDATA) * pFaceHeader->Count)))
+ {
+ return E_UNEXPECTED;
+ }
+ PMETADATA_FACEDATA pFaceData = (PMETADATA_FACEDATA)(pFaceHeader + 1);
+ UINT32 cbRectSize = sizeof(FaceRectInfoBlobHeader) + (sizeof(FaceRectInfo) * (pFaceHeader->Count));
+ BYTE* pRectBuf = new (std::nothrow) BYTE[cbRectSize];
+ if (pRectBuf == NULL)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ UINT32 cbCharSize = sizeof(FaceCharacterizationBlobHeader) + (sizeof(FaceCharacterization) * (pFaceHeader->Count));
+ BYTE* pCharBuf = new (std::nothrow) BYTE[cbCharSize];
+ if (pCharBuf == NULL)
+ {
+ delete[] pRectBuf;
+ return E_OUTOFMEMORY;
+ }
+
+ FaceRectInfoBlobHeader* pFaceRectHeader = (FaceRectInfoBlobHeader*)pRectBuf;
+ pFaceRectHeader->Size = cbRectSize;
+ pFaceRectHeader->Count = pFaceHeader->Count;
+
+ FaceCharacterizationBlobHeader* pFaceCharHeader = (FaceCharacterizationBlobHeader*)pCharBuf;
+ pFaceCharHeader->Size = cbCharSize;
+ pFaceCharHeader->Count = pFaceHeader->Count;
+
+ FaceRectInfo* FaceRegions = (FaceRectInfo*)(pFaceRectHeader + 1);
+ FaceCharacterization* FaceChars = (FaceCharacterization*)(pFaceCharHeader + 1);
+
+ for (UINT i = 0; i < pFaceHeader->Count; i++)
+ {
+ FaceRegions[i].Region = pFaceData[i].Region;
+ FaceRegions[i].confidenceLevel = pFaceData[i].confidenceLevel;
+
+ FaceChars[i].BlinkScoreLeft = pFaceData[i].BlinkScoreLeft;
+ FaceChars[i].BlinkScoreRight = pFaceData[i].BlinkScoreRight;
+ FaceChars[i].FacialExpression = (pFaceData[i].FacialExpression == EXPRESSION_SMILE) ? MF_METADATAFACIALEXPRESSION_SMILE : 0;
+ FaceChars[i].FacialExpressionScore = pFaceData[i].FacialExpressionScore;
+ }
+
+ hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROIS, pRectBuf, cbRectSize);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ MetadataTimeStamps timestamp;
+ timestamp.Flags = MF_METADATATIMESTAMPS_DEVICE;
+ timestamp.Device = pFaceHeader->Timestamp;
+
+ hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROITIMESTAMPS, (const UINT8*)&timestamp, sizeof(MetadataTimeStamps));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+ // Include characterization data if any of the associated bits were set.
+ if (pFaceHeader->Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK)
+ {
+ hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROICHARACTERIZATIONS, pCharBuf, cbCharSize);
+ }
+#endif // (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+
+done:
+ delete[] pRectBuf;
+ delete[] pCharBuf;
+
+ return hr;
+}
+#endif
diff --git a/avstream/avscamera/DMFT/Source.def b/avstream/avscamera/DMFT/Source.def
new file mode 100644
index 00000000..752ef2ea
--- /dev/null
+++ b/avstream/avscamera/DMFT/Source.def
@@ -0,0 +1,5 @@
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
+ DllGetClassObject PRIVATE
diff --git a/avstream/avscamera/DMFT/basepin.cpp b/avstream/avscamera/DMFT/basepin.cpp
new file mode 100644
index 00000000..e0178390
--- /dev/null
+++ b/avstream/avscamera/DMFT/basepin.cpp
@@ -0,0 +1,625 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#include "stdafx.h"
+
+#ifdef MF_WPP
+#include "basepin.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+/* -------> New STATE
+ |
+ |old State
+DeviceStreamState_Stop DeviceStreamState_Pause DeviceStreamState_Run DeviceStreamState_Disabled
+DeviceStreamState_Pause
+DeviceStreamState_Run
+DeviceStreamState_Disabled
+*/
+
+DeviceStreamState pinStateTransition[4][4] = {
+ { DeviceStreamState_Stop, DeviceStreamState_Pause, DeviceStreamState_Run, DeviceStreamState_Disabled },
+ { DeviceStreamState_Stop, DeviceStreamState_Pause, DeviceStreamState_Run, DeviceStreamState_Disabled },
+ { DeviceStreamState_Stop, DeviceStreamState_Pause, DeviceStreamState_Run, DeviceStreamState_Disabled },
+ { DeviceStreamState_Disabled, DeviceStreamState_Disabled, DeviceStreamState_Disabled, DeviceStreamState_Disabled }
+};
+
+CBasePin::CBasePin( _In_ ULONG id, _In_ CMultipinMft *parent) :
+ m_StreamId(id)
+ , m_Parent(parent)
+ , m_setMediaType(nullptr)
+ , m_nRefCount(0)
+ , m_state(DeviceStreamState_Stop)
+ , m_dwWorkQueueId(MFASYNC_CALLBACK_QUEUE_UNDEFINED)
+{
+
+}
+
+CBasePin::~CBasePin()
+{
+ m_listOfMediaTypes.clear();
+ m_spAttributes = nullptr;
+}
+
+IFACEMETHODIMP_(DeviceStreamState) CBasePin::GetState()
+{
+ return (DeviceStreamState) InterlockedCompareExchange((PLONG)&m_state, 0L,0L);
+}
+
+IFACEMETHODIMP_(DeviceStreamState) CBasePin::SetState(_In_ DeviceStreamState state)
+{
+ return (DeviceStreamState) InterlockedExchange((LONG*)&m_state, state);
+}
+
+HRESULT CBasePin::AddMediaType( _Inout_ DWORD *pos, _In_ IMFMediaType *pMediaType)
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+
+ DMFTCHECKNULL_GOTO(pMediaType, done, E_INVALIDARG);
+ hr = ExceptionBoundary([&]()
+ {
+ m_listOfMediaTypes.push_back(pMediaType);
+ });
+ DMFTCHECKHR_GOTO(hr, done);
+ if (pos)
+ {
+ *pos = (DWORD)(m_listOfMediaTypes.size() - 1);
+ }
+
+done:
+ return hr;
+}
+
+HRESULT CBasePin::GetMediaTypeAt( _In_ DWORD pos, _Outptr_result_maybenull_ IMFMediaType **ppMediaType )
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+ ComPtr<IMFMediaType> spMediaType;
+ DMFTCHECKNULL_GOTO(ppMediaType,done,E_INVALIDARG);
+ *ppMediaType = nullptr;
+ if (pos >= m_listOfMediaTypes.size())
+ {
+ DMFTCHECKHR_GOTO(MF_E_NO_MORE_TYPES,done);
+ }
+ spMediaType = m_listOfMediaTypes[pos];
+ *ppMediaType = spMediaType.Detach();
+done:
+ return hr;
+}
+
+IFACEMETHODIMP_(BOOL) CBasePin::IsMediaTypeSupported
+(
+ _In_ IMFMediaType *pMediaType,
+ _When_(ppIMFMediaTypeFull != nullptr, _Outptr_result_maybenull_)
+ IMFMediaType **ppIMFMediaTypeFull
+)
+{
+ HRESULT hr = S_OK;
+ BOOL bFound = FALSE;
+ CAutoLock Lock(lock());
+ DMFTCHECKNULL_GOTO(pMediaType,done,E_INVALIDARG);
+ if (ppIMFMediaTypeFull)
+ {
+ *ppIMFMediaTypeFull = nullptr;
+ }
+
+ for (UINT uIIndex = 0, uISize = (UINT)m_listOfMediaTypes.size(); uIIndex < uISize ; uIIndex++ )
+ {
+ DWORD dwResult = 0;
+ hr = m_listOfMediaTypes[ uIIndex ]->IsEqual( pMediaType, &dwResult );
+ if (hr == S_FALSE)
+ {
+
+ if ((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
+ (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
+ (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_DATA))
+ {
+ hr = S_OK;
+ }
+ }
+ if (hr == S_OK)
+ {
+ bFound = TRUE;
+ if (ppIMFMediaTypeFull) {
+ DMFTCHECKHR_GOTO(m_listOfMediaTypes[uIIndex].CopyTo(ppIMFMediaTypeFull), done);
+ }
+ break;
+ }
+ else if (FAILED(hr))
+ {
+ DMFTCHECKHR_GOTO(hr,done);
+ }
+ }
+done:
+ return SUCCEEDED(hr) ? TRUE : FALSE;
+}
+
+IFACEMETHODIMP CBasePin::GetOutputAvailableType(
+ _In_ DWORD dwTypeIndex,
+ _Out_opt_ IMFMediaType** ppType)
+{
+ return GetMediaTypeAt( dwTypeIndex, ppType );
+}
+
+HRESULT CBasePin::QueryInterface(
+ _In_ REFIID iid,
+ _Outptr_result_maybenull_ void** ppv
+ )
+{
+ HRESULT hr = S_OK;
+
+ DMFTCHECKNULL_GOTO(ppv, done, E_POINTER);
+ *ppv = nullptr;
+ if ( iid == __uuidof( IUnknown ) )
+ {
+ *ppv = static_cast<VOID*>(this);
+ }
+ else if ( iid == __uuidof( IMFAttributes ) )
+ {
+ *ppv = static_cast< IMFAttributes* >( this );
+ }
+ else if ( iid == __uuidof( IKsControl ) )
+ {
+ *ppv = static_cast< IKsControl* >( this );
+ }
+ else
+ {
+ hr = E_NOINTERFACE;
+ goto done;
+ }
+ AddRef();
+done:
+ return hr;
+}
+
+VOID CBasePin::SetD3DManager(_In_opt_ IUnknown* pManager)
+{
+ //
+ // Should release the old dxgi manager.. We will not invalidate the pins or allocators
+ // We will recreate all allocator when the media types are set, so we should be fine
+ // And the pipeline will not set the dxgimanager when the pipeline is already built
+ //
+ CAutoLock Lock(lock());
+ m_spDxgiManager = pManager;
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Setting D3DManager on pin %d", m_StreamId);
+}
+//
+//Input Pin implementation
+//
+CInPin::CInPin(
+ _In_opt_ IMFAttributes *pAttributes,
+ _In_ ULONG ulPinId,
+ _In_ CMultipinMft *pParent)
+ :
+ CBasePin(ulPinId, pParent),
+ m_stStreamType(GUID_NULL),
+ m_waitInputMediaTypeWaiter(NULL),
+ m_preferredStreamState(DeviceStreamState_Stop)
+{
+ setAttributes(pAttributes);
+}
+
+CInPin::~CInPin()
+{
+ setAttributes( nullptr );
+ m_spSourceTransform = nullptr;
+
+ if (m_waitInputMediaTypeWaiter)
+ {
+ CloseHandle(m_waitInputMediaTypeWaiter);
+ }
+}
+
+IFACEMETHODIMP CInPin::Init(
+ _In_ IMFDeviceTransform* pTransform
+ )
+{
+
+ HRESULT hr = S_OK;
+
+ DMFTCHECKNULL_GOTO( pTransform, done, E_INVALIDARG );
+
+ m_spSourceTransform = pTransform;
+
+ DMFTCHECKHR_GOTO( GetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType ), done );
+
+ //
+ //Get the DevProxy IKSControl.. used to send the KSControls or the device control IOCTLS over to devproxy and finally on to the driver!!!!
+ //
+ DMFTCHECKHR_GOTO( m_spAttributes.As( &m_spIkscontrol ), done );
+
+ m_waitInputMediaTypeWaiter = CreateEvent( NULL,
+ FALSE,
+ FALSE,
+ nullptr
+ );
+ DMFTCHECKNULL_GOTO( m_waitInputMediaTypeWaiter, done, E_OUTOFMEMORY );
+
+ DMFTCHECKHR_GOTO( GenerateMFMediaTypeListFromDevice(streamId()),done );
+
+done:
+ if ( FAILED(hr) )
+ {
+ m_spSourceTransform = nullptr;
+
+ if ( m_waitInputMediaTypeWaiter )
+ {
+ CloseHandle( m_waitInputMediaTypeWaiter );
+ m_waitInputMediaTypeWaiter = NULL;
+ }
+
+ m_stStreamType = GUID_NULL;
+ }
+
+ return hr;
+}
+
+HRESULT CInPin::GenerateMFMediaTypeListFromDevice(
+ _In_ UINT uiStreamId
+ )
+{
+ HRESULT hr = S_OK;
+ GUID stSubType = { 0 };
+ //This is only called in the begining when the input pin is constructed
+ DMFTCHECKNULL_GOTO( m_spSourceTransform, done, MF_E_TRANSFORM_TYPE_NOT_SET );
+ for (UINT iMediaType = 0; SUCCEEDED(hr) ; iMediaType++)
+ {
+ ComPtr<IMFMediaType> spMediaType;
+ DWORD pos = 0;
+
+ hr = m_spSourceTransform->GetOutputAvailableType(uiStreamId, iMediaType, spMediaType.GetAddressOf());
+ if (hr != S_OK)
+ break;
+
+ DMFTCHECKHR_GOTO(AddMediaType(&pos, spMediaType.Get()), done);
+ }
+done:
+ if (hr == MF_E_NO_MORE_TYPES) {
+ hr = S_OK;
+ }
+ return hr;
+}
+
+IFACEMETHODIMP CInPin::SendSample(
+ _In_ IMFSample *pSample
+ )
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+ if (FAILED(Active()))
+ {
+ goto done;
+ }
+ COutPin *poPin = static_cast<COutPin*>(m_outpin.Get());
+ DMFTCHECKNULL_GOTO(pSample, done, S_OK);
+ DMFTCHECKHR_GOTO(poPin->AddSample(pSample, this), done);
+
+ done:
+ return hr;
+}
+
+IFACEMETHODIMP_(VOID) CInPin::ConnectPin( _In_ CBasePin * poPin )
+{
+ CAutoLock Lock(lock());
+ if (poPin!=nullptr)
+ {
+ m_outpin = poPin;
+ }
+}
+
+IFACEMETHODIMP CInPin::WaitForSetInputPinMediaChange()
+{
+ DWORD dwWait = 0;
+ HRESULT hr = S_OK;
+
+ dwWait = WaitForSingleObject( m_waitInputMediaTypeWaiter, INFINITE );
+
+ if ( dwWait != WAIT_OBJECT_0 )
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto done;
+ }
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+HRESULT CInPin::GetInputStreamPreferredState(
+ _Inout_ DeviceStreamState* value,
+ _Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType
+ )
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+
+ if (value!=nullptr)
+ {
+ *value = m_preferredStreamState;
+ }
+
+ if (ppMediaType )
+ {
+ *ppMediaType = nullptr;
+ if (m_spPrefferedMediaType != nullptr )
+ {
+ m_spPrefferedMediaType.CopyTo(ppMediaType);
+ }
+ }
+
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+HRESULT CInPin::SetInputStreamState(
+ _In_ IMFMediaType* pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags
+ )
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwFlags);
+
+ CAutoLock Lock(lock());
+ //
+ //Set the media type
+ //
+ setMediaType(pMediaType);
+ SetState(value);
+ //
+ //Set the event. This event is being waited by an output media/state change operation
+ //
+ m_spPrefferedMediaType = nullptr;
+ SetEvent(m_waitInputMediaTypeWaiter);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+IFACEMETHODIMP_(VOID) CInPin::ShutdownPin()
+{
+ m_spSourceTransform = nullptr;
+ m_outpin = nullptr;
+}
+//
+//Output Pin Implementation
+//
+COutPin::COutPin(
+ _In_ ULONG ulPinId,
+ _In_opt_ CMultipinMft *pparent,
+ _In_ IKsControl* pIksControl
+ )
+ : CBasePin(ulPinId, pparent)
+ , m_firstSample(false)
+ , m_queue(nullptr)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFAttributes> spAttributes;
+
+ //
+ //Get the input pin IKS control.. the pin IKS control talks to sourcetransform's IKS control
+ //
+ m_spIkscontrol = pIksControl;
+
+ MFCreateAttributes( &spAttributes, 3 ); //Create the space for the attribute store!!
+ setAttributes( spAttributes.Get());
+ DMFTCHECKHR_GOTO( SetUINT32( MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE ), done );
+ DMFTCHECKHR_GOTO( SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft" ),done );
+ DMFTCHECKHR_GOTO( SetUINT32( MF_TRANSFORM_ASYNC, TRUE ),done );
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+}
+
+COutPin::~COutPin()
+{
+ m_spAttributes = nullptr;
+ SAFE_DELETE(m_queue);
+}
+
+/*++
+COutPin::AddPin
+Description:
+Called from AddSample if the Output Pin is in open state. This function looks for the queue
+corresponding to the input pin and adds it in the queue.
+--*/
+IFACEMETHODIMP COutPin::AddPin(
+ _In_ DWORD inputPinId
+ )
+{
+ //
+ //Add a new queue corresponding to the input pin
+ //
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+
+ m_queue = new (std::nothrow) CPinQueue(inputPinId,Parent());
+ DMFTCHECKNULL_GOTO(m_queue, done, E_OUTOFMEMORY );
+done:
+
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return S_OK;
+}
+/*++
+COutPin::AddSample
+Description:
+Called when ProcessInput is called on the Device Transform. The Input Pin puts the samples
+in the pins connected. If the Output pins are in open state the sample lands in the queues
+--*/
+
+IFACEMETHODIMP COutPin::AddSample(
+ _In_ IMFSample *pSample,
+ _In_ CBasePin *pPin)
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(pPin);
+
+ CAutoLock Lock(lock()); // Serialize
+
+ DMFTCHECKNULL_GOTO(pSample, done, E_INVALIDARG);
+ if (FAILED(Active()))
+ {
+ goto done;
+ }
+ DMFTCHECKHR_GOTO(m_queue->Insert(pSample), done);
+done:
+ if (FAILED(hr))
+ {
+ // Throw an Error to the pipeline
+ DMFTCHECKHR_GOTO(Parent()->QueueEvent(MEError, GUID_NULL, hr, NULL), done);
+ }
+ return hr;
+}
+
+/*++
+COutPin::SetState
+Description:
+State setter for the output pin
+--*/
+IFACEMETHODIMP_(VOID) COutPin::SetFirstSample(
+ _In_ BOOL fisrtSample )
+{
+ m_firstSample = fisrtSample;
+}
+
+/*++
+COutPin::FlushQueues
+Description:
+Called from the device Transform when the output queues have to be flushed
+
+--*/
+HRESULT COutPin::FlushQueues()
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock( lock() );
+ (VOID)m_queue->Clear();
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+/*++
+COutPin::ChangeMediaTypeFromInpin
+Description:
+called from the Device Transform when the input media type is changed. This will result in
+the xvp being possibly installed in the queue if the media types set on the input
+and the output dont match
+--*/
+HRESULT COutPin::ChangeMediaTypeFromInpin(
+ _In_ IMFMediaType* pOutMediaType,
+ _In_ DeviceStreamState state)
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+ //
+ //Set the state to disabled and while going out we will reset the state back to the requested state
+ //Flush so that we drop any samples we have in store!!
+ //
+ SetState(DeviceStreamState_Disabled);
+ DMFTCHECKHR_GOTO(FlushQueues(),done);
+ DMFTCHECKNULL_GOTO(m_queue,done, E_UNEXPECTED); // The queue should alwaye be set
+ if ( SUCCEEDED( hr ) )
+ {
+ (VOID)setMediaType( pOutMediaType );
+ (VOID)SetState( state );
+ }
+done:
+ return hr;
+}
+
+/*++
+Description:
+ called from the IMFdeviceTransform's
+--*/
+
+IFACEMETHODIMP COutPin::GetOutputStreamInfo(
+ _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
+ )
+{
+ HRESULT hr = S_OK;
+ IMFMediaType* pMediatype = nullptr;
+ getMediaType( &pMediatype );
+
+ if (SUCCEEDED(hr) && !pMediatype) {
+ pMediatype->Release();
+ pStreamInfo->cbAlignment = 0;
+ pStreamInfo->cbSize = 0;
+ pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
+ pStreamInfo->dwFlags |= MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
+ //We provide our samples..
+ }
+ else {
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+ return hr;
+}
+
+
+/*++
+COutPin::ProcessOutput
+Description:
+ called from the Device Transform when the transform manager demands output samples..
+ If we have samples we forward it.
+ If we are a photo pin then we forward only if trigger is sent. We ask the devicetransform if we have received the transform or not.
+ If we have received the sample and we are passing out a sample we should reset the trigger set on the Device Transform
+--*/
+
+IFACEMETHODIMP COutPin::ProcessOutput(_In_ DWORD dwFlags,
+ _Inout_ MFT_OUTPUT_DATA_BUFFER *pOutputSample,
+ _Out_ DWORD *pdwStatus
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFSample> spSample;
+ UNREFERENCED_PARAMETER(pdwStatus);
+ UNREFERENCED_PARAMETER(dwFlags);
+ CAutoLock lock(lock());
+ MFTIME llTime = 0;
+ if (FAILED(Active()))
+ {
+ goto done;
+ }
+ DMFTCHECKNULL_GOTO(m_queue, done, MF_E_INVALID_STREAM_STATE);
+ pOutputSample->dwStatus = S_OK;
+
+ DMFTCHECKHR_GOTO(m_queue->Remove(spSample.GetAddressOf()), done);
+
+ if (FAILED(spSample->GetSampleTime(&llTime)))
+ {
+ spSample->SetSampleTime(MFGetSystemTime());
+ }
+ if (m_firstSample)
+ {
+ spSample->SetUINT32(MFSampleExtension_Discontinuity,TRUE);
+ SetFirstSample(FALSE);
+ }
+ //
+ // Any processing before we pass the sample to further in the pipeline should be done here
+ // PROCESSSAMPLE(pSample); There is a bug in the pipeline and to circumvent that we have to
+ // keep a reference on the sample. The pipeline is not releasing a reference when the sample
+ // is fed in ProcessInput. We are explicitly releasing it for the pipeline.
+ //
+ pOutputSample->pSample = spSample.Detach();
+ pOutputSample->dwStatus = S_OK;
+done:
+ return hr;
+}
+
+/*++
+ COutPin::KsProperty
+Description:
+The KsProperty for the Pin.. this is to reroute all pin kscontrols to the input pin
+--*/
+IFACEMETHODIMP COutPin::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+{
+ //
+ //Route it to input pin
+ //
+ return m_spIkscontrol->KsProperty(pProperty,
+ ulPropertyLength,
+ pPropertyData,
+ ulDataLength,
+ pBytesReturned);
+}
+
diff --git a/avstream/avscamera/DMFT/basepin.h b/avstream/avscamera/DMFT/basepin.h
new file mode 100644
index 00000000..8051188a
--- /dev/null
+++ b/avstream/avscamera/DMFT/basepin.h
@@ -0,0 +1,568 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#pragma once
+#include "stdafx.h"
+
+extern DeviceStreamState pinStateTransition[][4];
+
+
+class CPinQueue;
+class CPinState;
+class CMultipinMft;
+
+class CBasePin:
+ public IMFAttributes,
+ public IKsControl
+{
+public:
+ CBasePin( _In_ ULONG _id=0, _In_ CMultipinMft *parent=NULL);
+
+ virtual ~CBasePin() = 0;
+ virtual IFACEMETHODIMP_(DeviceStreamState) GetState();
+ virtual IFACEMETHODIMP_(DeviceStreamState) SetState( _In_ DeviceStreamState State);
+
+
+ //
+ //IUnknown Interface functions
+ //
+
+ IFACEMETHODIMP_(ULONG) AddRef(
+ void
+ )
+ {
+ return InterlockedIncrement(&m_nRefCount);
+ }
+ IFACEMETHODIMP_(ULONG) Release(
+ void
+ )
+ {
+ ULONG uCount = InterlockedDecrement(&m_nRefCount);
+ if (uCount == 0)
+ {
+ delete this;
+ }
+ return uCount;
+ }
+
+ IFACEMETHODIMP_(HRESULT) QueryInterface(
+ _In_ REFIID riid,
+ _Outptr_result_maybenull_ void **ppvObject
+ );
+ //
+ // IKsControl Interface functions
+ //
+
+ IFACEMETHODIMP KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+ {
+ if ( m_spIkscontrol!=nullptr )
+ {
+ return m_spIkscontrol->KsProperty(pProperty,
+ ulPropertyLength,
+ pPropertyData,
+ ulDataLength,
+ pBytesReturned);
+ }
+ else
+ {
+ return E_NOTIMPL;
+ }
+ }
+ virtual IFACEMETHODIMP FlushQueues(
+ )
+ {
+ return S_OK;
+ }
+ //
+ // NOOPs for this iteration..
+ //
+ IFACEMETHODIMP KsMethod(
+ _In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+ {
+ UNREFERENCED_PARAMETER(pBytesReturned);
+ UNREFERENCED_PARAMETER(ulDataLength);
+ UNREFERENCED_PARAMETER(pMethodData);
+ UNREFERENCED_PARAMETER(pMethod);
+ UNREFERENCED_PARAMETER(ulMethodLength);
+ return S_OK;
+ }
+
+ IFACEMETHODIMP KsEvent(
+ _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+ {
+ UNREFERENCED_PARAMETER(pBytesReturned);
+ UNREFERENCED_PARAMETER(ulDataLength);
+ UNREFERENCED_PARAMETER(pEventData);
+ UNREFERENCED_PARAMETER(pEvent);
+ UNREFERENCED_PARAMETER(ulEventLength);
+ return S_OK;
+ }
+
+ //
+ //IMFAttributes implementation
+ //
+ IFACEMETHODIMP GetItem(
+ _In_ REFGUID guidKey,
+ _Inout_opt_ PROPVARIANT* pValue
+ )
+ {
+ return m_spAttributes->GetItem(guidKey, pValue);
+ }
+
+ IFACEMETHODIMP GetItemType(
+ _In_ REFGUID guidKey,
+ _Out_ MF_ATTRIBUTE_TYPE* pType
+ )
+ {
+ return m_spAttributes->GetItemType(guidKey, pType);
+ }
+
+ IFACEMETHODIMP CompareItem(
+ _In_ REFGUID guidKey,
+ _In_ REFPROPVARIANT Value,
+ _Out_ BOOL* pbResult
+ )
+ {
+ return m_spAttributes->CompareItem(guidKey, Value, pbResult);
+ }
+
+ IFACEMETHODIMP Compare(
+ _In_ IMFAttributes* pTheirs,
+ _In_ MF_ATTRIBUTES_MATCH_TYPE MatchType,
+ _Out_ BOOL* pbResult
+ )
+ {
+ return m_spAttributes->Compare(pTheirs, MatchType, pbResult);
+ }
+
+ IFACEMETHODIMP GetUINT32(
+ _In_ REFGUID guidKey,
+ _Out_ UINT32* punValue
+ )
+ {
+ return m_spAttributes->GetUINT32(guidKey, punValue);
+ }
+
+ IFACEMETHODIMP GetUINT64(
+ _In_ REFGUID guidKey,
+ _Out_ UINT64* punValue
+ )
+ {
+ return m_spAttributes->GetUINT64(guidKey, punValue);
+ }
+
+ IFACEMETHODIMP GetDouble(
+ _In_ REFGUID guidKey,
+ _Out_ double* pfValue
+ )
+ {
+ return m_spAttributes->GetDouble(guidKey, pfValue);
+ }
+
+ IFACEMETHODIMP GetGUID(
+ _In_ REFGUID guidKey,
+ _Out_ GUID* pguidValue
+ )
+ {
+ return m_spAttributes->GetGUID(guidKey, pguidValue);
+ }
+
+ IFACEMETHODIMP GetStringLength(
+ _In_ REFGUID guidKey,
+ _Out_ UINT32* pcchLength
+ )
+ {
+ return m_spAttributes->GetStringLength(guidKey, pcchLength);
+ }
+
+ IFACEMETHODIMP GetString(
+ _In_ REFGUID guidKey,
+ _Out_writes_(cchBufSize) LPWSTR pwszValue,
+ _In_ UINT32 cchBufSize,
+ _Inout_opt_ UINT32* pcchLength
+ )
+ {
+ return m_spAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
+ }
+
+ IFACEMETHODIMP GetAllocatedString(
+ _In_ REFGUID guidKey,
+ _Out_writes_(*pcchLength + 1) LPWSTR* ppwszValue,
+ _Inout_ UINT32* pcchLength
+ )
+ {
+ return m_spAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
+ }
+
+ IFACEMETHODIMP GetBlobSize(
+ _In_ REFGUID guidKey,
+ _Out_ UINT32* pcbBlobSize
+ )
+ {
+ return m_spAttributes->GetBlobSize(guidKey, pcbBlobSize);
+ }
+
+ IFACEMETHODIMP GetBlob(
+ _In_ REFGUID guidKey,
+ _Out_writes_(cbBufSize) UINT8* pBuf,
+ UINT32 cbBufSize,
+ _Inout_ UINT32* pcbBlobSize
+ )
+ {
+ return m_spAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
+ }
+
+ IFACEMETHODIMP GetAllocatedBlob(
+ __RPC__in REFGUID guidKey,
+ __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8** ppBuf,
+ __RPC__out UINT32* pcbSize
+ )
+ {
+ return m_spAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
+ }
+
+ IFACEMETHODIMP GetUnknown(
+ __RPC__in REFGUID guidKey,
+ __RPC__in REFIID riid,
+ __RPC__deref_out_opt LPVOID *ppv
+ )
+ {
+ return m_spAttributes->GetUnknown(guidKey, riid, ppv);
+ }
+
+ IFACEMETHODIMP SetItem(
+ _In_ REFGUID guidKey,
+ _In_ REFPROPVARIANT Value
+ )
+ {
+ return m_spAttributes->SetItem(guidKey, Value);
+ }
+
+ IFACEMETHODIMP DeleteItem(
+ _In_ REFGUID guidKey
+ )
+ {
+ return m_spAttributes->DeleteItem(guidKey);
+ }
+
+ IFACEMETHODIMP DeleteAllItems()
+ {
+ return m_spAttributes->DeleteAllItems();
+ }
+
+ IFACEMETHODIMP SetUINT32(
+ _In_ REFGUID guidKey,
+ _In_ UINT32 unValue
+ )
+ {
+ return m_spAttributes->SetUINT32(guidKey, unValue);
+ }
+
+ IFACEMETHODIMP SetUINT64(
+ _In_ REFGUID guidKey,
+ _In_ UINT64 unValue
+ )
+ {
+ return m_spAttributes->SetUINT64(guidKey, unValue);
+ }
+
+ IFACEMETHODIMP SetDouble(
+ _In_ REFGUID guidKey,
+ _In_ double fValue
+ )
+ {
+ return m_spAttributes->SetDouble(guidKey, fValue);
+ }
+
+ IFACEMETHODIMP SetGUID(
+ _In_ REFGUID guidKey,
+ _In_ REFGUID guidValue
+ )
+ {
+ return m_spAttributes->SetGUID(guidKey, guidValue);
+ }
+
+ IFACEMETHODIMP SetString(
+ _In_ REFGUID guidKey,
+ _In_ LPCWSTR wszValue
+ )
+ {
+ return m_spAttributes->SetString(guidKey, wszValue);
+ }
+
+ IFACEMETHODIMP SetBlob(
+ _In_ REFGUID guidKey,
+ _In_reads_(cbBufSize) const UINT8* pBuf,
+ UINT32 cbBufSize
+ )
+ {
+ return m_spAttributes->SetBlob(guidKey, pBuf, cbBufSize);
+ }
+
+ IFACEMETHODIMP SetUnknown(
+ _In_ REFGUID guidKey,
+ _In_ IUnknown* pUnknown
+ )
+ {
+ return m_spAttributes->SetUnknown(guidKey, pUnknown);
+ }
+
+ IFACEMETHODIMP LockStore()
+ {
+ return m_spAttributes->LockStore();
+ }
+
+ IFACEMETHODIMP UnlockStore()
+ {
+ return m_spAttributes->UnlockStore();
+ }
+
+ IFACEMETHODIMP GetCount(
+ _Out_ UINT32* pcItems
+ )
+ {
+ return m_spAttributes->GetCount(pcItems);
+ }
+
+ IFACEMETHODIMP GetItemByIndex(
+ UINT32 unIndex,
+ _Out_ GUID* pguidKey,
+ _Inout_ PROPVARIANT* pValue
+ )
+ {
+ return m_spAttributes->GetItemByIndex(unIndex, pguidKey, pValue);
+ }
+
+ IFACEMETHODIMP CopyAllItems(
+ _In_ IMFAttributes* pDest
+ )
+ {
+ return m_spAttributes->CopyAllItems(pDest);
+ }
+
+ //
+ //Helper Functions
+ //
+ __requires_lock_held(m_lock)
+ __inline HRESULT Active()
+ {
+ return (m_state == DeviceStreamState_Run)?S_OK:HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
+ }
+ __inline DWORD streamId()
+ {
+ return m_StreamId;
+ }
+
+ __inline VOID setMediaType(_In_opt_ IMFMediaType *pMediaType)
+ {
+ m_setMediaType = pMediaType;
+ }
+
+ __inline HRESULT getMediaType(_Outptr_opt_result_maybenull_ IMFMediaType **ppMediaType)
+ {
+ HRESULT hr = S_OK;
+ if (!ppMediaType)
+ return E_INVALIDARG;
+
+ if (m_setMediaType != nullptr)
+ {
+ hr = m_setMediaType.CopyTo(ppMediaType);
+ }
+ else
+ {
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+ return hr;
+ }
+
+ __inline IFACEMETHODIMP getPinAttributes (_In_ IMFAttributes **ppAttributes)
+ {
+ return QueryInterface( IID_PPV_ARGS(ppAttributes) );
+ }
+
+ IFACEMETHODIMP AddMediaType(
+ _Inout_ DWORD *pos,
+ _In_ IMFMediaType *pMediatype); /*Filling the media types data structure*/
+ IFACEMETHODIMP GetMediaTypeAt(
+ _In_ DWORD pos,
+ _Outptr_result_maybenull_ IMFMediaType **pMediaType); /* getting the data from the data structure*/
+ IFACEMETHODIMP_(BOOL) IsMediaTypeSupported(
+ _In_ IMFMediaType *pMediaType,
+ _When_(ppIMFMediaTypeFull != nullptr, _Outptr_result_maybenull_)
+ IMFMediaType **ppIMFMediaTypeFull);
+ IFACEMETHODIMP GetOutputAvailableType(
+ _In_ DWORD dwTypeIndex,
+ _Out_opt_ IMFMediaType **ppType);
+
+ VOID SetD3DManager(_In_opt_ IUnknown* pManager);
+ VOID SetWorkQueue(_In_ DWORD dwQueueId)
+ {
+ m_dwWorkQueueId = dwQueueId;
+ }
+protected:
+ //
+ //Inline helper functions
+ //
+ _inline CMultipinMft* Parent()
+ {
+ return m_Parent;
+ }
+ __inline HRESULT setAttributes(_In_ IMFAttributes* _pAttributes)
+ {
+ m_spAttributes = _pAttributes;
+ return S_OK;
+ }
+ __inline CCritSec& lock()
+ {
+ return m_lock;
+ }
+ IMFMediaTypeArray m_listOfMediaTypes;
+ ComPtr<IMFAttributes> m_spAttributes;
+ ComPtr<IKsControl> m_spIkscontrol;
+ DeviceStreamState m_state;
+ ComPtr<IUnknown> m_spDxgiManager;
+ DWORD m_dwWorkQueueId;
+private:
+ ULONG m_StreamId; /*Device Stream Id*/
+ CCritSec m_lock; /*This is only used to change the reference count i.e. active users of this stream*/
+ ComPtr<IMFMediaType> m_setMediaType;
+ CMultipinMft* m_Parent;
+ ULONG m_nRefCount;
+};
+
+
+
+class CInPin: public CBasePin{
+public:
+ CInPin( _In_opt_ IMFAttributes*, _In_ ULONG ulPinId = 0, _In_ CMultipinMft *pParent=NULL);
+ ~CInPin();
+
+ IFACEMETHODIMP Init(
+ _In_ IMFDeviceTransform *
+ );
+ IFACEMETHODIMP_(VOID) ConnectPin(
+ _In_ CBasePin *
+ );
+ IFACEMETHODIMP SendSample(
+ _In_ IMFSample *
+ );
+ HRESULT GenerateMFMediaTypeListFromDevice(
+ _In_ UINT uiStreamId
+ );
+ IFACEMETHODIMP WaitForSetInputPinMediaChange(
+ );
+ //
+ //Corresponding IMFDeviceTransform functions for the Pin
+ //
+ HRESULT GetInputStreamPreferredState(
+ _Inout_ DeviceStreamState *value,
+ _Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType
+ );
+ HRESULT SetInputStreamState(
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags
+ );
+
+ virtual IFACEMETHODIMP FlushQueues()
+ {
+ return S_OK;
+ }
+ //
+ //Inline functions
+ //
+ __inline IMFMediaType* getPreferredMediaType()
+ {
+ return m_spPrefferedMediaType.Get();
+ }
+ __inline VOID setPreferredMediaType( _In_ IMFMediaType *pMediaType)
+ {
+ m_spPrefferedMediaType = pMediaType;
+ }
+ __inline DeviceStreamState setPreferredStreamState(_In_ DeviceStreamState streamState)
+ {
+ return (DeviceStreamState)InterlockedCompareExchange((LONG*)&m_preferredStreamState, (LONG)streamState, (LONG)m_preferredStreamState);
+ }
+ __inline DeviceStreamState getPreferredStreamState()
+ {
+ return m_preferredStreamState;
+ }
+
+ IFACEMETHODIMP_( VOID) ShutdownPin();
+
+protected:
+ ComPtr<IMFDeviceTransform> m_spSourceTransform; /*Source Transform i.e. DevProxy*/
+ GUID m_stStreamType; /*GUID representing the GUID*/
+ ComPtr<CBasePin> m_outpin; //Only one output pin connected per input pin. There can be multiple pins connected and this could be a list
+ DeviceStreamState m_preferredStreamState;
+ ComPtr<IMFMediaType> m_spPrefferedMediaType;
+ HANDLE m_waitInputMediaTypeWaiter; /*Set when the input media type is changed*/
+
+};
+
+
+
+class COutPin: public CBasePin{
+public:
+ COutPin(
+ _In_ ULONG id = 0,
+ _In_opt_ CMultipinMft *pparent = NULL,
+ _In_ IKsControl* iksControl=NULL
+ );
+ ~COutPin();
+ IFACEMETHODIMP FlushQueues();
+ IFACEMETHODIMP AddPin(
+ _In_ DWORD pinId
+ );
+ virtual IFACEMETHODIMP AddSample(
+ _In_ IMFSample *pSample,
+ _In_ CBasePin *inPin
+ );
+ IFACEMETHODIMP GetOutputStreamInfo(
+ _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
+ );
+ virtual IFACEMETHODIMP ChangeMediaTypeFromInpin(
+ _In_ IMFMediaType* pOutMediaType,
+ _In_ DeviceStreamState state );
+ IFACEMETHODIMP ProcessOutput (
+ _In_ DWORD dwFlags,
+ _Inout_ MFT_OUTPUT_DATA_BUFFER *pOutputSample,
+ _Out_ DWORD *pdwStatus
+ );
+ IFACEMETHODIMP KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ );
+ IFACEMETHODIMP_(VOID) SetFirstSample(
+ _In_ BOOL
+ );
+
+ UINT32 GetMediatypeCount()
+ {
+ return (UINT32)m_listOfMediaTypes.size();
+ }
+
+protected:
+ CPinQueue * m_queue; /* Queue where the sample will be stored*/
+ BOOL m_firstSample;
+};
+
diff --git a/avstream/avscamera/DMFT/common.h b/avstream/avscamera/DMFT/common.h
new file mode 100644
index 00000000..b6e636a8
--- /dev/null
+++ b/avstream/avscamera/DMFT/common.h
@@ -0,0 +1,360 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#pragma once
+
+#ifndef MF_WPP
+#define DMFTRACE(...)
+#endif
+
+//
+// The below guid is used to register the GUID as the Device Transform. This should be adeed to the
+// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\ and under the
+// GLOBAL#\Device Parameters key, add a CameraDeviceMFTCLSID value, and set its value to
+// {836E84ED-45E9-4160-A79D-771F1C718CD2} for the Pipeline to pick up the Transform.
+//
+
+DEFINE_GUID(CLSID_AvsCameraDMFT, 0x836e84ed, 0x45e9, 0x4160, 0xa7, 0x9d, 0x77, 0x1f, 0x1c, 0x71, 0x8c, 0xd2);
+
+#ifdef DBG
+#define mf_assert(a) if(!a) DebugBreak()
+#else
+#define mf_assert(a)
+#endif
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID(CtlGUID_DMFTTrace, (CBCCA12E, 9472, 409D, A1B1, 753C98BF03C0), \
+ WPP_DEFINE_BIT(DMFT_INIT) \
+ WPP_DEFINE_BIT(DMFT_CONTROL) \
+ WPP_DEFINE_BIT(DMFT_GENERAL) \
+ )
+
+#define WPP_LEVEL_FLAG_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)
+#define WPP_LEVEL_FLAG_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+#define WPP_FLAG_LEVEL_LOGGER(flags,lvl) WPP_LEVEL_LOGGER(flags)
+#define WPP_FLAG_LEVEL_ENABLED(flags, lvl) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+
+#define WPP_CHECK_LEVEL_ENABLED(flags, level) 1
+
+//begin_wpp config
+//
+// USEPREFIX (DMFTCHECKNULL_GOTO,"%!STDPREFIX!");
+// FUNC DMFTCHECKNULL_GOTO(CHECKNULLGOTO_EXP,LABEL,HR,...);
+// USESUFFIX (DMFTCHECKNULL_GOTO," failed %!HRESULT!\n", hr);
+//
+//end_wpp
+
+//begin_wpp config
+//
+// USEPREFIX (DMFTCHECKHR_GOTO,"%!STDPREFIX!");
+// FUNC DMFTCHECKHR_GOTO(CHECKHRGOTO_EXP,LABEL,...);
+// USESUFFIX (DMFTCHECKHR_GOTO," failed %!HRESULT!\n", hr);
+//
+
+//end_wpp
+
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_PRE(pointer,label,HR) if( pointer == NULL ) { hr = HR;
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_POST(pointer,label,HR) ; goto label; }
+
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_LOGGER(pointer,label,HR) WPP_LEVEL_LOGGER( DMFT_INIT )
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_ENABLED(pointer,label,HR) WPP_CHECK_LEVEL_ENABLED( DMFT_INIT, TP_ERROR )
+
+#define WPP_CHECKHRGOTO_EXP_LABEL_PRE(HR,label) if( FAILED( hr = HR ) ) {
+#define WPP_CHECKHRGOTO_EXP_LABEL_POST(HR,label) ; goto label; }
+
+#define WPP_CHECKHRGOTO_EXP_LABEL_LOGGER(HR, label) WPP_LEVEL_LOGGER( DMFT_INIT )
+#define WPP_CHECKHRGOTO_EXP_LABEL_ENABLED(HR, label) WPP_CHECK_LEVEL_ENABLED( DMFT_INIT, TP_ERROR )
+
+
+// Give it checkhr and checknull definitions if some future generations of visual studio remove the wpp processor support
+
+//#if !defined DMFTCHECKHR_GOTO
+//#define DMFTCHECKHR_GOTO(a,b) {hr=(a); if(FAILED(hr)){goto b;}}
+//#endif
+//
+//#if !defined DMFTCHECKNULL_GOTO
+//#define DMFTCHECKNULL_GOTO(a,b,c) {if(!a) {hr = c; goto b;}}
+//#endif
+
+#define SAFE_ADDREF(p) if( NULL != p ) { ( p )->AddRef(); }
+#define SAFE_DELETE(p) delete p; p = NULL;
+#define SAFE_SHUTDELETE(p) if( NULL != p ) { ( p )->Shutdown(); delete p; p = NULL; }
+#define SAFE_RELEASE(p) if( NULL != p ) { ( p )->Release(); p = NULL; }
+#define SAFE_SHUTRELEASE(p) if( NULL != p ) { ( p )->Shutdown(); ( p )->Release(); p = NULL; }
+#define SAFE_CLOSERELEASE(p) if( NULL != p ) { ( p )->Close( TRUE ); ( p )->Release(); p = NULL; }
+#define SAFE_COTASKMEMFREE(p) CoTaskMemFree( p ); p = NULL;
+#define SAFE_SYSFREESTRING(p) SysFreeString( p ); p = NULL;
+#define SAFE_ARRAYDELETE(p) delete [] p; p = NULL;
+#define SAFE_BYTEARRAYDELETE(p) delete [] (BYTE*) p; p = NULL;
+#define SAFE_CLOSEHANDLE(h) { if(INVALID_HANDLE_VALUE != (h)) { ::CloseHandle(h); (h) = INVALID_HANDLE_VALUE; } }
+
+
+#define SAFERELEASE(x) \
+if (x) {\
+ x->Release(); \
+ x = NULL; \
+}
+
+#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 //!defined(_IKsControl_)
+
+//Forward defintion
+class CBasePin;
+//////////////////////////////////////////////////////////////////////////
+// CCritSec
+// Description: Wraps a critical section.
+//////////////////////////////////////////////////////////////////////////
+
+class CCritSec
+{
+private:
+ CRITICAL_SECTION m_criticalSection;
+public:
+ CCritSec();
+ ~CCritSec();
+ _Requires_lock_not_held_(m_criticalSection) _Acquires_lock_(m_criticalSection)
+ void Lock();
+ _Requires_lock_held_(m_criticalSection) _Releases_lock_(m_criticalSection)
+ void Unlock();
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+// CAutoLock
+// Description: Provides automatic locking and unlocking of a
+// of a critical section.
+//////////////////////////////////////////////////////////////////////////
+
+class CAutoLock
+{
+protected:
+ CCritSec *m_pCriticalSection;
+public:
+ _Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+ CAutoLock(CCritSec& crit);
+ _Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+ CAutoLock(CCritSec* crit);
+ _Releases_lock_(this->m_pCriticalSection->m_criticalSection)
+ ~CAutoLock();
+};
+
+class MediaBufferLock
+{
+public:
+ MediaBufferLock(_In_ IMFMediaBuffer* pBuffer) :
+ m_bLocked(false)
+ {
+ m_spBuffer = pBuffer;
+ }
+
+ HRESULT LockBuffer(
+ _Outptr_result_bytebuffer_to_(*pcbMaxLength, *pcbCurrentLength) BYTE** ppbBuffer,
+ _Out_opt_ DWORD* pcbMaxLength,
+ _Out_opt_ DWORD* pcbCurrentLength)
+ {
+ if (!m_spBuffer)
+ {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hr = m_spBuffer->Lock(ppbBuffer, pcbMaxLength, pcbCurrentLength);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ m_bLocked = true;
+ return S_OK;
+ }
+
+ ~MediaBufferLock()
+ {
+ if (m_spBuffer && m_bLocked)
+ {
+ //Unlock fails only if we did not lock it first
+ (void)m_spBuffer->Unlock();
+ }
+ }
+
+private:
+ ComPtr<IMFMediaBuffer> m_spBuffer;
+ bool m_bLocked;
+};
+
+typedef std::vector<ComPtr<IMFMediaType>> IMFMediaTypeArray;
+typedef std::vector<ComPtr<CBasePin>> CBasePinArray;
+typedef std::vector<ComPtr<IMFSample>> IMFSampleList;
+typedef std::pair< std::multimap<int, int>::iterator, std::multimap<int, int>::iterator > MMFTMMAPITERATOR;
+
+STDMETHODIMP_(BOOL) IsPinStateInActive(
+ _In_ DeviceStreamState state
+ );
+
+
+template <typename Lambda>
+HRESULT ExceptionBoundary(Lambda&& lambda)
+{
+ try
+ {
+ lambda();
+ return S_OK;
+ }
+ catch (const _com_error& e)
+ {
+ return e.Error();
+ }
+ catch (const std::bad_alloc&)
+ {
+ return E_OUTOFMEMORY;
+ }
+ catch (const std::out_of_range&)
+ {
+ return MF_E_INVALIDINDEX;
+ }
+ catch (...)
+ {
+ return E_UNEXPECTED;
+ }
+}
+
+//
+// Object LifeTime manager. The Class has a global variable which
+// maintains a reference count of the number of objects in the
+// system managed by the DLL.
+//
+class CDMFTModuleLifeTimeManager{
+public:
+ CDMFTModuleLifeTimeManager()
+ {
+ InterlockedIncrement(&s_lObjectCount);
+ }
+ ~CDMFTModuleLifeTimeManager()
+ {
+ InterlockedDecrement(&s_lObjectCount);
+ }
+ static long GetDMFTObjCount()
+ {
+ return s_lObjectCount;
+ }
+private:
+ static volatile long s_lObjectCount;
+};
+
+class CPinQueue : public IUnknown
+{
+public:
+ CPinQueue(_In_ DWORD _inPinId, _In_ IMFDeviceTransform* pTransform = nullptr);
+ ~CPinQueue();
+
+ STDMETHODIMP Insert(_In_ IMFSample* pSample);
+ STDMETHODIMP Remove(_Outptr_result_maybenull_ IMFSample** pSample);
+ STDMETHODIMP_(VOID) Clear();
+
+ //
+ // Inline functions
+ //
+ __inline BOOL Empty()
+ {
+ return (!m_sampleList.size());
+ }
+ __inline DWORD pinStreamId()
+ {
+ return m_dwInPinId;
+ }
+ __inline GUID pinCategory()
+ {
+ if (IsEqualCLSID(m_streamCategory, GUID_NULL))
+ {
+ ComPtr<IMFAttributes> spAttributes;
+ if (SUCCEEDED(m_pTransform->GetOutputStreamAttributes(pinStreamId(), spAttributes.ReleaseAndGetAddressOf())))
+ {
+ (VOID) spAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &m_streamCategory);
+ }
+ }
+ return m_streamCategory;
+ }
+
+ STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
+ {
+ HRESULT hr = S_OK;
+ if (ppv != nullptr)
+ {
+ *ppv = nullptr;
+ if (riid == __uuidof(IUnknown))
+ {
+ AddRef();
+ *ppv = static_cast<IUnknown*>(this);
+ }
+ else
+ {
+ hr = E_NOINTERFACE;
+ }
+ }
+ else
+ {
+ hr = E_POINTER;
+ }
+ return hr;
+ }
+
+ STDMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+ STDMETHODIMP_(ULONG) Release()
+ {
+ long cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0)
+ {
+ delete this;
+ }
+ return cRef;
+ }
+
+private:
+ DWORD m_dwInPinId; /* This is the input pin */
+ IMFSampleList m_sampleList; /* List storing the samples */
+ IMFDeviceTransform* m_pTransform; /* Weak reference to the the device MFT */
+ GUID m_streamCategory;
+ ULONG m_cRef;
+};
+
+
+HRESULT ProcessMetadata(_In_ IMFSample* pSample);
+// Metadata defintions
+
diff --git a/avstream/avscamera/DMFT/dllmain.cpp b/avstream/avscamera/DMFT/dllmain.cpp
new file mode 100644
index 00000000..5a988320
--- /dev/null
+++ b/avstream/avscamera/DMFT/dllmain.cpp
@@ -0,0 +1,354 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+// dllmain.cpp : Implements DLL exports and COM class factory
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: This source file implements the class factory for the transform,
+// plus the following DLL functions:
+// - DllMain
+// - DllCanUnloadNow
+// - DllRegisterServer
+// - DllUnregisterServer
+// - DllGetClassObject
+//
+//////////////////////////////////////////////////////////////////////////
+#include "stdafx.h"
+
+#ifdef MF_WPP
+#include "dllmain.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+
+//
+// The static variable needed to check the object count of the deviceMFts loaded.
+//
+
+volatile long CDMFTModuleLifeTimeManager::s_lObjectCount = 0;
+
+
+
+HRESULT RegisterObject(HMODULE hModule, REFGUID guid, PCWSTR pszDescription, PCWSTR pszThreadingModel);
+
+HRESULT UnregisterObject(const GUID& guid);
+
+
+// Module Ref count
+long g_cRefModule = 0;
+
+// Handle to the DLL's module
+HMODULE g_hModule = NULL;
+
+void DllAddRef()
+{
+ InterlockedIncrement(&g_cRefModule);
+}
+
+void DllRelease()
+{
+ InterlockedDecrement(&g_cRefModule);
+}
+
+//
+// IClassFactory implementation
+//
+
+typedef HRESULT (*PFNCREATEINSTANCE)(REFIID riid, void **ppvObject);
+struct CLASS_OBJECT_INIT
+{
+ const CLSID *pClsid;
+ PFNCREATEINSTANCE pfnCreate;
+};
+
+// Classes supported by this module:
+const CLASS_OBJECT_INIT c_rgClassObjectInit[] =
+{
+ { &CLSID_AvsCameraDMFT, MFT_CreateInstance },
+};
+
+class CClassFactory : public IClassFactory
+{
+public:
+
+ static HRESULT CreateInstance(
+ REFCLSID clsid, // The CLSID of the object to create (from DllGetClassObject)
+ const CLASS_OBJECT_INIT *pClassObjectInits, // Array of class factory data.
+ size_t cClassObjectInits, // Number of elements in the array.
+ REFIID riid, // The IID of the interface to retrieve (from DllGetClassObject)
+ void **ppv // Receives a pointer to the interface.
+ )
+ {
+ *ppv = NULL;
+
+ HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
+
+ for (size_t i = 0; i < cClassObjectInits; i++)
+ {
+ if (clsid == *pClassObjectInits[i].pClsid)
+ {
+ IClassFactory *pClassFactory = new (std::nothrow) CClassFactory(pClassObjectInits[i].pfnCreate);
+
+ if (pClassFactory)
+ {
+ hr = pClassFactory->QueryInterface(riid, ppv);
+ pClassFactory->Release();
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ break; // match found
+ }
+ }
+ return hr;
+ }
+
+ // IUnknown methods
+ IFACEMETHODIMP QueryInterface(REFIID riid, void ** ppv)
+ {
+#if 0
+ static const QITAB qit[] =
+ {
+ QITABENT(CClassFactory, IClassFactory),
+ { 0 }
+ };
+ return QISearch(this, qit, riid, ppv);
+
+#else
+ if (riid == __uuidof(IClassFactory))
+ {
+ *ppv = static_cast< IClassFactory* >(this);
+ AddRef();
+ }
+ return S_OK;
+#endif
+ }
+
+ IFACEMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ IFACEMETHODIMP_(ULONG) Release()
+ {
+ long cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0)
+ {
+ delete this;
+ }
+ return cRef;
+ }
+
+ // IClassFactory methods
+
+ IFACEMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
+ {
+ return punkOuter ? CLASS_E_NOAGGREGATION : m_pfnCreate(riid, ppv);
+ }
+
+ IFACEMETHODIMP LockServer(BOOL fLock)
+ {
+ if (fLock)
+ {
+ DllAddRef();
+ }
+ else
+ {
+ DllRelease();
+ }
+ return S_OK;
+ }
+
+private:
+
+ CClassFactory(PFNCREATEINSTANCE pfnCreate) : m_cRef(1), m_pfnCreate(pfnCreate)
+ {
+ DllAddRef();
+ }
+
+ ~CClassFactory()
+ {
+ DllRelease();
+ }
+
+ long m_cRef;
+ PFNCREATEINSTANCE m_pfnCreate;
+};
+
+
+
+//
+// Standard DLL functions
+//
+
+IFACEMETHODIMP_(BOOL) WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void*)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hModule = (HMODULE)hInstance;
+ DisableThreadLibraryCalls(hInstance);
+#ifdef MF_WPP
+ WPP_INIT_TRACING(L"MultiPinMft");
+#endif
+ }
+ else
+ if (dwReason == DLL_PROCESS_DETACH)
+ {
+#ifdef MF_WPP
+ WPP_CLEANUP();
+#endif
+ }
+ return TRUE;
+}
+
+IFACEMETHODIMP DllCanUnloadNow()
+{
+ HRESULT hr = ((g_cRefModule == 0) && (CDMFTModuleLifeTimeManager::GetDMFTObjCount() == 0)) ? S_OK : S_FALSE;
+ //
+ // Debug object lifetimes
+ //
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! returning %d %d %!HRESULT!",
+ g_cRefModule,
+ CDMFTModuleLifeTimeManager::GetDMFTObjCount(),
+ hr);
+
+ return hr;
+
+}
+
+_Check_return_
+STDAPI DllGetClassObject(_In_ REFCLSID clsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)
+{
+ return CClassFactory::CreateInstance(clsid, c_rgClassObjectInit, ARRAYSIZE(c_rgClassObjectInit), riid, ppv);
+}
+
+IFACEMETHODIMP DllRegisterServer()
+{
+ assert(g_hModule != NULL);
+
+ // Register the CLSID for CoCreateInstance.
+ HRESULT hr = RegisterObject(g_hModule, CLSID_AvsCameraDMFT, TEXT("Multiple MFTs"), TEXT("Both"));
+
+ return hr;
+}
+
+IFACEMETHODIMP DllUnregisterServer()
+{
+ // Unregister the CLSID.
+ UnregisterObject(CLSID_AvsCameraDMFT);
+
+ return S_OK;
+}
+
+
+// Converts a CLSID into a string with the form "CLSID\{clsid}"
+IFACEMETHODIMP CreateObjectKeyName(REFGUID guid, _Out_writes_(cchMax) PWSTR pszName, DWORD cchMax)
+{
+ const DWORD chars_in_guid = 39;
+
+ // convert CLSID uuid to string
+ OLECHAR szCLSID[chars_in_guid];
+ HRESULT hr = StringFromGUID2(guid, szCLSID, chars_in_guid);
+ if (SUCCEEDED(hr))
+ {
+ // Create a string of the form "CLSID\{clsid}"
+ hr = StringCchPrintf((STRSAFE_LPWSTR)pszName, cchMax, TEXT("Software\\Classes\\CLSID\\%ls"), szCLSID);
+ }
+ return hr;
+}
+
+// Creates a registry key (if needed) and sets the default value of the key
+IFACEMETHODIMP CreateRegKeyAndValue(HKEY hKey, PCWSTR pszSubKeyName, PCWSTR pszValueName,
+ PCWSTR pszData, PHKEY phkResult)
+{
+ *phkResult = NULL;
+ LONG lRet = RegCreateKeyExW(
+ hKey, pszSubKeyName,
+ 0, NULL, REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS, NULL, phkResult, NULL);
+
+ if (lRet == ERROR_SUCCESS)
+ {
+ lRet = RegSetValueExW(
+ (*phkResult),
+ pszValueName, 0, REG_SZ,
+ (LPBYTE) pszData,
+ ((DWORD) wcslen(pszData) + 1) * sizeof(WCHAR)
+ );
+
+ if (lRet != ERROR_SUCCESS)
+ {
+ RegCloseKey(*phkResult);
+ }
+ }
+
+ return HRESULT_FROM_WIN32(lRet);
+}
+
+// Creates the registry entries for a COM object.
+
+HRESULT RegisterObject(HMODULE hModule, const GUID& guid, const TCHAR *pszDescription, const TCHAR *pszThreadingModel)
+{
+ HKEY hKey = NULL;
+ HKEY hSubkey = NULL;
+ TCHAR achTemp[MAX_PATH];
+
+ // Create the name of the key from the object's CLSID
+ HRESULT hr = CreateObjectKeyName(guid, achTemp, MAX_PATH);
+
+ // Create the new key.
+ if (SUCCEEDED(hr))
+ {
+ hr = CreateRegKeyAndValue(HKEY_LOCAL_MACHINE, achTemp, NULL, pszDescription,&hKey);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ (void)GetModuleFileName(hModule, achTemp, MAX_PATH);
+
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ // Create the "InprocServer32" subkey
+ if (SUCCEEDED(hr))
+ {
+ hr = CreateRegKeyAndValue(hKey, L"InProcServer32", NULL, achTemp, &hSubkey);
+ RegCloseKey(hSubkey);
+ }
+
+ // Add a new value to the subkey, for "ThreadingModel" = <threading model>
+ if (SUCCEEDED(hr))
+ {
+ hr = CreateRegKeyAndValue(hKey, L"InProcServer32", L"ThreadingModel", pszThreadingModel, &hSubkey);
+ RegCloseKey(hSubkey);
+ }
+
+ // close hkeys
+ RegCloseKey(hKey);
+ return hr;
+}
+
+// Deletes the registry entries for a COM object.
+
+HRESULT UnregisterObject(const GUID& guid)
+{
+ WCHAR achTemp[MAX_PATH];
+
+ HRESULT hr = CreateObjectKeyName(guid, achTemp, MAX_PATH);
+ if (SUCCEEDED(hr))
+ {
+ // Delete the key recursively.
+ LONG lRes = RegDeleteTree(HKEY_LOCAL_MACHINE, achTemp);
+ hr = HRESULT_FROM_WIN32(lRes);
+ }
+ return hr;
+}
+
+
diff --git a/avstream/avscamera/DMFT/mftpeventgenerator.cpp b/avstream/avscamera/DMFT/mftpeventgenerator.cpp
new file mode 100644
index 00000000..1e510cfa
--- /dev/null
+++ b/avstream/avscamera/DMFT/mftpeventgenerator.cpp
@@ -0,0 +1,234 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#include "stdafx.h"
+#include "common.h"
+#include "mftpeventgenerator.h"
+
+
+
+#ifdef MF_WPP
+#include "mftpeventgenerator.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+
+CMediaEventGenerator::CMediaEventGenerator () :
+ m_nRefCount(0),
+ m_pQueue(NULL),
+ m_bShutdown(FALSE)
+{
+ //Call this explicit...
+ InitMediaEventGenerator();
+}
+
+STDMETHODIMP CMediaEventGenerator::InitMediaEventGenerator(
+ void
+ )
+{
+
+ return MFCreateEventQueue(&m_pQueue);
+
+}
+
+STDMETHODIMP_(ULONG) CMediaEventGenerator::AddRef(
+ void
+ )
+{
+ return InterlockedIncrement(&m_nRefCount);
+}
+
+STDMETHODIMP_(ULONG) CMediaEventGenerator::Release(
+ void
+ )
+{
+ ULONG uCount = InterlockedDecrement(&m_nRefCount);
+
+ if (uCount == 0)
+ {
+ delete this;
+ }
+ return uCount;
+}
+
+STDMETHODIMP CMediaEventGenerator::QueryInterface(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv)
+{
+ HRESULT hr = S_OK;
+
+ *ppv = NULL;
+
+ if (iid == __uuidof(IUnknown) || iid == __uuidof(IMFMediaEventGenerator))
+ {
+ *ppv = static_cast<IMFMediaEventGenerator*>(this);
+ AddRef();
+ }
+ else
+ {
+ hr = E_NOINTERFACE;
+ }
+
+ return hr;
+}
+
+//
+// IMediaEventGenerator methods
+//
+STDMETHODIMP CMediaEventGenerator::BeginGetEvent(
+ _In_ IMFAsyncCallback* pCallback,
+ _In_ IUnknown* pState
+ )
+{
+ HRESULT hr = S_OK;
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+
+ if (SUCCEEDED(hr))
+ {
+ hr = m_pQueue->BeginGetEvent(pCallback, pState);
+ }
+
+ m_critSec.Unlock();
+
+ return hr;
+}
+
+STDMETHODIMP CMediaEventGenerator::EndGetEvent(
+ _In_ IMFAsyncResult* pResult,
+ _Outptr_result_maybenull_ IMFMediaEvent** ppEvent
+ )
+{
+ HRESULT hr = S_OK;
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+
+ if (SUCCEEDED(hr))
+ {
+ hr = m_pQueue->EndGetEvent(pResult, ppEvent);
+ }
+
+ m_critSec.Unlock();
+
+ return hr;
+}
+
+STDMETHODIMP CMediaEventGenerator::GetEvent(
+ _In_ DWORD dwFlags,
+ _Outptr_result_maybenull_ IMFMediaEvent** ppEvent
+ )
+{
+ //
+ // Because GetEvent can block indefinitely, it requires
+ // a slightly different locking strategy.
+ //
+ HRESULT hr = S_OK;
+ IMFMediaEventQueue *pQueue = NULL;
+
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+ //
+ // Store the pointer in a local variable, so that another thread
+ // does not release it after we leave the critical section.
+ //
+ if (SUCCEEDED(hr))
+ {
+ pQueue = m_pQueue;
+ }
+
+ m_critSec.Unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ hr = pQueue->GetEvent(dwFlags, ppEvent);
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CMediaEventGenerator::QueueEvent(
+ _In_ MediaEventType met,
+ _In_ REFGUID extendedType,
+ _In_ HRESULT hrStatus,
+ _In_opt_ const PROPVARIANT* pvValue
+ )
+{
+ HRESULT hr = S_OK;
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+
+ if (SUCCEEDED(hr))
+ {
+
+ hr = m_pQueue->QueueEventParamVar(
+ met,
+ extendedType,
+ hrStatus,
+ pvValue
+ );
+ }
+
+ m_critSec.Unlock();
+
+ return hr;
+}
+
+STDMETHODIMP CMediaEventGenerator::ShutdownEventGenerator(
+ void
+ )
+{
+ HRESULT hr = S_OK;
+
+
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+
+ if (SUCCEEDED(hr))
+ {
+ if (m_pQueue)
+ {
+ hr = m_pQueue->Shutdown();
+ }
+ SAFE_RELEASE(m_pQueue);
+ m_bShutdown = TRUE;
+ }
+ m_critSec.Unlock();
+
+ return hr;
+}
+
+STDMETHODIMP CMediaEventGenerator::QueueEvent(
+ _In_ IMFMediaEvent* pEvent
+ )
+{
+ HRESULT hr = S_OK;
+ m_critSec.Lock();
+
+ hr = CheckShutdown();
+
+ if (SUCCEEDED(hr))
+ {
+ if (m_pQueue)
+ {
+ hr = m_pQueue->QueueEvent(pEvent);
+ }
+ }
+
+ m_critSec.Unlock();
+ return hr;
+}
+
+CMediaEventGenerator::~CMediaEventGenerator (
+ void
+ )
+{
+ ShutdownEventGenerator();
+}
diff --git a/avstream/avscamera/DMFT/mftpeventgenerator.h b/avstream/avscamera/DMFT/mftpeventgenerator.h
new file mode 100644
index 00000000..2ddae218
--- /dev/null
+++ b/avstream/avscamera/DMFT/mftpeventgenerator.h
@@ -0,0 +1,94 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+#pragma once
+
+class CMediaEventGenerator :
+ public IMFMediaEventGenerator
+{
+
+public:
+
+ //
+ // IUnknown
+ //
+ STDMETHOD_(ULONG, AddRef)(
+ void
+ );
+
+ STDMETHOD_(ULONG, Release)(
+ void
+ );
+
+ STDMETHOD(QueryInterface)(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv);
+
+
+ //
+ // IMFMediaEventGenerator
+ //
+ STDMETHOD(BeginGetEvent)(
+ _In_ IMFAsyncCallback* pCallback,
+ _In_ IUnknown* pState
+ );
+
+ STDMETHOD(EndGetEvent)(
+ _In_ IMFAsyncResult* pResult,
+ _Outptr_result_maybenull_ IMFMediaEvent** ppEvent
+ );
+
+ STDMETHOD(GetEvent)(
+ _In_ DWORD dwFlags,
+ _Outptr_result_maybenull_ IMFMediaEvent** ppEvent
+ );
+
+ STDMETHOD(QueueEvent)(
+ _In_ MediaEventType met,
+ _In_ REFGUID extendedType,
+ _In_ HRESULT hrStatus,
+ _In_opt_ const PROPVARIANT* pvValue
+ );
+
+ STDMETHOD(QueueEvent)(
+ _In_ IMFMediaEvent* pEvent
+ );
+
+protected:
+
+ CMediaEventGenerator(
+ void
+ );
+
+ virtual ~CMediaEventGenerator (
+ void
+ );
+ //
+ // Utility Methods
+ //
+ STDMETHOD(ShutdownEventGenerator)(
+ void
+ );
+
+ STDMETHOD (InitMediaEventGenerator)(
+ void
+ );
+
+ __inline HRESULT (CheckShutdown)(
+ void
+ ) const
+ {
+ return (m_bShutdown? MF_E_SHUTDOWN : S_OK);
+ }
+
+private:
+
+ long m_nRefCount;
+ CCritSec m_critSec;
+ IMFMediaEventQueue* m_pQueue;
+ BOOL m_bShutdown;
+};
diff --git a/avstream/avscamera/DMFT/packages.config b/avstream/avscamera/DMFT/packages.config
new file mode 100644
index 00000000..26065b14
--- /dev/null
+++ b/avstream/avscamera/DMFT/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" />
+</packages> \ No newline at end of file
diff --git a/avstream/avscamera/DMFT/stdafx.h b/avstream/avscamera/DMFT/stdafx.h
new file mode 100644
index 00000000..d21def93
--- /dev/null
+++ b/avstream/avscamera/DMFT/stdafx.h
@@ -0,0 +1,47 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#pragma once
+
+
+#include <SDKDDKVer.h>
+#include <windows.h>
+#include <winnt.h>
+#include <tchar.h>
+#include <comdef.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <Strsafe.h>
+#include <wchar.h>
+#include <stdio.h>
+#include <assert.h>
+#include <mfidl.h>
+#include <wincodec.h>
+#include <mfapi.h>
+#include <mftransform.h>
+#include <mfidl.h>
+#include <mferror.h>
+#include <mftransform.h>
+#include <time.h>
+#include <initguid.h>
+#include <d3d9.h>
+#include <dxva2api.h>
+#include <d3d11.h>
+#include <mfcaptureengine.h>
+#include <algorithm>
+#include <new>
+#include <d3d11_4.h>
+#include <vector>
+#include <map>
+#include <stdexcept>
+using namespace std;
+#include <Windows.Foundation.h>
+#include <wrl\client.h>
+using namespace ABI::Windows::Foundation;
+using namespace Microsoft::WRL;
+
+#include "common.h"
+#include "AvsCameraDMFT.h"
+#include "basepin.h"
+#include "metadataInternal.h"
diff --git a/avstream/avscamera/DMFT/stdafxsrc.cpp b/avstream/avscamera/DMFT/stdafxsrc.cpp
new file mode 100644
index 00000000..a6f44b0e
--- /dev/null
+++ b/avstream/avscamera/DMFT/stdafxsrc.cpp
@@ -0,0 +1,4 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+#include "stdafx.h" \ No newline at end of file
diff --git a/avstream/avscamera/Package/package.VcxProj b/avstream/avscamera/Package/package.VcxProj
index 32eb3354..885619ba 100644
--- a/avstream/avscamera/Package/package.VcxProj
+++ b/avstream/avscamera/Package/package.VcxProj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -19,8 +19,8 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\mft0\AvsCameraMft0.vcxproj">
- <Project>{2C0B129E-88F3-479A-AE5D-65609A88BE66}</Project>
+ <ProjectReference Include="..\DMFT\AvsCameraDMFT.vcxproj">
+ <Project>{e77657cd-a270-49e1-823a-8a14ff8596c8}</Project>
</ProjectReference>
<ProjectReference Include="..\sys\AvsCamera.vcxproj">
<Project>{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}</Project>
@@ -39,15 +39,11 @@
<SampleGuid>{B28A4CED-96FB-4426-8E77-15A9C0BCFDD5}</SampleGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
@@ -55,6 +51,10 @@
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -79,22 +79,22 @@
<VerifyDrivers />
<VerifyFlags>133563</VerifyFlags>
</PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
diff --git a/avstream/avscamera/README.md b/avstream/avscamera/README.md
index da8e8d65..2cfde98c 100644
--- a/avstream/avscamera/README.md
+++ b/avstream/avscamera/README.md
@@ -15,7 +15,7 @@ The AvsCamera sample provides a pin-centric AVStream capture driver for a simula
This sample features strong parameter validation and overflow detection. It provides validation and simulation logic for all advanced camera controls in the CCaptureFilter class. A real camera driver would replace the filter automation table and CSensor and CSynthesizer class hierarchies to produce a new camera driver.
-The sample comes with its own MFT0 called AvsCameraMft0.dll. This MFT0 is used to parse metadata supplied in the AvsCamera driver samples. The metadata communications from the driver is primarily a private channel to its MFT0. The MFT0 is responsible for reformatting that information for the capture pipeline.
+The sample comes with its own DeviceMFT called AvsCameraMft0.dll. This DeviceMFT is used to parse metadata supplied in the AvsCamera driver samples. The metadata communications from the driver is primarily a private channel to its DeviceMFT. The DeviceMFT is responsible for reformatting that information for the capture pipeline.
## Universal Windows Driver Compliant
@@ -23,4 +23,4 @@ This sample builds a Universal Windows Driver. It uses only APIs and DDIs that a
## Building the sample
-The AvsCamera sample can be built by opening the AvsCamera.sln solution file. A successful build produces AvsCamera.sys, AvsCameraMft0.dll, AvsCamera.inf and AvsCamera.cat.
+The AvsCamera sample can be built by opening the AvsCamera.sln solution file. A successful build produces AvsCamera.sys, AvsCameraDMFT.dll, AvsCamera.inf and AvsCamera.cat.
diff --git a/avstream/avscamera/avscamera.sln b/avstream/avscamera/avscamera.sln
index faa04506..0d913b7b 100644
--- a/avstream/avscamera/avscamera.sln
+++ b/avstream/avscamera/avscamera.sln
@@ -1,59 +1,65 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34009.444
MinimumVisualStudioVersion = 12.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{174AB66C-6250-4DDB-88C5-856B9D499DB7}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mft0", "Mft0", "{8031E506-AE20-4995-9F28-2D177A1FB319}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{72571B45-7827-4380-8821-38A33FBFF4E2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{9397D285-8C29-4661-A741-F6703E2F5FD6}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvsCameraMft0", "mft0\AvsCameraMft0.vcxproj", "{2C0B129E-88F3-479A-AE5D-65609A88BE66}"
+ ProjectSection(ProjectDependencies) = postProject
+ {E77657CD-A270-49E1-823A-8A14FF8596C8} = {E77657CD-A270-49E1-823A-8A14FF8596C8}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvsCamera", "sys\AvsCamera.vcxproj", "{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvsCameraDMFT", "DMFT\AvsCameraDMFT.vcxproj", "{E77657CD-A270-49E1-823A-8A14FF8596C8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DMFT", "DMFT", "{08C63CB6-78C2-44EC-AA24-8CBA0CFEE2E6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
+ Debug|ARM64 = Debug|ARM64
+ Release|ARM64 = Release|ARM64
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|Win32.ActiveCfg = Debug|Win32
- {9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|Win32.Build.0 = Debug|Win32
- {9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|Win32.ActiveCfg = Release|Win32
- {9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|Win32.Build.0 = Release|Win32
+ {9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|ARM64.Build.0 = Debug|ARM64
+ {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|ARM64.Build.0 = Debug|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|ARM64.Build.0 = Debug|ARM64
+ {9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|ARM64.ActiveCfg = Release|ARM64
+ {9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|ARM64.Build.0 = Release|ARM64
+ {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|ARM64.ActiveCfg = Release|ARM64
+ {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|ARM64.Build.0 = Release|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|ARM64.ActiveCfg = Release|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|ARM64.Build.0 = Release|ARM64
{9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|x64.ActiveCfg = Debug|x64
{9397D285-8C29-4661-A741-F6703E2F5FD6}.Debug|x64.Build.0 = Debug|x64
{9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|x64.ActiveCfg = Release|x64
{9397D285-8C29-4661-A741-F6703E2F5FD6}.Release|x64.Build.0 = Release|x64
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Debug|Win32.ActiveCfg = Debug|Win32
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Debug|Win32.Build.0 = Debug|Win32
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Release|Win32.ActiveCfg = Release|Win32
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Release|Win32.Build.0 = Release|Win32
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Debug|x64.ActiveCfg = Debug|x64
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Debug|x64.Build.0 = Debug|x64
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Release|x64.ActiveCfg = Release|x64
- {2C0B129E-88F3-479A-AE5D-65609A88BE66}.Release|x64.Build.0 = Release|x64
- {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|Win32.ActiveCfg = Debug|Win32
- {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|Win32.Build.0 = Debug|Win32
- {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|Win32.ActiveCfg = Release|Win32
- {24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|Win32.Build.0 = Release|Win32
{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|x64.ActiveCfg = Debug|x64
{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Debug|x64.Build.0 = Debug|x64
{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|x64.ActiveCfg = Release|x64
{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68}.Release|x64.Build.0 = Release|x64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|x64.ActiveCfg = Debug|x64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|x64.Build.0 = Debug|x64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|x64.ActiveCfg = Release|x64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9397D285-8C29-4661-A741-F6703E2F5FD6} = {174AB66C-6250-4DDB-88C5-856B9D499DB7}
- {2C0B129E-88F3-479A-AE5D-65609A88BE66} = {8031E506-AE20-4995-9F28-2D177A1FB319}
{24D35D6E-BDB0-4949-8A34-7DD25F0E8F68} = {72571B45-7827-4380-8821-38A33FBFF4E2}
+ {E77657CD-A270-49E1-823A-8A14FF8596C8} = {08C63CB6-78C2-44EC-AA24-8CBA0CFEE2E6}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2191F306-963C-4507-99DB-A9D54CB8615B}
EndGlobalSection
EndGlobal
diff --git a/avstream/avscamera/mft0/AvsCameraMFT0.rc b/avstream/avscamera/mft0/AvsCameraMFT0.rc
deleted file mode 100644
index 86c06ba2..00000000
--- a/avstream/avscamera/mft0/AvsCameraMFT0.rc
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <windows.h>
-#include <ntverp.h>
-
-
-#define VER_FILETYPE VFT_DLL
-#define VER_FILESUBTYPE VFT2_UNKNOWN
-#define VER_FILEDESCRIPTION_STR "A/V Stream Camera MFT0"
-#define VER_INTERNALNAME_STR "AvsCameraMft0.dll"
-#define VER_ORIGINALFILENAME_STR "AvsCameraMft0.dll"
-#define VER_LANGNEUTRAL
-
-#include "common.ver"
-
diff --git a/avstream/avscamera/mft0/AvsCameraMft0.vcxproj b/avstream/avscamera/mft0/AvsCameraMft0.vcxproj
deleted file mode 100644
index 518a324f..00000000
--- a/avstream/avscamera/mft0/AvsCameraMft0.vcxproj
+++ /dev/null
@@ -1,216 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{2C0B129E-88F3-479A-AE5D-65609A88BE66}</ProjectGuid>
- <RootNamespace>$(MSBuildProjectName)</RootNamespace>
- <SupportsPackaging>false</SupportsPackaging>
- <RequiresPackageProject>true</RequiresPackageProject>
- <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{1921F93C-296D-4875-BD67-D087F1DBF95B}</SampleGuid>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <PropertyGroup>
- <OutDir>$(IntDir)</OutDir>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ItemGroup Label="WrappedTaskItems" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <TargetName>AvsCameraMft0</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <TargetName>AvsCameraMft0</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>AvsCameraMft0</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>AvsCameraMft0</TargetName>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <ExceptionHandling>Sync</ExceptionHandling>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <ExceptionHandling>Sync</ExceptionHandling>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <ExceptionHandling>Sync</ExceptionHandling>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <ExceptionHandling>Sync</ExceptionHandling>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SDK_INC_PATH)\ks;..\common</AdditionalIncludeDirectories>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);mfplat.lib;uuid.lib;mfuuid.lib;OneCoreUAP.lib</AdditionalDependencies>
- <ModuleDefinitionFile>Mft0.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);mfplat.lib;uuid.lib;mfuuid.lib;OneCoreUAP.lib</AdditionalDependencies>
- <ModuleDefinitionFile>Mft0.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);mfplat.lib;uuid.lib;mfuuid.lib;OneCoreUAP.lib</AdditionalDependencies>
- <ModuleDefinitionFile>Mft0.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);mfplat.lib;uuid.lib;mfuuid.lib;OneCoreUAP.lib</AdditionalDependencies>
- <ModuleDefinitionFile>Mft0.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="$(IntDir)\Mft0_i.c" />
- <ClCompile Include="dllmain.cpp">
- <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
- <PreCompiledHeader>Use</PreCompiledHeader>
- <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
- </ClCompile>
- <ClCompile Include="Mft0Impl.cpp">
- <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
- <PreCompiledHeader>Use</PreCompiledHeader>
- <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
- </ClCompile>
- <ClCompile Include="stdafxsrc.cpp">
- <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
- <PreCompiledHeader>Create</PreCompiledHeader>
- <PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
- </ClCompile>
- <Midl Include="Mft0.idl" />
- <ResourceCompile Include="AvsCameraMft0.rc" />
- </ItemGroup>
- <ItemGroup>
- <Inf Exclude="@(Inf)" Include="*.inf" />
- <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
- </ItemGroup>
- <ItemGroup>
- <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
- <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
- <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project> \ No newline at end of file
diff --git a/avstream/avscamera/mft0/MFT0.def b/avstream/avscamera/mft0/MFT0.def
deleted file mode 100644
index b4430ceb..00000000
--- a/avstream/avscamera/mft0/MFT0.def
+++ /dev/null
@@ -1,13 +0,0 @@
-; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-; ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-; PARTICULAR PURPOSE.
-; Copyright (c) Microsoft Corporation. All rights reserved
-
-; SampleMft0.def : Declares the module parameters.
-
-LIBRARY
-
-EXPORTS
- DllCanUnloadNow PRIVATE
- DllGetClassObject PRIVATE \ No newline at end of file
diff --git a/avstream/avscamera/mft0/MFT0.idl b/avstream/avscamera/mft0/MFT0.idl
deleted file mode 100644
index 40098f71..00000000
--- a/avstream/avscamera/mft0/MFT0.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-//// PARTICULAR PURPOSE.
-////
-//// Copyright (c) Microsoft Corporation. All rights reserved
-
-// SampleMft0.idl : IDL source for SampleMft0
-//
-
-// This file will be processed by the MIDL tool to
-// produce the type library (SampleMft0.tlb) and marshalling code.
-
-import "oaidl.idl";
-import "ocidl.idl";
-import "Inspectable.idl";
-import "mftransform.idl";
-[
- object,
- uuid(7B917902-D657-4437-9F93-93B94482F286),
- oleautomation,
- nonextensible,
- pointer_default(unique)
-]
-interface ISocMft0 : IUnknown{
- [id(1)] HRESULT SetState([in] UINT32 state);
- [id(2)] HRESULT GetState([out] UINT* pState);
-};
-[
- uuid(8F14E328-2084-442E-A4D9-A80AA30ECBA8),
- version(1.0),
-]
-library SampleSocMft0Lib
-{
- importlib("stdole2.tlb");
- [
- uuid(424BF154-D92A-42EB-B041-1395F9E5B4A2)
- ]
- coclass Mft0
- {
- [default] interface ISocMft0;
- interface IInspectable;
- interface IMFTransform;
- };
-};
-
diff --git a/avstream/avscamera/mft0/MFT0Impl.cpp b/avstream/avscamera/mft0/MFT0Impl.cpp
deleted file mode 100644
index 26d40f99..00000000
--- a/avstream/avscamera/mft0/MFT0Impl.cpp
+++ /dev/null
@@ -1,2083 +0,0 @@
-/**************************************************************************
-
- A/V Stream Camera Sample
-
- Copyright (c) 2014, Microsoft Corporation.
-
- File:
-
- Mft0Impl.cpp
-
- Abstract:
-
- This is the implementation of CSocMft0.
-
- CSocMft0 is the MFT0 for the AvsCamera sample driver. This MFT0
- performs the following key tasks:
- 1. Filters overscan media types supplied by the driver, and
- 2. Parses private metadata and attaches an IMFAttribute to the sample.
-
- History:
-
- created 5/15/2014
-
-**************************************************************************/
-
-
-#include "stdafx.h"
-#include "Mft0Impl.h"
-#include "SampleHelpers.h"
-#include "metadataInternal.h"
-#include <WinString.h>
-#include <ks.h>
-#include <ksproxy.h>
-#include <initguid.h>
-
-#include "CustomProperties.h"
-#include "macros.h"
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-// These two functions demostrate that OEM application can communicate with MFT0
-//
-STDMETHODIMP CSocMft0::SetState(UINT32 state)
-{
- // OEM can use similar function to update the status of MFT
- // From their own application
- m_uiInternalState = state;
- return S_OK;
-}
-
-STDMETHODIMP CSocMft0::GetState(UINT32 *pState)
-{
- HRESULT hr = S_OK;
-
- // OEM can use similar function to get the status of MFT
- // From their own application
- if (!pState)
- {
- return E_POINTER;
- }
- *pState = m_uiInternalState;
-
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-//
-// This initializes the CSocMFT0 for Com
-//
-//
-HRESULT CSocMft0::CreateInstance(
- REFIID iid,
- void **ppMFT
-)
-{
- HRESULT hr = S_OK;
- ComPtr<IMFTransform> spMFT;
- UNREFERENCED_PARAMETER(iid);
-
- auto sObject = Microsoft::WRL::Make<CSocMft0>();
-
- if (!sObject)
- {
- return E_OUTOFMEMORY;
- }
- hr = sObject->FinalConstruct();
-
- if (SUCCEEDED(hr))
- {
- hr = sObject.As(&spMFT);
- *ppMFT = spMFT.Detach();
- }
-
- return hr;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-// IInspectable interface enable COM interface to talk with other programming environments
-//
-// Gets the interfaces that are implemented by the current Windows Runtime class.
-//
-STDMETHODIMP CSocMft0::GetIids(
- _Out_ ULONG *iidCount,
- _Outptr_result_buffer_maybenull_(*iidCount) IID **iids
-)
-{
- HRESULT hr = S_OK;
-
- if (!iidCount)
- {
- return E_POINTER;
- }
-
- if (!iids)
- {
- return E_POINTER;
- }
-
- *iids = NULL;
- *iidCount = 0;
-
- return hr;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-// Gets the fully qualified name of the current Windows Runtime object.
-//
-STDMETHODIMP CSocMft0::GetRuntimeClassName(
- _Outptr_result_maybenull_ HSTRING *pClassName
-)
-{
-
- if (!pClassName)
- {
- return E_POINTER;
- }
- return WindowsCreateString(NULL, 0, pClassName);
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-// Gets the trust level of the current Windows Runtime object.
-//
-STDMETHODIMP CSocMft0::GetTrustLevel(
- _Out_ TrustLevel *trustLevel
-)
-{
- HRESULT hr = S_OK;
-
- if (trustLevel)
- {
- return E_POINTER;
- }
- *trustLevel = TrustLevel::BaseTrust;
-
- return hr;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// Final Construct
-//
-HRESULT CSocMft0::FinalConstruct()
-{
- HRESULT hr = S_OK;
- hr = MFCreateAttributes(&m_spGlobalAttributes, 3);
- if (FAILED(hr))
- {
- goto done;
- }
-
- hr = m_spGlobalAttributes->SetUINT32(MF_TRANSFORM_ASYNC, FALSE);
- if (FAILED(hr))
- {
- goto done;
- }
-
- hr = m_spGlobalAttributes->SetString(
- MFT_ENUM_HARDWARE_URL_Attribute,
- L"Sample_CameraExtensionMft");
- if (FAILED(hr))
- {
- goto done;
- }
-
- hr = m_spGlobalAttributes->SetUINT32(
- MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE,
- TRUE);
-
-done:
- if (FAILED(hr))
- {
- m_spGlobalAttributes.Reset();
- }
- return hr;
-}
-
-// IMFTransform methods. Refer to the Media Foundation SDK documentation for details.
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetStreamLimits
-// Returns the minimum and maximum number of streams.
-//
-STDMETHODIMP CSocMft0::GetStreamLimits(
- _Out_ DWORD *pdwInputMinimum,
- _Out_ DWORD *pdwInputMaximum,
- _Out_ DWORD *pdwOutputMinimum,
- _Out_ DWORD *pdwOutputMaximum
-)
-{
- if ((!pdwInputMinimum) ||
- (!pdwInputMaximum) ||
- (!pdwOutputMinimum) ||
- (!pdwOutputMaximum))
- {
- return E_POINTER;
- }
-
- // This MFT has a fixed number of streams.
- *pdwInputMinimum = 1;
- *pdwInputMaximum = 1;
- *pdwOutputMinimum = 1;
- *pdwOutputMaximum = 1;
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetStreamCount
-// Returns the actual number of streams.
-//
-STDMETHODIMP CSocMft0::GetStreamCount(
- _Out_ DWORD *pcInputStreams,
- _Out_ DWORD *pcOutputStreams
-)
-{
- if (!pcInputStreams || !pcOutputStreams)
- {
- return E_POINTER;
- }
-
- // This MFT has a fixed number of streams.
- *pcInputStreams = 1;
- *pcOutputStreams = 1;
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetStreamIDs
-// Returns stream IDs for the input and output streams.
-//
-STDMETHODIMP CSocMft0::GetStreamIDs(
- DWORD dwInputIDArraySize,
- _Out_writes_(dwInputIDArraySize) DWORD *pdwInputIDs,
- DWORD dwOutputIDArraySize,
- _Out_writes_(dwOutputIDArraySize) DWORD *pdwOutputIDs
-)
-{
- UNREFERENCED_PARAMETER(dwInputIDArraySize);
- UNREFERENCED_PARAMETER(dwOutputIDArraySize);
- UNREFERENCED_PARAMETER(pdwInputIDs);
- UNREFERENCED_PARAMETER(pdwOutputIDs);
-
- // It is not required to implement this method if the MFT has a fixed number of
- // streams AND the stream IDs are numbered sequentially from zero (that is, the
- // stream IDs match the stream indexes).
-
- // In that case, it is OK to return E_NOTIMPL.
- return (E_NOTIMPL);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetInputStreamInfo
-// Returns information about an input stream.
-//
-STDMETHODIMP CSocMft0::GetInputStreamInfo(
- DWORD dwInputStreamID,
- _Out_ MFT_INPUT_STREAM_INFO *pStreamInfo
-)
-{
- UNREFERENCED_PARAMETER(dwInputStreamID);
- CAutoLock lock(&m_critSec);
-
- if (!pStreamInfo)
- {
- return E_POINTER;
- }
-
- if (!m_spInputType)
- {
- return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
-
- pStreamInfo->hnsMaxLatency = 0;
- pStreamInfo->cbAlignment = 0;
- pStreamInfo->cbSize = 0;
- pStreamInfo->dwFlags =
- MFT_INPUT_STREAM_WHOLE_SAMPLES |
- MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
- MFT_INPUT_STREAM_PROCESSES_IN_PLACE;
- pStreamInfo->hnsMaxLatency = 0;
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetOutputStreamInfo
-// Returns information about an output stream.
-//
-STDMETHODIMP CSocMft0::GetOutputStreamInfo(
- DWORD dwOutputStreamID,
- _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
-)
-{
- UNREFERENCED_PARAMETER(dwOutputStreamID);
- CAutoLock lock(&m_critSec);
-
- if (!pStreamInfo)
- {
- return E_POINTER;
- }
-
- if (!m_spOutputType)
- {
- return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
-
- pStreamInfo->cbAlignment = 0;
- pStreamInfo->cbSize = 0;
- pStreamInfo->dwFlags =
- MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
- MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
- MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
- MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
-
- return S_OK;
-}
-
-/////////////////////////////////////////////////////////////////////////
-//
-// GetAttributes
-// Returns the global attributes for the MFT.
-//
-STDMETHODIMP CSocMft0::GetAttributes(
- _Outptr_result_maybenull_ IMFAttributes **ppAttributes
-)
-{
- if (!ppAttributes)
- {
- return E_POINTER;
- }
-
- return m_spGlobalAttributes.CopyTo(ppAttributes);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetInputStreamAttributes
-// Returns stream-level attributes for an input stream.
-//
-STDMETHODIMP CSocMft0::GetInputStreamAttributes(
- DWORD dwInputStreamID,
- _Outptr_result_maybenull_ IMFAttributes **ppAttributes
-)
-{
- HRESULT hr = S_OK;
-
- if (dwInputStreamID > 0)
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
- if (!ppAttributes)
- {
- return E_POINTER;
- }
-
- if (!m_spInputAttributes)
- {
- hr = MFCreateAttributes(&m_spInputAttributes, 2);
- if (FAILED(hr))
- {
- goto done;
- }
- hr = m_spInputAttributes->SetUINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE);
- if (FAILED(hr))
- {
- goto done;
- }
- hr = m_spInputAttributes->SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft");
- if (FAILED(hr))
- {
- goto done;
- }
- }
- hr = m_spInputAttributes.CopyTo(ppAttributes);
-
-done:
- if (FAILED(hr))
- {
- m_spInputAttributes.Reset();
- }
- return hr;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetOutputStreamAttributes
-// Returns stream-level attributes for an output stream.
-//
-STDMETHODIMP CSocMft0::GetOutputStreamAttributes(
- DWORD dwOutputStreamID,
- _Outptr_result_maybenull_ IMFAttributes **ppAttributes
-)
-{
- if (dwOutputStreamID > 0)
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
- if (!ppAttributes)
- {
- return E_POINTER;
- }
-
- if (!m_spInputAttributes)
- {
- return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
-
- return m_spInputAttributes.CopyTo(ppAttributes);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// DeleteInputStream
-//
-STDMETHODIMP CSocMft0::DeleteInputStream(
- DWORD dwStreamID
-)
-{
- UNREFERENCED_PARAMETER(dwStreamID);
-
- // This MFT has a fixed number of input streams, so the method is not supported.
- return (E_NOTIMPL);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// AddInputStreams
-//
-STDMETHODIMP CSocMft0::AddInputStreams(
- DWORD cStreams,
- _In_ DWORD *adwStreamIDs
-)
-{
- UNREFERENCED_PARAMETER(cStreams);
- UNREFERENCED_PARAMETER(adwStreamIDs);
-
- // This MFT has a fixed number of output streams, so the method is not supported.
- return (E_NOTIMPL);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetInputAvailableType
-// Returns a preferred input type.
-//
-STDMETHODIMP CSocMft0::GetInputAvailableType(
- DWORD dwInputStreamID,
- DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- HRESULT hr = S_OK;
- ComPtr<IUnknown> spUnknown;
- ComPtr<IMFAttributes> spSourceAttributes;
-
- CAutoLock lock(&m_critSec);
-
- if (!m_spSourceTransform && m_spInputAttributes)
- {
- hr = m_spInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(spSourceAttributes.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(spUnknown.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spUnknown.As(&m_spSourceTransform);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetUINT32(MF_DEVICESTREAM_STREAM_ID, &m_uiSourceStreamId);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = GenerateMFMediaTypeListFromDevice();
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- hr = GetMediaType(dwInputStreamID, dwTypeIndex, ppType);
-
- return hr;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetOutputAvailableType
-// Returns a preferred output type.
-//
-STDMETHODIMP CSocMft0::GetOutputAvailableType(
- DWORD dwOutputStreamID,
- DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- HRESULT hr = S_OK;
- ComPtr<IUnknown> spUnknown;
- ComPtr<IMFAttributes> spSourceAttributes;
-
- CAutoLock lock(&m_critSec);
-
- if (!m_spSourceTransform && m_spInputAttributes)
- {
- hr = m_spInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(spSourceAttributes.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(spUnknown.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spUnknown.As(&m_spSourceTransform);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = spSourceAttributes->GetUINT32(MF_DEVICESTREAM_STREAM_ID, &m_uiSourceStreamId);
- if (FAILED(hr))
- {
- return hr;
- }
-
- //
- // This is the first function get called after the MFT0 object get instantiated,
- // Here we can generate the supported media type from the connected input pin,
- // Also, we can selectively plug in MFT0 only on pins requires processing
- // by returning error on the unwanted pin types. Example below if we did not
- // want MFT0 for Record
-
- //if(m_stStreamType != PINNAME_IMAGE && m_stStreamType != PINNAME_VIDEO_PREVIEW)
- //{
- // return E_UNEXPECTED;
- //}
-
- hr = GenerateMFMediaTypeListFromDevice();
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- return GetMediaType(dwOutputStreamID, dwTypeIndex, ppType);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// SetInputType
-//
-STDMETHODIMP CSocMft0::SetInputType(
- DWORD dwInputStreamID,
- _In_opt_ IMFMediaType *pType,
- DWORD dwFlags
-)
-{
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
-
- // Validate flags.
- // Only MFT_SET_TYPE_TEST_ONLY is supported, if any other bit flags
- // get set, it should return error.
- if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
- {
- return E_INVALIDARG;
- }
-
- if (!bReallySet)
- {
- return IsMediaTypeSupported(dwInputStreamID, pType);
- }
-
- ComPtr<IMFMediaType> spFullType;
- hr = IsMediaTypeSupported(dwInputStreamID, pType, spFullType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- m_spInputType = spFullType;
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// SetOutputType
-// This function set the output media type and at the same time, it should
-// also choose a compatible input type
-//
-STDMETHODIMP CSocMft0::SetOutputType(
- DWORD dwOutputStreamID,
- _In_opt_ IMFMediaType *pType,
- DWORD dwFlags
-)
-{
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
- BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
- BOOL bUseModifiedInputType = FALSE;
-
- // Validate flags.
- if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
- {
- return E_INVALIDARG;
- }
-
- if (!bReallySet)
- {
- return IsMediaTypeSupported(dwOutputStreamID, pType);
- }
-
- ComPtr<IMFMediaType> spFullType;
- ComPtr<IMFMediaType> spFullInputType;
- hr = IsMediaTypeSupported(dwOutputStreamID, pType, spFullType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- if (m_stStreamType == PINNAME_CAPTURE)
- {
- hr = GetVideoStabilizationEnabled();
- if (FAILED(hr))
- {
- return hr;
- }
-
- // Hardware Video Stabilization is enabled
- if (m_bEnableVideoStabilization)
- {
- UINT32 uiIndex = 0;
- //This shouldn't fail, since it is derived from IsMediaTypeSupported
- // and that just passed.
- hr = FindMediaIndex(dwOutputStreamID, pType, &uiIndex);
- if (FAILED(hr))
- {
- return hr;
- }
- //Device Driver contains a static list of mediatypes on the pin
- // We have ordered them in such a way so that all odd mediatypes are the
- // overscan media of the even mediatype immediatley proceeding it, ie.
- // -normalVGA
- // -overscanVGA
- // -normalQVGA
- // -overscanQVGA
- // etc
- // The following command determines if we are dealing with an overscan or normal mediatype
- // if it is overscan, we fail (cannot overscan an overscan mediatype)
- // otherwise, we set our input mediatype to the overscan type associated with it.
- if (uiIndex % 2 != 0) //odd means overscan
- {
- return MF_E_INVALIDMEDIATYPE;
- }
- else //even
- {
- hr = GetMediaType(dwOutputStreamID, uiIndex + 1, spFullInputType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- bUseModifiedInputType = TRUE;
- }
- }
- }
- m_spOutputType = spFullType;
-
- // Here, we choose a compatible input type which is the same type
- // as output. If OEM choose to encode sample here, it should choose
- // an input which is supported by encoder.
- if (bUseModifiedInputType)
- {
- m_spInputType = spFullInputType;
- }
- else
- {
- m_spInputType = spFullType;
- }
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetInputCurrentType
-// Returns the current input type.
-//
-STDMETHODIMP CSocMft0::GetInputCurrentType(
- DWORD dwInputStreamID,
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- UNREFERENCED_PARAMETER(dwInputStreamID);
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- if (!ppType)
- {
- return E_POINTER;
- }
-
- if (!m_spInputType)
- {
- return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
-
- ComPtr<IMFMediaType> spMediaType;
- hr = MFCreateMediaType(spMediaType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = m_spInputType->CopyAllItems(spMediaType.Get());
- if (FAILED(hr))
- {
- return hr;
- }
-
- return spMediaType.CopyTo(ppType);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetOutputCurrentType
-// Returns the current output type.
-//
-STDMETHODIMP CSocMft0::GetOutputCurrentType(
- DWORD dwOutputStreamID,
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- UNREFERENCED_PARAMETER(dwOutputStreamID);
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- if (!ppType)
- {
- return E_POINTER;
- }
-
- if (!m_spOutputType)
- {
- return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
-
- ComPtr<IMFMediaType> spMediaType;
- hr = MFCreateMediaType(spMediaType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = m_spOutputType->CopyAllItems(spMediaType.Get());
- if (FAILED(hr))
- {
- return hr;
- }
-
- return spMediaType.CopyTo(ppType);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetInputStatus
-// Query if the MFT is accepting more input.
-//
-STDMETHODIMP CSocMft0::GetInputStatus(
- DWORD dwInputStreamID,
- _Out_ DWORD *pdwFlags
-)
-{
- UNREFERENCED_PARAMETER(dwInputStreamID);
- CAutoLock lock(&m_critSec);
-
- if (!pdwFlags)
- {
- return E_POINTER;
- }
-
- // If we already have an input sample, we don't accept
- // another one until the client calls ProcessOutput or Flush.
- if (m_spSample == NULL)
- {
- *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
- }
- else
- {
- *pdwFlags = 0;
- }
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// GetOutputStatus
-// Query if the MFT can produce output.
-//
-STDMETHODIMP CSocMft0::GetOutputStatus(
- _Out_ DWORD *pdwFlags
-)
-{
- if (!pdwFlags)
- {
- return E_POINTER;
- }
-
- CAutoLock lock(&m_critSec);
-
- // We can produce an output sample if (and only if)
- // we have an input sample.
- if (m_spSample != NULL)
- {
- *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY;
- }
- else
- {
- *pdwFlags = 0;
- }
-
- return S_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// SetOutputBounds
-// Sets the range of time stamps that the MFT will output.
-//
-STDMETHODIMP CSocMft0::SetOutputBounds(
- LONGLONG hnsLowerBound,
- LONGLONG hnsUpperBound
-)
-{
- UNREFERENCED_PARAMETER(hnsLowerBound);
- UNREFERENCED_PARAMETER(hnsUpperBound);
-
- // Implementation of this method is optional.
- return (E_NOTIMPL);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// ProcessEvent
-// Sends an event to an input stream.
-//
-STDMETHODIMP CSocMft0::ProcessEvent(
- DWORD dwInputStreamID,
- _In_opt_ IMFMediaEvent *pEvent
-)
-{
- UNREFERENCED_PARAMETER(dwInputStreamID);
- UNREFERENCED_PARAMETER(pEvent);
- return E_NOTIMPL;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// ProcessMessage
-//
-STDMETHODIMP CSocMft0::ProcessMessage(
- MFT_MESSAGE_TYPE eMessage,
- ULONG_PTR ulParam
-)
-{
- UNREFERENCED_PARAMETER(ulParam);
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- switch (eMessage)
- {
- case MFT_MESSAGE_COMMAND_FLUSH:
- // Flush the MFT.
- hr = OnFlush();
- break;
- }
-
- return hr;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// ProcessInput
-// Process an input sample. The sample is cached and real work is done
-// in ProcessOutput
-//
-STDMETHODIMP CSocMft0::ProcessInput(
- DWORD dwInputStreamID,
- IMFSample *pSample,
- DWORD dwFlags
-)
-{
- UNREFERENCED_PARAMETER(dwInputStreamID);
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- if (!pSample)
- {
- return E_POINTER;
- }
- if (dwFlags != 0)
- {
- return E_INVALIDARG;
- }
-
- if (!m_spInputType || !m_spOutputType)
- {
- return MF_E_NOTACCEPTING; // Client must set input and output types.
- }
-
- if (m_spSample != NULL)
- {
- return MF_E_NOTACCEPTING; // We already have an input sample.
- }
-
- // Validate the number of buffers. There should only be a single buffer to hold the video frame.
- DWORD dwBufferCount = 0;
- hr = pSample->GetBufferCount(&dwBufferCount);
- if (FAILED(hr))
- {
- return hr;
- }
-
- if (dwBufferCount == 0)
- {
- return E_FAIL;
- }
-
- if (dwBufferCount > 1)
- {
- return MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS;
- }
-
- // Cache the sample. We do the actual work in ProcessOutput.
- m_spSample = pSample;
-
- return S_OK;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// ProcessOutput
-// Process an output sample.
-//
-STDMETHODIMP CSocMft0::ProcessOutput(
- DWORD dwFlags,
- DWORD cOutputBufferCount,
- MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
- DWORD *pdwStatus
-)
-{
- HRESULT hr = S_OK;
-
- CAutoLock lock(&m_critSec);
-
- if (dwFlags != 0)
- {
- return E_INVALIDARG;
- }
-
- if (!pOutputSamples || !pdwStatus)
- {
- return E_POINTER;
- }
-
- if (pOutputSamples[0].pSample)
- {
- pOutputSamples[0].pSample->Release();
- pOutputSamples[0].pSample = nullptr;
- }
-
- // Must be exactly one output buffer.
- if (cOutputBufferCount != 1)
- {
- return E_INVALIDARG;
- }
-
- // If we don't have an input sample, we need some input before
- // we can generate any output.
- if (m_spSample == nullptr)
- {
- return MF_E_TRANSFORM_NEED_MORE_INPUT;
- }
-#if (NTDDI_VERSION >= NTDDI_WINBLUE)
- hr = ProcessMetadata();
- if (FAILED(hr))
- {
- //Log the failure
- hr = S_OK;
- }
-#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
- hr = CreateOutputSample(&pOutputSamples[0].pSample);
- if (FAILED(hr))
- {
- return hr;
- }
- pOutputSamples[0].dwStatus = 0;
- *pdwStatus = 0;
-
- // if createOutputSample actually make a copy of the sample,
- // (for example, JPEG encoding case), we need to copy the
- // attribute from m_spSample to spOutputIMFSample
- m_spSample.Reset();
- return hr;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// The actual processing is here, required operation is demux
-// Other operation is optional
-//
-HRESULT
-CSocMft0::
-CreateOutputSample(
- _Outptr_result_maybenull_
- IMFSample **ppSample
-)
-{
- HRESULT hr = S_OK;
-
- //Do nothing for now
- if (!ppSample)
- {
- return E_POINTER;
- }
-
- m_spSample.CopyTo(ppSample);
-
- return hr;
-}
-/////////////////////////////////////////////////////////////////////
-//
-// Flush the MFT.
-//
-STDMETHODIMP CSocMft0::OnFlush()
-{
- // For this MFT, flushing just means releasing the input sample.
- CAutoLock lock(&m_critSec);
- m_spSample.Reset();
- return S_OK;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// Get the mediaType of selected stream.
-//
-STDMETHODIMP CSocMft0::GetMediaType(
- _In_ DWORD dwStreamId,
- _In_ DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- HRESULT hr = S_OK;
- ComPtr<IMFMediaType> spMediaType;
-
- if (!ppType)
- {
- return E_POINTER;
- }
-
- if (dwStreamId != 0)
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
- if (dwTypeIndex >= m_listOfMediaTypes.size())
- {
- return MF_E_NO_MORE_TYPES;
- }
-
- hr = MFCreateMediaType(spMediaType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = m_listOfMediaTypes[dwTypeIndex]->CopyAllItems(spMediaType.Get());
- if (FAILED(hr))
- {
- return hr;
- }
-
- return spMediaType.CopyTo(ppType);
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// Check if the media type is supported by MFT0.
-//
-STDMETHODIMP CSocMft0::IsMediaTypeSupported(
- _In_ UINT uiStreamId,
- _In_opt_ IMFMediaType *pIMFMediaType,
- _Outptr_opt_result_maybenull_ IMFMediaType **ppIMFMediaTypeFull
-)
-{
- HRESULT hr = S_OK;
-
- if (!pIMFMediaType)
- {
- return E_POINTER;
- }
-
- if (uiStreamId != 0)
- {
- return MF_E_INVALIDINDEX;
- }
-
- BOOL bFound = FALSE;
-
-
- for (UINT i = 0; i < m_listOfMediaTypes.size(); i++)
- {
- DWORD dwResult = 0;
- hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult);
- if (hr == S_FALSE)
- {
- if ((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
- (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
- (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_DATA))
- {
- hr = S_OK;
- }
- }
- if (hr == S_OK)
- {
- bFound = TRUE;
- if (ppIMFMediaTypeFull)
- {
- m_listOfMediaTypes[i].CopyTo(ppIMFMediaTypeFull);
- }
- break;
- }
- else if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (bFound == FALSE)
- {
- return MF_E_INVALIDMEDIATYPE;
- }
-
- return S_OK;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// Check if the media type is supported by MFT0.
-//
-_Success_(return == 0)
-STDMETHODIMP CSocMft0::FindMediaIndex(
- _In_ UINT uiStreamId,
- _In_ IMFMediaType *pIMFMediaType,
- _Out_ UINT *puiMediaIndex
-)
-{
- HRESULT hr = S_OK;
-
- if (!pIMFMediaType || !puiMediaIndex)
- {
- return E_INVALIDARG;
- }
-
- if (uiStreamId != 0)
- {
- return MF_E_INVALIDINDEX;
- }
-
- BOOL bFound = FALSE;
-
- for (UINT i = 0; i < m_listOfMediaTypes.size(); i++)
- {
- DWORD dwResult = 0;
- hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult);
- if (hr == S_FALSE)
- {
- if ((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
- (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
- (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_DATA))
- {
- hr = S_OK;
- }
- }
- if (hr == S_OK)
- {
- bFound = TRUE;
- *puiMediaIndex = i;
- break;
- }
- else if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (bFound == FALSE)
- {
- return MF_E_INVALIDMEDIATYPE;
- }
-
- return S_OK;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// Generate the supported input media type from device source media type
-//
-STDMETHODIMP CSocMft0::GenerateMFMediaTypeListFromDevice()
-{
- HRESULT hr = S_OK;
-
- if (!m_spSourceTransform)
- {
- return MF_E_NOT_FOUND;
- }
-
- m_listOfMediaTypes.clear();
- UINT iMediaType = 0;
- while (SUCCEEDED(hr))
- {
- ComPtr<IMFMediaType> spMediaType;
- hr = m_spSourceTransform->GetOutputAvailableType(m_uiSourceStreamId, iMediaType, spMediaType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- if (hr == MF_E_NO_MORE_TYPES)
- {
- hr = S_OK;
- }
- break;
- }
-
- if (m_stStreamType == PINNAME_IMAGE || m_stStreamType == PINNAME_VIDEO_STILL)
- {
- GUID guidPhotoSubType = {};
- spMediaType->GetGUID(MF_MT_SUBTYPE, &guidPhotoSubType);
- if (IsEqualGUID(guidPhotoSubType, MFVideoFormat_NV12))
- {
- // Need to set MF_MT_VIDEO_NOMINAL_RANGE on NV12 or the pipeline ends up with a copy due to mismatched nominal range
- hr = spMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
-
- m_listOfMediaTypes.push_back(spMediaType);
- }
-
- else if (m_stStreamType == PINNAME_CAPTURE)
- {
- UINT32 width = 0;
- UINT32 height = 0;
- hr = MFGetAttributeSize(spMediaType.Get(), MF_MT_FRAME_SIZE, &width, &height);
- if (FAILED(hr))
- {
- return hr;
- }
-
- MFVideoArea validVideo;
- validVideo.OffsetX.value = 0;
- validVideo.OffsetX.fract = 0;
- validVideo.OffsetY.value = 0;
- validVideo.OffsetY.fract = 0;
- validVideo.Area.cx = width;
- validVideo.Area.cy = height;
- hr = spMediaType->SetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&validVideo, sizeof(validVideo));
- if (FAILED(hr))
- {
- return hr;
- }
-
- m_listOfMediaTypes.push_back(spMediaType);
- }
-
- else
- {
- m_listOfMediaTypes.push_back(spMediaType);
- }
-
- iMediaType++;
- }
-
- return hr;
-}
-
-/////////////////////////////////////////////////////////////////////
-//
-// Get the current media type in order to generate photo confirmation
-//
-HRESULT CSocMft0::GetPreviewMediaType(
- _Outptr_result_maybenull_ IMFMediaType **ppType
-)
-{
- CAutoLock lock(&m_critSec);
- if (!m_spSourceTransform)
- {
- return MF_E_NOT_FOUND;
- }
-
- DWORD dwInStreamCount = 0, dwOutStreamCount = 0;
- HRESULT hr = m_spSourceTransform->GetStreamCount(
- &dwInStreamCount,
- &dwOutStreamCount);
- if (FAILED(hr))
- {
- return hr;
- }
-
- for (UINT32 i = 0; i < dwOutStreamCount; i++)
- {
- ComPtr<IMFAttributes> spAttributes;
- hr = m_spSourceTransform->GetOutputStreamAttributes(i, spAttributes.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- continue;
- }
-
- GUID guidPinCategory = GUID_NULL;
- hr = spAttributes->GetGUID(
- MF_DEVICESTREAM_STREAM_CATEGORY,
- &guidPinCategory);
- if (FAILED(hr))
- {
- continue;
- }
- if (IsEqualGUID(guidPinCategory, PINNAME_VIDEO_PREVIEW))
- {
- ComPtr<IMFMediaType> spMediaType;
- hr = m_spSourceTransform->GetOutputCurrentType(i, spMediaType.ReleaseAndGetAddressOf());
- if (FAILED(hr))
- {
- return MF_E_NOT_FOUND;
- }
- return spMediaType.CopyTo(ppType);
- }
- }
-
- return MF_E_NOT_FOUND;
-}
-
-#if (NTDDI_VERSION >= NTDDI_WINBLUE)
-/////////////////////////////////////////////////////////////////////
-//
-// Handle the Metadata with the buffer
-//
-HRESULT CSocMft0::ProcessMetadata()
-{
- ComPtr<IMFAttributes> spMetadata;
- HRESULT hr = m_spSample->GetUnknown(MFSampleExtension_CaptureMetadata, IID_PPV_ARGS(spMetadata.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- ComPtr<IMFMediaBuffer> spBuffer;
- hr = spMetadata->GetUnknown(MF_CAPTURE_METADATA_FRAME_RAWSTREAM, IID_PPV_ARGS(spBuffer.ReleaseAndGetAddressOf()));
- if (FAILED(hr))
- {
- return hr;
- }
-
- MediaBufferLock bufferLock(spBuffer.Get());
- BYTE *pData = NULL;
- DWORD dwLength = 0;
- hr = bufferLock.LockBuffer(&pData, NULL, &dwLength);
- if (FAILED(hr))
- {
- return hr;
- }
-
- // OEM put meta data passing logic here,
- if (FAILED(hr))
- {
- return hr;
- }
-
- LONG lBufferLeft = static_cast<LONG>(dwLength);
- if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
- {
- return E_UNEXPECTED;
- }
-
- PKSCAMERA_METADATA_ITEMHEADER pItem = (PKSCAMERA_METADATA_ITEMHEADER)pData;
-
- while (lBufferLeft > 0)
- {
- switch (pItem->MetadataId)
- {
- case MetadataId_Custom_PreviewAggregation:
- hr = ParseMetadata_PreviewAggregation(pItem, spMetadata.Get());
- if (FAILED(hr))
- {
- return hr;
- }
- break;
- case MetadataId_Custom_ImageAggregation:
- hr = ParseMetadata_ImageAggregation(pItem, spMetadata.Get());
- if (FAILED(hr))
- {
- return hr;
- }
- break;
- case MetadataId_Custom_Histogram:
- hr = ParseMetadata_Histogram(pItem, spMetadata.Get());
- if (FAILED(hr))
- {
- return hr;
- }
- break;
- case MetadataId_Custom_FaceDetection:
- hr = ParseMetadata_FaceDetection(pItem, spMetadata.Get());
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (!pItem->Size)
- {
- // 0 size item will cause the loop to break and
- // we will report buffer malformated
- break;
- }
- lBufferLeft -= (LONG)pItem->Size;
- if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
- {
- break;
- }
- pItem = reinterpret_cast<PKSCAMERA_METADATA_ITEMHEADER>
- (reinterpret_cast<PBYTE>(pItem) + pItem->Size);
- }
-
- if (lBufferLeft != 0)
- {
- //Check and log for malformated data
- return E_UNEXPECTED;
- }
-
- return S_OK;
-}
-
-HRESULT CSocMft0::ParseMetadata_PreviewAggregation(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
-)
-{
- HRESULT hr = S_OK;
- if (pItem->Size < sizeof(CAMERA_METADATA_PREVIEWAGGREGATION))
- {
- return E_UNEXPECTED;
- }
-
- PCAMERA_METADATA_PREVIEWAGGREGATION pFixedStruct =
- (PCAMERA_METADATA_PREVIEWAGGREGATION)pItem;
-
- if (pFixedStruct->Data.FocusState.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FOCUSSTATE,
- pFixedStruct->Data.FocusState.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.ExposureTime.Set)
- {
- hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_EXPOSURE_TIME,
- pFixedStruct->Data.ExposureTime.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.ISOSpeed.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ISO_SPEED,
- pFixedStruct->Data.ISOSpeed.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.LensPosition.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_LENS_POSITION,
- pFixedStruct->Data.LensPosition.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.FlashOn.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH,
- pFixedStruct->Data.FlashOn.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.WhiteBalanceMode.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_WHITEBALANCE,
- pFixedStruct->Data.WhiteBalanceMode.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.EVCompensation.Set)
- {
- CapturedMetadataExposureCompensation EVCompensation;
-
- EVCompensation.Flags = pFixedStruct->Data.EVCompensation.Flags;
- EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
-
- hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
- (const UINT8 *)&EVCompensation,
- sizeof(EVCompensation));
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.SensorFrameRate.Set)
- {
- hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_SENSORFRAMERATE,
- pFixedStruct->Data.SensorFrameRate.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.IsoAnalogGain.Set ||
- pFixedStruct->Data.IsoDigitalGain.Set)
- {
- CapturedMetadataISOGains IsoGains;
-
- if (pFixedStruct->Data.IsoAnalogGain.Set)
- {
- IsoGains.AnalogGain =
- FLOAT(pFixedStruct->Data.IsoAnalogGain.Numerator) /
- FLOAT(pFixedStruct->Data.IsoAnalogGain.Denominator);
- }
- if (pFixedStruct->Data.IsoDigitalGain.Set)
- {
- IsoGains.DigitalGain =
- FLOAT(pFixedStruct->Data.IsoDigitalGain.Numerator) /
- FLOAT(pFixedStruct->Data.IsoDigitalGain.Denominator);
- }
-
- hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_ISO_GAINS,
- (const UINT8 *)&IsoGains,
- sizeof(IsoGains));
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.WhiteBalanceGain_R.Set ||
- pFixedStruct->Data.WhiteBalanceGain_G.Set ||
- pFixedStruct->Data.WhiteBalanceGain_B.Set)
- {
- CapturedMetadataWhiteBalanceGains WhiteBalanceGains;
-
- if (pFixedStruct->Data.WhiteBalanceGain_R.Set)
- {
- WhiteBalanceGains.R =
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Numerator) /
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Denominator);
- }
- if (pFixedStruct->Data.WhiteBalanceGain_G.Set)
- {
- WhiteBalanceGains.G =
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Numerator) /
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Denominator);
- }
- if (pFixedStruct->Data.WhiteBalanceGain_B.Set)
- {
- WhiteBalanceGains.B =
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Numerator) /
- FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Denominator);
- }
-
- hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_WHITEBALANCE_GAINS,
- (const UINT8 *)&WhiteBalanceGains,
- sizeof(WhiteBalanceGains));
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- return S_OK;
-}
-
-HRESULT CSocMft0::ParseMetadata_ImageAggregation(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
-)
-{
- HRESULT hr = S_OK;
- if (pItem->Size < sizeof(CAMERA_METADATA_IMAGEAGGREGATION))
- {
- return E_UNEXPECTED;
- }
-
- PCAMERA_METADATA_IMAGEAGGREGATION pFixedStruct =
- (PCAMERA_METADATA_IMAGEAGGREGATION)pItem;
-
- if (pFixedStruct->Data.FrameId.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_REQUESTED_FRAME_SETTING_ID,
- pFixedStruct->Data.FrameId.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.ExposureTime.Set)
- {
- hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_EXPOSURE_TIME,
- pFixedStruct->Data.ExposureTime.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.ISOSpeed.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ISO_SPEED,
- pFixedStruct->Data.ISOSpeed.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.LensPosition.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_LENS_POSITION,
- pFixedStruct->Data.LensPosition.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.SceneMode.Set)
- {
- hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_SCENE_MODE,
- pFixedStruct->Data.SceneMode.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.FlashOn.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH,
- pFixedStruct->Data.FlashOn.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.FlashPower.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH_POWER,
- pFixedStruct->Data.FlashPower.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.WhiteBalanceMode.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_WHITEBALANCE,
- pFixedStruct->Data.WhiteBalanceMode.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.ZoomFactor.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ZOOMFACTOR,
- pFixedStruct->Data.ZoomFactor.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.EVCompensation.Set)
- {
- CapturedMetadataExposureCompensation EVCompensation;
-
- EVCompensation.Flags = pFixedStruct->Data.EVCompensation.Flags;
- EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
-
- hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
- (const UINT8 *)&EVCompensation,
- sizeof(EVCompensation));
- if (FAILED(hr))
- {
- return hr;
- }
- }
-
- if (pFixedStruct->Data.FocusState.Set)
- {
- hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FOCUSSTATE,
- pFixedStruct->Data.FocusState.Value);
- if (FAILED(hr))
- {
- return hr;
- }
- }
- return S_OK;
-}
-#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
-struct HistogramData
-{
- HistogramDataHeader Header;
- ULONG Color[256];
-
- HistogramData()
- {
- Header.Size = sizeof(*this);
- Header.ChannelMask = 0;
- Header.Linear = 1;
- RtlZeroMemory(Color, sizeof(Color));
- }
-};
-
-// This is the blob we pass back every time.
-template <ULONG I>
-struct Histogram
-{
- HistogramBlobHeader Blob;
- // RGB or YUV Histograms.
- HistogramHeader Header;
- HistogramData Data[I];
-
- Histogram(
- _In_ ULONG Width = 0,
- _In_ ULONG Height = 0
- )
- {
- Blob.Histograms = 1;
- Blob.Size = sizeof(*this);
-
- Header.Size = sizeof(Header) + sizeof(Data);
- Header.Bins = 256;
- Header.Grid.Height = Height;
- Header.Grid.Width = Width;
- Header.Grid.Region.top = 0;
- Header.Grid.Region.left = 0;
- Header.Grid.Region.bottom = Height - 1;
- Header.Grid.Region.right = Width - 1;
- }
-};
-
-#if (NTDDI_VERSION >= NTDDI_WINBLUE)
-#define MF_HISTOGRAM_RGB (MF_HISTOGRAM_CHANNEL_R | MF_HISTOGRAM_CHANNEL_G | MF_HISTOGRAM_CHANNEL_B )
-#define MF_HISTOGRAM_YCrCb (MF_HISTOGRAM_CHANNEL_Y | MF_HISTOGRAM_CHANNEL_Cr | MF_HISTOGRAM_CHANNEL_Cb)
-
-HRESULT CSocMft0::ParseMetadata_Histogram(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
-)
-{
- if (pItem->Size < sizeof(CAMERA_METADATA_HISTOGRAM))
- {
- return E_UNEXPECTED;
- }
-
- PCAMERA_METADATA_HISTOGRAM pHistogram = (PCAMERA_METADATA_HISTOGRAM)pItem;
-
- if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_RGB) == MF_HISTOGRAM_RGB)
- {
- Histogram<4> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
-
- Blob.Header.FourCC = pHistogram->Data.FourCC;
- Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
-
- // For a RGB Histogram, we fake the Y channel by copying the G channel.
- Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
- RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[0].Color));
-
- // Now just copy the RGB channels normally.
- Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_R;
- RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[1].Color));
- Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_G;
- RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[2].Color));
- Blob.Data[3].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_B;
- RtlCopyMemory(Blob.Data[3].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[3].Color));
-
- return pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_HISTOGRAM,
- (PBYTE)&Blob,
- sizeof(Blob)
- );
- }
- else if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_YCrCb) == MF_HISTOGRAM_YCrCb)
- {
- Histogram<3> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
-
- Blob.Header.FourCC = pHistogram->Data.FourCC;
- Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
-
- Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
- RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[0].Color));
- Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cr;
- RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[1].Color));
- Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cb;
- RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[2].Color));
-
- //TODO:
- return pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_HISTOGRAM,
- (PBYTE)&Blob,
- sizeof(Blob)
- );
- }
- return E_UNEXPECTED;
-}
-
-HRESULT CSocMft0::ParseMetadata_FaceDetection(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
-)
-{
- HRESULT hr = S_OK;
-
- if (pItem->Size < sizeof(CAMERA_METADATA_FACEHEADER))
- {
- return E_UNEXPECTED;
- }
-
- PCAMERA_METADATA_FACEHEADER pFaceHeader = (PCAMERA_METADATA_FACEHEADER)pItem;
-
- if (pItem->Size < (sizeof(CAMERA_METADATA_FACEHEADER) + (sizeof(METADATA_FACEDATA) * pFaceHeader->Count)))
- {
- return E_UNEXPECTED;
- }
- PMETADATA_FACEDATA pFaceData = (PMETADATA_FACEDATA)(pFaceHeader + 1);
- UINT32 cbRectSize = sizeof(FaceRectInfoBlobHeader) + (sizeof(FaceRectInfo) * (pFaceHeader->Count));
- BYTE *pRectBuf = new (std::nothrow) BYTE[cbRectSize];
- if (pRectBuf == NULL)
- {
- return E_OUTOFMEMORY;
- }
-
- UINT32 cbCharSize = sizeof(FaceCharacterizationBlobHeader) + (sizeof(FaceCharacterization) * (pFaceHeader->Count));
- BYTE *pCharBuf = new (std::nothrow) BYTE[cbCharSize];
- if (pCharBuf == NULL)
- {
- delete[] pRectBuf;
- return E_OUTOFMEMORY;
- }
-
- FaceRectInfoBlobHeader *pFaceRectHeader = (FaceRectInfoBlobHeader *)pRectBuf;
- pFaceRectHeader->Size = cbRectSize;
- pFaceRectHeader->Count = pFaceHeader->Count;
-
- FaceCharacterizationBlobHeader *pFaceCharHeader = (FaceCharacterizationBlobHeader *)pCharBuf;
- pFaceCharHeader->Size = cbCharSize;
- pFaceCharHeader->Count = pFaceHeader->Count;
-
- FaceRectInfo *FaceRegions = (FaceRectInfo *)(pFaceRectHeader + 1);
- FaceCharacterization *FaceChars = (FaceCharacterization *)(pFaceCharHeader + 1);
-
- for (UINT i = 0; i < pFaceHeader->Count; i++)
- {
- FaceRegions[i].Region = pFaceData[i].Region;
- FaceRegions[i].confidenceLevel = pFaceData[i].confidenceLevel;
-
- FaceChars[i].BlinkScoreLeft = pFaceData[i].BlinkScoreLeft;
- FaceChars[i].BlinkScoreRight = pFaceData[i].BlinkScoreRight;
- FaceChars[i].FacialExpression = (pFaceData[i].FacialExpression == EXPRESSION_SMILE) ? MF_METADATAFACIALEXPRESSION_SMILE : 0;
- FaceChars[i].FacialExpressionScore = pFaceData[i].FacialExpressionScore;
- }
-
- hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROIS, pRectBuf, cbRectSize);
- if (FAILED(hr))
- {
- goto done;
- }
-
- MetadataTimeStamps timestamp;
- timestamp.Flags = MF_METADATATIMESTAMPS_DEVICE;
- timestamp.Device = pFaceHeader->Timestamp;
-
- hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROITIMESTAMPS, (const UINT8 *)&timestamp, sizeof(MetadataTimeStamps));
- if (FAILED(hr))
- {
- goto done;
- }
-
-#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
- // Include characterization data if any of the associated bits were set.
- if (pFaceHeader->Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK)
- {
- hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROICHARACTERIZATIONS, pCharBuf, cbCharSize);
- }
-#endif // (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
-
-done:
- delete[] pRectBuf;
- delete[] pCharBuf;
-
- return hr;
-}
-#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
-HRESULT CSocMft0::FillBufferLengthFromMediaType(
- _In_ IMFMediaType *pPreviewType,
- _Inout_ IMFMediaBuffer *pBuffer
-)
-{
- if (!pPreviewType || !pBuffer)
- {
- return E_INVALIDARG;
- }
-
- UINT32 uiWidth = 0, uiHeight = 0, uiImageSize = 0;
- GUID guidSubType = {};
-
- HRESULT hr = MFGetAttributeSize(pPreviewType, MF_MT_FRAME_SIZE, &uiWidth, &uiHeight);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = pPreviewType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = MFCalculateImageSize(guidSubType, uiWidth, uiHeight, &uiImageSize);
- if (FAILED(hr))
- {
- return hr;
- }
-
- return pBuffer->SetCurrentLength(uiImageSize);
-}
-
-HRESULT CSocMft0::GetVideoStabilizationEnabled()
-{
- HRESULT hr = S_OK;
- ComPtr<IKsControl> spKsControl;
- KSPROPERTY ksProperty = { 0 };
- KSPROPERTY_CUSTOM_CAMERACONTROL_MFT0_VIDEOSTABILIZATION_S ksData = { 0 };
- ULONG bytesReturned = 0;
-
- if (m_spSourceTransform != NULL)
- {
- hr = m_spSourceTransform.As(&spKsControl);
- if (SUCCEEDED(hr))
- {
- ksProperty.Set = PROPSETID_VIDCAP_CUSTOM_CAMERACONTROL_MFT0;
- ksProperty.Id = KSPROPERTY_CUSTOM_CAMERACONTROL_MFT0_VIDEOSTABILIZATION;
- ksProperty.Flags = KSPROPERTY_TYPE_GET;
-
- hr = spKsControl->KsProperty(&ksProperty, sizeof(ksProperty), &ksData, sizeof(ksData), &bytesReturned);
- if (SUCCEEDED(hr))
- {
- m_bEnableVideoStabilization = ksData.VideoStabilizationEnabled;
- }
- }
- }
- else
- {
- hr = E_INVALIDARG;
- }
- return hr;
-}
diff --git a/avstream/avscamera/mft0/MFT0Impl.h b/avstream/avscamera/mft0/MFT0Impl.h
deleted file mode 100644
index 9427dd7d..00000000
--- a/avstream/avscamera/mft0/MFT0Impl.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/**************************************************************************
-
- A/V Stream Camera Sample
-
- Copyright (c) 2013, Microsoft Corporation.
-
- File:
-
- Mft0Impl.h
-
- Abstract:
-
- The CSocMft0 class definition - an implementation of the iSocMft0
- interface found in Mft0.idl.
-
- History:
-
- created 4/26/2013
-
-**************************************************************************/
-
-
-#pragma once
-#include "Mft0.h"
-#include "SampleHelpers.h"
-#include "Mft0clsid.h"
-
-#include <wrl.h>
-
-// CSocMft0
-#define FaceDetectionDelayMax 2 //frames between emitting facedetection data
-
-ULONG DllAddRef();
-ULONG DllRelease();
-
-using namespace Microsoft::WRL;
-
-class CSocMft0:
- public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
- ISocMft0,
- IMFTransform,
- IInspectable>
-{
-
-public:
-
- static HRESULT CreateInstance(REFIID iid, void **ppMFT);
-
- CSocMft0():
- m_bEnableEffects(TRUE),
- m_bEnableVideoStabilization(FALSE),
- m_uiSourceStreamId(0),
- m_uiInternalState(0),
- m_uThumbnailScaleFactor(4)
- {
- InitializeCriticalSection(&m_critSec);
- m_stThumbnailFormat = MFVideoFormat_ARGB32;
- DllAddRef();
-
- }
-
- HRESULT FinalConstruct();
-
-public:
-
- /*ISocMft0*/
- STDMETHOD(SetState)(UINT32 state);
- STDMETHOD(GetState)(UINT32 *pState);
-
- /*IInspectable*/
- STDMETHOD(GetIids)(
- _Out_ ULONG *iidCount,
- _Outptr_result_buffer_maybenull_(*iidCount)
- IID **iids
- );
-
- STDMETHOD(GetRuntimeClassName)(
- _Outptr_result_maybenull_ HSTRING *pClassName
- );
-
- STDMETHOD(GetTrustLevel)(
- _Out_ TrustLevel *trustLevel
- );
-
- /*IMFTransform*/
- STDMETHOD(GetStreamLimits)(
- _Out_ DWORD *pdwInputMinimum,
- _Out_ DWORD *pdwInputMaximum,
- _Out_ DWORD *pdwOutputMinimum,
- _Out_ DWORD *pdwOutputMaximum
- );
-
- STDMETHOD(GetStreamCount)(
- _Out_ DWORD *pcInputStreams,
- _Out_ DWORD *pcOutputStreams
- );
-
- STDMETHOD(GetStreamIDs)(
- DWORD dwInputIDArraySize,
- _Out_writes_(dwInputIDArraySize) DWORD *pdwInputIDs,
- DWORD dwOutputIDArraySize,
- _Out_writes_(dwOutputIDArraySize) DWORD *pdwOutputIDs
- );
-
- STDMETHOD(GetInputStreamInfo)(
- DWORD dwInputStreamID,
- _Out_ MFT_INPUT_STREAM_INFO *pStreamInfo
- );
-
- STDMETHOD(GetOutputStreamInfo)(
- DWORD dwOutputStreamID,
- _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
- );
-
- STDMETHOD(GetAttributes)(
- _Outptr_result_maybenull_ IMFAttributes **pAttributes
- );
-
- STDMETHOD(GetInputStreamAttributes)(
- DWORD dwInputStreamID,
- _Outptr_result_maybenull_ IMFAttributes **pAttributes
- );
-
- STDMETHOD(GetOutputStreamAttributes)(
- DWORD dwOutputStreamID,
- _Outptr_result_maybenull_
- IMFAttributes **pAttributes
- );
-
- STDMETHOD(DeleteInputStream)(
- DWORD dwStreamID
- );
-
- STDMETHOD(AddInputStreams)(
- DWORD cStreams,
- _In_ DWORD *adwStreamIDs
- );
-
- STDMETHOD(GetInputAvailableType)(
- DWORD dwInputStreamID,
- DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-
- STDMETHOD(GetOutputAvailableType)(
- DWORD dwOutputStreamID,
- DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-
- STDMETHOD(SetInputType)(
- DWORD dwInputStreamID,
- _In_opt_ IMFMediaType *pType,
- DWORD dwFlags);
-
- STDMETHOD(SetOutputType)(
- DWORD dwOutputStreamID,
- _In_opt_ IMFMediaType *pType,
- DWORD dwFlags);
-
- STDMETHOD(GetInputCurrentType)(
- DWORD dwInputStreamID,
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-
- STDMETHOD(GetOutputCurrentType)(
- DWORD dwOutputStreamID,
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-
- STDMETHOD(GetInputStatus)(
- DWORD dwInputStreamID,
- _Out_ DWORD *pdwFlags
- );
-
- STDMETHOD(GetOutputStatus)(
- _Out_ DWORD *pdwFlags
- );
-
- STDMETHOD(SetOutputBounds)(
- LONGLONG hnsLowerBound,
- LONGLONG hnsUpperBound
- );
-
- STDMETHOD(ProcessEvent)(
- DWORD dwInputStreamID,
- _In_opt_ IMFMediaEvent *pEvent
- );
-
- STDMETHOD(ProcessMessage)(
- MFT_MESSAGE_TYPE eMessage,
- ULONG_PTR ulParam
- );
-
- STDMETHOD(ProcessInput)(
- DWORD dwInputStreamID,
- IMFSample *pSample,
- DWORD dwFlags
- );
-
- STDMETHOD(ProcessOutput)(
- DWORD dwFlags,
- DWORD cOutputBufferCount,
- MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
- DWORD *pdwStatus
- );
-
-protected:
- virtual ~CSocMft0()
- {
- DeleteCriticalSection(&m_critSec);
- DllRelease();
- }
-
- STDMETHOD(GetMediaType)(
- _In_ DWORD dwStreamID,
- _In_ DWORD dwTypeIndex,
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-
- STDMETHOD(IsMediaTypeSupported)(
- _In_ UINT uiStreamId,
- _In_opt_ IMFMediaType *pIMFMediaType,
- _Outptr_opt_result_maybenull_ IMFMediaType **ppIMFMediaTypeFull = NULL
- );
-
- STDMETHOD(GenerateMFMediaTypeListFromDevice)();
-
- _Success_(return == 0)
- STDMETHOD(FindMediaIndex)(
- _In_ UINT uiStreamId,
- _In_ IMFMediaType *pIMFMediaType,
- _Out_ UINT *puiMediaIndex
- );
-
- // HasPendingOutput: Returns TRUE if the MFT is holding an input sample.
- BOOL HasPendingOutput() const
- {
- return m_spSample != NULL;
- }
-
- HRESULT CreateOutputSample(
- _Outptr_result_maybenull_ IMFSample **ppSample
- );
-
- HRESULT GetPreviewMediaType(
- _Outptr_result_maybenull_ IMFMediaType **ppType
- );
-#if (NTDDI_VERSION >= NTDDI_WINBLUE)
- HRESULT ProcessMetadata();
-
- HRESULT ParseMetadata_PreviewAggregation(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
- );
-
- HRESULT ParseMetadata_ImageAggregation(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
- );
-
- HRESULT ParseMetadata_Histogram(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
- );
-
- HRESULT ParseMetadata_FaceDetection(
- _In_ PKSCAMERA_METADATA_ITEMHEADER pItem,
- _In_ IMFAttributes *pMetaDataAttributes
- );
-#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
- HRESULT FillBufferLengthFromMediaType(
- _In_ IMFMediaType *pPreviewType,
- _Inout_ IMFMediaBuffer *pBuffer
- );
-
- STDMETHOD(OnFlush)();
-
- HRESULT GetVideoStabilizationEnabled();
-
- HRESULT GetThumbnailResolution();
-
- HRESULT OnProcessImage(
- _Outptr_result_maybenull_
- IMFSample **ppIMFOutputSample
- );
-
- CRITICAL_SECTION m_critSec;
-
- ComPtr<IMFSample> m_spSample; // Input sample.
- ComPtr<IMFMediaType> m_spInputType; // Input media type.
- ComPtr<IMFMediaType> m_spOutputType; // Output media type.
-
- // Image transform function. (Changes based on the media type.)
- ComPtr<IMFAttributes> m_spInputAttributes;
- ComPtr<IMFAttributes> m_spGlobalAttributes;
- GUID m_stStreamType;
- ComPtr<IMFTransform> m_spSourceTransform;
- volatile BOOL m_bEnableEffects;
- BOOL m_bEnableVideoStabilization;
- UINT m_uiSourceStreamId;
- UINT m_uiInternalState;
- BYTE m_uThumbnailScaleFactor;
- GUID m_stThumbnailFormat;
-
- std::vector<ComPtr<IMFMediaType>>
- m_listOfMediaTypes;
-
-};
-
-inline HRESULT MFT0CreateInstance(REFIID riid, void **ppv)
-{
- return CSocMft0::CreateInstance(riid, ppv);
-}
-
-//CoCreateableClass(CSocMft0); \ No newline at end of file
diff --git a/avstream/avscamera/mft0/MFT0clsid.h b/avstream/avscamera/mft0/MFT0clsid.h
deleted file mode 100644
index d8aad5f5..00000000
--- a/avstream/avscamera/mft0/MFT0clsid.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**************************************************************************
-
- A/V Stream Camera Sample
-
- Copyright (c) 2015, Microsoft Corporation.
-
- File:
-
- Mft0clsid.h
-
- Abstract:
-
- Define the Class GUID of the MFT.
-
- History:
-
- created 2/19/2015
-
-**************************************************************************/
-
-#pragma once
-
-// CLSID of the MFT.
-// {1C2CE17A-FAAD-4E73-85E7-167068093F25}
-DEFINE_GUID(CLSID_AvsCamMft0,
- 0x1c2ce17a, 0xfaad, 0x4e73, 0x85, 0xe7, 0x16, 0x70, 0x68, 0x9, 0x3f, 0x25);
diff --git a/avstream/avscamera/mft0/SampleHelpers.h b/avstream/avscamera/mft0/SampleHelpers.h
deleted file mode 100644
index 11908f82..00000000
--- a/avstream/avscamera/mft0/SampleHelpers.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/**************************************************************************
-
- A/V Stream Camera Sample
-
- Copyright (c) 2013, Microsoft Corporation.
-
- File:
-
- SampleHelpers.h
-
- Abstract:
-
- Helper classes for the MFT0.
-
- History:
-
- created 4/26/2013
-
-**************************************************************************/
-
-#pragma once
-
-/***************************************************************************\
-*****************************************************************************
-*
-* class CAutoLock
-*
-* Locks a critical section at construction time and unlocks it automatically
-* when the object goes out of scope
-*
-*****************************************************************************
-\***************************************************************************/
-
-class CAutoLock
-{
-private:
- // Make copy constructor and assignment operator inaccessible
- CAutoLock(const CAutoLock &refAutoLock);
- CAutoLock &operator=(const CAutoLock &refAutoLock);
-
- // CAutoLock should not be created on the heap, so declare
- // (but do not implement) private operator new/delete.
- static void *operator new(size_t);
- static void operator delete(void *);
- static void *operator new[](size_t);
- static void operator delete[](void *);
-
-protected:
- CRITICAL_SECTION *m_pLock;
-
-public:
- _Acquires_lock_(m_pLock)
- explicit CAutoLock(CRITICAL_SECTION *pLock):
- m_pLock(pLock)
- {
- EnterCriticalSection(m_pLock);
- }
-
- _Releases_lock_(m_pLock)
- ~CAutoLock()
- {
- LeaveCriticalSection(m_pLock);
- }
-};
-
-class MediaBufferLock
-{
-public:
- MediaBufferLock(_In_ IMFMediaBuffer *pBuffer):
- m_bLocked(false)
- {
- m_spBuffer = pBuffer;
- }
-
- HRESULT LockBuffer(
- _Outptr_result_bytebuffer_to_(*pcbMaxLength, *pcbCurrentLength) BYTE **ppbBuffer,
- _Out_opt_ DWORD *pcbMaxLength,
- _Out_opt_ DWORD *pcbCurrentLength)
- {
- if(!m_spBuffer)
- {
- return E_INVALIDARG;
- }
-
- HRESULT hr = m_spBuffer->Lock(ppbBuffer, pcbMaxLength, pcbCurrentLength);
- if(FAILED(hr))
- {
- return hr;
- }
- m_bLocked = true;
- return S_OK;
- }
-
- ~MediaBufferLock()
- {
- if(m_spBuffer && m_bLocked)
- {
- //Unlock fails only if we did not lock it first
- (void) m_spBuffer->Unlock();
- }
- }
-
-private:
- ComPtr<IMFMediaBuffer> m_spBuffer;
- bool m_bLocked;
-};
diff --git a/avstream/avscamera/mft0/dllmain.cpp b/avstream/avscamera/mft0/dllmain.cpp
deleted file mode 100644
index b5746417..00000000
--- a/avstream/avscamera/mft0/dllmain.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/**************************************************************************
-
- A/V Stream Camera Sample
-
- Copyright (c) 2014, Microsoft Corporation.
-
- File:
-
- dllmain.cpp
-
- Abstract:
-
- DLL and COM initialization.
-
- History:
-
- created 5/15/2014
-
-**************************************************************************/
-//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-//// PARTICULAR PURPOSE.
-////
-//// Copyright (c) Microsoft Corporation. All rights reserved
-
-
-#include "stdafx.h"
-#include "Mft0.h"
-#include "Mft0clsid.h"
-#include "Mft0Impl.h"
-#include <wrl\module.h>
-
-using namespace Microsoft::WRL;
-
-// Module Ref count
-volatile ULONG g_cRefModule = 0;
-
-// Handle to the DLL's module
-HMODULE g_hModule = NULL;
-
-ULONG DllAddRef()
-{
- return InterlockedIncrement(&g_cRefModule);
-}
-
-ULONG DllRelease()
-{
- return InterlockedDecrement(&g_cRefModule);
-}
-
-class CClassFactory : public IClassFactory
-{
-public:
- static HRESULT CreateInstance(
- REFCLSID clsid,
- REFIID riid,
- _COM_Outptr_ void **ppv
- )
- {
- *ppv = NULL;
-
- HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
-
- if(IsEqualGUID(clsid, CLSID_AvsCamMft0))
- {
- IClassFactory *pClassFactory = new (std::nothrow) CClassFactory();
- if(!pClassFactory)
- {
- return E_OUTOFMEMORY;
- }
- hr = pClassFactory->QueryInterface(riid, ppv);
- pClassFactory->Release();
- }
- return hr;
- }
-
- //IUnknown methods
- IFACEMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
- {
- HRESULT hr = S_OK;
-
- if(ppvObject == NULL)
- {
- return E_POINTER;
- }
-
- if(riid == IID_IUnknown)
- {
- *ppvObject = (IUnknown*)this;
- }
- else if(riid == IID_IClassFactory)
- {
- *ppvObject = (IClassFactory*)this;
- }
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-
- AddRef();
-
- return hr;
- }
-
- IFACEMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- IFACEMETHODIMP_(ULONG) Release()
- {
- long cRef = InterlockedDecrement(&m_cRef);
- if(cRef == 0)
- {
- delete this;
- }
- return cRef;
- }
-
- //IClassFactory Methods
- IFACEMETHODIMP CreateInstance(_In_ IUnknown *punkOuter, _In_ REFIID riid, _Outptr_ void **ppv)
- {
- return punkOuter ? CLASS_E_NOAGGREGATION : MFT0CreateInstance(riid, ppv);
- }
-
- IFACEMETHODIMP LockServer(BOOL fLock)
- {
- if(fLock)
- {
- DllAddRef();
- }
- else
- {
- DllRelease();
- }
- return S_OK;
- }
-
-private:
- CClassFactory() :
- m_cRef(1)
- {
- DllAddRef();
- }
-
- ~CClassFactory()
- {
- DllRelease();
- }
-
- long m_cRef;
-};
-
-
-
-
-STDAPI_(BOOL) DllMain(_In_ HINSTANCE hinst, DWORD reason, _In_opt_ void *)
-{
- if (reason == DLL_PROCESS_ATTACH)
- {
- g_hModule = (HMODULE)hinst;
- DisableThreadLibraryCalls(hinst);
- }
- return TRUE;
-}
-
-//
-// DllCanUnloadNow
-//
-/////////////////////////////////////////////////////////////////////////
-__control_entrypoint(DllExport)
-STDAPI DllCanUnloadNow()
-{
- return (g_cRefModule == 0) ? S_OK : S_FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////
-//
-// DllGetClassObject
-//
-/////////////////////////////////////////////////////////////////////////
-_Check_return_
-STDAPI DllGetClassObject(
- _In_ REFCLSID rclsid,
- _In_ REFIID riid,
- _Outptr_ LPVOID FAR *ppv
-)
-{
- return CClassFactory::CreateInstance(rclsid, riid, ppv);
-}
diff --git a/avstream/avscamera/mft0/stdafx.h b/avstream/avscamera/mft0/stdafx.h
deleted file mode 100644
index 6d784805..00000000
--- a/avstream/avscamera/mft0/stdafx.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-//// PARTICULAR PURPOSE.
-////
-//// Copyright (c) Microsoft Corporation. All rights reserved
-
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently,
-// but are changed infrequently
-
-#pragma once
-
-#ifndef STRICT
-#define STRICT
-#endif
-
-#include "targetver.h"
-#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
-#pragma message("MFT0 is deprecated for this target Windows version and beyond- Change project settings to target an older version of Windows")
-#endif
-
-#if (NTDDI_VERSION <= NTDDI_WIN7)
-// TODO: disable the MFT0 conditional to the target system version
-#pragma message("MFT0 is in not supported in this target Windows version - Change project settings to target a newer version of Windows")
-#endif
-
-#include <wrl.h>
-#include <initguid.h>
-#include <mfapi.h>
-#include <mfidl.h>
-#include <mferror.h>
-#include <ks.h>
-#include <ksmedia.h>
-#include <inspectable.h>
-#include <vector>
-
-
-using namespace Microsoft::WRL; \ No newline at end of file
diff --git a/avstream/avscamera/mft0/stdafxsrc.cpp b/avstream/avscamera/mft0/stdafxsrc.cpp
deleted file mode 100644
index 1577c4e3..00000000
--- a/avstream/avscamera/mft0/stdafxsrc.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "stdafx.h" \ No newline at end of file
diff --git a/avstream/avscamera/mft0/targetver.h b/avstream/avscamera/mft0/targetver.h
deleted file mode 100644
index fc349fa5..00000000
--- a/avstream/avscamera/mft0/targetver.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-//// PARTICULAR PURPOSE.
-////
-//// Copyright (c) Microsoft Corporation. All rights reserved
-
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>
diff --git a/avstream/avscamera/sys/AvsCamera.vcxproj b/avstream/avscamera/sys/AvsCamera.vcxproj
index 5456ee7a..1ce404cb 100644
--- a/avstream/avscamera/sys/AvsCamera.vcxproj
+++ b/avstream/avscamera/sys/AvsCamera.vcxproj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -24,38 +24,38 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{7F43971C-9E5A-46A0-B925-AFE3282E014C}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -67,26 +67,26 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>AvsCamera</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetName>AvsCamera</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>AvsCamera</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>AvsCamera</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -103,7 +103,7 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\common;$(SDK_INC_PATH)\ks</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib;$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\cng.lib</AdditionalDependencies>
</Link>
@@ -117,7 +117,7 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\common;$(SDK_INC_PATH)\ks</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib;$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\cng.lib</AdditionalDependencies>
</Link>
@@ -131,7 +131,7 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\common;$(SDK_INC_PATH)\ks</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib;$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\cng.lib</AdditionalDependencies>
</Link>
@@ -148,13 +148,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -171,7 +171,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
@@ -185,7 +185,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
@@ -199,7 +199,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
@@ -256,4 +256,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/avstream/avscamera/sys/AvsCamera.vcxproj.Filters b/avstream/avscamera/sys/AvsCamera.vcxproj.Filters
index 8d9ec469..1c346b6c 100644
--- a/avstream/avscamera/sys/AvsCamera.vcxproj.Filters
+++ b/avstream/avscamera/sys/AvsCamera.vcxproj.Filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -97,10 +97,23 @@
<ClCompile Include="YUY2Synthesizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="formats.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="AvsCamera.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="*.inf;*.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/avstream/avscamera/sys/Capture.cpp b/avstream/avscamera/sys/Capture.cpp
index 25e6a5f8..730370e6 100644
--- a/avstream/avscamera/sys/Capture.cpp
+++ b/avstream/avscamera/sys/Capture.cpp
@@ -2294,6 +2294,7 @@ SetFramingSizes(
PKSALLOCATOR_FRAMING_EX Framing
)
{
+ PAGED_CODE();
Framing->FramingItem[0].PhysicalRange.MinFrameSize = m_VideoInfoHeader->bmiHeader.biSizeImage;
Framing->FramingItem[0].PhysicalRange.MaxFrameSize = m_VideoInfoHeader->bmiHeader.biSizeImage;
Framing->FramingItem[0].FramingRange.Range.MinFrameSize = m_VideoInfoHeader->bmiHeader.biSizeImage;
diff --git a/avstream/avscamera/sys/Device.cpp b/avstream/avscamera/sys/Device.cpp
index 2741da08..38d4f555 100644
--- a/avstream/avscamera/sys/Device.cpp
+++ b/avstream/avscamera/sys/Device.cpp
@@ -110,6 +110,7 @@ IrpSynchronousCompletion(
IN PVOID pKevent
)
{
+ PAGED_CODE();
if (Irp->PendingReturned)
{
NT_ASSERT(pKevent);
diff --git a/avstream/avscamera/sys/avscamera.inx b/avstream/avscamera/sys/avscamera.inx
index f6f1e846..f75da695 100644
--- a/avstream/avscamera/sys/avscamera.inx
+++ b/avstream/avscamera/sys/avscamera.inx
Binary files differ
diff --git a/avstream/avscamera/sys/hwsim.cpp b/avstream/avscamera/sys/hwsim.cpp
index fdf7b367..80a4adcf 100644
--- a/avstream/avscamera/sys/hwsim.cpp
+++ b/avstream/avscamera/sys/hwsim.cpp
@@ -796,6 +796,7 @@ bool
CHardwareSimulation::
CheckForAvailableBuffer()
{
+ PAGED_CODE();
return true;
}
@@ -803,6 +804,7 @@ NTSTATUS
CHardwareSimulation::
CommitImageData(PSCATTER_GATHER_ENTRY sGEntry, ULONG stride)
{
+ PAGED_CODE();
// Have the synthesizer output a frame to the buffer.
ULONG CommitBufferSize = sGEntry->ByteCount;
PUCHAR CommitBufferAddress = sGEntry->Virtual;
@@ -818,6 +820,7 @@ NTSTATUS
CHardwareSimulation::
ValidateBuffer(PSCATTER_GATHER_ENTRY sGEntry)
{
+ PAGED_CODE();
return STATUS_SUCCESS;
}
diff --git a/avstream/avshws/avshws.inx b/avstream/avshws/avshws.inx
index 238ce187..9409635d 100644
--- a/avstream/avshws/avshws.inx
+++ b/avstream/avshws/avshws.inx
Binary files differ
diff --git a/avstream/avshws/avshws.sln b/avstream/avshws/avshws.sln
index ba4ee493..26f5306c 100644
--- a/avstream/avshws/avshws.sln
+++ b/avstream/avshws/avshws.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29519.181
@@ -7,34 +7,20 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avshws", "avshws.vcxproj",
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
- Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
- Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
- Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.ActiveCfg = Debug|ARM
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.Build.0 = Debug|ARM
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.Deploy.0 = Debug|ARM
{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.Build.0 = Debug|ARM64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.Deploy.0 = Debug|ARM64
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|Win32.ActiveCfg = Debug|Win32
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|Win32.Build.0 = Debug|Win32
{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|x64.ActiveCfg = Debug|x64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|x64.Build.0 = Debug|x64
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.ActiveCfg = Release|ARM
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.Build.0 = Release|ARM
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.Deploy.0 = Release|ARM
{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.ActiveCfg = Release|ARM64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.Build.0 = Release|ARM64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.Deploy.0 = Release|ARM64
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Release|Win32.ActiveCfg = Release|Win32
- {77FA53EC-3637-411C-B708-C8EED64543A4}.Release|Win32.Build.0 = Release|Win32
{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|x64.ActiveCfg = Release|x64
{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
diff --git a/avstream/avshws/avshws.vcxproj b/avstream/avshws/avshws.vcxproj
index 407048b7..b1b1d12b 100644
--- a/avstream/avshws/avshws.vcxproj
+++ b/avstream/avshws/avshws.vcxproj
@@ -1,30 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|ARM">
- <Configuration>Debug</Configuration>
- <Platform>ARM</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|ARM">
- <Configuration>Release</Configuration>
- <Platform>ARM</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -38,14 +22,14 @@
<ProjectGuid>{77FA53EC-3637-411C-B708-C8EED64543A4}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{555099C6-5354-4C50-A241-A09CDD72299D}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -53,23 +37,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>WDM</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>WDM</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -77,23 +45,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>WDM</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>WDM</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -101,7 +53,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -116,21 +68,9 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
@@ -141,21 +81,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>avshws</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>avshws</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <TargetName>avshws</TargetName>
- </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetName>avshws</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>avshws</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <TargetName>avshws</TargetName>
- </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>avshws</TargetName>
</PropertyGroup>
@@ -207,45 +135,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
@@ -264,45 +153,6 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
</Midl>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
diff --git a/avstream/avshws/avshws.vcxproj.Filters b/avstream/avshws/avshws.vcxproj.Filters
index 4e32a73f..bc11045f 100644
--- a/avstream/avshws/avshws.vcxproj.Filters
+++ b/avstream/avshws/avshws.vcxproj.Filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -43,4 +43,14 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="*.inf;*.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/avstream/avssamp/avssamp.inx b/avstream/avssamp/avssamp.inx
index 61d66fa3..c06925ea 100644
--- a/avstream/avssamp/avssamp.inx
+++ b/avstream/avssamp/avssamp.inx
Binary files differ
diff --git a/avstream/avssamp/avssamp.sln b/avstream/avssamp/avssamp.sln
index 6b6d6b07..ea74c295 100644
--- a/avstream/avssamp/avssamp.sln
+++ b/avstream/avssamp/avssamp.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
@@ -7,16 +7,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avssamp", "avssamp.vcxproj"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
+ Debug|ARM64 = Debug|ARM64
+ Release|ARM64 = Release|ARM64
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|Win32.ActiveCfg = Debug|Win32
- {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|Win32.Build.0 = Debug|Win32
- {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Release|Win32.ActiveCfg = Release|Win32
- {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Release|Win32.Build.0 = Release|Win32
+ {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|ARM64.Build.0 = Debug|ARM64
+ {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Release|ARM64.ActiveCfg = Release|ARM64
+ {2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Release|ARM64.Build.0 = Release|ARM64
{2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|x64.ActiveCfg = Debug|x64
{2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Debug|x64.Build.0 = Debug|x64
{2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}.Release|x64.ActiveCfg = Release|x64
diff --git a/avstream/avssamp/avssamp.vcxproj b/avstream/avssamp/avssamp.vcxproj
index 58d7992d..57994980 100644
--- a/avstream/avssamp/avssamp.vcxproj
+++ b/avstream/avssamp/avssamp.vcxproj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -22,38 +22,38 @@
<ProjectGuid>{2CCFF21D-0B89-4F39-A4FC-2D0CCC25A071}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{B0781D0B-B397-4C3A-9D2D-6993E9C47C60}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -65,26 +65,26 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>avssamp</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetName>avssamp</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>avssamp</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>avssamp</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -112,7 +112,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib</AdditionalDependencies>
<AdditionalOptions>%(AdditionalOptions) -merge:PAGECONST=PAGE</AdditionalOptions>
@@ -137,7 +137,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib</AdditionalDependencies>
<AdditionalOptions>%(AdditionalOptions) -merge:PAGECONST=PAGE</AdditionalOptions>
@@ -162,7 +162,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib</AdditionalDependencies>
<AdditionalOptions>%(AdditionalOptions) -merge:PAGECONST=PAGE</AdditionalOptions>
diff --git a/avstream/avssamp/avssamp.vcxproj.Filters b/avstream/avssamp/avssamp.vcxproj.Filters
index 8d345831..5a9d5e00 100644
--- a/avstream/avssamp/avssamp.vcxproj.Filters
+++ b/avstream/avssamp/avssamp.vcxproj.Filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -53,24 +53,6 @@
<ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
- <Filter>Header Files</Filter>
- </ClInclude>
</ItemGroup>
<ItemGroup>
<Inf Include="*.inf;*.inx">
diff --git a/avstream/sampledevicemft/SampleDeviceMft.sln b/avstream/sampledevicemft/SampleDeviceMft.sln
index a6a00c4d..c3c29d4e 100644
--- a/avstream/sampledevicemft/SampleDeviceMft.sln
+++ b/avstream/sampledevicemft/SampleDeviceMft.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
@@ -7,16 +7,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multipinmft", "multipinmft.
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
+ Debug|ARM64 = Debug|ARM64
+ Release|ARM64 = Release|ARM64
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|Win32.ActiveCfg = Debug|Win32
- {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|Win32.Build.0 = Debug|Win32
- {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|Win32.ActiveCfg = Release|Win32
- {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|Win32.Build.0 = Release|Win32
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|ARM64.Build.0 = Debug|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|ARM64.ActiveCfg = Release|ARM64
+ {E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|ARM64.Build.0 = Release|ARM64
{E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|x64.ActiveCfg = Debug|x64
{E77657CD-A270-49E1-823A-8A14FF8596C8}.Debug|x64.Build.0 = Debug|x64
{E77657CD-A270-49E1-823A-8A14FF8596C8}.Release|x64.ActiveCfg = Release|x64
diff --git a/avstream/sampledevicemft/SampleSocDeviceMFT.cpp b/avstream/sampledevicemft/SampleSocDeviceMFT.cpp
new file mode 100644
index 00000000..2a91906f
--- /dev/null
+++ b/avstream/sampledevicemft/SampleSocDeviceMFT.cpp
@@ -0,0 +1,1533 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#include "stdafx.h"
+#include "multipinmft.h"
+#ifdef MF_WPP
+#include "multipinmft.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+//
+// Note since MFT_UNIQUE_METHOD_NAMES is defined all the functions of IMFTransform have the Mft suffix..
+//
+extern const CLSID CLSID_HwMFTActivate;
+
+CMultipinMft::CMultipinMft()
+: m_nRefCount( 0 ),
+ m_InputPinCount( 0 ),
+ m_OutputPinCount( 0 ),
+ m_dwWorkQueueId ( MFASYNC_CALLBACK_QUEUE_MULTITHREADED ),
+ m_lWorkQueuePriority ( 0 ),
+ m_spAttributes( nullptr ),
+ m_spSourceTransform( nullptr ),
+ m_SymbolicLink(nullptr)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFAttributes> pAttributes = nullptr;
+ MFCreateAttributes( &pAttributes, 0 );
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_TRANSFORM_ASYNC, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_SA_D3D_AWARE, TRUE ), done);
+ DMFTCHECKHR_GOTO(pAttributes->SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"SampleMultiPinMft" ),done);
+ m_spAttributes = pAttributes;
+done:
+ if (FAILED(hr))
+ {
+
+ }
+}
+
+CMultipinMft::~CMultipinMft( )
+{
+
+
+ for ( ULONG ulIndex = 0, ulSize = (ULONG) m_InPins.size(); ulIndex < ulSize; ulIndex++ )
+ {
+ SAFERELEASE(m_InPins[ ulIndex ]);
+ }
+ m_InPins.clear();
+ for (ULONG ulIndex = 0, ulSize = (ULONG) m_OutPins.size(); ulIndex < ulSize; ulIndex++)
+ {
+ SAFERELEASE(m_OutPins[ ulIndex ]);
+ }
+ m_OutPins.clear();
+ SAFE_ARRAYDELETE(m_SymbolicLink);
+ m_spSourceTransform = nullptr;
+
+}
+
+STDMETHODIMP_(ULONG) CMultipinMft::AddRef(
+ void
+ )
+{
+ return InterlockedIncrement(&m_nRefCount);
+}
+
+STDMETHODIMP_(ULONG) CMultipinMft::Release(
+ void
+ )
+{
+ ULONG uCount = InterlockedDecrement(&m_nRefCount);
+
+ if ( uCount == 0 )
+ {
+ delete this;
+ }
+ return uCount;
+}
+
+STDMETHODIMP CMultipinMft::QueryInterface(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv
+ )
+{
+
+ HRESULT hr = S_OK;
+ *ppv = NULL;
+
+ if ((iid == __uuidof(IMFDeviceTransform)) || (iid == __uuidof(IUnknown)))
+ {
+ *ppv = static_cast< IMFDeviceTransform* >(this);
+ }
+ else if ( iid == __uuidof( IMFMediaEventGenerator ) )
+ {
+ *ppv = static_cast< IMFMediaEventGenerator* >(this);
+ }
+ else if ( iid == __uuidof( IMFShutdown ) )
+ {
+ *ppv = static_cast< IMFShutdown* >( this );
+ }
+#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
+ else if (iid == __uuidof(IMFTransform))
+ {
+ *ppv = static_cast< IMFTransform* >(this);
+ }
+#endif
+ else if ( iid == __uuidof( IKsControl ) )
+ {
+ *ppv = static_cast< IKsControl* >( this );
+ }
+ else if ( iid == __uuidof( IMFRealTimeClientEx ) )
+ {
+ *ppv = static_cast< IMFRealTimeClientEx* >( this );
+ }
+
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+ else if (iid == __uuidof(IMFSampleAllocatorControl))
+ {
+ *ppv = static_cast<IMFSampleAllocatorControl*>(this);
+ }
+#endif
+ else
+ {
+ hr = E_NOINTERFACE;
+ goto done;
+ }
+ AddRef();
+done:
+ return hr;
+}
+
+/*++
+ Description:
+ This function is the entry point of the transform
+ The following things may be initialized here
+ 1) Query for MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL on the attributes supplied
+ 2) From the IUnknown acquired get the IMFTransform interface.
+ 3) Get the stream count.. The output streams are of consequence to the tranform.
+ The input streams should correspond to the output streams exposed by the source transform
+ acquired from the Attributes supplied.
+ 4) Get the IKSControl which is used to send KSPROPERTIES, KSEVENTS and KSMETHODS to the driver for the filer level. Store it in your filter class
+ 5) Get the OutPutStreamAttributes for the output pins of the source transform. This can further be used to QI and acquire
+ the IKSControl related to the specific pin. This can be used to send PIN level KSPROPERTIES, EVENTS and METHODS to the pins
+ 6) Create the output pins
+
+--*/
+
+// This sample will create a grayscale for known media types. Please remove MF_DEVICEMFT_ADD_GRAYSCALER_ to remove the grayscaler
+// This sample also has photo confirmation enabled remove DMF_DEVICEMFT_PHTOTOCONFIRMATION to remove photo confirmation
+// Please search for the @@@@ README tag for critical sections in code and it's documentation
+//
+STDMETHODIMP CMultipinMft::InitializeTransform (
+ _In_ IMFAttributes *pAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IUnknown> spFilterUnk = nullptr;
+ DWORD *pcInputStreams = NULL, *pcOutputStreams = NULL;
+ DWORD inputStreams = 0;
+ DWORD outputStreams = 0;
+ GUID* outGuids = NULL;
+ GUID streamCategory = GUID_NULL;
+ ULONG ulOutPinIndex = 0;
+ UINT32 uiSymLinkLen = 0;
+ CPinCreationFactory* pPinFactory = new (std::nothrow) CPinCreationFactory(this);
+ DMFTCHECKNULL_GOTO( pAttributes, done, E_INVALIDARG );
+ //
+ // The attribute passed with MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL is the source transform. This generally represents a filter
+ // This needs to be stored so that we know the device properties. We cache it. We query for the IKSControl which is used to send
+ // controls to the driver.
+ //
+ DMFTCHECKHR_GOTO( pAttributes->GetUnknown( MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL,IID_PPV_ARGS( &spFilterUnk ) ),done );
+
+ if (SUCCEEDED(pAttributes->GetStringLength(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &uiSymLinkLen))) // Not available prior to RS5
+ {
+ m_SymbolicLink = new (std::nothrow) WCHAR[++uiSymLinkLen];
+ DMFTCHECKNULL_GOTO(m_SymbolicLink, done, E_OUTOFMEMORY);
+ DMFTCHECKHR_GOTO(pAttributes->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, m_SymbolicLink, uiSymLinkLen, &uiSymLinkLen), done);
+ }
+
+ DMFTCHECKHR_GOTO( spFilterUnk.As( &m_spSourceTransform ), done );
+
+ DMFTCHECKHR_GOTO( m_spSourceTransform.As( &m_spIkscontrol ), done );
+
+ DMFTCHECKHR_GOTO( m_spSourceTransform->MFTGetStreamCount( &inputStreams, &outputStreams ), done );
+
+ spFilterUnk = nullptr;
+
+ //
+ //The number of input pins created by the device transform should match the pins exposed by
+ //the source transform i.e. outputStreams from SourceTransform or DevProxy = Input pins of the Device MFT
+ //
+
+ if ( inputStreams > 0 || outputStreams > 0 )
+ {
+ pcInputStreams = new (std::nothrow) DWORD[ inputStreams ];
+ DMFTCHECKNULL_GOTO( pcInputStreams, done, E_OUTOFMEMORY);
+
+ pcOutputStreams = new (std::nothrow) DWORD[ outputStreams ];
+ DMFTCHECKNULL_GOTO( pcOutputStreams, done, E_OUTOFMEMORY );
+
+ DMFTCHECKHR_GOTO( m_spSourceTransform->MFTGetStreamIDs( inputStreams, pcInputStreams,
+ outputStreams,
+ pcOutputStreams ),done );
+
+ //
+ // Output pins from DevProxy = Input pins of device MFT.. We are the first transform in the pipeline before MFT0
+ //
+
+ for ( ULONG ulIndex = 0; ulIndex < outputStreams; ulIndex++ )
+ {
+ ComPtr<IMFAttributes> pInAttributes = nullptr;
+ BOOL bCustom = FALSE;
+ ComPtr<CInPin> spInPin;
+
+ DMFTCHECKHR_GOTO(pPinFactory->CreatePin(
+ pcOutputStreams[ulIndex], /*Input Pin ID as advertised by the pipeline*/
+ 0, /*This is not needed for Input Pin*/
+ CPinCreationFactory::DMFT_PIN_INPUT, /*Input Pin*/
+ (CBasePin**)spInPin.GetAddressOf(),
+ bCustom), done);
+ if (bCustom)
+ {
+ m_CustomPinCount++;
+ }
+ hr = ExceptionBoundary([&]()
+ {
+ m_InPins.push_back(spInPin.Get());
+ });
+ DMFTCHECKHR_GOTO(hr, done);
+ DMFTCHECKHR_GOTO( spInPin->Init(m_spSourceTransform.Get() ), done);
+ spInPin.Detach();
+ }
+
+ //
+ // Create one on one mapping
+ //
+ for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
+ {
+
+ ComPtr<COutPin> spoPin;
+ BOOL bCustom = FALSE;
+ ComPtr<CInPin> spiPin = ( CInPin * )m_InPins[ ulIndex ];
+
+ if (spiPin.Get())
+ {
+ BOOL isCustom = false;
+ if (SUCCEEDED(CheckCustomPin(spiPin.Get(), &isCustom)) && (isCustom))
+ {
+ //
+ // In this sample we are not connecting the custom pin to the output
+ // This is because we really have no way of testing the custom pin with the
+ // pipeline.
+ // This however can be changed if the custom media type is converted here in
+ // the device MFT and later exposed to the pipeline..
+ //
+ continue;
+ }
+
+ DMFTCHECKHR_GOTO(pPinFactory->CreatePin(spiPin->streamId(), /*Input Pin connected to the Output Pin*/
+ ulOutPinIndex, /*Output pin Id*/
+ CPinCreationFactory::DMFT_PIN_OUTPUT, /*Output pin */
+ (CBasePin**)spoPin.ReleaseAndGetAddressOf(),
+ bCustom), done);
+ hr = BridgeInputPinOutputPin(spiPin.Get(), spoPin.Get());
+ if (SUCCEEDED(hr))
+ {
+ DMFTCHECKHR_GOTO(ExceptionBoundary([&]()
+ {
+ m_OutPins.push_back(spoPin.Get());
+ }), done);
+ spoPin.Detach();
+ ulOutPinIndex++;
+ hr = S_OK;
+ }
+ if (hr == MF_E_INVALID_STREAM_DATA)
+ {
+ // Skip the pin which doesn't have any mediatypes exposed
+ hr = S_OK;
+ }
+ DMFTCHECKHR_GOTO(hr, done);
+ }
+ }
+
+ }
+
+ m_InputPinCount = ULONG ( m_InPins.size() );
+ m_OutputPinCount = ULONG ( m_OutPins.size() );
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!",hr,hr);
+
+ if ( pcInputStreams )
+ {
+ delete[ ] ( pcInputStreams );
+ }
+ if ( pcOutputStreams )
+ {
+ delete[ ] ( pcOutputStreams );
+ }
+ if ( outGuids )
+ {
+ delete [] ( outGuids );
+ }
+ SAFE_DELETE(pPinFactory);
+ if ( FAILED( hr ) )
+ {
+ //Release the pins and the resources acquired
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_InPins.size(); ulIndex < ulSize; ulIndex++)
+ {
+ SAFERELEASE(m_InPins[ulIndex]);
+ }
+ m_InPins.clear();
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_OutPins.size(); ulIndex < ulSize; ulIndex++)
+ {
+ SAFERELEASE(m_OutPins[ulIndex]);
+ }
+ m_OutPins.clear();
+ //
+ // Simply clear the custom pins since the input pins must have deleted the pin
+ //
+ m_spSourceTransform = nullptr;
+ m_spIkscontrol = nullptr;
+ }
+ return hr;
+}
+
+
+STDMETHODIMP CMultipinMft::SetWorkQueueEx(
+ _In_ DWORD dwWorkQueueId,
+ _In_ LONG lWorkItemBasePriority
+ )
+/*++
+ Description:
+
+ Implements IMFRealTimeClientEx::SetWorkQueueEx function
+
+--*/
+{
+ CAutoLock lock( m_critSec );
+ //
+ // Cache the WorkQueuId and WorkItemBasePriority. This is called once soon after the device MFT is initialized
+ //
+ m_dwWorkQueueId = dwWorkQueueId;
+ m_lWorkQueuePriority = lWorkItemBasePriority;
+ // Set it on the pins
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_InPins.size(); dwIndex++)
+ {
+ m_InPins[dwIndex]->SetWorkQueue(dwWorkQueueId);
+ }
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_OutPins.size(); dwIndex++)
+ {
+ m_OutPins[dwIndex]->SetWorkQueue(dwWorkQueueId);
+ }
+ return S_OK;
+
+}
+
+//
+// IMFDeviceTransform functions
+//
+STDMETHODIMP CMultipinMft::GetStreamCount(
+ _Inout_ DWORD *pdwInputStreams,
+ _Inout_ DWORD *pdwOutputStreams
+ )
+/*++
+ Description: Implements IMFTransform::GetStreamCount function
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+ DMFTCHECKNULL_GOTO(pdwInputStreams, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pdwOutputStreams, done, E_INVALIDARG);
+ *pdwInputStreams = m_InputPinCount;
+ *pdwOutputStreams = m_OutputPinCount;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+done:
+ return hr;
+}
+
+//
+//Doesn't strictly conform to the GetStreamIDs on IMFTransform Interface!
+//
+STDMETHODIMP CMultipinMft::GetStreamIDs(
+ _In_ DWORD dwInputIDArraySize,
+ _When_(dwInputIDArraySize >= m_InputPinCount, _Out_writes_(dwInputIDArraySize)) DWORD* pdwInputIDs,
+ _In_ DWORD dwOutputIDArraySize,
+ _When_(dwOutputIDArraySize >= m_OutputPinCount && (pdwInputIDs && (dwInputIDArraySize > 0)),
+ _Out_writes_(dwOutputIDArraySize)) _On_failure_(_Valid_) DWORD* pdwOutputIDs
+ )
+/*++
+ Description:
+ Implements IMFTransform::GetStreamIDs function
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+ if ( ( dwInputIDArraySize < m_InputPinCount ) && ( dwOutputIDArraySize < m_OutputPinCount ) )
+ {
+ hr = MF_E_BUFFERTOOSMALL;
+ goto done;
+ }
+
+ if ( dwInputIDArraySize )
+ {
+ DMFTCHECKNULL_GOTO( pdwInputIDs, done, E_POINTER );
+ for ( DWORD dwIndex = 0; dwIndex < ((dwInputIDArraySize > m_InputPinCount) ? m_InputPinCount:
+ dwInputIDArraySize); dwIndex++ )
+ {
+ pdwInputIDs[ dwIndex ] = ( m_InPins[dwIndex] )->streamId();
+ }
+ }
+
+ if ( dwOutputIDArraySize )
+ {
+ DMFTCHECKNULL_GOTO( pdwOutputIDs, done, E_POINTER );
+ for ( DWORD dwIndex = 0; dwIndex < ((dwOutputIDArraySize > m_OutputPinCount)? m_OutputPinCount:
+ dwOutputIDArraySize); dwIndex++ )
+ {
+ pdwOutputIDs[ dwIndex ] = (m_OutPins[ dwIndex ])->streamId();
+ }
+ }
+done:
+ return hr;
+}
+
+/*++
+Name: CMultipinMft::GetInputAvailableType
+Description:
+Implements IMFTransform::GetInputAvailableType function. This function
+gets the media type supported by the specified stream based on the
+index dwTypeIndex.
+--*/
+STDMETHODIMP CMultipinMft::GetInputAvailableType(
+ _In_ DWORD dwInputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType
+ )
+{
+ HRESULT hr = S_OK;
+
+ ComPtr<CInPin> spiPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO( spiPin, done, MF_E_INVALIDSTREAMNUMBER );
+
+ *ppMediaType = nullptr;
+
+ hr = spiPin->GetOutputAvailableType( dwTypeIndex,ppMediaType );
+
+ if (FAILED(hr))
+ {
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Pin: %d Index: %d exiting %!HRESULT!",
+ dwInputStreamID,
+ dwTypeIndex,
+ hr);
+ }
+
+done:
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetOutputAvailableType(
+ _In_ DWORD dwOutputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputAvailableType function. This function
+ gets the media type supported by the specified stream based on the
+ index dwTypeIndex.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin( dwOutputStreamID );
+
+ DMFTCHECKNULL_GOTO( spoPin.Get(), done, MF_E_INVALIDSTREAMNUMBER );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+
+ *ppMediaType = nullptr;
+
+ hr = spoPin->GetOutputAvailableType( dwTypeIndex, ppMediaType );
+
+ if ( FAILED( hr ) )
+ {
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Pin: %d Index: %d exiting %!HRESULT!",
+ dwOutputStreamID,
+ dwTypeIndex,
+ hr );
+ }
+
+done:
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetInputCurrentType(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+ Implements IMFTransform::GetInputCurrentType function. This function
+ returns the current media type set on the specified stream.
+--*/
+{
+ //
+ // The input current types will not come to this transform.
+ // The outputs of this transform matter. The DTM manages the
+ // output of this transform and the inptuts of the source transform
+ //
+ UNREFERENCED_PARAMETER(dwInputStreamID);
+ UNREFERENCED_PARAMETER(ppMediaType);
+ return S_OK;
+}
+
+STDMETHODIMP CMultipinMft::GetOutputCurrentType(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFMediaType** ppMediaType
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputCurrentType function. This function
+ returns the current media type set on the specified stream.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin;
+ CAutoLock lock( m_critSec );
+
+ DMFTCHECKNULL_GOTO( ppMediaType, done, E_INVALIDARG );
+
+ *ppMediaType = nullptr;
+
+ spoPin = GetOutPin( dwOutputStreamID );
+
+ DMFTCHECKNULL_GOTO(spoPin, done, MF_E_INVALIDSTREAMNUMBER );
+
+ DMFTCHECKHR_GOTO(spoPin->getMediaType( ppMediaType ),done );
+
+ DMFTCHECKNULL_GOTO( *ppMediaType, done, MF_E_TRANSFORM_TYPE_NOT_SET );
+
+done:
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ return hr;
+}
+
+
+STDMETHODIMP CMultipinMft::ProcessEvent(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFMediaEvent* pEvent
+ )
+ /*++
+ Description:
+
+ Implements IMFTransform::ProcessEvent function. This function
+ processes events that come to the MFT.
+
+ --*/
+{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
+ UNREFERENCED_PARAMETER(pEvent);
+ return S_OK;
+}
+
+
+
+STDMETHODIMP CMultipinMft::ProcessMessage(
+ _In_ MFT_MESSAGE_TYPE eMessage,
+ _In_ ULONG_PTR ulParam
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::ProcessMessage function. This function
+ processes messages coming to the MFT.
+
+--*/
+{
+ HRESULT hr = S_OK;
+
+ UNREFERENCED_PARAMETER(ulParam);
+
+ CAutoLock _lock( m_critSec );
+
+ printMessageEvent( eMessage );
+
+ switch ( eMessage )
+ {
+ case MFT_MESSAGE_COMMAND_FLUSH:
+ //
+ // This is MFT wide flush.. Flush all output pins
+ //
+ (VOID)FlushAllStreams();
+ break;
+ case MFT_MESSAGE_COMMAND_DRAIN:
+ //
+ // There is no draining for Device MFT. Just kept here for reference
+ //
+ break;
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
+ //
+ // No op for device MFTs
+ //
+ break;
+ case MFT_MESSAGE_SET_D3D_MANAGER:
+ {
+ if ( ulParam )
+ {
+ ComPtr< IDirect3DDeviceManager9 > spD3D9Manager;
+ ComPtr< IMFDXGIDeviceManager > spDXGIManager;
+
+ hr = ( ( IUnknown* ) ulParam )->QueryInterface( IID_PPV_ARGS( &spD3D9Manager ) );
+ if ( SUCCEEDED( hr ) )
+ {
+ m_spDeviceManagerUnk = ( IUnknown* )ulParam;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! IDirect3DDeviceManager9 %p, is passed", spD3D9Manager.Get() );
+ }
+ else
+ {
+ hr = ( ( IUnknown* ) ulParam )->QueryInterface( IID_PPV_ARGS( &spDXGIManager ) );
+ if ( SUCCEEDED(hr) )
+ {
+ m_spDeviceManagerUnk = (IUnknown*)ulParam;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! IMFDXGIDeviceManager %p, is passed", spDXGIManager.Get());
+ }
+ }
+ }
+ else
+ {
+ m_spDeviceManagerUnk = nullptr;
+ hr = S_OK;
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC!IDirect3DDeviceManager9 was not passed in");
+ }
+ //
+ // set it on the pins. Can happen anytime
+ //
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_InPins.size(); dwIndex++)
+ {
+ m_InPins[dwIndex]->SetD3DManager(m_spDeviceManagerUnk.Get());
+ }
+ for (DWORD dwIndex = 0; dwIndex < (DWORD)m_OutPins.size(); dwIndex++)
+ {
+ m_OutPins[dwIndex]->SetD3DManager(m_spDeviceManagerUnk.Get());
+ }
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
+ {
+ SetStreamingState( DeviceStreamState_Run );
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_END_STREAMING:
+ {
+ SetStreamingState(DeviceStreamState_Stop);
+ }
+ break;
+ case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
+ {
+ SetStreamingState(DeviceStreamState_Stop);
+ }
+ break;
+ default:
+ ;
+ }
+
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::ProcessInput(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFSample* pSample,
+ _In_ DWORD dwFlags
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::ProcessInput function.This function is called
+ when the sourcetransform has input to feed. the pins will try to deliver the
+ samples to the active output pins conencted. if none are connected then just
+ returns the sample back to the source transform
+
+--*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER( dwFlags );
+
+ ComPtr<CInPin> spInPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO(spInPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ if ( !IsStreaming() )
+ {
+ goto done;
+ }
+
+ DMFTCHECKHR_GOTO(spInPin->SendSample( pSample ), done );
+done:
+ DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ //
+ //@@@@ README : There is a bug in the sample that the device transform manager which manages the
+ // device MFT does not release the sample after passing it to Device MFT in processInput like it should. The
+ // Device MFT therefore unfortunately has to make sure that the sample that leaves processoutput has a reference count of 1
+ //
+ SAFE_RELEASE(pSample);
+ return hr;
+
+}
+
+STDMETHODIMP CMultipinMft::ProcessOutput(
+ _In_ DWORD dwFlags,
+ _In_ DWORD cOutputBufferCount,
+ _Inout_updates_(cOutputBufferCount) MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
+ _Out_ DWORD *pdwStatus
+)
+/*++
+Description:
+
+Implements IMFTransform::ProcessOutput function. This is called by the DTM when
+the DT indicates it has samples to give. The DTM will send enough MFT_OUTPUT_DATA_BUFFER
+pointers to be filled up as is the number of output pins available. The DT should traverse its
+output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the samples available
+
+--*/
+{
+ HRESULT hr = S_OK;
+ BOOL gotOne = false;
+ ComPtr<COutPin> spOpin;
+ UNREFERENCED_PARAMETER( dwFlags );
+
+ if (cOutputBufferCount > m_OutputPinCount )
+ {
+ DMFTCHECKHR_GOTO( E_INVALIDARG, done );
+ }
+ *pdwStatus = 0;
+
+ for ( DWORD i = 0; i < cOutputBufferCount; i++ )
+ {
+ DWORD dwStreamID = pOutputSamples[i].dwStreamID;
+ {
+ CAutoLock _lock(m_critSec);
+ spOpin = nullptr;
+ spOpin = GetOutPin(dwStreamID);
+ GUID pinGuid = GUID_NULL;
+ DMFTCHECKNULL_GOTO(spOpin.Get(), done, E_INVALIDARG);
+ }
+ if ( SUCCEEDED(spOpin->ProcessOutput( dwFlags, &pOutputSamples[i],
+ pdwStatus ) ) )
+ {
+ gotOne = true;
+ }
+ }
+ if (gotOne)
+ {
+ hr = S_OK;
+ }
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetInputStreamAttributes(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFAttributes** ppAttributes
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetInputStreamAttributes function. This function
+ gets the specified input stream's attributes.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> spIPin;
+
+ DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG );
+ *ppAttributes = nullptr;
+
+ spIPin = GetInPin( dwInputStreamID );
+
+ DMFTCHECKNULL_GOTO(spIPin, done, E_INVALIDARG );
+
+ hr = spIPin->getPinAttributes(ppAttributes);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetOutputStreamAttributes(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFAttributes** ppAttributes
+ )
+/*++
+ Description:
+
+ Implements IMFTransform::GetOutputStreamAttributes function. This function
+ gets the specified output stream's attributes.
+
+--*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin;
+
+ DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
+
+ *ppAttributes = nullptr;
+
+ spoPin = GetOutPin(dwOutputStreamID);
+
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG );
+
+ DMFTCHECKHR_GOTO(spoPin->getPinAttributes(ppAttributes), done );
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+_Requires_no_locks_held_
+STDMETHODIMP CMultipinMft::SetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::SetInputStreamState function.
+ Sets the input stream state.
+
+ The control lock is not taken here. The lock is taken for operations on
+ output pins. This operation is a result of the DT notifying the DTM that
+ output pin change has resulted in the need for the input to be changed. In
+ this case the DTM sends a getpreferredinputstate and then this call
+
+ --*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(m_critSec);
+ ComPtr<CInPin> spiPin = GetInPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(spiPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ DMFTCHECKHR_GOTO(spiPin->SetInputStreamState(pMediaType, value, dwFlags),done);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> piPin = GetInPin(dwStreamID);
+
+ DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
+
+ *value = piPin->GetState();
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+STDMETHODIMP CMultipinMft::SetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState state,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::SetOutputStreamState function.
+ Sets the output stream state. This is called whenever the stream
+ is selected or deslected i.e. started or stopped.
+
+ The control lock taken here and this operation should be atomic.
+ This function should check the input pins connected to the output pin
+ switch off the state of the input pin. Check if any other Pin connected
+ to the input pin is in a conflicting state with the state requested on this
+ output pin. Accordinly it calculates the media type to be set on the input pin
+ and the state to transition into. It then might recreate the other output pins
+ connected to it
+ --*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwFlags);
+ CAutoLock Lock(m_critSec);
+
+ DMFTCHECKHR_GOTO(ChangeMediaTypeEx(dwStreamID, pMediaType, state),done);
+
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *pState
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::GetOutputStreamState function.
+ Gets the output stream state.
+ Called by the DTM to checks states. Atomic operation. needs a lock
+ --*/
+{
+ HRESULT hr = S_OK;
+ CAutoLock lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(pState, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(spoPin, done, MF_E_INVALIDSTREAMNUMBER);
+ *pState = spoPin->GetState();
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::GetInputStreamPreferredState(
+ _In_ DWORD dwStreamID,
+ _Inout_ DeviceStreamState *value,
+ _Outptr_opt_result_maybenull_ IMFMediaType **ppMediaType
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::GetInputStreamPreferredState function.
+ Gets the preferred state and the media type to be set on the input pin.
+ The lock is not held as this will always be called only when we notify
+ DTM to call us. We notify DTM only from the context on operations
+ happening on the output pin
+ --*/
+{
+ HRESULT hr = S_OK;
+ ComPtr<CInPin> spiPin = GetInPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(spiPin, done, MF_E_INVALIDSTREAMNUMBER);
+ hr = spiPin->GetInputStreamPreferredState(value, ppMediaType);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::FlushInputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::FlushInputStream function.
+ --*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwStreamIndex);
+ UNREFERENCED_PARAMETER(dwFlags);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::FlushOutputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags
+ )
+ /*++
+ Description:
+
+ Implements IMFdeviceTransform::FlushOutputStream function.
+ Called by the DTM to flush streams
+ --*/
+{
+
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(dwFlags);
+ CAutoLock Lock(m_critSec);
+
+ ComPtr<COutPin> spoPin = GetOutPin(dwStreamIndex);
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG);
+ DeviceStreamState oldState = spoPin->SetState(DeviceStreamState_Disabled);
+ DMFTCHECKHR_GOTO(spoPin->FlushQueues(),done);
+ spoPin->SetState(oldState);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+/*++
+ Description:
+
+ Called when the Device Transform gets a MFT_MESSAGE_COMMAND_FLUSH. We drain all the queues.
+ This is called in device source when the source gets end of streaming.
+ --*/
+STDMETHODIMP_(VOID) CMultipinMft::FlushAllStreams(
+ VOID
+ )
+{
+ DeviceStreamState oldState;
+ CAutoLock Lock(m_critSec);
+ for ( DWORD dwIndex = 0, dwSize = (DWORD)m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
+ {
+ ComPtr<COutPin> spoPin = (COutPin *)m_OutPins[dwIndex];
+ oldState = spoPin->SetState(DeviceStreamState_Disabled);
+ spoPin->FlushQueues();
+ //
+ //Restore state
+ //
+ spoPin->SetState(oldState);
+ }
+}
+
+
+//
+// IKsControl interface functions
+//
+STDMETHODIMP CMultipinMft::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pvPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pulBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsProperty function.
+ used to pass control commands to the driver (generally)
+ This can be used to intercepted the control to figure out
+ if it needs to be propogated to the driver or not
+ --*/
+{
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(pulBytesReturned);
+ DMFTCHECKNULL_GOTO(pProperty, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pulBytesReturned, done, E_INVALIDARG);
+
+ if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Extended Control %d Passed ",pProperty->Id);
+ }
+ else if ((IsEqualCLSID(pProperty->Set, PROPSETID_VIDCAP_VIDEOCONTROL)) && (pProperty->Id == KSPROPERTY_VIDEOCONTROL_MODE))
+ {
+ // A function illustrating how we can capture and service photos from the device MFT. This block shows how we can
+ // intercept Photo triggers going down to the pipeline
+
+ if (sizeof(KSPROPERTY_VIDEOCONTROL_MODE_S) == ulDataLength)
+ {
+ PKSPROPERTY_VIDEOCONTROL_MODE_S VideoControl = (PKSPROPERTY_VIDEOCONTROL_MODE_S)pvPropertyData;
+ m_PhotoModeIsPhotoSequence = false;
+ if (VideoControl->Mode == KS_VideoControlFlag_StartPhotoSequenceCapture)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Starting PhotoSequence Trigger");
+ m_PhotoModeIsPhotoSequence = true;
+ }
+ else if (VideoControl->Mode == KS_VideoControlFlag_StopPhotoSequenceCapture)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Stopping PhotoSequence Trigger");
+ m_PhotoModeIsPhotoSequence = false;
+ }
+ else
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Take Single Photo Trigger");
+ }
+ }
+ }
+ DMFTCHECKHR_GOTO(m_spIkscontrol->KsProperty(pProperty,
+ ulPropertyLength,
+ pvPropertyData,
+ ulDataLength,
+ pulBytesReturned),done);
+done:
+ LPSTR guidStr = DumpGUIDA(pProperty->Set);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! g:%s p:%d exiting %x = %!HRESULT!", guidStr, pProperty->Id, hr, hr);
+ delete(guidStr);
+ return hr;
+}
+
+STDMETHODIMP CMultipinMft::KsMethod(
+ _In_reads_bytes_(ulPropertyLength) PKSMETHOD pMethod,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pvPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pulBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsMethod function. We can trap ksmethod calls here.
+ --*/
+{
+ return m_spIkscontrol->KsMethod(
+ pMethod,
+ ulPropertyLength,
+ pvPropertyData,
+ ulDataLength,
+ pulBytesReturned
+ );
+}
+
+STDMETHODIMP CMultipinMft::KsEvent(
+ _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ )
+ /*++
+ Description:
+
+ Implements IKSProperty::KsEvent function.
+ --*/
+{
+
+ HRESULT hr = S_OK;
+ {
+
+ //
+ // All the Events we don't handle should be sent to the driver!
+ //
+ hr = m_spIkscontrol->KsEvent(pEvent,
+ ulEventLength,
+ pEventData,
+ ulDataLength,
+ pBytesReturned);
+ }
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
+
+//
+// IMFTransform function(s).
+//
+
+//
+// Note: This is the only IMFTransform function which is not a redirector to the
+// DeviceTransform functions. The rest of IMFTransform functions are in the file common.h
+// This function returns the IMFAttribute created for Device MFT. If DMFT is
+// not loaded (usually )MFT0's call to GetAttributes will get the Attribute store of DevProxy.
+// A device MFT loaded will not pass through the devproxy attribute store, but it will pass
+// the device MFT attributes. This should be similar to the singular DevProxy attribute
+// which the MFT0 providers can use to synchronize across various MFT0's
+//
+
+STDMETHODIMP CMultipinMft::GetAttributes(
+ _COM_Outptr_opt_result_maybenull_ IMFAttributes** ppAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(m_critSec);
+ DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
+
+ *ppAttributes = nullptr;
+
+ if (m_spAttributes != nullptr)
+ {
+ m_spAttributes.CopyTo(ppAttributes);
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+
+done:
+ return hr;
+}
+#endif
+
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+//
+// IMFSampleAllocatorControl Inferface function declarations
+//
+
+STDMETHODIMP CMultipinMft::SetDefaultAllocator(
+ _In_ DWORD dwOutputStreamID,
+ _In_ IUnknown *pAllocator
+)
+{
+ CAutoLock Lock(m_critSec);
+
+ // SetAllocator will be called on the streamId that returns MFSampleAllocatorMode_Default
+ wil::com_ptr_nothrow<COutPin> outPin = GetOutPin(dwOutputStreamID);
+ RETURN_HR_IF_NULL(E_INVALIDARG, outPin);
+ RETURN_HR_IF_NULL(E_INVALIDARG, pAllocator);
+
+ wil::com_ptr_nothrow<IMFVideoSampleAllocator> defaultAllocator;
+ RETURN_IF_FAILED(pAllocator->QueryInterface(&defaultAllocator));
+ outPin->SetAllocator(defaultAllocator.get());
+
+ return S_OK;
+}
+
+STDMETHODIMP CMultipinMft::GetAllocatorUsage(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ DWORD* pdwInputStreamID,
+ _Out_ MFSampleAllocatorUsage* peUsage
+)
+{
+ CAutoLock Lock(m_critSec);
+
+ RETURN_HR_IF_NULL(E_INVALIDARG, peUsage);
+
+ wil::com_ptr_nothrow<COutPin> outPin = GetOutPin(dwOutputStreamID);
+ RETURN_HR_IF_NULL(MF_E_INVALIDSTREAMNUMBER, outPin);
+ *peUsage = outPin->GetSampleAllocatorUsage();
+
+ if (*peUsage == MFSampleAllocatorUsage_DoesNotAllocate)
+ {
+ RETURN_HR_IF_NULL(E_INVALIDARG, pdwInputStreamID);
+ RETURN_IF_FAILED(GetConnectedInpin((ULONG)dwOutputStreamID, *(ULONG*)pdwInputStreamID));
+ }
+
+ return S_OK;
+}
+#endif // ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+
+//
+// HELPER FUNCTIONS
+//
+
+//
+// A lock here could mean a deadlock because this will be called when the lock is already held
+// in another thread.
+//
+CInPin* CMultipinMft::GetInPin(
+ _In_ DWORD dwStreamId
+)
+{
+ CInPin *inPin = NULL;
+ for (DWORD dwIndex = 0, dwSize = (DWORD)m_InPins.size(); dwIndex < dwSize; dwIndex++)
+ {
+ inPin = (CInPin *)m_InPins[dwIndex];
+ if (dwStreamId == inPin->streamId())
+ {
+ break;
+ }
+ inPin = NULL;
+ }
+ return inPin;
+}
+
+COutPin* CMultipinMft::GetOutPin(
+ _In_ DWORD dwStreamId
+ )
+{
+ COutPin *outPin = NULL;
+ for ( DWORD dwIndex = 0, dwSize = (DWORD) m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
+ {
+ outPin = ( COutPin * )m_OutPins[ dwIndex ];
+
+ if ( dwStreamId == outPin->streamId() )
+ {
+ break;
+ }
+
+ outPin = NULL;
+ }
+
+ return outPin;
+}
+_Requires_lock_held_(m_Critsec)
+HRESULT CMultipinMft::GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin)
+{
+ HRESULT hr = S_OK;
+ map<int, int>::iterator it = m_outputPinMap.find(ulOutpin);
+ if (it != m_outputPinMap.end())
+ {
+ ulInPin = it->second;
+ }
+ else
+ {
+ hr = MF_E_INVALIDSTREAMNUMBER;
+ }
+ return hr;
+}
+
+//
+// The Below function changes media type on the pins exposed by device MFT
+//
+__requires_lock_held(m_critSec)
+HRESULT CMultipinMft::ChangeMediaTypeEx(
+ _In_ ULONG pinId,
+ _In_opt_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState reqState
+)
+{
+ HRESULT hr = S_OK;
+ ComPtr<COutPin> spoPin = GetOutPin(pinId);
+ ComPtr<CInPin> spinPin;
+ DeviceStreamState oldOutPinState, oldInputStreamState, newOutStreamState, newRequestedInPinState;
+ ComPtr<IMFMediaType> pFullType, pInputMediaType;
+ ULONG ulInPinId = 0;
+ DWORD dwFlags = 0;
+
+
+ DMFTCHECKNULL_GOTO(spoPin, done, E_INVALIDARG);
+ {
+ //
+ // dump the media types to the logs
+ //
+ ComPtr<IMFMediaType> spOldMediaType;
+ (VOID)spoPin->getMediaType(spOldMediaType.GetAddressOf());
+ CMediaTypePrinter newType(pMediaType);
+ CMediaTypePrinter oldType(spOldMediaType.Get());
+ if (WPP_LEVEL_ENABLED(DMFT_GENERAL))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Pin:%d old MT:[%s] St:%d", pinId, oldType.ToString(), reqState);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Pin:%d new MT:[%s] St:%d", pinId, newType.ToString(), reqState);
+ }
+ }
+
+ if (pMediaType)
+ {
+ if (!spoPin->IsMediaTypeSupported(pMediaType, &pFullType))
+ {
+ DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
+ }
+ }
+
+ DMFTCHECKHR_GOTO(GetConnectedInpin(pinId, ulInPinId), done);
+ spinPin = GetInPin(ulInPinId); // Get the input pin
+
+ (VOID)spinPin->getMediaType(&pInputMediaType);
+ oldInputStreamState = spinPin->SetState(DeviceStreamState_Disabled); // Disable input pin
+ oldOutPinState = spoPin->SetState(DeviceStreamState_Disabled); // Disable output pin
+ (void)spoPin->FlushQueues(); // Flush the output queues
+ (void)spinPin->FlushQueues(); // Flush the input queues
+ newOutStreamState = pinStateTransition[oldOutPinState][reqState]; // New state needed
+
+ // The Old input and the output pin states should be the same
+ newRequestedInPinState = newOutStreamState;
+
+ if ((newOutStreamState != oldOutPinState) /*State change*/
+ ||((pFullType.Get() != nullptr) && (pInputMediaType.Get()!=nullptr) && (S_OK != (pFullType->IsEqual(pInputMediaType.Get(), &dwFlags)))) /*Media Types dont match*/
+ ||((pFullType == nullptr)||(pInputMediaType == nullptr))/*Either one of the mediatypes is null*/
+ )
+ {
+ //
+ // State has change or media type has changed so we need to change the media type on the
+ // underlying kernel pin
+ //
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Changing Mediatype on the input ");
+ spinPin->setPreferredMediaType(pFullType.Get());
+ spinPin->setPreferredStreamState(newRequestedInPinState);
+ // Let the pipline know that the input needs to be changed.
+ SendEventToManager(METransformInputStreamStateChanged, GUID_NULL, spinPin->streamId());
+ //
+ // The media type will be set on the input pin by the time we return from the wait
+ //
+ m_critSec.Unlock();
+ hr = spinPin->WaitForSetInputPinMediaChange();
+ m_critSec.Lock();
+ // Change the media type on the output..
+ DMFTCHECKHR_GOTO(spoPin->ChangeMediaTypeFromInpin(pFullType.Get(), pMediaType , reqState), done);
+ //
+ // Notify the pipeline that the output stream media type has changed
+ //
+ DMFTCHECKHR_GOTO(SendEventToManager(MEUnknown, MEDeviceStreamCreated, spoPin->streamId()), done);
+ spoPin->SetFirstSample(TRUE);
+ }
+ else
+ {
+ // Restore back old states as we have nothing to do
+ spinPin->SetState(oldInputStreamState);
+ spoPin->SetState(oldOutPinState);
+ }
+
+
+done:
+ return hr;
+}
+
+//
+// The below function sends events to the pipeline.
+//
+
+HRESULT CMultipinMft::SendEventToManager(
+ _In_ MediaEventType eventType,
+ _In_ REFGUID pGuid,
+ _In_ UINT32 context
+ )
+ /*++
+ Description:
+ Used to send the event to DTM.
+ --*/
+ {
+ HRESULT hr = S_OK;
+ ComPtr<IMFMediaEvent> pEvent = nullptr;
+
+ DMFTCHECKHR_GOTO(MFCreateMediaEvent(eventType, pGuid, S_OK, NULL, &pEvent ),done);
+ DMFTCHECKHR_GOTO(pEvent->SetUINT32(MF_EVENT_MFT_INPUT_STREAM_ID, (ULONG)context),done);
+ DMFTCHECKHR_GOTO(QueueEvent(pEvent.Get()),done);
+ done:
+
+ return hr;
+ }
+/*++
+Description:
+This function connects the input and output pins.
+Any media type filtering can happen here
+--*/
+HRESULT CMultipinMft::BridgeInputPinOutputPin(
+ _In_ CInPin* piPin,
+ _In_ COutPin* poPin
+ )
+{
+ HRESULT hr = S_OK;
+ ULONG ulIndex = 0;
+ ULONG ulAddedMediaTypeCount = 0;
+ ComPtr<IMFMediaType> spMediaType;
+
+ DMFTCHECKNULL_GOTO( piPin, done, E_INVALIDARG );
+ DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
+ //
+ // Copy over the media types from input pin to output pin. Since there is no
+ // decoder support, only the uncompressed media types are inserted. Please make
+ // sure any pin advertised supports at least one media type. The pipeline doesn't
+ // like pins with no media types
+ //
+ while ( SUCCEEDED( hr = piPin->GetMediaTypeAt( ulIndex++, spMediaType.ReleaseAndGetAddressOf() )))
+ {
+ GUID subType = GUID_NULL;
+ DMFTCHECKHR_GOTO( spMediaType->GetGUID(MF_MT_SUBTYPE,&subType), done );
+ {
+ DMFTCHECKHR_GOTO(hr = poPin->AddMediaType(NULL, spMediaType.Get() ), done );
+ if (hr == S_OK)
+ {
+ ulAddedMediaTypeCount++;
+ }
+ }
+ }
+ if (ulAddedMediaTypeCount == 0)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Make Sure Pin %d has one media type exposed ", piPin->streamId());
+ DMFTCHECKHR_GOTO( MF_E_INVALID_STREAM_DATA, done );
+ }
+ //
+ //Add the Input Pin to the output Pin
+ //
+ DMFTCHECKHR_GOTO(poPin->AddPin(piPin->streamId()), done);
+ hr = ExceptionBoundary([&](){
+ //
+ // Add the output pin to the input pin.
+ // Create the pin map. So that we know which pin input pin is connected to which output pin
+ //
+ piPin->ConnectPin(poPin);
+ m_outputPinMap.insert(std::pair< int, int >(poPin->streamId(), piPin->streamId()));
+ });
+
+
+
+done:
+ //
+ //Failed adding media types
+ //
+ if (FAILED(hr))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_ERROR, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ }
+ return hr;
+}
+
+//
+// IMFShutdown interface functions
+//
+
+/*++
+Description:
+Implements the Shutdown from IMFShutdown
+--*/
+STDMETHODIMP CMultipinMft::Shutdown(
+ void
+ )
+{
+ CAutoLock Lock(m_critSec);
+ (VOID) m_eventHandler.Clear();
+
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_InPins.size(); ulIndex < ulSize; ulIndex++ )
+ {
+ CInPin *pInPin = static_cast<CInPin *>(m_InPins[ulIndex]);
+
+ // Deref on the connected outpins to break reference loop
+ (VOID)pInPin->ShutdownPin();
+ }
+#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_OutPins.size(); ulIndex < ulSize; ulIndex++)
+ {
+ (VOID) m_OutPins[ulIndex]->DeleteItem(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT);
+ }
+#endif
+ return ShutdownEventGenerator();
+}
+
+//
+// Static method to create an instance of the MFT.
+//
+HRESULT CMultipinMft::CreateInstance(REFIID iid, void **ppMFT)
+{
+ HRESULT hr = S_OK;
+ CMultipinMft *pMFT = NULL;
+ DMFTCHECKNULL_GOTO(ppMFT, done, E_POINTER);
+ pMFT = new (std::nothrow) CMultipinMft();
+ DMFTCHECKNULL_GOTO(pMFT, done, E_OUTOFMEMORY);
+
+ DMFTCHECKHR_GOTO(pMFT->QueryInterface(iid, ppMFT), done);
+
+done:
+ if (FAILED(hr))
+ {
+ SAFERELEASE(pMFT);
+ }
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
diff --git a/avstream/sampledevicemft/SampleSocDeviceMFT.h b/avstream/sampledevicemft/SampleSocDeviceMFT.h
new file mode 100644
index 00000000..91635fb1
--- /dev/null
+++ b/avstream/sampledevicemft/SampleSocDeviceMFT.h
@@ -0,0 +1,374 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#pragma once
+#include "common.h"
+#include "mftpeventgenerator.h"
+#include "basepin.h"
+#include "custompin.h"
+#include "multipinmfthelpers.h"
+
+//
+// The Below GUID is needed to transfer photoconfirmation sample successfully in the pipeline
+// It is used to propagate the mediatype of the sample to the pipeline which will consume the sample
+// This attribute is known to the OS, but not publicly defined.
+//
+
+DEFINE_GUID(MFSourceReader_SampleAttribute_MediaType_priv,
+ 0x0ea5c1e8, 0x9845, 0x41e0, 0xa2, 0x43, 0x72, 0x32, 0x07, 0xfc, 0x78, 0x1f);
+
+
+interface IDirect3DDeviceManager9;
+
+//
+// Forward declarations
+//
+class CMFAttributes;
+class CPinCreationFactory;
+//
+// CMultipinMft class:
+// Implements a device proxy MFT.
+//
+class CMultipinMft :
+ public IMFDeviceTransform
+#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
+ , public IMFTransform
+#endif
+ , public IMFShutdown
+ , public CMediaEventGenerator
+ , public IMFRealTimeClientEx
+ , public IKsControl
+ , public CDMFTModuleLifeTimeManager
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+ , public IMFSampleAllocatorControl
+#endif
+{
+ friend class CPinCreationFactory;
+public:
+ CMultipinMft(
+ void );
+
+ virtual ~CMultipinMft();
+
+ //
+ // IUnknown
+ //
+ STDMETHOD_(ULONG, AddRef)(
+ void );
+
+ STDMETHOD_(ULONG, Release)(
+ void );
+
+ STDMETHOD(QueryInterface)(
+ _In_ REFIID iid,
+ _COM_Outptr_ void** ppv);
+
+
+ //
+ // IMFDeviceTransform functions
+ //
+ STDMETHOD(GetStreamCount)(
+ _Inout_ DWORD *pdwInputStreams,
+ _Inout_ DWORD *pdwOutputStreams);
+
+
+ STDMETHOD(GetStreamIDs)(
+ _In_ DWORD dwInputIDArraySize,
+ _When_(dwInputIDArraySize >= m_InputPinCount, _Out_writes_(dwInputIDArraySize)) DWORD* pdwInputIDs,
+ _In_ DWORD dwOutputIDArraySize,
+ _When_(dwOutputIDArraySize >= m_OutputPinCount && (pdwInputIDs && (dwInputIDArraySize > 0)),
+ _Out_writes_(dwOutputIDArraySize)) _On_failure_(_Valid_) DWORD* pdwOutputIDs
+ );
+
+ STDMETHOD(GetInputStreamAttributes)(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFAttributes** ppAttributes);
+
+ STDMETHOD(GetOutputStreamAttributes)(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFAttributes** ppAttributes);
+
+ STDMETHOD(GetInputAvailableType)(
+ _In_ DWORD dwInputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppType);
+
+ STDMETHOD(GetOutputAvailableType)(
+ _In_ DWORD dwOutputStreamID,
+ _In_ DWORD dwTypeIndex,
+ _Out_ IMFMediaType** ppMediaType);
+
+ STDMETHOD(GetInputCurrentType)(
+ _In_ DWORD dwInputStreamID,
+ _COM_Outptr_result_maybenull_ IMFMediaType** ppMediaType);
+
+ STDMETHOD(GetOutputCurrentType)(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ IMFMediaType** ppMediaType);
+
+ STDMETHOD(ProcessMessage)(
+ _In_ MFT_MESSAGE_TYPE eMessage,
+ _In_ ULONG_PTR ulParam );
+
+ STDMETHOD(ProcessEvent)(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFMediaEvent *pEvent);
+
+
+ STDMETHOD(ProcessInput)(
+ _In_ DWORD dwInputStreamID,
+ _In_ IMFSample* pSample,
+ _In_ DWORD dwFlags );
+
+ STDMETHOD(ProcessOutput)(
+ _In_ DWORD dwFlags,
+ _In_ DWORD cOutputBufferCount,
+ _Inout_updates_(cOutputBufferCount) MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
+ _Out_ DWORD *pdwStatus );
+
+ //
+ // IMFRealTimeClientEx
+ //
+ STDMETHOD(RegisterThreadsEx)(
+ _Inout_ DWORD* pdwTaskIndex,
+ _In_ LPCWSTR wszClassName,
+ _In_ LONG lBasePriority )
+ {
+ UNREFERENCED_PARAMETER(pdwTaskIndex);
+ UNREFERENCED_PARAMETER(wszClassName);
+ UNREFERENCED_PARAMETER(lBasePriority);
+ return S_OK;
+ }
+
+ STDMETHOD(UnregisterThreads)()
+ {
+ return S_OK;
+ }
+
+ STDMETHOD(SetWorkQueueEx)(
+ _In_ DWORD dwWorkQueueId,
+ _In_ LONG lWorkItemBasePriority );
+
+ //
+ // IMFShutdown
+ //
+ STDMETHOD(Shutdown)(
+ void );
+
+ STDMETHOD(GetShutdownStatus)(
+ MFSHUTDOWN_STATUS *pStatus)
+ {
+ UNREFERENCED_PARAMETER(pStatus);
+ return(m_eShutdownStatus);
+ };
+
+ //
+ // IMFDeviceTransform function declarations
+ //
+ STDMETHODIMP InitializeTransform(
+ _In_ IMFAttributes *pAttributes );
+
+ _Requires_no_locks_held_
+ STDMETHODIMP SetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags );
+
+ STDMETHODIMP GetInputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value );
+
+ STDMETHODIMP SetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _In_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState value,
+ _In_ DWORD dwFlags );
+
+ STDMETHODIMP GetOutputStreamState(
+ _In_ DWORD dwStreamID,
+ _Out_ DeviceStreamState *value );
+
+ STDMETHODIMP GetInputStreamPreferredState(
+ _In_ DWORD dwStreamID,
+ _Inout_ DeviceStreamState *value,
+ _Outptr_opt_result_maybenull_ IMFMediaType **ppMediaType );
+
+ STDMETHODIMP FlushInputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags );
+
+ STDMETHODIMP FlushOutputStream(
+ _In_ DWORD dwStreamIndex,
+ _In_ DWORD dwFlags );
+
+ STDMETHODIMP_(VOID) FlushAllStreams(
+ VOID
+ );
+
+ //
+ //IKSControl Inferface function declarations
+ //
+ STDMETHOD(KsEvent)(
+ _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+ STDMETHOD(KsProperty)(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+ STDMETHOD(KsMethod)(
+ _In_reads_bytes_(ulPropertyLength) PKSMETHOD pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_bytes_(ulDataLength) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Inout_ ULONG* pBytesReturned
+ );
+
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+ //
+ // IMFSampleAllocatorControl Inferface function declarations
+ //
+
+ STDMETHOD(SetDefaultAllocator)(
+ _In_ DWORD dwOutputStreamID,
+ _In_ IUnknown *pAllocator
+ );
+
+ STDMETHOD(GetAllocatorUsage)(
+ _In_ DWORD dwOutputStreamID,
+ _Out_ DWORD* pdwInputStreamID,
+ _Out_ MFSampleAllocatorUsage* peUsage
+ );
+#endif
+ static STDMETHODIMP CreateInstance(
+ REFIID iid, void **ppMFT);
+
+ __inline BOOL isPhotoModePhotoSequence()
+ {
+ return m_PhotoModeIsPhotoSequence;
+ }
+
+ _inline DWORD GetQueueId()
+ {
+ return m_dwWorkQueueId;
+ }
+
+ //
+ //Will be used from Pins to get the D3D manager once set!!!
+ //
+ __inline STDMETHODIMP_(VOID) GetD3DDeviceManager(
+ IUnknown** ppDeviceManagerUnk
+ )
+ {
+ m_spDeviceManagerUnk.CopyTo( ppDeviceManagerUnk );
+ }
+
+ HRESULT SendEventToManager(
+ _In_ MediaEventType,
+ _In_ REFGUID,
+ _In_ UINT32
+ );
+
+protected:
+
+ //
+ //Helper functions
+ //
+
+ CInPin* GetInPin(
+ _In_ DWORD dwStreamID
+ );
+
+ COutPin* GetOutPin(
+ _In_ DWORD dwStreamID
+ );
+
+ HRESULT GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin);
+
+ __requires_lock_held(m_critSec)
+ HRESULT ChangeMediaTypeEx(
+ _In_ ULONG pinId,
+ _In_opt_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState newState
+ );
+ HRESULT BridgeInputPinOutputPin(
+ _In_ CInPin* pInPin,
+ _In_ COutPin* pOutPin);
+#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
+ STDMETHODIMP CMultipinMft::GetAttributes(
+ _COM_Outptr_opt_result_maybenull_ IMFAttributes** ppAttributes
+ );
+#endif
+
+#if (defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES))
+ _DEFINE_DEVICEMFT_MFT0HELPER_IMPL__
+#endif
+
+
+
+ //
+ //Inline functions
+ //
+
+ __inline IMFTransform* Parent()
+ {
+ return m_spSourceTransform.Get();
+ }
+
+ __inline VOID SetStreamingState(DeviceStreamState state)
+ {
+ InterlockedExchange((LONG*)&m_StreamingState, state);
+ }
+ __inline DeviceStreamState GetStreamingState()
+ {
+ return (DeviceStreamState)InterlockedCompareExchange((LONG*)&m_StreamingState, 0L, 0L);
+ }
+ __inline BOOL IsStreaming()
+ {
+ return (InterlockedCompareExchange((LONG*)&m_StreamingState, DeviceStreamState_Run, DeviceStreamState_Run) == DeviceStreamState_Run);
+ }
+
+private:
+ ULONG m_InputPinCount;
+ ULONG m_OutputPinCount;
+ ULONG m_CustomPinCount;
+ DeviceStreamState m_StreamingState;
+ CBasePinArray m_OutPins;
+ CBasePinArray m_InPins;
+ BOOL m_PhotoModeIsPhotoSequence; // used to store if the filter is in photo sequence or not
+ long m_nRefCount; // Reference count
+ CCritSec m_critSec; // Control lock.. taken only durign state change operations
+ ComPtr <IUnknown> m_spDeviceManagerUnk; // D3D Manager set, when MFT_MESSAGE_SET_D3D_MANAGER is called through ProcessMessage
+ ComPtr<IMFTransform> m_spSourceTransform; // The sources transform. This is the pipeline DevProxy
+ MFSHUTDOWN_STATUS m_eShutdownStatus;
+ DWORD m_dwWorkQueueId;
+ LONG m_lWorkQueuePriority;
+ UINT32 m_punValue;
+ ComPtr<IKsControl> m_spIkscontrol;
+ ComPtr<IMFAttributes> m_spAttributes;
+ map<int, int> m_outputPinMap; // How output pins are connected to input pins i-><0..outpins>
+ CDMFTEventHandler m_eventHandler;
+ PWCHAR m_SymbolicLink;
+
+};
+
+
+
+inline HRESULT MFT_CreateInstance(REFIID riid, void **ppv)
+{
+ return CMultipinMft::CreateInstance(riid, ppv);
+}
+
+
diff --git a/avstream/sampledevicemft/SampleSocDeviceMFTutils.cpp b/avstream/sampledevicemft/SampleSocDeviceMFTutils.cpp
new file mode 100644
index 00000000..1b41496b
--- /dev/null
+++ b/avstream/sampledevicemft/SampleSocDeviceMFTutils.cpp
@@ -0,0 +1,1320 @@
+//*@@@+++@@@@******************************************************************
+//
+// Microsoft Windows Media Foundation
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//*@@@---@@@@******************************************************************
+//
+
+#include "stdafx.h"
+#include "common.h"
+#include "multipinmft.h"
+#include "basepin.h"
+
+#pragma comment(lib, "d2d1")
+#ifdef MF_WPP
+#include "multipinmftutils.tmh" //--REF_ANALYZER_DONT_REMOVE--
+#endif
+
+// Critical sections
+
+CCritSec::CCritSec()
+{
+ InitializeCriticalSection(&m_criticalSection);
+}
+
+CCritSec::~CCritSec()
+{
+ DeleteCriticalSection(&m_criticalSection);
+}
+
+_Requires_lock_not_held_(m_criticalSection) _Acquires_lock_(m_criticalSection)
+void CCritSec::Lock()
+{
+ EnterCriticalSection(&m_criticalSection);
+}
+
+_Requires_lock_held_(m_criticalSection) _Releases_lock_(m_criticalSection)
+void CCritSec::Unlock()
+{
+ LeaveCriticalSection(&m_criticalSection);
+}
+
+
+_Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::CAutoLock(CCritSec& crit)
+{
+ m_pCriticalSection = &crit;
+ m_pCriticalSection->Lock();
+}
+_Acquires_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::CAutoLock(CCritSec* crit)
+{
+ m_pCriticalSection = crit;
+ m_pCriticalSection->Lock();
+}
+_Releases_lock_(this->m_pCriticalSection->m_criticalSection)
+CAutoLock::~CAutoLock()
+{
+ m_pCriticalSection->Unlock();
+}
+
+//
+//Some utility functions..
+//
+
+/*++
+ Description:
+ Used to check if the input and the output Image types are optinmized or not
+--*/
+
+STDMETHODIMP IsOptimizedPlanarVideoInputImageOutputPair(
+ _In_ IMFMediaType *inMediaType,
+ _In_ IMFMediaType *outMediaType,
+ _Out_ bool *optimized,
+ _Out_ bool *optimizedxvpneeded )
+{
+ HRESULT hr = S_OK;
+ GUID guidInputSubType = GUID_NULL;
+ GUID guidOutputSubType = GUID_NULL;
+ UINT32 uWidthIn = 0, uHeightIn = 0, uWidthOut = 0, uHeightOut = 0;
+
+
+ DMFTCHECKHR_GOTO(inMediaType->GetGUID(MF_MT_SUBTYPE, &guidInputSubType), done);
+
+ DMFTCHECKHR_GOTO(outMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
+
+ *optimized = false; //Assume we aren't optimized . Optimized = (ip = YU12|NV12 and op = JPEG)
+ *optimizedxvpneeded = true; //Assume we need xvps
+
+ if (IsEqualGUID(guidInputSubType, MFVideoFormat_YV12) || IsEqualGUID(guidInputSubType, MFVideoFormat_NV12))
+ {
+ if (IsEqualGUID(guidOutputSubType, GUID_ContainerFormatJpeg))
+ {
+ *optimized = true;
+ }
+ }
+
+ if (!*optimized)
+ {
+ goto done;
+ }
+
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(inMediaType, MF_MT_FRAME_SIZE, &uWidthIn, &uHeightIn), done);
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(outMediaType, MF_MT_FRAME_SIZE, &uWidthOut, &uHeightOut), done);
+
+ if ((uWidthIn == uWidthOut) && (uHeightIn == uHeightOut))
+ {
+ *optimizedxvpneeded = false;
+ }
+ if (!*optimizedxvpneeded)
+ {
+ UINT32 nominalRange;
+ hr = inMediaType->GetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, &nominalRange);
+
+ if (FAILED(hr) || nominalRange != MFNominalRange_0_255)
+ {
+ //XVP needed since nominal range is not 0-255 for YV12 or NV12 fed into WIC
+ *optimizedxvpneeded = true;
+ }
+ hr = S_OK;
+ }
+
+done:
+ return hr;
+}
+
+
+/*
+Description:
+
+ This is used whenever there is a media type change on an output pin and the
+ Output queue is being reconfigured.
+ The possible return values for the function are as follows
+
+ DeviceMftTransformXVPIllegal -> If either of the mediatypes or both are NULL
+ DeviceMftTransformXVPDisruptiveIn -> If the mediatype at the output pin is greater than the input pin. This will result in change of the media type on the input
+ DeviceMftTransformXVPDisruptiveOut -> This is a reconfiguration or addition of the XVP in the Output pin queue
+ DeviceMftTransformXVPCurrent -> No XVP needed at all
+*/
+STDMETHODIMP CompareMediaTypesForConverter(
+ _In_opt_ IMFMediaType *inMediaType,
+ _In_ IMFMediaType *newMediaType,
+ _Inout_ PDMFT_conversion_type operation
+ )
+{
+ HRESULT hr = S_OK;
+ GUID guidTypeA = GUID_NULL;
+ GUID guidTypeB = GUID_NULL;
+
+ *operation = DeviceMftTransformTypeIllegal;
+ if ((!inMediaType) || (!newMediaType))
+ {
+ goto done;
+ }
+
+ if ( SUCCEEDED( inMediaType->GetGUID( MF_MT_MAJOR_TYPE, &guidTypeA ) ) &&
+ SUCCEEDED( newMediaType->GetGUID( MF_MT_MAJOR_TYPE, &guidTypeB ) ) &&
+ IsEqualGUID( guidTypeA, guidTypeB ) )
+ {
+ if ( SUCCEEDED( inMediaType->GetGUID ( MF_MT_SUBTYPE, &guidTypeA ) ) &&
+ SUCCEEDED( newMediaType->GetGUID( MF_MT_SUBTYPE, &guidTypeB ) ) &&
+ IsEqualGUID( guidTypeA, guidTypeB ) )
+ {
+ BOOL passThrough = TRUE;
+ DMFTCHECKHR_GOTO(CheckPassthroughMediaType(inMediaType, newMediaType, passThrough), done);
+ *operation = passThrough?DeviceMftTransformTypeEqual: DeviceMftTransformTypeXVP;
+ }
+ else
+ {
+ //This is a disruptive operation. Actually a decoder operation!
+ *operation = DeviceMftTransformTypeDecoder;
+ }
+ }
+ done:
+ return hr;
+}
+
+/*++
+Description: Used to test if the sample passed is a DX sample or not?
+--*/
+HRESULT IsInputDxSample(
+ _In_ IMFSample* pSample,
+ _Inout_ BOOL *isDxSample
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFMediaBuffer> spBuffer = nullptr;
+ DMFTCHECKNULL_GOTO( pSample, done, E_INVALIDARG );
+
+ *isDxSample = false;
+ if ( SUCCEEDED( pSample->GetBufferByIndex( 0, &spBuffer ) ) )
+ {
+ ComPtr<IMFDXGIBuffer> spDXGIBuffer;
+ ComPtr<ID3D11Texture2D> spResourceTexture;
+ if ( SUCCEEDED( spBuffer.As(&spDXGIBuffer ) ) &&
+ SUCCEEDED( spDXGIBuffer-> GetResource( IID_PPV_ARGS( &spResourceTexture ) ) ) )
+ {
+ *isDxSample = true;
+ }
+ }
+done:
+ return hr;
+}
+
+
+/*++
+ Description:
+ Helper function to return back if the Pin is in stopped stateo or not
+--*/
+STDMETHODIMP_(BOOL) IsPinStateInActive( _In_ DeviceStreamState state)
+{
+ if ((state == DeviceStreamState_Disabled) ||
+ (state == DeviceStreamState_Stop))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+Description:
+ A Helper function to return if the Mediatype is a compressed video type or not!
+*/
+STDMETHODIMP_(BOOL) IsKnownUncompressedVideoType(_In_ GUID guidSubType)
+{
+ if (guidSubType == MFVideoFormat_ARGB32 ||
+ guidSubType == MFVideoFormat_RGB24 ||
+ guidSubType == MFVideoFormat_RGB555 ||
+ guidSubType == MFVideoFormat_RGB565 ||
+ guidSubType == MFVideoFormat_RGB32 ||
+ guidSubType == MFVideoFormat_RGB8 ||
+ guidSubType == MFVideoFormat_AI44 ||
+ guidSubType == MFVideoFormat_AYUV ||
+ guidSubType == MFVideoFormat_YUY2 ||
+ guidSubType == MFVideoFormat_YVYU ||
+ guidSubType == MFVideoFormat_YVU9 ||
+ guidSubType == MFVideoFormat_UYVY ||
+ guidSubType == MFVideoFormat_NV11 ||
+ guidSubType == MFVideoFormat_NV12 ||
+ guidSubType == MFVideoFormat_YV12 ||
+ guidSubType == MFVideoFormat_I420 ||
+ guidSubType == MFVideoFormat_IYUV ||
+ guidSubType == MFVideoFormat_Y210 ||
+ guidSubType == MFVideoFormat_Y216 ||
+ guidSubType == MFVideoFormat_Y410 ||
+ guidSubType == MFVideoFormat_Y416 ||
+ guidSubType == MFVideoFormat_Y41P ||
+ guidSubType == MFVideoFormat_Y41T ||
+ guidSubType == MFVideoFormat_Y42T ||
+ guidSubType == MFVideoFormat_P210 ||
+ guidSubType == MFVideoFormat_P216 ||
+ guidSubType == MFVideoFormat_P010 ||
+ guidSubType == MFVideoFormat_P016 ||
+ guidSubType == MFVideoFormat_v210 ||
+ guidSubType == MFVideoFormat_v216 ||
+ guidSubType == MFVideoFormat_v410 ||
+ guidSubType == MFVideoFormat_L8 ||
+ guidSubType == MFVideoFormat_L16 ||
+ guidSubType == MFVideoFormat_D16)
+ {
+ return( TRUE );
+ }
+
+ return( FALSE );
+}
+
+#ifndef IF_EQUAL_RETURN
+#define IF_EQUAL_RETURN(param, val) if(val == param) return #val
+#endif
+
+#define checkAdjustBufferCap(a,len){\
+ char* tStore = NULL; \
+if (a && strlen(a) > ((len * 7) / 10)){\
+ tStore = a; \
+ len *= 2; \
+ a = new (std::nothrow) char[len]; \
+if (!a){\
+goto done;}\
+ a[0] = 0; \
+ strcat_s(a, len, tStore); \
+ delete(tStore); }\
+}
+
+
+/*++
+Description:
+ returns an ascii buffer for the GUID passed. The Caller should release the memory allocated
+--*/
+LPSTR DumpGUIDA(_In_ REFGUID guid)
+{
+ LPOLESTR lpszGuidString = NULL;
+ char *ansiguidStr = NULL;
+ if (SUCCEEDED(StringFromCLSID(guid, &lpszGuidString)))
+ {
+ int mbGuidLen = 0;
+ mbGuidLen = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, lpszGuidString, -1, NULL, 0, NULL, NULL);
+ if (mbGuidLen > 0)
+ {
+ mf_assert(mbGuidLen == (int)wcslen(lpszGuidString));
+ ansiguidStr = new (std::nothrow) char[mbGuidLen];
+ if (ansiguidStr)
+ {
+ WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, lpszGuidString, -1, ansiguidStr, mbGuidLen, NULL, NULL);
+ CoTaskMemFree(lpszGuidString);
+ ansiguidStr[mbGuidLen - 1] = 0;
+ }
+ }
+ }
+ return ansiguidStr;
+}
+
+//
+//Borrrowed from MDSN sample
+//
+LPCSTR GetGUIDNameConst(const GUID& guid)
+{
+ IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_SUBTYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_ALL_SAMPLES_INDEPENDENT);
+ IF_EQUAL_RETURN(guid, MF_MT_FIXED_SIZE_SAMPLES);
+ IF_EQUAL_RETURN(guid, MF_MT_COMPRESSED);
+ IF_EQUAL_RETURN(guid, MF_MT_SAMPLE_SIZE);
+ IF_EQUAL_RETURN(guid, MF_MT_WRAPPED_TYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_NUM_CHANNELS);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_SECOND);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_AVG_BYTES_PER_SECOND);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BLOCK_ALIGNMENT);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BITS_PER_SAMPLE);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_VALID_BITS_PER_SAMPLE);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_BLOCK);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_CHANNEL_MASK);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FOLDDOWN_MATRIX);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKREF);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKTARGET);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGREF);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGTARGET);
+ IF_EQUAL_RETURN(guid, MF_MT_AUDIO_PREFER_WAVEFORMATEX);
+ IF_EQUAL_RETURN(guid, MF_MT_AAC_PAYLOAD_TYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION);
+ IF_EQUAL_RETURN(guid, MF_MT_FRAME_SIZE);
+ IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE);
+ IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MAX);
+ IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MIN);
+ IF_EQUAL_RETURN(guid, MF_MT_PIXEL_ASPECT_RATIO);
+ IF_EQUAL_RETURN(guid, MF_MT_DRM_FLAGS);
+ IF_EQUAL_RETURN(guid, MF_MT_PAD_CONTROL_FLAGS);
+ IF_EQUAL_RETURN(guid, MF_MT_SOURCE_CONTENT_HINT);
+ IF_EQUAL_RETURN(guid, MF_MT_VIDEO_CHROMA_SITING);
+ IF_EQUAL_RETURN(guid, MF_MT_INTERLACE_MODE);
+ IF_EQUAL_RETURN(guid, MF_MT_TRANSFER_FUNCTION);
+ IF_EQUAL_RETURN(guid, MF_MT_VIDEO_PRIMARIES);
+ IF_EQUAL_RETURN(guid, MF_MT_CUSTOM_VIDEO_PRIMARIES);
+ IF_EQUAL_RETURN(guid, MF_MT_YUV_MATRIX);
+ IF_EQUAL_RETURN(guid, MF_MT_VIDEO_LIGHTING);
+ IF_EQUAL_RETURN(guid, MF_MT_VIDEO_NOMINAL_RANGE);
+ IF_EQUAL_RETURN(guid, MF_MT_GEOMETRIC_APERTURE);
+ IF_EQUAL_RETURN(guid, MF_MT_MINIMUM_DISPLAY_APERTURE);
+ IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_APERTURE);
+ IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_ENABLED);
+ IF_EQUAL_RETURN(guid, MF_MT_AVG_BITRATE);
+ IF_EQUAL_RETURN(guid, MF_MT_AVG_BIT_ERROR_RATE);
+ IF_EQUAL_RETURN(guid, MF_MT_MAX_KEYFRAME_SPACING);
+ IF_EQUAL_RETURN(guid, MF_MT_DEFAULT_STRIDE);
+ IF_EQUAL_RETURN(guid, MF_MT_PALETTE);
+ IF_EQUAL_RETURN(guid, MF_MT_USER_DATA);
+ IF_EQUAL_RETURN(guid, MF_MT_AM_FORMAT_TYPE);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG_START_TIME_CODE);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG2_PROFILE);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG2_LEVEL);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG2_FLAGS);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG_SEQUENCE_HEADER);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_0);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_0);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_1);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_1);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_SRC_PACK);
+ IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_CTRL_PACK);
+ IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_HEADER);
+ IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_FORMAT);
+ IF_EQUAL_RETURN(guid, MF_MT_IMAGE_LOSS_TOLERANT);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG4_SAMPLE_DESCRIPTION);
+ IF_EQUAL_RETURN(guid, MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY);
+ IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_4CC);
+ IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_WAVE_FORMAT_TAG);
+
+ // Media types
+
+ IF_EQUAL_RETURN(guid, MFMediaType_Audio);
+ IF_EQUAL_RETURN(guid, MFMediaType_Video);
+ IF_EQUAL_RETURN(guid, MFMediaType_Protected);
+ IF_EQUAL_RETURN(guid, MFMediaType_SAMI);
+ IF_EQUAL_RETURN(guid, MFMediaType_Script);
+ IF_EQUAL_RETURN(guid, MFMediaType_Image);
+ IF_EQUAL_RETURN(guid, MFMediaType_HTML);
+ IF_EQUAL_RETURN(guid, MFMediaType_Binary);
+ IF_EQUAL_RETURN(guid, MFMediaType_FileTransfer);
+
+ IF_EQUAL_RETURN(guid, MFVideoFormat_AI44); // FCC('AI44')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_ARGB32); // D3DFMT_A8R8G8B8
+ IF_EQUAL_RETURN(guid, MFVideoFormat_AYUV); // FCC('AYUV')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_DV25); // FCC('dv25')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_DV50); // FCC('dv50')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_DVH1); // FCC('dvh1')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_DVSD); // FCC('dvsd')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_DVSL); // FCC('dvsl')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_H264); // FCC('H264')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_I420); // FCC('I420')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_IYUV); // FCC('IYUV')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_M4S2); // FCC('M4S2')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MJPG);
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MP43); // FCC('MP43')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MP4S); // FCC('MP4S')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MP4V); // FCC('MP4V')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MPG1); // FCC('MPG1')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MSS1); // FCC('MSS1')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_MSS2); // FCC('MSS2')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_NV11); // FCC('NV11')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_NV12); // FCC('NV12')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_P010); // FCC('P010')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_P016); // FCC('P016')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_P210); // FCC('P210')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_P216); // FCC('P216')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_RGB24); // D3DFMT_R8G8B8
+ IF_EQUAL_RETURN(guid, MFVideoFormat_RGB32); // D3DFMT_X8R8G8B8
+ IF_EQUAL_RETURN(guid, MFVideoFormat_RGB555); // D3DFMT_X1R5G5B5
+ IF_EQUAL_RETURN(guid, MFVideoFormat_RGB565); // D3DFMT_R5G6B5
+ IF_EQUAL_RETURN(guid, MFVideoFormat_RGB8);
+ IF_EQUAL_RETURN(guid, MFVideoFormat_UYVY); // FCC('UYVY')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_v210); // FCC('v210')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_v410); // FCC('v410')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_WMV1); // FCC('WMV1')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_WMV2); // FCC('WMV2')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_WMV3); // FCC('WMV3')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_WVC1); // FCC('WVC1')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y210); // FCC('Y210')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y216); // FCC('Y216')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y410); // FCC('Y410')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y416); // FCC('Y416')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y41P);
+ IF_EQUAL_RETURN(guid, MFVideoFormat_Y41T);
+ IF_EQUAL_RETURN(guid, MFVideoFormat_YUY2); // FCC('YUY2')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_YV12); // FCC('YV12')
+ IF_EQUAL_RETURN(guid, MFVideoFormat_YVYU);
+
+ IF_EQUAL_RETURN(guid, MFAudioFormat_PCM); // WAVE_FORMAT_PCM
+ IF_EQUAL_RETURN(guid, MFAudioFormat_Float); // WAVE_FORMAT_IEEE_FLOAT
+ IF_EQUAL_RETURN(guid, MFAudioFormat_DTS); // WAVE_FORMAT_DTS
+ IF_EQUAL_RETURN(guid, MFAudioFormat_Dolby_AC3_SPDIF); // WAVE_FORMAT_DOLBY_AC3_SPDIF
+ IF_EQUAL_RETURN(guid, MFAudioFormat_DRM); // WAVE_FORMAT_DRM
+ IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV8); // WAVE_FORMAT_WMAUDIO2
+ IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV9); // WAVE_FORMAT_WMAUDIO3
+ IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudio_Lossless); // WAVE_FORMAT_WMAUDIO_LOSSLESS
+ IF_EQUAL_RETURN(guid, MFAudioFormat_WMASPDIF); // WAVE_FORMAT_WMASPDIF
+ IF_EQUAL_RETURN(guid, MFAudioFormat_MSP1); // WAVE_FORMAT_WMAVOICE9
+ IF_EQUAL_RETURN(guid, MFAudioFormat_MP3); // WAVE_FORMAT_MPEGLAYER3
+ IF_EQUAL_RETURN(guid, MFAudioFormat_MPEG); // WAVE_FORMAT_MPEG
+ IF_EQUAL_RETURN(guid, MFAudioFormat_AAC); // WAVE_FORMAT_MPEG_HEAAC
+ IF_EQUAL_RETURN(guid, MFAudioFormat_ADTS); // WAVE_FORMAT_MPEG_ADTS_AAC
+
+ return NULL;
+}
+
+
+LPSTR DumpAttribute( _In_ const MF_ATTRIBUTE_TYPE& type,
+ _In_ REFPROPVARIANT var)
+{
+ CHAR *tempStr = NULL;
+ tempStr = new (std::nothrow) CHAR[256];
+ switch (type)
+ {
+ case MF_ATTRIBUTE_UINT32:
+ if (var.vt == VT_UI4)
+ {
+ sprintf_s(tempStr, 256, "%u", var.ulVal);
+ }
+ break;
+ case MF_ATTRIBUTE_UINT64:
+ if (var.vt == VT_UI8)
+ {
+ sprintf_s(tempStr, 256, "%I64d (high: %d low: %d)", var.uhVal.QuadPart, var.uhVal.HighPart, var.uhVal.LowPart);
+ }
+ break;
+ case MF_ATTRIBUTE_DOUBLE:
+ if (var.vt == VT_R8)
+ {
+ sprintf_s(tempStr, 256, "%.4f", var.dblVal);
+ }
+ break;
+ case MF_ATTRIBUTE_GUID:
+ if (var.vt == VT_CLSID)
+ {
+ return DumpGUIDA(*var.puuid);
+ }
+ break;
+ case MF_ATTRIBUTE_STRING:
+ if (var.vt == VT_LPWSTR)
+ {
+ sprintf_s(tempStr, 256, "%S", var.pwszVal);
+ }
+ break;
+ case MF_ATTRIBUTE_IUNKNOWN:
+ break;
+ default:
+ printf("(Unknown Attribute Type = %d) ", type);
+ break;
+ }
+ return tempStr;
+}
+
+CMediaTypePrinter::CMediaTypePrinter(
+ _In_ IMFMediaType *_pMediaType )
+ : pMediaType(_pMediaType),
+ m_pBuffer(NULL)
+{
+}
+
+CMediaTypePrinter::~CMediaTypePrinter()
+{
+ if (m_pBuffer)
+ {
+ delete(m_pBuffer);
+ }
+}
+
+/*++
+Description:
+Rudimentary function to print the complete Media type
+--*/
+PCHAR CMediaTypePrinter::ToCompleteString( )
+{
+ HRESULT hr = S_OK;
+ UINT32 attrCount = 0;
+ GUID attrGuid = { 0 };
+ char *tempStore = nullptr;
+ PROPVARIANT var;
+ LPSTR pTempBaseStr;
+ MF_ATTRIBUTE_TYPE pType;
+
+ if ( pMediaType && !m_pBuffer )
+ {
+ DMFTCHECKHR_GOTO(pMediaType->GetCount(&attrCount), done);
+ buffLen = MEDIAPRINTER_STARTLEN;
+ m_pBuffer = new char[buffLen];
+ DMFTCHECKNULL_GOTO(m_pBuffer, done, E_OUTOFMEMORY);
+ m_pBuffer[0] = 0;
+ for ( UINT32 ulIndex = 0; ulIndex < attrCount; ulIndex++ )
+ {
+ PropVariantInit( &var );
+ checkAdjustBufferCap( m_pBuffer, buffLen );
+ DMFTCHECKHR_GOTO( pMediaType->GetItemByIndex( ulIndex, &attrGuid, &var ), done );
+ DMFTCHECKHR_GOTO( pMediaType->GetItemType( attrGuid, &pType ), done );
+ if ( ulIndex > 0 )
+ strcat_s(m_pBuffer, MEDIAPRINTER_STARTLEN, " : ");
+ strcat_s( m_pBuffer, buffLen, GetGUIDNameConst( attrGuid ) );
+ strcat_s( m_pBuffer, buffLen, "=" );
+ pTempBaseStr = DumpAttribute( pType, var );
+ strcat_s( m_pBuffer, buffLen, pTempBaseStr );
+ delete( pTempBaseStr );
+ PropVariantClear( &var );
+ }
+ done:
+ if ( tempStore )
+ {
+ delete( tempStore );
+ }
+ }
+ return m_pBuffer;
+}
+
+/*++
+Description:
+Rudimentary function to print the Media type
+--*/
+
+PCHAR CMediaTypePrinter::ToString()
+{
+ //
+ //Following are the important ones of Mediatype attributes
+ //
+
+ HRESULT hr = S_OK;
+ PROPVARIANT var;
+ LPSTR pTempBaseStr;
+ MF_ATTRIBUTE_TYPE pType;
+ GUID attrGuid;
+ GUID impGuids[] = {
+ MF_MT_SUBTYPE,
+ MF_MT_FRAME_SIZE,
+ MF_MT_SAMPLE_SIZE,
+ MF_MT_FRAME_RATE,
+ MF_MT_DEFAULT_STRIDE,
+ MF_XVP_DISABLE_FRC
+ };
+
+ if (pMediaType && !m_pBuffer)
+ {
+ buffLen = MEDIAPRINTER_STARTLEN;
+ m_pBuffer = new (std::nothrow) char[buffLen];
+ DMFTCHECKNULL_GOTO(m_pBuffer, done, E_OUTOFMEMORY);
+ m_pBuffer[0] = 0;
+ for (UINT32 ulIndex = 0; ulIndex < ARRAYSIZE(impGuids); ulIndex++)
+ {
+ PropVariantInit(&var);
+ checkAdjustBufferCap(m_pBuffer, buffLen);
+ attrGuid = impGuids[ulIndex];
+ DMFTCHECKHR_GOTO(pMediaType->GetItemType(attrGuid, &pType), done);
+ DMFTCHECKHR_GOTO(pMediaType->GetItem(attrGuid, &var), done);
+ if (ulIndex > 0)
+ strcat_s(m_pBuffer, MEDIAPRINTER_STARTLEN, " : ");
+ strcat_s(m_pBuffer, buffLen, GetGUIDNameConst(attrGuid));
+ strcat_s(m_pBuffer, buffLen, "=");
+ pTempBaseStr = DumpAttribute(pType, var);
+ strcat_s(m_pBuffer, buffLen, pTempBaseStr);
+ delete(pTempBaseStr);
+ PropVariantClear(&var);
+ }
+ }
+done:
+ return m_pBuffer;
+}
+/*++
+Description:
+ Debug message printer to print the message passed through WPP
+--*/
+void printMessageEvent(MFT_MESSAGE_TYPE msg)
+{
+ switch (msg)
+ {
+ case MFT_MESSAGE_COMMAND_FLUSH:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_COMMAND_FLUSH");
+ break;
+ case MFT_MESSAGE_COMMAND_DRAIN:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_COMMAND_DRAIN");
+ break;
+ case MFT_MESSAGE_COMMAND_MARKER:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_COMMAND_MARKER");
+ break;
+ case MFT_MESSAGE_COMMAND_TICK:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_COMMAND_TICK");
+ break;
+ case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_NOTIFY_END_OF_STREAM");
+ break;
+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_NOTIFY_BEGIN_STREAMING");
+ break;
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_NOTIFY_START_OF_STREAM");
+ break;
+ case MFT_MESSAGE_DROP_SAMPLES:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_DROP_SAMPLES");
+ break;
+ case MFT_MESSAGE_SET_D3D_MANAGER:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! :PROCESSMESSAGE: MFT_MESSAGE_SET_D3D_MANAGER");
+ break;
+
+ }
+}
+
+HRESULT GetDXGIAdapterLuid(_In_ IMFDXGIDeviceManager *pDXManager, _Out_ LUID &AdapterLuid)
+{
+ HRESULT hr = S_OK;
+ ComPtr<ID3D11Device> spDevice;
+ ComPtr<IDXGIDevice> spDXGIDevice;
+ ComPtr<IDXGIAdapter> spDXGIAdapter;
+ DXGI_ADAPTER_DESC adapterDesc = { 0 };
+ HANDLE hDevice = NULL;
+
+ DMFTCHECKNULL_GOTO(pDXManager, done, E_INVALIDARG);
+
+ DMFTCHECKHR_GOTO(pDXManager->OpenDeviceHandle(&hDevice), done);
+ DMFTCHECKHR_GOTO(pDXManager->GetVideoService(hDevice, IID_PPV_ARGS(&spDevice)), done);
+ DMFTCHECKHR_GOTO(spDevice->QueryInterface(IID_PPV_ARGS(&spDXGIDevice)), done);
+ DMFTCHECKHR_GOTO(spDXGIDevice->GetAdapter(&spDXGIAdapter), done);
+ DMFTCHECKHR_GOTO(spDXGIAdapter->GetDesc(&adapterDesc), done);
+
+ CopyMemory(&AdapterLuid, &adapterDesc.AdapterLuid, sizeof(LUID));
+
+done:
+ if (NULL != hDevice)
+ {
+ pDXManager->CloseDeviceHandle(hDevice);
+ }
+
+ return hr;
+}
+
+HRESULT EnumSWDecoder(_Outptr_ IMFTransform** ppTransform, _In_ GUID subType)
+{
+ HRESULT hr = S_OK;
+ IMFActivate** ppActivate = nullptr;
+ UINT32 count = 0;
+ ComPtr<IMFTransform> spTransform;
+ LPWSTR pszFriendlyName = nullptr;
+
+ MFT_REGISTER_TYPE_INFO info = { MFMediaType_Video, subType };
+ UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT |
+ MFT_ENUM_FLAG_LOCALMFT |
+ MFT_ENUM_FLAG_SORTANDFILTER;
+
+ DMFTCHECKNULL_GOTO(ppTransform, done, E_INVALIDARG);
+ *ppTransform = nullptr;
+
+ DMFTCHECKHR_GOTO(MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER, unFlags,
+ &info, // Input type
+ NULL, // Output type
+ &ppActivate,
+ &count
+ ), done);
+
+
+ if (count == 0)
+ {
+ DMFTCHECKHR_GOTO(MF_E_TOPO_CODEC_NOT_FOUND, done);
+ }
+
+ if (SUCCEEDED(MFGetAttributeString(ppActivate[0], MFT_FRIENDLY_NAME_Attribute, &pszFriendlyName)))
+ {
+ //
+ // Log the friendly name of the decoder
+ //
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! decoder name: %S ", (pszFriendlyName ? pszFriendlyName : L"UnknownCodec"));
+ SAFE_COTASKMEMFREE(pszFriendlyName);
+ }
+
+ DMFTCHECKHR_GOTO(ppActivate[0]->ActivateObject(IID_PPV_ARGS(spTransform.GetAddressOf())), done);
+
+ *ppTransform = spTransform.Detach();
+
+done:
+ if (ppActivate)
+ {
+ for (UINT32 uiIndex = 0; uiIndex < count; uiIndex++)
+ {
+ ppActivate[uiIndex]->Release();
+ }
+ CoTaskMemFree(ppActivate);
+ }
+ return hr;
+}
+//
+// @@@@ README Create the decoder
+//
+HRESULT CreateDecoderFromLuid( _In_ LUID ullAdapterLuidRunningOn,
+ _In_ IMFMediaType* pInputType,
+ _In_ IMFMediaType* pOutputType,
+ _Inout_ BOOL fHwMft,
+ _Outptr_ IMFTransform** ppDecoder)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFAttributes> spAttribs;
+ ComPtr<IMFTransform> spMJPGDecoder;
+ IMFActivate **ppActivates = nullptr;
+ DWORD dwFlags = MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_HARDWARE | 0x10000000 /*Internal attribute*/;
+ UINT32 cMFTActivate = 0;
+ MFT_REGISTER_TYPE_INFO InputType;
+ MFT_REGISTER_TYPE_INFO OutputType;
+ GUID compressedGUID;
+ ComPtr<ID3D11Device> spD3D11Device;
+
+ fHwMft = FALSE;
+
+
+ DMFTCHECKNULL_GOTO(pInputType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pOutputType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(ppDecoder, done, E_INVALIDARG);
+ *ppDecoder = nullptr;
+ DMFTCHECKHR_GOTO(pInputType->GetGUID(MF_MT_SUBTYPE, &compressedGUID), done);
+
+ InputType.guidMajorType = MFMediaType_Video;
+ InputType.guidSubtype = compressedGUID;
+
+ DMFTCHECKHR_GOTO(pOutputType->GetMajorType(&OutputType.guidMajorType), done);
+ DMFTCHECKHR_GOTO(pOutputType->GetGUID(MF_MT_SUBTYPE, &OutputType.guidSubtype), done);
+
+ DMFTCHECKHR_GOTO(MFCreateAttributes(&spAttribs, 1), done);
+ DMFTCHECKHR_GOTO(spAttribs->SetBlob(MFT_ENUM_ADAPTER_LUID, (byte*)&ullAdapterLuidRunningOn, sizeof(ullAdapterLuidRunningOn)), done);
+ DMFTCHECKHR_GOTO(MFTEnum2(MFT_CATEGORY_VIDEO_DECODER, dwFlags, &InputType, &OutputType, spAttribs.Get(), &ppActivates, &cMFTActivate), done);
+
+ for (DWORD i = 0; i < cMFTActivate; i++)
+ {
+ HRESULT hrTemp = ppActivates[i]->ActivateObject(IID_PPV_ARGS(spMJPGDecoder.GetAddressOf()));
+ fHwMft = (MFT_ENUM_FLAG_HARDWARE & MFGetAttributeUINT32(ppActivates[i], MF_TRANSFORM_FLAGS_Attribute, 0));
+ // Pickup the first MFT enumerated. Normally, it should be a HW MFT, if HWMFT is available.
+ if (SUCCEEDED(hrTemp))
+ {
+ break;
+ }
+ else
+ {
+ spMJPGDecoder = nullptr;
+ }
+ }
+ if (spMJPGDecoder == nullptr)
+ {
+ hr = MF_E_NOT_FOUND;
+ }
+ *ppDecoder = spMJPGDecoder.Detach();
+done:
+
+ for (UINT32 i = 0; i < cMFTActivate; i++)
+ {
+ if (nullptr != ppActivates[i])
+ {
+ ppActivates[i]->Release();
+ }
+ }
+ SAFE_COTASKMEMFREE(ppActivates);
+ return hr;
+}
+
+HRESULT SetDX11BindFlags( _In_ IUnknown *pUnkManager,
+ _In_ GUID guidPinCategory,
+ _Inout_ DWORD &dwBindFlags)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IUnknown> spDeviceManager;
+ BOOL fFL10 = FALSE;
+
+ auto
+ IsFeatureLevel10OrBetter = [&]() -> BOOL
+ {
+ ComPtr<IMFDXGIDeviceManager> spDXGIManager;
+ ComPtr<ID3D11Device> spDevice;
+ HANDLE hDevice = 0;
+ BOOL fRet = FALSE;
+ UINT level = 0, result = 0;
+
+ if (SUCCEEDED(pUnkManager->QueryInterface(IID_PPV_ARGS(&spDXGIManager))) &&
+ SUCCEEDED(spDXGIManager->OpenDeviceHandle(&hDevice)) &&
+ SUCCEEDED(spDXGIManager->LockDevice(hDevice, IID_PPV_ARGS(&spDevice), FALSE)))
+ {
+
+ level = (UINT)spDevice->GetFeatureLevel();
+ fRet = (level >= D3D_FEATURE_LEVEL_10_0);
+ if (!fRet)
+ {
+ if (SUCCEEDED(spDevice->CheckFormatSupport(DXGI_FORMAT_NV12, &result)))
+ {
+ fRet = (result & D3D11_FORMAT_SUPPORT_TEXTURE2D) && (result & D3D11_FORMAT_SUPPORT_RENDER_TARGET);
+ }
+ }
+ (void)spDXGIManager->UnlockDevice(hDevice, FALSE);
+ (void)spDXGIManager->CloseDeviceHandle(hDevice);
+ }
+ return fRet;
+ };
+
+ DMFTCHECKNULL_GOTO(pUnkManager, done, E_INVALIDARG);
+ fFL10 = IsFeatureLevel10OrBetter();
+
+ dwBindFlags |= fFL10 ? D3D11_BIND_SHADER_RESOURCE : 0;
+ dwBindFlags |= (guidPinCategory != PINNAME_VIDEO_PREVIEW) ? D3D11_BIND_VIDEO_ENCODER : 0;
+ if ((dwBindFlags != 0) && ((dwBindFlags & ~(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_VIDEO_ENCODER)) == 0))
+ {
+ dwBindFlags |= D3D11_BIND_RENDER_TARGET;
+ }
+done:
+ return hr;
+}
+
+// @@@@ README: Create the Decoder
+HRESULT CreateDecoderHW(_In_ IMFDXGIDeviceManager* pManager,
+ _In_ IMFMediaType* inType,
+ _In_ IMFMediaType* outType,
+ _Outptr_ IMFTransform** ppTransform,
+ _Inout_ BOOL& fHwMft)
+{
+ HRESULT hr = S_OK;
+ LUID luid;
+ ComPtr<IMFTransform> spTransform;
+ DMFTCHECKNULL_GOTO(ppTransform, done, E_INVALIDARG);
+ *ppTransform = nullptr;
+
+ if (pManager)
+ {
+ if (SUCCEEDED(hr = GetDXGIAdapterLuid(pManager, luid)))
+ {
+ hr = CreateDecoderFromLuid(luid, inType, outType, fHwMft, spTransform.GetAddressOf());
+ if (FAILED(hr))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Error creating HW Decoder with LUID %d-%d", luid.HighPart, luid.LowPart);
+ DMFTCHECKHR_GOTO(hr, done);
+ }
+ }
+ }
+ *ppTransform = spTransform.Detach();
+done:
+ return hr;
+}
+
+HRESULT
+SubtypeToDXGIFormat(
+ _In_ GUID subType,
+ _Inout_ DXGI_FORMAT &format
+)
+{
+ HRESULT hr = S_OK;
+ typedef struct {
+ GUID subType;
+ DXGI_FORMAT format;
+ }DXGIFormatMap;
+ DXGIFormatMap formatMap[]
+ {
+ { MFVideoFormat_NV12, DXGI_FORMAT_NV12 },
+ { MFVideoFormat_YUY2, DXGI_FORMAT_YUY2 },
+ { MFVideoFormat_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM },
+ { MFVideoFormat_ARGB32, DXGI_FORMAT_B8G8R8A8_UNORM },
+ { MFVideoFormat_AYUV, DXGI_FORMAT_AYUV },
+ { MFVideoFormat_NV11, DXGI_FORMAT_NV11 },
+ { MFVideoFormat_AI44, DXGI_FORMAT_AI44 },
+ { MFVideoFormat_P010, DXGI_FORMAT_P010 },
+ { MFVideoFormat_P016, DXGI_FORMAT_P016 },
+ { MFVideoFormat_Y210, DXGI_FORMAT_Y210 },
+ { MFVideoFormat_Y216, DXGI_FORMAT_Y216 },
+ { MFVideoFormat_Y410, DXGI_FORMAT_Y410 },
+ { MFVideoFormat_Y416, DXGI_FORMAT_Y416 },
+ };
+ format = DXGI_FORMAT_UNKNOWN;
+ for (UINT32 uiIndex = 0; uiIndex < _countof(formatMap); uiIndex++)
+ {
+ if (formatMap[uiIndex].subType == subType)
+ {
+ format = formatMap[uiIndex].format;
+ break;
+ }
+ }
+ // compressed media type or unsupported of the range
+ hr = (format == DXGI_FORMAT_UNKNOWN) ? E_NOTIMPL : S_OK;
+ return hr;
+}
+
+HRESULT IsDXFormatSupported(
+ _In_ IMFDXGIDeviceManager* pDeviceManager ,
+ _In_ GUID subType,
+ _Outptr_opt_ ID3D11Device** ppDevice,
+ _In_opt_ PUINT32 pSupportedFormat)
+{
+ HRESULT hr = S_OK;
+ DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
+ UINT32 supportedFormat = 0;
+ HANDLE hDevice = NULL;
+ ComPtr<ID3D11Device> spDevice;
+ DMFTCHECKNULL_GOTO(pDeviceManager, done, E_INVALIDARG);
+ DMFTCHECKHR_GOTO(pDeviceManager->OpenDeviceHandle(&hDevice), done);
+ DMFTCHECKHR_GOTO(pDeviceManager->GetVideoService(hDevice, IID_PPV_ARGS(&spDevice)), done);
+ DMFTCHECKHR_GOTO(SubtypeToDXGIFormat(subType, format), done);
+ DMFTCHECKHR_GOTO(spDevice->CheckFormatSupport(format, &supportedFormat), done);
+ if (pSupportedFormat)
+ {
+ *pSupportedFormat = supportedFormat;
+ }
+ if (ppDevice)
+ {
+ *ppDevice = spDevice.Detach();
+ }
+done:
+ if (hDevice != NULL)
+ {
+ pDeviceManager->CloseDeviceHandle(hDevice);
+ }
+ return hr;
+}
+
+HRESULT
+UpdateAllocatorAttributes(
+ _In_ IMFAttributes *pAttributes,
+ _In_ REFGUID guidStreamCategory,
+ _In_ GUID subType,
+ _In_ IMFDXGIDeviceManager *pDeviceManager
+)
+{
+ HRESULT hr = S_OK;
+ UINT32 supportedFormat = 0;
+ ComPtr<ID3D11Device> spDevice;
+ DWORD dwBindFlags = 0;
+
+ DMFTCHECKHR_GOTO(IsDXFormatSupported(pDeviceManager,subType,
+ spDevice.GetAddressOf(),&supportedFormat),done);
+
+ // MF_SA_D3D11_USAGE should be D3D11_USAGE_DEFAULT, same as previous release.
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT), done);
+
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE), done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_SA_D3D11_SHARED_WITH_NTHANDLE_PRIVATE, TRUE), done);
+
+ // Bind Flags
+ dwBindFlags |= ((supportedFormat & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0 ? D3D11_BIND_RENDER_TARGET : 0);
+
+ if (((supportedFormat & D3D11_FORMAT_SUPPORT_VIDEO_ENCODER) != 0) &&
+ (!IsEqualGUID(guidStreamCategory, PINNAME_VIDEO_PREVIEW)) &&
+ IsEqualGUID(subType, MFVideoFormat_NV12))
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS4 Options = { 0 };
+
+ // "D3D11_BIND_VIDEO_ENCODER + sharing" is only supported on those devices that
+ // advertise ExtendedNV12SharedTextureSupported.
+ DMFTCHECKHR_GOTO(spDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS4, &Options, sizeof(Options)), done);
+ if (Options.ExtendedNV12SharedTextureSupported)
+ {
+ dwBindFlags |= D3D11_BIND_VIDEO_ENCODER;
+ }
+ }
+
+ // D3D requires one of the flags (D3D11_BIND_RENDER_TARGET, D3D11_PRIVATE_BIND_CAPTURE, or D3D11_BIND_VIDEO_ENCODER) to be set for non-zero bind flags.
+ if (dwBindFlags != 0)
+ {
+ D3D_FEATURE_LEVEL level;
+
+ // D3D11_BIND_SHADER_RESOURCE
+ level = spDevice->GetFeatureLevel();
+ dwBindFlags |= ((level >= D3D_FEATURE_LEVEL_10_0) ? D3D11_BIND_SHADER_RESOURCE : 0);
+ }
+
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_SA_D3D11_BINDFLAGS, dwBindFlags), done);
+
+done:
+ return hr;
+}
+
+const UINT32 ALLOCATOR_MIN_SAMPLES = 10;
+const UINT32 ALLOCATOR_MAX_SAMPLES = 50;
+
+HRESULT ConfigureAllocator(
+ _In_ IMFMediaType* pOutputMediaType,
+ _In_ GUID streamCategory,
+ _In_ IUnknown* pDeviceManagerUnk,
+ _In_ BOOL &bDxAllocator,
+ _In_ IMFVideoSampleAllocator* pAllocator)
+{
+ HRESULT hr = S_OK;
+ wil::com_ptr_nothrow<IMFVideoSampleAllocatorEx> spPrivateAllocator;
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+ wil::com_ptr_nothrow<IMFVideoCaptureSampleAllocator> spDefaultAllocator;
+#endif
+ wil::com_ptr_nothrow<IMFAttributes> spAllocatorAttributes;
+ GUID guidMajorType = GUID_NULL;
+ GUID guidSubtype = GUID_NULL;
+ BOOL fDXAllocator = FALSE;
+
+ RETURN_HR_IF_NULL(E_INVALIDARG, pAllocator );
+ RETURN_HR_IF_NULL(E_INVALIDARG, pOutputMediaType );
+
+ RETURN_IF_FAILED(pOutputMediaType->GetMajorType(&guidMajorType));
+
+ if (!IsEqualGUID(guidMajorType, MFMediaType_Video))
+ {
+ RETURN_HR(MF_E_INVALIDMEDIATYPE);
+ }
+
+ RETURN_IF_FAILED(pOutputMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubtype));
+ //
+ // Set Attributes on the allocator we need. First get the Bind Flags.
+ //
+ RETURN_IF_FAILED(MFCreateAttributes(&spAllocatorAttributes, 8));
+ RETURN_IF_FAILED(spAllocatorAttributes->SetUINT32(MF_SA_BUFFERS_PER_SAMPLE, 1));
+
+ if (pDeviceManagerUnk != nullptr)
+ {
+ if (SUCCEEDED(UpdateAllocatorAttributes(spAllocatorAttributes.get(), streamCategory, guidSubtype, (IMFDXGIDeviceManager*)pDeviceManagerUnk)))
+ {
+ fDXAllocator = TRUE;
+ }
+ }
+
+ if (fDXAllocator)
+ {
+ RETURN_IF_FAILED(pAllocator->SetDirectXManager(pDeviceManagerUnk));
+ }
+
+ if (SUCCEEDED(pAllocator->QueryInterface(IID_PPV_ARGS(&spPrivateAllocator))))
+ {
+ RETURN_IF_FAILED(spPrivateAllocator->InitializeSampleAllocatorEx(
+ ALLOCATOR_MIN_SAMPLES,
+ ALLOCATOR_MAX_SAMPLES,
+ spAllocatorAttributes.get(),
+ pOutputMediaType));
+ }
+#if ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB))
+ else if (SUCCEEDED(pAllocator->QueryInterface(IID_PPV_ARGS(&spDefaultAllocator))))
+ {
+ RETURN_IF_FAILED(spDefaultAllocator->InitializeCaptureSampleAllocator(
+ 0, /*use sample size by MediaType*/
+ 0, /*metadata size*/
+ 0, /*default alignment*/
+ ALLOCATOR_MIN_SAMPLES,
+ spAllocatorAttributes.get(),
+ pOutputMediaType));
+ }
+#endif
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+
+ bDxAllocator = fDXAllocator;
+
+ return hr;
+}
+//
+//@@@@ README: Creating an Allocator.. Please don't allocate samples individually using MFCreateSample as that can lead to fragmentation and is
+// extremely inefficent. Instead create an Allocator which will create a fixed number of samples which are recycled when the pipeline returns back
+// the buffers. The above has defines will enable to create a circular allocator which will have maximum 20 samples flowing in the pipeline
+// This way we can also catch samples leaks if any.
+//
+HRESULT CreateAllocator( _In_ IMFMediaType* pOutputMediaType,
+ _In_ GUID streamCategory,
+ _In_ IUnknown* pDeviceManagerUnk,
+ _In_ BOOL &bDxAllocator,
+ _Outptr_ IMFVideoSampleAllocatorEx** ppAllocator )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFVideoSampleAllocatorEx> spVideoSampleAllocator;
+ ComPtr<IMFAttributes> spAllocatorAttributes;
+ GUID guidMajorType = GUID_NULL;
+ GUID guidSubtype = GUID_NULL;
+ BOOL fDXAllocator = FALSE;
+
+ DMFTCHECKNULL_GOTO(ppAllocator, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pOutputMediaType, done, E_INVALIDARG);
+ DMFTCHECKHR_GOTO(pOutputMediaType->GetMajorType(&guidMajorType), done);
+
+ *ppAllocator = nullptr;
+ if (!IsEqualGUID(guidMajorType, MFMediaType_Video))
+ {
+ DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
+ }
+
+ DMFTCHECKHR_GOTO(pOutputMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubtype), done);
+ //
+ // Set Attributes on the allocator we need. First get the Bind Flags.
+ //
+ DMFTCHECKHR_GOTO(MFCreateAttributes(&spAllocatorAttributes, 8), done);
+ DMFTCHECKHR_GOTO(spAllocatorAttributes->SetUINT32(MF_SA_BUFFERS_PER_SAMPLE, 1), done);
+
+ if (pDeviceManagerUnk != nullptr)
+ {
+ if (SUCCEEDED(UpdateAllocatorAttributes(spAllocatorAttributes.Get(), streamCategory,guidSubtype, (IMFDXGIDeviceManager*)pDeviceManagerUnk)))
+ {
+ fDXAllocator = TRUE;
+ }
+ }
+ DMFTCHECKHR_GOTO(MFCreateVideoSampleAllocatorEx(IID_PPV_ARGS(spVideoSampleAllocator.ReleaseAndGetAddressOf())), done);
+ if (fDXAllocator)
+ {
+ DMFTCHECKHR_GOTO(spVideoSampleAllocator->SetDirectXManager(pDeviceManagerUnk), done);
+ }
+
+ DMFTCHECKHR_GOTO(spVideoSampleAllocator->InitializeSampleAllocatorEx(ALLOCATOR_MIN_SAMPLES, ALLOCATOR_MAX_SAMPLES, spAllocatorAttributes.Get(), pOutputMediaType), done);
+
+ *ppAllocator = spVideoSampleAllocator.Detach();
+ bDxAllocator = fDXAllocator;
+done:
+ return hr;
+}
+
+HRESULT CheckPassthroughMediaType(_In_ IMFMediaType *pMediaType1,
+ _In_ IMFMediaType *pMediaType2,
+ _Out_ BOOL& pfPassThrough)
+{
+ HRESULT hr = S_OK;
+ BOOL fPassThrough = FALSE;
+ UINT32 uWidth, uHeight;
+ UINT32 uWidth2, uHeight2;
+
+ // Compare Width/Height.
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(pMediaType1, MF_MT_FRAME_SIZE, &uWidth, &uHeight), done);
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(pMediaType2, MF_MT_FRAME_SIZE, &uWidth2, &uHeight2), done);
+ if ((uWidth != uWidth2) || (uHeight != uHeight2))
+ {
+ goto done;
+ }
+
+ // Compare rotation
+ {
+ UINT32 uRotation;
+ UINT32 uRotation2;
+
+ uRotation = MFGetAttributeUINT32(pMediaType1, MF_MT_VIDEO_ROTATION, 0);
+ uRotation2 = MFGetAttributeUINT32(pMediaType2, MF_MT_VIDEO_ROTATION, 0);
+ if (uRotation != uRotation2)
+ {
+ goto done;
+ }
+ }
+
+ // Compare Aspect Ratio
+ {
+ UINT32 uNumerator = 1, uDenominator = 1;
+ UINT32 uNumerator2 = 1, uDenominator2 = 1;
+
+ (void)MFGetAttributeRatio(pMediaType1, MF_MT_FRAME_RATE, &uNumerator, &uDenominator);
+ (void)MFGetAttributeRatio(pMediaType2, MF_MT_FRAME_RATE, &uNumerator2, &uDenominator2);
+ if ((uNumerator * uDenominator2) != (uNumerator2 * uDenominator))
+ {
+ goto done;
+ }
+ }
+
+ // Compare Nominal Range
+ {
+ UINT32 uNorminalRange;
+ UINT32 uNorminalRange2;
+
+ uNorminalRange = MFGetAttributeUINT32(pMediaType1, MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_Unknown);
+ uNorminalRange2 = MFGetAttributeUINT32(pMediaType2, MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_Unknown);
+ if (uNorminalRange != uNorminalRange2)
+ {
+ goto done;
+ }
+ }
+
+ // Compare color primaries
+ {
+ UINT32 uPrimaries;
+ UINT32 uPrimaries2;
+
+ uPrimaries = MFGetAttributeUINT32(pMediaType1, MF_MT_VIDEO_PRIMARIES, MFVideoPrimaries_Unknown);
+ uPrimaries2 = MFGetAttributeUINT32(pMediaType2, MF_MT_VIDEO_PRIMARIES, MFVideoPrimaries_Unknown);
+ if (uPrimaries != uPrimaries2)
+ {
+ goto done;
+ }
+ }
+
+
+ // Compare InterlaceMode
+ {
+ UINT32 uInterlaceMode;
+ UINT32 uInterlaceMode2;
+
+ uInterlaceMode = MFGetAttributeUINT32(pMediaType1, MF_MT_INTERLACE_MODE, MFVideoInterlace_Unknown);
+ uInterlaceMode2 = MFGetAttributeUINT32(pMediaType2, MF_MT_INTERLACE_MODE, MFVideoInterlace_Unknown);
+ if (uInterlaceMode != uInterlaceMode2)
+ {
+ goto done;
+ }
+ }
+
+ // Compare display aperture
+ {
+ MFVideoArea VideoArea = { 0 };
+ MFVideoArea VideoArea2 = { 0 };
+ UINT32 cbBlobSize = 0;
+
+ if (SUCCEEDED(pMediaType1->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&VideoArea, sizeof(MFVideoArea), &cbBlobSize)))
+ {
+ if ((VideoArea.OffsetX.value == 0 && VideoArea.OffsetX.fract == 0) &&
+ (VideoArea.OffsetY.value == 0 && VideoArea.OffsetY.fract == 0) &&
+ (VideoArea.Area.cx == (LONG)uWidth) &&
+ (VideoArea.Area.cy == (LONG)uHeight))
+ {
+ // If the display aperture is the whole frame size, ignore it.
+ ZeroMemory(&VideoArea, sizeof(VideoArea));
+ }
+ }
+
+ if (SUCCEEDED(pMediaType2->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&VideoArea2, sizeof(MFVideoArea), &cbBlobSize)))
+ {
+ if ((VideoArea2.OffsetX.value == 0 && VideoArea2.OffsetX.fract == 0) &&
+ (VideoArea2.OffsetY.value == 0 && VideoArea2.OffsetY.fract == 0) &&
+ (VideoArea2.Area.cx == (LONG)uWidth) &&
+ (VideoArea2.Area.cy == (LONG)uHeight))
+ {
+ // If the display aperture is the whole frame size, ignore it.
+ ZeroMemory(&VideoArea, sizeof(VideoArea));
+ }
+ }
+
+ if (memcmp(&VideoArea, &VideoArea2, sizeof(MFVideoArea)) != 0)
+ {
+ goto done;
+ }
+ }
+
+ fPassThrough = TRUE;
+
+done:
+ pfPassThrough = fPassThrough;
+ return hr;
+}
+
+
+HRESULT MergeSampleAttributes( _In_ IMFSample* pInSample, _Inout_ IMFSample* pOutSample)
+{
+ HRESULT hr = S_OK;
+ UINT32 cAttributes = 0;
+ GUID guidAttribute;
+ PROPVARIANT varAttribute;
+ PROPVARIANT varAttributeExists;
+ PropVariantInit(&varAttribute);
+ PropVariantInit(&varAttributeExists);
+
+ DMFTCHECKNULL_GOTO(pInSample, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pOutSample, done, E_INVALIDARG);
+
+ DMFTCHECKHR_GOTO(pInSample->GetCount(&cAttributes), done);
+ for (UINT32 i = 0; i < cAttributes; i++)
+ {
+ PropVariantClear(&varAttribute);
+ PropVariantClear(&varAttributeExists);
+
+ DMFTCHECKHR_GOTO(pInSample->GetItemByIndex(i, &guidAttribute, &varAttribute), done);
+
+ if (S_OK == pOutSample->GetItem(guidAttribute, &varAttributeExists))
+ {
+ // Exists.. dont clobber
+ continue;
+ }
+
+ DMFTCHECKHR_GOTO(pOutSample->SetItem(guidAttribute, varAttribute), done);
+ }
+
+done:
+ PropVariantClear(&varAttribute);
+ PropVariantClear(&varAttributeExists);
+ return hr;
+}
diff --git a/avstream/sampledevicemft/multipinmft.vcxproj b/avstream/sampledevicemft/multipinmft.vcxproj
index f13ed67d..3b9ddf87 100644
--- a/avstream/sampledevicemft/multipinmft.vcxproj
+++ b/avstream/sampledevicemft/multipinmft.vcxproj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -23,38 +23,38 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{D6CB33D6-DEF2-497E-A72D-6E6E29C67F48}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -66,13 +66,13 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ItemGroup Label="WrappedTaskItems">
@@ -163,17 +163,17 @@
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
@@ -189,11 +189,11 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ResourceCompile>
<Link>
- <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <AdditionalDependencies>onecore.lib;D2d1.lib;mfcore.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ClCompile>
@@ -204,11 +204,11 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ResourceCompile>
<Link>
- <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <AdditionalDependencies>onecore.lib;D2d1.lib;mfcore.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ClCompile>
@@ -219,11 +219,11 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ResourceCompile>
<Link>
- <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <AdditionalDependencies>onecore.lib;D2d1.lib;mfcore.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ClCompile>
@@ -234,7 +234,7 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
</ResourceCompile>
<Link>
- <AdditionalDependencies>%(AdditionalDependencies);D2d1.lib;mf.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
+ <AdditionalDependencies>onecore.lib;D2d1.lib;mfcore.lib;mfplat.lib;mfuuid.lib;uuid.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
diff --git a/avstream/samplemft0/Package/package.vcxproj b/avstream/samplemft0/Package/package.vcxproj
index c898c343..997cd1d1 100644
--- a/avstream/samplemft0/Package/package.vcxproj
+++ b/avstream/samplemft0/Package/package.vcxproj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -32,15 +32,11 @@
<SampleGuid>{A92ABE31-4404-4415-B763-7186FA03850E}</SampleGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
@@ -48,6 +44,10 @@
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -78,7 +78,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<!--Inf Include="DriverInf.inv" /-->
- <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ <FilesToPackage Include="@(Inf-&gt;'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SampleMft0.vcxproj">
diff --git a/avstream/samplemft0/SampleMft0.sln b/avstream/samplemft0/SampleMft0.sln
index 8084fbc7..c2df6702 100644
--- a/avstream/samplemft0/SampleMft0.sln
+++ b/avstream/samplemft0/SampleMft0.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 11
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{D5FD28DE-8407-4B27-8785-9839775E254A}"
@@ -9,26 +9,26 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleMft0", "SampleMft0.vc
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
+ Debug|ARM64 = Debug|ARM64
+ Release|ARM64 = Release|ARM64
Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|Win32.ActiveCfg = Debug|Win32
- {07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|Win32.Build.0 = Debug|Win32
+ {07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|ARM64.Build.0 = Debug|ARM64
+ {07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|ARM64.Build.0 = Release|ARM64
+ {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|ARM64.Build.0 = Release|ARM64
{07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|x64.ActiveCfg = Debug|x64
{07664D04-E5E5-4249-8382-4D97E3E5557D}.Debug|x64.Build.0 = Debug|x64
- {07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|Win32.ActiveCfg = Release|Win32
- {07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|Win32.Build.0 = Release|Win32
{07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|x64.ActiveCfg = Release|x64
{07664D04-E5E5-4249-8382-4D97E3E5557D}.Release|x64.Build.0 = Release|x64
- {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|Win32.ActiveCfg = Debug|Win32
- {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|Win32.Build.0 = Debug|Win32
{DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|x64.ActiveCfg = Debug|x64
{DCF923F6-7164-4A0E-9486-B8A140234CCA}.Debug|x64.Build.0 = Debug|x64
- {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|Win32.ActiveCfg = Release|Win32
- {DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|Win32.Build.0 = Release|Win32
{DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|x64.ActiveCfg = Release|x64
{DCF923F6-7164-4A0E-9486-B8A140234CCA}.Release|x64.Build.0 = Release|x64
EndGlobalSection
diff --git a/avstream/samplemft0/SampleMft0.vcxproj b/avstream/samplemft0/SampleMft0.vcxproj
index c7a28b8e..357bc0be 100644
--- a/avstream/samplemft0/SampleMft0.vcxproj
+++ b/avstream/samplemft0/SampleMft0.vcxproj
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
+ <ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
+ <ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
- <Platform>Win32</Platform>
+ <Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
@@ -25,7 +25,7 @@
</PropertyGroup>
<PropertyGroup Label="Globals">
<Configuration>Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsKernelModeDriver8.0'">DbgengKernelDebugger</DebuggerFlavor>
<DebuggerFlavor Condition="'$(PlatformToolset)' == 'WindowsUserModeDriver8.0'">DbgengRemoteDebugger</DebuggerFlavor>
<SampleGuid>{0D23004B-9844-4510-ABA0-E60F720528B8}</SampleGuid>
@@ -35,15 +35,11 @@
<ProjectGuid>{DCF923F6-7164-4A0E-9486-B8A140234CCA}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
</PropertyGroup>
@@ -51,6 +47,10 @@
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
</PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<OutDir>$(IntDir)</OutDir>
@@ -58,13 +58,13 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ItemGroup Label="WrappedTaskItems" />