summaryrefslogtreecommitdiff
path: root/avstream/sampledevicemft
diff options
context:
space:
mode:
authorJoel Corley <[email protected]>2018-06-29 19:19:18 -0700
committerJoel Corley <[email protected]>2018-06-29 19:19:18 -0700
commit30ddbb997660fa4ae3608759b9d2d0789774ccdc (patch)
treed656c50cea303cb554460d529038fe5364634b01 /avstream/sampledevicemft
parent6c1981b8504329521343ad00f32daa847fa6083a (diff)
Update AVStream / Camera samples for RS4.
Diffstat (limited to 'avstream/sampledevicemft')
-rw-r--r--avstream/sampledevicemft/basepin.cpp6
-rw-r--r--avstream/sampledevicemft/common.h2
-rw-r--r--avstream/sampledevicemft/multipinmft.cpp19
-rw-r--r--avstream/sampledevicemft/multipinmft.h2
-rw-r--r--avstream/sampledevicemft/multipinmfthelpers.cpp135
-rw-r--r--avstream/sampledevicemft/multipinmfthelpers.h7
6 files changed, 97 insertions, 74 deletions
diff --git a/avstream/sampledevicemft/basepin.cpp b/avstream/sampledevicemft/basepin.cpp
index 80647f39..5e4ba038 100644
--- a/avstream/sampledevicemft/basepin.cpp
+++ b/avstream/sampledevicemft/basepin.cpp
@@ -644,9 +644,11 @@ STDMETHODIMP COutPin::ProcessOutput(_In_ DWORD dwFlags,
}
//
// Any processing before we pass the sample to further in the pipeline should be done here
- // PROCESSSAMPLE(pSample);
+ // PROCESSSAMPLE(pSample); There is a bug in the pipeline and to circumvent that we have to
+ // keep a reference on the sample. The pipeline is not releasing a reference when the sample
+ // is fed in ProcessInput. We are explicitly releasing it for the pipeline.
//
- pOutputSample->pSample = spSample.Get();
+ pOutputSample->pSample = spSample.Detach();
pOutputSample->dwStatus = S_OK;
done:
return hr;
diff --git a/avstream/sampledevicemft/common.h b/avstream/sampledevicemft/common.h
index 93f107c6..d32ec618 100644
--- a/avstream/sampledevicemft/common.h
+++ b/avstream/sampledevicemft/common.h
@@ -537,7 +537,7 @@ public:
// Query for the 2-D buffer interface. OK if this fails.
if (FAILED(m_pBuffer->QueryInterface(IID_PPV_ARGS(m_p2DBuffer2.GetAddressOf()))))
{
- m_p2DBuffer->QueryInterface(IID_PPV_ARGS(m_p2DBuffer.GetAddressOf()));
+ m_pBuffer->QueryInterface(IID_PPV_ARGS(m_p2DBuffer.GetAddressOf()));
}
}
~VideoBufferLock()
diff --git a/avstream/sampledevicemft/multipinmft.cpp b/avstream/sampledevicemft/multipinmft.cpp
index 4b9a10e2..5a3bb933 100644
--- a/avstream/sampledevicemft/multipinmft.cpp
+++ b/avstream/sampledevicemft/multipinmft.cpp
@@ -27,6 +27,7 @@ CMultipinMft::CMultipinMft()
m_filterInWarmStart(false)
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
, m_spPhotoConfirmationCallback(nullptr)
+ , m_firePhotoConfirmation(FALSE)
#endif
{
HRESULT hr = S_OK;
@@ -156,6 +157,9 @@ done:
--*/
+// This Sample will create a grayscale for known media types. Please remove MF_DEVICEMFT_ADD_GRAYSCALER_ to remove the grayscaler
+// This sample also has photo confirmation enabled remove DMF_DEVICEMFT_PHTOTOCONFIRMATION to remove photo confirmation
+
STDMETHODIMP CMultipinMft::InitializeTransform (
_In_ IMFAttributes *pAttributes
)
@@ -681,6 +685,8 @@ STDMETHODIMP CMultipinMft::ProcessInput(
DMFTCHECKHR_GOTO( inPin->SendSample( pSample ), done );
done:
DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+ // Workaround A Bug in the pipeline which is incorrectly not releasing the sample
+ SAFE_RELEASE(pSample);
return hr;
}
@@ -723,22 +729,24 @@ output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the sampl
pdwStatus ) ) )
{
gotOne = true;
- // Do photo confirmation if enabled
+ // Do photo confirmation if enabled off the preview stream only
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- BOOL pIsImagePin = FALSE;
+ BOOL pIsPreviewPin = FALSE;
if (pOutputSamples[i].pSample &&
IsPhotoConfirmationEnabled() &&
- (SUCCEEDED(CheckImagePin(static_cast<IMFAttributes*>(poPin), &pIsImagePin)) && pIsImagePin))
+ ((SUCCEEDED(CheckPreviewPin(static_cast<IMFAttributes*>(poPin), &pIsPreviewPin)) && pIsPreviewPin) &&
+ InterlockedCompareExchange(reinterpret_cast<PLONG>(&m_firePhotoConfirmation),FALSE,TRUE)))
{
+ // Please note photo confirmation should always be fired off the preview stream.
ComPtr<IMFMediaType> spMediaType;
if (SUCCEEDED(poPin->getMediaType(spMediaType.GetAddressOf())))
{
// Do Photo confirmation
ProcessCapturePhotoConfirmationCallBack(spMediaType.Get(), pOutputSamples[i].pSample);
+ m_firePhotoConfirmation = FALSE;
}
}
#endif
-
}
}
if (gotOne)
@@ -1071,6 +1079,9 @@ STDMETHODIMP CMultipinMft::KsProperty(
else
{
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Take Single Photo Trigger");
+#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
+ InterlockedExchange(reinterpret_cast<PLONG>(&m_firePhotoConfirmation),TRUE);
+#endif
}
}
}
diff --git a/avstream/sampledevicemft/multipinmft.h b/avstream/sampledevicemft/multipinmft.h
index 5bdaaca9..b55a221a 100644
--- a/avstream/sampledevicemft/multipinmft.h
+++ b/avstream/sampledevicemft/multipinmft.h
@@ -7,7 +7,6 @@
//
#pragma once
-#define MF_DEVICEMFT_ADD_GRAYSCALER_ 1
#include "common.h"
#include "mftpeventgenerator.h"
#include "basepin.h"
@@ -402,6 +401,7 @@ private:
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
ComPtr<IMFAsyncCallback> m_spPhotoConfirmationCallback; //Photo Confirmation related definitions
GUID m_guidPhotoConfirmationSubtype;
+ BOOL m_firePhotoConfirmation;
#endif
};
diff --git a/avstream/sampledevicemft/multipinmfthelpers.cpp b/avstream/sampledevicemft/multipinmfthelpers.cpp
index 788b52ab..063fafca 100644
--- a/avstream/sampledevicemft/multipinmfthelpers.cpp
+++ b/avstream/sampledevicemft/multipinmfthelpers.cpp
@@ -44,6 +44,7 @@ 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);
}
}
@@ -108,9 +109,6 @@ STDMETHODIMP CPinQueue::RecreateTee( _In_ IMFMediaType *inMediatype,
HRESULT hr = S_OK;
MF_TRANSFORM_XVP_OPERATION operation = DeviceMftTransformXVPIllegal;
- DMFTCHECKNULL_GOTO(inMediatype, done, E_INVALIDARG);
- DMFTCHECKNULL_GOTO(outMediatype, done, E_INVALIDARG);
-
SAFE_DELETE(m_teer);
CNullTee *nulltee = new (std::nothrow) CNullTee();
@@ -158,7 +156,7 @@ STDMETHODIMP CPinQueueWithGrayScale::RecreateTee( _In_ IMFMediaType *inMediatyp
outMediatype,
punkManager),done);
DMFTCHECKNULL_GOTO(m_teer, done, E_UNEXPECTED);
- // Wrap the media type with Gray scale tee only if the input media type is a YUY2, UYVY or NV12
+ // Wrap the media type with Gray scale tee only if the input media type is a YUY2, UYVY, NV12 or RGB32
DMFTCHECKHR_GOTO(inMediatype->GetGUID(MF_MT_SUBTYPE, &gInputSubType), done);
if (IsEqualCLSID(gInputSubType, MFVideoFormat_NV12)
||IsEqualCLSID(gInputSubType, MFVideoFormat_YUY2)
@@ -359,10 +357,7 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
}
*pOutSample = spXVPOutputSample.Detach();
- //
- //Release the Sample back to the pipeline
- //
- pSample->Release();
+
done:
hr = FAILED(pohr) ? pohr : hr;
@@ -535,6 +530,7 @@ CXvptee::~CXvptee()
m_spDeviceManagerUnk = nullptr;
}
+#ifdef MF_DEVICEMFT_ADD_GRAYSCALER_
CGrayTee::CGrayTee(_In_ Ctee *tee) : CWrapTee(tee),m_transformfn(nullptr)
{
}
@@ -542,68 +538,66 @@ STDMETHODIMP CGrayTee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSam
{
HRESULT hr = S_OK;
ComPtr<IMFSample> spOutputSample;
- ComPtr<IMFMediaType> spMediaType = getOutMediaType();
ComPtr <IMFMediaBuffer> spMediaBufInput, spMediaBufOutput;
LONG lDefaultStride = 0, lSrcStride = 0,lDestStride = 0;
-
GUID guidOutputSubType = GUID_NULL;
LONGLONG hnsDuration, hnsTime = 0;
DWORD dwTotalLength = 0;
- DMFTCHECKHR_GOTO(pSample->GetTotalLength(&dwTotalLength), done);
+ BYTE *pDest = NULL, *pSrc = NULL;
+ DWORD cbBuffer = 0;
+ ComPtr<IMFMediaType> spMediaType = getOutMediaType();
DMFTCHECKNULL_GOTO(ppOutSample, done, E_INVALIDARG);
DMFTCHECKNULL_GOTO(pSample, done, E_INVALIDARG);
+
+ DMFTCHECKHR_GOTO(pSample->GetTotalLength(&dwTotalLength), done);
*ppOutSample = nullptr;
DMFTCHECKHR_GOTO(pSample->ConvertToContiguousBuffer(spMediaBufInput.GetAddressOf()), done);
- DMFTCHECKHR_GOTO(getOutMediaType()->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
- DMFTCHECKHR_GOTO(MFGetStrideForBitmapInfoHeader(guidOutputSubType.Data1, m_rect.right, &lDefaultStride), done);
-
- DMFTCHECKHR_GOTO(MFCreateSample(spOutputSample.GetAddressOf()), done);
- DMFTCHECKHR_GOTO(pSample->CopyAllItems(spOutputSample.Get()), done);
- // Create the MediaBuffer for the new sample
- hr = MFCreate2DMediaBuffer(
- m_rect.right,
- m_rect.bottom,
- guidOutputSubType.Data1,
- FALSE, // top-down buffer (DX compatible)
- &spMediaBufOutput);
- if (FAILED(hr))
- {
- spMediaBufOutput = nullptr;
- DMFTCHECKHR_GOTO(MFCreateAlignedMemoryBuffer(
- dwTotalLength,
- MF_1_BYTE_ALIGNMENT,
- &spMediaBufOutput), done);
- }
- // Add the media buffer to the output sample
- DMFTCHECKHR_GOTO(spOutputSample->AddBuffer(spMediaBufOutput.Get()), done);
+
{
- BYTE *pDest = NULL, *pSrc = NULL;
- DWORD cbBuffer = 0;
VideoBufferLock inputLock(spMediaBufInput.Get());
- VideoBufferLock outputLock(spMediaBufOutput.Get());
- DMFTCHECKHR_GOTO(inputLock.LockBuffer(lDefaultStride, m_rect.bottom, &pSrc, &lSrcStride,&cbBuffer), done);
- DMFTCHECKHR_GOTO(outputLock.LockBuffer(lDefaultStride, m_rect.bottom, &pDest, &lDestStride,&cbBuffer,FALSE), done);
- if (m_transformfn)
+
+ DMFTCHECKHR_GOTO(spMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
+ DMFTCHECKHR_GOTO(MFGetStrideForBitmapInfoHeader(guidOutputSubType.Data1, m_rect.right, &lDefaultStride), done);
+ DMFTCHECKHR_GOTO(MFCreateSample(spOutputSample.GetAddressOf()), done);
+ DMFTCHECKHR_GOTO(pSample->CopyAllItems(spOutputSample.Get()), done);
+ DMFTCHECKHR_GOTO(inputLock.LockBuffer(lDefaultStride, m_rect.bottom, &pSrc, &lSrcStride, &cbBuffer), done);
+ dwTotalLength = max(dwTotalLength, (DWORD)(abs(lSrcStride*m_rect.bottom)));
+ // Create the MediaBuffer for the new sample
+ hr = MFCreate2DMediaBuffer(
+ m_rect.right,
+ m_rect.bottom,
+ guidOutputSubType.Data1,
+ (lSrcStride < 0), // top-down buffer (DX compatible)
+ &spMediaBufOutput);
+ if (FAILED(hr))
{
- m_transformfn(m_rect, pDest, lDestStride, pSrc, lSrcStride, m_rect.right, m_rect.bottom);
+ spMediaBufOutput = nullptr;
+ DMFTCHECKHR_GOTO(MFCreateAlignedMemoryBuffer(
+ dwTotalLength,
+ MF_1_BYTE_ALIGNMENT,
+ &spMediaBufOutput), done);
+ }
+ // Add the media buffer to the output sample
+ DMFTCHECKHR_GOTO(spOutputSample->AddBuffer(spMediaBufOutput.Get()), done);
+ {
+ VideoBufferLock outputLock(spMediaBufOutput.Get());
+ DMFTCHECKHR_GOTO(outputLock.LockBuffer(lDefaultStride, m_rect.bottom, &pDest, &lDestStride, &cbBuffer, FALSE), done);
+ if (m_transformfn)
+ {
+ m_transformfn(m_rect, pDest, lDestStride, pSrc, lSrcStride, m_rect.right, m_rect.bottom);
+ }
+ }
+ if (SUCCEEDED(pSample->GetSampleDuration(&hnsDuration)))
+ {
+ DMFTCHECKHR_GOTO(spOutputSample->SetSampleDuration(hnsDuration), done);
+ }
+ if (SUCCEEDED(pSample->GetSampleTime(&hnsTime)))
+ {
+ DMFTCHECKHR_GOTO(spOutputSample->SetSampleTime(hnsTime), done);
}
}
- if (SUCCEEDED(pSample->GetSampleDuration(&hnsDuration)))
- {
- DMFTCHECKHR_GOTO(spOutputSample->SetSampleDuration(hnsDuration),done);
- }
- if (SUCCEEDED(pSample->GetSampleTime(&hnsTime)))
- {
- DMFTCHECKHR_GOTO(spOutputSample->SetSampleTime(hnsTime),done);
- }
- if (SUCCEEDED(spMediaBufInput->GetCurrentLength(&dwTotalLength)))
- {
- DMFTCHECKHR_GOTO(spMediaBufOutput->SetCurrentLength(dwTotalLength),done);
- }
-
*ppOutSample = spOutputSample.Detach();
- pSample->Release();
done:
return hr;
}
@@ -643,6 +637,7 @@ HRESULT CGrayTee::Configure(
done:
return hr;
}
+#endif
/*++
Descrtiption:
@@ -1061,21 +1056,35 @@ done:
return hr;
}
-HRESULT CheckImagePin( _In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsImagePin )
+HRESULT CheckPinType(_In_ IMFAttributes* pAttributes, _In_ GUID pinType, _Out_ PBOOL pResult)
{
HRESULT hr = S_OK;
+ GUID pinClsid = GUID_NULL;
+
DMFTCHECKNULL_GOTO(pAttributes, done, E_INVALIDARG);
- DMFTCHECKNULL_GOTO(pbIsImagePin, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pResult, done, E_INVALIDARG);
+ *pResult = FALSE;
+
+ if (SUCCEEDED(pAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinClsid))
+ && (IsEqualCLSID(pinClsid, pinType)))
{
- GUID pinClsid = GUID_NULL;
- *pbIsImagePin = FALSE;
- if (SUCCEEDED(pAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinClsid))
- && ((IsEqualCLSID(pinClsid, PINNAME_IMAGE)) || IsEqualCLSID(pinClsid, PINNAME_VIDEO_STILL)))
- {
- *pbIsImagePin = TRUE;
- }
+ *pResult = TRUE;
}
done:
return hr;
}
+HRESULT CheckImagePin( _In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsImagePin )
+{
+ if ((SUCCEEDED(CheckPinType(pAttributes, PINNAME_IMAGE, pbIsImagePin)) && pbIsImagePin) ||
+ (SUCCEEDED(CheckPinType(pAttributes, PINNAME_VIDEO_STILL, pbIsImagePin)) && pbIsImagePin))
+ {
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT CheckPreviewPin( _In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsPreviewPin)
+{
+ return CheckPinType(pAttributes, PINNAME_PREVIEW, pbIsPreviewPin);
+}
diff --git a/avstream/sampledevicemft/multipinmfthelpers.h b/avstream/sampledevicemft/multipinmfthelpers.h
index 9376470e..41472c85 100644
--- a/avstream/sampledevicemft/multipinmfthelpers.h
+++ b/avstream/sampledevicemft/multipinmfthelpers.h
@@ -149,7 +149,7 @@ private:
UINT32 m_uHeight;
ComPtr<IUnknown> m_spDeviceManagerUnk;
};
-
+#ifdef MF_DEVICEMFT_ADD_GRAYSCALER_
class CGrayTee : public CWrapTee {
public:
CGrayTee(Ctee*);
@@ -163,7 +163,7 @@ private:
DMFT_IMAGE_TRANSFORM_FN m_transformfn;
RECT m_rect;
};
-
+#endif
/*
################## EVENT HANDLING #############################################
Events are usually divided into two categories by the Capture Pipeline
@@ -265,7 +265,8 @@ public:
CPinCreationFactory(_In_ CMultipinMft* pDeviceTransform):m_spDeviceTransform(pDeviceTransform){
}
};
-
+HRESULT CheckPinType(_In_ IMFAttributes* pAttributes, _In_ GUID pinType, _Out_ PBOOL pbIsImagePin);
HRESULT CheckImagePin(_In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsImagePin);
+HRESULT CheckPreviewPin(_In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsPreviewPin);