-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from microsoft/user/cjrog/AddSamples
Add Xaml Swapchain samples
- Loading branch information
Showing
87 changed files
with
4,272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
#include "pch.h" | ||
#include "BasicMFT.h" | ||
|
||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::GetStreamLimits(DWORD* pdwInputMinimum, DWORD* pdwInputMaximum, DWORD* pdwOutputMinimum, DWORD* pdwOutputMaximum) | ||
{ | ||
if ((pdwInputMinimum == nullptr) || (pdwInputMaximum == nullptr) || (pdwOutputMinimum == nullptr) || (pdwOutputMaximum == nullptr)) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
// This MFT has a fixed number of streams. | ||
*pdwInputMinimum = 1; | ||
*pdwInputMaximum = 1; | ||
*pdwOutputMinimum = 1; | ||
*pdwOutputMaximum = 1; | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::GetStreamCount(DWORD* pcInputStreams, DWORD* pcOutputStreams) | ||
{ | ||
if ((pcInputStreams == nullptr) || (pcOutputStreams == nullptr)) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
// This MFT has a fixed number of streams. | ||
*pcInputStreams = 1; | ||
*pcOutputStreams = 1; | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP BasicMFT::GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO* pStreamInfo) | ||
{ | ||
if (dwInputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
if (pStreamInfo == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
pStreamInfo->dwFlags = MFT_INPUT_STREAM_PROCESSES_IN_PLACE; | ||
|
||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP BasicMFT::GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO* pStreamInfo) | ||
{ | ||
if (dwOutputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
if (pStreamInfo == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; | ||
|
||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::SetInputType(DWORD dwInputStreamID, IMFMediaType* pType, DWORD dwFlags) | ||
{ | ||
if (dwInputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
RETURN_IF_FAILED(MFCreateMediaType(&m_inputType)); | ||
RETURN_IF_FAILED(pType->CopyAllItems(m_inputType.Get())); | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::SetOutputType(DWORD dwOutputStreamID, IMFMediaType* pType, DWORD dwFlags) | ||
{ | ||
if (dwOutputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
RETURN_IF_FAILED(MFCreateMediaType(&m_outputType)); | ||
RETURN_IF_FAILED(pType->CopyAllItems(m_outputType.Get())); | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType** ppType) | ||
{ | ||
if (ppType == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
if (dwInputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
if (!m_inputType) | ||
{ | ||
return MF_E_TRANSFORM_TYPE_NOT_SET; | ||
} | ||
|
||
return m_inputType->CopyAllItems(*ppType); | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType** ppType) | ||
{ | ||
if (ppType == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
if (dwOutputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
if (!m_outputType) | ||
{ | ||
return MF_E_TRANSFORM_TYPE_NOT_SET; | ||
} | ||
|
||
return m_outputType->CopyAllItems(*ppType); | ||
} | ||
|
||
IFACEMETHODIMP BasicMFT::GetInputStatus(DWORD dwInputStreamID, DWORD* pdwFlags) | ||
{ | ||
if (dwInputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
if (m_inputType == nullptr || m_outputType == nullptr) | ||
{ | ||
return MF_E_TRANSFORM_TYPE_NOT_SET; | ||
} | ||
|
||
*pdwFlags = m_sample == nullptr ? 1 : 0; | ||
|
||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) | ||
{ | ||
switch (eMessage) | ||
{ | ||
case MFT_MESSAGE_COMMAND_FLUSH: | ||
// Flush the MFT. | ||
m_sample = nullptr; | ||
break; | ||
|
||
case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: | ||
m_streamingInitialized = true; | ||
break; | ||
|
||
case MFT_MESSAGE_NOTIFY_END_STREAMING: | ||
m_streamingInitialized = false; | ||
break; | ||
|
||
// The remaining messages require no action | ||
case MFT_MESSAGE_SET_D3D_MANAGER: | ||
case MFT_MESSAGE_NOTIFY_END_OF_STREAM: | ||
case MFT_MESSAGE_NOTIFY_START_OF_STREAM: | ||
case MFT_MESSAGE_COMMAND_DRAIN: | ||
break; | ||
} | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::ProcessInput(DWORD dwInputStreamID, IMFSample* pSample, DWORD dwFlags) | ||
{ | ||
// Check input parameters. | ||
if (pSample == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
if (dwInputStreamID != 0) | ||
{ | ||
return MF_E_INVALIDSTREAMNUMBER; | ||
} | ||
|
||
auto lock = m_critSec.Lock(); | ||
|
||
// Check for valid media types. | ||
// The client must set input and output types before calling ProcessInput. | ||
// Check if an input sample is already queued. | ||
if (!m_inputType || !m_outputType || (m_sample != nullptr)) | ||
{ | ||
return MF_E_NOTACCEPTING; | ||
} | ||
|
||
// Cache the sample. We do the actual work in ProcessOutput. | ||
m_sample = pSample; | ||
return S_OK; | ||
} | ||
|
||
IFACEMETHODIMP_(HRESULT __stdcall) BasicMFT::ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER* pOutputSamples, DWORD* pdwStatus) | ||
{ | ||
if (dwFlags != 0 || cOutputBufferCount != 1) | ||
{ | ||
return E_INVALIDARG; | ||
} | ||
|
||
if (pOutputSamples == nullptr || pdwStatus == nullptr) | ||
{ | ||
return E_POINTER; | ||
} | ||
|
||
if (pOutputSamples->pSample != nullptr) | ||
{ | ||
return E_INVALIDARG; | ||
} | ||
|
||
auto lock = m_critSec.Lock(); | ||
|
||
if (m_sample == nullptr) | ||
{ | ||
return MF_E_TRANSFORM_NEED_MORE_INPUT; | ||
} | ||
|
||
RETURN_IF_FAILED(m_sample.CopyTo(IID_PPV_ARGS(&pOutputSamples[0].pSample))); | ||
pOutputSamples[0].dwStatus = 0; | ||
|
||
m_sample = nullptr; | ||
|
||
return S_OK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#pragma once | ||
|
||
#include "pch.h" | ||
#include <wrl\wrappers\corewrappers.h> | ||
#include <mfapi.h> | ||
|
||
using namespace Microsoft::WRL; | ||
using Microsoft::WRL::ComPtr; | ||
using Microsoft::WRL::Wrappers::CriticalSection; | ||
|
||
class __declspec(uuid("F1BF74F0-65F4-4F47-925C-E8B564A9A87E")) BasicMFT : | ||
public RuntimeClass < | ||
RuntimeClassFlags< RuntimeClassType::WinRtClassicComMix >, | ||
IMFTransform > | ||
{ | ||
public: | ||
IFACEMETHOD(RuntimeClassInitialize)() { return S_OK; } | ||
|
||
BasicMFT() {} | ||
|
||
// IMFTransform | ||
IFACEMETHODIMP GetStreamLimits(DWORD* pdwInputMinimum, DWORD* pdwInputMaximum, DWORD* pdwOutputMinimum, DWORD* pdwOutputMaximum); | ||
IFACEMETHODIMP GetStreamCount(DWORD* pcInputStreams, DWORD* pcOutputStreams); | ||
IFACEMETHODIMP GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO* pStreamInfo); | ||
IFACEMETHODIMP GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO* pStreamInfo); | ||
IFACEMETHODIMP GetAttributes(IMFAttributes** pAttributes) { return E_NOTIMPL; } | ||
IFACEMETHODIMP GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType** ppType) { return E_NOTIMPL; } | ||
IFACEMETHODIMP GetOutputAvailableType(DWORD dwOutputStreamID, DWORD dwTypeIndex, IMFMediaType** ppType) { return E_NOTIMPL; } | ||
IFACEMETHODIMP SetInputType(DWORD dwInputStreamID, IMFMediaType* pType, DWORD dwFlags); | ||
IFACEMETHODIMP SetOutputType(DWORD dwOutputStreamID, IMFMediaType* pType, DWORD dwFlags); | ||
IFACEMETHODIMP GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType** ppType); | ||
IFACEMETHODIMP GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType** ppType); | ||
IFACEMETHODIMP GetInputStatus(DWORD dwInputStreamID, DWORD* pdwFlags); | ||
IFACEMETHODIMP GetOutputStatus(DWORD* pdwFlags) { return E_NOTIMPL; } | ||
IFACEMETHODIMP ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam); | ||
IFACEMETHODIMP ProcessInput(DWORD dwInputStreamID, IMFSample* pSample, DWORD dwFlags); | ||
IFACEMETHODIMP ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER* pOutputSamples, DWORD* pdwStatus); | ||
IFACEMETHODIMP GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes** ppAttributes) { return E_NOTIMPL; } | ||
IFACEMETHODIMP GetStreamIDs(DWORD, DWORD*, DWORD, DWORD*) { return E_NOTIMPL; } | ||
IFACEMETHODIMP GetInputStreamAttributes(DWORD, IMFAttributes**) { return E_NOTIMPL; } | ||
IFACEMETHODIMP DeleteInputStream(DWORD) { return E_NOTIMPL; } | ||
IFACEMETHODIMP AddInputStreams(DWORD, DWORD*) { return E_NOTIMPL; } | ||
IFACEMETHODIMP SetOutputBounds(LONGLONG, LONGLONG) { return E_NOTIMPL; } | ||
IFACEMETHODIMP ProcessEvent(DWORD, IMFMediaEvent*) { return E_NOTIMPL; } | ||
|
||
private: | ||
bool m_streamingInitialized = false; | ||
ComPtr<IMFSample> m_sample; // Input sample. | ||
ComPtr<IMFMediaType> m_inputType; // Input media type. | ||
ComPtr<IMFMediaType> m_outputType; // Output media type. | ||
|
||
CriticalSection m_critSec; | ||
}; |
Oops, something went wrong.