diff options
| -rw-r--r-- | avstream/sampledevicemft/basepin.cpp | 53 | ||||
| -rw-r--r-- | avstream/sampledevicemft/basepin.h | 14 | ||||
| -rw-r--r-- | avstream/sampledevicemft/common.h | 6 | ||||
| -rw-r--r-- | avstream/sampledevicemft/multipinmft.cpp | 57 | ||||
| -rw-r--r-- | avstream/sampledevicemft/multipinmft.h | 4 | ||||
| -rw-r--r-- | avstream/sampledevicemft/multipinmfthelpers.cpp | 105 | ||||
| -rw-r--r-- | avstream/sampledevicemft/multipinmfthelpers.h | 13 | ||||
| -rw-r--r-- | avstream/sampledevicemft/stdafx.h | 4 |
8 files changed, 118 insertions, 138 deletions
diff --git a/avstream/sampledevicemft/basepin.cpp b/avstream/sampledevicemft/basepin.cpp index 563ff610..471bbca7 100644 --- a/avstream/sampledevicemft/basepin.cpp +++ b/avstream/sampledevicemft/basepin.cpp @@ -37,12 +37,6 @@ CBasePin::CBasePin( _In_ ULONG id, _In_ CMultipinMft *parent) : CBasePin::~CBasePin() { - - for ( ULONG ulIndex = 0, ulSize = (ULONG)m_listOfMediaTypes.size(); ulIndex < ulSize; ulIndex++ ) - { - ComPtr<IMFMediaType> spMediaType; - spMediaType.Attach(m_listOfMediaTypes[ulIndex]); // Releases the previously stored pointer - } m_listOfMediaTypes.clear(); m_spAttributes = nullptr; } @@ -68,7 +62,6 @@ HRESULT CBasePin::AddMediaType( _Inout_ DWORD *pos, _In_ IMFMediaType *pMediaTyp m_listOfMediaTypes.push_back(pMediaType); }); DMFTCHECKHR_GOTO(hr, done); - pMediaType->AddRef(); if (pos) { *pos = (DWORD)(m_listOfMediaTypes.size() - 1); @@ -89,7 +82,8 @@ HRESULT CBasePin::GetMediaTypeAt( _In_ DWORD pos, _Outptr_result_maybenull_ IMFM { DMFTCHECKHR_GOTO(MF_E_NO_MORE_TYPES,done); } - spMediaType = m_listOfMediaTypes[pos]; + DMFTCHECKHR_GOTO(MFCreateMediaType(spMediaType.GetAddressOf()), done); + DMFTCHECKHR_GOTO(m_listOfMediaTypes[pos]->CopyAllItems(spMediaType.Get()), done); *ppMediaType = spMediaType.Detach(); done: return hr; @@ -129,8 +123,10 @@ STDMETHODIMP_(BOOL) CBasePin::IsMediaTypeSupported { bFound = TRUE; if (ppIMFMediaTypeFull) { - *ppIMFMediaTypeFull = m_listOfMediaTypes[uIIndex]; - (*ppIMFMediaTypeFull)->AddRef(); + ComPtr<IMFMediaType> spMediaType; + DMFTCHECKHR_GOTO(MFCreateMediaType(spMediaType.GetAddressOf()), done); + DMFTCHECKHR_GOTO(m_listOfMediaTypes[uIIndex]->CopyAllItems(spMediaType.Get()), done); + *ppIMFMediaTypeFull = spMediaType.Detach(); } break; } @@ -219,7 +215,7 @@ CInPin::~CInPin() } STDMETHODIMP CInPin::Init( - _In_ IMFTransform* pTransform + _In_ IMFDeviceTransform* pTransform ) { @@ -239,7 +235,7 @@ STDMETHODIMP CInPin::Init( m_waitInputMediaTypeWaiter = CreateEvent( NULL, FALSE, FALSE, - TEXT("MediaTypeWaiter") + nullptr ); DMFTCHECKNULL_GOTO( m_waitInputMediaTypeWaiter, done, E_OUTOFMEMORY ); @@ -275,7 +271,7 @@ HRESULT CInPin::GenerateMFMediaTypeListFromDevice( ComPtr<IMFMediaType> spMediaType; DWORD pos = 0; - hr = m_spSourceTransform->MFTGetOutputAvailableType(uiStreamId, iMediaType, spMediaType.GetAddressOf()); + hr = m_spSourceTransform->GetOutputAvailableType(uiStreamId, iMediaType, spMediaType.GetAddressOf()); if (hr != S_OK) break; @@ -813,11 +809,6 @@ STDMETHODIMP CTranslateOutPin::AddMediaType( DMFTCHECKHR_GOTO(pMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubType), done); // @@@@ README the below lines show how to exclude mediatypes which we don't want - /* if ((guidSubType != MFVideoFormat_H264)) - { - hr = S_FALSE; - goto done; - }*/ if (needTranslation(pMediaType)) { @@ -829,9 +820,21 @@ STDMETHODIMP CTranslateOutPin::AddMediaType( DMFTCHECKHR_GOTO(MFCalculateImageSize(translatedGUID, uiWidth, uiHeight, &uiImageSize), done); DMFTCHECKHR_GOTO(pNewMediaType->SetGUID(MF_MT_SUBTYPE, translatedGUID), done); DMFTCHECKHR_GOTO(pNewMediaType->SetUINT32(MF_MT_SAMPLE_SIZE, uiImageSize), done); + + (void)pNewMediaType->DeleteItem(MF_MT_COMPRESSED); + (void)pNewMediaType->DeleteItem(MF_MT_SAMPLE_SIZE); + (void)pNewMediaType->DeleteItem(MF_MT_AVG_BITRATE); + (void)pNewMediaType->DeleteItem(MF_MT_MPEG2_PROFILE); + (void)pNewMediaType->DeleteItem(MF_MT_MPEG2_LEVEL); + + (void)pNewMediaType->DeleteItem(MF_MT_VIDEO_ROTATION); + (void)pNewMediaType->DeleteItem(MF_MT_MINIMUM_DISPLAY_APERTURE); + + DMFTCHECKHR_GOTO(pNewMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE), done); + DMFTCHECKHR_GOTO(pNewMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255), done); hr = ExceptionBoundary([&]() { - m_TranslatedMediaTypes.insert(std::pair<IMFMediaType*, IMFMediaType*>( pNewMediaType.Get(), pMediaType)); + m_TranslatedMediaTypes.insert(std::pair<ComPtr<IMFMediaType>, ComPtr<IMFMediaType>>( pNewMediaType.Get(), pMediaType)); }); DMFTCHECKHR_GOTO(hr, done); } @@ -858,18 +861,22 @@ STDMETHODIMP_(BOOL) CTranslateOutPin::IsMediaTypeSupported( { DWORD dwFlags = 0, dwMatchedFlags = (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA); - std::map<IMFMediaType*, IMFMediaType*>::iterator found = std::find_if(m_TranslatedMediaTypes.begin(), m_TranslatedMediaTypes.end(), - [&](std::pair<IMFMediaType*, IMFMediaType*> p) + auto found = std::find_if(m_TranslatedMediaTypes.begin(), m_TranslatedMediaTypes.end(), + [&](std::pair<ComPtr<IMFMediaType>, ComPtr<IMFMediaType>> p) { - return (SUCCEEDED(pMediaType->IsEqual(p.first, &dwFlags)) + return (SUCCEEDED(pMediaType->IsEqual(p.first.Get(), &dwFlags)) && ((dwFlags & dwMatchedFlags) == (dwMatchedFlags))); }); if (found != m_TranslatedMediaTypes.end()) { - ComPtr<IMFMediaType> spMediaType = (*found).second; + ComPtr<IMFMediaType> spMediaType; if (ppIMFMediaTypeFull) { + if (FAILED(MFCreateMediaType(spMediaType.GetAddressOf()))|| FAILED((*found).second->CopyAllItems(spMediaType.Get()))) + { + return false; + } *ppIMFMediaTypeFull = spMediaType.Detach(); } return true; diff --git a/avstream/sampledevicemft/basepin.h b/avstream/sampledevicemft/basepin.h index cce17d0b..d3e45c93 100644 --- a/avstream/sampledevicemft/basepin.h +++ b/avstream/sampledevicemft/basepin.h @@ -458,10 +458,10 @@ private: class CInPin: public CBasePin{ public: CInPin( _In_opt_ IMFAttributes*, _In_ ULONG ulPinId = 0, _In_ CMultipinMft *pParent=NULL); - ~CInPin(); + virtual ~CInPin(); STDMETHOD ( Init )( - _In_ IMFTransform * + _In_ IMFDeviceTransform * ); STDMETHOD_( VOID, ConnectPin)( _In_ CBasePin * @@ -514,7 +514,7 @@ public: STDMETHOD_( VOID, ShutdownPin)(); protected: - ComPtr<IMFTransform> m_spSourceTransform; /*Source Transform i.e. DevProxy*/ + 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; @@ -541,7 +541,7 @@ public: , _In_ MFSampleAllocatorUsage allocatorUsage = MFSampleAllocatorUsage_DoesNotAllocate #endif ); - ~COutPin(); + virtual ~COutPin(); STDMETHODIMP FlushQueues(); STDMETHODIMP AddPin( _In_ DWORD pinId @@ -619,7 +619,7 @@ public: Init(); } STDMETHOD_(VOID, ShutdownPin)(); - ~CAsyncInPin() + virtual ~CAsyncInPin() { FlushQueues(); } @@ -663,10 +663,10 @@ public: _In_ IMFMediaType *pInMediatype, _In_ IMFMediaType* pOutMediaType, _In_ DeviceStreamState state); - + virtual ~CTranslateOutPin() {} protected: - map<IMFMediaType*, IMFMediaType*> m_TranslatedMediaTypes; + map<ComPtr<IMFMediaType>, ComPtr<IMFMediaType>> m_TranslatedMediaTypes; }; diff --git a/avstream/sampledevicemft/common.h b/avstream/sampledevicemft/common.h index bc6bbf28..57126378 100644 --- a/avstream/sampledevicemft/common.h +++ b/avstream/sampledevicemft/common.h @@ -230,9 +230,9 @@ typedef enum _DMFT_conversion_type{ DeviceMftTransformTypeIllegal // We cannot satisfy the input and output combination }DMFT_conversion_type,*PDMFT_conversion_type; -typedef std::vector< IMFMediaType *> IMFMediaTypeArray; -typedef std::vector< CBasePin *> CBasePinArray; -typedef std::vector< IMFSample *> IMFSampleList; +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; diff --git a/avstream/sampledevicemft/multipinmft.cpp b/avstream/sampledevicemft/multipinmft.cpp index 30c0463f..b171338a 100644 --- a/avstream/sampledevicemft/multipinmft.cpp +++ b/avstream/sampledevicemft/multipinmft.cpp @@ -54,21 +54,10 @@ done: 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( @@ -205,7 +194,7 @@ STDMETHODIMP CMultipinMft::InitializeTransform ( DMFTCHECKHR_GOTO( m_spSourceTransform.As( &m_spIkscontrol ), done ); - DMFTCHECKHR_GOTO( m_spSourceTransform->MFTGetStreamCount( &inputStreams, &outputStreams ), done ); + DMFTCHECKHR_GOTO( m_spSourceTransform->GetStreamCount( &inputStreams, &outputStreams ), done ); spFilterUnk = nullptr; @@ -222,7 +211,7 @@ STDMETHODIMP CMultipinMft::InitializeTransform ( pcOutputStreams = new (std::nothrow) DWORD[ outputStreams ]; DMFTCHECKNULL_GOTO( pcOutputStreams, done, E_OUTOFMEMORY ); - DMFTCHECKHR_GOTO( m_spSourceTransform->MFTGetStreamIDs( inputStreams, pcInputStreams, + DMFTCHECKHR_GOTO( m_spSourceTransform->GetStreamIDs( inputStreams, pcInputStreams, outputStreams, pcOutputStreams ),done ); @@ -252,7 +241,6 @@ STDMETHODIMP CMultipinMft::InitializeTransform ( }); DMFTCHECKHR_GOTO(hr, done); DMFTCHECKHR_GOTO( spInPin->Init(m_spSourceTransform.Get() ), done); - spInPin.Detach(); } // @@ -263,7 +251,7 @@ STDMETHODIMP CMultipinMft::InitializeTransform ( ComPtr<COutPin> spoPin; BOOL bCustom = FALSE; - ComPtr<CInPin> spiPin = ( CInPin * )m_InPins[ ulIndex ]; + ComPtr<CInPin> spiPin = ( CInPin * )m_InPins[ ulIndex ].Get(); if (spiPin.Get()) { @@ -292,7 +280,6 @@ STDMETHODIMP CMultipinMft::InitializeTransform ( { m_OutPins.push_back(spoPin.Get()); }), done); - spoPin.Detach(); ulOutPinIndex++; hr = S_OK; } @@ -329,15 +316,7 @@ done: 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 @@ -461,7 +440,7 @@ STDMETHODIMP CMultipinMft::GetInputAvailableType( ) { HRESULT hr = S_OK; - + CAutoLock lock(m_critSec); ComPtr<CInPin> spiPin = GetInPin( dwInputStreamID ); DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG); DMFTCHECKNULL_GOTO( spiPin, done, MF_E_INVALIDSTREAMNUMBER ); @@ -721,7 +700,7 @@ STDMETHODIMP CMultipinMft::ProcessInput( { HRESULT hr = S_OK; UNREFERENCED_PARAMETER( dwFlags ); - + CAutoLock lock(m_critSec); ComPtr<CInPin> spInPin = GetInPin( dwInputStreamID ); DMFTCHECKNULL_GOTO(spInPin, done, MF_E_INVALIDSTREAMNUMBER); @@ -762,6 +741,7 @@ output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the sampl HRESULT hr = S_OK; BOOL gotOne = false; ComPtr<COutPin> spOpin; + CAutoLock _lock(m_critSec); UNREFERENCED_PARAMETER( dwFlags ); if (cOutputBufferCount > m_OutputPinCount ) @@ -774,7 +754,6 @@ output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the sampl { DWORD dwStreamID = pOutputSamples[i].dwStreamID; { - CAutoLock _lock(m_critSec); spOpin = nullptr; spOpin = GetOutPin(dwStreamID); GUID pinGuid = GUID_NULL; @@ -828,7 +807,7 @@ STDMETHODIMP CMultipinMft::GetInputStreamAttributes( { HRESULT hr = S_OK; ComPtr<CInPin> spIPin; - + CAutoLock Lock(m_critSec); DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG ); *ppAttributes = nullptr; @@ -857,7 +836,7 @@ STDMETHODIMP CMultipinMft::GetOutputStreamAttributes( { HRESULT hr = S_OK; ComPtr<COutPin> spoPin; - + CAutoLock Lock(m_critSec); DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG); *ppAttributes = nullptr; @@ -893,6 +872,7 @@ STDMETHODIMP CMultipinMft::SetInputStreamState( --*/ { HRESULT hr = S_OK; + CAutoLock Lock(m_critSec); ComPtr<CInPin> spiPin = GetInPin(dwStreamID); DMFTCHECKNULL_GOTO(spiPin, done, MF_E_INVALIDSTREAMNUMBER); @@ -909,6 +889,7 @@ STDMETHODIMP CMultipinMft::GetInputStreamState( ) { HRESULT hr = S_OK; + CAutoLock Lock(m_critSec); ComPtr<CInPin> piPin = GetInPin(dwStreamID); DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER); @@ -994,6 +975,7 @@ STDMETHODIMP CMultipinMft::GetInputStreamPreferredState( --*/ { 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); @@ -1061,7 +1043,7 @@ STDMETHODIMP_(VOID) CMultipinMft::FlushAllStreams( CAutoLock Lock(m_critSec); for ( DWORD dwIndex = 0, dwSize = (DWORD)m_OutPins.size(); dwIndex < dwSize; dwIndex++ ) { - ComPtr<COutPin> spoPin = (COutPin *)m_OutPins[dwIndex]; + ComPtr<COutPin> spoPin = (COutPin *)m_OutPins[dwIndex].Get(); oldState = spoPin->SetState(DeviceStreamState_Disabled); spoPin->FlushQueues(); // @@ -1391,7 +1373,7 @@ CInPin* CMultipinMft::GetInPin( CInPin *inPin = NULL; for (DWORD dwIndex = 0, dwSize = (DWORD)m_InPins.size(); dwIndex < dwSize; dwIndex++) { - inPin = (CInPin *)m_InPins[dwIndex]; + inPin = (CInPin *)m_InPins[dwIndex].Get(); if (dwStreamId == inPin->streamId()) { break; @@ -1408,7 +1390,7 @@ COutPin* CMultipinMft::GetOutPin( COutPin *outPin = NULL; for ( DWORD dwIndex = 0, dwSize = (DWORD) m_OutPins.size(); dwIndex < dwSize; dwIndex++ ) { - outPin = ( COutPin * )m_OutPins[ dwIndex ]; + outPin = ( COutPin * )m_OutPins[ dwIndex ].Get(); if ( dwStreamId == outPin->streamId() ) { @@ -1509,7 +1491,10 @@ HRESULT CMultipinMft::ChangeMediaTypeEx( // // The media type will be set on the input pin by the time we return from the wait // - DMFTCHECKHR_GOTO(spinPin->WaitForSetInputPinMediaChange(), done); + m_critSec.Unlock(); + hr = spinPin->WaitForSetInputPinMediaChange(); + m_critSec.Lock(); + DMFTCHECKHR_GOTO(hr, done); // Change the media type on the output.. DMFTCHECKHR_GOTO(spoPin->ChangeMediaTypeFromInpin(pFullType.Get(), pMediaType , reqState), done); // @@ -1728,10 +1713,8 @@ STDMETHODIMP CMultipinMft::Shutdown( 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(); + (VOID)((CInPin*)m_InPins[ulIndex].Get())->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++) @@ -1833,7 +1816,7 @@ HRESULT CMultipinMft::SetStreamingStateCustomPins( for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++) { BOOL isCustom = false; - CInPin* pInPin = static_cast<CInPin*>(m_InPins[ulIndex]); + CInPin* pInPin = static_cast<CInPin*>(m_InPins[ulIndex].Get()); if ( SUCCEEDED( CheckCustomPin(pInPin, &isCustom) ) && ( isCustom ) ) diff --git a/avstream/sampledevicemft/multipinmft.h b/avstream/sampledevicemft/multipinmft.h index 70367f1d..be86d66b 100644 --- a/avstream/sampledevicemft/multipinmft.h +++ b/avstream/sampledevicemft/multipinmft.h @@ -377,7 +377,7 @@ protected: //Inline functions // - __inline IMFTransform* Parent() + __inline IMFDeviceTransform* Parent() { return m_spSourceTransform.Get(); } @@ -406,7 +406,7 @@ private: 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 + ComPtr<IMFDeviceTransform> m_spSourceTransform; // The sources transform. This is the pipeline DevProxy MFSHUTDOWN_STATUS m_eShutdownStatus; DWORD m_dwWorkQueueId; LONG m_lWorkQueuePriority; diff --git a/avstream/sampledevicemft/multipinmfthelpers.cpp b/avstream/sampledevicemft/multipinmfthelpers.cpp index 34cebe8b..0d720c3d 100644 --- a/avstream/sampledevicemft/multipinmfthelpers.cpp +++ b/avstream/sampledevicemft/multipinmfthelpers.cpp @@ -38,7 +38,6 @@ Description: --*/ STDMETHODIMP_(VOID) CPinQueue::InsertInternal( _In_ IMFSample *pSample ) { - pSample->AddRef(); HRESULT hr = ExceptionBoundary([&]() { m_sampleList.push_back(pSample); @@ -52,8 +51,6 @@ STDMETHODIMP_(VOID) CPinQueue::InsertInternal( _In_ IMFSample *pSample ) 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); } } @@ -78,7 +75,7 @@ STDMETHODIMP CPinQueue::Remove( _Outptr_result_maybenull_ IMFSample **ppSample) if ( !m_sampleList.empty() ) { - *ppSample = m_sampleList.front(); + *ppSample = m_sampleList.front().Detach(); } DMFTCHECKNULL_GOTO( *ppSample, done, MF_E_TRANSFORM_NEED_MORE_INPUT ); @@ -177,33 +174,31 @@ STDMETHODIMP CPinQueue::RecreateTeeByAllocatorMode( Ctee::ReleaseTee(m_spTeer);// Should release the reference - wistd::unique_ptr<CNullTee> nulltee = wil::make_unique_nothrow<CNullTee>(this); - RETURN_IF_NULL_ALLOC(nulltee); + ComPtr<CNullTee> spNulltee = new (std::nothrow) CNullTee(this); + DMFTCHECKNULL_GOTO(spNulltee.Get(), done, E_OUTOFMEMORY); if (allocatorUsage == MFSampleAllocatorUsage_DoesNotAllocate) { - m_spTeer.Attach(nulltee.release()); /*A simple passthrough*/ + m_spTeer = spNulltee.Get(); } else { - wistd::unique_ptr<CSampleCopytee> sampleCopytee; - RETURN_IF_NULL_ALLOC(sampleCopytee); - (void)sampleCopytee->SetD3DManager(punkManager); - + ComPtr<CSampleCopytee> spSampleCopytee; if (allocatorUsage == MFSampleAllocatorUsage_UsesProvidedAllocator) { RETURN_HR_IF_NULL(E_INVALIDARG, pAllocator); - sampleCopytee = wil::make_unique_nothrow<CSampleCopytee>(nulltee.release(), pinCategory(), pAllocator); + spSampleCopytee = new (std::nothrow) CSampleCopytee(spNulltee.Get(), pinCategory(), pAllocator); } else { - sampleCopytee = wil::make_unique_nothrow<CSampleCopytee>(nulltee.release(), pinCategory(), nullptr); + spSampleCopytee = new (std::nothrow) CSampleCopytee(spNulltee.Get(), pinCategory(), nullptr); } - - RETURN_IF_FAILED(sampleCopytee->SetMediaTypes(inMediatype, outMediatype)); - m_spTeer.Attach(sampleCopytee.release()); + DMFTCHECKNULL_GOTO(spSampleCopytee.Get(), done, E_OUTOFMEMORY); + (void)spSampleCopytee->SetD3DManager(punkManager); + RETURN_IF_FAILED(spSampleCopytee->SetMediaTypes(inMediatype, outMediatype)); + m_spTeer = spSampleCopytee.Get(); } - +done: return hr; } #endif // ((defined NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB)) @@ -283,28 +278,13 @@ this path traversed. This function feeds the sample to the XVP or the decoding T STDMETHODIMP CWrapTee::PassThrough( _In_ IMFSample* pInSample ) { HRESULT hr = S_OK; - IMFSample* pOutSample = nullptr; - bool newSample = false; + ComPtr<IMFSample> spOutSample = nullptr; DMFTCHECKNULL_GOTO(pInSample, done, S_OK); // pass through for no sample - DMFTCHECKHR_GOTO(Do(pInSample, &pOutSample,newSample),done); + DMFTCHECKHR_GOTO(Do(pInSample, spOutSample.ReleaseAndGetAddressOf()), done); if (m_spObjectWrapped) { - if (SUCCEEDED(hr = m_spObjectWrapped->PassThrough( pOutSample ))) - { - //@@@@README There is a very bad bug in the pipeline that the device transform manager - // is not releasing the reference on the sample when it is passed to the device MFT so any - // sample produced has to be referenced matched in the deviceMFT so that the net reference remains one - // This goes against the ownership rules in Com, but this bug has existed in the pipeline so far, - // so until we rev the interface we will have to live with it - // - if (newSample) - { - // If we produce the sample, then we have to release the sample - SAFE_RELEASE(pOutSample); - } - } - + DMFTCHECKHR_GOTO(m_spObjectWrapped->PassThrough(spOutSample.Get()), done); } done: @@ -326,7 +306,7 @@ HRESULT CVideoProcTee::SetMediaTypes(_In_ IMFMediaType* pInMediaType, _In_ IMFMe ComPtr<IMFTransform> spTransform; DMFTCHECKHR_GOTO(CWrapTee::SetMediaTypes(pInMediaType, pOutMediaType),done); DMFTCHECKHR_GOTO(Configure(pInMediaType, pOutMediaType, spTransform.GetAddressOf()), done); - m_spVideoProcessor = spTransform.Detach(); + m_spVideoProcessor = spTransform; // // Start streaming // @@ -380,6 +360,15 @@ HRESULT CVideoProcTee::CreateAllocator() return hr; } +CVideoProcTee::~CVideoProcTee() +{ + if (m_spPrivateAllocator.Get()) + { + (VOID)m_spPrivateAllocator->UninitializeSampleAllocator(); + m_spPrivateAllocator = nullptr; + } +} + // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@// // @@@@ README: Video Processor functions below // @@ -412,10 +401,9 @@ HRESULT CXvptee::StopStreaming() HRESULT hr = S_OK; CAutoLock Lock(m_Lock); SetAsyncStatus(MF_E_SHUTDOWN); - DMFTCHECKHR_GOTO(Transform()->MFTProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0), done); // Flush the stream - DMFTCHECKHR_GOTO(Transform()->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0), done); // Notify end of stream - DMFTCHECKHR_GOTO(Transform()->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0), done); // Notify end of streaming -done: + Transform()->MFTProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0); // Flush the stream + Transform()->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0); // Notify end of stream + Transform()->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0); // Notify end of streaming return hr; } @@ -429,7 +417,7 @@ outpin should be in Open state for the sample to reach the XVP and consequetivel Output Pin. --*/ -STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample, _Inout_ bool &newSample) +STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample) { HRESULT hr = S_OK; MFT_OUTPUT_DATA_BUFFER outputSample; @@ -474,7 +462,6 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSamp if (spXVPOutputSample.Get()) { - newSample = true; *ppOutSample = spXVPOutputSample.Detach(); } done: @@ -554,11 +541,6 @@ CDecoderTee::~CDecoderTee() { (VOID)StopStreaming(); MFUnlockWorkQueue(m_dwCameraStreamWorkQueueId); - if (m_spPrivateAllocator) - { - m_spPrivateAllocator->UninitializeSampleAllocator(); - m_spPrivateAllocator = nullptr; - } } HRESULT CDecoderTee::StartStreaming() @@ -584,9 +566,9 @@ HRESULT CDecoderTee::StopStreaming() if (spTransform.Get()) { ComPtr<IMFShutdown> spShutdown; - DMFTCHECKHR_GOTO(spTransform->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, m_dwMFTInputId), done); - DMFTCHECKHR_GOTO(spTransform->MFTProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0), done); - DMFTCHECKHR_GOTO(spTransform->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0), done); + spTransform->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, m_dwMFTInputId); + spTransform->MFTProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0); + spTransform->MFTProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0); // Shut it down if (SUCCEEDED(spTransform->QueryInterface(IID_PPV_ARGS(&spShutdown)))) { @@ -595,7 +577,6 @@ HRESULT CDecoderTee::StopStreaming() spTransform = nullptr; } -done: return hr; } @@ -675,14 +656,13 @@ done: } -STDMETHODIMP CDecoderTee::Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **ppoutSample, _Inout_ bool &newSample) +STDMETHODIMP CDecoderTee::Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **ppoutSample) { HRESULT hr = S_OK; ComPtr<IMFSample> spOutputSample; CAutoLock lock(m_Lock); ComPtr<IMFTransform> spTransform = Transform(); - newSample = false; DMFTCHECKNULL_GOTO(ppoutSample, done, E_INVALIDARG); *ppoutSample = nullptr; DMFTCHECKHR_GOTO(GetAsyncStatus(), done); @@ -983,6 +963,7 @@ HRESULT CDecoderTee::ConfigDecoder(_In_ IMFTransform* pTransform, _In_ GUID guid GUID guidMajorType; GUID guidSubtype; DWORD dwMediaTypeIndex = 0; + DWORD dwFlags = 0; ComPtr<IMFDXGIDeviceManager> spDxgiManager; UNREFERENCED_PARAMETER(guidSubType); DMFTCHECKNULL_GOTO(pTransform, done, E_INVALIDARG); @@ -1050,6 +1031,18 @@ HRESULT CDecoderTee::ConfigDecoder(_In_ IMFTransform* pTransform, _In_ GUID guid // Try to set output type on the MJPG decoder. DMFTCHECKHR_GOTO(pTransform->MFTSetOutputType(m_dwMFTOutputId, spMediaType.Get(), 0), done); + if (S_OK != (spMediaType->IsEqual(m_pOutputMediaType.Get(), &dwFlags))) + { + ComPtr<CXvptee> spXvpTee = new (std::nothrow) CXvptee(m_spObjectWrapped.Get(), m_streamCategory); + DMFTCHECKNULL_GOTO(spXvpTee.Get(), done, E_OUTOFMEMORY); + (VOID)spXvpTee->SetD3DManager(m_spDeviceManagerUnk.Get()); + DMFTCHECKHR_GOTO(spXvpTee->SetMediaTypes(spMediaType.Get(), m_pOutputMediaType.Get()), done); + m_spObjectWrapped = spXvpTee; + m_pOutputMediaType = spMediaType; + //Recreate the Allocator + DMFTCHECKHR_GOTO(CreateAllocator(), done); + m_bXvpAdded = TRUE; + } done: if (FAILED(hr)) { @@ -1125,7 +1118,7 @@ VOID CDecoderTee::ShutdownTee() CGrayTee::CGrayTee(_In_ Ctee *tee) : CWrapTee(tee),m_transformfn(nullptr) { } -STDMETHODIMP CGrayTee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample, _Inout_ bool &newSample) +STDMETHODIMP CGrayTee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample) { HRESULT hr = S_OK; ComPtr<IMFSample> spOutputSample; @@ -1190,7 +1183,6 @@ STDMETHODIMP CGrayTee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSam } if (spOutputSample.Get()) { - newSample = true; *ppOutSample = spOutputSample.Detach(); } done: @@ -1275,7 +1267,7 @@ HRESULT CSampleCopytee::StopStreaming() return S_OK; } -STDMETHODIMP CSampleCopytee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample, _Inout_ bool &newSample) +STDMETHODIMP CSampleCopytee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample) { HRESULT hr = S_OK; @@ -1318,7 +1310,6 @@ STDMETHODIMP CSampleCopytee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pp if (spXVPOutputSample.Get()) { - newSample = true; *ppOutSample = spXVPOutputSample.Detach(); } diff --git a/avstream/sampledevicemft/multipinmfthelpers.h b/avstream/sampledevicemft/multipinmfthelpers.h index 681ca071..4237dbf4 100644 --- a/avstream/sampledevicemft/multipinmfthelpers.h +++ b/avstream/sampledevicemft/multipinmfthelpers.h @@ -326,7 +326,7 @@ public: } STDMETHODIMP PassThrough ( _In_ IMFSample* ); - virtual STDMETHODIMP Do ( _In_ IMFSample* pSample, _Out_ IMFSample ** , _Inout_ bool &newSample) = 0; + virtual STDMETHODIMP Do ( _In_ IMFSample* pSample, _Out_ IMFSample **) = 0; STDMETHODIMP SetMediaTypes(_In_ IMFMediaType* pInMediaType, _In_ IMFMediaType* pOutMediaType); // // Inline functions @@ -395,8 +395,7 @@ public: } return hr; } - virtual ~CVideoProcTee() - {} + virtual ~CVideoProcTee(); protected: CCritSec m_Lock; __inline VOID SetAsyncStatus(_In_ HRESULT hrStatus) @@ -426,7 +425,7 @@ public: virtual ~CXvptee(); STDMETHOD(StartStreaming)(); STDMETHOD(StopStreaming)(); - STDMETHODIMP Do ( _In_ IMFSample* pSample, _Outptr_ IMFSample **, _Inout_ bool &newSample); + STDMETHODIMP Do ( _In_ IMFSample* pSample, _Outptr_ IMFSample **); STDMETHODIMP Configure ( _In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform** ); }; @@ -453,7 +452,7 @@ public: } virtual ~CDecoderTee(); - STDMETHODIMP Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **, _Inout_ bool &newSample); + STDMETHODIMP Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **); STDMETHODIMP Configure(_In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform**); STDMETHODIMP Invoke(_In_ IMFAsyncResult*); protected: @@ -491,7 +490,7 @@ public: ~CSampleCopytee(); STDMETHOD(StartStreaming)(); STDMETHOD(StopStreaming)(); - STDMETHODIMP Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **, _Inout_ bool &newSample); + STDMETHODIMP Do(_In_ IMFSample* pSample, _Outptr_ IMFSample **); STDMETHODIMP Configure(_In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform**); }; @@ -502,7 +501,7 @@ public: ~CGrayTee() { } - STDMETHODIMP Do(_In_ IMFSample* pSample, _Out_ IMFSample **, , _Inout_ bool &newSample); + STDMETHODIMP Do(_In_ IMFSample* pSample, _Out_ IMFSample **); STDMETHODIMP Configure(_In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform**); private: // Function pointer for the function that transforms the image. diff --git a/avstream/sampledevicemft/stdafx.h b/avstream/sampledevicemft/stdafx.h index 657208cd..a76118c0 100644 --- a/avstream/sampledevicemft/stdafx.h +++ b/avstream/sampledevicemft/stdafx.h @@ -54,8 +54,8 @@ using namespace Microsoft::WRL; // //#define MF_DEVICEMFT_ADD_GRAYSCALER_ 1 #define MF_DEVICEMFT_ASYNCPIN_NEEDED 1 -//#define MF_DEVICEMFT_DECODING_MEDIATYPE_NEEDED 0 -#define MF_DEVICEMFT_SET_SPHERICAL_ATTRIBUTES 1 +//#define MF_DEVICEMFT_DECODING_MEDIATYPE_NEEDED 1 +//#define MF_DEVICEMFT_SET_SPHERICAL_ATTRIBUTES 1 //#define MF_DEVICEMFT_ENUM_HW_DECODERS 1 |
