summaryrefslogtreecommitdiff
path: root/avstream/sampledevicemft/multipinmftutils.cpp
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 /avstream/sampledevicemft/multipinmftutils.cpp
parentdd7e6f697ed67e94dc45cd33078b1dbcb643f439 (diff)
Updating Camera WDK Samples to RS3 version (#193)
Diffstat (limited to 'avstream/sampledevicemft/multipinmftutils.cpp')
-rw-r--r--avstream/sampledevicemft/multipinmftutils.cpp348
1 files changed, 240 insertions, 108 deletions
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