Skip to content

Commit

Permalink
Merge pull request #64 from microsoft/user/cjrog/AddSamples
Browse files Browse the repository at this point in the history
Add Xaml Swapchain samples
  • Loading branch information
cjrog authored Mar 13, 2024
2 parents db559c3 + 5f9865b commit 24a5f0c
Show file tree
Hide file tree
Showing 87 changed files with 4,272 additions and 0 deletions.
233 changes: 233 additions & 0 deletions samples/XamlSwapchainSample/BasicMFTClass/BasicMFT.cpp
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;
}
53 changes: 53 additions & 0 deletions samples/XamlSwapchainSample/BasicMFTClass/BasicMFT.h
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;
};
Loading

0 comments on commit 24a5f0c

Please sign in to comment.