summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaredd <[email protected]>2018-01-19 17:19:00 -0800
committerWei Mao <[email protected]>2018-01-19 17:19:00 -0800
commit6e7c8cb437135e55917c34cfebe1be944bbf6d3f (patch)
treef7570fe170194facd45e4f9f887ff56dc683a31c
parentdd7e6f697ed67e94dc45cd33078b1dbcb643f439 (diff)
Updating Camera WDK Samples to RS3 version (#193)
-rw-r--r--avstream/avscamera/common/MetadataInternal.h22
-rw-r--r--avstream/avscamera/mft0/MFT0Impl.cpp559
-rw-r--r--avstream/avscamera/mft0/MFT0Impl.h12
-rw-r--r--avstream/avscamera/sys/AvsCamera.vcxproj8
-rw-r--r--avstream/avscamera/sys/AvsCameraFilter.cpp3
-rw-r--r--avstream/avscamera/sys/CameraSimulatorCommon.h391
-rw-r--r--avstream/avscamera/sys/Capture.cpp335
-rw-r--r--avstream/avscamera/sys/Capture.h1
-rw-r--r--avstream/avscamera/sys/Common.h386
-rw-r--r--avstream/avscamera/sys/Device.cpp2
-rw-r--r--avstream/avscamera/sys/NV12Synthesizer.cpp44
-rw-r--r--avstream/avscamera/sys/NV12Synthesizer.h1
-rw-r--r--avstream/avscamera/sys/Sensor.cpp6
-rw-r--r--avstream/avscamera/sys/Sensor.h1
-rw-r--r--avstream/avscamera/sys/SensorSimulation.cpp33
-rw-r--r--avstream/avscamera/sys/SensorSimulation.h4
-rw-r--r--avstream/avscamera/sys/Synthesizer.h8
-rw-r--r--avstream/avscamera/sys/Timer.h2
-rw-r--r--avstream/avscamera/sys/Util.cpp60
-rw-r--r--avstream/avscamera/sys/Util.h39
-rw-r--r--avstream/avscamera/sys/YUVSynthesizer.h2
-rw-r--r--avstream/avscamera/sys/avscamera.infbin26814 -> 26816 bytes
-rw-r--r--avstream/avscamera/sys/filter.cpp239
-rw-r--r--avstream/avscamera/sys/filter.h29
-rw-r--r--avstream/avscamera/sys/hwsim.cpp8
-rw-r--r--avstream/avscamera/sys/imagehwsim.cpp4
-rw-r--r--avstream/avshws/README.md10
-rw-r--r--avstream/avshws/avshws.h148
-rw-r--r--avstream/avshws/avshws.inf4
-rw-r--r--avstream/avshws/device.cpp343
-rw-r--r--avstream/avssamp/avssamp.cpp118
-rw-r--r--avstream/avssamp/avssamp.h84
-rw-r--r--avstream/avssamp/avssamp.inf4
-rw-r--r--avstream/sampledevicemft/README.md38
-rw-r--r--avstream/sampledevicemft/basepin.cpp492
-rw-r--r--avstream/sampledevicemft/basepin.h209
-rw-r--r--avstream/sampledevicemft/common.h431
-rw-r--r--avstream/sampledevicemft/mftpeventgenerator.cpp16
-rw-r--r--avstream/sampledevicemft/multipinmft.cpp1294
-rw-r--r--avstream/sampledevicemft/multipinmft.h109
-rw-r--r--avstream/sampledevicemft/multipinmft.vcxproj7
-rw-r--r--avstream/sampledevicemft/multipinmfthelpers.cpp435
-rw-r--r--avstream/sampledevicemft/multipinmfthelpers.h130
-rw-r--r--avstream/sampledevicemft/multipinmftutils.cpp348
-rw-r--r--avstream/sampledevicemft/stdafx.h2
-rw-r--r--avstream/samplemft0/SampleMft0.vcxproj8
-rw-r--r--avstream/samplemft0/resource.hbin828 -> 1710 bytes
47 files changed, 3264 insertions, 3165 deletions
diff --git a/avstream/avscamera/common/MetadataInternal.h b/avstream/avscamera/common/MetadataInternal.h
index 28572efc..2f789a02 100644
--- a/avstream/avscamera/common/MetadataInternal.h
+++ b/avstream/avscamera/common/MetadataInternal.h
@@ -18,7 +18,7 @@
created 4/29/2013
**************************************************************************/
-
+#pragma once
enum MetadataId_Custom
@@ -353,3 +353,23 @@ typedef struct _CAMERA_METADATA_INTRINSICS
KS_CAMERA_INTRINSICS Data;
} CAMERA_METADATA_INTRINSICS, *PCAMERA_METADATA_INTRINSICS;
+#if !defined(STATIC_KSPROPERTYSETID_CameraAttributes)
+// Property set implemented by USBVideo.sys and accessed by devproxy
+// {2A3C5205-F9C8-4F78-B110-43D534C0CA64}
+#define STATIC_KSPROPERTYSETID_CameraAttributes \
+ 0x2a3c5205, 0xf9c8, 0x4f78, 0xb1, 0x10, 0x43, 0xd5, 0x34, 0xc0, 0xca, 0x64
+DEFINE_GUIDSTRUCT("2A3C5205-F9C8-4F78-B110-43D534C0CA64", KSPROPERTYSETID_CameraAttributes);
+#define KSPROPERTYSETID_CameraAttributes DEFINE_GUIDNAMED(KSPROPERTYSETID_CameraAttributes)
+
+#define KSPROPERTY_CAMERA_ATTRIBUTES_EXTRINSICS 0
+#define KSPROPERTY_CAMERA_ATTRIBUTES_INTRINSICS 1
+
+#pragma message( "Defining KSCAMERA_ATTRIBUTES_HEADER" )
+
+typedef
+struct _KSCAMERA_ATTRIBUTES_HEADER
+{
+ ULONG Size; // Size of the entire payload including this header.
+ ULONG PinId; // The Pin this payload affects.
+} KSCAMERA_ATTRIBUTES_HEADER, *PKSCAMERA_ATTRIBUTES_HEADER;
+#endif
diff --git a/avstream/avscamera/mft0/MFT0Impl.cpp b/avstream/avscamera/mft0/MFT0Impl.cpp
index e2c07ce3..892160d4 100644
--- a/avstream/avscamera/mft0/MFT0Impl.cpp
+++ b/avstream/avscamera/mft0/MFT0Impl.cpp
@@ -11,7 +11,7 @@
Abstract:
This is the implementation of CSocMft0.
-
+
CSocMft0 is the MFT0 for the AvsCamera sample driver. This MFT0
performs the following key tasks:
1. Filters overscan media types supplied by the driver, and
@@ -54,7 +54,7 @@ STDMETHODIMP CSocMft0::GetState(UINT32 *pState)
// OEM can use similar function to get the status of MFT
// From their own application
- if(!pState)
+ if (!pState)
{
return E_POINTER;
}
@@ -79,13 +79,13 @@ HRESULT CSocMft0::CreateInstance(
auto sObject = Microsoft::WRL::Make<CSocMft0>();
- if(!sObject)
+ if (!sObject)
{
return E_OUTOFMEMORY;
}
hr = sObject->FinalConstruct();
- if(SUCCEEDED(hr))
+ if (SUCCEEDED(hr))
{
hr = sObject.As(&spMFT);
*ppMFT = spMFT.Detach();
@@ -107,12 +107,12 @@ STDMETHODIMP CSocMft0::GetIids(
{
HRESULT hr = S_OK;
- if(!iidCount)
+ if (!iidCount)
{
return E_POINTER;
}
- if(!iids)
+ if (!iids)
{
return E_POINTER;
}
@@ -132,7 +132,7 @@ STDMETHODIMP CSocMft0::GetRuntimeClassName(
)
{
- if(!pClassName)
+ if (!pClassName)
{
return E_POINTER;
}
@@ -149,7 +149,7 @@ STDMETHODIMP CSocMft0::GetTrustLevel(
{
HRESULT hr = S_OK;
- if(trustLevel)
+ if (trustLevel)
{
return E_POINTER;
}
@@ -178,19 +178,19 @@ HRESULT CSocMft0::FinalConstruct()
}
hr = m_spGlobalAttributes->SetString(
- MFT_ENUM_HARDWARE_URL_Attribute,
- L"Sample_CameraExtensionMft");
+ MFT_ENUM_HARDWARE_URL_Attribute,
+ L"Sample_CameraExtensionMft");
if (FAILED(hr))
{
goto done;
}
hr = m_spGlobalAttributes->SetUINT32(
- MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE,
- TRUE);
+ MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE,
+ TRUE);
done:
- if(FAILED(hr))
+ if (FAILED(hr))
{
m_spGlobalAttributes.Reset();
}
@@ -211,10 +211,10 @@ STDMETHODIMP CSocMft0::GetStreamLimits(
_Out_ DWORD *pdwOutputMaximum
)
{
- if( (!pdwInputMinimum) ||
- (!pdwInputMaximum) ||
- (!pdwOutputMinimum) ||
- (!pdwOutputMaximum))
+ if ((!pdwInputMinimum) ||
+ (!pdwInputMaximum) ||
+ (!pdwOutputMinimum) ||
+ (!pdwOutputMaximum))
{
return E_POINTER;
}
@@ -238,7 +238,7 @@ STDMETHODIMP CSocMft0::GetStreamCount(
_Out_ DWORD *pcOutputStreams
)
{
- if(!pcInputStreams || !pcOutputStreams)
+ if (!pcInputStreams || !pcOutputStreams)
{
return E_POINTER;
}
@@ -285,30 +285,26 @@ STDMETHODIMP CSocMft0::GetInputStreamInfo(
_Out_ MFT_INPUT_STREAM_INFO *pStreamInfo
)
{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
CAutoLock lock(&m_critSec);
- if(!pStreamInfo)
+ if (!pStreamInfo)
{
return E_POINTER;
}
- if (!IsValidInputStream(dwInputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
- if(!m_spInputType)
+ if (!m_spInputType)
{
return MF_E_TRANSFORM_TYPE_NOT_SET;
}
- pStreamInfo->hnsMaxLatency = 0;
+ pStreamInfo->hnsMaxLatency = 0;
pStreamInfo->cbAlignment = 0;
pStreamInfo->cbSize = 0;
pStreamInfo->dwFlags =
MFT_INPUT_STREAM_WHOLE_SAMPLES |
MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
- MFT_INPUT_STREAM_PROCESSES_IN_PLACE ;
+ MFT_INPUT_STREAM_PROCESSES_IN_PLACE;
pStreamInfo->hnsMaxLatency = 0;
return S_OK;
@@ -324,19 +320,15 @@ STDMETHODIMP CSocMft0::GetOutputStreamInfo(
_Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
)
{
+ UNREFERENCED_PARAMETER(dwOutputStreamID);
CAutoLock lock(&m_critSec);
- if(!pStreamInfo)
+ if (!pStreamInfo)
{
return E_POINTER;
}
- if (!IsValidInputStream(dwOutputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
- if(!m_spOutputType)
+ if (!m_spOutputType)
{
return MF_E_TRANSFORM_TYPE_NOT_SET;
}
@@ -344,7 +336,7 @@ STDMETHODIMP CSocMft0::GetOutputStreamInfo(
pStreamInfo->cbAlignment = 0;
pStreamInfo->cbSize = 0;
pStreamInfo->dwFlags =
- MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
+ MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
@@ -361,7 +353,7 @@ STDMETHODIMP CSocMft0::GetAttributes(
_Outptr_result_maybenull_ IMFAttributes **ppAttributes
)
{
- if(!ppAttributes)
+ if (!ppAttributes)
{
return E_POINTER;
}
@@ -381,16 +373,16 @@ STDMETHODIMP CSocMft0::GetInputStreamAttributes(
{
HRESULT hr = S_OK;
- if(dwInputStreamID > 0)
+ if (dwInputStreamID > 0)
{
return MF_E_INVALIDSTREAMNUMBER;
}
- if(!ppAttributes)
+ if (!ppAttributes)
{
return E_POINTER;
}
- if(!m_spInputAttributes)
+ if (!m_spInputAttributes)
{
hr = MFCreateAttributes(&m_spInputAttributes, 2);
if (FAILED(hr))
@@ -411,7 +403,7 @@ STDMETHODIMP CSocMft0::GetInputStreamAttributes(
hr = m_spInputAttributes.CopyTo(ppAttributes);
done:
- if(FAILED(hr))
+ if (FAILED(hr))
{
m_spInputAttributes.Reset();
}
@@ -428,17 +420,17 @@ STDMETHODIMP CSocMft0::GetOutputStreamAttributes(
_Outptr_result_maybenull_ IMFAttributes **ppAttributes
)
{
- if(dwOutputStreamID > 0)
+ if (dwOutputStreamID > 0)
{
return MF_E_INVALIDSTREAMNUMBER;
}
- if(!ppAttributes)
+ if (!ppAttributes)
{
return E_POINTER;
}
- if(!m_spInputAttributes)
+ if (!m_spInputAttributes)
{
return MF_E_TRANSFORM_TYPE_NOT_SET;
}
@@ -492,12 +484,8 @@ STDMETHODIMP CSocMft0::GetInputAvailableType(
ComPtr<IMFAttributes> spSourceAttributes;
CAutoLock lock(&m_critSec);
- if(!IsValidInputStream(dwInputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
- if(!m_spSourceTransform && m_spInputAttributes)
+ if (!m_spSourceTransform && m_spInputAttributes)
{
hr = m_spInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(spSourceAttributes.ReleaseAndGetAddressOf()));
if (FAILED(hr))
@@ -558,11 +546,6 @@ STDMETHODIMP CSocMft0::GetOutputAvailableType(
CAutoLock lock(&m_critSec);
- if (!IsValidInputStream(dwOutputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
if (!m_spSourceTransform && m_spInputAttributes)
{
hr = m_spInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(spSourceAttributes.ReleaseAndGetAddressOf()));
@@ -636,19 +619,19 @@ STDMETHODIMP CSocMft0::SetInputType(
// Validate flags.
// Only MFT_SET_TYPE_TEST_ONLY is supported, if any other bit flags
// get set, it should return error.
- if(dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
+ if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
{
return E_INVALIDARG;
}
- if(!bReallySet)
+ if (!bReallySet)
{
return IsMediaTypeSupported(dwInputStreamID, pType);
}
ComPtr<IMFMediaType> spFullType;
hr = IsMediaTypeSupported(dwInputStreamID, pType, spFullType.ReleaseAndGetAddressOf());
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -677,12 +660,12 @@ STDMETHODIMP CSocMft0::SetOutputType(
BOOL bUseModifiedInputType = FALSE;
// Validate flags.
- if(dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
+ if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
{
return E_INVALIDARG;
}
- if(!bReallySet)
+ if (!bReallySet)
{
return IsMediaTypeSupported(dwOutputStreamID, pType);
}
@@ -690,7 +673,7 @@ STDMETHODIMP CSocMft0::SetOutputType(
ComPtr<IMFMediaType> spFullType;
ComPtr<IMFMediaType> spFullInputType;
hr = IsMediaTypeSupported(dwOutputStreamID, pType, spFullType.ReleaseAndGetAddressOf());
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -768,20 +751,17 @@ STDMETHODIMP CSocMft0::GetInputCurrentType(
_Outptr_result_maybenull_ IMFMediaType **ppType
)
{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
HRESULT hr = S_OK;
CAutoLock lock(&m_critSec);
- if(!ppType)
+ if (!ppType)
{
return E_POINTER;
}
- if (!IsValidInputStream(dwInputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
- if(!m_spInputType)
+ if (!m_spInputType)
{
return MF_E_TRANSFORM_TYPE_NOT_SET;
}
@@ -812,20 +792,17 @@ STDMETHODIMP CSocMft0::GetOutputCurrentType(
_Outptr_result_maybenull_ IMFMediaType **ppType
)
{
+ UNREFERENCED_PARAMETER(dwOutputStreamID);
HRESULT hr = S_OK;
CAutoLock lock(&m_critSec);
- if(!ppType)
+ if (!ppType)
{
return E_POINTER;
}
- if (!IsValidOutputStream(dwOutputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
- if(!m_spOutputType)
+ if (!m_spOutputType)
{
return MF_E_TRANSFORM_TYPE_NOT_SET;
}
@@ -856,18 +833,14 @@ STDMETHODIMP CSocMft0::GetInputStatus(
_Out_ DWORD *pdwFlags
)
{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
CAutoLock lock(&m_critSec);
- if(!pdwFlags)
+ if (!pdwFlags)
{
return E_POINTER;
}
- if (!IsValidInputStream(dwInputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
// If we already have an input sample, we don't accept
// another one until the client calls ProcessOutput or Flush.
if (m_spSample == NULL)
@@ -891,7 +864,7 @@ STDMETHODIMP CSocMft0::GetOutputStatus(
_Out_ DWORD *pdwFlags
)
{
- if(!pdwFlags)
+ if (!pdwFlags)
{
return E_POINTER;
}
@@ -981,24 +954,20 @@ STDMETHODIMP CSocMft0::ProcessInput(
DWORD dwFlags
)
{
+ UNREFERENCED_PARAMETER(dwInputStreamID);
HRESULT hr = S_OK;
CAutoLock lock(&m_critSec);
- if(!pSample)
+ if (!pSample)
{
return E_POINTER;
}
- if(dwFlags != 0)
+ if (dwFlags != 0)
{
return E_INVALIDARG;
}
- if (!IsValidInputStream(dwInputStreamID))
- {
- return MF_E_INVALIDSTREAMNUMBER;
- }
-
if (!m_spInputType || !m_spOutputType)
{
return MF_E_NOTACCEPTING; // Client must set input and output types.
@@ -1012,7 +981,7 @@ STDMETHODIMP CSocMft0::ProcessInput(
// Validate the number of buffers. There should only be a single buffer to hold the video frame.
DWORD dwBufferCount = 0;
hr = pSample->GetBufferCount(&dwBufferCount);
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -1049,43 +1018,43 @@ STDMETHODIMP CSocMft0::ProcessOutput(
CAutoLock lock(&m_critSec);
- if(dwFlags != 0)
+ if (dwFlags != 0)
{
return E_INVALIDARG;
}
- if(!pOutputSamples || !pdwStatus)
+ if (!pOutputSamples || !pdwStatus)
{
return E_POINTER;
}
- if( pOutputSamples[0].pSample)
+ if (pOutputSamples[0].pSample)
{
pOutputSamples[0].pSample->Release();
pOutputSamples[0].pSample = nullptr;
}
// Must be exactly one output buffer.
- if(cOutputBufferCount != 1)
+ if (cOutputBufferCount != 1)
{
return E_INVALIDARG;
}
// If we don't have an input sample, we need some input before
// we can generate any output.
- if(m_spSample == nullptr)
+ if (m_spSample == nullptr)
{
return MF_E_TRANSFORM_NEED_MORE_INPUT;
}
hr = ProcessMetadata();
- if(FAILED(hr))
+ if (FAILED(hr))
{
//Log the failure
hr = S_OK;
- }
+ }
hr = CreateOutputSample(&pOutputSamples[0].pSample);
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -1114,7 +1083,7 @@ CreateOutputSample(
HRESULT hr = S_OK;
//Do nothing for now
- if(!ppSample)
+ if (!ppSample)
{
return E_POINTER;
}
@@ -1148,17 +1117,17 @@ STDMETHODIMP CSocMft0::GetMediaType(
HRESULT hr = S_OK;
ComPtr<IMFMediaType> spMediaType;
- if(!ppType)
+ if (!ppType)
{
return E_POINTER;
}
- if(dwStreamId != 0)
+ if (dwStreamId != 0)
{
return MF_E_INVALIDSTREAMNUMBER;
}
- if(dwTypeIndex >= m_listOfMediaTypes.size())
+ if (dwTypeIndex >= m_listOfMediaTypes.size())
{
return MF_E_NO_MORE_TYPES;
}
@@ -1190,48 +1159,48 @@ STDMETHODIMP CSocMft0::IsMediaTypeSupported(
{
HRESULT hr = S_OK;
- if(!pIMFMediaType)
+ if (!pIMFMediaType)
{
return E_POINTER;
}
- if(uiStreamId != 0)
+ if (uiStreamId != 0)
{
return MF_E_INVALIDINDEX;
}
- BOOL bFound =FALSE;
+ BOOL bFound = FALSE;
- for(UINT i = 0; i< m_listOfMediaTypes.size(); i++)
+ for (UINT i = 0; i < m_listOfMediaTypes.size(); i++)
{
DWORD dwResult = 0;
hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult);
- if(hr == S_FALSE)
+ if (hr == S_FALSE)
{
- if((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
- (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
- (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_DATA))
+ if ((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
+ (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
+ (dwResult& MF_MEDIATYPE_EQUAL_FORMAT_DATA))
{
hr = S_OK;
}
}
- if(hr == S_OK)
+ if (hr == S_OK)
{
bFound = TRUE;
- if(ppIMFMediaTypeFull)
+ if (ppIMFMediaTypeFull)
{
m_listOfMediaTypes[i].CopyTo(ppIMFMediaTypeFull);
}
break;
}
- else if(FAILED(hr))
+ else if (FAILED(hr))
{
return hr;
}
}
- if(bFound == FALSE)
+ if (bFound == FALSE)
{
return MF_E_INVALIDMEDIATYPE;
}
@@ -1252,44 +1221,44 @@ STDMETHODIMP CSocMft0::FindMediaIndex(
{
HRESULT hr = S_OK;
- if(!pIMFMediaType || !puiMediaIndex)
+ if (!pIMFMediaType || !puiMediaIndex)
{
return E_INVALIDARG;
}
- if(uiStreamId != 0)
+ if (uiStreamId != 0)
{
return MF_E_INVALIDINDEX;
}
BOOL bFound = FALSE;
- for(UINT i = 0; i< m_listOfMediaTypes.size(); i++)
+ for (UINT i = 0; i < m_listOfMediaTypes.size(); i++)
{
DWORD dwResult = 0;
hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult);
- if(hr == S_FALSE)
+ if (hr == S_FALSE)
{
- if((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
- (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
- (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_DATA))
+ if ((dwResult & MF_MEDIATYPE_EQUAL_MAJOR_TYPES) &&
+ (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_TYPES) &&
+ (dwResult & MF_MEDIATYPE_EQUAL_FORMAT_DATA))
{
hr = S_OK;
}
}
- if(hr == S_OK)
+ if (hr == S_OK)
{
bFound = TRUE;
*puiMediaIndex = i;
break;
}
- else if(FAILED(hr))
+ else if (FAILED(hr))
{
return hr;
}
}
- if(bFound == FALSE)
+ if (bFound == FALSE)
{
return MF_E_INVALIDMEDIATYPE;
}
@@ -1305,27 +1274,27 @@ STDMETHODIMP CSocMft0::GenerateMFMediaTypeListFromDevice()
{
HRESULT hr = S_OK;
- if(!m_spSourceTransform)
+ if (!m_spSourceTransform)
{
return MF_E_NOT_FOUND;
}
m_listOfMediaTypes.clear();
UINT iMediaType = 0;
- while(SUCCEEDED(hr))
+ while (SUCCEEDED(hr))
{
ComPtr<IMFMediaType> spMediaType;
hr = m_spSourceTransform->GetOutputAvailableType(m_uiSourceStreamId, iMediaType, spMediaType.ReleaseAndGetAddressOf());
- if(FAILED(hr))
+ if (FAILED(hr))
{
- if(hr == MF_E_NO_MORE_TYPES)
+ if (hr == MF_E_NO_MORE_TYPES)
{
hr = S_OK;
}
break;
}
- if(m_stStreamType == PINNAME_IMAGE || m_stStreamType == PINNAME_VIDEO_STILL)
+ if (m_stStreamType == PINNAME_IMAGE || m_stStreamType == PINNAME_VIDEO_STILL)
{
GUID guidPhotoSubType = {};
spMediaType->GetGUID(MF_MT_SUBTYPE, &guidPhotoSubType);
@@ -1339,7 +1308,7 @@ STDMETHODIMP CSocMft0::GenerateMFMediaTypeListFromDevice()
}
}
-
+
m_listOfMediaTypes.push_back(spMediaType);
}
@@ -1389,42 +1358,42 @@ HRESULT CSocMft0::GetPreviewMediaType(
)
{
CAutoLock lock(&m_critSec);
- if(!m_spSourceTransform)
+ if (!m_spSourceTransform)
{
return MF_E_NOT_FOUND;
}
DWORD dwInStreamCount = 0, dwOutStreamCount = 0;
HRESULT hr = m_spSourceTransform->GetStreamCount(
- &dwInStreamCount,
- &dwOutStreamCount);
+ &dwInStreamCount,
+ &dwOutStreamCount);
if (FAILED(hr))
{
return hr;
}
- for(UINT32 i = 0 ; i < dwOutStreamCount; i++)
+ for (UINT32 i = 0; i < dwOutStreamCount; i++)
{
ComPtr<IMFAttributes> spAttributes;
hr = m_spSourceTransform->GetOutputStreamAttributes(i, spAttributes.ReleaseAndGetAddressOf());
- if(FAILED(hr))
+ if (FAILED(hr))
{
continue;
}
GUID guidPinCategory = GUID_NULL;
hr = spAttributes->GetGUID(
- MF_DEVICESTREAM_STREAM_CATEGORY,
- &guidPinCategory);
- if(FAILED(hr))
+ MF_DEVICESTREAM_STREAM_CATEGORY,
+ &guidPinCategory);
+ if (FAILED(hr))
{
continue;
}
if (IsEqualGUID(guidPinCategory, PINNAME_VIDEO_PREVIEW))
{
ComPtr<IMFMediaType> spMediaType;
- hr = m_spSourceTransform->GetOutputCurrentType(i, spMediaType.ReleaseAndGetAddressOf());
- if(FAILED(hr))
+ hr = m_spSourceTransform->GetOutputCurrentType(i, spMediaType.ReleaseAndGetAddressOf());
+ if (FAILED(hr))
{
return MF_E_NOT_FOUND;
}
@@ -1443,14 +1412,14 @@ HRESULT CSocMft0::ProcessMetadata()
{
ComPtr<IMFAttributes> spMetadata;
HRESULT hr = m_spSample->GetUnknown(MFSampleExtension_CaptureMetadata, IID_PPV_ARGS(spMetadata.ReleaseAndGetAddressOf()));
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
ComPtr<IMFMediaBuffer> spBuffer;
hr = spMetadata->GetUnknown(MF_CAPTURE_METADATA_FRAME_RAWSTREAM, IID_PPV_ARGS(spBuffer.ReleaseAndGetAddressOf()));
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -1459,46 +1428,46 @@ HRESULT CSocMft0::ProcessMetadata()
BYTE *pData = NULL;
DWORD dwLength = 0;
hr = bufferLock.LockBuffer(&pData, NULL, &dwLength);
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
// OEM put meta data passing logic here,
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
LONG lBufferLeft = static_cast<LONG>(dwLength);
- if(lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
+ if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
{
return E_UNEXPECTED;
}
- PKSCAMERA_METADATA_ITEMHEADER pItem = (PKSCAMERA_METADATA_ITEMHEADER) pData;
+ PKSCAMERA_METADATA_ITEMHEADER pItem = (PKSCAMERA_METADATA_ITEMHEADER)pData;
- while(lBufferLeft > 0)
+ while (lBufferLeft > 0)
{
switch (pItem->MetadataId)
{
case MetadataId_Custom_PreviewAggregation:
hr = ParseMetadata_PreviewAggregation(pItem, spMetadata.Get());
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
break;
case MetadataId_Custom_ImageAggregation:
hr = ParseMetadata_ImageAggregation(pItem, spMetadata.Get());
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
break;
case MetadataId_Custom_Histogram:
hr = ParseMetadata_Histogram(pItem, spMetadata.Get());
- if(FAILED(hr))
+ if (FAILED(hr))
{
return hr;
}
@@ -1511,22 +1480,22 @@ HRESULT CSocMft0::ProcessMetadata()
}
}
- if(!pItem->Size)
+ if (!pItem->Size)
{
// 0 size item will cause the loop to break and
// we will report buffer malformated
break;
}
lBufferLeft -= (LONG)pItem->Size;
- if(lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
+ if (lBufferLeft < sizeof(KSCAMERA_METADATA_ITEMHEADER))
{
break;
}
pItem = reinterpret_cast<PKSCAMERA_METADATA_ITEMHEADER>
- (reinterpret_cast<PBYTE>(pItem) + pItem->Size);
+ (reinterpret_cast<PBYTE>(pItem) + pItem->Size);
}
- if(lBufferLeft != 0)
+ if (lBufferLeft != 0)
{
//Check and log for malformated data
return E_UNEXPECTED;
@@ -1541,7 +1510,7 @@ HRESULT CSocMft0::ParseMetadata_PreviewAggregation(
)
{
HRESULT hr = S_OK;
- if(pItem->Size < sizeof(CAMERA_METADATA_PREVIEWAGGREGATION))
+ if (pItem->Size < sizeof(CAMERA_METADATA_PREVIEWAGGREGATION))
{
return E_UNEXPECTED;
}
@@ -1560,62 +1529,62 @@ HRESULT CSocMft0::ParseMetadata_PreviewAggregation(
}
}
- if(pFixedStruct->Data.ExposureTime.Set)
+ if (pFixedStruct->Data.ExposureTime.Set)
{
hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_EXPOSURE_TIME,
- pFixedStruct->Data.ExposureTime.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_EXPOSURE_TIME,
+ pFixedStruct->Data.ExposureTime.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.ISOSpeed.Set)
+ if (pFixedStruct->Data.ISOSpeed.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ISO_SPEED,
- pFixedStruct->Data.ISOSpeed.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_ISO_SPEED,
+ pFixedStruct->Data.ISOSpeed.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.LensPosition.Set)
+ if (pFixedStruct->Data.LensPosition.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_LENS_POSITION,
- pFixedStruct->Data.LensPosition.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_LENS_POSITION,
+ pFixedStruct->Data.LensPosition.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.FlashOn.Set)
+ if (pFixedStruct->Data.FlashOn.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH,
- pFixedStruct->Data.FlashOn.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_FLASH,
+ pFixedStruct->Data.FlashOn.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.WhiteBalanceMode.Set)
+ if (pFixedStruct->Data.WhiteBalanceMode.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_WHITEBALANCE,
- pFixedStruct->Data.WhiteBalanceMode.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_WHITEBALANCE,
+ pFixedStruct->Data.WhiteBalanceMode.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.EVCompensation.Set)
+ if (pFixedStruct->Data.EVCompensation.Set)
{
CapturedMetadataExposureCompensation EVCompensation;
@@ -1623,84 +1592,84 @@ HRESULT CSocMft0::ParseMetadata_PreviewAggregation(
EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
- (const UINT8 *)&EVCompensation,
- sizeof(EVCompensation));
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
+ (const UINT8 *)&EVCompensation,
+ sizeof(EVCompensation));
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.SensorFrameRate.Set)
+ if (pFixedStruct->Data.SensorFrameRate.Set)
{
hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_SENSORFRAMERATE,
- pFixedStruct->Data.SensorFrameRate.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_SENSORFRAMERATE,
+ pFixedStruct->Data.SensorFrameRate.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if( pFixedStruct->Data.IsoAnalogGain.Set ||
- pFixedStruct->Data.IsoDigitalGain.Set )
+ if (pFixedStruct->Data.IsoAnalogGain.Set ||
+ pFixedStruct->Data.IsoDigitalGain.Set)
{
CapturedMetadataISOGains IsoGains;
- if( pFixedStruct->Data.IsoAnalogGain.Set )
+ if (pFixedStruct->Data.IsoAnalogGain.Set)
{
IsoGains.AnalogGain =
- FLOAT( pFixedStruct->Data.IsoAnalogGain.Numerator ) /
- FLOAT( pFixedStruct->Data.IsoAnalogGain.Denominator );
+ FLOAT(pFixedStruct->Data.IsoAnalogGain.Numerator) /
+ FLOAT(pFixedStruct->Data.IsoAnalogGain.Denominator);
}
- if( pFixedStruct->Data.IsoDigitalGain.Set )
+ if (pFixedStruct->Data.IsoDigitalGain.Set)
{
IsoGains.DigitalGain =
- FLOAT( pFixedStruct->Data.IsoDigitalGain.Numerator ) /
- FLOAT( pFixedStruct->Data.IsoDigitalGain.Denominator );
+ FLOAT(pFixedStruct->Data.IsoDigitalGain.Numerator) /
+ FLOAT(pFixedStruct->Data.IsoDigitalGain.Denominator);
}
hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_ISO_GAINS,
- (const UINT8 *)&IsoGains,
- sizeof(IsoGains));
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_ISO_GAINS,
+ (const UINT8 *)&IsoGains,
+ sizeof(IsoGains));
+ if (FAILED(hr))
{
return hr;
}
}
- if( pFixedStruct->Data.WhiteBalanceGain_R.Set ||
- pFixedStruct->Data.WhiteBalanceGain_G.Set ||
- pFixedStruct->Data.WhiteBalanceGain_B.Set )
+ if (pFixedStruct->Data.WhiteBalanceGain_R.Set ||
+ pFixedStruct->Data.WhiteBalanceGain_G.Set ||
+ pFixedStruct->Data.WhiteBalanceGain_B.Set)
{
CapturedMetadataWhiteBalanceGains WhiteBalanceGains;
- if( pFixedStruct->Data.WhiteBalanceGain_R.Set )
+ if (pFixedStruct->Data.WhiteBalanceGain_R.Set)
{
WhiteBalanceGains.R =
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_R.Numerator ) /
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_R.Denominator );
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_R.Denominator);
}
- if( pFixedStruct->Data.WhiteBalanceGain_G.Set )
+ if (pFixedStruct->Data.WhiteBalanceGain_G.Set)
{
WhiteBalanceGains.G =
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_G.Numerator ) /
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_G.Denominator );
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_G.Denominator);
}
- if( pFixedStruct->Data.WhiteBalanceGain_B.Set )
+ if (pFixedStruct->Data.WhiteBalanceGain_B.Set)
{
WhiteBalanceGains.B =
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_B.Numerator ) /
- FLOAT( pFixedStruct->Data.WhiteBalanceGain_B.Denominator );
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Numerator) /
+ FLOAT(pFixedStruct->Data.WhiteBalanceGain_B.Denominator);
}
hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_WHITEBALANCE_GAINS,
- (const UINT8 *)&WhiteBalanceGains,
- sizeof(WhiteBalanceGains));
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_WHITEBALANCE_GAINS,
+ (const UINT8 *)&WhiteBalanceGains,
+ sizeof(WhiteBalanceGains));
+ if (FAILED(hr))
{
return hr;
}
@@ -1715,7 +1684,7 @@ HRESULT CSocMft0::ParseMetadata_ImageAggregation(
)
{
HRESULT hr = S_OK;
- if(pItem->Size < sizeof(CAMERA_METADATA_IMAGEAGGREGATION))
+ if (pItem->Size < sizeof(CAMERA_METADATA_IMAGEAGGREGATION))
{
return E_UNEXPECTED;
}
@@ -1723,106 +1692,106 @@ HRESULT CSocMft0::ParseMetadata_ImageAggregation(
PCAMERA_METADATA_IMAGEAGGREGATION pFixedStruct =
(PCAMERA_METADATA_IMAGEAGGREGATION)pItem;
- if(pFixedStruct->Data.FrameId.Set)
+ if (pFixedStruct->Data.FrameId.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_REQUESTED_FRAME_SETTING_ID,
- pFixedStruct->Data.FrameId.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_REQUESTED_FRAME_SETTING_ID,
+ pFixedStruct->Data.FrameId.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.ExposureTime.Set)
+ if (pFixedStruct->Data.ExposureTime.Set)
{
hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_EXPOSURE_TIME,
- pFixedStruct->Data.ExposureTime.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_EXPOSURE_TIME,
+ pFixedStruct->Data.ExposureTime.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.ISOSpeed.Set)
+ if (pFixedStruct->Data.ISOSpeed.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ISO_SPEED,
- pFixedStruct->Data.ISOSpeed.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_ISO_SPEED,
+ pFixedStruct->Data.ISOSpeed.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.LensPosition.Set)
+ if (pFixedStruct->Data.LensPosition.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_LENS_POSITION,
- pFixedStruct->Data.LensPosition.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_LENS_POSITION,
+ pFixedStruct->Data.LensPosition.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.SceneMode.Set)
+ if (pFixedStruct->Data.SceneMode.Set)
{
hr = pMetaDataAttributes->SetUINT64(
- MF_CAPTURE_METADATA_SCENE_MODE,
- pFixedStruct->Data.SceneMode.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_SCENE_MODE,
+ pFixedStruct->Data.SceneMode.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.FlashOn.Set)
+ if (pFixedStruct->Data.FlashOn.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH,
- pFixedStruct->Data.FlashOn.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_FLASH,
+ pFixedStruct->Data.FlashOn.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.FlashPower.Set)
+ if (pFixedStruct->Data.FlashPower.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FLASH_POWER,
- pFixedStruct->Data.FlashPower.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_FLASH_POWER,
+ pFixedStruct->Data.FlashPower.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.WhiteBalanceMode.Set)
+ if (pFixedStruct->Data.WhiteBalanceMode.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_WHITEBALANCE,
- pFixedStruct->Data.WhiteBalanceMode.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_WHITEBALANCE,
+ pFixedStruct->Data.WhiteBalanceMode.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.ZoomFactor.Set)
+ if (pFixedStruct->Data.ZoomFactor.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_ZOOMFACTOR,
- pFixedStruct->Data.ZoomFactor.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_ZOOMFACTOR,
+ pFixedStruct->Data.ZoomFactor.Value);
+ if (FAILED(hr))
{
return hr;
}
}
- if(pFixedStruct->Data.EVCompensation.Set)
+ if (pFixedStruct->Data.EVCompensation.Set)
{
CapturedMetadataExposureCompensation EVCompensation;
@@ -1830,21 +1799,21 @@ HRESULT CSocMft0::ParseMetadata_ImageAggregation(
EVCompensation.Value = pFixedStruct->Data.EVCompensation.Value;
hr = pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
- (const UINT8 *)&EVCompensation,
- sizeof(EVCompensation));
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_EXPOSURE_COMPENSATION,
+ (const UINT8 *)&EVCompensation,
+ sizeof(EVCompensation));
+ if (FAILED(hr))
{
return hr;
}
}
- if( pFixedStruct->Data.FocusState.Set )
+ if (pFixedStruct->Data.FocusState.Set)
{
hr = pMetaDataAttributes->SetUINT32(
- MF_CAPTURE_METADATA_FOCUSSTATE,
- pFixedStruct->Data.FocusState.Value);
- if(FAILED(hr))
+ MF_CAPTURE_METADATA_FOCUSSTATE,
+ pFixedStruct->Data.FocusState.Value);
+ if (FAILED(hr))
{
return hr;
}
@@ -1862,7 +1831,7 @@ struct HistogramData
Header.Size = sizeof(*this);
Header.ChannelMask = 0;
Header.Linear = 1;
- RtlZeroMemory( Color, sizeof(Color) );
+ RtlZeroMemory(Color, sizeof(Color));
}
};
@@ -1876,8 +1845,8 @@ struct Histogram
HistogramData Data[I];
Histogram(
- _In_ ULONG Width=0,
- _In_ ULONG Height=0
+ _In_ ULONG Width = 0,
+ _In_ ULONG Height = 0
)
{
Blob.Histograms = 1;
@@ -1889,8 +1858,8 @@ struct Histogram
Header.Grid.Width = Width;
Header.Grid.Region.top = 0;
Header.Grid.Region.left = 0;
- Header.Grid.Region.bottom = Height-1;
- Header.Grid.Region.right = Width-1;
+ Header.Grid.Region.bottom = Height - 1;
+ Header.Grid.Region.right = Width - 1;
}
};
@@ -1902,58 +1871,58 @@ HRESULT CSocMft0::ParseMetadata_Histogram(
_In_ IMFAttributes *pMetaDataAttributes
)
{
- if(pItem->Size < sizeof(CAMERA_METADATA_HISTOGRAM))
+ if (pItem->Size < sizeof(CAMERA_METADATA_HISTOGRAM))
{
return E_UNEXPECTED;
}
- PCAMERA_METADATA_HISTOGRAM pHistogram = (PCAMERA_METADATA_HISTOGRAM) pItem;
+ PCAMERA_METADATA_HISTOGRAM pHistogram = (PCAMERA_METADATA_HISTOGRAM)pItem;
- if( (pHistogram->Data.ChannelMask & MF_HISTOGRAM_RGB) == MF_HISTOGRAM_RGB )
+ if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_RGB) == MF_HISTOGRAM_RGB)
{
- Histogram<4> Blob( pHistogram->Data.Width, pHistogram->Data.Height );
+ Histogram<4> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
Blob.Header.FourCC = pHistogram->Data.FourCC;
Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
// For a RGB Histogram, we fake the Y channel by copying the G channel.
Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
- RtlCopyMemory( Blob.Data[0].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[0].Color) );
+ RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[0].Color));
// Now just copy the RGB channels normally.
Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_R;
- RtlCopyMemory( Blob.Data[1].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[1].Color) );
+ RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[1].Color));
Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_G;
- RtlCopyMemory( Blob.Data[2].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[2].Color) );
+ RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[2].Color));
Blob.Data[3].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_B;
- RtlCopyMemory( Blob.Data[3].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[3].Color) );
+ RtlCopyMemory(Blob.Data[3].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[3].Color));
return pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_HISTOGRAM,
- (PBYTE) &Blob,
- sizeof(Blob)
- );
+ MF_CAPTURE_METADATA_HISTOGRAM,
+ (PBYTE)&Blob,
+ sizeof(Blob)
+ );
}
- else if( (pHistogram->Data.ChannelMask & MF_HISTOGRAM_YCrCb) == MF_HISTOGRAM_YCrCb )
+ else if ((pHistogram->Data.ChannelMask & MF_HISTOGRAM_YCrCb) == MF_HISTOGRAM_YCrCb)
{
- Histogram<3> Blob( pHistogram->Data.Width, pHistogram->Data.Height );
+ Histogram<3> Blob(pHistogram->Data.Width, pHistogram->Data.Height);
Blob.Header.FourCC = pHistogram->Data.FourCC;
Blob.Header.ChannelMasks = pHistogram->Data.ChannelMask;
Blob.Data[0].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Y;
- RtlCopyMemory( Blob.Data[0].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[0].Color) );
+ RtlCopyMemory(Blob.Data[0].Color, pHistogram->Data.P0Data, sizeof(Blob.Data[0].Color));
Blob.Data[1].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cr;
- RtlCopyMemory( Blob.Data[1].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[1].Color) );
+ RtlCopyMemory(Blob.Data[1].Color, pHistogram->Data.P1Data, sizeof(Blob.Data[1].Color));
Blob.Data[2].Header.ChannelMask = MF_HISTOGRAM_CHANNEL_Cb;
- RtlCopyMemory( Blob.Data[2].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[2].Color) );
+ RtlCopyMemory(Blob.Data[2].Color, pHistogram->Data.P2Data, sizeof(Blob.Data[2].Color));
//TODO:
return pMetaDataAttributes->SetBlob(
- MF_CAPTURE_METADATA_HISTOGRAM,
- (PBYTE) &Blob,
- sizeof(Blob)
- );
+ MF_CAPTURE_METADATA_HISTOGRAM,
+ (PBYTE)&Blob,
+ sizeof(Blob)
+ );
}
return E_UNEXPECTED;
}
@@ -1972,13 +1941,13 @@ HRESULT CSocMft0::ParseMetadata_FaceDetection(
PCAMERA_METADATA_FACEHEADER pFaceHeader = (PCAMERA_METADATA_FACEHEADER)pItem;
- if( pItem->Size < (sizeof(CAMERA_METADATA_FACEHEADER) + (sizeof(METADATA_FACEDATA) * pFaceHeader->Count)) )
+ if (pItem->Size < (sizeof(CAMERA_METADATA_FACEHEADER) + (sizeof(METADATA_FACEDATA) * pFaceHeader->Count)))
{
return E_UNEXPECTED;
}
- PMETADATA_FACEDATA pFaceData = (PMETADATA_FACEDATA) (pFaceHeader+1);
+ PMETADATA_FACEDATA pFaceData = (PMETADATA_FACEDATA)(pFaceHeader + 1);
UINT32 cbRectSize = sizeof(FaceRectInfoBlobHeader) + (sizeof(FaceRectInfo) * (pFaceHeader->Count));
- BYTE *pRectBuf = new BYTE [cbRectSize];
+ BYTE *pRectBuf = new BYTE[cbRectSize];
if (pRectBuf == NULL)
{
return E_OUTOFMEMORY;
@@ -1988,7 +1957,7 @@ HRESULT CSocMft0::ParseMetadata_FaceDetection(
BYTE *pCharBuf = new BYTE[cbCharSize];
if (pCharBuf == NULL)
{
- delete [] pRectBuf;
+ delete[] pRectBuf;
return E_OUTOFMEMORY;
}
@@ -2001,21 +1970,21 @@ HRESULT CSocMft0::ParseMetadata_FaceDetection(
pFaceCharHeader->Count = pFaceHeader->Count;
FaceRectInfo *FaceRegions = (FaceRectInfo *)(pFaceRectHeader + 1);
- FaceCharacterization *FaceChars = (FaceCharacterization *) (pFaceCharHeader + 1);
+ FaceCharacterization *FaceChars = (FaceCharacterization *)(pFaceCharHeader + 1);
for (UINT i = 0; i < pFaceHeader->Count; i++)
{
FaceRegions[i].Region = pFaceData[i].Region;
FaceRegions[i].confidenceLevel = pFaceData[i].confidenceLevel;
- FaceChars[i].BlinkScoreLeft = pFaceData[i].BlinkScoreLeft;
+ FaceChars[i].BlinkScoreLeft = pFaceData[i].BlinkScoreLeft;
FaceChars[i].BlinkScoreRight = pFaceData[i].BlinkScoreRight;
- FaceChars[i].FacialExpression = (pFaceData[i].FacialExpression==EXPRESSION_SMILE)?MF_METADATAFACIALEXPRESSION_SMILE:0;
+ FaceChars[i].FacialExpression = (pFaceData[i].FacialExpression == EXPRESSION_SMILE) ? MF_METADATAFACIALEXPRESSION_SMILE : 0;
FaceChars[i].FacialExpressionScore = pFaceData[i].FacialExpressionScore;
}
hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROIS, pRectBuf, cbRectSize);
- if( FAILED(hr) )
+ if (FAILED(hr))
{
goto done;
}
@@ -2025,20 +1994,20 @@ HRESULT CSocMft0::ParseMetadata_FaceDetection(
timestamp.Device = pFaceHeader->Timestamp;
hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROITIMESTAMPS, (const UINT8 *)&timestamp, sizeof(MetadataTimeStamps));
- if( FAILED(hr) )
+ if (FAILED(hr))
{
goto done;
}
// Include characterization data if any of the associated bits were set.
- if( pFaceHeader->Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK )
+ if (pFaceHeader->Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK)
{
- hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROICHARACTERIZATIONS , pCharBuf, cbCharSize);
+ hr = pMetaDataAttributes->SetBlob(MF_CAPTURE_METADATA_FACEROICHARACTERIZATIONS, pCharBuf, cbCharSize);
}
done:
- delete [] pRectBuf;
- delete [] pCharBuf;
+ delete[] pRectBuf;
+ delete[] pCharBuf;
return hr;
}
@@ -2048,13 +2017,13 @@ HRESULT CSocMft0::FillBufferLengthFromMediaType(
_Inout_ IMFMediaBuffer *pBuffer
)
{
- if(!pPreviewType || !pBuffer)
+ if (!pPreviewType || !pBuffer)
{
return E_INVALIDARG;
}
UINT32 uiWidth = 0, uiHeight = 0, uiImageSize = 0;
- GUID guidSubType= {};
+ GUID guidSubType = {};
HRESULT hr = MFGetAttributeSize(pPreviewType, MF_MT_FRAME_SIZE, &uiWidth, &uiHeight);
if (FAILED(hr))
diff --git a/avstream/avscamera/mft0/MFT0Impl.h b/avstream/avscamera/mft0/MFT0Impl.h
index 9112a345..a73e8c0d 100644
--- a/avstream/avscamera/mft0/MFT0Impl.h
+++ b/avstream/avscamera/mft0/MFT0Impl.h
@@ -239,18 +239,6 @@ protected:
return m_spSample != NULL;
}
- // IsValidInputStream: Returns TRUE if dwInputStreamID is a valid input stream identifier.
- BOOL IsValidInputStream(DWORD dwInputStreamID) const
- {
- return dwInputStreamID == 0;
- }
-
- // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier.
- BOOL IsValidOutputStream(DWORD dwOutputStreamID) const
- {
- return dwOutputStreamID == 0;
- }
-
HRESULT CreateOutputSample(
_Outptr_result_maybenull_ IMFSample **ppSample
);
diff --git a/avstream/avscamera/sys/AvsCamera.vcxproj b/avstream/avscamera/sys/AvsCamera.vcxproj
index d46c7277..326b1848 100644
--- a/avstream/avscamera/sys/AvsCamera.vcxproj
+++ b/avstream/avscamera/sys/AvsCamera.vcxproj
@@ -146,16 +146,16 @@
</Midl>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION>
+ <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION>
+ <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION>
+ <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION>
+ <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
diff --git a/avstream/avscamera/sys/AvsCameraFilter.cpp b/avstream/avscamera/sys/AvsCameraFilter.cpp
index bff6466f..af25b691 100644
--- a/avstream/avscamera/sys/AvsCameraFilter.cpp
+++ b/avstream/avscamera/sys/AvsCameraFilter.cpp
@@ -229,7 +229,8 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItems)
DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_HISTOGRAM, CExtendedProperty, Histogram ),
DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_OIS, CExtendedProperty, OpticalImageStabilization ),
DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO, CExtendedProperty, AdvancedPhoto ),
- DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE, CExtendedProfile, CameraProfile )
+ DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE, CExtendedProfile, CameraProfile ),
+ DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING, CExtendedProperty, VideoTemporalDenoising)
};
// Front-facing cameras often have limited capabilities. One way to express that is to use a restricted automation table such as this one.
diff --git a/avstream/avscamera/sys/CameraSimulatorCommon.h b/avstream/avscamera/sys/CameraSimulatorCommon.h
new file mode 100644
index 00000000..f1e300b0
--- /dev/null
+++ b/avstream/avscamera/sys/CameraSimulatorCommon.h
@@ -0,0 +1,391 @@
+/**************************************************************************
+
+A/V Stream Camera Sample
+
+Copyright (c) 2017, Microsoft Corporation.
+
+File:
+
+CameraSimulatorCommon.h
+
+Abstract:
+
+Common header applicable for all camera simulators.
+
+History:
+
+created 06/05/2017
+
+**************************************************************************/
+
+#pragma once
+#pragma warning (disable : 4100 4127 4131 4189 4701 4706)
+
+#define IFFAILED_EXIT(status) \
+ if (!NT_SUCCESS( Status = (status) )) \
+ { \
+ goto done; \
+ }
+
+#define IFNULL_EXIT(exp) \
+ if ( (exp) == nullptr ) \
+ { \
+ Status = STATUS_INSUFFICIENT_RESOURCES; \
+ goto done; \
+ }
+
+//
+// Number of 100ns in one second
+//
+#define ONESECOND 10000000
+
+#define ABS(x) ((x) < 0 ? (-(x)) : (x))
+
+#ifndef mmioFOURCC
+#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
+ ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
+ ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
+#endif
+
+#define FOURCC_YUY2 mmioFOURCC('Y', 'U', 'Y', '2')
+#define FOURCC_NV12 mmioFOURCC('N', 'V', '1', '2')
+
+#define AVSCAM_SIZE_VIDEOHEADER2(pbmi) ((pbmi)->bmiHeader.biSize + FIELD_OFFSET(KS_VIDEOINFOHEADER2,bmiHeader))
+
+// RGB24
+#define STATIC_KSDATAFORMAT_SUBTYPE_RGB24\
+ 0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70
+DEFINE_GUIDSTRUCT("e436eb7d-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB24);
+#define KSDATAFORMAT_SUBTYPE_RGB24 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB24)
+
+// RGB32
+#define STATIC_KSDATAFORMAT_SUBTYPE_RGB32\
+ 0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70
+DEFINE_GUIDSTRUCT("e436eb7e-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB32);
+#define KSDATAFORMAT_SUBTYPE_RGB32 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB32)
+
+// NV12
+#define STATIC_KSDATAFORMAT_SUBTYPE_NV12\
+ 0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("3231564E-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_NV12);
+#define KSDATAFORMAT_SUBTYPE_NV12 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NV12)
+
+// YUY2
+#define STATIC_KSDATAFORMAT_SUBTYPE_YUY2\
+ 0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_YUY2);
+#define KSDATAFORMAT_SUBTYPE_YUY2 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_YUY2)
+
+//Arbitrary Maximum faces
+#define MAX_FACES 15
+
+//
+// Define the number of frames needed in the queue for image capture.
+//
+#define IMAGE_CAPTURE_PIN_MINIMUM_FRAMES 3
+#define IMAGE_CAPTURE_PIN_MAXIMUM_FRAMES 20
+#define IMAGE_CAPTURE_PIN_MAXIMUM_HISTORY_FRAMES 10
+
+#define AVSHWS_POOLTAG 'hSVA'
+
+//
+// Focal length definitions
+//
+// These are the definitions found in MSDN for the legacy zoom controls.
+//
+//#define FOCALLENGTH_OCULAR 50
+//#define FOCALLENGTH_OPTICAL_MIN 10
+//#define FOCALLENGTH_OPTICAL_MAX 600
+//
+// Note: Despite what MSDN says, they are NOT limits as far as the
+// pipeline is conerned. You should supply values here that are
+// appropriate to your hardware - whatever that may be.
+//
+// Also note that since both optical and ocular focal length are
+// nomally measured in millimeters, and since the optical length is
+// always the numerator and ocular is used as the denominator, the
+// units (millimeters) cancel out. This means you can stick any set
+// of values you like here that can be used to represent the min and
+// maximum zoom value of your hardware as a simple rational number.
+//
+// Again, the rational number is: (Objective length / Ocular length)
+//
+// We use the following definitions in this simulation in order to have the
+// values produced and used in the legacy control be the same as the ones
+// in the new extended zoom control.
+//
+#define FOCALLENGTH_OCULAR (1<<16) // Denominator of 2^16 makes this the same as Q16 format in extended.
+#define FOCALLENGTH_OPTICAL_MIN (FOCALLENGTH_OCULAR/16) // Allow a wide-field view of 1/16th.
+#define FOCALLENGTH_OPTICAL_MAX (FOCALLENGTH_OCULAR*32) // Allow a zoom-in view of 32x.
+
+//
+// Values for Power Line Frequency
+//
+#define POWERLINEFREQ_DISABLED 0
+#define POWERLINEFREQ_50HZ 1
+#define POWERLINEFREQ_60HZ 2
+#define POWERLINEFREQ_AUTO 3
+#define POWERLINEFREQ_DEFAULT POWERLINEFREQ_DISABLED
+
+//
+// Q-format definitions.
+//
+#define BASE_Q(n) (((ULONGLONG)1)<<n)
+#define TO_Q31(_x_) (LONGLONG)( (_x_) * BASE_Q(31) )
+#define TO_Q16(_x_) (LONGLONG)( (_x_) * BASE_Q(16) )
+#define FROM_Q16(_x_, _denominator_) ((LONG)( (LONGLONG)(_x_) / ( TO_Q16(1) / (LONGLONG)(_denominator_)) ))
+
+#define MULT_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_) * (LONGLONG)(_y_)) + (BASE_Q(15)))>>16)
+#define DIV_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_)<<16)+(_y_/2))/(LONGLONG)(_y_))
+
+#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
+#define MAKEDWORD(l, h) ( ( DWORD ) ( ( ( WORD ) ( l ) ) | ( ( DWORD ) ( ( WORD ) ( h ) ) ) << 16 ) )
+#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
+
+//
+// Copy of histogram channel bitmask definitions from mfapi.h (not available in wdk).
+//
+#define MF_HISTOGRAM_CHANNEL_Y 0x00000001
+#define MF_HISTOGRAM_CHANNEL_R 0x00000002
+#define MF_HISTOGRAM_CHANNEL_G 0x00000004
+#define MF_HISTOGRAM_CHANNEL_B 0x00000008
+#define MF_HISTOGRAM_CHANNEL_Cb 0x00000010
+#define MF_HISTOGRAM_CHANNEL_Cr 0x00000020
+
+/*************************************************
+
+ Enums / Typedefs
+
+*************************************************/
+
+typedef enum _PIN_STATE
+{
+
+ PinStopped = 0,
+ PinPaused,
+ PinRunning
+
+} PIN_STATE, *PPIN_STATE;
+
+typedef enum _PIN_MODE
+{
+
+ PinNormalMode = 0,
+ PinBurstMode
+
+} PIN_MODE, *PPIN_MODE;
+
+/*************************************************
+
+ Struct / Class Definitions
+
+*************************************************/
+
+struct ISP_FRAME_SETTINGS
+{
+ ULONGLONG ISOMode;
+ ULONG ISOValue; // for Manual ISO settings.
+ KSCAMERA_EXTENDEDPROP_EVCOMPENSATION EVCompensation;
+ ULONGLONG WhiteBalanceMode;
+ KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING WhiteBalanceSetting;
+ ULONGLONG ExposureMode;
+ KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING ExposureSetting;
+ ULONGLONG FocusMode;
+ KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING FocusSetting;
+ ULONGLONG FocusPriority;
+ ULONGLONG FlashMode;
+ ULONG FlashValue; // Adjustable power setting (0-100)
+ BOOLEAN bPhotoConfirmation;
+} ;
+
+struct SOC_CAP_WITH_STEPPING
+{
+ KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr;
+ KSPROPERTY_STEPPING_LONG Stepping;
+} ;
+
+struct SOC_CAP_WITH_STEPPING_LONGLONG
+{
+ KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr;
+ KSPROPERTY_STEPPING_LONGLONG Stepping;
+} ;
+
+//
+// ICapturePin:
+//
+// This is a capture pin interface. The device level calls back the
+// CompleteMapping method passing the number of completed mappings for
+// the capture pin.
+//
+class ICapturePin
+{
+
+public:
+
+ virtual
+ NTSTATUS
+ CompleteMapping(
+ _In_opt_ PKSSTREAM_POINTER Clone=nullptr
+ ) = 0;
+
+};
+
+class LockDevice
+{
+public:
+
+ LockDevice(PKSDEVICE device) : m_device(device)
+ {
+ NT_ASSERT(m_device);
+ KsAcquireDevice(m_device);
+ }
+
+ ~LockDevice()
+ {
+ KsReleaseDevice(m_device);
+ }
+private:
+ PKSDEVICE m_device;
+};
+
+class LockFilter
+{
+public:
+
+ LockFilter(PKSFILTER filter) : m_filter(filter)
+ {
+ NT_ASSERT(m_filter);
+ KsFilterAcquireControl(m_filter);
+ }
+
+ ~LockFilter()
+ {
+ KsFilterReleaseControl(m_filter);
+ }
+private:
+ PKSFILTER m_filter;
+};
+
+// The following class definitions and ctors are used solely
+// to simplify initialization of the parent metadata structures.
+// They are not here for any other purpose.
+
+template <class T, class U>
+class CMetaRational : public U
+{
+public:
+ CMetaRational( T Num=1, T Denom=1 )
+ {
+ Set=TRUE;
+ Numerator = Num;
+ Denominator = Denom;
+ }
+};
+
+typedef CMetaRational<UINT32, METADATA_RATIONAL> CMetadataRational;
+typedef CMetaRational<INT32, METADATA_SRATIONAL> CMetadataSRational;
+
+template <class T, class U>
+class CMetaPrimative : public U
+{
+public:
+ CMetaPrimative( T n )
+ {
+ Set = TRUE;
+ Value = n;
+ }
+};
+
+typedef CMetaPrimative<UINT16, METADATA_UINT16> CMetadataShort;
+typedef CMetaPrimative<UINT32, METADATA_UINT32> CMetadataLong;
+typedef CMetaPrimative<INT64, METADATA_INT64> CMetadataLongLong;
+typedef CMetaPrimative<UINT64, METADATA_UINT64> CMetadataULongLong;
+
+class CMetadataShortString : public METADATA_SHORTSTRING
+{
+public:
+ CMetadataShortString(
+ _In_z_ const CHAR *str
+ )
+ {
+ Length = (UINT32) min(strlen(str), sizeof(String));
+ strncpy_s( String, str, Length );
+ }
+};
+
+class CMetadataEVCompensation : public METADATA_EVCOMP
+{
+public:
+ CMetadataEVCompensation(
+ _In_ UINT64 flags,
+ _In_ UINT32 value
+ )
+ {
+ Set = TRUE;
+ Flags = flags;
+ Value = value;
+ }
+};
+
+typedef struct
+{
+ LONG Value;
+ ULONG Flags;
+ ULONG Capabilities;
+} VIDCAP_PROPERTY, *PVIDCAP_PROPERTY;
+
+typedef struct
+{
+ LONG lOcularFocalLength;
+ LONG lObjectiveFocalLengthMin;
+ LONG lObjectiveFocalLengthMax;
+} FOCAL_LENGTH_PROPERTY, *PFOCAL_LENGTH_PROPERTY;
+
+const ULONG KSCAMERA_EXTENDEDPROP_VERSION = 1;
+
+//
+// Note: I cannot simplify this down to just the FrameIndex.
+// Past frames and non-VPS photos can have a photo confirmation set
+// and those images will not have an index associated with them.
+//
+class PHOTOCONFIRMATION_INFO
+{
+public:
+ PHOTOCONFIRMATION_INFO(
+ _In_ ULONG FrameIndex,
+ _In_ LONGLONG Time
+ )
+ : m_Index( FrameIndex )
+ , m_Time(Time)
+ , m_bRequired(TRUE)
+ {}
+
+ PHOTOCONFIRMATION_INFO()
+ : m_Index(0)
+ , m_Time(0)
+ , m_bRequired( FALSE )
+ {}
+
+ BOOL
+ isRequired() const
+ {
+ return m_bRequired;
+ }
+
+ ULONG
+ getIndex() const
+ {
+ return m_Index;
+ }
+
+ LONGLONG
+ getTime() const
+ {
+ return m_Time;
+ }
+
+private:
+ BOOL m_bRequired;
+ ULONG m_Index;
+ LONGLONG m_Time;
+};
diff --git a/avstream/avscamera/sys/Capture.cpp b/avstream/avscamera/sys/Capture.cpp
index cd62bae1..77bd618c 100644
--- a/avstream/avscamera/sys/Capture.cpp
+++ b/avstream/avscamera/sys/Capture.cpp
@@ -51,7 +51,6 @@ CCapturePin (
, m_PendIo(FALSE)
, m_AcquiredResources(FALSE)
, m_VideoInfoHeader(nullptr)
- , m_pBitmapInfoHeader(nullptr)
, m_PreviousStreamPointer(nullptr)
, m_PresentationTime(0)
, m_FrameNumber(0)
@@ -100,7 +99,6 @@ CCapturePin::
{
PAGED_CODE();
- SAFE_FREE( m_pBitmapInfoHeader );
SAFE_FREE( m_VideoInfoHeader );
}
@@ -254,23 +252,11 @@ Return Value:
const GUID ImageInfoSpecifier ={ STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) };
const GUID VideoInfoSpecifier ={ STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) };
+ const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) };
// Free any previous copy of these header.
- SAFE_FREE(m_pBitmapInfoHeader);
SAFE_FREE(m_VideoInfoHeader);
- m_pBitmapInfoHeader = reinterpret_cast <PKS_BITMAPINFOHEADER> (
- ExAllocatePoolWithTag (
- NonPagedPoolNx,
- sizeof(KS_BITMAPINFOHEADER),
- AVSHWS_POOLTAG
- )
- );
- if( !m_pBitmapInfoHeader )
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
if( IsEqualGUID( m_Pin->ConnectionFormat->Specifier, ImageInfoSpecifier ) &&
m_Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_IMAGEINFO) )
{
@@ -279,40 +265,35 @@ Return Value:
&((reinterpret_cast <PKS_DATAFORMAT_IMAGEINFO>
(m_Pin->ConnectionFormat))->ImageInfoHeader);
- //
- // Copy the connection format video info header into the newly
- // allocated "captured" video info header.
- //
- *m_pBitmapInfoHeader = *ConnectionHeader;
-
m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> (
ExAllocatePoolWithTag (
NonPagedPoolNx,
- sizeof(KS_VIDEOINFOHEADER),
+ max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->biSize + KS_SIZE_PREHEADER),
AVSHWS_POOLTAG
)
);
if( !m_VideoInfoHeader )
{
- SAFE_FREE( m_pBitmapInfoHeader );
return STATUS_INSUFFICIENT_RESOURCES;
}
//
- // Copy the connection format video info header into the newly
+ // Copy the connection format bitmap info header into the newly
// allocated "captured" video info header.
//
m_VideoInfoHeader->bmiHeader = *ConnectionHeader;
+ PKS_BITMAPINFOHEADER CurrentBitmapInfoHeader = &(m_VideoInfoHeader->bmiHeader);
+
// If we don't have a known bit-depth (compressed formats), assume the worse-case.
- if( m_pBitmapInfoHeader->biBitCount==0 )
+ if( CurrentBitmapInfoHeader->biBitCount==0 )
{
- m_pBitmapInfoHeader->biBitCount=32;
+ CurrentBitmapInfoHeader->biBitCount=32;
}
// Estimate the image size. The derived pin can chose to override this value.
- m_VideoInfoHeader->bmiHeader.biSizeImage =
- (m_pBitmapInfoHeader->biWidth*m_pBitmapInfoHeader->biHeight*m_pBitmapInfoHeader->biBitCount)/8;
+ CurrentBitmapInfoHeader->biSizeImage =
+ (CurrentBitmapInfoHeader->biWidth*CurrentBitmapInfoHeader->biHeight*CurrentBitmapInfoHeader->biBitCount)/8;
// Estimate a frame rate. The derived pin can chose to override this value.
m_VideoInfoHeader->AvgTimePerFrame = ONESECOND/30;
@@ -329,13 +310,12 @@ Return Value:
m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> (
ExAllocatePoolWithTag (
NonPagedPoolNx,
- KS_SIZE_VIDEOHEADER (ConnectionHeader),
+ max(sizeof(KS_VIDEOINFOHEADER), KS_SIZE_VIDEOHEADER (ConnectionHeader)),
AVSHWS_POOLTAG
)
);
if( !m_VideoInfoHeader )
{
- SAFE_FREE( m_pBitmapInfoHeader );
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -348,12 +328,42 @@ Return Value:
ConnectionHeader,
KS_SIZE_VIDEOHEADER (ConnectionHeader)
);
+ }
+ else
+ if( IsEqualGUID( m_Pin->ConnectionFormat->Specifier, VideoInfo2Specifier ) &&
+ m_Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER2) )
+ {
+ PKS_VIDEOINFOHEADER2 ConnectionHeader =
+ &((reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER2>
+ (m_Pin->ConnectionFormat))->
+ VideoInfoHeader2);
+
+ m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> (
+ ExAllocatePoolWithTag(
+ NonPagedPoolNx,
+ max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->bmiHeader.biSize + KS_SIZE_PREHEADER),
+ AVSHWS_POOLTAG
+ )
+ );
+ if (!m_VideoInfoHeader)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
//
// Copy the connection format video info header into the newly
// allocated "captured" video info header.
//
- *m_pBitmapInfoHeader = m_VideoInfoHeader->bmiHeader;
+ m_VideoInfoHeader->rcSource = ConnectionHeader->rcSource;
+ m_VideoInfoHeader->rcTarget = ConnectionHeader->rcTarget;
+ m_VideoInfoHeader->dwBitRate = ConnectionHeader->dwBitRate;
+ m_VideoInfoHeader->dwBitErrorRate = ConnectionHeader->dwBitErrorRate;
+ m_VideoInfoHeader->AvgTimePerFrame = ConnectionHeader->AvgTimePerFrame;
+ RtlCopyMemory (
+ &m_VideoInfoHeader->bmiHeader,
+ &ConnectionHeader->bmiHeader,
+ ConnectionHeader->bmiHeader.biSize
+ );
}
else
{
@@ -1165,6 +1175,7 @@ Return Value:
NTSTATUS Status = STATUS_NO_MATCH;
const GUID ImageInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) };
const GUID VideoInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) };
+ const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) };
//
// Find the pin, if it exists yet. OldFormat will be an indication of
@@ -1176,11 +1187,14 @@ Return Value:
CCapturePin *CapPin = reinterpret_cast <CCapturePin *> (Pin->Context);
// For debugging...
+ UNICODE_STRING NewFormatSpecifier;
UNICODE_STRING NewFormat;
UNICODE_STRING RefFormat;
+ (void)RtlStringFromGUID( Pin->ConnectionFormat->Specifier, &NewFormatSpecifier );
(void)RtlStringFromGUID( Pin->ConnectionFormat->SubFormat, &NewFormat );
(void)RtlStringFromGUID( DataRange->SubFormat, &RefFormat );
+ DBG_TRACE("Format specifier for Pin %d is %wZ)", Pin->Id, &NewFormatSpecifier);
if( IsEqualGUID( Pin->ConnectionFormat->Specifier, ImageInfoSpecifier ) &&
Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_IMAGEINFO) )
{
@@ -1276,68 +1290,105 @@ Return Value:
}
}
}
-
- else if( IsEqualGUID( Pin->ConnectionFormat->Specifier,
- VideoInfoSpecifier ) &&
- Pin->ConnectionFormat->FormatSize >=
- sizeof (KS_DATAFORMAT_VIDEOINFOHEADER) )
+ else
+ if( ( IsEqualGUID( Pin->ConnectionFormat->Specifier, VideoInfoSpecifier ) &&
+ Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER) ) ||
+ ( IsEqualGUID( Pin->ConnectionFormat->Specifier, VideoInfo2Specifier ) &&
+ Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER2) ) )
{
+ ULONG VideoHeaderSize = 0;
+ ULONG DataFormatSize = 0;
+ ULONG ConnectionFormatDataFormatSize = 0;
+ KS_BITMAPINFOHEADER ConnectionFormatBitMapInfoHeader = {};
+ KS_BITMAPINFOHEADER DataRangeBitMapInfoHeader = {};
- PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat =
- reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER>
- (Pin->ConnectionFormat);
+ if (IsEqualGUID(Pin->ConnectionFormat->Specifier, VideoInfo2Specifier))
+ {
+ PKS_DATAFORMAT_VIDEOINFOHEADER2 ConnectionFormat =
+ reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER2>
+ (Pin->ConnectionFormat);
- //
- // DataRange comes out of OUR data range list. I know the range
- // is valid as such.
- //
- const KS_DATARANGE_VIDEO *VIRange =
- reinterpret_cast <const KS_DATARANGE_VIDEO *>
- (DataRange);
+ //
+ // DataRange comes out of OUR data range list. I know the range
+ // is valid as such.
+ //
+ const KS_DATARANGE_VIDEO2 *VIRange =
+ reinterpret_cast <const KS_DATARANGE_VIDEO2 *>
+ (DataRange);
- //
- // Check that bmiHeader.biSize is valid since we use it later.
- //
- ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER(
- &ConnectionFormat->VideoInfoHeader
- );
+ VideoHeaderSize = AVSCAM_SIZE_VIDEOHEADER2(
+ &ConnectionFormat->VideoInfoHeader2
+ );
+
+ DataFormatSize = FIELD_OFFSET(
+ KS_DATAFORMAT_VIDEOINFOHEADER2, VideoInfoHeader2
+ ) + VideoHeaderSize;
+
+ ConnectionFormatDataFormatSize = ConnectionFormat->DataFormat.FormatSize;
+ ConnectionFormatBitMapInfoHeader = ConnectionFormat->VideoInfoHeader2.bmiHeader;
+ DataRangeBitMapInfoHeader = VIRange->VideoInfoHeader.bmiHeader;
+ }
+ else
+ {
+ PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat =
+ reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER>
+ (Pin->ConnectionFormat);
+
+ //
+ // DataRange comes out of OUR data range list. I know the range
+ // is valid as such.
+ //
+ const KS_DATARANGE_VIDEO *VIRange =
+ reinterpret_cast <const KS_DATARANGE_VIDEO *>
+ (DataRange);
+
+ VideoHeaderSize = KS_SIZE_VIDEOHEADER(
+ &ConnectionFormat->VideoInfoHeader
+ );
+
+ DataFormatSize = FIELD_OFFSET(
+ KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader
+ ) + VideoHeaderSize;
- ULONG DataFormatSize = FIELD_OFFSET(
- KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader
- ) + VideoHeaderSize;
+ ConnectionFormatDataFormatSize = ConnectionFormat->DataFormat.FormatSize;
+ ConnectionFormatBitMapInfoHeader = ConnectionFormat->VideoInfoHeader.bmiHeader;
+ DataRangeBitMapInfoHeader = VIRange->VideoInfoHeader.bmiHeader;
+ }
- if( VideoHeaderSize < ConnectionFormat->VideoInfoHeader.bmiHeader.biSize ||
+ //
+ // Check that ConnectionFormatBitMapInfoHeader.biSize is valid since we use it later.
+ //
+ if (VideoHeaderSize < ConnectionFormatBitMapInfoHeader.biSize ||
DataFormatSize < VideoHeaderSize ||
- DataFormatSize > ConnectionFormat->DataFormat.FormatSize )
+ DataFormatSize > ConnectionFormatDataFormatSize)
{
Status = STATUS_INVALID_PARAMETER;
}
-
//
// Check that the format is a match for the selected range.
//
else if(
- (ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth !=
- VIRange->VideoInfoHeader.bmiHeader.biWidth) ||
- (ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight !=
- VIRange->VideoInfoHeader.bmiHeader.biHeight) ||
+ (ConnectionFormatBitMapInfoHeader.biWidth !=
+ DataRangeBitMapInfoHeader.biWidth) ||
+ (ConnectionFormatBitMapInfoHeader.biHeight !=
+ DataRangeBitMapInfoHeader.biHeight) ||
!IsEqualGUID( Pin->ConnectionFormat->SubFormat, DataRange->SubFormat ) )
{
DBG_TRACE("FAILED: Height=(%d,%d), Width=(%d,%d), SubFormat=(%wZ,%wZ)",
- ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth,
- VIRange->VideoInfoHeader.bmiHeader.biWidth,
- ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight,
- VIRange->VideoInfoHeader.bmiHeader.biHeight,
+ ConnectionFormatBitMapInfoHeader.biWidth,
+ DataRangeBitMapInfoHeader.biWidth,
+ ConnectionFormatBitMapInfoHeader.biHeight,
+ DataRangeBitMapInfoHeader.biHeight,
&NewFormat, &RefFormat );
Status = STATUS_NO_MATCH;
}
else
{
DBG_TRACE("MATCH: Height=(%d,%d), Width=(%d,%d), SubFormat=(%wZ,%wZ)",
- ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth,
- VIRange->VideoInfoHeader.bmiHeader.biWidth,
- ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight,
- VIRange->VideoInfoHeader.bmiHeader.biHeight,
+ ConnectionFormatBitMapInfoHeader.biWidth,
+ DataRangeBitMapInfoHeader.biWidth,
+ ConnectionFormatBitMapInfoHeader.biHeight,
+ DataRangeBitMapInfoHeader.biHeight,
&NewFormat, &RefFormat );
//
@@ -1356,9 +1407,8 @@ Return Value:
ULONG ImageSize;
if( !MultiplyCheckOverflow(
- (ULONG) ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth,
- (ULONG) abs( ConnectionFormat->
- VideoInfoHeader.bmiHeader.biHeight ),
+ (ULONG) ConnectionFormatBitMapInfoHeader.biWidth,
+ (ULONG) abs( ConnectionFormatBitMapInfoHeader.biHeight ),
&ImageSize
) )
{
@@ -1371,8 +1421,7 @@ Return Value:
//
else if( !MultiplyCheckOverflow(
ImageSize,
- (ULONG) (ConnectionFormat->
- VideoInfoHeader.bmiHeader.biBitCount / 8),
+ (ULONG) (ConnectionFormatBitMapInfoHeader.biBitCount / 8),
&ImageSize
) )
{
@@ -1383,7 +1432,7 @@ Return Value:
// Valid for the formats we use. Otherwise, this would be
// checked later.
//
- else if( ConnectionFormat->VideoInfoHeader.bmiHeader.biSizeImage <
+ else if( ConnectionFormatBitMapInfoHeader.biSizeImage <
ImageSize )
{
Status = STATUS_INVALID_PARAMETER;
@@ -1431,6 +1480,7 @@ Return Value:
}
}
+ RtlFreeUnicodeString(&NewFormatSpecifier);
RtlFreeUnicodeString(&NewFormat);
RtlFreeUnicodeString(&RefFormat);
@@ -1509,6 +1559,7 @@ Return Value:
const GUID ImageInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) };
const GUID VideoInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) };
+ const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) };
ULONG DataFormatSize;
NT_ASSERT( Filter );
@@ -1733,6 +1784,138 @@ Return Value:
return STATUS_SUCCESS;
+ }
+ else if( IsEqualGUID( CallerDataRange->Specifier, VideoInfo2Specifier ) &&
+ CallerDataRange->FormatSize >= sizeof (KS_DATARANGE_VIDEO2) )
+ {
+
+ PKS_DATARANGE_VIDEO2 callerDataRange =
+ reinterpret_cast <PKS_DATARANGE_VIDEO2> (CallerDataRange);
+
+ PKS_DATARANGE_VIDEO2 descriptorDataRange =
+ reinterpret_cast <PKS_DATARANGE_VIDEO2> (DescriptorDataRange);
+
+ PKS_DATAFORMAT_VIDEOINFOHEADER2 FormatVideoInfoHeader;
+
+ //
+ // Check that the other fields match
+ //
+ if( (callerDataRange->bFixedSizeSamples !=
+ descriptorDataRange->bFixedSizeSamples) ||
+ (callerDataRange->bTemporalCompression !=
+ descriptorDataRange->bTemporalCompression) ||
+ (callerDataRange->StreamDescriptionFlags !=
+ descriptorDataRange->StreamDescriptionFlags) ||
+ (callerDataRange->MemoryAllocationFlags !=
+ descriptorDataRange->MemoryAllocationFlags) ||
+ (RtlCompareMemory( &callerDataRange->ConfigCaps,
+ &descriptorDataRange->ConfigCaps,
+ sizeof (KS_VIDEO_STREAM_CONFIG_CAPS) ) !=
+ sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) )
+ {
+ return STATUS_NO_MATCH;
+ }
+
+ //
+ // AVSCAM_SIZE_VIDEOHEADER2() below is relying on bmiHeader.biSize from
+ // the caller's data range. This **MUST** be validated; the
+ // extended bmiHeader size (biSize) must not extend past the end
+ // of the range buffer. Possible arithmetic overflow is also
+ // checked for.
+ //
+ ULONG VideoHeaderSize = AVSCAM_SIZE_VIDEOHEADER2(
+ &callerDataRange->VideoInfoHeader
+ );
+
+ ULONG DataRangeSize =
+ FIELD_OFFSET( KS_DATARANGE_VIDEO2, VideoInfoHeader ) +
+ VideoHeaderSize;
+
+ //
+ // Check that biSize does not extend past the buffer. The
+ // first two checks are for arithmetic overflow on the
+ // operations to compute the alleged size. (On unsigned
+ // math, a+b < a iff an arithmetic overflow occurred).
+ //
+ if( VideoHeaderSize < callerDataRange->VideoInfoHeader.bmiHeader.biSize ||
+ DataRangeSize < VideoHeaderSize ||
+ DataRangeSize > callerDataRange->DataRange.FormatSize )
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ DataFormatSize =
+ sizeof (KSDATAFORMAT) +
+ AVSCAM_SIZE_VIDEOHEADER2( &callerDataRange->VideoInfoHeader );
+
+
+ //
+ // If the passed buffer size is 0, it indicates that this is a size
+ // only query. Return the size of the intersecting data format and
+ // pass back STATUS_BUFFER_OVERFLOW.
+ //
+ if( BufferSize == 0 )
+ {
+ *DataSize = DataFormatSize;
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ //
+ // Verify that the provided structure is large enough to
+ // accept the result.
+ //
+ if( BufferSize < DataFormatSize )
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader
+ //
+ *DataSize = DataFormatSize;
+
+ FormatVideoInfoHeader = PKS_DATAFORMAT_VIDEOINFOHEADER2( Data );
+
+ //
+ // Copy over the KSDATAFORMAT. This is precisely the same as the
+ // KSDATARANGE (it's just the GUIDs, etc... not the format information
+ // following any data format.
+ //
+ RtlCopyMemory(
+ &FormatVideoInfoHeader->DataFormat,
+ DescriptorDataRange,
+ sizeof (KSDATAFORMAT) );
+
+ FormatVideoInfoHeader->DataFormat.FormatSize = DataFormatSize;
+
+ //
+ // Copy over the callers requested VIDEOINFOHEADER
+ //
+
+ RtlCopyMemory(
+ &FormatVideoInfoHeader->VideoInfoHeader2,
+ &callerDataRange->VideoInfoHeader,
+ AVSCAM_SIZE_VIDEOHEADER2( &callerDataRange->VideoInfoHeader )
+ );
+
+ //
+ // Calculate biSizeImage for this request, and put the result in both
+ // the biSizeImage field of the bmiHeader AND in the SampleSize field
+ // of the DataFormat.
+ //
+ // Note that for compressed sizes, this calculation will probably not
+ // be just width * height * bitdepth
+ //
+ FormatVideoInfoHeader->VideoInfoHeader2.bmiHeader.biSizeImage =
+ FormatVideoInfoHeader->DataFormat.SampleSize =
+ KS_DIBSIZE( FormatVideoInfoHeader->VideoInfoHeader2.bmiHeader );
+
+ //
+ // REVIEW - Perform other validation such as cropping and scaling checks
+ //
+
+ return STATUS_SUCCESS;
+
} // End of VIDEOINFOHEADER specifier
return STATUS_NO_MATCH;
diff --git a/avstream/avscamera/sys/Capture.h b/avstream/avscamera/sys/Capture.h
index 1e0c62b9..0a065d24 100644
--- a/avstream/avscamera/sys/Capture.h
+++ b/avstream/avscamera/sys/Capture.h
@@ -92,7 +92,6 @@ protected:
BOOLEAN m_PendIo; // An indication of whether or not we pended I/O for some reason.
BOOLEAN m_AcquiredResources; // An indication of whether or not this pin has acquired the necessary hardware resources to operate.
PKS_VIDEOINFOHEADER m_VideoInfoHeader;
- PKS_BITMAPINFOHEADER m_pBitmapInfoHeader; // Optional info for image formats.
//
// If we are unable to insert all of the mappings in a stream pointer into
diff --git a/avstream/avscamera/sys/Common.h b/avstream/avscamera/sys/Common.h
index d54ba2f3..5c83f2fc 100644
--- a/avstream/avscamera/sys/Common.h
+++ b/avstream/avscamera/sys/Common.h
@@ -40,6 +40,7 @@
#include "MetadataInternal.h"
#include "CustomProperties.h"
#include "Dbg.h"
+#include "CameraSimulatorCommon.h"
#ifndef _NEW_DELETE_OPERATORS_
#define _NEW_DELETE_OPERATORS_
@@ -181,71 +182,8 @@ void __cdecl operator delete[]
Misc Definitions
*************************************************/
-#pragma warning (disable : 4100 4127 4131 4189 4701 4706)
#define STR_MODULENAME "AvsCamera: "
-#define IFFAILED_EXIT(status) \
- if (!NT_SUCCESS( Status = (status) )) \
- { \
- goto done; \
- }
-
-#define IFNULL_EXIT(exp) \
- if ( (exp) == nullptr ) \
- { \
- Status = STATUS_INSUFFICIENT_RESOURCES; \
- goto done; \
- }
-
-//
-// Number of 100ns in one second
-//
-#define ONESECOND 10000000
-
-#define ABS(x) ((x) < 0 ? (-(x)) : (x))
-
-#ifndef mmioFOURCC
-#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
- ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
- ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
-#endif
-
-#define FOURCC_YUY2 mmioFOURCC('Y', 'U', 'Y', '2')
-#define FOURCC_NV12 mmioFOURCC('N', 'V', '1', '2')
-
-// RGB24
-#define STATIC_KSDATAFORMAT_SUBTYPE_RGB24\
- 0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70
-DEFINE_GUIDSTRUCT("e436eb7d-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB24);
-#define KSDATAFORMAT_SUBTYPE_RGB24 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB24)
-
-// RGB32
-#define STATIC_KSDATAFORMAT_SUBTYPE_RGB32\
- 0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70
-DEFINE_GUIDSTRUCT("e436eb7e-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB32);
-#define KSDATAFORMAT_SUBTYPE_RGB32 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB32)
-
-// NV12
-#define STATIC_KSDATAFORMAT_SUBTYPE_NV12\
- 0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
-DEFINE_GUIDSTRUCT("3231564E-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_NV12);
-#define KSDATAFORMAT_SUBTYPE_NV12 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NV12)
-
-// YUY2
-#define STATIC_KSDATAFORMAT_SUBTYPE_YUY2\
- 0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
-DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_YUY2);
-#define KSDATAFORMAT_SUBTYPE_YUY2 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_YUY2)
-
-#define CAPTURE_FILTER_COUNT 2
-
-//filter index
-#define CAPTURE_FILTER_RFC 0
-#define CAPTURE_FILTER_FFC 1
-
-//Arbitrary Maximum faces
-#define MAX_FACES 15
-
//
// CAPTURE_PIN_DATA_RANGE_COUNT:(formats)
//
@@ -256,90 +194,12 @@ DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_Y
#define VIDEO_PREVIEW_PIN_DATA_RANGE_COUNT 15
//
-// Define the number of frames needed in the queue for each pin.
-//
-#define IMAGE_CAPTURE_PIN_MINIMUM_FRAMES 3
-#define VIDEO_CAPTURE_PIN_MINIMUM_FRAMES 4
-#define PREVIEW_PIN_MINIMUM_FRAMES 6
-#define IMAGE_CAPTURE_PIN_MAXIMUM_FRAMES 20
-#define IMAGE_CAPTURE_PIN_MAXIMUM_HISTORY_FRAMES 10
-
-//
// CAPTURE_FILTER_CATEGORIES_COUNT:
//
// The number of categories for the capture filter.
//
#define CAPTURE_FILTER_CATEGORIES_COUNT 3
-#define AVSHWS_POOLTAG 'hSVA'
-
-//
-// Focal length definitions
-//
-
-// These are the definitions found in MSDN for the legacy zoom controls.
-//
-//#define FOCALLENGTH_OCULAR 50
-//#define FOCALLENGTH_OPTICAL_MIN 10
-//#define FOCALLENGTH_OPTICAL_MAX 600
-
-//#define FOCALLENGTH_OCULAR 50
-//#define FOCALLENGTH_OPTICAL_MIN 10
-//#define FOCALLENGTH_OPTICAL_MAX 600
-
-// Note: Despite what MSDN says, they are NOT limits as far as the
-// pipeline is conerned. You should supply values here that are
-// appropriate to your hardware - whatever that may be.
-//
-// Also note that since both optical and ocular focal length are
-// nomally measured in millimeters, and since the optical length is
-// always the numerator and ocular is used as the denominator, the
-// units (millimeters) cancel out. This means you can stick any set
-// of values you like here that can be used to represent the min and
-// maximum zoom value of your hardware as a simple rational number.
-//
-// Again, the rational number is: (Objective length / Ocular length)
-//
-// We use the following definitions in this simulation in order to have the
-// values produced and used in the legacy control be the same as the ones
-// in the new extended zoom control.
-//
-#define FOCALLENGTH_OCULAR (1<<16) // Denominator of 2^16 makes this the same as Q16 format in extended.
-#define FOCALLENGTH_OPTICAL_MIN (FOCALLENGTH_OCULAR/16) // Allow a wide-field view of 1/16th.
-#define FOCALLENGTH_OPTICAL_MAX (FOCALLENGTH_OCULAR*32) // Allow a zoom-in view of 32x.
-
-// Values for Power Line Frequency
-#define POWERLINEFREQ_DISABLED 0
-#define POWERLINEFREQ_50HZ 1
-#define POWERLINEFREQ_60HZ 2
-#define POWERLINEFREQ_AUTO 3
-#define POWERLINEFREQ_DEFAULT POWERLINEFREQ_DISABLED
-
-
-//
-// Q-format definitions.
-//
-#define BASE_Q(n) (((ULONGLONG)1)<<n)
-#define TO_Q31(_x_) (LONGLONG)( (_x_) * BASE_Q(31) )
-#define TO_Q16(_x_) (LONGLONG)( (_x_) * BASE_Q(16) )
-#define FROM_Q16(_x_, _denominator_) ((LONG)( (LONGLONG)(_x_) / ( TO_Q16(1) / (LONGLONG)(_denominator_)) ))
-
-#define MULT_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_) * (LONGLONG)(_y_)) + (BASE_Q(15)))>>16)
-#define DIV_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_)<<16)+(_y_/2))/(LONGLONG)(_y_))
-
-#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
-#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
-
-//
-// Copy of histogram channel bitmask definitions from mfapi.h (not available in wdk).
-//
-#define MF_HISTOGRAM_CHANNEL_Y 0x00000001
-#define MF_HISTOGRAM_CHANNEL_R 0x00000002
-#define MF_HISTOGRAM_CHANNEL_G 0x00000004
-#define MF_HISTOGRAM_CHANNEL_B 0x00000008
-#define MF_HISTOGRAM_CHANNEL_Cb 0x00000010
-#define MF_HISTOGRAM_CHANNEL_Cr 0x00000020
-
/*************************************************
Externed information
@@ -393,250 +253,6 @@ ImageCapturePinDispatch;
/*************************************************
- Enums / Typedefs
-
-*************************************************/
-
-typedef enum _PIN_STATE
-{
-
- PinStopped = 0,
- PinPaused,
- PinRunning
-
-} PIN_STATE, *PPIN_STATE;
-
-typedef enum _PIN_MODE
-{
-
- PinNormalMode = 0,
- PinBurstMode
-
-} PIN_MODE, *PPIN_MODE;
-
-/*************************************************
-
- Class Definitions
-
-*************************************************/
-
-struct ISP_FRAME_SETTINGS
-{
- ULONGLONG ISOMode;
- ULONG ISOValue; // for Manual ISO settings.
- KSCAMERA_EXTENDEDPROP_EVCOMPENSATION EVCompensation;
- ULONGLONG WhiteBalanceMode;
- KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING WhiteBalanceSetting;
- ULONGLONG ExposureMode;
- KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING ExposureSetting;
- ULONGLONG FocusMode;
- KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING FocusSetting;
- ULONGLONG FocusPriority;
- ULONGLONG FlashMode;
- ULONG FlashValue; // Adjustable power setting (0-100)
- BOOLEAN bPhotoConfirmation;
-} ;
-
-struct SOC_CAP_WITH_STEPPING
-{
- KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr;
- KSPROPERTY_STEPPING_LONG Stepping;
-} ;
-
-struct SOC_CAP_WITH_STEPPING_LONGLONG
-{
- KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr;
- KSPROPERTY_STEPPING_LONGLONG Stepping;
-} ;
-
-//
-// ICapturePin:
-//
-// This is a capture pin interface. The device level calls back the
-// CompleteMapping method passing the number of completed mappings for
-// the capture pin.
-//
-class ICapturePin
-{
-
-public:
-
- virtual
- NTSTATUS
- CompleteMapping(
- _In_opt_ PKSSTREAM_POINTER Clone=nullptr
- ) = 0;
-
-};
-
-class LockDevice
-{
-public:
-
- LockDevice(PKSDEVICE device) : m_device(device)
- {
- NT_ASSERT(m_device);
- KsAcquireDevice(m_device);
- }
-
- ~LockDevice()
- {
- KsReleaseDevice(m_device);
- }
-private:
- PKSDEVICE m_device;
-};
-
-class LockFilter
-{
-public:
-
- LockFilter(PKSFILTER filter) : m_filter(filter)
- {
- NT_ASSERT(m_filter);
- KsFilterAcquireControl(m_filter);
- }
-
- ~LockFilter()
- {
- KsFilterReleaseControl(m_filter);
- }
-private:
- PKSFILTER m_filter;
-};
-
-// The following class definitions and ctors are used solely
-// to simplify initialization of the parent metadata structures.
-// They are not here for any other purpose.
-
-template <class T, class U>
-class CMetaRational : public U
-{
-public:
- CMetaRational( T Num=1, T Denom=1 )
- {
- Set=TRUE;
- Numerator = Num;
- Denominator = Denom;
- }
-};
-
-typedef CMetaRational<UINT32, METADATA_RATIONAL> CMetadataRational;
-typedef CMetaRational<INT32, METADATA_SRATIONAL> CMetadataSRational;
-
-template <class T, class U>
-class CMetaPrimative : public U
-{
-public:
- CMetaPrimative( T n )
- {
- Set = TRUE;
- Value = n;
- }
-};
-
-typedef CMetaPrimative<UINT16, METADATA_UINT16> CMetadataShort;
-typedef CMetaPrimative<UINT32, METADATA_UINT32> CMetadataLong;
-typedef CMetaPrimative<INT64, METADATA_INT64> CMetadataLongLong;
-typedef CMetaPrimative<UINT64, METADATA_UINT64> CMetadataULongLong;
-
-class CMetadataShortString : public METADATA_SHORTSTRING
-{
-public:
- CMetadataShortString(
- _In_z_ const CHAR *str
- )
- {
- Length = (UINT32) min(strlen(str), sizeof(String));
- strncpy_s( String, str, Length );
- }
-};
-
-class CMetadataEVCompensation : public METADATA_EVCOMP
-{
-public:
- CMetadataEVCompensation(
- _In_ UINT64 flags,
- _In_ UINT32 value
- )
- {
- Set = TRUE;
- Flags = flags;
- Value = value;
- }
-};
-
-typedef struct
-{
- LONG Value;
- ULONG Flags;
- ULONG Capabilities;
-} VIDCAP_PROPERTY, *PVIDCAP_PROPERTY;
-
-typedef struct
-{
- LONG lOcularFocalLength;
- LONG lObjectiveFocalLengthMin;
- LONG lObjectiveFocalLengthMax;
-} FOCAL_LENGTH_PROPERTY, *PFOCAL_LENGTH_PROPERTY;
-
-const ULONG KSCAMERA_EXTENDEDPROP_VERSION = 1;
-
-//
-// Note: I cannot simplify this down to just the FrameIndex.
-// Past frames and non-VPS photos can have a photo confirmation set
-// and those images will not have an index associated with them.
-//
-class PHOTOCONFIRMATION_INFO
-{
-public:
- PHOTOCONFIRMATION_INFO(
- _In_ ULONG FrameIndex,
- _In_ LONGLONG Time
- )
- : m_Index( FrameIndex )
- , m_Time(Time)
- , m_bRequired(TRUE)
- {}
-
- PHOTOCONFIRMATION_INFO()
- : m_Index(0)
- , m_Time(0)
- , m_bRequired( FALSE )
- {}
-
- BOOL
- isRequired()
- {
- return m_bRequired;
- }
-
- ULONG
- getIndex()
- {
- return m_Index;
- }
-
- LONGLONG
- getTime()
- {
- return m_Time;
- }
-
-private:
- BOOL m_bRequired;
- ULONG m_Index;
- LONGLONG m_Time;
-};
-
-/*************************************************
-
- Global Functions
-
-*************************************************/
-
-/*************************************************
-
Internal Includes
*************************************************/
diff --git a/avstream/avscamera/sys/Device.cpp b/avstream/avscamera/sys/Device.cpp
index 1b5f8090..ed46bdc8 100644
--- a/avstream/avscamera/sys/Device.cpp
+++ b/avstream/avscamera/sys/Device.cpp
@@ -688,7 +688,7 @@ Return Value:
LOCALE_NEUTRAL,
PLUGPLAY_PROPERTY_PERSISTENT,
DEVPROP_TYPE_BINARY,
- sizeof(ACPI_PLD_BUFFER),
+ sizeof(pld),
(PVOID)&pld)
);
diff --git a/avstream/avscamera/sys/NV12Synthesizer.cpp b/avstream/avscamera/sys/NV12Synthesizer.cpp
index 2cdbf71b..32ee6ea8 100644
--- a/avstream/avscamera/sys/NV12Synthesizer.cpp
+++ b/avstream/avscamera/sys/NV12Synthesizer.cpp
@@ -49,10 +49,6 @@
#endif // ALLOC_PRAGMA
-// suppressed due to Esp:773
-#pragma warning (push)
-#pragma warning( disable:26015 ) // Suppress OACR error. Seems nonsensical. TODO: Must revisit.
-#pragma warning( disable:26019 )
_Success_(return > 0)
ULONG
CNV12Synthesizer::
@@ -86,8 +82,11 @@ Return Value:
--*/
{
- // We assume the output stride is the same as the original width here.
- UNREFERENCED_PARAMETER(Stride);
+ // In case stride isn't initialized.
+ if( Stride==0 )
+ {
+ Stride = m_OutputStride;
+ }
// The code actually handles this gracefully. It rounds down.
NT_ASSERT( (m_Width&1) == 0 );
@@ -107,7 +106,7 @@ Return Value:
ULONG MacroPixelsWide = m_Width/2;
// Impossible.
- if( MacroPixelsWide==0 )
+ if (MacroPixelsWide == 0 || Stride < (MacroPixelsWide*2)) // 1 macropixel for NV12 is 2 bytes wide
{
NT_ASSERT(FALSE);
return 0;
@@ -117,7 +116,7 @@ Return Value:
// Notice that we limit the number of macro pixel rows to what will
// fit in the space available, no matter what is in the original.
ULONG Y_limit = (Size /3) * 2;
- ULONG MacroPixelsHigh = min( m_Height, Y_limit/m_Width)/2;
+ ULONG MacroPixelsHigh = min(m_Height, Y_limit / Stride) / 2;
// Impossible.
if( MacroPixelsHigh==0 )
@@ -127,8 +126,8 @@ Return Value:
}
// Now we work back to arrive at the Y & UV plane sizes.
- ULONG UV_size = MacroPixelsWide * MacroPixelsHigh *2;
- ULONG Y_size = MacroPixelsWide * MacroPixelsHigh *4;
+ ULONG UV_size = Stride * MacroPixelsHigh;
+ ULONG Y_size = Stride * MacroPixelsHigh * 2;
ULONG YUV_size = Y_size + UV_size;
// Impossible.
@@ -138,12 +137,14 @@ Return Value:
return 0;
}
- PWORD pY = (PWORD) Buffer;
- PWORD pUV = (PWORD) (Buffer + Y_size);
-
+ PUCHAR pYRow = Buffer;
+ PUCHAR pUVRow = Buffer + Y_size;
for(ULONG row = 0; row < MacroPixelsHigh; row++)
{
PKS_RGBQUAD pSrc = (PKS_RGBQUAD) GetImageLocation(0, row*2);
+ PWORD pYUpper = (PWORD)pYRow;
+ PWORD pYLower = (PWORD)(pYRow + Stride);
+ PWORD pUV = (PWORD)pUVRow;
for(ULONG col = 0; col < MacroPixelsWide; col++)
{
KS_RGBQUAD TL = pSrc[0];
@@ -153,9 +154,10 @@ Return Value:
pSrc += 2;
// Copy luma first
- pY[0] = MAKEWORD(TL.rgbGreen, TR.rgbGreen);
- pY[MacroPixelsWide] = MAKEWORD(BL.rgbGreen, BR.rgbGreen);
- pY++;
+ pYUpper[0] = MAKEWORD(TL.rgbGreen, TR.rgbGreen);
+ pYLower[0] = MAKEWORD(BL.rgbGreen, BR.rgbGreen);
+ pYUpper++;
+ pYLower++;
LONG
tU = TL.rgbBlue; //top left
@@ -172,12 +174,10 @@ Return Value:
// Copy decimated chroma
*pUV++ = MAKEWORD(((tU+2)>>2), ((tV+2)>>2));
}
- // Skip a scan line, since we've already copied it.
- pY += MacroPixelsWide;
+ // A row of macropixels covers two Y rows and one UV row
+ pYRow += (Stride * 2);
+ pUVRow += Stride;
}
- return (ULONG) (((PUCHAR) pUV) - Buffer);
+ return (ULONG)(pUVRow - Buffer);
}
-// suppressed due to Esp:773
-#pragma warning (pop)
-
diff --git a/avstream/avscamera/sys/NV12Synthesizer.h b/avstream/avscamera/sys/NV12Synthesizer.h
index 27bc6ccb..1ef2f3e7 100644
--- a/avstream/avscamera/sys/NV12Synthesizer.h
+++ b/avstream/avscamera/sys/NV12Synthesizer.h
@@ -53,6 +53,7 @@ public:
{
NT_ASSERT( ( Width % 2 ) == 0 );
NT_ASSERT( ( Height % 2 ) == 0 );
+ m_OutputStride = Width * sizeof(BYTE);
}
//
diff --git a/avstream/avscamera/sys/Sensor.cpp b/avstream/avscamera/sys/Sensor.cpp
index 19988073..97615250 100644
--- a/avstream/avscamera/sys/Sensor.cpp
+++ b/avstream/avscamera/sys/Sensor.cpp
@@ -301,6 +301,8 @@ CreateSynthesizer(
// Create the necessary type of image synthesizer.
//
{
+ PAGED_CODE();
+
NTSTATUS Status = STATUS_SUCCESS;
LONG Width = VideoInfoHeader->bmiHeader.biWidth;
LONG Height = VideoInfoHeader->bmiHeader.biHeight;
@@ -1053,6 +1055,7 @@ Return Value:
--*/
{
PAGED_CODE();
+
KScopedMutex Lock(m_SensorMutex);
// Set the current ISP settings and free any prior.
@@ -1090,6 +1093,8 @@ SetSynthesizerAttribute(
LONGLONG Info
)
{
+ PAGED_CODE();
+
for( ULONG Pin=0; IsValidIndex(Pin); Pin++ )
{
if( m_Synthesizer[Pin] )
@@ -1344,6 +1349,7 @@ DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, OpticalImageStabilization)
DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, OptimizationHint)
DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, AdvancedPhoto)
DEFINE_NULL_PROPERTY(CSensor, CExtendedVidProcSetting, FaceDetection)
+DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, VideoTemporalDenoising)
DEFINE_NULL_PROPERTY(CSensor, KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S, VideoStabMode)
diff --git a/avstream/avscamera/sys/Sensor.h b/avstream/avscamera/sys/Sensor.h
index a40b9d0c..dac97630 100644
--- a/avstream/avscamera/sys/Sensor.h
+++ b/avstream/avscamera/sys/Sensor.h
@@ -574,6 +574,7 @@ public:
DECLARE_PROPERTY( CExtendedProperty, OptimizationHint );
DECLARE_PROPERTY( CExtendedProperty, AdvancedPhoto );
DECLARE_PROPERTY( CExtendedVidProcSetting, FaceDetection );
+ DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising);
DECLARE_PROPERTY_VARSIZE_ASYNC( CRoiProperty, Roi );
diff --git a/avstream/avscamera/sys/SensorSimulation.cpp b/avstream/avscamera/sys/SensorSimulation.cpp
index 3ebeb56b..ce6a2c17 100644
--- a/avstream/avscamera/sys/SensorSimulation.cpp
+++ b/avstream/avscamera/sys/SensorSimulation.cpp
@@ -299,6 +299,7 @@ Return Value:
m_VideoStabilization = KSCAMERA_EXTENDEDPROP_VIDEOSTABILIZATION_OFF;
m_Histogram = KSCAMERA_EXTENDEDPROP_HISTOGRAM_OFF;
m_OpticalImageStabilization = KSCAMERA_EXTENDEDPROP_OIS_AUTO;
+ m_VideoTemporalDenoising = KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO;
m_AdvancedPhoto.PinId = GetNextStillIndex();
m_AdvancedPhoto.Flags = KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_OFF;
@@ -1773,6 +1774,38 @@ SetOpticalImageStabilization(
return STATUS_SUCCESS;
}
+// Get KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING.
+NTSTATUS
+CSensorSimulation::
+GetVideoTemporalDenoising(
+ _Inout_ CExtendedProperty *pProperty
+)
+{
+ PAGED_CODE();
+ KScopedMutex lock(m_SensorMutex);
+
+ pProperty->Flags = m_VideoTemporalDenoising;
+ pProperty->Capability = KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO |
+ KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_OFF |
+ KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_ON;
+
+ return STATUS_SUCCESS;
+}
+
+// Set KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING.
+NTSTATUS
+CSensorSimulation::
+SetVideoTemporalDenoising(
+ _In_ CExtendedProperty *pProperty
+)
+{
+ PAGED_CODE();
+ KScopedMutex lock(m_SensorMutex);
+
+ m_VideoTemporalDenoising = pProperty->Flags;
+ return STATUS_SUCCESS;
+}
+
// Get KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO.
NTSTATUS
CSensorSimulation::
diff --git a/avstream/avscamera/sys/SensorSimulation.h b/avstream/avscamera/sys/SensorSimulation.h
index 4b07f84e..7fb30825 100644
--- a/avstream/avscamera/sys/SensorSimulation.h
+++ b/avstream/avscamera/sys/SensorSimulation.h
@@ -59,7 +59,8 @@ protected:
ULONGLONG m_VideoHDR;
ULONGLONG m_VideoStabilization;
ULONGLONG m_Histogram;
- ULONGLONG m_OpticalImageStabilization;
+ ULONGLONG m_OpticalImageStabilization;
+ ULONGLONG m_VideoTemporalDenoising;
CExtendedProperty m_AdvancedPhoto;
CWhiteBalanceRoiIspControl m_RoiWhiteBalance;
@@ -226,6 +227,7 @@ public:
DECLARE_PROPERTY( CExtendedMaxVideoFpsForPhotoRes, MaxVideoFpsForPhotoRes );
DECLARE_PROPERTY_GET( CExtendedFieldOfView, FieldOfView );
DECLARE_PROPERTY_GET( CExtendedCameraAngleOffset, CameraAngleOffset );
+ DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising);
DECLARE_PROPERTY_VARSIZE_ASYNC_NOCANCEL( CRoiProperty, Roi );
diff --git a/avstream/avscamera/sys/Synthesizer.h b/avstream/avscamera/sys/Synthesizer.h
index 175fa348..6612a3f6 100644
--- a/avstream/avscamera/sys/Synthesizer.h
+++ b/avstream/avscamera/sys/Synthesizer.h
@@ -161,7 +161,7 @@ protected:
//
// The assumed stride of our output format. Currently used by YUY2 and
- // all image captures, except NV12. This value should be initialized by
+ // all image captures. This value should be initialized by
// the derived classes.
//
LONG m_OutputStride;
@@ -178,7 +178,7 @@ protected:
//
// A printable name identifying this format.
//
- PCCHAR m_FormatName;
+ const CHAR *m_FormatName;
//
// A color palette for this colorspace.
@@ -213,7 +213,7 @@ public:
// DEFAULT CONSTRUCTOR
//
CSynthesizer(
- PCCHAR Name="[Unknown]",
+ const CHAR *Name="[Unknown]",
ULONG ChannelMask=0,
ULONG Width=0,
ULONG Height=0
@@ -471,7 +471,7 @@ public:
// Get the color channel mask associated with this format.
//
ULONG
- GetChannelMask()
+ GetChannelMask() const
{
return m_ChannelMask;
}
diff --git a/avstream/avscamera/sys/Timer.h b/avstream/avscamera/sys/Timer.h
index d4e6322e..1927158b 100644
--- a/avstream/avscamera/sys/Timer.h
+++ b/avstream/avscamera/sys/Timer.h
@@ -133,7 +133,7 @@ private:
_Inout_opt_ PVOID Arg2
) ;
- TIMER_TYPE GetType()
+ TIMER_TYPE GetType() const
{
return m_type;
}
diff --git a/avstream/avscamera/sys/Util.cpp b/avstream/avscamera/sys/Util.cpp
index 7c788990..a64dc42f 100644
--- a/avstream/avscamera/sys/Util.cpp
+++ b/avstream/avscamera/sys/Util.cpp
@@ -175,7 +175,7 @@ WhiteBalancePreset2Temperature(
break;
}
- return temp;
+ return min( max( temp, WHITEBALANCE_MIN ), WHITEBALANCE_MAX );
}
typedef struct
@@ -475,6 +475,8 @@ DbgRotation2Degrees(
AcpiPldRotation r
)
{
+ PAGED_CODE();
+
switch( r )
{
case AcpiPldRotation0 : return 0;
@@ -489,3 +491,59 @@ DbgRotation2Degrees(
return -1;
}
+CCameraExtrinsics_2Transforms::
+CCameraExtrinsics_2Transforms( ULONG Seed )
+{
+ PAGED_CODE();
+
+ static
+ KS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM temp =
+ {
+ {0x2eef2648, 0x67e7, 0x48a0, 0xa2, 0x27, 0x46, 0xed, 0x5c, 0xdc, 0x84, 0xb4}, // CalibrationId
+ {0.5, 0.5, 0.5}, // Position
+ {0.5, 0.5, 0.5, 0.5} // Orientation
+ };
+
+ TransformCount = 2;
+ PKS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM pTransform = CalibratedTransforms;
+ for( UINT32 i=0; i<2; i++ )
+ {
+ *pTransform = temp;
+ pTransform->CalibrationId.Data4[7] = (unsigned char) i;
+ pTransform->CalibrationId.Data1 = Seed;
+ pTransform++;
+ }
+}
+
+CCameraIntrinsics_2Models::
+CCameraIntrinsics_2Models()
+{
+ PAGED_CODE();
+
+ static
+ KS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL temp =
+ {
+ 0xBADF00D, // Width
+ 0xBADF00D, // Height
+ { {1.0,2.0}, {3.0,4.0} }, // CameraModel
+ { 1.0, 2.0, 3.0, (float)3.1415296, (float)2.71828 } // DistortionModel
+ };
+
+ static
+ POINT Dimension[]=
+ {
+ {DMAX_X, DMAX_Y},
+ {D_X, D_Y}
+ };
+
+ IntrinsicModelCount = 2;
+ PKS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL pModel = IntrinsicModels;
+ for( UINT32 i=0; i<2; i++ )
+ {
+
+ *pModel = temp;
+ pModel->Width = Dimension[i].x;
+ pModel->Height = Dimension[i].y;
+ pModel++;
+ }
+}
diff --git a/avstream/avscamera/sys/Util.h b/avstream/avscamera/sys/Util.h
index f235a42d..7ed08979 100644
--- a/avstream/avscamera/sys/Util.h
+++ b/avstream/avscamera/sys/Util.h
@@ -123,7 +123,8 @@ BoundsCheck(
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- if( ((Value - T(Bounds.Min) ) % T(Bounds.Step)) != 0 ||
+ if( (Bounds.Step==0 && Bounds.Min!=Bounds.Max) ||
+ (Bounds.Step!=0 && ((Value - T(Bounds.Min) ) % T(Bounds.Step)) != 0) ||
Value > T(Bounds.Max) ||
Value < T(Bounds.Min) )
{
@@ -152,7 +153,8 @@ BoundsCheckSigned(
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- if( ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 ||
+ if( (Bounds.SteppingDelta==0 && Bounds.Bounds.SignedMinimum!=Bounds.Bounds.SignedMaximum) ||
+ (Bounds.SteppingDelta!=0 && (Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 ||
Value > Bounds.Bounds.SignedMaximum ||
Value < Bounds.Bounds.SignedMinimum )
{
@@ -171,7 +173,8 @@ BoundsCheckSigned(
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- if( ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 ||
+ if( (Bounds.SteppingDelta==0 && Bounds.Bounds.SignedMinimum!=Bounds.Bounds.SignedMaximum) ||
+ (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0) ||
Value > Bounds.Bounds.SignedMaximum ||
Value < Bounds.Bounds.SignedMinimum )
{
@@ -193,7 +196,8 @@ BoundsCheckUnsigned(
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- if( ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0 ||
+ if( (Bounds.SteppingDelta==0 && Bounds.Bounds.UnsignedMinimum!=Bounds.Bounds.UnsignedMaximum) ||
+ (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0) ||
Value > Bounds.Bounds.UnsignedMaximum ||
Value < Bounds.Bounds.UnsignedMinimum )
{
@@ -212,7 +216,8 @@ BoundsCheckUnsigned(
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- if( ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0 ||
+ if( (Bounds.SteppingDelta==0 && Bounds.Bounds.UnsignedMinimum!=Bounds.Bounds.UnsignedMaximum) ||
+ (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0) ||
Value > Bounds.Bounds.UnsignedMaximum ||
Value < Bounds.Bounds.UnsignedMinimum )
{
@@ -267,6 +272,30 @@ DbgRotation2Degrees(
AcpiPldRotation r
);
+// Create a definition that self-initialize a KS_CAMERA_EXTRINSIC structure.
+class CCameraExtrinsics_2Transforms : public KS_CAMERA_EXTRINSICS
+{
+public:
+ KS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM CalibratedTransform2;
+
+public:
+ CCameraExtrinsics_2Transforms()
+ {
+ RtlZeroMemory(this, sizeof(*this));
+ }
+ CCameraExtrinsics_2Transforms( ULONG Seed );
+};
+
+// Create a definition that self-initialize a KS_CAMERA_EXTRINSIC structure.
+class CCameraIntrinsics_2Models : public KS_CAMERA_INTRINSICS
+{
+public:
+ KS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL IntrinsicModel2;
+
+public:
+ CCameraIntrinsics_2Models();
+};
+
#define SAFE_FREE(_x_) \
if( _x_ ) \
diff --git a/avstream/avscamera/sys/YUVSynthesizer.h b/avstream/avscamera/sys/YUVSynthesizer.h
index 819139e4..4f856dd6 100644
--- a/avstream/avscamera/sys/YUVSynthesizer.h
+++ b/avstream/avscamera/sys/YUVSynthesizer.h
@@ -59,7 +59,7 @@ public:
//Default constructor
CYUVSynthesizer (
- PCCHAR Name="[Something YUV]",
+ const CHAR *Name="[Something YUV]",
ULONG Width=0,
ULONG Height=0
)
diff --git a/avstream/avscamera/sys/avscamera.inf b/avstream/avscamera/sys/avscamera.inf
index d855cc6f..2a17a764 100644
--- a/avstream/avscamera/sys/avscamera.inf
+++ b/avstream/avscamera/sys/avscamera.inf
Binary files differ
diff --git a/avstream/avscamera/sys/filter.cpp b/avstream/avscamera/sys/filter.cpp
index cb28775e..2680f503 100644
--- a/avstream/avscamera/sys/filter.cpp
+++ b/avstream/avscamera/sys/filter.cpp
@@ -3029,8 +3029,7 @@ SetVFR(
pVFR->isValid() &&
pVFR->Capability == 0 &&
(KSCAMERA_EXTENDEDPROP_VFR_OFF == pVFR->Flags ||
- KSCAMERA_EXTENDEDPROP_VFR_ON == pVFR->Flags ||
- KSCAMERA_EXTENDEDPROP_VIDEOHDR_AUTO == pVFR->Flags ) )
+ KSCAMERA_EXTENDEDPROP_VFR_ON == pVFR->Flags) )
{
//Set the current VFR state
Status = m_Sensor->SetVFR( pVFR );
@@ -3370,6 +3369,69 @@ SetVideoStabilization(
return Status;
}
+// Get KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING.
+NTSTATUS
+CCaptureFilter::
+GetVideoTemporalDenoising(
+ _Inout_ CExtendedProperty *pVideoTemporalDenoising
+)
+{
+ PAGED_CODE();
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+
+ // Call must come for filter scope only
+ if (pVideoTemporalDenoising->isValid() &&
+ pVideoTemporalDenoising->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE)
+ {
+ //Get the current state
+ Status = m_Sensor->GetVideoTemporalDenoising(pVideoTemporalDenoising);
+ }
+
+ DBG_TRACE("pVideoTemporalDenoising = %p, PinId = %u, Flags = %llu, Version = %u",
+ pVideoTemporalDenoising, pVideoTemporalDenoising->PinId, pVideoTemporalDenoising->Flags, pVideoTemporalDenoising->Version);
+
+ return Status;
+}
+
+// Set KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING.
+NTSTATUS
+CCaptureFilter::
+SetVideoTemporalDenoising(
+ _In_ CExtendedProperty *pVideoTemporalDenoising
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+
+ // Call must come for filter scope only and flags must be supported and mutually exclusive
+ if (pVideoTemporalDenoising->isValid() &&
+ pVideoTemporalDenoising->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE &&
+ !(pVideoTemporalDenoising->Capability & KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL) &&
+ (KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO == pVideoTemporalDenoising->Flags ||
+ KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_OFF == pVideoTemporalDenoising->Flags ||
+ KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_ON == pVideoTemporalDenoising->Flags))
+ {
+ CExtendedProperty Caps(*pVideoTemporalDenoising);
+ Status = m_Sensor->GetVideoTemporalDenoising(&Caps);
+
+ if (NT_SUCCESS(Status))
+ {
+ // Assume an invalid parameter.
+ Status = STATUS_INVALID_PARAMETER;
+
+ if (pVideoTemporalDenoising->Flags == (pVideoTemporalDenoising->Flags & Caps.Capability))
+ {
+ Status = m_Sensor->SetVideoTemporalDenoising(pVideoTemporalDenoising);
+ }
+ }
+ }
+ DBG_TRACE("pVideoTemporalDenoising = %p, PinId = %u, Flags = %llu, Version = %u",
+ pVideoTemporalDenoising, pVideoTemporalDenoising->PinId, pVideoTemporalDenoising->Flags, pVideoTemporalDenoising->Version);
+
+ return Status;
+}
+
// Get KSPROPERTY_CAMERACONTROL_EXTENDED_OIS.
NTSTATUS
CCaptureFilter::
@@ -4078,3 +4140,176 @@ GetVideoControlCaps(
return Status;
}
+NTSTATUS
+CCaptureFilter::GetExtrinsic(
+ _In_opt_ KS_CAMERA_EXTRINSICS *Data,
+ _In_ ULONG PinId,
+ _Inout_ ULONG *Length)
+{
+ PAGED_CODE();
+
+ if( PinId < m_pKSFilter->Descriptor->PinDescriptorsCount )
+ {
+ CCameraExtrinsics_2Transforms Extrinsics( PinId ); // Parameters are just identification for now.
+ if( Data )
+ {
+ RtlCopyMemory(Data, &Extrinsics, sizeof(Extrinsics));
+ }
+
+ *Length = sizeof(Extrinsics);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS
+CCaptureFilter::GetIntrinsic(
+ _In_opt_ KS_CAMERA_INTRINSICS *Data,
+ _In_ ULONG PinId,
+ _Inout_ ULONG *Length)
+{
+ PAGED_CODE();
+
+ if( PinId < m_pKSFilter->Descriptor->PinDescriptorsCount )
+ {
+ CCameraIntrinsics_2Models Intrinsics;
+ if( Data )
+ {
+ RtlCopyMemory(Data, &Intrinsics, sizeof(Intrinsics));
+ }
+
+ *Length = sizeof(Intrinsics);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_INVALID_PARAMETER;
+}
+
+// Get KSPROPERTY_CAMERA_ATTRIBUTES_EXTRINSICS
+NTSTATUS
+CCaptureFilter::GetExtrinsics(
+ _In_ PIRP pIrp,
+ _In_ PKSP_PIN pProperty,
+ _Inout_ PVOID pData
+)
+{
+ PAGED_CODE();
+
+ NT_ASSERT(pIrp);
+ NT_ASSERT(pProperty);
+
+ CCaptureFilter *pFilter = reinterpret_cast <CCaptureFilter *>(KsGetFilterFromIrp(pIrp)->Context);
+ PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
+ ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
+ ULONG RequiredLength = 0;
+
+ NTSTATUS Status =
+ pFilter->GetExtrinsic( nullptr, pProperty->PinId, &RequiredLength );
+
+ // Note: We may want to determine capabilities at runtime in the future.
+
+ // We only handle GETs
+ if( NT_SUCCESS(Status) )
+ {
+ RequiredLength += sizeof(KSCAMERA_ATTRIBUTES_HEADER);
+
+ if (ulOutputBufferLength == 0)
+ {
+ pIrp->IoStatus.Information = RequiredLength;
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (ulOutputBufferLength < RequiredLength)
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else if (pData && ulOutputBufferLength >= RequiredLength)
+ {
+ PKSCAMERA_ATTRIBUTES_HEADER pHdr = (PKSCAMERA_ATTRIBUTES_HEADER) pData;
+ PKS_CAMERA_EXTRINSICS pExtrinsic = (PKS_CAMERA_EXTRINSICS) (pHdr + 1);
+ ULONG Size=0;
+
+ Status =
+ pFilter->GetExtrinsic(
+ pExtrinsic,
+ pProperty->PinId,
+ &Size );
+
+ if( NT_SUCCESS(Status) )
+ {
+ pHdr->Size = RequiredLength;
+ pHdr->PinId = pProperty->PinId;
+ pIrp->IoStatus.Information = RequiredLength;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ return Status;
+}
+
+// Get KSPROPERTY_CAMERA_ATTRIBUTES_INTRINSICS
+NTSTATUS
+CCaptureFilter::GetIntrinsics(
+ _In_ PIRP pIrp,
+ _In_ PKSP_PIN pProperty,
+ _Inout_ PVOID pData
+)
+{
+ PAGED_CODE();
+
+ NT_ASSERT(pIrp);
+ NT_ASSERT(pProperty);
+
+ CCaptureFilter *pFilter = reinterpret_cast <CCaptureFilter *>(KsGetFilterFromIrp(pIrp)->Context);
+ PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
+ ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
+ ULONG RequiredLength = 0;
+
+ NTSTATUS Status =
+ pFilter->GetIntrinsic( nullptr, pProperty->PinId, &RequiredLength );
+
+ // Note: We may want to determine capabilities at runtime in the future.
+
+ // We only handle GETs
+ if( NT_SUCCESS(Status) )
+ {
+ RequiredLength += sizeof(KSCAMERA_ATTRIBUTES_HEADER);
+
+ if (ulOutputBufferLength == 0)
+ {
+ pIrp->IoStatus.Information = RequiredLength;
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (ulOutputBufferLength < RequiredLength)
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else if (pData && ulOutputBufferLength >= RequiredLength)
+ {
+ PKSCAMERA_ATTRIBUTES_HEADER pHdr = (PKSCAMERA_ATTRIBUTES_HEADER) pData;
+ PKS_CAMERA_INTRINSICS pIntrinsic = (PKS_CAMERA_INTRINSICS) (pHdr + 1);
+ ULONG Size=0;
+
+ Status =
+ pFilter->GetIntrinsic(
+ pIntrinsic,
+ pProperty->PinId,
+ &Size );
+
+ if( NT_SUCCESS(Status) )
+ {
+ pHdr->Size = RequiredLength;
+ pHdr->PinId = pProperty->PinId;
+ pIrp->IoStatus.Information = RequiredLength;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ return Status;
+}
+
+
diff --git a/avstream/avscamera/sys/filter.h b/avstream/avscamera/sys/filter.h
index 58a0e9e8..292a6bc7 100644
--- a/avstream/avscamera/sys/filter.h
+++ b/avstream/avscamera/sys/filter.h
@@ -72,6 +72,18 @@ protected:
void
Cleanup();
+ NTSTATUS
+ GetExtrinsic(
+ _In_opt_ KS_CAMERA_EXTRINSICS *Data,
+ _In_ ULONG PinId,
+ _Inout_ ULONG *Length);
+
+ NTSTATUS
+ GetIntrinsic(
+ _In_opt_ KS_CAMERA_INTRINSICS *Data,
+ _In_ ULONG PinId,
+ _Inout_ ULONG *Length);
+
public:
//
@@ -319,6 +331,7 @@ DECLARE_PROPERTY_SET_HANDLER( type, name )
DECLARE_PROPERTY_HANDLERS( CExtendedProperty, Thumbnail )
DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TriggerTime )
DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TorchMode )
+ DECLARE_PROPERTY_HANDLERS( CExtendedProperty, VideoTemporalDenoising)
DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S, VideoStabMode )
DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_FLASH_S, Flash )
@@ -379,6 +392,22 @@ DECLARE_PROPERTY_SET_HANDLER( type, name )
_Outptr_opt_result_maybenull_
ISP_FRAME_SETTINGS **ppSettings );
+ static
+ NTSTATUS
+ GetExtrinsics(
+ _In_ PIRP pIrp,
+ _In_ PKSP_PIN pProperty,
+ _Inout_ PVOID pData
+ );
+
+ static
+ NTSTATUS
+ GetIntrinsics(
+ _In_ PIRP pIrp,
+ _In_ PKSP_PIN pProperty,
+ _Inout_ PVOID pData
+ );
+
// Helper function for finding our filter object.
static
CCaptureFilter *
diff --git a/avstream/avscamera/sys/hwsim.cpp b/avstream/avscamera/sys/hwsim.cpp
index df8240b4..4309befb 100644
--- a/avstream/avscamera/sys/hwsim.cpp
+++ b/avstream/avscamera/sys/hwsim.cpp
@@ -1107,7 +1107,7 @@ Return Value:
**************************************************************************/
-PCCHAR
+const CHAR *
DVS_Text( ULONGLONG Flags )
{
PAGED_CODE();
@@ -1123,12 +1123,12 @@ DVS_Text( ULONGLONG Flags )
CHAR buffer[32];
RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags);
- return (PCCHAR) buffer;
+ return (const CHAR *) buffer;
}
}
}
-PCCHAR
+const CHAR *
OIS_Text( ULONGLONG Flags )
{
PAGED_CODE();
@@ -1144,7 +1144,7 @@ OIS_Text( ULONGLONG Flags )
CHAR buffer[32];
RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags);
- return (PCCHAR) buffer;
+ return (const CHAR *) buffer;
}
}
}
diff --git a/avstream/avscamera/sys/imagehwsim.cpp b/avstream/avscamera/sys/imagehwsim.cpp
index 1f4d7a1a..2ba44721 100644
--- a/avstream/avscamera/sys/imagehwsim.cpp
+++ b/avstream/avscamera/sys/imagehwsim.cpp
@@ -884,7 +884,7 @@ Return Value:
**************************************************************************/
-PCCHAR
+const CHAR *
AdvancedPhoto_Text( ULONGLONG Flags )
{
PAGED_CODE();
@@ -908,7 +908,7 @@ AdvancedPhoto_Text( ULONGLONG Flags )
CHAR buffer[32];
RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags);
- return (PCCHAR) buffer;
+ return (const CHAR *) buffer;
}
}
}
diff --git a/avstream/avshws/README.md b/avstream/avshws/README.md
index 19019304..9474ae60 100644
--- a/avstream/avshws/README.md
+++ b/avstream/avshws/README.md
@@ -17,7 +17,7 @@ This sample features enhanced parameter validation and overflow detection.
Provision a target computer
---------------------------
-After you've cloned the sample repo to your host computer, run Visual Studio, and from the **File** menu, select **Open**, then **Project/Solution...**, navigate to the Avshws sample directory, and select **avshws.sln**.
+After you've installed the sample on your host computer, run Visual Studio, and from the **File** menu, select **Open**, then **Project/Solution...**, navigate to the directory where you've copied the Avshws sample, then to the C++ folder, and select **avshws.vcxproj** (the VC++ Project).
In the **Solution Explorer** pane in Visual Studio, at the top is **Solution 'avshws'**. Right-click this and select **Configuration Manager**. Follow the instructions in [Building a Driver with the WDK](http://msdn.microsoft.com/en-us/library/windows/hardware/ff554644) to set the platform, operating system, and debug configuration you want to use, and to build the sample. This sample project will automatically sign the driver package.
@@ -26,7 +26,7 @@ Provision your target computer using instructions in, for example, [Preparing a
Deploy the driver to the target computer
----------------------------------------
-Now you can deploy the Avshws driver that you've just built to the target computer, using guidance in [Deploying a Driver to a Test Computer](https://docs.microsoft.com/windows-hardware/drivers/develop/deploying-a-driver-to-a-test-computer). Specifically, in the Visual Studio Solution Explorer, right click the Avshws project and select **Properties**. Under Configuration Properties, click **Driver Install** and then **Deployment**. Enter the **Target Device Name** and the host computer automatically provisions the target computer and sets up debugger options.
+Now you can deploy the Avshws driver that you've just built to the target computer, using guidance in [Deploying a Driver to a Test Computer](http://msdn.microsoft.com/en-us/library/windows/hardware/hh454834). Specifically, find the package file under the **Package** folder in the Avshws solution. Right-click **package** and select **Properties**. Under Configuration Properties, click **Driver install** and then **Deployment**. Here you must click the check box for **Enable deployment**, and then click the button to the right of **\<Configure Computer...\>**. In the next dialog you enter the **Target Computer Name** and can let the host computer automatically provision the target computer and set up debugger options.
Finally, in Visual Studio, from the **Build** menu select **Deploy Solution** to deploy the sample to the target computer. On the target computer, you can see the deployed package in the **%Systemdrive%\\drivertest\\drivers** folder.
@@ -35,7 +35,7 @@ Install the driver
On the target computer, open Device Manager, and follow these steps:
-1. In the **Action** menu, select the top node and click **Add Legacy Hardware**. Click **Next** and then **Next** again. You might need to select **Have disk** and search for the driver in the target driver folder that was set up when the test computer was provisioned.
+1. In the **Action** menu, click **Add Legacy Hardware**, and the **Add Hardware Wizard** appears. Click **Next** and then **Next** again.
2. In the **Add Hardware** window, select **Show All Devices**.
3. In the **Manufacturer** list in the left pane, click **Microsoft**.
4. You should see the **AVStream Simulated Hardware Sample** in the **Model** pane on the right. Click this and then click **Next**.
@@ -64,8 +64,8 @@ Run the sample
Follow these steps to see how the sample driver functions:
1. After installation has completed, access the driver through the Graphedt tool. Graphedt.exe is available in the *tools* directory of the WDK.
-2. Before running GraphEdt, use the regsvr32 utility to register the proppage.dll DLL and to enable GraphEdit to display property pages for some of the built-in Microsoft DirectShow filters. Open an elevated command window with Administrator privileges, and navigate to the WDK or SDK *tools* directory that contains proppage.dll.
-3. On the command line, type `regsvr32 "c:\Program Files (x86)\Windows Kits\10\Tools\x64\proppage.dll"`. If the registration succeeds, you'll get a message, "DllRegisterServer in proppage.dll succeeded." Click OK.
+2. Before running GraphEdit, use the regsvr32 utility to register the proppage.dll DLL and to enable GraphEdit to display property pages for some of the built-in Microsoft DirectShow filters. Open an elevated command window with Administrator privileges, and navigate to the WDK or SDK *tools* directory that contains proppage.dll.
+3. On the command line, type regsvr32 proppage.dll. If the registration succeeds, you'll get a message, "DllRegisterServer in proppage.dll succeeded." Click OK.
4. In the Graphedt tool, click the **Graph** menu and click **Insert Filters**. The sample appears under "WDM Streaming Capture Devices" as "avshws Source."
5. Click **Insert Filter**. The sample appears in the graph as a single filter labeled, "avshws Source." There is one output pin, which is the video capture pin. This pin emits video in YUY2 format.
6. Attach this filter to either a DirectShow Video Renderer or to the VMR default video renderer. Then click **Play**.
diff --git a/avstream/avshws/avshws.h b/avstream/avshws/avshws.h
index a6b3d8bc..3b8cc913 100644
--- a/avstream/avshws/avshws.h
+++ b/avstream/avshws/avshws.h
@@ -10,7 +10,7 @@
Abstract:
- AVStream Simulated Hardware Sample header file. This is the
+ AVStream Simulated Hardware Sample header file. This is the
main header.
History:
@@ -44,14 +44,6 @@ extern "C" {
#include <ks.h>
#include <ksmedia.h>
-// Note: Since VS2015 Update 2 overloaded operator new and operator delete may not
-// be declared inline (Level 1 (/W1) on-by-default, warning C4595).
-// See https://msdn.microsoft.com/en-us/library/mt656697.aspx
-//
-// To mitigate this issue, add "#define _NEW_DELETE_OPERATORS_" before "#include <kcom.h>"
-// and implement non-inline operator new and operator delete locally.
-#define _NEW_DELETE_OPERATORS_
-#include <kcom.h>
/*************************************************
@@ -84,7 +76,7 @@ const DebugLevel = DEBUGLVL_TERSE;
#define ABS(x) ((x) < 0 ? (-(x)) : (x))
-#ifndef mmioFOURCC
+#ifndef mmioFOURCC
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
@@ -145,12 +137,12 @@ CaptureFilterCategories [CAPTURE_FILTER_CATEGORIES_COUNT];
//
// capture.cpp externs:
//
-extern
+extern
const
KSALLOCATOR_FRAMING_EX
CapturePinAllocatorFraming;
-extern
+extern
const
KSPIN_DISPATCH
CapturePinDispatch;
@@ -218,38 +210,148 @@ public:
};
+
/*************************************************
Global Functions
*************************************************/
+#ifndef _NEW_DELETE_OPERATORS_
+#define _NEW_DELETE_OPERATORS_
-void __cdecl operator delete[]
+/*************************************************
+
+ Add definitions that are missing for C++14.
+
+*************************************************/
+
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType
+);
+
+PVOID operator new
(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+);
+
+/*++
+
+Routine Description:
+
+ Array new() operator for creating objects with a specified allocation tag.
+
+Arguments:
+
+ iSize -
+ The size of the entire allocation.
+
+ poolType -
+ The type of allocation. Ex: PagedPool or NonPagedPoolNx
+
+ tag -
+ A 4-byte allocation identifier.
+
+Return Value:
+
+ None
+
+--*/
+PVOID
+operator new[](
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+);
+
+/*++
+
+Routine Description:
+
+ Array delete() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+Return Value:
+
+ None
+
+--*/
+void
+__cdecl
+operator delete[](
PVOID pVoid
);
+/*++
+
+Routine Description:
+
+ Sized delete() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+ size -
+ The size of the memory to free.
+
+Return Value:
+
+ None
+
+--*/
void __cdecl operator delete
(
void *pVoid,
size_t /*size*/
);
+/*++
+
+Routine Description:
+
+ Sized delete[]() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+ size -
+ The size of the memory to free.
+
+Return Value:
+
+ None
+
+--*/
void __cdecl operator delete[]
(
void *pVoid,
size_t /*size*/
);
-PVOID operator new
-(
- size_t iSize,
- _When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
- POOL_TYPE poolType,
- ULONG tag
-);
+#endif // _NEW_DELETE_OPERATORS_
+
+
+
/*************************************************
@@ -263,4 +365,4 @@ PVOID operator new
#include "filter.h"
#include "capture.h"
#include <uuids.h>
-#endif //_avshws_h_
+#endif //_avshws_h_ \ No newline at end of file
diff --git a/avstream/avshws/avshws.inf b/avstream/avshws/avshws.inf
index 8360d50f..9bbbc42a 100644
--- a/avstream/avshws/avshws.inf
+++ b/avstream/avshws/avshws.inf
@@ -21,8 +21,8 @@
[Version]
signature="$WINDOWS NT$"
-Class=Media
-ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318}
+Class=Camera
+ClassGuid={ca3e7ab9-b4c3-4ae6-8251-579ef933890f}
Provider=%ProviderName%
Catalogfile=avshws.cat
DriverVer=08/31/2006,6.0.5600.0
diff --git a/avstream/avshws/device.cpp b/avstream/avshws/device.cpp
index 2f54aca4..93376be4 100644
--- a/avstream/avshws/device.cpp
+++ b/avstream/avshws/device.cpp
@@ -21,6 +21,164 @@
**************************************************************************/
#include "avshws.h"
+
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType
+)
+{
+ PVOID result = ExAllocatePoolWithTag(poolType,iSize,'wNCK');
+
+ if (result) {
+ RtlZeroMemory(result,iSize);
+ }
+
+ return result;
+}
+
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+)
+{
+ PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag);
+
+ if (result) {
+ RtlZeroMemory(result,iSize);
+ }
+
+ return result;
+}
+
+PVOID
+operator new[](
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+)
+{
+ PVOID result = ExAllocatePoolWithTag(poolType, iSize, tag);
+
+ if (result)
+ {
+ RtlZeroMemory(result, iSize);
+ }
+
+ return result;
+}
+
+/*++
+
+Routine Description:
+
+ Array delete() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+Return Value:
+
+ None
+
+--*/
+void
+__cdecl
+operator delete[](
+ PVOID pVoid
+)
+{
+ if (pVoid)
+ {
+ ExFreePool(pVoid);
+ }
+}
+
+/*++
+
+Routine Description:
+
+ Sized delete() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+ size -
+ The size of the memory to free.
+
+Return Value:
+
+ None
+
+--*/
+void __cdecl operator delete
+(
+ void *pVoid,
+ size_t /*size*/
+)
+{
+ if (pVoid)
+ {
+ ExFreePool(pVoid);
+ }
+}
+
+/*++
+
+Routine Description:
+
+ Sized delete[]() operator.
+
+Arguments:
+
+ pVoid -
+ The memory to free.
+
+ size -
+ The size of the memory to free.
+
+Return Value:
+
+ None
+
+--*/
+void __cdecl operator delete[]
+(
+ void *pVoid,
+ size_t /*size*/
+)
+{
+ if (pVoid)
+ {
+ ExFreePool(pVoid);
+ }
+}
+
+void __cdecl operator delete
+(
+ PVOID pVoid
+ )
+{
+ if (pVoid) {
+ ExFreePool(pVoid);
+ }
+}
+
/**************************************************************************
PAGEABLE CODE
@@ -161,7 +319,7 @@ Return Value:
//
// By PnP, it's possible to receive multiple starts without an intervening
// stop (to reevaluate resources, for example). Thus, we only perform
- // creations of the simulation on the initial start and ignore any
+ // creations of the simulation on the initial start and ignore any
// subsequent start. Hardware drivers with resources should evaluate
// resources and make changes on 2nd start.
//
@@ -173,7 +331,7 @@ Return Value:
// If we couldn't create the hardware simulation, fail.
//
Status = STATUS_INSUFFICIENT_RESOURCES;
-
+
} else {
Status = KsAddItemToObjectBag (
m_Device -> Bag,
@@ -197,15 +355,15 @@ Return Value:
//
// Set up DMA...
//
- // Ordinarilly, we'd be using InterfaceBuffer or
- // InterfaceTypeUndefined if !NT_SUCCESS (IfStatus) as the
- // InterfaceType below; however, for the purposes of this sample,
+ // Ordinarilly, we'd be using InterfaceBuffer or
+ // InterfaceTypeUndefined if !NT_SUCCESS (IfStatus) as the
+ // InterfaceType below; however, for the purposes of this sample,
// we lie and say we're on the PCI Bus. Otherwise, we're using map
// registers on x86 32 bit physical to 32 bit logical and this isn't
// what I want to show in this sample.
//
//
- // NTSTATUS IfStatus =
+ // NTSTATUS IfStatus =
IoGetDeviceProperty (
m_Device -> PhysicalDeviceObject,
@@ -216,7 +374,7 @@ Return Value:
);
//
- // Initialize our fake device description. We claim to be a
+ // Initialize our fake device description. We claim to be a
// bus-mastering 32-bit scatter/gather capable piece of hardware.
//
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
@@ -229,7 +387,7 @@ Return Value:
DeviceDescription.Dma32BitAddresses = TRUE;
DeviceDescription.AutoInitialize = FALSE;
DeviceDescription.MaximumLength = (ULONG) -1;
-
+
//
// Get a DMA adapter object from the system.
//
@@ -238,21 +396,21 @@ Return Value:
&DeviceDescription,
&m_NumberOfMapRegisters
);
-
+
if (!m_DmaAdapterObject) {
Status = STATUS_UNSUCCESSFUL;
}
-
+
}
-
+
if (NT_SUCCESS (Status)) {
//
- // Initialize our DMA adapter object with AVStream. This is
+ // Initialize our DMA adapter object with AVStream. This is
// **ONLY** necessary **IF** you are doing DMA directly into
// capture buffers as this sample does. For this,
// KSPIN_FLAG_GENERATE_MAPPINGS must be specified on a queue.
//
-
+
//
// The (1 << 20) below is the maximum size of a single s/g mapping
// that this hardware can handle. Note that I have pulled this
@@ -264,11 +422,11 @@ Return Value:
(1 << 20),
sizeof (KSMAPPING)
);
-
+
}
#endif
}
-
+
return Status;
}
@@ -306,7 +464,7 @@ Return Value:
//
// Return the DMA adapter back to the system.
//
- m_DmaAdapterObject -> DmaOperations ->
+ m_DmaAdapterObject -> DmaOperations ->
PutDmaAdapter (m_DmaAdapterObject);
m_DmaAdapterObject = NULL;
@@ -328,7 +486,7 @@ AcquireHardwareResources (
Routine Description:
- Acquire hardware resources for the capture hardware. If the
+ Acquire hardware resources for the capture hardware. If the
resources are already acquired, this will return an error.
The hardware configuration must be passed as a VideoInfoHeader.
@@ -376,44 +534,44 @@ Return Value:
delete m_ImageSynth;
m_ImageSynth = NULL;
}
-
+
//
// Create the necessary type of image synthesizer.
//
if (m_VideoInfoHeader -> bmiHeader.biBitCount == 24 &&
m_VideoInfoHeader -> bmiHeader.biCompression == KS_BI_RGB) {
-
+
//
// If we're RGB24, create a new RGB24 synth. RGB24 surfaces
// can be in either orientation. The origin is lower left if
// height < 0. Otherwise, it's upper left.
//
- m_ImageSynth = new (NonPagedPoolNx, 'RysI')
+ m_ImageSynth = new (NonPagedPoolNx, 'RysI')
CRGB24Synthesizer (
m_VideoInfoHeader -> bmiHeader.biHeight >= 0
);
-
+
} else
if (m_VideoInfoHeader -> bmiHeader.biBitCount == 16 &&
(m_VideoInfoHeader -> bmiHeader.biCompression == FOURCC_YUY2)) {
-
+
//
// If we're UYVY, create the YUV synth.
//
m_ImageSynth = new(NonPagedPoolNx, 'YysI') CYUVSynthesizer;
-
+
}
else
//
// We don't synthesize anything but RGB 24 and UYVY.
//
Status = STATUS_INVALID_PARAMETER;
-
+
if (NT_SUCCESS (Status) && !m_ImageSynth) {
-
+
Status = STATUS_INSUFFICIENT_RESOURCES;
-
- }
+
+ }
if (NT_SUCCESS (Status)) {
//
@@ -428,7 +586,7 @@ Return Value:
//
ReleaseHardwareResources ();
}
-
+
} else {
//
@@ -660,9 +818,9 @@ Return Value:
PAGED_CODE();
+
-
- return
+ return
m_HardwareSimulation -> ProgramScatterGatherMappings (
Clone,
Buffer,
@@ -749,7 +907,7 @@ Return Value:
// of hardware registers (ReadNumberOfMappingsCompleted) which would likely
// be done in the ISR.
//
- ULONG NumMappingsCompleted =
+ ULONG NumMappingsCompleted =
m_HardwareSimulation -> ReadNumberOfMappingsCompleted ();
//
@@ -774,7 +932,7 @@ Return Value:
// CaptureFilterDescriptor:
//
// The filter descriptor for the capture device.
-DEFINE_KSFILTER_DESCRIPTOR_TABLE (FilterDescriptors) {
+DEFINE_KSFILTER_DESCRIPTOR_TABLE (FilterDescriptors) {
&CaptureFilterDescriptor
};
@@ -810,8 +968,8 @@ CaptureDeviceDispatch = {
// This is the device descriptor for the capture device. It points to the
// dispatch table and contains a list of filter descriptors that describe
// filter-types that this device supports. Note that the filter-descriptors
-// can be created dynamically and the factories created via
-// KsCreateFilterFactory as well.
+// can be created dynamically and the factories created via
+// KsCreateFilterFactory as well.
//
const
KSDEVICE_DESCRIPTOR
@@ -865,7 +1023,7 @@ Return Value:
// at add & start. Everything is done based on the descriptors passed
// here.
//
- return
+ return
KsInitializeDriver (
DriverObject,
RegistryPath,
@@ -873,118 +1031,3 @@ Return Value:
);
}
-
-/*************************************************
-
- Global Functions
-
-*************************************************/
-
-/*++
-
-Routine Description:
-
- Array delete() operator.
-
-Arguments:
-
- pVoid -
- The memory to free.
-
-Return Value:
-
- None
-
---*/
-void
-__cdecl
-operator delete[](
- PVOID pVoid
-)
-{
- if (pVoid)
- {
- ExFreePool(pVoid);
- }
-}
-
-/*++
-
-Routine Description:
-
- Sized delete() operator.
-
-Arguments:
-
- pVoid -
- The memory to free.
-
- size -
- The size of the memory to free.
-
-Return Value:
-
- None
-
---*/
-void __cdecl operator delete
-(
- void *pVoid,
- size_t /*size*/
-)
-{
- if (pVoid)
- {
- ExFreePool(pVoid);
- }
-}
-
-/*++
-
-Routine Description:
-
- Sized delete[]() operator.
-
-Arguments:
-
- pVoid -
- The memory to free.
-
- size -
- The size of the memory to free.
-
-Return Value:
-
- None
-
---*/
-void __cdecl operator delete[]
-(
- void *pVoid,
- size_t /*size*/
-)
-{
- if (pVoid)
- {
- ExFreePool(pVoid);
- }
-}
-
-PVOID operator new
-(
- size_t iSize,
- _When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
- POOL_TYPE poolType,
- ULONG tag
-)
-{
- PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag);
-
- if (result) {
- RtlZeroMemory(result,iSize);
- }
-
- return result;
-}
diff --git a/avstream/avssamp/avssamp.cpp b/avstream/avssamp/avssamp.cpp
index 5a2c2b77..68741c9e 100644
--- a/avstream/avssamp/avssamp.cpp
+++ b/avstream/avssamp/avssamp.cpp
@@ -1,20 +1,20 @@
/**************************************************************************
-AVStream Filter-Centric Sample
+ AVStream Filter-Centric Sample
-Copyright (c) 1999 - 2001, Microsoft Corporation
+ Copyright (c) 1999 - 2001, Microsoft Corporation
-File:
+ File:
-avssamp.cpp
+ avssamp.cpp
-Abstract:
+ Abstract:
-This is the main file for the filter-centric sample.
+ This is the main file for the filter-centric sample.
-History:
+ History:
-created 6/18/01
+ created 6/18/01
**************************************************************************/
@@ -22,26 +22,26 @@ created 6/18/01
/**************************************************************************
-INITIALIZATION CODE
+ INITIALIZATION CODE
**************************************************************************/
-
+
extern "C" DRIVER_INITIALIZE DriverEntry;
PVOID operator new
(
size_t iSize,
_When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
POOL_TYPE poolType
- )
+)
{
- PVOID result = ExAllocatePoolWithTag(poolType, iSize, 'wNCK');
+ PVOID result = ExAllocatePoolWithTag(poolType,iSize,'wNCK');
if (result) {
- RtlZeroMemory(result, iSize);
+ RtlZeroMemory(result,iSize);
}
return result;
@@ -51,16 +51,16 @@ PVOID operator new
(
size_t iSize,
_When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
POOL_TYPE poolType,
ULONG tag
- )
+)
{
- PVOID result = ExAllocatePoolWithTag(poolType, iSize, tag);
+ PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag);
if (result) {
- RtlZeroMemory(result, iSize);
+ RtlZeroMemory(result,iSize);
}
return result;
@@ -70,23 +70,23 @@ PVOID operator new
Routine Description:
-Array delete() operator.
+ Array delete() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
Return Value:
-None
+ None
--*/
-void
-__cdecl
+void
+__cdecl
operator delete[](
PVOID pVoid
- )
+)
{
if (pVoid)
{
@@ -98,19 +98,19 @@ operator delete[](
Routine Description:
-Sized delete() operator.
+ Sized delete() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
-size -
-The size of the memory to free.
+ size -
+ The size of the memory to free.
Return Value:
-None
+ None
--*/
void __cdecl operator delete
@@ -129,26 +129,26 @@ void __cdecl operator delete
Routine Description:
-Sized delete[]() operator.
+ Sized delete[]() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
-size -
-The size of the memory to free.
+ size -
+ The size of the memory to free.
Return Value:
-None
+ None
--*/
void __cdecl operator delete[]
(
void *pVoid,
size_t /*size*/
- )
+)
{
if (pVoid)
{
@@ -156,31 +156,41 @@ void __cdecl operator delete[]
}
}
+void __cdecl operator delete
+(
+ PVOID pVoid
+ )
+{
+ if (pVoid) {
+ ExFreePool(pVoid);
+ }
+}
+
extern "C"
NTSTATUS
-DriverEntry(
+DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
-)
+ )
/*++
Routine Description:
-Driver entry point. Pass off control to the AVStream initialization
-function (KsInitializeDriver) and return the status code from it.
+ Driver entry point. Pass off control to the AVStream initialization
+ function (KsInitializeDriver) and return the status code from it.
Arguments:
-DriverObject -
-The WDM driver object for our driver
+ DriverObject -
+ The WDM driver object for our driver
-RegistryPath -
-The registry path for our registry info
+ RegistryPath -
+ The registry path for our registry info
Return Value:
-As from KsInitializeDriver
+ As from KsInitializeDriver
--*/
@@ -193,17 +203,17 @@ As from KsInitializeDriver
// here.
//
return
- KsInitializeDriver(
+ KsInitializeDriver (
DriverObject,
RegistryPath,
&CaptureDeviceDescriptor
- );
+ );
}
/**************************************************************************
-DESCRIPTOR AND DISPATCH LAYOUT
+ DESCRIPTOR AND DISPATCH LAYOUT
**************************************************************************/
@@ -213,7 +223,7 @@ DESCRIPTOR AND DISPATCH LAYOUT
// The table of filter descriptors that this device supports. Each one of
// these will be used as a template to create a filter-factory on the device.
//
-DEFINE_KSFILTER_DESCRIPTOR_TABLE(FilterDescriptors) {
+DEFINE_KSFILTER_DESCRIPTOR_TABLE (FilterDescriptors) {
&CaptureFilterDescriptor
};
@@ -236,7 +246,7 @@ CaptureDeviceDescriptor = {
// by AVStream will be quite sufficient.
//
NULL,
- SIZEOF_ARRAY(FilterDescriptors),
+ SIZEOF_ARRAY (FilterDescriptors),
FilterDescriptors,
KSDEVICE_DESCRIPTOR_VERSION
};
diff --git a/avstream/avssamp/avssamp.h b/avstream/avssamp/avssamp.h
index 7d0bd7c3..b00cb7ba 100644
--- a/avstream/avssamp/avssamp.h
+++ b/avstream/avssamp/avssamp.h
@@ -1,27 +1,27 @@
/**************************************************************************
-AVStream Filter-Centric Sample
+ AVStream Filter-Centric Sample
-Copyright (c) 2001, Microsoft Corporation
+ Copyright (c) 2001, Microsoft Corporation
-File:
+ File:
-avssamp.h
+ avssamp.h
-Abstract:
+ Abstract:
-AVStream Filter-Centric Sample header file. This is the main
-header.
+ AVStream Filter-Centric Sample header file. This is the main
+ header.
-History:
+ History:
-created 6/18/01
+ created 6/18/01
**************************************************************************/
/*************************************************
-Standard Includes
+ Standard Includes
*************************************************/
@@ -42,7 +42,7 @@ extern "C" {
#pragma warning (disable : 4100 4101 4131 4127 4189 4701 4706)
/*************************************************
-Misc Definitions
+ Misc Definitions
*************************************************/
@@ -81,7 +81,7 @@ Misc Definitions
/*************************************************
-Externed information
+ Externed information
*************************************************/
@@ -101,12 +101,12 @@ CaptureFilterDescriptor;
extern
const
KSPIN_DESCRIPTOR_EX
-CaptureFilterPinDescriptors[CAPTURE_FILTER_PIN_COUNT];
+CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT];
extern
const
GUID
-CaptureFilterCategories[CAPTURE_FILTER_CATEGORIES_COUNT];
+CaptureFilterCategories [CAPTURE_FILTER_CATEGORIES_COUNT];
//
// video.cpp externs:
@@ -124,7 +124,7 @@ VideoCapturePinDispatch;
extern
const
PKSDATARANGE
-VideoCapturePinDataRanges[CAPTURE_PIN_DATA_RANGE_COUNT];
+VideoCapturePinDataRanges [CAPTURE_PIN_DATA_RANGE_COUNT];
//
// audio.cpp externs:
@@ -149,60 +149,60 @@ PVOID operator new
(
size_t iSize,
_When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
POOL_TYPE poolType
- );
+);
PVOID operator new
(
size_t iSize,
_When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
POOL_TYPE poolType,
ULONG tag
- );
+);
/*++
Routine Description:
-Array delete() operator.
+ Array delete() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
Return Value:
-None
+ None
--*/
-void
-__cdecl
+void
+__cdecl
operator delete[](
PVOID pVoid
- );
+);
/*++
Routine Description:
-Sized delete() operator.
+ Sized delete() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
-size -
-The size of the memory to free.
+ size -
+ The size of the memory to free.
Return Value:
-None
+ None
--*/
void __cdecl operator delete
@@ -215,32 +215,32 @@ void __cdecl operator delete
Routine Description:
-Sized delete[]() operator.
+ Sized delete[]() operator.
Arguments:
-pVoid -
-The memory to free.
+ pVoid -
+ The memory to free.
-size -
-The size of the memory to free.
+ size -
+ The size of the memory to free.
Return Value:
-None
+ None
--*/
void __cdecl operator delete[]
(
void *pVoid,
size_t /*size*/
- );
+);
#endif // _NEW_DELETE_OPERATORS_
/*************************************************
-Internal Includes
+ Internal Includes
*************************************************/
diff --git a/avstream/avssamp/avssamp.inf b/avstream/avssamp/avssamp.inf
index 62db5009..00003e78 100644
--- a/avstream/avssamp/avssamp.inf
+++ b/avstream/avssamp/avssamp.inf
@@ -14,8 +14,8 @@
[Version]
Signature="$Windows NT$"
-Class=MEDIA
-ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318}
+Class=Camera
+ClassGuid={ca3e7ab9-b4c3-4ae6-8251-579ef933890f}
Provider=%ProviderName%
CatalogFile=avssamp.cat
DriverVer=09/30/2004,1.0.0.0
diff --git a/avstream/sampledevicemft/README.md b/avstream/sampledevicemft/README.md
new file mode 100644
index 00000000..085cd9a2
--- /dev/null
+++ b/avstream/sampledevicemft/README.md
@@ -0,0 +1,38 @@
+<!---
+ Driver Device Transform Sample
+ platform: WDM
+ language: cpp
+ category: Camera
+ description: A driver device transform which loads in a process streaming an Avstream based camera device using Media Foundation.
+ samplefwlink: https://go.microsoft.com/fwlink/?linkid=866747
+--->
+
+Driver Device Transform Sample
+==============================
+Illustrative example for a *Driver Device Transform* which loads in a process streaming an Avstream based camera device using Media Foundation.
+
+A *Driver Device Transform* is a new kind of a transform that's used with a specific camera when capturing video. The *Driver Device Transform* is also known as DeviceMFT because it is the first Device Transform applied to the video source. This *Driver Device Transform* is an alternative to the Driver MFT i.e. MFT0 in that, it caters to the source rather than the streams . An N stream source supporting DeviceMFT will have a single instance of the *Device Driver Transform* loaded, while MFT0 will have *N* instances for each pipeline process. The DeviceMFT can advertise multiple streams at the output, which can differ from the number of streams advertised by the source. This is analogous to having a user mode driver in the MF pipeline which intercepts and processes commands before they enter/ leave the Kernel mode driver loaded for the streaming source.
+
+In this sample, the Device Transform , when enabled, will replicate a photo sequence in the user mode from a one pin device . It acts as a passthrough for sources exposing more than one pins.
+
+This sample is designed to be used with a specific camera. To run the sample, you need the your camera's device ID and device metadata package.
+
+
+Related topics
+--------------
+
+**Concepts**
+
+[Windows Store device apps for cameras](http://go.microsoft.com/fwlink/p/?LinkId=306683)
+
+[Media Foundation Transforms](http://msdn.microsoft.com/en-us/library/windows/hardware/ms703138)
+
+[Roadmap for Developing Streaming Media Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff568130)
+
+[Universal camera driver design guide for Windows 10](https://msdn.microsoft.com/en-us/Library/Windows/Hardware/dn937080)
+
+**Samples**
+
+[Windows Store device app for camera sample](http://go.microsoft.com/fwlink/p/?linkid=249442)
+
+[Camera Capture UI sample](http://go.microsoft.com/fwlink/p/?linkid=249441%20) \ No newline at end of file
diff --git a/avstream/sampledevicemft/basepin.cpp b/avstream/sampledevicemft/basepin.cpp
index a1f71860..80647f39 100644
--- a/avstream/sampledevicemft/basepin.cpp
+++ b/avstream/sampledevicemft/basepin.cpp
@@ -27,36 +27,45 @@ CBasePin::CBasePin( _In_ ULONG id, _In_ CMultipinMft *parent) :
m_StreamId(id)
, m_Parent(parent)
, m_setMediaType(nullptr)
+ , m_nRefCount(0)
+ , m_state(DeviceStreamState_Stop)
{
}
CBasePin::~CBasePin()
{
- IMFMediaType *pMediaType = nullptr;
+
for ( ULONG ulIndex = 0, ulSize = (ULONG)m_listOfMediaTypes.size(); ulIndex < ulSize; ulIndex++ )
{
- pMediaType = m_listOfMediaTypes[ulIndex];
- SAFE_RELEASE(pMediaType);
+ ComPtr<IMFMediaType> spMediaType;
+ spMediaType.Attach(m_listOfMediaTypes[ulIndex]); // Releases the previously stored pointer
}
m_listOfMediaTypes.clear();
m_spAttributes = nullptr;
}
+STDMETHODIMP_(DeviceStreamState) CBasePin::GetState()
+{
+ return (DeviceStreamState) InterlockedCompareExchange((PLONG)&m_state, 0L,0L);
+}
+
+STDMETHODIMP_(DeviceStreamState) CBasePin::SetState(_In_ DeviceStreamState state)
+{
+ return (DeviceStreamState) InterlockedExchange((LONG*)&m_state, state);
+}
+
HRESULT CBasePin::AddMediaType( _Inout_ DWORD *pos, _In_ IMFMediaType *pMediaType)
{
HRESULT hr = S_OK;
CAutoLock Lock(lock());
DMFTCHECKNULL_GOTO(pMediaType, done, E_INVALIDARG);
-
hr = ExceptionBoundary([&]()
{
m_listOfMediaTypes.push_back(pMediaType);
});
-
DMFTCHECKHR_GOTO(hr, done);
pMediaType->AddRef();
-
if (pos)
{
*pos = (DWORD)(m_listOfMediaTypes.size() - 1);
@@ -70,17 +79,15 @@ HRESULT CBasePin::GetMediaTypeAt( _In_ DWORD pos, _Outptr_result_maybenull_ IMFM
{
HRESULT hr = S_OK;
CAutoLock Lock(lock());
+ ComPtr<IMFMediaType> spMediaType;
DMFTCHECKNULL_GOTO(ppMediaType,done,E_INVALIDARG);
-
+ *ppMediaType = nullptr;
if (pos >= m_listOfMediaTypes.size())
{
DMFTCHECKHR_GOTO(MF_E_NO_MORE_TYPES,done);
}
- *ppMediaType = m_listOfMediaTypes[pos];
- if (*ppMediaType)
- {
- (*ppMediaType)->AddRef();
- }
+ spMediaType = m_listOfMediaTypes[pos];
+ *ppMediaType = spMediaType.Detach();
done:
return hr;
}
@@ -134,7 +141,9 @@ done:
}
-STDMETHODIMP CBasePin::GetOutputAvailableType(_In_ DWORD dwTypeIndex, _Out_opt_ IMFMediaType** ppType)
+STDMETHODIMP CBasePin::GetOutputAvailableType(
+ _In_ DWORD dwTypeIndex,
+ _Out_opt_ IMFMediaType** ppType)
{
return GetMediaTypeAt( dwTypeIndex, ppType );
}
@@ -147,32 +156,27 @@ HRESULT CBasePin::QueryInterface(
{
HRESULT hr = S_OK;
- DMFTCHECKNULL_GOTO(ppv, out, E_POINTER);
-
+ DMFTCHECKNULL_GOTO(ppv, done, E_POINTER);
*ppv = nullptr;
-
if ( iid == __uuidof( IUnknown ) )
{
*ppv = static_cast<VOID*>(this);
- AddRef();
}
- else
- if ( iid == __uuidof( IMFAttributes ) )
+ else if ( iid == __uuidof( IMFAttributes ) )
{
*ppv = static_cast< IMFAttributes* >( this );
- AddRef();
}
- else
- if ( iid == __uuidof( IKsControl ) )
+ else if ( iid == __uuidof( IKsControl ) )
{
*ppv = static_cast< IKsControl* >( this );
- AddRef();
}
else
{
hr = E_NOINTERFACE;
+ goto done;
}
-out:
+ AddRef();
+done:
return hr;
}
@@ -189,9 +193,6 @@ CInPin::CInPin(
:
CBasePin(ulPinId, pParent),
m_stStreamType(GUID_NULL),
- m_activeStreamCount(0),
- m_state(DeviceStreamState_Stop),
- m_prefferedMediaType(nullptr),
m_waitInputMediaTypeWaiter(NULL),
m_preferredStreamState(DeviceStreamState_Stop)
{
@@ -205,18 +206,10 @@ CInPin::~CInPin()
setAttributes( nullptr );
m_spSourceTransform = nullptr;
- for (ULONG ulIndex = 0, ulSize = (ULONG)m_outpins.size();
- ulIndex < ulSize;
- ulIndex++)
- {
- CBasePin *pPin = m_outpins[ulIndex];
- SAFERELEASE(pPin);
- }
if (m_waitInputMediaTypeWaiter)
{
CloseHandle(m_waitInputMediaTypeWaiter);
}
-
}
@@ -266,7 +259,7 @@ done:
}
-STDMETHODIMP CInPin::GenerateMFMediaTypeListFromDevice(
+HRESULT CInPin::GenerateMFMediaTypeListFromDevice(
_In_ UINT uiStreamId
)
{
@@ -297,23 +290,17 @@ STDMETHODIMP CInPin::SendSample(
)
{
HRESULT hr = S_OK;
- BOOL sentOne = TRUE;
- DMFTCHECKNULL_GOTO(pSample, done, S_OK);
-
- for ( ULONG ulIndex = 0, ulSize = (ULONG) m_outpins.size(); ulIndex < ulSize; ulIndex++ )
+ CAutoLock Lock(lock());
+ if (FAILED(Active()))
{
- COutPin *poPin = (COutPin *)m_outpins[ ulIndex ];
-
- pSample->AddRef();
-
- if (FAILED(hr = poPin->AddSample(pSample, this)))
- {
- pSample->Release();
- }
- sentOne = (sentOne || SUCCEEDED(hr));
+ goto done;
}
-done:
- return sentOne ? S_OK : E_FAIL;
+ COutPin *poPin = static_cast<COutPin*>(m_outpin.Get());
+ DMFTCHECKNULL_GOTO(pSample, done, S_OK);
+ DMFTCHECKHR_GOTO(poPin->AddSample(pSample, this), done);
+ DMFTCHECKHR_GOTO(Parent()->QueueEvent(METransformHaveOutput, GUID_NULL, S_OK, NULL),done);
+ done:
+ return hr;
}
STDMETHODIMP_(VOID) CInPin::ConnectPin( _In_ CBasePin * poPin )
@@ -321,20 +308,10 @@ STDMETHODIMP_(VOID) CInPin::ConnectPin( _In_ CBasePin * poPin )
CAutoLock Lock(lock());
if (poPin!=nullptr)
{
- m_outpins.push_back(poPin);
- poPin->AddRef();
+ m_outpin = poPin;
}
}
-STDMETHODIMP_(DeviceStreamState) CInPin::GetState()
-{
- return m_state;
-}
-
-STDMETHODIMP_(DeviceStreamState) CInPin::SetState( _In_ DeviceStreamState state )
-{
- return (DeviceStreamState)InterlockedExchange((LONG*)&m_state, state );
-}
STDMETHODIMP CInPin::WaitForSetInputPinMediaChange()
{
@@ -353,7 +330,7 @@ done:
return hr;
}
-STDMETHODIMP CInPin::GetInputStreamPreferredState(
+HRESULT CInPin::GetInputStreamPreferredState(
_Inout_ DeviceStreamState* value,
_Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType
)
@@ -369,9 +346,9 @@ STDMETHODIMP CInPin::GetInputStreamPreferredState(
if (ppMediaType )
{
*ppMediaType = nullptr;
- if ( m_prefferedMediaType != nullptr )
+ if (m_spPrefferedMediaType != nullptr )
{
- m_prefferedMediaType.CopyTo(ppMediaType);
+ m_spPrefferedMediaType.CopyTo(ppMediaType);
}
}
@@ -400,12 +377,16 @@ HRESULT CInPin::SetInputStreamState(
//Set the event. This event is being waited by an output media/state change operation
//
- m_prefferedMediaType = nullptr;
+ m_spPrefferedMediaType = nullptr;
SetEvent(m_waitInputMediaTypeWaiter);
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
}
+void CInPin::ReleaseConnectedPins()
+{
+ m_outpin = nullptr;
+}
//
//Output Pin Implementation
@@ -416,34 +397,12 @@ COutPin::COutPin(
_In_ IKsControl* pIksControl
)
: CBasePin( ulPinId, pparent ),
- m_firstSample( false )
+ m_firstSample( false ),
+ m_queue(nullptr)
{
HRESULT hr = S_OK;
- CPinState* pState = NULL;
ComPtr<IMFAttributes> spAttributes;
- for ( ULONG ulIndex = 0; ulIndex <= DeviceStreamState_Disabled; ulIndex++ )
- {
- switch ( ulIndex )
- {
-
- case DeviceStreamState_Run:
- pState = ( CPinState* )new CPinOpenState(this);
- DMFTCHECKNULL_GOTO(pState, done, E_OUTOFMEMORY);
- break;
- case DeviceStreamState_Pause:
- case DeviceStreamState_Stop:
- case DeviceStreamState_Disabled:
- //Currently both the closed and the drain state behave similarly
- pState = ( CPinState* )new CPinClosedState();
- DMFTCHECKNULL_GOTO(pState, done, E_OUTOFMEMORY);
- break;
- }
-
- m_states.push_back( pState );
-
- m_state = m_states[ DeviceStreamState_Stop ];
- }
//
//Get the input pin IKS control.. the pin IKS control talks to sourcetransform's IKS control
//
@@ -461,24 +420,11 @@ done:
COutPin::~COutPin()
{
- CPinQueue *que = NULL;
m_spAttributes = nullptr;
-
- for ( ULONG ulIndex = 0, ulSize = (ULONG)m_queues.size(); ulIndex < ulSize; ulIndex++ )
- {
- que = m_queues[ ulIndex ];
- delete(que);
- que = NULL;
- }
- CPinState *pinState = NULL;
- for (ULONG ulIndex = 0, ulSize = (ULONG)m_states.size(); ulIndex < ulSize; ulIndex++)
+ if (m_queue)
{
- pinState = m_states[ ulIndex ];
- delete( pinState );
- pinState = NULL;
+ SAFE_DELETE(m_queue);
}
- m_states.clear();
- m_queues.clear();
}
/*++
@@ -497,13 +443,19 @@ STDMETHODIMP COutPin::AddPin(
HRESULT hr = S_OK;
CAutoLock Lock(lock());
- CPinQueue *que = new (std::nothrow) CPinQueue(inputPinId);
- DMFTCHECKNULL_GOTO( que, done, E_OUTOFMEMORY );
- hr = ExceptionBoundary([&]()
+ if (m_queue != NULL)
{
- (void)m_queues.push_back(que);
- });
- DMFTCHECKHR_GOTO(hr, done);
+ // This pin is alreaqdy connected.. This sample only supports a one on one pin mapping
+ DMFTCHECKHR_GOTO(E_UNEXPECTED, done);
+
+ }
+#if defined MF_DEVICEMFT_ADD_GRAYSCALER_ // Take this out to remove the gray scaler
+ m_queue = new (std::nothrow) CPinQueueWithGrayScale(inputPinId);
+#else
+ m_queue = new (std::nothrow) CPinQueue(inputPinId);
+#endif
+ DMFTCHECKNULL_GOTO(m_queue, done, E_OUTOFMEMORY );
+
//
//Just ramdonmize media types for odd numbered pins
//
@@ -525,29 +477,20 @@ Called from AddSample if the Output Pin is in open state. This function looks fo
corresponding to the input pin and adds it in the queue.
--*/
-STDMETHODIMP COutPin::AddSampleInternal( _In_ IMFSample *pSample, _In_ CBasePin *pPin )
+STDMETHODIMP COutPin::AddSampleInternal(
+ _In_ IMFSample *pSample,
+ _In_ CBasePin *pPin )
{
- BOOL res = true;
+ HRESULT hr = S_OK;
+ UNREFERENCED_PARAMETER(pPin);
CAutoLock Lock( lock() );
-
- for ( DWORD dwIndex = 0, dwSize = (DWORD)m_queues.size(); dwIndex < dwSize; dwIndex++ )
- {
- //
- //This output pin maybe connected to multiple input pins
- //Only insert into the corresponding queue to the input pin on which the
- //sample is received
- //
- if (m_queues[dwIndex]->pinStreamId() == pPin->streamId())
- {
- if (! m_queues[ dwIndex ]->Insert( pSample ) )
- {
- res |= false;
- }
-
- }
- }
- return res ? S_OK : E_FAIL;
-}
+ //
+ // Add the sample into the queue. Add Ref the Sample
+ //
+ DMFTCHECKHR_GOTO(m_queue->Insert(pSample), done);
+done:
+return hr;
+ }
/*++
COutPin::AddSample
@@ -556,13 +499,17 @@ Called when ProcessInput is called on the Device Transform. The Input Pin puts t
in the pins connected. If the Output pins are in open state the sample lands in the queues
--*/
-STDMETHODIMP COutPin::AddSample( _In_ IMFSample *pSample, _In_ CBasePin *pPin)
+STDMETHODIMP COutPin::AddSample(
+ _In_ IMFSample *pSample,
+ _In_ CBasePin *pPin)
{
HRESULT hr = S_OK;
CAutoLock lock( lock() );
-
- DMFTCHECKHR_GOTO( m_state->Open(), done );
-
+ DMFTCHECKNULL_GOTO(pSample, done, E_INVALIDARG);
+ if (FAILED(Active()))
+ {
+ goto done;
+ }
DMFTCHECKHR_GOTO( AddSampleInternal( pSample, pPin ),done );
done:
@@ -581,31 +528,6 @@ STDMETHODIMP_(VOID) COutPin::SetFirstSample(
}
/*++
-COutPin::GetState
-Description:
-State getter for the output pin
---*/
-DeviceStreamState COutPin::GetState()
-{
- return m_state->State();
-}
-
-/*++
-COutPin::SetState
-Description:
-State setter for the output pin
---*/
-
-DeviceStreamState COutPin::SetState(DeviceStreamState state)
-{
- CAutoLock Lock(lock());
- DeviceStreamState oldState = m_state->State();
- m_state = m_states[state];
- return oldState;
-
-}
-
-/*++
COutPin::FlushQueues
Description:
Called from the device Transform when the output queues have to be flushed
@@ -615,14 +537,8 @@ HRESULT COutPin::FlushQueues()
{
HRESULT hr = S_OK;
CAutoLock Lock( lock() );
-
- for ( DWORD dwIndex = 0, dwSize = (DWORD) m_queues.size(); dwIndex < dwSize; dwIndex++ )
- {
- CPinQueue *que = m_queues[ dwIndex ];
- que->Clear();
- }
-
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ (VOID)m_queue->Clear();
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
}
/*++
@@ -633,47 +549,28 @@ the xvp being possibly installed in the queue if the media types set on the inpu
and the output dont match
--*/
HRESULT COutPin::ChangeMediaTypeFromInpin(
- _In_ CInPin* inPin,
_In_ IMFMediaType *pInMediatype,
_In_ IMFMediaType* pOutMediaType,
_In_ DeviceStreamState state)
{
HRESULT hr = S_OK;
- CPinQueue *que = NULL;
+ ComPtr<IUnknown> spD3DManagerUnk = NULL;
CAutoLock Lock(lock());
//
//Set the state to disabled and while going out we will reset the state back to the requested state
//Flush so that we drop any samples we have in store!!
//
SetState(DeviceStreamState_Disabled);
- FlushQueues();
-
- for (DWORD dwIndex = 0, dwSize = (DWORD) m_queues.size(); dwIndex < dwSize; dwIndex++)
- {
- que = m_queues[ dwIndex ];
- if (inPin->streamId() == que->pinStreamId())
- {
- break;
- }
- que = NULL;
- }
-
- if ( que )
+ DMFTCHECKHR_GOTO(FlushQueues(),done);
+ DMFTCHECKNULL_GOTO(m_queue,done, E_UNEXPECTED); // The queue should alwaye be set
+ (VOID)Parent()->GetD3DDeviceManager(spD3DManagerUnk.GetAddressOf());
+ hr = m_queue->RecreateTee( pInMediatype, pOutMediaType, spD3DManagerUnk.Get() );
+ if ( SUCCEEDED( hr ) )
{
- //
- //recreate the tee, pass the D3D Manager to the Tee which will use DX if D3D manager is present
- //
- IUnknown *pD3DManagerUnk = NULL;
-
- (VOID)Parent()->GetD3DDeviceManager( &pD3DManagerUnk );
- hr = que->RecreateTee( pInMediatype, pOutMediaType, pD3DManagerUnk );
- if ( SUCCEEDED( hr ) )
- {
- (VOID)setMediaType( pOutMediaType );
- (VOID)SetState( state );
- }
- SAFE_RELEASE(pD3DManagerUnk);
+ (VOID)setMediaType( pOutMediaType );
+ (VOID)SetState( state );
}
+done:
return hr;
}
@@ -719,103 +616,38 @@ STDMETHODIMP COutPin::ProcessOutput(_In_ DWORD dwFlags,
_Out_ DWORD *pdwStatus
)
{
- HRESULT hr = S_OK;
- IMFSample* pSample = nullptr;
- GUID pinClsid = GUID_NULL;
- BOOL IsImagePin = FALSE;
- BOOL IsSkipSample = FALSE;
+ HRESULT hr = S_OK;
+ ComPtr<IMFSample> spSample;
+ MFTIME llTime = 0L;
+
UNREFERENCED_PARAMETER(pdwStatus);
UNREFERENCED_PARAMETER(dwFlags);
CAutoLock lock(lock());
- DMFTCHECKHR_GOTO(m_state->Open(), done);
-
- //
- //Check if we are an image photo pin. The process output in that case should only proceed if trigger has been sent
- //Candidate for subclass!
- //
-
- if (SUCCEEDED(GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinClsid))
- && ((IsEqualCLSID(pinClsid, PINNAME_IMAGE)) || IsEqualCLSID(pinClsid, PINNAME_VIDEO_STILL)))
- {
- IsImagePin = TRUE;
- }
- if (IsImagePin && !Parent()->isPhotoTriggerSent())
+ if (FAILED(Active()))
{
- IsSkipSample = TRUE;
+ goto done;
}
-
-
-
- for ( DWORD dwIndex = 0, dwSize = (DWORD) m_queues.size(); dwIndex < dwSize; dwIndex++ )
+
+ DMFTCHECKNULL_GOTO(m_queue, done, MF_E_INVALID_STREAM_STATE);
+ pOutputSample->dwStatus = S_OK;
+ DMFTCHECKHR_GOTO(m_queue->Remove(spSample.GetAddressOf()), done);
+ if (FAILED(spSample->GetSampleTime(&llTime)))
{
- CPinQueue *que = m_queues[dwIndex];
-
- pOutputSample->dwStatus = S_OK;
-
- if (!que->Remove(&pSample))
- {
- break;
- }
-
- MFTIME llTime = 0L;
-
- if (FAILED(pSample->GetSampleTime(&llTime)))
- {
- llTime = MFGetSystemTime();
- pSample->SetSampleTime(llTime);
- }
-
- if (!IsSkipSample)
- {
- if (m_firstSample)
- {
- pSample->SetUINT32(MFSampleExtension_Discontinuity,TRUE);
- SetFirstSample(FALSE);
- }
-
- //
- // Any processing before we pass the sample to further in the pipeline should be done here
- // PROCESSSAMPLE(pSample);
- //
-
- pOutputSample->pSample = pSample;
- pOutputSample->dwStatus = S_OK;
- }
- else
- {
- SAFERELEASE(pSample);
- }
+ llTime = MFGetSystemTime();
+ spSample->SetSampleTime(llTime);
}
- if (!IsSkipSample && IsImagePin && pSample)
+ if (m_firstSample)
{
- //
- //A sample has been sent over so image pin should exit
- //
-#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- if (Parent()->IsPhotoConfirmationEnabled())
- {
- //
- // Photo confirmation is enabled i.e. the pipeline has set up photo confirmation
- // Service photo confirmation.
- //
- ComPtr<IMFMediaType> spMediaType = nullptr;
-
- DMFTCHECKHR_GOTO(getMediaType(spMediaType.GetAddressOf()), done);
-
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Calling PhotoConfirmation %p, is passed", pSample);
-
- DMFTCHECKHR_GOTO(Parent()->ProcessCapturePhotoConfirmationCallBack(spMediaType.Get(), pSample), done);
- }
-#endif
- if (!Parent()->isPhotoModePhotoSequence())
- {
- //
- //A sample has been sent over so image pin should exit
- //
- Parent()->setPhotoTriggerSent(FALSE);
- }
+ spSample->SetUINT32(MFSampleExtension_Discontinuity,TRUE);
+ SetFirstSample(FALSE);
}
+ //
+ // Any processing before we pass the sample to further in the pipeline should be done here
+ // PROCESSSAMPLE(pSample);
+ //
+ pOutputSample->pSample = spSample.Get();
+ pOutputSample->dwStatus = S_OK;
done:
return hr;
}
@@ -843,5 +675,97 @@ STDMETHODIMP COutPin::KsProperty(
pBytesReturned);
}
+//
+// Asynchronous IO handling.
+//
+
+STDMETHODIMP CAsyncInPin::SendSample(_In_ IMFSample *pSample)
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+ if (!m_bFlushing)
+ {
+ if (m_dwWorkQueueId == MFASYNC_CALLBACK_QUEUE_UNDEFINED)
+ {
+ //
+ // Set the queue now
+ // We will have the work queue id set before we start streaming
+ //
+ m_dwWorkQueueId = Parent()->GetQueueId();
+ }
+ DMFTCHECKHR_GOTO(MFPutWorkItem(m_dwWorkQueueId, &m_asyncCallback, pSample), done);
+ pSample->AddRef();
+ if (1 == InterlockedIncrement(&m_dwSamplesInFlight))
+ {
+ ResetEvent(m_hHandle);
+ }
+ }
+ else
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! 0x%p Pin Flushing %d",this, streamId());
+ // Let the sample fall through
+ }
+done:
+ return hr;
+}
+
+STDMETHODIMP CAsyncInPin::SendSampleInternal(_In_ IMFSample *pSample)
+{
+ HRESULT hr = S_OK;
+ CAutoLock Lock(lock());
+ DMFTCHECKNULL_GOTO(pSample, done, E_INVALIDARG);
+ hr = CInPin::SendSample(pSample);
+ pSample->Release();
+ if (0 == InterlockedDecrement(&m_dwSamplesInFlight))
+ {
+ // No samples in flight.. Set the Event
+ SetEvent(m_hHandle);
+ }
+done:
+ return hr;
+}
+STDMETHODIMP CAsyncInPin::CDMFTAsyncCallback::Invoke(_In_ IMFAsyncResult* pResult)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IUnknown> spUnknown;
+ ComPtr<IMFSample> spSample;
+ DMFTCHECKNULL_GOTO(pResult, done, E_UNEXPECTED);
+ DMFTCHECKHR_GOTO(pResult->GetState(&spUnknown), done);
+ DMFTCHECKHR_GOTO(spUnknown->QueryInterface(__uuidof(IUnknown), reinterpret_cast<PVOID*>(spSample.GetAddressOf())), done);
+ CAsyncInPin *pPin = GetParent();
+ DMFTCHECKNULL_GOTO(pPin, done, E_UNEXPECTED);
+ DMFTCHECKHR_GOTO(pPin->SendSampleInternal(spSample.Get()), done);
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
+
+
+STDMETHODIMP CAsyncInPin::FlushQueues()
+{
+ HRESULT hr = S_OK;
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Entering ");
+ // Flush in async mode else it is a NOOP
+ {
+ CAutoLock Lock(lock());
+ if (m_bFlushing)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Pin %d Already Flushing ", streamId());
+ goto done;
+ }
+ m_bFlushing = TRUE;
+ }
+ //
+ // Wait for the IOs to drain
+ //
+ WaitForSingleObject(m_hHandle, INFINITE);
+ {
+ CAutoLock Lock(lock());
+ m_bFlushing = FALSE;
+ }
+done:
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
+ return hr;
+}
diff --git a/avstream/sampledevicemft/basepin.h b/avstream/sampledevicemft/basepin.h
index 9b254e2a..24c2e765 100644
--- a/avstream/sampledevicemft/basepin.h
+++ b/avstream/sampledevicemft/basepin.h
@@ -25,8 +25,8 @@ public:
CBasePin( _In_ ULONG _id=0, _In_ CMultipinMft *parent=NULL);
virtual ~CBasePin() = 0;
- virtual STDMETHODIMP_(DeviceStreamState) GetState() = 0;
- virtual STDMETHODIMP_(DeviceStreamState) SetState( _In_ DeviceStreamState State) = 0;
+ virtual STDMETHODIMP_(DeviceStreamState) GetState();
+ virtual STDMETHODIMP_(DeviceStreamState) SetState( _In_ DeviceStreamState State);
//
@@ -80,8 +80,13 @@ public:
return E_NOTIMPL;
}
}
+ virtual STDMETHODIMP FlushQueues(
+ )
+ {
+ return S_OK;
+ }
//
- //NOOPs for this iteration..
+ // NOOPs for this iteration..
//
STDMETHOD(KsMethod)(
_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
@@ -360,6 +365,11 @@ public:
//
//Helper Functions
//
+ __requires_lock_held(m_lock)
+ __inline HRESULT Active()
+ {
+ return (m_state == DeviceStreamState_Run)?S_OK:E_FAIL;
+ }
__inline DWORD streamId()
{
return m_StreamId;
@@ -389,11 +399,7 @@ public:
__inline STDMETHOD (getPinAttributes) (_In_ IMFAttributes **ppAttributes)
{
- HRESULT hr = S_OK;
- DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG );
- DMFTCHECKHR_GOTO ( QueryInterface( IID_PPV_ARGS(ppAttributes) ), done );
- done:
- return hr;
+ return QueryInterface( IID_PPV_ARGS(ppAttributes) );
}
STDMETHODIMP AddMediaType(
@@ -416,7 +422,7 @@ protected:
//
_inline CMultipinMft* Parent()
{
- return m_Parent.Get();
+ return m_Parent;
}
__inline HRESULT setAttributes(_In_ IMFAttributes* _pAttributes)
{
@@ -427,16 +433,16 @@ protected:
{
return m_lock;
}
- IMFMediaTypeArray m_listOfMediaTypes;
+ IMFMediaTypeArray m_listOfMediaTypes;
ComPtr<IMFAttributes> m_spAttributes;
ComPtr<IKsControl> m_spIkscontrol;
-
+ DeviceStreamState m_state;
private:
- ULONG m_StreamId; /*Device Stream Id*/
- CCritSec m_lock; /*This is only used to change the reference count i.e. active users of this stream*/
+ ULONG m_StreamId; /*Device Stream Id*/
+ CCritSec m_lock; /*This is only used to change the reference count i.e. active users of this stream*/
ComPtr<IMFMediaType> m_setMediaType;
- ComPtr<CMultipinMft> m_Parent;
- ULONG m_nRefCount;
+ CMultipinMft* m_Parent;
+ ULONG m_nRefCount;
};
@@ -455,40 +461,38 @@ public:
STDMETHOD (SendSample)(
_In_ IMFSample *
);
- STDMETHODIMP GenerateMFMediaTypeListFromDevice(
+ HRESULT GenerateMFMediaTypeListFromDevice(
_In_ UINT uiStreamId
);
STDMETHODIMP WaitForSetInputPinMediaChange(
);
- STDMETHOD_ (DeviceStreamState, SetState)(
- _In_ DeviceStreamState
- ); /*True for Active and False for Stop*/
- STDMETHOD_(DeviceStreamState, GetState)(
- VOID
- );
//
//Corresponding IMFDeviceTransform functions for the Pin
//
- STDMETHODIMP_(HRESULT) GetInputStreamPreferredState(
+ HRESULT GetInputStreamPreferredState(
_Inout_ DeviceStreamState *value,
_Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType
);
- STDMETHODIMP_(HRESULT) SetInputStreamState(
+ HRESULT SetInputStreamState(
_In_ IMFMediaType *pMediaType,
_In_ DeviceStreamState value,
_In_ DWORD dwFlags
);
+ virtual STDMETHODIMP FlushQueues()
+ {
+ return S_OK;
+ }
//
//Inline functions
//
__inline IMFMediaType* getPreferredMediaType()
{
- return m_prefferedMediaType.Get();
+ return m_spPrefferedMediaType.Get();
}
__inline VOID setPreferredMediaType( _In_ IMFMediaType *pMediaType)
{
- m_prefferedMediaType = pMediaType;
+ m_spPrefferedMediaType = pMediaType;
}
__inline DeviceStreamState setPreferredStreamState(_In_ DeviceStreamState streamState)
{
@@ -499,15 +503,16 @@ public:
return m_preferredStreamState;
}
+ void ReleaseConnectedPins();
+
protected:
ComPtr<IMFTransform> m_spSourceTransform; /*Source Transform*/
+
private:
GUID m_stStreamType; /*GUID representing the GUID*/
- ULONG m_activeStreamCount; /*Set when this stream is active*/
- vector<CBasePin*> m_outpins;
- DeviceStreamState m_state;
+ ComPtr<CBasePin> m_outpin; //Only one output pin connected per input pin. There can be multiple pins connected and this could be a list
DeviceStreamState m_preferredStreamState;
- ComPtr<IMFMediaType> m_prefferedMediaType;
+ ComPtr<IMFMediaType> m_spPrefferedMediaType;
HANDLE m_waitInputMediaTypeWaiter; /*Set when the input media type is changed*/
};
@@ -519,10 +524,11 @@ public:
_In_opt_ CMultipinMft *pparent = NULL,
_In_ IKsControl* iksControl=NULL);
~COutPin();
+ STDMETHODIMP FlushQueues();
STDMETHODIMP AddPin(
_In_ DWORD pinId
);
- STDMETHODIMP AddSample(
+ virtual STDMETHODIMP AddSample(
_In_ IMFSample *pSample,
_In_ CBasePin *inPin
);
@@ -530,21 +536,11 @@ public:
_In_ IMFSample *pSample,
_In_ CBasePin *inPin
);
- STDMETHODIMP RemoveSample(
- _Out_ IMFSample **
- );
- STDMETHODIMP_(DeviceStreamState) SetState(
- _In_ DeviceStreamState
- ); /*True for Active and False for Stop*/
- STDMETHODIMP_(DeviceStreamState) GetState(
- );
- STDMETHODIMP FlushQueues(
- );
+
STDMETHODIMP GetOutputStreamInfo(
_Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo
);
STDMETHODIMP ChangeMediaTypeFromInpin(
- _In_ CInPin* inPin,
_In_ IMFMediaType *pInMediatype,
_In_ IMFMediaType* pOutMediaType,
_In_ DeviceStreamState state );
@@ -560,37 +556,122 @@ public:
_In_ ULONG ulDataLength,
_Out_opt_ ULONG* pBytesReturned
);
- STDMETHODIMP_(VOID) SetD3Dmanager(
- _In_opt_ IUnknown *
- );
STDMETHODIMP_(VOID) SetFirstSample(
_In_ BOOL
);
-private:
- vector< CPinState *> m_states; /*Array of possible states*/
- CPinState* m_state; /*Current state*/
- vector< CPinQueue *> m_queues; /*List of Queues corresponding to input pins*/
+protected:
+ CPinQueue * m_queue; /* Queue where the sample will be stored*/
BOOL m_firstSample;
- friend class CPinState;
};
-//
-//Not Implemented!!!
-//
-
-class CImagePin : public COutPin{
-private:
- BOOL isTriggerSent;
+class CAsyncInPin: public CInPin {
public:
- CImagePin();
- ~CImagePin();
- STDMETHODIMP ProcessOutput(
- _In_ DWORD dwFlags,
- _Inout_ MFT_OUTPUT_DATA_BUFFER *pOutputSample,
- _Out_ DWORD *pdwStatus
+
+ STDMETHODIMP FlushQueues();
+ STDMETHODIMP SendSample(
+ _In_ IMFSample *
+ );
+ STDMETHODIMP SendSampleInternal(
+ _In_ IMFSample *
);
-};
+ CAsyncInPin(
+ _In_opt_ IMFAttributes *pAttributes,
+ _In_ ULONG ulPinId,
+ _In_ CMultipinMft *pParent) : CInPin(pAttributes,
+ ulPinId, pParent)
+ , m_dwWorkQueueId(MFASYNC_CALLBACK_QUEUE_UNDEFINED)
+ , m_dwSamplesInFlight(0)
+ , m_hHandle(INVALID_HANDLE_VALUE)
+ , m_bFlushing(FALSE)
+
+ {
+ m_hHandle = CreateEvent(NULL, TRUE, TRUE, L"Async_Pin Event");
+ }
+ ~CAsyncInPin()
+ {
+ CloseHandle(m_hHandle);
+ m_hHandle = INVALID_HANDLE_VALUE;
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // Start of Asynchronous callback definitions :- If we need to use MF work queues
+ ////////////////////////////////////////////////////////////////////////////////////////
+ class CDMFTAsyncCallback : public IMFAsyncCallback
+ {
+ public:
+ CDMFTAsyncCallback() : m_cRef(1) { }
+ virtual ~CDMFTAsyncCallback() { }
+
+ STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
+ {
+ HRESULT hr = S_OK;
+ if (ppv != nullptr)
+ {
+ *ppv = nullptr;
+ if (riid == __uuidof(IMFAsyncCallback) || riid == __uuidof(IUnknown))
+ {
+ AddRef();
+ *ppv = static_cast<IUnknown*>(this);
+ }
+ else
+ {
+ hr = E_NOINTERFACE;
+ }
+ }
+ else
+ {
+ hr = E_POINTER;
+ }
+ return hr;
+ }
+
+ STDMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+ STDMETHODIMP_(ULONG) Release()
+ {
+ long cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0)
+ {
+ delete this;
+ }
+ return cRef;
+ }
+
+ STDMETHODIMP GetParameters(DWORD* pdwFlags, DWORD* pdwQueue)
+ {
+ // Implementation of this method is optional.
+ UNREFERENCED_PARAMETER(pdwFlags);
+ UNREFERENCED_PARAMETER(pdwQueue);
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);
+ // TODO: Implement this method.
+ // Inside Invoke, IMFAsyncResult::GetStatus to get the status.
+ // Then call the EndX method to complete the operation.
+ CAsyncInPin* GetParent()
+ {
+ // The restrictioh that the below expression sets is that
+ // we should now have
+ return CONTAINING_RECORD(this, CAsyncInPin, m_asyncCallback);
+ }
+ private:
+ long m_cRef;
+ };
+
+ CDMFTAsyncCallback m_asyncCallback; // Callback object
+ DWORD m_dwWorkQueueId; // Work queue Id
+ HANDLE m_hHandle; // Handles to keep flush state
+ DWORD m_dwSamplesInFlight; // Samples in flight i.e. waiting for the callback functions to be called
+ BOOL m_bFlushing;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // End of Asynchronous callback definitions
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+};
diff --git a/avstream/sampledevicemft/common.h b/avstream/sampledevicemft/common.h
index 238decfb..93f107c6 100644
--- a/avstream/sampledevicemft/common.h
+++ b/avstream/sampledevicemft/common.h
@@ -17,6 +17,29 @@
#define DMFTRACE(...)
#endif
+//
+// The below guid is used to register the GUID as the Device Transform. This should be adeed to the
+// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\ and under the
+// GLOBAL#\Device Parameters key, add a CameraDeviceMFTCLSID value, and set its value to
+// {0E313280-3169-4F41-A329-9E854169634F} for the Pipeline to pick up the Transform.
+//
+DEFINE_GUID(CLSID_MultiPinMFT,
+ 0xe313280, 0x3169, 0x4f41, 0xa3, 0x29, 0x9e, 0x85, 0x41, 0x69, 0x63, 0x4f);
+
+
+//
+// Custom Pin GUID. The avstream driver should define a PIN_DESCRIPTOR with this GUID
+// defined in cateogory. This will lead to devproxy creating this pin. This pin however
+// cannot be used by the pipeline as it may share a custom media type and pipeline could
+// fail. Moreover pipeline can currently (when this sample is written) only deal with
+// the known pins (PREVIEW/CAPTURE/IMAGE). This code snippet creates a custom pin
+// and
+//
+DEFINE_GUID(AVSTREAM_CUSTOM_PIN_IMAGE,
+ 0x888c4105, 0xb328, 0x4ed6, 0xa3, 0xca, 0x2f, 0xf4, 0xc0, 0x3a, 0x9f, 0x33);
+
+
+
//TP_NORMAL
//TP_LOWEST
//TP_LOW
@@ -24,10 +47,11 @@
//TP_HIGHEST
//TP_ERROR
//TP_MUTED = 0x00070000
-
-
-
+#ifdef DBG
#define mf_assert(a) if(!a) DebugBreak()
+#else
+#define mf_assert(a)
+#endif
#define WPP_CONTROL_GUIDS \
WPP_DEFINE_CONTROL_GUID(CtlGUID_DMFTTrace, (CBCCA12E, 9472, 409D, A1B1, 753C98BF03C0), \
@@ -41,6 +65,38 @@
#define WPP_FLAG_LEVEL_LOGGER(flags,lvl) WPP_LEVEL_LOGGER(flags)
#define WPP_FLAG_LEVEL_ENABLED(flags, lvl) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+#define WPP_CHECK_LEVEL_ENABLED(flags, level) 1
+
+//begin_wpp config
+//
+// USEPREFIX (DMFTCHECKNULL_GOTO,"%!STDPREFIX!");
+// FUNC DMFTCHECKNULL_GOTO(CHECKNULLGOTO_EXP,LABEL,HR,...);
+// USESUFFIX (DMFTCHECKNULL_GOTO," failed %!HRESULT!\n", hr);
+//
+//end_wpp
+
+//begin_wpp config
+//
+// USEPREFIX (DMFTCHECKHR_GOTO,"%!STDPREFIX!");
+// FUNC DMFTCHECKHR_GOTO(CHECKHRGOTO_EXP,LABEL,...);
+// USESUFFIX (DMFTCHECKHR_GOTO," failed %!HRESULT!\n", hr);
+//
+
+//end_wpp
+
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_PRE(pointer,label,HR) if( pointer == NULL ) { hr = HR;
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_POST(pointer,label,HR) ; goto label; }
+
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_LOGGER(pointer,label,HR) WPP_LEVEL_LOGGER( DMFT_INIT )
+#define WPP_CHECKNULLGOTO_EXP_LABEL_HR_ENABLED(pointer,label,HR) WPP_CHECK_LEVEL_ENABLED( DMFT_INIT, TP_ERROR )
+
+#define WPP_CHECKHRGOTO_EXP_LABEL_PRE(HR,label) if( FAILED( hr = HR ) ) {
+#define WPP_CHECKHRGOTO_EXP_LABEL_POST(HR,label) ; goto label; }
+
+#define WPP_CHECKHRGOTO_EXP_LABEL_LOGGER(HR, label) WPP_LEVEL_LOGGER( DMFT_INIT )
+#define WPP_CHECKHRGOTO_EXP_LABEL_ENABLED(HR, label) WPP_CHECK_LEVEL_ENABLED( DMFT_INIT, TP_ERROR )
+
+
#define SAFE_ADDREF(p) if( NULL != p ) { ( p )->AddRef(); }
#define SAFE_DELETE(p) delete p; p = NULL;
#define SAFE_SHUTDELETE(p) if( NULL != p ) { ( p )->Shutdown(); delete p; p = NULL; }
@@ -53,68 +109,12 @@
#define SAFE_BYTEARRAYDELETE(p) delete [] (BYTE*) p; p = NULL;
-
-#define DMFTCHECKHR_GOTO(val,label) \
- hr = (val); \
-if (FAILED(hr)) {\
- /*DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr); */\
- goto label; \
-}
-
-
-#define DMFTCHECKNULL_GOTO( val, label, err) \
-if( (val) == NULL ) { \
- hr = (err); \
- /*DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);*/\
- goto label; \
-}
-
-#define TP_SCOPE_TRACE TP_NORMAL
-#define DH_THIS_FILE DH_DEVPROXY
-
#define SAFERELEASE(x) \
if (x) {\
x->Release(); \
x = NULL; \
}
-#define CHK_LOG_BRK(exp) \
-if (FAILED(hr = (exp))) {\
- wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \
- /*MFWMITRACE(DH_THIS_FILE, TP_NORMAL, __FUNCTION__ " : MULTIPINERROR File: %s Ln:%d",__FILE__,__LINE__);*/\
- break; \
-}
-
-
-#define CHK_NULL_BRK(exp) \
-if ((exp) == NULL) {\
-hr = E_OUTOFMEMORY; \
-wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \
-break; \
-}
-
-#define CHK_NULL_PTR_BRK(exp) \
-if ((exp) == NULL) {\
-hr = E_INVALIDARG; \
-wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \
-break; \
-}
-
-#define CHK_BOOL_BRK(exp) \
-if (!exp) {\
- hr = E_FAIL; \
- wprintf(L"HR=%08x File: %S Ln: %d\n", hr, __FILE__, __LINE__); \
- break; \
-}
-
-
-//
-// The Below type definitions are added for this iteration. It will taken out in the
-// next one when we will have the windows headers modified to include the interfaces
-// externally.
-//
-
-
#if !defined(_IKsControl_)
#define _IKsControl_
interface DECLSPEC_UUID("28F54685-06FD-11D2-B27A-00A0C9223196") IKsControl;
@@ -149,180 +149,6 @@ DECLARE_INTERFACE_(IKsControl, IUnknown)
};
#endif //!defined(_IKsControl_)
-
-
-#if !defined(__IMFDeviceTransform_INTERFACE_DEFINED__)
-//
-//These definitions will have to be taken out when the
-//internal defines are made public
-//
-
-EXTERN_GUID(MEDeviceStreamCreated, 0x0252a1cf, 0x3540, 0x43b4, 0x91, 0x64, 0xd7, 0x2e, 0xb4, 0x05, 0xfa, 0x40);
-
-typedef
-enum _DeviceStreamState
-{
- DeviceStreamState_Stop = 0,
- DeviceStreamState_Pause = (DeviceStreamState_Stop + 1),
- DeviceStreamState_Run = (DeviceStreamState_Pause + 1),
- DeviceStreamState_Disabled = (DeviceStreamState_Run + 1)
-} DeviceStreamState;
-
-/* size is 4, align is 4*/
-typedef enum _DeviceStreamState *PDeviceStreamState;
-
-EXTERN_C const IID IID_IMFDeviceTransform;
-MIDL_INTERFACE("D818FBD8-FC46-42F2-87AC-1EA2D1F9BF32")
-IMFDeviceTransform : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE InitializeTransform(
- /* [annotation][in] */
- _In_ IMFAttributes *pAttributes) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInputAvailableType(
- /* [annotation][in] */
- _In_ DWORD dwInputStreamID,
- /* [annotation][in] */
- _In_ DWORD dwTypeIndex,
- /* [annotation][out] */
- _COM_Outptr_ IMFMediaType **pMediaType) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInputCurrentType(
- /* [annotation][in] */
- _In_ DWORD dwInputStreamID,
- /* [annotation][out] */
- _COM_Outptr_ IMFMediaType **pMediaType) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInputStreamAttributes(
- /* [annotation][in] */
- _In_ DWORD dwInputStreamID,
- /* [annotation][out] */
- _COM_Outptr_ IMFAttributes **ppAttributes) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetOutputAvailableType(
- /* [annotation][in] */
- _In_ DWORD dwOutputStreamID,
- /* [annotation][in] */
- _In_ DWORD dwTypeIndex,
- /* [annotation][out] */
- _COM_Outptr_ IMFMediaType **pMediaType) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetOutputCurrentType(
- /* [annotation][in] */
- _In_ DWORD dwOutputStreamID,
- /* [annotation][out] */
- _COM_Outptr_ IMFMediaType **pMediaType) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetOutputStreamAttributes(
- /* [annotation][in] */
- _In_ DWORD dwOutputStreamID,
- /* [annotation][out] */
- _COM_Outptr_ IMFAttributes **ppAttributes) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetStreamCount(
- /* [annotation][out] */
- _Out_ DWORD *pcInputStreams,
- /* [annotation][out] */
- _Out_ DWORD *pcOutputStreams) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetStreamIDs(
- /* [annotation][in] */
- _In_ DWORD dwInputIDArraySize,
- /* [annotation][out] */
- _Out_ DWORD *pdwInputStreamIds,
- /* [annotation][in] */
- _In_ DWORD dwOutputIDArraySize,
- /* [annotation][out] */
- _Out_ DWORD *pdwOutputStreamIds) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ProcessEvent(
- /* [annotation][in] */
- _In_ DWORD dwInputStreamID,
- /* [annotation][in] */
- _In_ IMFMediaEvent *pEvent) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ProcessInput(
- /* [annotation][in] */
- _In_ DWORD dwInputStreamID,
- /* [annotation][in] */
- _In_ IMFSample *pSample,
- /* [annotation][in] */
- _In_ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ProcessMessage(
- /* [annotation][in] */
- _In_ MFT_MESSAGE_TYPE eMessage,
- /* [annotation][in] */
- _In_ ULONG_PTR ulParam) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ProcessOutput(
- /* [annotation][in] */
- _In_ DWORD dwFlags,
- /* [annotation][in] */
- _In_ DWORD cOutputBufferCount,
- /* [size_is][annotation][out][in] */
- _Inout_ MFT_OUTPUT_DATA_BUFFER *pOutputSample,
- /* [annotation][out] */
- _Out_ DWORD *pdwStatus) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetInputStreamState(
- /* [annotation][in] */
- _In_ DWORD dwStreamID,
- /* [annotation][in] */
- _In_ IMFMediaType *pMediaType,
- /* [annotation][in] */
- _In_ DeviceStreamState value,
- /* [annotation][in] */
- _In_ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInputStreamState(
- /* [annotation][in] */
- _In_ DWORD dwStreamID,
- /* [annotation][out] */
- _Out_ DeviceStreamState *value) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetOutputStreamState(
- /* [annotation][in] */
- _In_ DWORD dwStreamID,
- /* [annotation][in] */
- _In_ IMFMediaType *pMediaType,
- /* [annotation][in] */
- _In_ DeviceStreamState value,
- /* [annotation][in] */
- _In_ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetOutputStreamState(
- /* [annotation][in] */
- _In_ DWORD dwStreamID,
- /* [annotation][out] */
- _Out_ DeviceStreamState *value) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInputStreamPreferredState(
- /* [annotation][in] */
- _In_ DWORD dwStreamID,
- /* [annotation][out] */
- _Out_ DeviceStreamState *value,
- /* [annotation][out] */
- _COM_Outptr_ IMFMediaType **ppMediaType) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE FlushInputStream(
- /* [annotation][in] */
- _In_ DWORD dwStreamIndex,
- /* [annotation][in] */
- _In_ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE FlushOutputStream(
- /* [annotation][in] */
- _In_ DWORD dwStreamIndex,
- /* [annotation][in] */
- _In_ DWORD dwFlags) = 0;
-
-};
-
-#endif
-
-
interface IDirect3DDeviceManager9;
//Forward defintion
class CBasePin;
@@ -384,14 +210,6 @@ public:
};
-//
-//The below guid is used to register the GUID as the Device Transform. This should be adeed to the
-//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\ and under the
-//GLOBAL#\Device Parameters key, add a CameraDeviceMFTCLSID value, and set its value to
-// {0E313280-3169-4F41-A329-9E854169634F} for the Pipeline to pick up the Transform.
-//
-DEFINE_GUID(CLSID_MultiPinMFT,
- 0xe313280, 0x3169, 0x4f41, 0xa3, 0x29, 0x9e, 0x85, 0x41, 0x69, 0x63, 0x4f);
typedef enum _MF_TRANSFORM_XVP_OPERATION{
@@ -407,12 +225,6 @@ typedef std::vector< IMFSample *> IMFSampleList;
typedef std::pair< std::multimap<int, int>::iterator, std::multimap<int, int>::iterator > MMFTMMAPITERATOR;
-HRESULT CreateCodec(
- _In_opt_ IMFMediaType * inMediaType,
- _In_opt_ IMFMediaType *outMediaType,
- _In_ BOOL operation /*True = Encode, False = Decode*/,
- _Out_ IMFTransform **pTransform
- );
STDMETHODIMP IsOptimizedPlanarVideoInputImageOutputPair(
_In_ IMFMediaType *inMediaType,
@@ -430,7 +242,7 @@ STDMETHODIMP RandomnizeMediaTypes(
_In_ IMFMediaTypeArray &pMediaTypeArray
);
-STDMETHODIMP IsInputDxSample(
+HRESULT IsInputDxSample(
_In_ IMFSample* pSample,
_Inout_ BOOL *isDxSample
);
@@ -476,19 +288,6 @@ HRESULT ExceptionBoundary(Lambda&& lambda)
}
}
-
-//
-// Custom Pin GUID. The avstream driver should define a PIN_DESCRIPTOR with this GUID
-// defined in cateogory. This will lead to devproxy creating this pin. This pin however
-// cannot be used by the pipeline as it may share a custom media type and pipeline could
-// fail. Moreover pipeline can currently (when this sample is written) only deal with
-// the known pins (PREVIEW/CAPTURE/IMAGE). This code snippet creates a custom pin
-// and
-//
-DEFINE_GUID(AVSTREAM_CUSTOM_PIN_IMAGE,
- 0x888c4105, 0xb328, 0x4ed6, 0xa3, 0xca, 0x2f, 0xf4, 0xc0, 0x3a, 0x9f, 0x33);
-
-
//
// The Below redirections are to support MFT0. Implement this only if you need to load
// MFT0 and DeviceMft simultaneously.
@@ -715,3 +514,113 @@ public:
private:
static volatile long s_lObjectCount;
};
+#define DECLARE_TransformImageFunctions(a) void TransformImage_##a(\
+const RECT &rcDest,\
+_Inout_updates_(_Inexpressible_(lDestStride * dwHeightInPixels)) BYTE *pDest,\
+_In_ LONG lDestStride,\
+_In_reads_(_Inexpressible_(lSrcStride * dwHeightInPixels)) const BYTE *pSrc,\
+_In_ LONG lSrcStride,\
+_In_ DWORD dwWidthInPixels,\
+_In_ DWORD dwHeightInPixels)
+
+DECLARE_TransformImageFunctions(YUY2);
+DECLARE_TransformImageFunctions(UYVY);
+DECLARE_TransformImageFunctions(NV12);
+DECLARE_TransformImageFunctions(RGB32);
+
+class VideoBufferLock
+{
+public:
+ VideoBufferLock(IMFMediaBuffer *pBuffer)
+ {
+ m_pBuffer = pBuffer;
+ // 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()));
+ }
+ }
+ ~VideoBufferLock()
+ {
+ UnlockBuffer();
+ }
+ // LockBuffer:
+ // Locks the buffer. Returns a pointer to scan line 0 and returns the stride.
+
+ // The caller must provide the default stride as an input parameter, in case
+ // the buffer does not expose IMF2DBuffer. You can calculate the default stride
+ // from the media type.
+
+ HRESULT LockBuffer(
+ _In_ LONG lDefaultStride, // Minimum stride (with no padding).
+ _In_ DWORD dwHeightInPixels, // Height of the image, in pixels.
+ _Out_ BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0.
+ _Inout_ LONG *plStride, // Receives the actual stride.
+ _Out_ DWORD *pcbBuffer, // Length of the Buffer
+ _In_ BOOL Read = TRUE // Whether Read
+ )
+ {
+ HRESULT hr = S_OK;
+ // Use the 2-D version if available.
+ if (m_p2DBuffer2)
+ {
+ BYTE *pbBufferStart = NULL;
+ MF2DBuffer_LockFlags Flags = (Read == TRUE) ? MF2DBuffer_LockFlags_Read : MF2DBuffer_LockFlags_Write;
+ hr = m_p2DBuffer2->Lock2DSize(
+ Flags,
+ ppbScanLine0,
+ plStride,
+ &pbBufferStart,
+ pcbBuffer);
+ if (dwHeightInPixels* abs(*plStride) > *pcbBuffer)
+ {
+ hr = E_FAIL;
+ }
+ } else if (m_p2DBuffer)
+ {
+ hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
+ }
+ else
+ {
+ // Use non-2D version.
+ BYTE *pData = NULL;
+ hr = m_pBuffer->Lock(&pData, NULL, NULL);
+ if (SUCCEEDED(hr))
+ {
+ *plStride = lDefaultStride;
+ if (lDefaultStride < 0)
+ {
+ // Bottom-up orientation. Return a pointer to the start of the
+ // last row *in memory* which is the top row of the image.
+ *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
+ }
+ else
+ {
+ // Top-down orientation. Return a pointer to the start of the
+ // buffer.
+ *ppbScanLine0 = pData;
+ }
+ }
+ }
+ return hr;
+ }
+ HRESULT UnlockBuffer()
+ {
+ if (m_p2DBuffer2.Get())
+ {
+ return m_p2DBuffer2->Unlock2D();
+ }
+ else if (m_p2DBuffer.Get())
+ {
+ return m_p2DBuffer->Unlock2D();
+ }
+ else
+ {
+ return m_pBuffer->Unlock();
+ }
+ }
+private:
+ ComPtr<IMFMediaBuffer> m_pBuffer;
+ ComPtr<IMF2DBuffer> m_p2DBuffer;
+ ComPtr<IMF2DBuffer2> m_p2DBuffer2;
+};
diff --git a/avstream/sampledevicemft/mftpeventgenerator.cpp b/avstream/sampledevicemft/mftpeventgenerator.cpp
index 72b395ff..1e510cfa 100644
--- a/avstream/sampledevicemft/mftpeventgenerator.cpp
+++ b/avstream/sampledevicemft/mftpeventgenerator.cpp
@@ -11,8 +11,6 @@
#include "mftpeventgenerator.h"
-#define TP_SCOPE_TRACE TP_NORMAL
-#define DH_THIS_FILE DH_DEVPROXY
#ifdef MF_WPP
#include "mftpeventgenerator.tmh" //--REF_ANALYZER_DONT_REMOVE--
@@ -72,11 +70,8 @@ STDMETHODIMP CMediaEventGenerator::QueryInterface(
else
{
hr = E_NOINTERFACE;
- DMFTCHECKHR_GOTO(hr, done);
}
-done:
-
return hr;
}
@@ -89,7 +84,6 @@ STDMETHODIMP CMediaEventGenerator::BeginGetEvent(
)
{
HRESULT hr = S_OK;
- //MFWMITRACE(DH_THIS_FILE, TP_NORMAL, __FUNCTION__ " : MultiPinMFT BeginGetEvent called");
m_critSec.Lock();
hr = CheckShutdown();
@@ -110,7 +104,6 @@ STDMETHODIMP CMediaEventGenerator::EndGetEvent(
)
{
HRESULT hr = S_OK;
- //MFWMITRACE(DH_THIS_FILE, TP_NORMAL, __FUNCTION__ " : MultiPinMFT EndGetEvent called");
m_critSec.Lock();
hr = CheckShutdown();
@@ -135,7 +128,6 @@ STDMETHODIMP CMediaEventGenerator::GetEvent(
// a slightly different locking strategy.
//
HRESULT hr = S_OK;
- //MFWMITRACE(DH_THIS_FILE, TP_NORMAL, __FUNCTION__ " : MultiPinMFT GetEvent called");
IMFMediaEventQueue *pQueue = NULL;
m_critSec.Lock();
@@ -168,7 +160,6 @@ STDMETHODIMP CMediaEventGenerator::QueueEvent(
)
{
HRESULT hr = S_OK;
- //MFWMITRACE(DH_THIS_FILE, TP_NORMAL, __FUNCTION__ " : MultiPinMFT QueueEvent called");
m_critSec.Lock();
hr = CheckShutdown();
@@ -195,7 +186,6 @@ STDMETHODIMP CMediaEventGenerator::ShutdownEventGenerator(
{
HRESULT hr = S_OK;
- // MFWMITRACE( DH_THIS_FILE, TP_LOWEST, __FUNCTION__ " : entering ...");
m_critSec.Lock();
@@ -206,15 +196,12 @@ STDMETHODIMP CMediaEventGenerator::ShutdownEventGenerator(
if (m_pQueue)
{
hr = m_pQueue->Shutdown();
- //MFWMITRACE( DH_THIS_FILE, TP_NORMAL, __FUNCTION__ "Event Generator Queue shutdown hr = %x", hr);
}
SAFE_RELEASE(m_pQueue);
m_bShutdown = TRUE;
}
m_critSec.Unlock();
- // MFWMITRACE( DH_THIS_FILE, TP_LOWEST, __FUNCTION__ " : exiting...");
-
return hr;
}
@@ -223,7 +210,6 @@ STDMETHODIMP CMediaEventGenerator::QueueEvent(
)
{
HRESULT hr = S_OK;
- //MFWMITRACE(DH_THIS_FILE, TP_LOWEST, __FUNCTION__ " : QueueEvent 1 ...");
m_critSec.Lock();
hr = CheckShutdown();
@@ -245,6 +231,4 @@ CMediaEventGenerator::~CMediaEventGenerator (
)
{
ShutdownEventGenerator();
- //MFASSERT(m_bShutdown);
- //MFASSERT(m_nRefCount == 0);
}
diff --git a/avstream/sampledevicemft/multipinmft.cpp b/avstream/sampledevicemft/multipinmft.cpp
index ea7fd892..4b9a10e2 100644
--- a/avstream/sampledevicemft/multipinmft.cpp
+++ b/avstream/sampledevicemft/multipinmft.cpp
@@ -12,24 +12,10 @@
#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..
+// 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 ),
@@ -38,41 +24,41 @@ CMultipinMft::CMultipinMft()
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
{
+ HRESULT hr = S_OK;
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" );
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_TRANSFORM_ASYNC, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE ),done);
+ DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_SA_D3D_AWARE, TRUE ), done);
+ DMFTCHECKHR_GOTO(pAttributes->SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"SampleMultiPinMft" ),done);
m_spAttributes = pAttributes;
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
m_guidPhotoConfirmationSubtype = MFVideoFormat_NV12;
#endif
+done:
+ if (FAILED(hr))
+ {
+
+ }
}
CMultipinMft::~CMultipinMft( )
{
- CBasePin *pioPin = NULL;
+
for ( ULONG ulIndex = 0, ulSize = (ULONG) m_InPins.size(); ulIndex < ulSize; ulIndex++ )
{
- pioPin = m_InPins[ ulIndex ];
- SAFERELEASE( pioPin );
+ SAFERELEASE(m_InPins[ ulIndex ]);
}
m_InPins.clear();
-
for (ULONG ulIndex = 0, ulSize = (ULONG) m_OutPins.size(); ulIndex < ulSize; ulIndex++)
{
- pioPin = m_OutPins[ ulIndex ];
- SAFERELEASE( pioPin );
+ SAFERELEASE(m_OutPins[ ulIndex ]);
}
m_OutPins.clear();
m_spSourceTransform = nullptr;
@@ -111,58 +97,46 @@ STDMETHODIMP CMultipinMft::QueryInterface(
if ((iid == __uuidof(IMFDeviceTransform)) || (iid == __uuidof(IUnknown)))
{
*ppv = static_cast< IMFDeviceTransform* >(this);
- AddRef();
}
- else
- if ( iid == __uuidof( IMFMediaEventGenerator ) )
+ else if ( iid == __uuidof( IMFMediaEventGenerator ) )
{
*ppv = static_cast< IMFMediaEventGenerator* >(this);
- AddRef();
}
- else
- if ( iid == __uuidof( IMFShutdown ) )
+ 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))
+ else if (iid == __uuidof(IMFTransform))
{
*ppv = static_cast< IMFTransform* >(this);
- AddRef();
}
#endif
- else
- if ( iid == __uuidof( IKsControl ) )
+ else if ( iid == __uuidof( IKsControl ) )
{
*ppv = static_cast< IKsControl* >( this );
- AddRef();
}
- else
- if ( iid == __uuidof( IMFRealTimeClientEx ) )
+ else if ( iid == __uuidof( IMFRealTimeClientEx ) )
{
*ppv = static_cast< IMFRealTimeClientEx* >( this );
- AddRef();
}
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
- else
- if (iid == __uuidof(IMFCapturePhotoConfirmation))
+ else if (iid == __uuidof(IMFCapturePhotoConfirmation))
{
*ppv = static_cast< IMFCapturePhotoConfirmation* >(this);
- AddRef();
}
- else
- if (iid == __uuidof(IMFGetService))
+ else if (iid == __uuidof(IMFGetService))
{
*ppv = static_cast< IMFGetService* >(this);
- AddRef();
}
#endif
else
{
hr = E_NOINTERFACE;
+ goto done;
}
+ AddRef();
+done:
return hr;
}
@@ -193,12 +167,13 @@ STDMETHODIMP CMultipinMft::InitializeTransform (
DWORD outputStreams = 0;
GUID* outGuids = NULL;
GUID streamCategory = GUID_NULL;
-
+ ULONG ulOutPinIndex = 0;
+ CPinCreationFactory* pPinFactory = new CPinCreationFactory(this);
DMFTCHECKNULL_GOTO( pAttributes, done, E_INVALIDARG );
//
- //The attribute passed with MF_DEVICEMFT_CONNECTED_FILTER_KSCONTROL is the source transform. This generally represents a filter
- //This needs to be stored so that we know the device properties. We cache it. We query for the IKSControl which is used to send
- //controls to the driver.
+ // 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 );
@@ -233,174 +208,69 @@ STDMETHODIMP CMultipinMft::InitializeTransform (
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))
+ ComPtr<IMFAttributes> pInAttributes = nullptr;
+ BOOL bCustom = FALSE;
+ CInPin *pInPin = nullptr;
+
+ DMFTCHECKHR_GOTO(pPinFactory->CreatePin(
+ pcOutputStreams[ulIndex], /*Input Pin ID as advertised by the pipeline*/
+ 0, /*This is not needed for Input Pin*/
+ CPinCreationFactory::DMFT_PIN_INPUT, /*Input Pin*/
+ (CBasePin**)&pInPin,
+ bCustom), done);
+ if (bCustom)
{
- 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
+ // Create one on one mapping
//
- if ( ( outputStreams == 1 ) && IsEqualGUID( streamCategory, PINNAME_VIDEO_CAPTURE ) )
+ for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
{
- 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
- //
+ COutPin *poPin = nullptr;
+ BOOL bCustom = FALSE;
+ CInPin *piPin = ( CInPin * )m_InPins[ ulIndex ];
- for (ULONG ulIndex = 0; ulIndex < m_InPins.size(); ulIndex++)
+ if (piPin)
{
- 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 ) )
{
- 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!
+ // 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;
+ }
- 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(pPinFactory->CreatePin(piPin->streamId(), /*Input Pin connected to the Output Pin*/
+ ulOutPinIndex, /*Output pin Id*/
+ CPinCreationFactory::DMFT_PIN_OUTPUT, /*Output pin */
+ (CBasePin**)&poPin,
+ bCustom), done);
DMFTCHECKHR_GOTO(BridgeInputPinOutputPin(piPin, poPin), done);
- hr = ExceptionBoundary([&]()
+ DMFTCHECKHR_GOTO(ExceptionBoundary([&]()
{
m_OutPins.push_back(poPin);
- });
- DMFTCHECKHR_GOTO(hr, done);
+ }),done);
+ poPin->AddRef();
+ ulOutPinIndex++;
}
}
- }
+
}
m_InputPinCount = ULONG ( m_InPins.size() );
@@ -422,6 +292,7 @@ done:
{
delete [] ( outGuids );
}
+ SAFE_DELETE(pPinFactory);
if ( FAILED( hr ) )
{
//Release the pins and the resources acquired
@@ -482,17 +353,17 @@ STDMETHODIMP CMultipinMft::GetStreamCount(
{
HRESULT hr = S_OK;
CAutoLock lock(m_critSec);
-
-
+ DMFTCHECKNULL_GOTO(pdwInputStreams, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pdwOutputStreams, done, E_INVALIDARG);
*pdwInputStreams = m_InputPinCount;
*pdwOutputStreams = m_OutputPinCount;
-
DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
+done:
return hr;
}
//
-//Doesn't striclt conform to GetStreamIDs on IMFTransform Interface!
+//Doesn't strictly conform to the GetStreamIDs on IMFTransform Interface!
//
STDMETHODIMP CMultipinMft::GetStreamIDs(
_In_ DWORD dwInputIDArraySize,
@@ -508,9 +379,6 @@ STDMETHODIMP CMultipinMft::GetStreamIDs(
{
HRESULT hr = S_OK;
CAutoLock lock(m_critSec);
-
- MFTLOCKED();
-
if ( ( dwInputIDArraySize < m_InputPinCount ) && ( dwOutputIDArraySize < m_OutputPinCount ) )
{
hr = MF_E_BUFFERTOOSMALL;
@@ -550,15 +418,13 @@ index dwTypeIndex.
STDMETHODIMP CMultipinMft::GetInputAvailableType(
_In_ DWORD dwInputStreamID,
_In_ DWORD dwTypeIndex,
- _Out_ IMFMediaType** ppMediaType
+ _Out_ IMFMediaType** ppMediaType
)
{
HRESULT hr = S_OK;
- MFTLOCKED();
-
-
- CInPin *piPin = ( CInPin* )GetInPin( dwInputStreamID );
-
+
+ CInPin *piPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
DMFTCHECKNULL_GOTO( piPin, done, MF_E_INVALIDSTREAMNUMBER );
*ppMediaType = nullptr;
@@ -571,7 +437,6 @@ STDMETHODIMP CMultipinMft::GetInputAvailableType(
dwInputStreamID,
dwTypeIndex,
hr);
-
}
done:
@@ -593,17 +458,15 @@ STDMETHODIMP CMultipinMft::GetOutputAvailableType(
--*/
{
HRESULT hr = S_OK;
- MFTLOCKED();
- DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
+ ComPtr<COutPin> spoPin = GetOutPin( dwOutputStreamID );
- COutPin*poPin = ( COutPin* )GetOutPin( dwOutputStreamID );
-
- DMFTCHECKNULL_GOTO( poPin, done, MF_E_INVALIDSTREAMNUMBER );
+ DMFTCHECKNULL_GOTO( spoPin.Get(), done, MF_E_INVALIDSTREAMNUMBER );
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
*ppMediaType = nullptr;
- hr = poPin->GetOutputAvailableType( dwTypeIndex, ppMediaType );
+ hr = spoPin->GetOutputAvailableType( dwTypeIndex, ppMediaType );
if ( FAILED( hr ) )
{
@@ -628,9 +491,9 @@ STDMETHODIMP CMultipinMft::GetInputCurrentType(
--*/
{
//
- //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
+ // 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);
@@ -650,14 +513,13 @@ STDMETHODIMP CMultipinMft::GetOutputCurrentType(
--*/
{
HRESULT hr = S_OK;
- MFTLOCKED();
CAutoLock lock( m_critSec );
DMFTCHECKNULL_GOTO( ppMediaType, done, E_INVALIDARG );
*ppMediaType = nullptr;
- COutPin *poPin = ( COutPin* )GetOutPin( dwOutputStreamID );
+ COutPin *poPin = GetOutPin( dwOutputStreamID );
DMFTCHECKNULL_GOTO( poPin, done, MF_E_INVALIDSTREAMNUMBER );
@@ -703,7 +565,6 @@ STDMETHODIMP CMultipinMft::ProcessMessage(
--*/
{
HRESULT hr = S_OK;
- MFTLOCKED();
UNREFERENCED_PARAMETER(ulParam);
@@ -715,18 +576,18 @@ STDMETHODIMP CMultipinMft::ProcessMessage(
{
case MFT_MESSAGE_COMMAND_FLUSH:
//
- //This is MFT wide flush.. Flush all output pins
+ // 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
+ // 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
+ // No op for device MFTs
//
break;
case MFT_MESSAGE_SET_D3D_MANAGER:
@@ -808,11 +669,9 @@ STDMETHODIMP CMultipinMft::ProcessInput(
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER( dwFlags );
-
- MFTLOCKED();
-
- CInPin *inPin = ( CInPin* )GetInPin( dwInputStreamID );
- DMFTCHECKNULL_GOTO( inPin, done, E_INVALIDARG );
+
+ CInPin *inPin = GetInPin( dwInputStreamID );
+ DMFTCHECKNULL_GOTO( inPin, done, MF_E_INVALIDSTREAMNUMBER);
if ( !IsStreaming() )
{
@@ -820,11 +679,7 @@ STDMETHODIMP CMultipinMft::ProcessInput(
}
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;
@@ -848,7 +703,6 @@ output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the sampl
{
HRESULT hr = S_OK;
BOOL gotOne = false;
- MFTLOCKED();
UNREFERENCED_PARAMETER( dwFlags );
if (cOutputBufferCount > m_OutputPinCount )
@@ -861,13 +715,30 @@ output pins and populate the corresponding MFT_OUTPUT_DATA_BUFFER with the sampl
{
DWORD dwStreamID = pOutputSamples[i].dwStreamID;
- COutPin *poPin = ( COutPin * )GetOutPin( dwStreamID );
+ COutPin *poPin = GetOutPin( dwStreamID );
+ GUID pinGuid = GUID_NULL;
DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
if ( SUCCEEDED( poPin->ProcessOutput( dwFlags, &pOutputSamples[i],
pdwStatus ) ) )
{
gotOne = true;
+ // Do photo confirmation if enabled
+#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
+ BOOL pIsImagePin = FALSE;
+ if (pOutputSamples[i].pSample &&
+ IsPhotoConfirmationEnabled() &&
+ (SUCCEEDED(CheckImagePin(static_cast<IMFAttributes*>(poPin), &pIsImagePin)) && pIsImagePin))
+ {
+ ComPtr<IMFMediaType> spMediaType;
+ if (SUCCEEDED(poPin->getMediaType(spMediaType.GetAddressOf())))
+ {
+ // Do Photo confirmation
+ ProcessCapturePhotoConfirmationCallBack(spMediaType.Get(), pOutputSamples[i].pSample);
+ }
+ }
+#endif
+
}
}
if (gotOne)
@@ -893,12 +764,11 @@ STDMETHODIMP CMultipinMft::GetInputStreamAttributes(
--*/
{
HRESULT hr = S_OK;
- MFTLOCKED();
DMFTCHECKNULL_GOTO( ppAttributes, done, E_INVALIDARG );
*ppAttributes = nullptr;
- CInPin *piPin = static_cast<CInPin*>(GetInPin( dwInputStreamID ));
+ CInPin *piPin = GetInPin( dwInputStreamID );
DMFTCHECKNULL_GOTO( piPin, done, E_INVALIDARG );
@@ -922,12 +792,11 @@ STDMETHODIMP CMultipinMft::GetOutputStreamAttributes(
--*/
{
HRESULT hr = S_OK;
- MFTLOCKED();
-
+
DMFTCHECKNULL_GOTO(ppAttributes, done, E_INVALIDARG);
*ppAttributes = nullptr;
- COutPin *poPin = (COutPin *)GetOutPin(dwOutputStreamID);
+ COutPin *poPin = GetOutPin(dwOutputStreamID);
DMFTCHECKNULL_GOTO( poPin, done, E_INVALIDARG );
@@ -958,7 +827,7 @@ STDMETHODIMP CMultipinMft::SetInputStreamState(
--*/
{
HRESULT hr = S_OK;
- CInPin *piPin = (CInPin*)GetInPin(dwStreamID);
+ CInPin *piPin = GetInPin(dwStreamID);
DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
DMFTCHECKHR_GOTO(piPin->SetInputStreamState(pMediaType, value, dwFlags),done);
@@ -974,7 +843,7 @@ STDMETHODIMP CMultipinMft::GetInputStreamState(
)
{
HRESULT hr = S_OK;
- CInPin *piPin = (CInPin*)GetInPin(dwStreamID);
+ ComPtr<CInPin> piPin = GetInPin(dwStreamID);
DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
@@ -1010,7 +879,7 @@ STDMETHODIMP CMultipinMft::SetOutputStreamState(
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER(dwFlags);
- CAutoLock Lock(m_critSec);
+ CAutoLock Lock(m_critSec);
DMFTCHECKHR_GOTO(ChangeMediaTypeEx(dwStreamID, pMediaType, state),done);
@@ -1021,7 +890,7 @@ done:
STDMETHODIMP CMultipinMft::GetOutputStreamState(
_In_ DWORD dwStreamID,
- _Out_ DeviceStreamState *value
+ _Out_ DeviceStreamState *pState
)
/*++
Description:
@@ -1034,10 +903,10 @@ STDMETHODIMP CMultipinMft::GetOutputStreamState(
HRESULT hr = S_OK;
CAutoLock lock(m_critSec);
- COutPin *poPin = (COutPin *)GetOutPin(dwStreamID);
+ COutPin *poPin = GetOutPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(pState, done, E_INVALIDARG);
DMFTCHECKNULL_GOTO(poPin, done, MF_E_INVALIDSTREAMNUMBER);
-
- *value = poPin->GetState();
+ *pState = poPin->GetState();
done:
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
@@ -1059,10 +928,10 @@ STDMETHODIMP CMultipinMft::GetInputStreamPreferredState(
--*/
{
HRESULT hr = S_OK;
- CInPin *piPin = (CInPin*)GetInPin(dwStreamID);
+ CInPin *piPin = GetInPin(dwStreamID);
+ DMFTCHECKNULL_GOTO(ppMediaType, done, E_INVALIDARG);
DMFTCHECKNULL_GOTO(piPin, done, MF_E_INVALIDSTREAMNUMBER);
-
- piPin->GetInputStreamPreferredState(value, ppMediaType);
+ hr = piPin->GetInputStreamPreferredState(value, ppMediaType);
done:
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
@@ -1101,20 +970,10 @@ STDMETHODIMP CMultipinMft::FlushOutputStream(
UNREFERENCED_PARAMETER(dwFlags);
CAutoLock Lock(m_critSec);
- COutPin *poPin = (COutPin*)GetOutPin(dwStreamIndex);
+ COutPin *poPin = 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
- //
+ DMFTCHECKHR_GOTO(poPin->FlushQueues(),done);
poPin->SetState(oldState);
done:
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
@@ -1133,6 +992,7 @@ STDMETHODIMP_(VOID) CMultipinMft::FlushAllStreams(
)
{
DeviceStreamState oldState;
+ CAutoLock Lock(m_critSec);
for ( DWORD dwIndex = 0, dwSize = (DWORD)m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
{
COutPin *poPin = (COutPin *)m_OutPins[dwIndex];
@@ -1177,103 +1037,48 @@ STDMETHODIMP CMultipinMft::KsProperty(
if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl)
&& (pProperty->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART))
{
+#if MF_DEVICEMFT_WARMSTART_HANDLING
DMFTCHECKHR_GOTO(WarmStartHandler(pProperty,
ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned),done);
goto done;
+#endif
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Warm Start Control %d Passed ", pProperty->Id);
}
- 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()))
+ if (IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl))
{
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))
+ 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;
+ // A function illustrating how we can capture and service photos from the device MFT. This block shows how we can
+ // intercept Photo triggers going down to the pipeline
+
if (sizeof(KSPROPERTY_VIDEOCONTROL_MODE_S) == ulDataLength)
{
- VideoControl = (PKSPROPERTY_VIDEOCONTROL_MODE_S)pvPropertyData;
+ PKSPROPERTY_VIDEOCONTROL_MODE_S 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)
+ 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,
+ DMFTCHECKHR_GOTO(m_spIkscontrol->KsProperty(pProperty,
ulPropertyLength,
pvPropertyData,
ulDataLength,
- pulBytesReturned);
-
-
+ pulBytesReturned),done);
done:
LPSTR guidStr = DumpGUIDA(pProperty->Set);
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! g:%s p:%d exiting %x = %!HRESULT!", guidStr, pProperty->Id, hr, hr);
@@ -1291,7 +1096,7 @@ STDMETHODIMP CMultipinMft::KsMethod(
/*++
Description:
- Implements IKSProperty::KsMethod function.
+ Implements IKSProperty::KsMethod function. We can trap ksmethod calls here.
--*/
{
return m_spIkscontrol->KsMethod(
@@ -1318,6 +1123,7 @@ STDMETHODIMP CMultipinMft::KsEvent(
{
HRESULT hr = S_OK;
+#if MF_DEVICEMFT_WARMSTART_HANDLING
if (pEvent && (pEvent->Set == KSEVENTSETID_ExtendedCameraControl) &&
(pEvent->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART))
{
@@ -1331,52 +1137,20 @@ STDMETHODIMP CMultipinMft::KsEvent(
ulDataLength,
pBytesReturned
);
- goto done;
}
-
- if ((pEvent && (pEvent->Set == KSEVENTSETID_ExtendedCameraControl))
- && (!filterHasIndependentPin()))
+ else
+#endif
{
+
//
- // 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.
+ // All the Events we don't handle should be sent to the driver!
//
- 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;
- }
- }
+ hr = m_spIkscontrol->KsEvent(pEvent,
+ ulEventLength,
+ pEventData,
+ ulDataLength,
+ pBytesReturned);
}
- //
- // 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;
}
@@ -1483,16 +1257,17 @@ done:
}
#endif
-
-
-
//
-//HELPER FUNCTIONS
+// HELPER FUNCTIONS
//
-STDMETHODIMP_(CBasePin*) CMultipinMft::GetInPin(
+//
+// A lock here could mean a deadlock because this will be called when the lock is already held
+// in another thread.
+//
+CInPin* CMultipinMft::GetInPin(
_In_ DWORD dwStreamId
- )
+)
{
CInPin *inPin = NULL;
for (DWORD dwIndex = 0, dwSize = (DWORD)m_InPins.size(); dwIndex < dwSize; dwIndex++)
@@ -1507,12 +1282,12 @@ STDMETHODIMP_(CBasePin*) CMultipinMft::GetInPin(
return inPin;
}
-STDMETHODIMP_(CBasePin*) CMultipinMft::GetOutPin(
+COutPin* CMultipinMft::GetOutPin(
_In_ DWORD dwStreamId
)
{
COutPin *outPin = NULL;
-
+ CAutoLock Lock(m_critSec);
for ( DWORD dwIndex = 0, dwSize = (DWORD) m_OutPins.size(); dwIndex < dwSize; dwIndex++ )
{
outPin = ( COutPin * )m_OutPins[ dwIndex ];
@@ -1528,224 +1303,117 @@ STDMETHODIMP_(CBasePin*) CMultipinMft::GetOutPin(
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 CMultipinMft::GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin)
{
- 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 )
+ HRESULT hr = S_OK;
+ map<int, int>::iterator it = m_outputPinMap.find(ulOutpin);
+ if (it != m_outputPinMap.end())
{
- if ( !poPin->IsMediaTypeSupported( pMediaType, &pFullType ) )
- {
- DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
- }
+ ulInPin = it->second;
}
- //
- //First step disable the output pin. store the old state
- //
- oldOutPinState = poPin->SetState( DeviceStreamState_Disabled );
-
- (void)poPin->FlushQueues();
+ else
+ {
+ hr = MF_E_INVALIDSTREAMNUMBER;
+ }
+ return hr;
+}
- 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 );
+//
+// The Below function changes media type on the pins exposed by device MFT
+//
+__requires_lock_held(m_critSec)
+HRESULT CMultipinMft::ChangeMediaTypeEx(
+ _In_ ULONG pinId,
+ _In_opt_ IMFMediaType *pMediaType,
+ _In_ DeviceStreamState reqState
+)
+{
+ HRESULT hr = S_OK;
+ COutPin *poPin = GetOutPin(pinId);
+ DeviceStreamState oldOutPinState, oldInputStreamState, newOutStreamState, newRequestedInPinState;
+ ComPtr<IMFMediaType> pFullType, pInputMediaType;
+ ULONG ulInPinId = 0;
+ DWORD dwFlags = 0;
- for (std::multimap<int, int>::iterator piterator = inputPinPos.first; piterator != inputPinPos.second;piterator++)
+ DMFTCHECKNULL_GOTO(poPin, done, E_INVALIDARG);
{
//
- //Get the output pins connected to the input pin. The input pin map consists of the output pins connected
+ // dump the media types to the logs
//
- 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)
+ ComPtr<IMFMediaType> spOldMediaType;
+ (VOID)poPin->getMediaType(spOldMediaType.GetAddressOf());
+ CMediaTypePrinter newType(pMediaType);
+ CMediaTypePrinter oldType(spOldMediaType.Get());
+ if (WPP_LEVEL_ENABLED(DMFT_GENERAL))
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Pin:%d old MT:[%s] St:%d", pinId, oldType.ToString(), reqState);
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, " Pin:%d new MT:[%s] St:%d", pinId, newType.ToString(), reqState);
+ }
+ }
+ if (pMediaType)
+ {
+ if (!poPin->IsMediaTypeSupported(pMediaType, &pFullType))
{
- pconnectedInPin->getMediaType( &pInputMediaType );
+ DMFTCHECKHR_GOTO(MF_E_INVALIDMEDIATYPE, done);
}
-
- //
- // 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
-
+ }
+
+ DMFTCHECKHR_GOTO(GetConnectedInpin(pinId, ulInPinId), done);
+ CInPin *pinPin = GetInPin(ulInPinId); // Get the input pin
+
+ (VOID)pinPin->getMediaType(&pInputMediaType);
+ oldInputStreamState = pinPin->SetState(DeviceStreamState_Disabled); // Disable input pin
+ oldOutPinState = poPin->SetState(DeviceStreamState_Disabled); // Disable output pin
+ (void)pinPin->FlushQueues(); // Flush the input queues
+ (void)poPin->FlushQueues(); // Flush the output queues
+ newOutStreamState = pinStateTransition[oldOutPinState][reqState]; // New state needed
+
+ // The Old input and the output pin states should be the same
+ newRequestedInPinState = newOutStreamState;
+
+ if ((newOutStreamState != oldOutPinState) /*State change*/
+ ||((pFullType.Get() != nullptr) && (pInputMediaType.Get()!=nullptr) && (S_OK != (pFullType->IsEqual(pInputMediaType.Get(), &dwFlags)))) /*Media Types dont match*/
+ ||((pFullType == nullptr)||(pInputMediaType == nullptr))/*Either one of the mediatypes is null*/
+ )
+ {
//
- //Check if we are asked to go to an active state
- //Check for the new media type. if
+ // State has change or media type has changed so we need to change the media type on the
+ // underlying kernel pin
//
- 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;
- }
- }
- }
-
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Changing Mediatype on the input ");
+ pinPin->setPreferredMediaType(pFullType.Get());
+ pinPin->setPreferredStreamState(newRequestedInPinState);
+ // Let the pipline know that the input needs to be changed.
+ SendEventToManager(METransformInputStreamStateChanged, GUID_NULL, pinPin->streamId());
//
- // 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.
+ // The media type will be set on the input pin by the time we return from the wait
+ //
+ DMFTCHECKHR_GOTO(pinPin->WaitForSetInputPinMediaChange(), done);
+ // Change the media type on the output..
+ DMFTCHECKHR_GOTO(poPin->ChangeMediaTypeFromInpin(pFullType.Get(), pFullType.Get(), reqState), done);
//
-
- 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
+ // Notify the pipeline that the output stream media type has changed
//
- 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;
- }
-
+ DMFTCHECKHR_GOTO(SendEventToManager(MEUnknown, MEDeviceStreamCreated, poPin->streamId()), done);
+ poPin->SetFirstSample(TRUE);
+ }
+ else
+ {
+ // Restore back old states as we have nothing to do
+ pinPin->SetState(oldInputStreamState);
+ poPin->SetState(oldOutPinState);
}
+
done:
- DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
}
-STDMETHODIMP CMultipinMft::SendEventToManager(
+//
+// The below function sends events to the pipeline.
+//
+
+HRESULT CMultipinMft::SendEventToManager(
_In_ MediaEventType eventType,
_In_ REFGUID pGuid,
_In_ UINT32 context
@@ -1765,67 +1433,19 @@ STDMETHODIMP CMultipinMft::SendEventToManager(
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(
+HRESULT CMultipinMft::BridgeInputPinOutputPin(
_In_ CInPin* piPin,
_In_ COutPin* poPin
)
{
- HRESULT hr = S_OK;
- ULONG ulIndex = 0;
+ HRESULT hr = S_OK;
+ ULONG ulIndex = 0;
+ ULONG ulAddedMediaTypeCount = 0;
ComPtr<IMFMediaType> pMediaType = nullptr;
DMFTCHECKNULL_GOTO( piPin, done, E_INVALIDARG );
@@ -1844,26 +1464,31 @@ STDMETHODIMP CMultipinMft::BridgeInputPinOutputPin(
if ( IsKnownUncompressedVideoType( subType ) )
{
DMFTCHECKHR_GOTO( poPin->AddMediaType(NULL, pMediaType.Get() ), done );
+ ulAddedMediaTypeCount++;
}
pMediaType = nullptr;
}
+ if (ulAddedMediaTypeCount == 0)
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Make Sure Pin %d has one media type exposed ", piPin->streamId());
+ DMFTCHECKHR_GOTO( MF_E_INVALID_STREAM_DATA, done );
+ }
//
//Add the Input Pin to the output Pin
//
DMFTCHECKHR_GOTO(poPin->AddPin(piPin->streamId()), done);
hr = ExceptionBoundary([&](){
//
- //Add the output pin to the input pin.
+ // Add the output pin to the input pin.
+ // Create the pin map. So that we know which pin input pin is connected to which output pin
//
piPin->ConnectPin(poPin);
+ m_outputPinMap.insert(std::pair< int, int >(poPin->streamId(), piPin->streamId()));
});
- 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
@@ -1875,370 +1500,11 @@ done:
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
+// Look at the below code only if we need to handle an extended property in Device MFT
//
-/*++
-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(
+HRESULT CMultipinMft::WarmStartHandler(
_In_ PKSPROPERTY Property,
_In_ ULONG ulPropertyLength,
_In_ LPVOID pData,
@@ -2345,6 +1611,14 @@ STDMETHODIMP CMultipinMft::Shutdown(
{
CAutoLock Lock(m_critSec);
(VOID) m_eventHandler.Clear();
+
+ for (ULONG ulIndex = 0, ulSize = (ULONG)m_InPins.size(); ulIndex < ulSize; ulIndex++ )
+ {
+ CInPin *pInPin = static_cast<CInPin *>(m_InPins[ulIndex]);
+
+ // Deref on the connected outpins to break reference loop
+ pInPin->ReleaseConnectedPins();
+ }
return ShutdownEventGenerator();
}
@@ -2426,7 +1700,7 @@ done:
// Only worry about this if you have customs pins defined in the driver
//
-STDMETHODIMP CMultipinMft::SetStreamingStateCustomPins(
+HRESULT CMultipinMft::SetStreamingStateCustomPins(
DeviceStreamState State
)
{
@@ -2444,10 +1718,30 @@ STDMETHODIMP CMultipinMft::SetStreamingStateCustomPins(
if ( SUCCEEDED( CheckCustomPin(pInPin, &isCustom) )
&& ( isCustom ) )
{
- pInPin->SetState(State);
- }
+ // Start the custom stream here. This will involve sending an event to the pipeline about the stream needing a state change
+ ComPtr<IMFMediaType> spMediaType;
+ if ( State == DeviceStreamState_Run )
+ {
+ // Only get the media type if we are going into run state
+ DMFTCHECKHR_GOTO(pInPin->GetMediaTypeAt(0, spMediaType.GetAddressOf()), done);
+ }
+ pInPin->SetState(DeviceStreamState_Disabled);
+ pInPin->setPreferredMediaType(spMediaType.Get());
+ pInPin->setPreferredStreamState(State);
+ //
+ // Let the pipline know that the input needs to be changed on the custom pin
+ //
+ SendEventToManager(METransformInputStreamStateChanged, GUID_NULL, pInPin->streamId());
+ //
+ // The media type will be set on the input pin by the time we return from the wait.
+ // For a custom pin, which is often the stats pin we can skip the wait as this will
+ // simply make the pipeline wait
+ //
+ DMFTCHECKHR_GOTO(pInPin->WaitForSetInputPinMediaChange(), done);
+ }
}
}
+done:
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
return hr;
}
diff --git a/avstream/sampledevicemft/multipinmft.h b/avstream/sampledevicemft/multipinmft.h
index 244a47be..5bdaaca9 100644
--- a/avstream/sampledevicemft/multipinmft.h
+++ b/avstream/sampledevicemft/multipinmft.h
@@ -7,7 +7,7 @@
//
#pragma once
-
+#define MF_DEVICEMFT_ADD_GRAYSCALER_ 1
#include "common.h"
#include "mftpeventgenerator.h"
#include "basepin.h"
@@ -30,7 +30,7 @@ interface IDirect3DDeviceManager9;
// Forward declarations
//
class CMFAttributes;
-
+class CPinCreationFactory;
//
// CMultipinMft class:
// Implements a device proxy MFT.
@@ -48,7 +48,9 @@ class CMultipinMft :
, public IMFCapturePhotoConfirmation
, public IMFGetService
#endif
+ , public CDMFTModuleLifeTimeManager
{
+ friend class CPinCreationFactory;
public:
CMultipinMft(
void );
@@ -277,28 +279,15 @@ public:
static STDMETHODIMP CreateInstance(
REFIID iid, void **ppMFT);
-
- //
- //Below functions are used by the pins to enquire the state of the Filter for Photo sequence.
- //A Trigger is a ksproperty sent to the filter.
- //
-
- __inline VOID setPhotoTriggerSent(_In_ BOOL Set)
- {
- m_PhotoTriggerSent = Set;
- }
- __inline BOOL isPhotoTriggerSent()
- {
- return m_PhotoTriggerSent;
- }
-
+
__inline BOOL isPhotoModePhotoSequence()
{
return m_PhotoModeIsPhotoSequence;
}
- __inline BOOL filterHasIndependentPin()
+
+ _inline DWORD GetQueueId()
{
- return m_filterHasIndependentPin;
+ return m_dwWorkQueueId;
}
//
@@ -311,7 +300,7 @@ public:
m_spDeviceManagerUnk.CopyTo( ppDeviceManagerUnk );
}
- STDMETHODIMP SendEventToManager(
+ HRESULT SendEventToManager(
_In_ MediaEventType,
_In_ REFGUID,
_In_ UINT32
@@ -323,77 +312,31 @@ protected:
//Helper functions
//
- STDMETHODIMP SetStreamingStateCustomPins(
+ HRESULT SetStreamingStateCustomPins(
_In_ DeviceStreamState
);
- STDMETHODIMP_(CBasePin*) GetInPin(
+ CInPin* GetInPin(
_In_ DWORD dwStreamID
);
- STDMETHODIMP_(CBasePin*) GetOutPin(
+ COutPin* GetOutPin(
_In_ DWORD dwStreamID
);
+
+ HRESULT GetConnectedInpin(_In_ ULONG ulOutpin, _Out_ ULONG &ulInPin);
- STDMETHODIMP ChangeMediaTypeEx(
+ __requires_lock_held(m_critSec)
+ HRESULT ChangeMediaTypeEx(
_In_ ULONG pinId,
_In_opt_ IMFMediaType *pMediaType,
_In_ DeviceStreamState newState
);
-
- STDMETHODIMP GetConnectOutPinStatus(
- _In_ ULONG ulPinId,
- _In_ ULONG ulOutPin,
- _Inout_ PBOOL pAnyInPauseState,
- _Inout_ PBOOL pAnyInRunState,
- _Inout_ PBOOL pAnyActive
- );
- STDMETHODIMP BridgeInputPinOutputPin(
+ HRESULT BridgeInputPinOutputPin(
_In_ CInPin* pInPin,
_In_ COutPin* pOutPin);
- //
- //Implementing the below to simulate a photosequence
- //This is just to show that photosequence can be achieved purely in
- //the user mode with the device MFT..
- //
- STDMETHODIMP ExtendedPhotoModeHandler(
- _In_ PKSPROPERTY pProperty,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pvPropertyData,
- _In_ ULONG ulDataLength,
- _Inout_ PULONG pulBytesReturned
- );
-
- STDMETHODIMP ExtendedPhotoMaxFrameRate(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- );
- STDMETHODIMP MaxVidFPS_PhotoResHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- );
- STDMETHODIMP QPCTimeHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- );
- STDMETHODIMP PhotoFrameRateHandler(
- _In_ PKSPROPERTY Property,
- _In_ ULONG ulPropertyLength,
- _In_ LPVOID pData,
- _In_ ULONG ulOutputBufferLength,
- _Inout_ PULONG pulBytesReturned
- );
- STDMETHODIMP CMultipinMft::WarmStartHandler(
+ HRESULT CMultipinMft::WarmStartHandler(
_In_ PKSPROPERTY Property,
_In_ ULONG ulPropertyLength,
_In_ LPVOID pData,
@@ -409,7 +352,8 @@ protected:
#if (defined (MF_DEVICEMFT_ALLOW_MFT0_LOAD) && defined (MFT_UNIQUE_METHOD_NAMES))
_DEFINE_DEVICEMFT_MFT0HELPER_IMPL__
#endif
-
+
+
//
//Inline functions
@@ -426,7 +370,7 @@ protected:
}
__inline DeviceStreamState GetStreamingState()
{
- return (DeviceStreamState)InterlockedCompareExchange((LONG*)&m_StreamingState, m_StreamingState, m_StreamingState);
+ return (DeviceStreamState)InterlockedCompareExchange((LONG*)&m_StreamingState, 0L, 0L);
}
__inline BOOL IsStreaming()
{
@@ -440,25 +384,20 @@ private:
DeviceStreamState m_StreamingState;
CBasePinArray m_OutPins;
CBasePinArray m_InPins;
- BOOL m_PhotoTriggerSent;
BOOL m_PhotoModeIsPhotoSequence; // used to store if the filter is in photo sequence or not
- BOOL m_FilterInPhotoSequence; // This applies for the filter, which is in a photo sequence or not. This is set by the Extended property handler
- BOOL m_filterHasIndependentPin; // If any of the input pins from the source transform expose an independent photo pin then we will not simluate photoseqeunce
BOOL m_filterInWarmStart; // Used to store if the filter is in warm start or not!
long m_nRefCount; // Reference count
CCritSec m_critSec; // Control lock.. taken only durign state change operations
ComPtr <IUnknown> m_spDeviceManagerUnk; // D3D Manager set, when MFT_MESSAGE_SET_D3D_MANAGER is called through ProcessMessage
- ComPtr<IMFTransform> m_spSourceTransform; // The sources transform
+ ComPtr<IMFTransform> m_spSourceTransform; // The sources transform. This is the pipeline DevProxy
MFSHUTDOWN_STATUS m_eShutdownStatus;
DWORD m_dwWorkQueueId;
LONG m_lWorkQueuePriority;
UINT32 m_punValue;
ComPtr<IKsControl> m_spIkscontrol;
ComPtr<IMFAttributes> m_spAttributes;
-
- multimap<int, int> m_inputPinMap; // How input pins are connected to output pins o-><0..inpins>
- multimap<int, int> m_outputPinMap; // How output pins are connected to input pins i-><0..outpins>
- CDMFTEventHandler m_eventHandler;
+ map<int, int> m_outputPinMap; // How output pins are connected to input pins i-><0..outpins>
+ CDMFTEventHandler m_eventHandler;
#if defined (MF_DEVICEMFT_PHTOTOCONFIRMATION)
ComPtr<IMFAsyncCallback> m_spPhotoConfirmationCallback; //Photo Confirmation related definitions
diff --git a/avstream/sampledevicemft/multipinmft.vcxproj b/avstream/sampledevicemft/multipinmft.vcxproj
index 31107772..0f560e2c 100644
--- a/avstream/sampledevicemft/multipinmft.vcxproj
+++ b/avstream/sampledevicemft/multipinmft.vcxproj
@@ -85,6 +85,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="multipinmft.cpp">
<WppEnabled>true</WppEnabled>
@@ -95,6 +96,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="basepin.cpp">
<WppEnabled>true</WppEnabled>
@@ -105,6 +107,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="multipinmfthelpers.cpp">
<WppEnabled>true</WppEnabled>
@@ -115,6 +118,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="multipinmftutils.cpp">
<WppEnabled>true</WppEnabled>
@@ -125,6 +129,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="custompin.cpp">
<WppEnabled>true</WppEnabled>
@@ -135,6 +140,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<WppEnabled>true</WppEnabled>
@@ -145,6 +151,7 @@
<PreCompiledHeaderFile>stdafx.h</PreCompiledHeaderFile>
<PreCompiledHeader>Use</PreCompiledHeader>
<PreCompiledHeaderOutputFile>$(IntDir)\stdafx.h.pch</PreCompiledHeaderOutputFile>
+ <WppScanConfigurationData>common.h</WppScanConfigurationData>
</ClCompile>
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/avstream/sampledevicemft/multipinmfthelpers.cpp b/avstream/sampledevicemft/multipinmfthelpers.cpp
index 078ca337..788b52ab 100644
--- a/avstream/sampledevicemft/multipinmfthelpers.cpp
+++ b/avstream/sampledevicemft/multipinmfthelpers.cpp
@@ -8,19 +8,20 @@
#ifdef MF_WPP
#include "multipinmfthelpers.tmh" //--REF_ANALYZER_DONT_REMOVE--
#endif
+
+#define MF_DEVICEMFT_ASYNCPIN_NEEDED 1
+
class CMediaTypePrinter;
//
//Queue implementation
//
-CPinQueue::CPinQueue( _In_ DWORD _InpinId )
+CPinQueue::CPinQueue( _In_ DWORD dwPinId )
: m_teer(0),
- m_discotinuity(0),
- m_sampleCount(0),
- m_dwInPinId(_InpinId)
+ m_dwInPinId(dwPinId)
/*
Description
- _InpinId is the input pin Id to which this queue corresponds
+ dwPinId is the input pin Id to which this queue corresponds
*/
{
}
@@ -47,21 +48,20 @@ STDMETHODIMP_(VOID) CPinQueue::InsertInternal( _In_ IMFSample *pSample )
}
}
-STDMETHODIMP_(BOOL) CPinQueue::Insert( _In_ IMFSample *pSample )
+STDMETHODIMP CPinQueue::Insert( _In_ IMFSample *pSample )
//
//m_teer is the wraptee.. this could be a null tee which is a passthrough, an xvp tee, which inserts an xvp into the queue
//
{
- return SUCCEEDED( m_teer->PassThrough( pSample, this ) );
+ return m_teer->PassThrough( pSample, this );
}
-
/*++
Description:
This extracts the first sample from the queue. called from Pin's ProcessOutput
--*/
-STDMETHODIMP_(BOOL) CPinQueue::Remove( _Outptr_result_maybenull_ IMFSample **ppSample)
+STDMETHODIMP CPinQueue::Remove( _Outptr_result_maybenull_ IMFSample **ppSample)
{
HRESULT hr = S_OK;
DMFTCHECKNULL_GOTO( ppSample, done,E_INVALIDARG );
@@ -73,12 +73,9 @@ STDMETHODIMP_(BOOL) CPinQueue::Remove( _Outptr_result_maybenull_ IMFSample **ppS
}
DMFTCHECKNULL_GOTO( *ppSample, done, MF_E_TRANSFORM_NEED_MORE_INPUT );
-
- (*ppSample)->Release( );
-
m_sampleList.erase( m_sampleList.begin() );
done:
- return SUCCEEDED( hr ) ? TRUE : FALSE;
+ return hr;
}
/*++
@@ -87,11 +84,11 @@ Description:
--*/
VOID CPinQueue::Clear( )
{
- IMFSample* pSample = nullptr;
+
while ( !Empty() )
{
- Remove( &pSample );
- SAFE_RELEASE( pSample );
+ ComPtr<IMFSample> spSample;
+ Remove( spSample.GetAddressOf());
}
}
@@ -147,17 +144,40 @@ done:
}
return hr;
}
-
-//
-//State implementation
-//
-CPinOpenState::CPinOpenState(CBasePin *_pin)
-:CPinState(DeviceStreamState_Run), m_pin(_pin)
+#ifdef MF_DEVICEMFT_ADD_GRAYSCALER_
+STDMETHODIMP CPinQueueWithGrayScale::RecreateTee( _In_ IMFMediaType *inMediatype,
+ _In_ IMFMediaType *outMediatype,
+ _In_opt_ IUnknown* punkManager)
{
-
+ HRESULT hr = S_OK;
+
+ GUID gInputSubType = GUID_NULL;
+ DMFTCHECKNULL_GOTO(inMediatype, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(outMediatype, done, E_INVALIDARG);
+ DMFTCHECKHR_GOTO(CPinQueue::RecreateTee(inMediatype,
+ 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
+ DMFTCHECKHR_GOTO(inMediatype->GetGUID(MF_MT_SUBTYPE, &gInputSubType), done);
+ if (IsEqualCLSID(gInputSubType, MFVideoFormat_NV12)
+ ||IsEqualCLSID(gInputSubType, MFVideoFormat_YUY2)
+ ||IsEqualCLSID(gInputSubType, MFVideoFormat_UYVY)
+ ||IsEqualCLSID(gInputSubType, MFVideoFormat_RGB32))
+ {
+ CGrayTee *pTee = NULL;
+ pTee = new CGrayTee(m_teer);
+ DMFTCHECKHR_GOTO(pTee->SetMediaTypes(inMediatype, outMediatype), done);
+ m_teer = dynamic_cast< Ctee* >(pTee);
+ }
+ else
+ {
+ DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Skipping Gray scale Effect");
+ }
+done:
+ return hr;
}
-
-
+#endif
/*++
Description:
@@ -240,18 +260,19 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
//
//Since we are streaming in the software mode we will create a new sample
//
- HRESULT hr = S_OK,pohr = S_OK;
- MFT_OUTPUT_DATA_BUFFER outputSample;
- MFT_OUTPUT_STREAM_INFO StreamInfo;
- IMFSample* spXVPOutputSample = nullptr;
- IMFMediaType* pOutMediaType = nullptr;
- ComPtr <IMFMediaBuffer> spIMFMediaBuffer = nullptr;
+ HRESULT hr = S_OK,pohr = S_OK;
+ MFT_OUTPUT_DATA_BUFFER outputSample;
+ MFT_OUTPUT_STREAM_INFO StreamInfo;
+ ComPtr <IMFSample> spXVPOutputSample;
+ ComPtr <IMFMediaType> spOutMediaType;
+ ComPtr <IMFMediaBuffer> spIMFMediaBuffer;
GUID guidOutputSubType = GUID_NULL;
- pOutMediaType = getOutMediaType();
+
+ spOutMediaType.Attach(getOutMediaType());
DMFTCHECKNULL_GOTO(pOutSample, done, E_INVALIDARG);
- DMFTCHECKHR_GOTO(pOutMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
+ DMFTCHECKHR_GOTO(spOutMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
BOOL isDx = false;
@@ -270,31 +291,25 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
//
DMFTCHECKHR_GOTO(MFCreateSample(&spXVPOutputSample), done);
- DMFTCHECKHR_GOTO(pSample->CopyAllItems(spXVPOutputSample), done);
-
- outputSample.pSample = spXVPOutputSample;
-
+ DMFTCHECKHR_GOTO(pSample->CopyAllItems(spXVPOutputSample.Get()), done);
DMFTCHECKHR_GOTO(Transform()->MFTGetOutputStreamInfo(0, &StreamInfo), done);
if (!m_isOutPutImage)
{
- DMFTCHECKHR_GOTO(MFGetAttributeSize(pOutMediaType, MF_MT_FRAME_SIZE, &m_uWidth, &m_uHeight), done);
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(spOutMediaType.Get(), MF_MT_FRAME_SIZE, &m_uWidth, &m_uHeight), done);
hr = MFCreate2DMediaBuffer(
m_uWidth,
m_uHeight,
guidOutputSubType.Data1,
FALSE, // top-down buffer (DX compatible)
- &spIMFMediaBuffer);
+ spIMFMediaBuffer.GetAddressOf());
if (FAILED(hr))
{
- spIMFMediaBuffer = nullptr;
- spXVPOutputSample->Release();
-
DMFTCHECKHR_GOTO(MFCreateAlignedMemoryBuffer(
StreamInfo.cbSize,
StreamInfo.cbAlignment,
- &spIMFMediaBuffer), done);
+ spIMFMediaBuffer.GetAddressOf()), done);
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! XVP Configured without DX, Created a 1D buffer");
}
@@ -303,10 +318,10 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! XVP Configured with DX, Created a 2D buffer");
}
DMFTCHECKHR_GOTO(spXVPOutputSample->AddBuffer(spIMFMediaBuffer.Get()), done);
+
+ outputSample.pSample = spXVPOutputSample.Detach();
}
}
-
-
//
//Start streaming the xvp transform..
//
@@ -323,14 +338,13 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
if (FAILED(pohr))
{
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! XVP ProcessOutput,failure %x sample =%p", pohr, &outputSample);
- SAFERELEASE(spXVPOutputSample);
}
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
- spXVPOutputSample = outputSample.pSample;
+ spXVPOutputSample.Attach(outputSample.pSample);
if ( SUCCEEDED(pohr) )
{
@@ -344,7 +358,7 @@ STDMETHODIMP CXvptee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** pOutSampl
spXVPOutputSample->SetSampleTime(hnsSampleTime);
}
- *pOutSample = spXVPOutputSample;
+ *pOutSample = spXVPOutputSample.Detach();
//
//Release the Sample back to the pipeline
//
@@ -359,7 +373,7 @@ done:
Description:
Set the D3D Manager on the XVP
--*/
-STDMETHODIMP_(VOID) CXvptee::SetD3DManager(IUnknown* pUnk)
+STDMETHODIMP_(VOID) CXvptee::SetD3DManager( _In_opt_ IUnknown* pUnk)
{
m_spDeviceManagerUnk = pUnk;
}
@@ -412,7 +426,7 @@ STDMETHODIMP CXvptee::Configure(
DMFTCHECKHR_GOTO( inMediaType->GetMajorType( &inMajorType ),done );
DMFTCHECKHR_GOTO( outMediaType->GetMajorType( &outMajorType ), done );
//
- //Configuring DX Manager in SW mode. We will look to make it DX complaint in the next phase
+ //Configuring DX Manager in SW mode.
//
if ( !IsEqualGUID(MFMediaType_Video, outMajorType ) )
{
@@ -521,155 +535,120 @@ CXvptee::~CXvptee()
m_spDeviceManagerUnk = nullptr;
}
-//To be implemented..Not needed for the sample!!
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-STDMETHODIMP CDecoderTee::Do(_In_ IMFSample* pSample, _Out_ IMFSample **pOutSample )
+CGrayTee::CGrayTee(_In_ Ctee *tee) : CWrapTee(tee),m_transformfn(nullptr)
{
- UNREFERENCED_PARAMETER(pSample);
- UNREFERENCED_PARAMETER(pOutSample);
- return S_OK;
}
-STDMETHODIMP CDecoderTee::Configure( _In_opt_ IMFMediaType *inMediaType, _In_opt_ IMFMediaType *outMediaType, _Outptr_ IMFTransform** ppTransform)
+STDMETHODIMP CGrayTee::Do(_In_ IMFSample *pSample, _Outptr_ IMFSample** ppOutSample)
{
- HRESULT hr = S_OK;
- GUID guidcategory = GUID_NULL;
- BOOL IsDecoder = true;
- UINT32 unFlags = 0;
- MFT_REGISTER_TYPE_INFO in;
- MFT_REGISTER_TYPE_INFO out;
- UINT32 cActivates = 0;
- UINT32 unMFTFlags = 0;
- ComPtr<IMFMediaType> pInputMediaType = nullptr;
- ComPtr<IMFMediaType> pOutputMediaType = nullptr;
- IMFActivate **ppActivates = nullptr;
- DWORD dwInputStreams;
- DWORD dwOutputStreams;
- UNREFERENCED_PARAMETER(outMediaType);
- UNREFERENCED_PARAMETER(inMediaType);
- UNREFERENCED_PARAMETER(ppTransform);
+ 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);
- guidcategory = (IsDecoder)?MFT_CATEGORY_VIDEO_DECODER : MFT_CATEGORY_VIDEO_ENCODER;
+ DMFTCHECKNULL_GOTO(ppOutSample, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pSample, done, E_INVALIDARG);
+ *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);
- if (IsDecoder)
+ 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))
{
- DMFTCHECKHR_GOTO(pInputMediaType->GetGUID(MF_MT_MAJOR_TYPE, &in.guidMajorType), done);
- DMFTCHECKHR_GOTO(pInputMediaType->GetGUID(MF_MT_SUBTYPE, &in.guidSubtype), done);
+ spMediaBufOutput = nullptr;
+ DMFTCHECKHR_GOTO(MFCreateAlignedMemoryBuffer(
+ dwTotalLength,
+ MF_1_BYTE_ALIGNMENT,
+ &spMediaBufOutput), done);
}
- else
+ // Add the media buffer to the output sample
+ DMFTCHECKHR_GOTO(spOutputSample->AddBuffer(spMediaBufOutput.Get()), done);
{
- DMFTCHECKHR_GOTO(pOutputMediaType->GetGUID(MF_MT_MAJOR_TYPE, &out.guidMajorType), done);
- DMFTCHECKHR_GOTO(pOutputMediaType->GetGUID(MF_MT_SUBTYPE, &out.guidSubtype), 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)
+ {
+ m_transformfn(m_rect, pDest, lDestStride, pSrc, lSrcStride, m_rect.right, m_rect.bottom);
+ }
}
-
- //
- //Use all possible plugins
- //
-
- unFlags = MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_SORTANDFILTER_WEB_ONLY;
- DMFTCHECKHR_GOTO(MFTEnumEx(guidcategory,
- unFlags,
- IsDecoder ? &in : NULL,
- IsDecoder ? NULL : &out,
- &ppActivates,
- &cActivates
- ),done);
- if (cActivates!=0)
+ if (SUCCEEDED(pSample->GetSampleDuration(&hnsDuration)))
{
- DMFTCHECKHR_GOTO(MF_E_TOPO_CODEC_NOT_FOUND, done);
+ DMFTCHECKHR_GOTO(spOutputSample->SetSampleDuration(hnsDuration),done);
}
- for (DWORD dwIndex = 0; dwIndex < cActivates; dwIndex++)
+ if (SUCCEEDED(pSample->GetSampleTime(&hnsTime)))
{
- //
- //Check if this MFT requires an unlocking.. skip if it does
- //
- unMFTFlags = MFGetAttributeUINT32(ppActivates[dwIndex], MF_TRANSFORM_FLAGS_Attribute, 0);
- if (unMFTFlags & MFT_ENUM_FLAG_FIELDOFUSE)
- {
- //
- //If you have the unlocking key set MFT_FIELDOFUSE_UNLOCK_Attribute on the activate
- //
- continue;
- }
-
- hr = ppActivates[dwIndex]->ActivateObject(IID_PPV_ARGS(ppTransform));
- if (FAILED(hr))
- continue; //hope the next activate is activable
- ppActivates[dwIndex]->DetachObject();
-
- hr = (*ppTransform)->MFTGetStreamCount(&dwInputStreams, &dwOutputStreams);
-
- if (FAILED(hr) || dwInputStreams != 1 || dwOutputStreams > 127)//remove the hardcoding
- {
- //
- //Exception.. we can't use a stream that doesn't give us an idea about it's streams
- //
- continue;
- }
- if (IsDecoder)
- {
- hr = ConfigureDecoder(*ppTransform);
- }
- else
- {
- hr = ConfigureEncoder(*ppTransform);
- }
- if (FAILED(hr))
- {
- SAFE_RELEASE(*ppTransform);
- }
+ 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;
}
-/*++
-
---*/
-
-STDMETHODIMP CDecoderTee::ConfigureEncoder( _In_ IMFTransform *pTransform )
+HRESULT CGrayTee::Configure(
+ _In_ IMFMediaType* pInMediaType,
+ _In_ IMFMediaType* pOutMediaType,
+ _In_opt_ IMFTransform** ppTransform)
{
HRESULT hr = S_OK;
- //
- //Set the input media type and the output media type and that should be pretty much it
- //
- ComPtr<IMFMediaType> pInputType = nullptr;
- ComPtr<IMFMediaType> pOutputType = nullptr;
-
- pInputType = getInMediaType();
- pOutputType = getOutMediaType();
-
- if (pInputType && pOutputType)
+ DWORD dwFlags = 0;
+ UINT32 ulWidth = 0, ulHeight = 0;
+ GUID guidOutputSubType = GUID_NULL;
+ UNREFERENCED_PARAMETER(ppTransform);
+ DMFTCHECKNULL_GOTO(pInMediaType, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pOutMediaType, done, E_INVALIDARG);
+ DMFTCHECKHR_GOTO((pInMediaType->IsEqual(pOutMediaType, &dwFlags)), done);
+ DMFTCHECKHR_GOTO(pInMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done);
+ if (IsEqualCLSID(guidOutputSubType, MFVideoFormat_YUY2))
{
- //We should be good by now
- DMFTCHECKHR_GOTO( pTransform->MFTSetInputType( 0,pInputType.Get(), 0), done);
- //If we have D3D enabled then try again with D3D disabled and see the result
- //
- DMFTCHECKHR_GOTO(pTransform->MFTSetOutputType(0,pOutputType.Get(), 0), done);
- //
- //If the above operation fails and we are allowing partial media types then
- //we have to find the full media type and then check again
+ m_transformfn = TransformImage_YUY2;
}
- else
+ else if (IsEqualCLSID(guidOutputSubType, MFVideoFormat_UYVY))
{
- hr = E_FAIL;
+ m_transformfn = TransformImage_UYVY;
}
+ else if (IsEqualCLSID(guidOutputSubType, MFVideoFormat_NV12))
+ {
+ m_transformfn = TransformImage_NV12;
+ }
+ else if (IsEqualCLSID(guidOutputSubType, MFVideoFormat_RGB32))
+ {
+ m_transformfn = TransformImage_RGB32;
+ }
+ DMFTCHECKHR_GOTO(MFGetAttributeSize(pInMediaType, MF_MT_FRAME_SIZE, &ulWidth, &ulHeight), done);
+ m_rect = { 0, 0, (LONG)ulWidth, (LONG)ulHeight };
done:
return hr;
}
-STDMETHODIMP CDecoderTee::ConfigureDecoder( _In_ IMFTransform *pTransform)
-{
- UNREFERENCED_PARAMETER( pTransform );
- return S_OK;
-}
-
/*++
Descrtiption:
Handles events sent by the pipeline
--*/
-STDMETHODIMP CDMFTEventHandler::KSEvent(
+HRESULT CDMFTEventHandler::KSEvent(
_In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
_In_ ULONG ulEventLength,
_Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
@@ -826,7 +805,7 @@ Descrtiption:
will not send a reset or a clear for one shot events
--*/
-STDMETHODIMP CDMFTEventHandler::SetOneShot( ULONG ulEventId )
+HRESULT CDMFTEventHandler::SetOneShot( ULONG ulEventId )
{
HRESULT hr = S_OK;
hr = ExceptionBoundary([&]()
@@ -872,7 +851,7 @@ Descrtiption:
until the pipeline explicitly needs the event to be unset.
--*/
-STDMETHODIMP CDMFTEventHandler::SetRegularEvent(ULONG ulEventId)
+HRESULT CDMFTEventHandler::SetRegularEvent(ULONG ulEventId)
{
BOOL bEvtFound = FALSE;
HRESULT hr = ExceptionBoundary([&]()
@@ -912,7 +891,7 @@ Descrtiption:
Duplicates the handle passed.
--*/
-STDMETHODIMP CDMFTEventHandler::Dupe(_In_ HANDLE hEventHandle, _Outptr_ LPHANDLE lpTargetHandle)
+HRESULT CDMFTEventHandler::Dupe(_In_ HANDLE hEventHandle, _Outptr_ LPHANDLE lpTargetHandle)
{
HRESULT hr = S_OK;
DMFTCHECKNULL_GOTO(hEventHandle, done, E_INVALIDARG);
@@ -942,7 +921,7 @@ Descrtiption:
Cleans the event lists, both the Single shot and the Regular ones
--*/
-STDMETHODIMP CDMFTEventHandler::Clear()
+HRESULT CDMFTEventHandler::Clear()
{
HRESULT hr = S_OK;
hr = ExceptionBoundary([&]()
@@ -986,3 +965,117 @@ STDMETHODIMP CDMFTEventHandler::Clear()
done:
return hr;
}
+
+HRESULT CPinCreationFactory::CreatePin(_In_ ULONG ulInputStreamId, /* The Input stream Id*/
+ _In_ ULONG ulOutStreamId, /*The output stream Id*/
+ _In_ type_pin type, /*Input Pin or the ourput pin*/
+ _Outptr_ CBasePin** ppPin, /*Output*/
+ _In_ BOOL& isCustom)
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFAttributes> spAttributes;
+ GUID streamCategory = GUID_NULL;
+ DMFTCHECKNULL_GOTO(ppPin, done, E_INVALIDARG);
+ *ppPin = nullptr;
+ isCustom = FALSE;
+ DMFTCHECKHR_GOTO(m_spDeviceTransform->Parent()->GetOutputStreamAttributes(ulInputStreamId, &spAttributes),done);
+ if (type == DMFT_PIN_INPUT)
+ {
+ CInPin *pInPin = nullptr;
+ DMFTCHECKHR_GOTO(spAttributes->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &streamCategory), done);
+ // Create Cutom Pin
+ if (IsEqualCLSID(streamCategory, AVSTREAM_CUSTOM_PIN_IMAGE))
+ {
+ pInPin = new CCustomPin(spAttributes.Get(), ulInputStreamId, static_cast<CMultipinMft*> (m_spDeviceTransform.Get()));
+ isCustom = TRUE;
+ }
+ else
+ {
+#if defined MF_DEVICEMFT_ASYNCPIN_NEEDED
+ pInPin = new CAsyncInPin(spAttributes.Get(), ulInputStreamId, m_spDeviceTransform.Get()); // Asynchronous PIn, if you need it
+#else
+ pInPin = new CInPin(spAttributes.Get(), ulInputStreamId, m_spDeviceTransform.Get());
+#endif
+ }
+ DMFTCHECKNULL_GOTO(pInPin, done, E_OUTOFMEMORY);
+ *ppPin = pInPin;
+
+ }
+ else if(type == DMFT_PIN_OUTPUT)
+ {
+ COutPin* pOutPin = nullptr;
+ ComPtr<IKsControl> spKscontrol;
+ CInPin* pInPin = nullptr;
+ GUID pinGuid = GUID_NULL;
+ UINT32 uiFrameSourceType = 0;
+
+ pInPin = static_cast<CInPin*>(m_spDeviceTransform->GetInPin(ulInputStreamId)); // Get the Input Pin connected to the Output pin
+ DMFTCHECKNULL_GOTO(pInPin, done, E_INVALIDARG);
+ DMFTCHECKHR_GOTO(pInPin->QueryInterface(IID_PPV_ARGS(spKscontrol.GetAddressOf())), done); // Grab the IKSControl off the input pin
+ DMFTCHECKHR_GOTO(pInPin->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &pinGuid), done); // Get the Stream Category. Advertise on the output pin
+
+
+ pOutPin = new COutPin(ulOutStreamId, m_spDeviceTransform.Get(), spKscontrol.Get()); // Create the output pin
+ DMFTCHECKNULL_GOTO(pOutPin, done, E_OUTOFMEMORY);
+
+ *ppPin = pOutPin;
+ DMFTCHECKHR_GOTO(pOutPin->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, pinGuid), done); // Advertise the Stream category to the Pipeline
+ DMFTCHECKHR_GOTO(pOutPin->SetUINT32(MF_DEVICESTREAM_STREAM_ID, ulOutStreamId), done); // Advertise the stream Id to the Pipeline
+ if (SUCCEEDED(pInPin->GetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, &uiFrameSourceType)))
+ {
+ DMFTCHECKHR_GOTO(pOutPin->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, uiFrameSourceType),done); // Copy over the Frame Source Type.
+ }
+
+#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;
+ if (SUCCEEDED(pInPin->GetGUID(MF_DEVICESTREAM_EXTENSION_PLUGIN_CLSID, &guidMFT0)))
+ {
+ //
+ // 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", ulOutStreamId);
+
+ DMFTCHECKHR_GOTO(pOutPin->SetGUID(MF_DEVICESTREAM_EXTENSION_PLUGIN_CLSID, guidMFT0), done);
+
+ DMFTCHECKHR_GOTO(pOutPin->SetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT,
+ static_cast< IUnknown* >(static_cast < IKsControl * >(m_spDeviceTransform.Get()))), done);
+
+ }
+#endif
+ }
+ else
+ {
+ DMFTCHECKHR_GOTO(E_INVALIDARG, done);
+ }
+
+done:
+ return hr;
+}
+
+HRESULT CheckImagePin( _In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsImagePin )
+{
+ HRESULT hr = S_OK;
+ DMFTCHECKNULL_GOTO(pAttributes, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO(pbIsImagePin, done, E_INVALIDARG);
+ {
+ 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;
+ }
+ }
+done:
+ return hr;
+}
+
diff --git a/avstream/sampledevicemft/multipinmfthelpers.h b/avstream/sampledevicemft/multipinmfthelpers.h
index 25d87eb8..9376470e 100644
--- a/avstream/sampledevicemft/multipinmfthelpers.h
+++ b/avstream/sampledevicemft/multipinmfthelpers.h
@@ -9,8 +9,15 @@
#include "stdafx.h"
#include "common.h"
-
-
+typedef void(*DMFT_IMAGE_TRANSFORM_FN)(
+ const RECT& rcDest, // Destination rectangle for the transformation.
+ BYTE* pDest, // Destination buffer.
+ LONG lDestStride, // Destination stride.
+ const BYTE* pSrc, // Source buffer.
+ LONG lSrcStride, // Source stride.
+ DWORD dwWidthInPixels, // Image width in pixels.
+ DWORD dwHeightInPixels // Image height in pixels.
+ );
//
//Queue class!!!
//
@@ -23,11 +30,10 @@ public:
CPinQueue(_In_ DWORD _inPinId);
~CPinQueue();
- STDMETHODIMP_(BOOL) SetState ( _In_ BOOL state );
STDMETHODIMP_(VOID) InsertInternal ( _In_ IMFSample *pSample = nullptr );
- STDMETHODIMP_(BOOL) Insert ( _In_ IMFSample *pSample );
- STDMETHODIMP_(BOOL) Remove (_Outptr_result_maybenull_ IMFSample **pSample);
- STDMETHODIMP RecreateTee ( _In_ IMFMediaType *inMediatype, _In_ IMFMediaType *outMediatype, _In_opt_ IUnknown* punkManager );
+ STDMETHODIMP Insert ( _In_ IMFSample *pSample );
+ STDMETHODIMP Remove (_Outptr_result_maybenull_ IMFSample **pSample);
+ virtual STDMETHODIMP RecreateTee ( _In_ IMFMediaType *inMediatype, _In_ IMFMediaType *outMediatype, _In_opt_ IUnknown* punkManager );
STDMETHODIMP_(VOID) Clear();
//
@@ -37,7 +43,6 @@ public:
{
return (!m_sampleList.size());
}
-
__inline DWORD pinStreamId()
{
return m_dwInPinId;
@@ -46,65 +51,20 @@ public:
private:
DWORD m_dwInPinId; /*This is the input pin */
IMFSampleList m_sampleList; /*List storing the samples */
- ULONG m_sampleCount; /*Numebr of sampels */
+protected:
Ctee* m_teer; /*Tee that acts as a passthrough or an XVP */
- BOOL m_discotinuity; /*Set after the queue is emptied or flushed */
+ };
-};
-class CPinState{
-public:
- virtual STDMETHODIMP Open() = 0;
- CPinState( _In_ DeviceStreamState _state = DeviceStreamState_Disabled) :m_State( _state )
- {
-
- }
- STDMETHODIMP_(DeviceStreamState) SetState( _In_ DeviceStreamState ); /*True for Active and False for Stop*/
- STDMETHODIMP_(DeviceStreamState) GetState();
-
- __inline STDMETHODIMP_(DeviceStreamState) State()
- {
- return m_State;
- }
- virtual ~CPinState() = 0
- {
- }
-protected:
- DeviceStreamState m_State;
-};
-
-class CPinOpenState :public CPinState{
-public:
- CPinOpenState( _In_ CBasePin *p = NULL );
- //
- //Inline
- //
- __inline STDMETHODIMP Open()
- {
- return S_OK;
- }
-
-private:
- CBasePin *m_pin;
-};
-class CPinClosedState : public CPinState{
+#ifdef MF_DEVICEMFT_ADD_GRAYSCALER_
+class CPinQueueWithGrayScale:public CPinQueue{
public:
- CPinClosedState(DeviceStreamState _state = DeviceStreamState_Stop)
- :CPinState(_state)
+ CPinQueueWithGrayScale(_In_ DWORD dwPinId) :CPinQueue(dwPinId)
{
-
- }
- //
- //Inline
- //
- __inline STDMETHODIMP Open()
- {
- return MF_INVALID_STATE_ERR;
}
+ STDMETHODIMP RecreateTee(_In_ IMFMediaType *inMediatype, _In_ IMFMediaType *outMediatype, _In_opt_ IUnknown* punkManager);
};
-
-
-
+#endif
//
// Define these in different components
// The below classes are used to add the
@@ -143,7 +103,7 @@ public:
STDMETHODIMP PassThrough ( _In_ IMFSample*, _In_ CPinQueue * );
virtual STDMETHODIMP Configure ( _In_ IMFMediaType *, _In_ IMFMediaType *, _Inout_ IMFTransform** ) = 0;
virtual STDMETHODIMP Do ( _In_ IMFSample* pSample, _Out_ IMFSample ** ) = 0;
- STDMETHODIMP SetMediaTypes ( _In_ IMFMediaType* pInMediaType, _In_ IMFMediaType* pOutMediaType );
+ STDMETHODIMP SetMediaTypes(_In_ IMFMediaType* pInMediaType, _In_ IMFMediaType* pOutMediaType);
//
//Inline functions
@@ -180,7 +140,7 @@ public:
~CXvptee();
STDMETHODIMP Do ( _In_ IMFSample* pSample, _Outptr_ IMFSample ** );
STDMETHODIMP Configure ( _In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform** );
- STDMETHODIMP_(VOID) SetD3DManager( IUnknown* punk );
+ STDMETHODIMP_(VOID) SetD3DManager( _In_opt_ IUnknown* punk );
private:
BOOL m_isoptimizedPlanarInputOutput;
@@ -190,20 +150,20 @@ private:
ComPtr<IUnknown> m_spDeviceManagerUnk;
};
-class CDecoderTee : public CWrapTee{
+class CGrayTee : public CWrapTee {
public:
- CDecoderTee(Ctee* *);
- ~CDecoderTee();
+ CGrayTee(Ctee*);
+ ~CGrayTee() {
+ }
- STDMETHODIMP Do( _In_ IMFSample* pSample, _Out_ IMFSample ** );
- STDMETHODIMP Configure( _In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform** );
- STDMETHODIMP ConfigureEncoder( _In_ IMFTransform *pTransform );
- STDMETHODIMP ConfigureDecoder( _In_ IMFTransform *pTransform );
+ STDMETHODIMP Do(_In_ IMFSample* pSample, _Out_ IMFSample **);
+ STDMETHODIMP Configure(_In_opt_ IMFMediaType *, _In_opt_ IMFMediaType *, _Outptr_ IMFTransform**);
private:
- ComPtr<IUnknown> m_spDeviceManagerUnk;
+ // Function pointer for the function that transforms the image.
+ DMFT_IMAGE_TRANSFORM_FN m_transformfn;
+ RECT m_rect;
};
-
/*
################## EVENT HANDLING #############################################
Events are usually divided into two categories by the Capture Pipeline
@@ -272,20 +232,40 @@ public:
//
// Handle the events here
//
- STDMETHOD(KSEvent)(_In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
+ HRESULT KSEvent( _In_reads_bytes_(ulEventLength) PKSEVENT pEvent,
_In_ ULONG ulEventLength,
_Inout_updates_bytes_opt_(ulDataLength) LPVOID pEventData,
_In_ ULONG ulDataLength,
_Inout_ ULONG* pBytesReturned);
- STDMETHOD(SetOneShot)(ULONG);
- STDMETHOD(SetRegularEvent)(ULONG);
- STDMETHOD(Clear)();
+ HRESULT SetOneShot(ULONG);
+ HRESULT SetRegularEvent(ULONG);
+ HRESULT Clear();
protected:
- STDMETHOD(Dupe)(_In_ HANDLE hEventHandle, _Outptr_ LPHANDLE lpTargetHandle);
+ HRESULT Dupe (_In_ HANDLE hEventHandle, _Outptr_ LPHANDLE lpTargetHandle);
private:
map< ULONG, HANDLE > m_OneShotEventMap;
vector< PDMFTEventEntry > m_RegularEventList;
};
+class CMultipinMft;
+class CInPin;
+class COutPin;
+
+class CPinCreationFactory {
+protected:
+ ComPtr<CMultipinMft> m_spDeviceTransform;
+public:
+ typedef enum _type_pin {
+ DMFT_PIN_INPUT,
+ DMFT_PIN_OUTPUT,
+ DMFT_PIN_CUSTOM,
+ DMFT_MAX
+ }type_pin;
+ HRESULT CreatePin( _In_ ULONG ulInputStreamId, _In_ ULONG ulOutStreamId, _In_ type_pin type,_Outptr_ CBasePin** ppPin, _In_ BOOL& isCustom);
+ CPinCreationFactory(_In_ CMultipinMft* pDeviceTransform):m_spDeviceTransform(pDeviceTransform){
+ }
+};
+
+HRESULT CheckImagePin(_In_ IMFAttributes* pAttributes, _Out_ PBOOL pbIsImagePin);
diff --git a/avstream/sampledevicemft/multipinmftutils.cpp b/avstream/sampledevicemft/multipinmftutils.cpp
index 6f5735b5..737eb13f 100644
--- a/avstream/sampledevicemft/multipinmftutils.cpp
+++ b/avstream/sampledevicemft/multipinmftutils.cpp
@@ -253,7 +253,7 @@ STDMETHODIMP RandomnizeMediaTypes(_In_ IMFMediaTypeArray &pMediaTypeArray)
/*++
Description: Used to test if the sample passed is a DX sample or not?
--*/
-STDMETHODIMP IsInputDxSample(
+HRESULT IsInputDxSample(
_In_ IMFSample* pSample,
_Inout_ BOOL *isDxSample
)
@@ -339,31 +339,6 @@ STDMETHODIMP_(BOOL) IsKnownUncompressedVideoType(_In_ GUID guidSubType)
return( FALSE );
}
-/*++
-Description:
- Function used to lock the MFT.
---*/
-
-STDMETHODIMP UnLockAsynMFT(IMFTransform* pTransform)
-{
- HRESULT hr = S_OK;
- IMFAttributes *pAttributes;
- UINT32 unValue;
-
- DMFTCHECKNULL_GOTO(pTransform,done, E_INVALIDARG);
- DMFTCHECKHR_GOTO(pTransform->GetAttributes(&pAttributes),done);
- DMFTCHECKHR_GOTO(pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &unValue), done);
-
- if (unValue)
- {
- DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_TRANSFORM_ASYNC, true), done);
- }
-
-done:
- return hr;
-}
-
-
#ifndef IF_EQUAL_RETURN
#define IF_EQUAL_RETURN(param, val) if(val == param) return #val
#endif
@@ -754,124 +729,281 @@ void printMessageEvent(MFT_MESSAGE_TYPE msg)
}
}
-/*++
-Below functions not used in the current iteration..
---*/
-HRESULT CreateCodec(
- _In_opt_ IMFMediaType* inMediaType,
- _In_opt_ IMFMediaType *outMediaType,
- _In_ BOOL operation /*True = Encode, False = Decode*/,
- _Out_ IMFTransform **pTransform)
+//
+// Used to check if the pin is a custom pin or not!!
+//
+STDMETHODIMP CheckCustomPin(
+ _In_ CInPin * pPin,
+ _Inout_ PBOOL pIsCustom
+ )
{
- UNREFERENCED_PARAMETER(inMediaType);
- UNREFERENCED_PARAMETER(outMediaType);
- UNREFERENCED_PARAMETER(operation);
- UNREFERENCED_PARAMETER(pTransform);
HRESULT hr = S_OK;
- *pTransform = nullptr;
+ DMFTCHECKNULL_GOTO( pPin, done, E_INVALIDARG);
+ DMFTCHECKNULL_GOTO( pIsCustom, done, E_INVALIDARG);
+
+ *pIsCustom = false;
+
+#if defined _CPPRTTI
+ if (dynamic_cast<CCustomPin*>(pPin) != nullptr)
+ {
+ *pIsCustom = true;
+ }
+ else
+#endif
+ {
+ GUID categoryGUID = GUID_NULL;
+ if (SUCCEEDED(pPin->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &categoryGUID))
+ && IsEqualCLSID(categoryGUID, AVSTREAM_CUSTOM_PIN_IMAGE))
+ {
+ *pIsCustom = true;
+ }
+ }
+done:
return hr;
}
-HRESULT CheckDX9RotationSupport(_In_ ID3D11VideoDevice* pVideoDevice)
+#ifdef MF_DEVICEMFT_ADD_GRAYSCALER_
+//
+// Please remove the below functions if you don't need them.
+// Helper functions for the gray scaler
+//
+
+void TransformImage_UYVY(
+ const RECT &rcDest,
+ _Inout_updates_(_Inexpressible_(lDestStride * dwHeightInPixels)) BYTE *pDest,
+ _In_ LONG lDestStride,
+ _In_reads_(_Inexpressible_(lSrcStride * dwHeightInPixels)) const BYTE *pSrc,
+ _In_ LONG lSrcStride,
+ _In_ DWORD dwWidthInPixels,
+ _In_ DWORD dwHeightInPixels)
{
- HRESULT hr = S_OK;
- //
- // check if the DX9 device is ok
- // New drivers should have an DXVA-HD rotation cap set
- //
- D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {};
- D3D11_VIDEO_PROCESSOR_CAPS caps;
- ComPtr<ID3D11VideoProcessorEnumerator> spVideoProcEnum = nullptr;
+ DWORD y = 0;
+ // Round down to the even value.
+ const UINT32 left = rcDest.left & ~(1);
+ const UINT32 right = rcDest.right & ~(1);
+ const DWORD y0 = min((DWORD)rcDest.bottom, dwHeightInPixels);
+
+ // Lines above the destination rectangle.
+ for (; y < (DWORD)rcDest.top; y++)
+ {
+ CopyMemory(pDest, pSrc, dwWidthInPixels * 2);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
+ }
- DMFTCHECKNULL_GOTO(pVideoDevice, done, E_NOTIMPL);
- desc.InputWidth = 640;
- desc.InputHeight = 480;
- desc.OutputWidth = 640;
- desc.OutputHeight = 480;
+ // Lines within the destination rectangle.
+ for (; y < y0; y++)
+ {
+ const WORD *pSrc_Pixel = reinterpret_cast<const WORD*>(pSrc);
+ WORD *pDest_Pixel = reinterpret_cast<WORD*>(pDest);
- DMFTCHECKHR_GOTO(pVideoDevice->CreateVideoProcessorEnumerator(&desc, &spVideoProcEnum), done);
- DMFTCHECKHR_GOTO(spVideoProcEnum->GetVideoProcessorCaps(&caps), done);
+ CopyMemory(pDest, pSrc, left * 2);
+ for (DWORD x = left; (x + 1) < right; x += 2)
+ {
+ // Byte order is Y0 U0 Y1 V0
+ // Each WORD is a byte pair (Y, U/V)
+ // Windows is little-endian so the order appears reversed.
- if (!(caps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ROTATION))
+ DWORD tmp = *reinterpret_cast<const DWORD*>(&pSrc_Pixel[x]);
+ *reinterpret_cast<DWORD*>(&pDest_Pixel[x]) = (tmp & 0xFF00FF00) | 0x00800080;
+ }
+ CopyMemory(pDest + (right * 2), pSrc + (right * 2), (dwWidthInPixels - right) * 2);
+
+ pDest += lDestStride;
+ pSrc += lSrcStride;
+ }
+
+ // Lines below the destination rectangle.
+ for (; y < dwHeightInPixels; y++)
{
- hr = E_NOTIMPL;
+ CopyMemory(pDest, pSrc, dwWidthInPixels * 2);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
}
-done:
- return hr;
}
+// Convert YUY2 image.
-HRESULT IsDXOptimal(_In_ IUnknown *pDeviceManager, _Out_ BOOL *pIsOptimal)
+void TransformImage_YUY2(
+ const RECT &rcDest,
+ _Inout_updates_(_Inexpressible_(lDestStride * dwHeightInPixels)) BYTE *pDest,
+ _In_ LONG lDestStride,
+ _In_reads_(_Inexpressible_(lSrcStride * dwHeightInPixels)) const BYTE *pSrc,
+ _In_ LONG lSrcStride,
+ _In_ DWORD dwWidthInPixels,
+ _In_ DWORD dwHeightInPixels)
{
- HRESULT hr = S_OK;
- ComPtr<IMFDXGIDeviceManager> spDXGIDeviceManager = nullptr;
- ComPtr<ID3D11Device> spD3D11 = nullptr;
- ComPtr<ID3D11VideoDevice> spVideoDevice = nullptr;
- HANDLE hDevice = NULL;
- BOOL locked = FALSE;
+ DWORD y = 0;
+ // Round down to the even value.
+ const UINT32 left = rcDest.left & ~(1);
+ const UINT32 right = rcDest.right & ~(1);
+ const DWORD y0 = min((DWORD)rcDest.bottom, dwHeightInPixels);
- *pIsOptimal = false;
- DMFTCHECKNULL_GOTO( pDeviceManager, done, E_INVALIDARG );
- DMFTCHECKHR_GOTO( pDeviceManager->QueryInterface(IID_PPV_ARGS( &spDXGIDeviceManager )), done );
- DMFTCHECKHR_GOTO( spDXGIDeviceManager->OpenDeviceHandle( &hDevice ), done );
- DMFTCHECKHR_GOTO( spDXGIDeviceManager->LockDevice( hDevice, IID_PPV_ARGS( &spD3D11 ), TRUE), done );
- locked = TRUE;
- DMFTCHECKHR_GOTO( spD3D11.As(&spVideoDevice), done );
+ // Lines above the destination rectangle.
+ for (; y < (DWORD)rcDest.top; y++)
+ {
+ CopyMemory(pDest, pSrc, dwWidthInPixels * 2);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
+ }
- if (spD3D11->GetFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ // Lines within the destination rectangle.
+ for (; y < y0; y++)
{
- if (FAILED(CheckDX9RotationSupport(spVideoDevice.Get())))
+ const WORD *pSrc_Pixel = reinterpret_cast<const WORD*>(pSrc);
+ WORD *pDest_Pixel = reinterpret_cast<WORD*>(pDest);
+
+ CopyMemory(pDest, pSrc, left * 2);
+ for (DWORD x = left; (x + 1) < right; x += 2)
{
- goto done;
+ // Byte order is Y0 U0 Y1 V0
+ // Each WORD is a byte pair (Y, U/V)
+ // Windows is little-endian so the order appears reversed.
+
+ DWORD tmp = *reinterpret_cast<const DWORD*>(&pSrc_Pixel[x]);
+ *reinterpret_cast<DWORD*>(&pDest_Pixel[x]) = (tmp & 0x00FF00FF) | 0x80008000;
}
+ CopyMemory(pDest + (right * 2), pSrc + (right * 2), (dwWidthInPixels - right) * 2);
+
+ pDest += lDestStride;
+ pSrc += lSrcStride;
}
- *pIsOptimal = TRUE;
-done:
- if (hDevice)
+
+ // Lines below the destination rectangle.
+ for (; y < dwHeightInPixels; y++)
{
- if (locked)
- {
- spDXGIDeviceManager->UnlockDevice(hDevice, false);
- }
- spDXGIDeviceManager->CloseDeviceHandle(hDevice);
+ CopyMemory(pDest, pSrc, dwWidthInPixels * 2);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
}
- return hr;
}
+// Convert NV12 image
-//
-// Used to check if the pin is a custom pin or not!!
-//
+void TransformImage_NV12(
+ const RECT &rcDest,
+ _Inout_updates_(_Inexpressible_(2 * lDestStride * dwHeightInPixels)) BYTE *pDest,
+ _In_ LONG lDestStride,
+ _In_reads_(_Inexpressible_(2 * lSrcStride * dwHeightInPixels)) const BYTE *pSrc,
+ _In_ LONG lSrcStride,
+ _In_ DWORD dwWidthInPixels,
+ _In_ DWORD dwHeightInPixels)
+{
+ // NV12 is planar: Y plane, followed by packed U-V plane.
-STDMETHODIMP CheckCustomPin(
- _In_ CInPin * pPin,
- _Inout_ PBOOL pIsCustom
- )
+ // Y plane
+ for (DWORD y = 0; y < dwHeightInPixels; y++)
+ {
+ CopyMemory(pDest, pSrc, dwWidthInPixels);
+ pDest += lDestStride;
+ pSrc += lSrcStride;
+ }
+
+ // U-V plane
+
+ // NOTE: The U-V plane has 1/2 the number of lines as the Y plane.
+
+ // Lines above the destination rectangle.
+ DWORD y = 0;
+ const DWORD y0 = min((DWORD)rcDest.bottom, dwHeightInPixels);
+
+ for (; y < (DWORD)rcDest.top / 2; y++)
+ {
+ CopyMemory(pDest, pSrc, dwWidthInPixels);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
+ }
+
+ // Lines within the destination rectangle.
+ for (; y < y0 / 2; y++)
+ {
+ CopyMemory(pDest, pSrc, rcDest.left);
+ FillMemory(pDest + rcDest.left, rcDest.right - rcDest.left, 128);
+ CopyMemory(pDest + rcDest.right, pSrc + rcDest.right, dwWidthInPixels - rcDest.right);
+ pDest += lDestStride;
+ pSrc += lSrcStride;
+ }
+
+ // Lines below the destination rectangle.
+ for (; y < dwHeightInPixels / 2; y++)
+ {
+ CopyMemory(pDest, pSrc, dwWidthInPixels);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
+ }
+}
+
+
+
+void TransformImage_RGB32(
+ const RECT &rcDest,
+ _Inout_updates_(_Inexpressible_(2 * lDestStride * dwHeightInPixels)) BYTE *pDest,
+ _In_ LONG lDestStride,
+ _In_reads_(_Inexpressible_(2 * lSrcStride * dwHeightInPixels)) const BYTE *pSrc,
+ _In_ LONG lSrcStride,
+ _In_ DWORD dwWidthInPixels,
+ _In_ DWORD dwHeightInPixels)
{
- HRESULT hr = S_OK;
- DMFTCHECKNULL_GOTO( pPin, done, E_INVALIDARG);
- DMFTCHECKNULL_GOTO( pIsCustom, done, E_INVALIDARG);
-
- *pIsCustom = false;
+ DWORD y = 0;
+ const DWORD y0 = min((DWORD)rcDest.bottom, dwHeightInPixels);
-#if defined _CPPRTTI
- if (dynamic_cast<CCustomPin*>(pPin) != nullptr)
+ // Lines above the destination rectangle.
+ for (; y < (DWORD)rcDest.top; y++)
{
- *pIsCustom = true;
+ memcpy(pDest, pSrc, dwWidthInPixels * 4);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
}
- else
-#endif
+
+ // Lines within the destination rectangle.
+ // Use the grayscale conversion Red = 30%, Green = 59%, Blue = 11%
+ for (; y < y0; y++)
{
- GUID categoryGUID = GUID_NULL;
- if (SUCCEEDED(pPin->GetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, &categoryGUID))
- && IsEqualCLSID(categoryGUID, AVSTREAM_CUSTOM_PIN_IMAGE))
+ DWORD *pSrc_Pixel = (DWORD*)pSrc;
+ DWORD *pDest_Pixel = (DWORD*)pDest;
+
+ for (DWORD x = 0; (x + 1) < dwWidthInPixels; x++)
{
- *pIsCustom = true;
+ // Byte order is X8 R8 G8 B8
+
+ if (x >= (DWORD)rcDest.left && x < (DWORD)rcDest.right)
+ {
+ WORD color;
+ color = (pSrc_Pixel[x] & 0x000000FF);
+ int r = (int)(color * 0.3);
+ color = (pSrc_Pixel[x] & 0x0000FF00) >> 8;
+ int g = (int)(color * 0.59);
+ color = (pSrc_Pixel[x] & 0x00FF0000) >> 16;
+ int b = (int)(color * 0.11);
+ int gray = r + g + b;
+
+ pDest_Pixel[x] = (gray & 0x000000FF) << 16 |
+ (gray & 0x000000FF) << 8 |
+ (gray & 0x000000FF);
+ }
+ else
+ {
+#pragma warning(push)
+#pragma warning(disable: 6385)
+#pragma warning(disable: 6386)
+ pDest_Pixel[x] = pSrc_Pixel[x];
+#pragma warning(pop)
+ }
}
+
+ pDest += lDestStride;
+ pSrc += lSrcStride;
+ }
+
+ // Lines below the destination rectangle.
+ for (; y < dwHeightInPixels; y++)
+ {
+ memcpy(pDest, pSrc, dwWidthInPixels * 4);
+ pSrc += lSrcStride;
+ pDest += lDestStride;
}
-done:
- return hr;
}
+#endif \ No newline at end of file
diff --git a/avstream/sampledevicemft/stdafx.h b/avstream/sampledevicemft/stdafx.h
index 9f4bab9f..6c5550a3 100644
--- a/avstream/sampledevicemft/stdafx.h
+++ b/avstream/sampledevicemft/stdafx.h
@@ -37,3 +37,5 @@ using namespace std;
#include <wrl\client.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
+
+#define MF_DEVICEMFT_ADD_GRAYSCALER_ 1 // remore this to remove the grayscaler
diff --git a/avstream/samplemft0/SampleMft0.vcxproj b/avstream/samplemft0/SampleMft0.vcxproj
index f4d3fff4..90c623ba 100644
--- a/avstream/samplemft0/SampleMft0.vcxproj
+++ b/avstream/samplemft0/SampleMft0.vcxproj
@@ -36,19 +36,19 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows8</TargetVersion>
+ <TargetVersion>Win8</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows8</TargetVersion>
+ <TargetVersion>Win8</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <TargetVersion>Windows8</TargetVersion>
+ <TargetVersion>Win8</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <TargetVersion>Windows8</TargetVersion>
+ <TargetVersion>Win8</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff --git a/avstream/samplemft0/resource.h b/avstream/samplemft0/resource.h
index b2eb3f8b..d20cf5a1 100644
--- a/avstream/samplemft0/resource.h
+++ b/avstream/samplemft0/resource.h
Binary files differ