Sample Code
Windows Driver Samples/ Driver MFT Sample/ C++/ Mft0.cpp/
// Mft0.cpp : Implementation of CMft0 #include "stdafx.h" #include "Mft0.h" #include "SampleHelpers.h" #include <WinString.h> // CMft0 STDMETHODIMP CMft0::UpdateDsp(UINT32 uiPercentOfScreen) { m_percentOfScreen = uiPercentOfScreen; return S_OK; } STDMETHODIMP CMft0::Enable(void) { m_bEnableEffects = TRUE; return S_OK; } STDMETHODIMP CMft0::Disable(void) { m_bEnableEffects = FALSE; return S_OK; } STDMETHODIMP CMft0::GetDspSetting(UINT* puiPercentOfScreen, BOOL* pIsEnabled) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(puiPercentOfScreen); CHK_NULL_PTR_BRK(pIsEnabled); *puiPercentOfScreen = m_percentOfScreen; *pIsEnabled = m_bEnableEffects; } while (FALSE); return S_OK; } STDMETHODIMP CMft0::GetIids( /* [out] */ _Out_ ULONG *iidCount, /* [size_is][size_is][out] */ _Outptr_result_buffer_maybenull_(*iidCount) IID **iids) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(iidCount); CHK_NULL_PTR_BRK(iids); *iids = NULL; *iidCount = 0; } while (FALSE); return hr; } STDMETHODIMP CMft0::GetRuntimeClassName( /* [out] */ _Outptr_result_maybenull_ HSTRING *className) { HRESULT hr = S_OK; if(className != nullptr) { hr = WindowsCreateString(NULL, 0, className); if(FAILED(hr)){ hr = E_OUTOFMEMORY; } }else { hr = E_INVALIDARG; } return hr; } STDMETHODIMP CMft0::GetTrustLevel( /* [out] */ _Out_ TrustLevel *trustLevel) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(trustLevel); *trustLevel = TrustLevel::BaseTrust; } while (FALSE); return hr; } STDMETHODIMP CMft0::GetStreamLimits( /* [out] */ _Out_ DWORD *pdwInputMinimum, /* [out] */ _Out_ DWORD *pdwInputMaximum, /* [out] */ _Out_ DWORD *pdwOutputMinimum, /* [out] */ _Out_ DWORD *pdwOutputMaximum) { HRESULT hr = S_OK; do { if ((pdwInputMinimum == NULL) || (pdwInputMaximum == NULL) || (pdwOutputMinimum == NULL) || (pdwOutputMaximum == NULL)) { hr = E_POINTER; break; } // This MFT has a fixed number of streams. *pdwInputMinimum = 1; *pdwInputMaximum = 1; *pdwOutputMinimum = 1; *pdwOutputMaximum = 1; } while (FALSE); return hr; } STDMETHODIMP CMft0::GetStreamCount( /* [out] */ _Out_ DWORD *pcInputStreams, /* [out] */ _Out_ DWORD *pcOutputStreams) { HRESULT hr = S_OK; do { if ((pcInputStreams == NULL) || (pcOutputStreams == NULL)) { hr = E_POINTER; break; } // This MFT has a fixed number of streams. *pcInputStreams = 1; *pcOutputStreams = 1; } while (FALSE); return hr; } STDMETHODIMP CMft0::GetStreamIDs( DWORD dwInputIDArraySize, /* [size_is][out] */ _Out_writes_(dwInputIDArraySize) DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, /* [size_is][out] */ _Out_writes_(dwOutputIDArraySize) DWORD *pdwOutputIDs) { dwOutputIDArraySize = 0; dwInputIDArraySize = 0; pdwInputIDs = NULL; pdwOutputIDs = NULL; return E_NOTIMPL; } STDMETHODIMP CMft0::GetInputStreamInfo( DWORD dwInputStreamID, /* [out] */ _Out_ MFT_INPUT_STREAM_INFO *pStreamInfo) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(pStreamInfo); if (!IsValidInputStream(dwInputStreamID)) { CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); } if(m_pInputType) { pStreamInfo->cbAlignment = 0; pStreamInfo->cbSize = 0; pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER ; pStreamInfo->hnsMaxLatency = 0; } else { hr = MF_E_TRANSFORM_TYPE_NOT_SET; } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::GetOutputStreamInfo( DWORD dwOutputStreamID, /* [out] */ _Out_ MFT_OUTPUT_STREAM_INFO *pStreamInfo) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(pStreamInfo); if (!IsValidInputStream(dwOutputStreamID)) { CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); } if(m_pOutputType) { pStreamInfo->cbAlignment = 0; pStreamInfo->cbSize = 0; pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE; } else { hr = MF_E_TRANSFORM_TYPE_NOT_SET; } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::GetAttributes( /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(ppAttributes); if(!m_pGlobalAttributes) { CHK_LOG_BRK(MFCreateAttributes(&m_pGlobalAttributes, 3)); CHK_LOG_BRK(m_pGlobalAttributes->SetUINT32(MF_TRANSFORM_ASYNC, FALSE)); CHK_LOG_BRK(m_pGlobalAttributes->SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft")); CHK_LOG_BRK(m_pGlobalAttributes->SetUINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE)); } *ppAttributes = m_pGlobalAttributes; (*ppAttributes)->AddRef(); } while (FALSE); return hr; } STDMETHODIMP CMft0::GetInputStreamAttributes( DWORD dwInputStreamID, /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) { HRESULT hr = S_OK; do { if(dwInputStreamID > 0) { hr = MF_E_INVALIDSTREAMNUMBER; break; } CHK_NULL_PTR_BRK(ppAttributes); if(!m_pInputAttributes){ CHK_LOG_BRK(MFCreateAttributes(&m_pInputAttributes, 2)); CHK_LOG_BRK(m_pInputAttributes->SetUINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, TRUE)); CHK_LOG_BRK(m_pInputAttributes->SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"Sample_CameraExtensionMft")); } *ppAttributes = m_pInputAttributes; (*ppAttributes)->AddRef(); } while (FALSE); return hr; } STDMETHODIMP CMft0::GetOutputStreamAttributes( DWORD dwOutputStreamID, /* [out] */ _Outptr_result_maybenull_ IMFAttributes **ppAttributes) { HRESULT hr = S_OK; do { if(dwOutputStreamID > 0) { hr = MF_E_INVALIDSTREAMNUMBER; break; } CHK_NULL_PTR_BRK(ppAttributes); CHK_NULL_PTR_BRK(m_pInputAttributes); *ppAttributes = m_pInputAttributes; (*ppAttributes)->AddRef(); } while (FALSE); return hr; } STDMETHODIMP CMft0::DeleteInputStream( DWORD dwStreamID) { HRESULT hr = S_OK; if(dwStreamID > 0) { hr = MF_E_INVALIDSTREAMNUMBER; } else { hr = E_NOTIMPL; } return hr; } STDMETHODIMP CMft0::AddInputStreams( DWORD cStreams, /* [in] */ _In_ DWORD *adwStreamIDs) { HRESULT hr = S_OK; if( !adwStreamIDs || cStreams > 0) { hr = E_INVALIDARG; } else { hr = E_NOTIMPL; } return hr; } STDMETHODIMP CMft0::GetInputAvailableType( DWORD dwInputStreamID, DWORD dwTypeIndex, /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) { HRESULT hr = S_OK; IUnknown *pUnk = NULL; IMFAttributes *pSourceAttributes = NULL; wchar_t *pszName; EnterCriticalSection(&m_critSec); do { CHK_BOOL_BRK(IsValidInputStream(dwInputStreamID)); if(!m_pSourceTransform && m_pInputAttributes) { CHK_LOG_BRK(m_pInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(&pSourceAttributes))); CHK_LOG_BRK(pSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(&pUnk))); CHK_LOG_BRK(pUnk->QueryInterface(__uuidof(IMFTransform), (void**)&m_pSourceTransform)); CHK_LOG_BRK(pSourceAttributes->GetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType)); if(m_stStreamType == PINNAME_VIDEO_CAPTURE) { wprintf(L"Stream type: PINNAME_VIDEO_CAPTURE\n"); } else if(m_stStreamType == PINNAME_VIDEO_PREVIEW) { wprintf(L"Stream type: PINNAME_VIDEO_PREVIEW\n"); } else if(m_stStreamType == PINNAME_VIDEO_STILL) { wprintf(L"Stream type: PINNAME_VIDEO_STILL\n"); } else if(m_stStreamType == PINNAME_IMAGE) { wprintf(L"Stream type: PINNAME_IMAGE\n"); } else { StringFromCLSID(m_stStreamType, &pszName); if(pszName){ wprintf(L"Stream type: %s\n", pszName); CoTaskMemFree(pszName); } } CHK_LOG_BRK((m_stStreamType == PINNAME_VIDEO_PREVIEW || m_stStreamType == PINNAME_VIDEO_CAPTURE) ? S_OK : E_UNEXPECTED); CHK_LOG_BRK(GenerateMFMediaTypeListFromDevice(dwInputStreamID)); } CHK_LOG_BRK(GetMediaType(dwInputStreamID, dwTypeIndex, ppType)); } while (FALSE); LeaveCriticalSection(&m_critSec); SAFERELEASE(pUnk); SAFERELEASE(pSourceAttributes); return hr; } STDMETHODIMP CMft0::GetOutputAvailableType( DWORD dwOutputStreamID, DWORD dwTypeIndex, /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) { HRESULT hr = S_OK; IUnknown *pUnk = NULL; IMFAttributes *pSourceAttributes = NULL; wchar_t *pszName; EnterCriticalSection(&m_critSec); do { CHK_BOOL_BRK(IsValidOutputStream(dwOutputStreamID)); if(!m_pSourceTransform && m_pInputAttributes) { CHK_LOG_BRK(m_pInputAttributes->GetUnknown(MFT_CONNECTED_STREAM_ATTRIBUTE, IID_PPV_ARGS(&pSourceAttributes))); CHK_LOG_BRK(pSourceAttributes->GetUnknown(MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT, IID_PPV_ARGS(&pUnk))); CHK_LOG_BRK(pUnk->QueryInterface(__uuidof(IMFTransform), (void**)&m_pSourceTransform)); CHK_LOG_BRK(pSourceAttributes->GetGUID( MF_DEVICESTREAM_STREAM_CATEGORY, &m_stStreamType)); if(m_stStreamType == PINNAME_VIDEO_CAPTURE) { wprintf(L"Stream type: PINNAME_VIDEO_CAPTURE\n"); } else if(m_stStreamType == PINNAME_VIDEO_PREVIEW) { wprintf(L"Stream type: PINNAME_VIDEO_PREVIEW\n"); } else if(m_stStreamType == PINNAME_VIDEO_STILL) { wprintf(L"Stream type: PINNAME_VIDEO_STILL\n"); } else if(m_stStreamType == PINNAME_IMAGE) { wprintf(L"Stream type: PINNAME_IMAGE\n"); } else { StringFromCLSID(m_stStreamType, &pszName); wprintf(L"Stream type: %s\n", pszName); } CHK_LOG_BRK((m_stStreamType == PINNAME_VIDEO_PREVIEW || m_stStreamType == PINNAME_VIDEO_CAPTURE) ? S_OK : E_UNEXPECTED); CHK_LOG_BRK(GenerateMFMediaTypeListFromDevice(dwOutputStreamID)); } CHK_LOG_BRK(GetMediaType(dwOutputStreamID, dwTypeIndex, ppType)); } while (FALSE); LeaveCriticalSection(&m_critSec); SAFERELEASE(pUnk); SAFERELEASE(pSourceAttributes); return hr; } STDMETHODIMP CMft0::SetInputType( DWORD dwInputStreamID, /* [in] */ _In_opt_ IMFMediaType *pType, DWORD dwFlags) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0); // Validate flags. do { if(bReallySet) { CComPtr<IMFMediaType> pFullType; CHK_LOG_BRK(IsMediaTypeSupported(dwInputStreamID, pType, &pFullType)); SAFERELEASE(m_pInputType); SAFERELEASE(m_pOutputType); m_pOutputType = pFullType; m_pOutputType->AddRef(); m_pInputType = pFullType; m_pInputType->AddRef(); } else { CHK_LOG_BRK(IsMediaTypeSupported(dwInputStreamID, pType)); } } while(FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::SetOutputType( DWORD dwOutputStreamID, /* [in] */ _In_opt_ IMFMediaType *pType, DWORD dwFlags) { HRESULT hr = S_OK; do { CHK_LOG_BRK(SetInputType(dwOutputStreamID, pType, dwFlags)); } while (FALSE); return hr; } STDMETHODIMP CMft0::GetInputCurrentType( DWORD dwInputStreamID, /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(ppType); if (!IsValidInputStream(dwInputStreamID)) { CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); } else if(m_pInputType) { *ppType = m_pInputType; (*ppType)->AddRef(); } else { CHK_LOG_BRK(MF_E_TRANSFORM_TYPE_NOT_SET); } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::GetOutputCurrentType( DWORD dwOutputStreamID, /* [out] */ _Outptr_result_maybenull_ IMFMediaType **ppType) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(ppType); if (!IsValidOutputStream(dwOutputStreamID)) { CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); } else if(m_pOutputType) { *ppType = m_pOutputType; (*ppType)->AddRef(); } else { CHK_LOG_BRK(MF_E_TRANSFORM_TYPE_NOT_SET); } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::GetInputStatus( DWORD dwInputStreamID, /* [out] */ _Out_ DWORD *pdwFlags) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_BOOL_BRK(pdwFlags); if (!IsValidInputStream(dwInputStreamID)) { CHK_LOG_BRK(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_pSample == NULL) { *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA; } else { *pdwFlags = 0; } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::GetOutputStatus( /* [out] */ _Out_ DWORD *pdwFlags) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(pdwFlags); // We can produce an output sample if (and only if) // we have an input sample. if (m_pSample != NULL) { *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY; } else { *pdwFlags = 0; } } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::SetOutputBounds( LONGLONG hnsLowerBound, LONGLONG hnsUpperBound) { UNREFERENCED_PARAMETER(hnsLowerBound); UNREFERENCED_PARAMETER(hnsUpperBound); return S_OK; } STDMETHODIMP CMft0::ProcessEvent( DWORD dwInputStreamID, /* [in] */ _In_opt_ IMFMediaEvent *pEvent) { UNREFERENCED_PARAMETER(dwInputStreamID); UNREFERENCED_PARAMETER(pEvent); return E_NOTIMPL; } STDMETHODIMP CMft0::ProcessMessage( MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) { UNREFERENCED_PARAMETER(ulParam); HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); switch (eMessage) { case MFT_MESSAGE_COMMAND_FLUSH: // Flush the MFT. hr = OnFlush(); break; case MFT_MESSAGE_COMMAND_DRAIN: // Drain: Tells the MFT not to accept any more input until // all of the pending output has been processed. That is our // default behevior already, so there is nothing to do. break; case MFT_MESSAGE_SET_D3D_MANAGER: // The pipeline should never send this message unless the MFT // has the MF_SA_D3D_AWARE attribute set to TRUE. However, if we // do get this message, it's invalid and we don't implement it. hr = E_NOTIMPL; break; // The remaining messages do not require any action from this MFT. case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: case MFT_MESSAGE_NOTIFY_END_STREAMING: case MFT_MESSAGE_NOTIFY_END_OF_STREAM: case MFT_MESSAGE_NOTIFY_START_OF_STREAM: break; } LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::ProcessInput( DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags) { HRESULT hr = S_OK; EnterCriticalSection(&m_critSec); do { CHK_NULL_BRK(pSample); CHK_BOOL_BRK(dwFlags == 0) DWORD dwBufferCount = 0; if (!IsValidInputStream(dwInputStreamID)) { CHK_LOG_BRK(hr = MF_E_INVALIDSTREAMNUMBER); } if (!m_pInputType || !m_pOutputType) { CHK_LOG_BRK(MF_E_NOTACCEPTING); // Client must set input and output types. } if (m_pSample != NULL) { CHK_LOG_BRK(MF_E_NOTACCEPTING); // We already have an input sample. } // Validate the number of buffers. There should only be a single buffer to hold the video frame. CHK_LOG_BRK(pSample->GetBufferCount(&dwBufferCount)); if (dwBufferCount == 0) { CHK_LOG_BRK(E_FAIL); } if (dwBufferCount > 1) { CHK_LOG_BRK(MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS); } // Cache the sample. We do the actual work in ProcessOutput. m_pSample = pSample; pSample->AddRef(); // Hold a reference count on the sample. } while (FALSE); LeaveCriticalSection(&m_critSec); return hr; } STDMETHODIMP CMft0::ProcessOutput( DWORD dwFlags, DWORD cOutputBufferCount, /* [size_is][out][in] */ MFT_OUTPUT_DATA_BUFFER *pOutputSamples, /* [out] */ DWORD *pdwStatus) { HRESULT hr = S_OK; IMFMediaBuffer *pMediaBufInput = NULL, *pMediaBufOutput = NULL; IMFSample *pOutputIMFSample = NULL; LONGLONG hnsDuration = 0, hnsTime = 0; EnterCriticalSection(&m_critSec); do { CHK_BOOL_BRK(dwFlags == 0); CHK_NULL_BRK(pOutputSamples); CHK_NULL_BRK(pdwStatus); // Must be exactly one output buffer. CHK_BOOL_BRK(cOutputBufferCount == 1); // If we don't have an input sample, we need some input before // we can generate any output. if (m_pSample == NULL) { hr = MF_E_TRANSFORM_NEED_MORE_INPUT; break; } CHK_LOG_BRK(m_pSample->ConvertToContiguousBuffer(&pMediaBufInput)); MFCreateSample(&pOutputIMFSample); if(!pOutputSamples[0].pSample){ CHK_LOG_BRK(m_pSample->ConvertToContiguousBuffer(&pMediaBufOutput)); } else { CHK_LOG_BRK(pOutputSamples[0].pSample->ConvertToContiguousBuffer(&pMediaBufOutput)); } pOutputIMFSample->AddBuffer(pMediaBufOutput); CHK_LOG_BRK(OnProcessOutput(pMediaBufInput, pMediaBufOutput)); pOutputSamples[0].pSample = pOutputIMFSample; pOutputIMFSample->AddRef(); pOutputSamples[0].dwStatus = 0; *pdwStatus = 0; if (SUCCEEDED(m_pSample->GetSampleDuration(&hnsDuration))) { CHK_LOG_BRK(pOutputSamples[0].pSample->SetSampleDuration(hnsDuration)); } if (SUCCEEDED(m_pSample->GetSampleTime(&hnsTime))) { CHK_LOG_BRK(pOutputSamples[0].pSample->SetSampleTime(hnsTime)); } } while (FALSE); SAFERELEASE(pOutputIMFSample); SAFERELEASE(pMediaBufInput); SAFERELEASE(pMediaBufOutput); SAFERELEASE(m_pSample); // Release our input sample. LeaveCriticalSection(&m_critSec); return hr; } BOOL CMft0::IsValidInputStream(DWORD dwInputStreamID) { return dwInputStreamID == 0; } // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier. BOOL CMft0::IsValidOutputStream(DWORD dwOutputStreamID) { //update return dwOutputStreamID == 0; } STDMETHODIMP CMft0::OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut) { HRESULT hr = S_OK; LONG lDefaultStride = 0, lSrcStride = 0, lDestStride = 0; UINT uiWidth = 0, uiHeight = 0; BYTE *pDest = NULL, *pSrc = NULL; //BOOL bCompressed = TRUE; GUID stSubType = {0}; do { CHK_NULL_PTR_BRK(m_pSample); CHK_NULL_PTR_BRK(m_pInputType); CHK_LOG_BRK(m_pInputType->GetGUID(MF_MT_SUBTYPE, &stSubType)); if(((stSubType == MFVideoFormat_RGB8) || (stSubType == MFVideoFormat_RGB555) || (stSubType == MFVideoFormat_RGB565) || (stSubType == MFVideoFormat_RGB24) || (stSubType == MFVideoFormat_RGB32) || (stSubType == MFVideoFormat_ARGB32) || (stSubType == MFVideoFormat_AI44) || (stSubType == MFVideoFormat_AYUV) || (stSubType == MFVideoFormat_I420) || (stSubType == MFVideoFormat_IYUV) || (stSubType == MFVideoFormat_NV11) || (stSubType == MFVideoFormat_NV12) || (stSubType == MFVideoFormat_UYVY) || (stSubType == MFVideoFormat_Y41P) || (stSubType == MFVideoFormat_Y41T) || (stSubType == MFVideoFormat_Y42T) || (stSubType == MFVideoFormat_YUY2) || (stSubType == MFVideoFormat_YV12) || (stSubType == MFVideoFormat_P010) || (stSubType == MFVideoFormat_P016) || (stSubType == MFVideoFormat_P210) || (stSubType == MFVideoFormat_P216) || (stSubType == MFVideoFormat_v210) || (stSubType == MFVideoFormat_v216) || (stSubType == MFVideoFormat_v410) || (stSubType == MFVideoFormat_Y210) || (stSubType == MFVideoFormat_Y216) || (stSubType == MFVideoFormat_Y410) || (stSubType == MFVideoFormat_Y416)) && m_bEnableEffects) { CHK_LOG_BRK(GetDefaultStride(&lDefaultStride)); CHK_LOG_BRK(MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &uiWidth, &uiHeight)); VideoBufferLock inputLock(pIn); VideoBufferLock outputLock(pOut); // Lock the input buffer. CHK_LOG_BRK(inputLock.LockBuffer(lDefaultStride, uiHeight, &pSrc, &lSrcStride)); // Lock the output buffer. CHK_LOG_BRK(outputLock.LockBuffer(lDefaultStride, uiHeight, &pDest, &lDestStride)); long lines = uiHeight; if(m_percentOfScreen != -1 && m_percentOfScreen != 0) { lines = (UINT)(uiHeight * (1.0- m_percentOfScreen/100.00)); } for(long i = 0; i < (long)uiHeight; i++) { if(lDestStride < 0) { if(i >= lines) { memset(pDest+i*lDestStride, 0, abs(lDefaultStride)); } else { memcpy(pDest+i*lDestStride, pSrc+i*lDefaultStride, abs(lDefaultStride)); } } else { if(i >= lines) { memset(pDest+i*lDestStride, 0, lDestStride); } else { memcpy(pDest+i*lDestStride, pSrc+i*lDestStride, lDestStride); } } } } } while (FALSE); return hr; } STDMETHODIMP CMft0::GetDefaultStride(LONG *plStride) { LONG lStride = 0; // Try to get the default stride from the media type. HRESULT hr = m_pInputType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride); if (FAILED(hr)) { // Attribute not set. Try to calculate the default stride. GUID subtype = GUID_NULL; UINT32 width = 0; UINT32 height = 0; // Get the subtype and the image size. hr = m_pInputType->GetGUID(MF_MT_SUBTYPE, &subtype); if (SUCCEEDED(hr)) { hr = MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &width, &height); } if (SUCCEEDED(hr)) { hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride); } // Set the attribute for later reference. if (SUCCEEDED(hr)) { (void)m_pInputType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride)); } } if (SUCCEEDED(hr)) { *plStride = lStride; } return hr; } STDMETHODIMP CMft0::OnFlush() { HRESULT hr = S_OK; // For this MFT, flushing just means releasing the input sample. SAFERELEASE(m_pSample); return hr; } STDMETHODIMP CMft0::GetMediaType( DWORD dwStreamId, DWORD dwTypeIndex, IMFMediaType **ppType) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(ppType); if(dwStreamId != 0) CHK_LOG_BRK(MF_E_INVALIDSTREAMNUMBER); if(dwTypeIndex >= m_listOfMediaTypes.GetCount()) CHK_LOG_BRK(MF_E_NO_MORE_TYPES); *ppType = m_listOfMediaTypes[dwTypeIndex]; (*ppType)->AddRef(); } while (FALSE); return hr; } STDMETHODIMP CMft0::IsMediaTypeSupported(UINT uiStreamId, IMFMediaType *pIMFMediaType, IMFMediaType **ppIMFMediaTypeFull) { HRESULT hr = S_OK; do { CHK_NULL_PTR_BRK(pIMFMediaType); if(uiStreamId != 0) { CHK_LOG_BRK(MF_E_INVALIDINDEX); } BOOL bFound =FALSE; for(UINT i = 0; i< m_listOfMediaTypes.GetCount(); i++) { DWORD dwResult = 0; hr = m_listOfMediaTypes[i]->IsEqual(pIMFMediaType, &dwResult); if(hr == S_FALSE) { 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) { bFound = TRUE; if(ppIMFMediaTypeFull) { *ppIMFMediaTypeFull = m_listOfMediaTypes[i]; (*ppIMFMediaTypeFull)->AddRef(); } break; } else if(FAILED(hr)) { CHK_LOG_BRK(hr); } } if(bFound == FALSE) { CHK_LOG_BRK(MF_E_INVALIDMEDIATYPE); } } while (FALSE); return hr; } STDMETHODIMP CMft0::GenerateMFMediaTypeListFromDevice(UINT uiStreamId) { HRESULT hr = S_OK; GUID stSubType = {0}; do { CHK_NULL_PTR_BRK(m_pSourceTransform); m_listOfMediaTypes.RemoveAll(); for(UINT iMediaType = 0; TRUE; iMediaType++) { CComPtr<IMFMediaType> pMediaType; hr = m_pSourceTransform->GetOutputAvailableType(uiStreamId, iMediaType, &pMediaType); if(hr != S_OK) break; CHK_LOG_BRK(pMediaType->GetGUID(MF_MT_SUBTYPE, &stSubType)); if(((stSubType == MFVideoFormat_RGB8) || (stSubType == MFVideoFormat_RGB555) || (stSubType == MFVideoFormat_RGB565) || (stSubType == MFVideoFormat_RGB24) || (stSubType == MFVideoFormat_RGB32) || (stSubType == MFVideoFormat_ARGB32) || (stSubType == MFVideoFormat_AI44) || (stSubType == MFVideoFormat_AYUV) || (stSubType == MFVideoFormat_I420) || (stSubType == MFVideoFormat_IYUV) || (stSubType == MFVideoFormat_NV11) || (stSubType == MFVideoFormat_NV12) || (stSubType == MFVideoFormat_UYVY) || (stSubType == MFVideoFormat_Y41P) || (stSubType == MFVideoFormat_Y41T) || (stSubType == MFVideoFormat_Y42T) || (stSubType == MFVideoFormat_YUY2) || (stSubType == MFVideoFormat_YV12) || (stSubType == MFVideoFormat_P010) || (stSubType == MFVideoFormat_P016) || (stSubType == MFVideoFormat_P210) || (stSubType == MFVideoFormat_P216) || (stSubType == MFVideoFormat_v210) || (stSubType == MFVideoFormat_v216) || (stSubType == MFVideoFormat_v410) || (stSubType == MFVideoFormat_Y210) || (stSubType == MFVideoFormat_Y216) || (stSubType == MFVideoFormat_Y410) || (stSubType == MFVideoFormat_Y416)) && m_bEnableEffects) { m_listOfMediaTypes[(ULONG)(m_listOfMediaTypes.GetCount())] = pMediaType; } } } while (FALSE); if(hr == MF_E_NO_MORE_TYPES) { hr = S_OK; } return hr; }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials