summaryrefslogtreecommitdiff
path: root/AVStream/sampledevicemft/multipinmft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'AVStream/sampledevicemft/multipinmft.cpp')
-rw-r--r--AVStream/sampledevicemft/multipinmft.cpp2453
1 files changed, 0 insertions, 2453 deletions
diff --git a/AVStream/sampledevicemft/multipinmft.cpp b/AVStream/sampledevicemft/multipinmft.cpp
deleted file mode 100644
index ea7fd892..00000000
--- a/AVStream/sampledevicemft/multipinmft.cpp
+++ /dev/null
@@ -1,2453 +0,0 @@
-//*@@@+++@@@@******************************************************************
-//
-// 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;
-
-#if _NEED_MFTLOCKING_
-#define MFTLOCKED() {\
- UINT32 punValue = FALSE; \
- hr = GetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, &punValue);\
-if (FAILED(hr) || punValue == FALSE){\
- return MF_E_TRANSFORM_ASYNC_LOCKED; \
-}\
-}
-#else
-
-#define MFTLOCKED()
-
-#endif
-
-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_PhotoTriggerSent(false),
- m_filterHasIndependentPin( false ),
- m_FilterInPhotoSequence( false ),
- m_filterInWarmStart(false)
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- , m_spPhotoConfirmationCallback(nullptr)
-#endif
-{
- ComPtr<IMFAttributes> pAttributes = nullptr;
- MFCreateAttributes( &pAttributes, 0 );
- pAttributes->SetUINT32( MF_TRANSFORM_ASYNC, TRUE );
- pAttributes->SetUINT32( MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE );
- pAttributes->SetUINT32( MF_SA_D3D_AWARE, TRUE );
- pAttributes->SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"SampleMultiPinMft" );
- m_spAttributes = pAttributes;
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- m_guidPhotoConfirmationSubtype = MFVideoFormat_NV12;
-#endif
-}
-
-CMultipinMft::~CMultipinMft( )
-{
- CBasePin *pioPin = NULL;
-
- for ( ULONG ulIndex = 0, ulSize = (ULONG) m_InPins.size(); ulIndex < ulSize; ulIndex++ )
- {
- pioPin = m_InPins[ ulIndex ];
- SAFERELEASE( pioPin );
- }
- m_InPins.clear();
-
- for (ULONG ulIndex = 0, ulSize = (ULONG) m_OutPins.size(); ulIndex < ulSize; ulIndex++)
- {
- pioPin = m_OutPins[ ulIndex ];
- SAFERELEASE( pioPin );
- }
- m_OutPins.clear();
- 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);
- AddRef();
- }
- else
- if ( iid == __uuidof( IMFMediaEventGenerator ) )
- {
- *ppv = static_cast< IMFMediaEventGenerator* >(this);
- AddRef();
- }
- else
- if ( iid == __uuidof( IMFShutdown ) )
- {
- *ppv = static_cast< IMFShutdown* >( this );
- AddRef();
- }
-#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
- else
- if (iid == __uuidof(IMFTransform))
- {
- *ppv = static_cast< IMFTransform* >(this);
- AddRef();
- }
-#endif
- else
- if ( iid == __uuidof( IKsControl ) )
- {
- *ppv = static_cast< IKsControl* >( this );
- AddRef();
- }
- else
- if ( iid == __uuidof( IMFRealTimeClientEx ) )
- {
- *ppv = static_cast< IMFRealTimeClientEx* >( this );
- AddRef();
- }
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- else
- if (iid == __uuidof(IMFCapturePhotoConfirmation))
- {
- *ppv = static_cast< IMFCapturePhotoConfirmation* >(this);
- AddRef();
- }
- else
- if (iid == __uuidof(IMFGetService))
- {
- *ppv = static_cast< IMFGetService* >(this);
- AddRef();
- }
-#endif
- else
- {
- hr = E_NOINTERFACE;
- }
- 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
-
---*/
-
-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;
-
- 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 );
-
- 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 DWORD[ inputStreams ];
- DMFTCHECKNULL_GOTO( pcInputStreams, done, E_OUTOFMEMORY);
-
- pcOutputStreams = new 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;
-
- DMFTCHECKHR_GOTO( m_spSourceTransform->GetOutputStreamAttributes(pcOutputStreams[ulIndex], pInAttributes.GetAddressOf()), done);
-
- DMFTCHECKHR_GOTO( pInAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &streamCategory), done);
-
- if ( IsEqualCLSID( streamCategory, PINNAME_IMAGE ) )
- {
- //We have independent pins..
- m_filterHasIndependentPin = true;
- }
- CInPin *pInPin = nullptr;
- if (IsEqualCLSID(streamCategory, AVSTREAM_CUSTOM_PIN_IMAGE))
- {
- pInPin = new CCustomPin( pInAttributes.Get(), pcOutputStreams[ulIndex], this);
- DMFTCHECKNULL_GOTO( pInPin, done, E_OUTOFMEMORY);
- //
- // Since the custom pin is an input pin too we will push it
- // in the input pins list. This is however not being connected
- // to the output in this sample.
- m_CustomPinCount++;
- }
- else
- {
- pInPin = new CInPin( pInAttributes.Get(), pcOutputStreams[ulIndex], this);
- DMFTCHECKNULL_GOTO(pInPin, done, E_OUTOFMEMORY);
- }
-
- hr = ExceptionBoundary([this,pInPin]()
- {
- m_InPins.push_back(pInPin);
- });
-
- DMFTCHECKHR_GOTO(hr, done);
- DMFTCHECKHR_GOTO( pInPin->Init(m_spSourceTransform.Get() ), done);
-
-
- pInPin->AddRef();
-
- }
- //
- // If we have just one output stream exposed off the source transform create a one to three pin
- //
- if ( ( outputStreams == 1 ) && IsEqualGUID( streamCategory, PINNAME_VIDEO_CAPTURE ) )
- {
- outputStreams = 3;
- outGuids = new GUID [ outputStreams ];
- DMFTCHECKNULL_GOTO(outGuids, done, E_OUTOFMEMORY);
-
- m_OutPins.resize(outputStreams, nullptr);
-
- CInPin *piPin = (CInPin *)m_InPins[0];
-
- *outGuids = PINNAME_VIDEO_CAPTURE;
- *( outGuids + 1 ) = PINNAME_VIDEO_PREVIEW;
- *(outGuids + 2) = PINNAME_IMAGE; //PINNAME_IMAGE for independent pin and PINNAME_VIDEO_STILL for dependent pin!!
-
- for ( ULONG ulIndex = 0; ulIndex < outputStreams; ulIndex++ )
- {
- ComPtr<IKsControl> pKsControl = NULL;
- COutPin *poPin = nullptr;
-
- DMFTCHECKHR_GOTO( piPin->QueryInterface(IID_PPV_ARGS( &pKsControl ) ), done);
-
- hr = ExceptionBoundary([&]()
- {
- poPin = new COutPin(ulIndex, this, pKsControl.Get());
- });
-
- DMFTCHECKHR_GOTO(hr, done);
-
- DMFTCHECKNULL_GOTO( poPin,done, E_OUTOFMEMORY );
-
- DMFTCHECKHR_GOTO( BridgeInputPinOutputPin( piPin, poPin ),done );
-
- DMFTCHECKHR_GOTO( poPin->SetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, outGuids[ ulIndex ] ),done );
-
- DMFTCHECKHR_GOTO( poPin->SetUINT32( MF_DEVICESTREAM_STREAM_ID, ulIndex ),done );
-
- m_OutPins[ ulIndex ] = poPin;
- poPin->AddRef();
-
- }
- }
- else
- {
- //
- //Create one on one mapping
- //
-
- for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
- {
- ULONG ulPinIndex = 0;
- GUID pinGuid = GUID_NULL;
- ComPtr< IKsControl > pKsControl = nullptr;
-
- CInPin *piPin = ( CInPin * )m_InPins[ ulIndex ];
-
- if (piPin)
- {
- BOOL isCustom = false;
- if ( SUCCEEDED( CheckCustomPin( piPin, &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;
- }
- ulPinIndex = piPin->streamId();
-
- DMFTCHECKHR_GOTO(piPin->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinGuid), done);
-
- DMFTCHECKHR_GOTO(piPin->QueryInterface(IID_PPV_ARGS(&pKsControl)), done);
-
- COutPin *poPin = new COutPin(ulPinIndex, this, pKsControl.Get());
-
- DMFTCHECKNULL_GOTO(poPin, done, E_OUTOFMEMORY);
-
- DMFTCHECKHR_GOTO(poPin->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, pinGuid), done);
-
- DMFTCHECKHR_GOTO(poPin->SetUINT32(MF_DEVICESTREAM_STREAM_ID, ulPinIndex), done);
-
-#if defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES)
- //
- // If we wish to load MFT0 as well as Device MFT then we should be doing the following
- // Copy over the GUID attribute MF_DEVICESTREAM_EXTENSION_PLUGIN_CLSID from the input
- // pin to the output pin. This is because Device MFT is the new face of the filter now
- // and MFT0 will now get loaded for the output pins exposed from Device MFT rather than
- // DevProxy!
- //
-
- GUID guidMFT0 = GUID_NULL;
-
- hr = piPin->GetGUID(MF_DEVICESTREAM_EXTENSION_PLUGIN_CLSID, &guidMFT0);
-
- if (SUCCEEDED(hr))
- {
- //
- // This stream has an MFT0 .. Attach the GUID to the Outpin pin attribute
- // The downstream will query this attribute on the pins exposed from device MFT
- //
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! setting Mft0 guid on pin %d", ulIndex);
-
- DMFTCHECKHR_GOTO(poPin->SetGUID(MF_DEVICESTREAM_EXTENSION_PLUGIN_CLSID, guidMFT0), done);
-
- DMFTCHECKHR_GOTO(poPin->SetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT,
- static_cast< IUnknown* >(static_cast < IKsControl * >(this))), done);
-
- }
- else
- {
- // Reset Error.. MFT0 absence should not be an error
- hr = S_OK;
- }
-#endif
- DMFTCHECKHR_GOTO(BridgeInputPinOutputPin(piPin, poPin), done);
- hr = ExceptionBoundary([&]()
- {
- m_OutPins.push_back(poPin);
- });
- 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
- while ( m_InPins.size() > 0 )
- {
- CInPin *pInPin = nullptr;
- pInPin = ( CInPin* )m_InPins.back();
- m_InPins.pop_back();
- SAFERELEASE( pInPin );
- }
- while ( m_OutPins.size() > 0 )
- {
- COutPin *pin = nullptr;
- pin = ( COutPin* )m_OutPins.back();
- m_OutPins.pop_back();
- SAFERELEASE( pin );
- }
- //
- // Simply clear the custom pins since the input pins must have deleted the pin
- //
- m_spSourceTransform = 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
- //
- m_dwWorkQueueId = dwWorkQueueId;
- m_lWorkQueuePriority = lWorkItemBasePriority;
- 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);
-
-
- *pdwInputStreams = m_InputPinCount;
- *pdwOutputStreams = m_OutputPinCount;
-
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
- return hr;
-}
-
-//
-//Doesn't striclt conform to 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);
-
- MFTLOCKED();
-
- 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;
- MFTLOCKED();
-
-
- CInPin *piPin = ( CInPin* )GetInPin( dwInputStreamID );
-
- DMFTCHECKNULL_GOTO( piPin, done, MF_E_INVALIDSTREAMNUMBER );
-
- *ppMediaType = nullptr;
-
- hr = piPin->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;
- MFTLOCKED();
-
- DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
-
- COutPin*poPin = ( COutPin* )GetOutPin( dwOutputStreamID );
-
- DMFTCHECKNULL_GOTO( poPin, done, MF_E_INVALIDSTREAMNUMBER );
-
- *ppMediaType = nullptr;
-
- hr = poPin->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;
- MFTLOCKED();
- CAutoLock lock( m_critSec );
-
- DMFTCHECKNULL_GOTO( ppMediaType, done, E_INVALIDARG );
-
- *ppMediaType = nullptr;
-
- COutPin *poPin = ( COutPin* )GetOutPin( dwOutputStreamID );
-
- DMFTCHECKNULL_GOTO( poPin, done, MF_E_INVALIDSTREAMNUMBER );
-
- DMFTCHECKHR_GOTO( poPin->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;
- MFTLOCKED();
-
- 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");
- }
- }
- break;
- case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
- {
- SetStreamingState( DeviceStreamState_Run );
- //
- // Start Streaming custom pins if the device transfrom has any
- //
- SetStreamingStateCustomPins( DeviceStreamState_Run );
- }
- break;
- case MFT_MESSAGE_NOTIFY_END_STREAMING:
- {
- SetStreamingState(DeviceStreamState_Stop);
- //
- // Stop streaming custom pins if the device transform has any
- //
- SetStreamingStateCustomPins( 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 );
-
- MFTLOCKED();
-
- CInPin *inPin = ( CInPin* )GetInPin( dwInputStreamID );
- DMFTCHECKNULL_GOTO( inPin, done, E_INVALIDARG );
-
- if ( !IsStreaming() )
- {
- goto done;
- }
-
- DMFTCHECKHR_GOTO( inPin->SendSample( pSample ), done );
-
- QueueEvent( METransformHaveOutput, GUID_NULL, S_OK, NULL );
-
-done:
- SAFERELEASE( pSample );
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
- 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;
- MFTLOCKED();
- 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;
-
- COutPin *poPin = ( COutPin * )GetOutPin( dwStreamID );
- DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
-
- if ( SUCCEEDED( poPin->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;
- MFTLOCKED();
-
- DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG );
- *ppAttributes = nullptr;
-
- CInPin *piPin = static_cast<CInPin*>(GetInPin( dwInputStreamID ));
-
- DMFTCHECKNULL_GOTO( piPin, done, E_INVALIDARG );
-
- hr = piPin->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;
- MFTLOCKED();
-
- DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
- *ppAttributes = nullptr;
-
- COutPin *poPin = (COutPin *)GetOutPin(dwOutputStreamID);
-
- DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
-
- DMFTCHECKHR_GOTO( poPin->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;
- CInPin *piPin = (CInPin*)GetInPin(dwStreamID);
- DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
-
- DMFTCHECKHR_GOTO(piPin->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;
- CInPin *piPin = (CInPin*)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 *value
- )
- /*++
- 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);
-
- COutPin *poPin = (COutPin *)GetOutPin(dwStreamID);
- DMFTCHECKNULL_GOTO(poPin, done, MF_E_INVALIDSTREAMNUMBER);
-
- *value = poPin->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;
- CInPin *piPin = (CInPin*)GetInPin(dwStreamID);
- DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
-
- piPin->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);
-
- COutPin *poPin = (COutPin*)GetOutPin(dwStreamIndex);
- DMFTCHECKNULL_GOTO(poPin, done, E_INVALIDARG);
-
- DeviceStreamState oldState = poPin->SetState(DeviceStreamState_Disabled);
-
- hr = poPin->FlushQueues();
-
- if (FAILED(hr))
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! failed %x = %!HRESULT!", hr, hr);
- }
- //
- //Restore state
- //
- poPin->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;
- for ( DWORD dwIndex = 0, dwSize = (DWORD)m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
- {
- COutPin *poPin = (COutPin *)m_OutPins[dwIndex];
- oldState = poPin->SetState(DeviceStreamState_Disabled);
- poPin->FlushQueues();
- //
- //Restore state
- //
- poPin->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);
-
- //
- // Enable Warm Start on All filters for the sample. Please comment out this
- // section if this is not needed
- //
- if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl)
- && (pProperty->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART))
- {
- DMFTCHECKHR_GOTO(WarmStartHandler(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned),done);
- goto done;
- }
-
- if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl)
- && (pProperty->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOTHUMBNAIL))
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Thumbnail sent %d",pProperty->Flags);
- }
- if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl)
- &&(!filterHasIndependentPin()))
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Extended Control %d Passed ",pProperty->Id);
- switch (pProperty->Id)
- {
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE:
- hr = ExtendedPhotoModeHandler(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned);
- goto done;
- break;
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMAXFRAMERATE:
- hr = ExtendedPhotoMaxFrameRate(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned);
- goto done;
- break;
- case KSPROPERTY_CAMERACONTROL_EXTENDED_MAXVIDFPS_PHOTORES:
- hr = MaxVidFPS_PhotoResHandler(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned);
- goto done;
- break;
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOTRIGGERTIME:
- hr = QPCTimeHandler(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned);
- goto done;
- break;
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOFRAMERATE:
- hr = PhotoFrameRateHandler(pProperty,
- ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned);
- goto done;
- break;
-
- }
- }
- else
- if ((IsEqualCLSID(pProperty->Set, PROPSETID_VIDCAP_VIDEOCONTROL)) &&
- (pProperty->Id == KSPROPERTY_VIDEOCONTROL_MODE))
- {
- //
- //A photo trigger was sent!!!
- //We need to set the event haveoutput
- //
- PKSPROPERTY_VIDEOCONTROL_MODE_S VideoControl = NULL;
- if (sizeof(KSPROPERTY_VIDEOCONTROL_MODE_S) == ulDataLength)
- {
- VideoControl = (PKSPROPERTY_VIDEOCONTROL_MODE_S)pvPropertyData;
- m_PhotoModeIsPhotoSequence = false;
-
- if (VideoControl->Mode == KS_VideoControlFlag_StartPhotoSequenceCapture)
- {
- //
- //Signalling start of photo sequence
- //
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Starting PhotoSequence Trigger");
- m_PhotoModeIsPhotoSequence = true;
- setPhotoTriggerSent(true);
- }
- else
- if (VideoControl->Mode == KS_VideoControlFlag_StopPhotoSequenceCapture)
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Stopping PhotoSequence Trigger");
- m_PhotoModeIsPhotoSequence = false;
- setPhotoTriggerSent(false);
- }
- else
- {
- //
- //Normal trigger sent for single photo acquisition!
- //
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Take Single Photo Trigger");
- setPhotoTriggerSent(true);
- }
-
- }
-
- if (!filterHasIndependentPin())
- {
- goto done;
- }
- }
- hr = m_spIkscontrol->KsProperty(pProperty,
- ulPropertyLength,
- pvPropertyData,
- ulDataLength,
- pulBytesReturned);
-
-
-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.
- --*/
-{
- 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;
- if (pEvent && (pEvent->Set == KSEVENTSETID_ExtendedCameraControl) &&
- (pEvent->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART))
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Acquiring Event for Async Extended Control");
- //
- // For the Sample the warmstate handlers are supported by Device MFT and not passed to driver
- //
- hr = m_eventHandler.KSEvent(pEvent,
- ulEventLength,
- pEventData,
- ulDataLength,
- pBytesReturned
- );
- goto done;
- }
-
- if ((pEvent && (pEvent->Set == KSEVENTSETID_ExtendedCameraControl))
- && (!filterHasIndependentPin()))
- {
- //
- // Important: Extended controls will send events which are strictly
- // One shot. The event comes first where it should be duped and stored,
- // the control comes next. The event should be set after control completes
- // and it should be then closed.
- // The below code handles only certain events needed for
- // implementing photo sequence. For a complete exhaustive
- // list refer documentation.
- //
- switch (pEvent->Id)
- {
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE:
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMAXFRAMERATE:
- case KSPROPERTY_CAMERACONTROL_EXTENDED_MAXVIDFPS_PHOTORES:
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOTRIGGERTIME:
- case KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOFRAMERATE:
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Acquiring Event for Async Extended Control");
- //
- // Let the event handler handle the event
- //
- DMFTCHECKHR_GOTO(m_eventHandler.KSEvent(pEvent,
- ulEventLength,
- pEventData,
- ulDataLength,
- pBytesReturned
- ),done);
- goto done;
- }
- }
- }
- //
- // All the Events we don't handle should be sent to the driver!
- //
- hr = m_spIkscontrol->KsEvent(pEvent,
- ulEventLength,
- pEventData,
- ulDataLength,
- pBytesReturned);
-done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
- return hr;
-}
-
-
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
-//
-//IMFGetService functions
-//
-
-STDMETHODIMP CMultipinMft::GetService(
- __in REFGUID guidService,
- __in REFIID riid,
- __deref_out LPVOID* ppvObject
- )
-{
- //
- //This doesn't necessarily need to be a GetService function, but this is just so that the
- //pipeline implementation and the Device transform implementation is consistent.
- //In this sample the photoconfirmation interface is implementated by the same class
- //we can delegate it later to any of the pins if needed
- //
- UNREFERENCED_PARAMETER(guidService);
- if (riid == __uuidof(IMFCapturePhotoConfirmation))
- {
- return QueryInterface(riid, ppvObject);
- }
- else
- return MF_E_UNSUPPORTED_SERVICE;
-
-
-}
-
-//
-//IMFCapturePhotoConfirmation functions implemented
-//
-
-STDMETHODIMP CMultipinMft::SetPhotoConfirmationCallback(
- _In_ IMFAsyncCallback* pNotificationCallback
- )
-{
- CAutoLock Lock(m_critSec);
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Setting PhotoConfirmation %p, is passed", pNotificationCallback);
-
- m_spPhotoConfirmationCallback = pNotificationCallback;
- return S_OK;
-}
-STDMETHODIMP CMultipinMft::SetPixelFormat(
- _In_ GUID subtype
- )
-{
- m_guidPhotoConfirmationSubtype = subtype;
- return S_OK;
-}
-STDMETHODIMP CMultipinMft::GetPixelFormat(
- _Out_ GUID* subtype
- )
-{
- *subtype = m_guidPhotoConfirmationSubtype;
- return S_OK;
-}
-
-#endif
-
-
-
-#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;
-
- DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
-
- *ppAttributes = nullptr;
-
- if (m_spAttributes != nullptr)
- {
- m_spAttributes.CopyTo(ppAttributes);
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
-
-done:
- return hr;
-}
-#endif
-
-
-
-
-//
-//HELPER FUNCTIONS
-//
-
-STDMETHODIMP_(CBasePin*) 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;
-}
-
-STDMETHODIMP_(CBasePin*) 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;
-}
-
-/*++
-Description:
-This is a critical function which changes the state on an output pin
-This should be called under the control lock of the DT.
-Here the
---*/
-STDMETHODIMP CMultipinMft::ChangeMediaTypeEx(
- _In_ ULONG pinId,
- _In_opt_ IMFMediaType *pMediaType,
- _In_ DeviceStreamState reqState
- )
-{
- HRESULT hr = S_OK;
- DeviceStreamState oldOutPinState;
- DeviceStreamState newOutStreamState;
- ComPtr<IMFMediaType> pFullType = nullptr;
-
- COutPin *poPin = static_cast<COutPin*>( GetOutPin(pinId) );
-
- MMFTMMAPITERATOR inputPinPos;
-
- DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
- //
- //Check if the media type requested is a supported type
- //
- if ( pMediaType )
- {
- if ( !poPin->IsMediaTypeSupported( pMediaType, &pFullType ) )
- {
- DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
- }
- }
- //
- //First step disable the output pin. store the old state
- //
- oldOutPinState = poPin->SetState( DeviceStreamState_Disabled );
-
- (void)poPin->FlushQueues();
-
- newOutStreamState = pinStateTransition[oldOutPinState][reqState]; //New state needed
-
- //
- //Go through the output pins' maps that has the conencted input pin to the output pin
- //
- inputPinPos = m_outputPinMap.equal_range( pinId );
-
- for (std::multimap<int, int>::iterator piterator = inputPinPos.first; piterator != inputPinPos.second;piterator++)
- {
- //
- //Get the output pins connected to the input pin. The input pin map consists of the output pins connected
- //
- ULONG connectedInputPin = (*piterator).second;
- BOOL isAnyConnectedOutPinActive = false;
- BOOL isAnyConnectedOutPinPaused = false;
- BOOL isAnyConnectedOutPinRunning = false;
- BOOL doWeWaitForSetInput = false;
- DeviceStreamState oldInputStreamState;
- MF_TRANSFORM_XVP_OPERATION operation = DeviceMftTransformXVPIllegal;
- ComPtr<IMFMediaType> pInputMediaType = nullptr;
- CInPin *pconnectedInPin = (CInPin*)GetInPin( connectedInputPin );
- oldInputStreamState = pconnectedInPin->SetState( DeviceStreamState_Disabled );
- DeviceStreamState newRequestedInPinState = pinStateTransition[oldInputStreamState][newOutStreamState];
-
- if (pFullType)
- {
- pconnectedInPin->getMediaType( &pInputMediaType );
- }
-
- //
- // Check if we need an XVP to be inserted between this input and output pins.
- //
- CompareMediaTypesForXVP( pInputMediaType.Get(), pFullType.Get(), &operation );
- DMFTCHECKHR_GOTO( GetConnectOutPinStatus( connectedInputPin,
- pinId, // pinId = stream which should be excluded from the search. This function searches if
- &isAnyConnectedOutPinPaused, // there are any other output pins connected other than the ouput pin (on which the change media type is requested)
- &isAnyConnectedOutPinRunning, //, which is streaming, paused. This way if the output pin is requested to go to Pause, Stop and if any of the
- &isAnyConnectedOutPinActive ),done ); //other connected output pins are active, then input it not deactivated
-
- //
- //Check if we are asked to go to an active state
- //Check for the new media type. if
- //
- if ( !IsPinStateInActive( newRequestedInPinState ) )
- {
- //
- //We are being told to go active
- //We will request a change in input stream state.
- //
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! %p Going active IN: %d OUT: %d ", this, connectedInputPin, pinId );
- doWeWaitForSetInput = true;
- if ( !pFullType )
- {
- DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
- }
- if ( (! pInputMediaType ) || ( operation == DeviceMftTransformXVPDisruptiveIn ) )
- {
- pInputMediaType = pFullType;
- }
- if ( newRequestedInPinState == DeviceStreamState_Pause && isAnyConnectedOutPinRunning )
- {
- newRequestedInPinState = DeviceStreamState_Run;
- }
- }
- else
- {
- //
- //We have been requested to go inactive
- //
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! %p Going Inactive IN: %d OUT: %d ", this, connectedInputPin, pinId );
-
- if ( operation == DeviceMftTransformXVPDisruptiveIn )
- {
- //
- //Only where we recieve a disruptive media type change and a media type along with it, which is unlikely!!
- //
- pInputMediaType = pFullType;
- doWeWaitForSetInput = true;
- }
- if ( isAnyConnectedOutPinActive )
- {
- newRequestedInPinState = ( isAnyConnectedOutPinRunning ) ? DeviceStreamState_Run : DeviceStreamState_Pause;
- }
- else
- {
- //Switch over to the new media type..
- pInputMediaType = pFullType;
- if ( !IsPinStateInActive( oldInputStreamState ) )
- {
- //It was originall active.. now going down
- doWeWaitForSetInput = true;
- }
- }
- }
-
- //
- // This will happen if we need a change in Input media type, We will send an event
- // METransformInputStreamStateChanged to the Device transform manager. This will result
- // in the Device Transform manager calling us back in getprefferedinputstate where
- // we will give it back the state of the input and the media type to be set.
- // All this happens when we are holding a lock here in Change output media type. Hence during the
- // input media type change we don't hold a lock. THE DTM takes care not to send you any more media
- // type change operations that can cause a deadlock.
- //
-
- if ( doWeWaitForSetInput )
- {
- pconnectedInPin->setPreferredMediaType( pInputMediaType.Get() );
- pconnectedInPin->setPreferredStreamState( newRequestedInPinState );
- SendEventToManager( METransformInputStreamStateChanged, GUID_NULL, pconnectedInPin->streamId() );
- //
- //The media type will be set on the input pin by the time we return from the wait
- //
- DMFTCHECKHR_GOTO( pconnectedInPin->WaitForSetInputPinMediaChange(), done );
- }
- else
- {
- pconnectedInPin->SetState( oldInputStreamState );
- pconnectedInPin->setMediaType( pInputMediaType.Get() );
- }
-
- //Now the input type is all set..
- pInputMediaType = nullptr;
- (VOID)pconnectedInPin->getMediaType( &pInputMediaType );
- //
- //Now propogate the media type change to the output pins
- //
- MMFTMMAPITERATOR outputPinPos = m_inputPinMap.equal_range(pconnectedInPin->streamId());
- for ( std::multimap<int, int>::iterator poutPinsIterator = outputPinPos.first;
- poutPinsIterator != outputPinPos.second;
- poutPinsIterator++ )
- {
- ComPtr<IMFMediaType> pOutMediatype = nullptr;
- DeviceStreamState outPinState;
- ULONG connectedoutPin = (*poutPinsIterator).second;
- COutPin* pIoPin = static_cast<COutPin*>( GetOutPin ( connectedoutPin ) );
-
- (VOID)pIoPin->getMediaType( &pOutMediatype );
- outPinState = pIoPin->GetState();
-
- if ( pIoPin->streamId() != pinId)
- {
- //
- //This is the pin other than the output pin where the original change media type was recieved.
- //
-
- if ( pInputMediaType != nullptr && pOutMediatype != nullptr )
- {
- DMFTCHECKHR_GOTO( pIoPin->ChangeMediaTypeFromInpin(pconnectedInPin, pInputMediaType.Get(),
- pOutMediatype.Get(),
- outPinState ),done);
- }
- }
- else
- {
- //
- //Change the media type of the requested output pin
- //
- DMFTCHECKHR_GOTO( pIoPin->ChangeMediaTypeFromInpin(pconnectedInPin, pInputMediaType.Get(), pFullType.Get(), newOutStreamState), done);
- //Also signal to the manager that a stream state change has happened
- SendEventToManager( MEUnknown, MEDeviceStreamCreated, pIoPin->streamId());
- //
- //Set the First Sample Flag. this will get reset when the first sample comes in. We will signal the discontinuity
- //when we get a Processoutput from the Device Transform Manager
- //
- pIoPin->SetFirstSample(TRUE);
-
- }
- pOutMediatype = nullptr;
- }
-
- }
-
-done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
- return hr;
-}
-
-STDMETHODIMP 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;
- }
-
-
-STDMETHODIMP CMultipinMft::GetConnectOutPinStatus(
- _In_ ULONG ulPinId,
- _In_ ULONG ulOutPinId,
- _Inout_ PBOOL pAnyInPauseState,
- _Inout_ PBOOL pAnyInRunState,
- _Inout_ PBOOL pAnyActive
- )
- /*++
- Description:
-
- This function gets the statuses of the output pins other than the one specified
- The arguments are as follows
- ulPinId: The input pins which are connected to the ouput pin ulOutPinId
- ulOutPinId: The pin to be excluded from the check i.e. the input pin from which the request is usually sent.
- --*/
-{
- HRESULT hr = S_OK;
- MMFTMMAPITERATOR outputPinPos;
- CInPin *pconnectedInPin = (CInPin*)GetInPin(ulPinId);
- DMFTCHECKNULL_GOTO( pconnectedInPin, done, E_INVALIDARG );
-
- outputPinPos = m_inputPinMap.equal_range( pconnectedInPin->streamId() );
- DMFTCHECKNULL_GOTO( pconnectedInPin, done, E_FAIL );
-
- *pAnyActive = *pAnyInPauseState = *pAnyInRunState = false;
-
- for ( std::multimap<int, int>::iterator poutPosIterator = outputPinPos.first;
- poutPosIterator != outputPinPos.second;
- poutPosIterator++ )
- {
- ULONG connectedoutPin = (*poutPosIterator).second;
- COutPin* pconnectedOutPin = ( COutPin * )GetOutPin( connectedoutPin );
-
- if (pconnectedOutPin->streamId() != ulOutPinId)
- {
- //This is excluding the outpin which requested pin state change
- *pAnyActive |= !IsPinStateInActive( pconnectedOutPin->GetState() );
- *pAnyInPauseState |= ( pconnectedOutPin->GetState() == DeviceStreamState_Pause );
- *pAnyInRunState |= ( pconnectedOutPin->GetState() == DeviceStreamState_Run );
- }
-
- }
- done:
- return S_OK;
-}
-
-
-/*++
-Description:
-This function connects the input and output pins.
-Any media type filtering can happen here
---*/
-STDMETHODIMP CMultipinMft::BridgeInputPinOutputPin(
- _In_ CInPin* piPin,
- _In_ COutPin* poPin
- )
-{
- HRESULT hr = S_OK;
- ULONG ulIndex = 0;
- ComPtr<IMFMediaType> pMediaType = nullptr;
-
- 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++, &pMediaType )))
- {
- GUID subType = GUID_NULL;
- DMFTCHECKHR_GOTO( pMediaType->GetGUID(MF_MT_SUBTYPE,&subType), done );
-
- if ( IsKnownUncompressedVideoType( subType ) )
- {
- DMFTCHECKHR_GOTO( poPin->AddMediaType(NULL, pMediaType.Get() ), done );
- }
-
- pMediaType = nullptr;
- }
- //
- //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.
- //
- piPin->ConnectPin(poPin);
- });
- DMFTCHECKHR_GOTO(hr, done);
- //
- //Create the map. This will be useful when we have to decide the state transitions of the pins
- //
- m_inputPinMap.insert ( std::pair< int,int >( piPin->streamId(), poPin->streamId()) );
- 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;
-}
-
-
-//
-//The below routines are used to implement the extended controls needed to implement the photo sequence
-//The photo sequence is enabled for cameras with no independent image pins
-//The extended controls needed to enable photo sequence are discussed in detail in the photo sequence document
-//
-
-/*++
-Extended Photo Mode handler is the extended property handler dealing with the photosequence and single mode capabilities of the camera
---*/
-STDMETHODIMP CMultipinMft::ExtendedPhotoModeHandler(
-_In_ PKSPROPERTY Property,
-_In_ ULONG ulPropertyLength,
-_In_ LPVOID pData,
-_In_ ULONG ulOutputBufferLength,
-_Inout_ PULONG pulBytesReturned
-)
-
-{
- HRESULT hr = S_OK;
- UNREFERENCED_PARAMETER( ulPropertyLength );
-
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE );
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if ( ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE ) )
- {
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE ) )
- {
- PBYTE pPayload = ( PBYTE )pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- //
- //Use the below structure to make changes to the Property and thus affect the configuration
- //PKSCAMERA_EXTENDEDPROP_PHOTOMODE pExtendedValue = (PKSCAMERA_EXTENDEDPROP_PHOTOMODE)(pPayload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- m_FilterInPhotoSequence = pExtendedHeader->Flags & KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE;
- DMFTCHECKHR_GOTO(m_eventHandler.SetOneShot(KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE), done);
- }
- else
- {
- DMFTCHECKHR_GOTO(E_INVALIDARG, done);
- }
- }
- else if ( Property->Flags & KSPROPERTY_TYPE_GET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE );
- hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE ) )
- {
- PBYTE pPayload = (PBYTE)pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- PKSCAMERA_EXTENDEDPROP_PHOTOMODE pExtendedValue = ( PKSCAMERA_EXTENDEDPROP_PHOTOMODE )( pPayload + sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) );
-
- pExtendedHeader->Capability = ( KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL | KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE );
- pExtendedHeader->Flags = ( m_FilterInPhotoSequence ) ? KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE : KSCAMERA_EXTENDEDPROP_PHOTOMODE_NORMAL;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE );
- pExtendedHeader->Version = 1;
-
- pExtendedValue->MaxHistoryFrames = 10;
- pExtendedValue->RequestedHistoryFrames = 0 ;
- pExtendedValue->SubMode = 0 ;
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_PHOTOMODE );
- }
- else
- {
- DMFTCHECKHR_GOTO( E_INVALIDARG, done );
- }
- }
-
-done:
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
-
- return hr;
-}
-
-/*++
-The Extended Max Frame rate is self explanatory
---*/
-STDMETHODIMP CMultipinMft::ExtendedPhotoMaxFrameRate(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- )
-
-{
- HRESULT hr = S_OK;
- UNREFERENCED_PARAMETER( ulPropertyLength );
-
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if (ulOutputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
- {
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if (pData && ulOutputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
- {
- //
- //This is for setting the Max frame rate..
- //
- //PBYTE pPayload = (PBYTE)pData;
- //PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)(pPayload);
- //PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(pPayload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- DMFTCHECKHR_GOTO(m_eventHandler.SetOneShot(KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMAXFRAMERATE), done);
- }
- else
- {
- DMFTCHECKHR_GOTO(E_INVALIDARG, done);
- }
- }
- else if ( Property->Flags & KSPROPERTY_TYPE_GET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- hr = HRESULT_FROM_WIN32( ERROR_MORE_DATA );
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- PBYTE pPayload = ( PBYTE )pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = ( PKSCAMERA_EXTENDEDPROP_VALUE )( pPayload + sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) );
- pExtendedHeader->Capability = KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL;
- pExtendedHeader->Flags = 0;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
- pExtendedHeader->Version = 1;
- pExtendedValue->Value.ratio.HighPart = 30;
- pExtendedValue->Value.ratio.LowPart = 1;
- *pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
- }
- else
- {
- DMFTCHECKHR_GOTO(E_INVALIDARG, done);
- }
- }
-
-done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
-
- return hr;
-}
-
-
-STDMETHODIMP CMultipinMft::MaxVidFPS_PhotoResHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- )
-{
- HRESULT hr = S_OK;
- UNREFERENCED_PARAMETER( ulPropertyLength );
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+ sizeof( KSCAMERA_MAXVIDEOFPS_FORPHOTORES );
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if ( ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+ sizeof( KSCAMERA_MAXVIDEOFPS_FORPHOTORES ) )
- {
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if (pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_MAXVIDEOFPS_FORPHOTORES ))
- {
- PBYTE pPayload = (PBYTE)pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- //
- //Use the extended value to make changes to the property.. refer documentation
- //PKSCAMERA_MAXVIDEOFPS_FORPHOTORES pExtendedValue = (PKSCAMERA_MAXVIDEOFPS_FORPHOTORES)(pPayload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- pExtendedHeader->Capability = 0;
- pExtendedHeader->Flags = 0;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- pExtendedHeader->Version = 1;
-
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_MAXVIDEOFPS_FORPHOTORES );
- }
-
- else
- {
- hr = E_INVALIDARG;
- }
- }
- else if (Property->Flags & KSPROPERTY_TYPE_GET)
- {
- if (ulOutputBufferLength == 0)
- {
- *pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_MAXVIDEOFPS_FORPHOTORES);
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if (ulOutputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_MAXVIDEOFPS_FORPHOTORES))
- {
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if (pData && ulOutputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER)+sizeof(KSCAMERA_MAXVIDEOFPS_FORPHOTORES))
- {
- PBYTE pPayload = (PBYTE)pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )(pPayload );
- PKSCAMERA_MAXVIDEOFPS_FORPHOTORES pExtendedValue = (PKSCAMERA_MAXVIDEOFPS_FORPHOTORES)(pPayload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- pExtendedHeader->Capability = 0;
- pExtendedHeader->Flags = 0;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(PKSCAMERA_MAXVIDEOFPS_FORPHOTORES);
- pExtendedHeader->Version = 1;
-
- pExtendedValue->PreviewFPSNum = 30;
- pExtendedValue->PreviewFPSDenom = 1;
- pExtendedValue->CaptureFPSNum = 30;
- pExtendedValue->CaptureFPSDenom = 1;
- pExtendedValue->PhotoResHeight = 240;
- pExtendedValue->PhotoResWidth = 320;
-
- *pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_MAXVIDEOFPS_FORPHOTORES);
- }
- else
- {
- hr = E_INVALIDARG;
- }
- }
-done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
- return hr;
-}
-
-
-STDMETHODIMP CMultipinMft::QPCTimeHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- )
-{
- HRESULT hr = S_OK;
- UNREFERENCED_PARAMETER( ulPropertyLength );
-
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if ( ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ) )
- {
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ) )
- {
- //PBYTE pPayload = (PBYTE)pData;
- //
- //If the payload is to be used.. use the below structures
- //
- //PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)(pPayload);
- //Use the extended value to make changes to the property.. refer documentation
- //PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(pPayload +sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- *pulBytesReturned = sizeof( PKSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- }
- else
- {
- hr = E_INVALIDARG;
- }
- }
- else if ( Property->Flags & KSPROPERTY_TYPE_GET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if ( ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) + sizeof( KSCAMERA_EXTENDEDPROP_VALUE ) )
- {
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) + sizeof( KSCAMERA_EXTENDEDPROP_VALUE ) )
- {
- PBYTE pPayload = (PBYTE)pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = ( PKSCAMERA_EXTENDEDPROP_VALUE )( pPayload + sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) );
- pExtendedHeader->Capability = 0;
- pExtendedHeader->Flags = KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_SET;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) + sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- pExtendedHeader->Version = 1;
- pExtendedValue->Value.ull = 0;
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+ sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- }
- else
- {
- hr = E_INVALIDARG;
- }
- }
-done:
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
- return hr;
-}
-
-STDMETHODIMP CMultipinMft::PhotoFrameRateHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- )
-{
- HRESULT hr = S_OK;
-
- UNREFERENCED_PARAMETER( ulPropertyLength );
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- //
- //This is a read only property!!!
- //
- hr = E_INVALIDARG;
- }
- else if ( Property->Flags & KSPROPERTY_TYPE_GET )
- {
- if ( ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- PBYTE pPayload = (PBYTE)pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = ( PKSCAMERA_EXTENDEDPROP_VALUE )( pPayload + sizeof( KSCAMERA_EXTENDEDPROP_HEADER ) );
- pExtendedHeader->Capability = 0;
- pExtendedHeader->Flags = 0;
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- pExtendedHeader->Version = 1;
- pExtendedValue->Value.ratio.HighPart = 30;
- pExtendedValue->Value.ratio.LowPart = 1;
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
-
- }
-done:
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
- return hr;
-}
-
-
-STDMETHODIMP CMultipinMft::WarmStartHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- )
-{
-
- HRESULT hr = S_OK;
- UNREFERENCED_PARAMETER( ulPropertyLength );
- *pulBytesReturned = 0;
-
- if ( Property->Flags & KSPROPERTY_TYPE_SET )
- {
- if ( ulOutputBufferLength == 0 )
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done);
- }
- else if (ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done);
- }
- else if ( pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- PBYTE pPayload = ( PBYTE )pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )pPayload;
- //
- //Use the extended value to make changes to the property.. refer documentation
- //PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(pPayload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- if ( pExtendedHeader->Flags & KSCAMERA_EXTENDEDPROP_WARMSTART_MODE_ENABLED )
- {
- m_filterInWarmStart = true;
- }
- else
- {
- m_filterInWarmStart = false;
- }
-
- *pulBytesReturned = sizeof( PKSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- m_eventHandler.SetOneShot(KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART);
- }
- else
- {
- hr = S_OK;
- }
- }
- else if (Property->Flags & KSPROPERTY_TYPE_GET)
- {
- if (ulOutputBufferLength == 0)
- {
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- DMFTCHECKHR_GOTO(HRESULT_FROM_WIN32(ERROR_MORE_DATA), done);
- }
- else if (ulOutputBufferLength < sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- DMFTCHECKHR_GOTO( HRESULT_FROM_WIN32( ERROR_MORE_DATA ), done );
- }
- else if (pData && ulOutputBufferLength >= sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE ))
- {
- PBYTE pPayload = ( PBYTE )pData;
- PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = ( PKSCAMERA_EXTENDEDPROP_HEADER )( pPayload );
- //
- //Use the extended value to make changes to the property.. refer documentation
- //PKSCAMERA_EXTENDEDPROP_VALUE pExtendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(pPayload +sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
- //
- pExtendedHeader->Capability = KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL | KSCAMERA_EXTENDEDPROP_WARMSTART_MODE_ENABLED;
- pExtendedHeader->Flags = 0;
-
- if (m_filterInWarmStart)
- {
- pExtendedHeader->Flags |= KSCAMERA_EXTENDEDPROP_WARMSTART_MODE_ENABLED;
- }
-
- pExtendedHeader->Result = 0;
- pExtendedHeader->Size = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- pExtendedHeader->Version = 1;
- *pulBytesReturned = sizeof( KSCAMERA_EXTENDEDPROP_HEADER )+sizeof( KSCAMERA_EXTENDEDPROP_VALUE );
- hr = S_OK;
- }
- else
- {
- hr = S_OK;
- }
- }
-done:
- DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!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();
- 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;
-}
-
-
-
-
-
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
-/*
-Desciption:
-This function will be called by the preview pin to execute the photo confirmation stored with the
-MFT.
-*/
-
-STDMETHODIMP CMultipinMft::ProcessCapturePhotoConfirmationCallBack(
- _In_ IMFMediaType* pMediaType,
- _In_ IMFSample* pSample
- )
-{
- //
- //PhotoConfirmation Implementation
- //Note this function doesn't scan the metadata as the pipeline does to find out which buffer is the photoconfirmation buffer
- //The pipeline treats the preview buffer as the photo confirmation buffer and the driver marks the metadata on the buffer as being so.
- //This example treats every buffer coming on the pin as the confirmation buffer.
- //
-
- HRESULT hr = S_OK;
- ComPtr<IMFMediaType> spMediaType = nullptr;
- LONGLONG timeStamp = 0;
-
- DMFTCHECKHR_GOTO(MFCreateMediaType(&spMediaType), done);
- DMFTCHECKHR_GOTO(pMediaType->CopyAllItems(spMediaType.Get()), done);
-
- DMFTCHECKHR_GOTO(pSample->SetUnknown(MFSourceReader_SampleAttribute_MediaType_priv, spMediaType.Get()), done);
-
- DMFTCHECKHR_GOTO(pSample->GetSampleTime(&timeStamp), done);
- DMFTCHECKHR_GOTO(pSample->SetUINT64(MFSampleExtension_DeviceReferenceSystemTime, timeStamp), done);
-
- if (m_spPhotoConfirmationCallback)
- {
-
- //
- //We are directly sending the photo sample over to the consumers of the photoconfirmation interface.
- //
- ComPtr<IMFAsyncResult> spResult;
- DMFTCHECKHR_GOTO(MFCreateAsyncResult(pSample, m_spPhotoConfirmationCallback.Get(), NULL, &spResult), done);
- DMFTCHECKHR_GOTO(MFInvokeCallback(spResult.Get()), done);
- }
-done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
- return hr;
-}
-
-#endif
-
-//
-// Only worry about this if you have customs pins defined in the driver
-//
-
-STDMETHODIMP CMultipinMft::SetStreamingStateCustomPins(
- DeviceStreamState State
- )
-{
- HRESULT hr = S_OK;
-
- if ( m_CustomPinCount > 0 )
- {
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Custom Pin State changing to %d", State);
-
- for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
- {
- BOOL isCustom = false;
- CInPin* pInPin = static_cast<CInPin*>(m_InPins[ulIndex]);
-
- if ( SUCCEEDED( CheckCustomPin(pInPin, &isCustom) )
- && ( isCustom ) )
- {
- pInPin->SetState(State);
- }
- }
- }
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
- return hr;
-}