266 lines
12 KiB
C++
266 lines
12 KiB
C++
#pragma once
|
|
|
|
#include "IMYMFT.h"
|
|
#include "CSampleQueue.h"
|
|
#include <Mfidl.h>
|
|
|
|
#define MFT_MAX_STREAMS 1
|
|
#define MFT_OUTPUT_WIDTH 1280
|
|
#define MFT_OUTPUT_HEIGHT 720
|
|
#define MFT_FRAMERATE_NUMERATOR 30
|
|
#define MFT_FRAMERATE_DENOMINATOR 1
|
|
#define MFT_DEFAULT_SAMPLE_DURATION 300000 // 1/30th of a second in hundred nanoseconds
|
|
|
|
enum eMFTStatus
|
|
{
|
|
MYMFT_STATUS_INPUT_ACCEPT_DATA = 0x00000001, /* The MFT can accept input data */
|
|
MYMFT_STATUS_OUTPUT_SAMPLE_READY = 0x00000002,
|
|
MYMFT_STATUS_STREAM_STARTED = 0x00000004,
|
|
MYMFT_STATUS_DRAINING = 0x00000008, /* See http://msdn.microsoft.com/en-us/library/dd940418(v=VS.85).aspx
|
|
** While the MFT is is in this state, it must not send
|
|
** any more METransformNeedInput events. It should continue
|
|
** to send METransformHaveOutput events until it is out of
|
|
** output. At that time, it should send METransformDrainComplete */
|
|
};
|
|
|
|
extern const GUID* g_ppguidInputTypes[];
|
|
extern const DWORD g_dwNumInputTypes;
|
|
extern const GUID* g_ppguidOutputTypes[];
|
|
extern const DWORD g_dwNumOutputTypes;
|
|
extern const GUID MYMFT_MFSampleExtension_Marker;
|
|
|
|
class CHWMFT:
|
|
public IMFTransform,
|
|
public IMFShutdown,
|
|
public IMFMediaEventGenerator,
|
|
public IMFAsyncCallback,
|
|
public IMYMFT
|
|
/*****************************
|
|
** Todo: if you add interfaces
|
|
** ensure that you add them
|
|
** to QueryInterface
|
|
*****************************/
|
|
{
|
|
public:
|
|
static volatile ULONG m_ulNumObjects; // Total object count
|
|
|
|
// Initializer
|
|
static HRESULT CreateInstance(IMFTransform** ppHWMFT);
|
|
|
|
#pragma region IUnknown
|
|
// IUnknown Implementations
|
|
ULONG __stdcall AddRef(void);
|
|
HRESULT __stdcall QueryInterface(
|
|
REFIID riid,
|
|
void** ppvObject
|
|
);
|
|
ULONG __stdcall Release(void);
|
|
#pragma endregion IUnknown
|
|
|
|
#pragma region IMFTransform
|
|
// IMFTransform Implementations
|
|
HRESULT __stdcall AddInputStreams(
|
|
DWORD dwStreams,
|
|
DWORD* pdwStreamIDs
|
|
);
|
|
HRESULT __stdcall DeleteInputStream(
|
|
DWORD dwStreamID
|
|
);
|
|
HRESULT __stdcall GetAttributes(
|
|
IMFAttributes** ppAttributes
|
|
);
|
|
HRESULT __stdcall GetInputAvailableType(
|
|
DWORD dwInputStreamID,
|
|
DWORD dwTypeIndex,
|
|
IMFMediaType** ppType
|
|
);
|
|
HRESULT __stdcall GetInputCurrentType(
|
|
DWORD dwInputStreamID,
|
|
IMFMediaType** ppType
|
|
);
|
|
HRESULT __stdcall GetInputStatus(
|
|
DWORD dwInputStreamID,
|
|
DWORD* pdwFlags
|
|
);
|
|
HRESULT __stdcall GetInputStreamAttributes(
|
|
DWORD dwInputStreamID,
|
|
IMFAttributes** ppAttributes
|
|
);
|
|
HRESULT __stdcall GetInputStreamInfo(
|
|
DWORD dwInputStreamID,
|
|
MFT_INPUT_STREAM_INFO* pStreamInfo
|
|
);
|
|
HRESULT __stdcall GetOutputAvailableType(
|
|
DWORD dwOutputStreamID,
|
|
DWORD dwTypeIndex,
|
|
IMFMediaType** ppType
|
|
);
|
|
HRESULT __stdcall GetOutputCurrentType(
|
|
DWORD dwOutputStreamID,
|
|
IMFMediaType** ppType
|
|
);
|
|
HRESULT __stdcall GetOutputStatus(
|
|
DWORD* pdwFlags
|
|
);
|
|
HRESULT __stdcall GetOutputStreamAttributes(
|
|
DWORD dwOutputStreamID,
|
|
IMFAttributes** ppAttributes
|
|
);
|
|
HRESULT __stdcall GetOutputStreamInfo(
|
|
DWORD dwOutputStreamID,
|
|
MFT_OUTPUT_STREAM_INFO* pStreamInfo
|
|
);
|
|
HRESULT __stdcall GetStreamCount(
|
|
DWORD* pdwInputStreams,
|
|
DWORD* pdwOutputStreams
|
|
);
|
|
HRESULT __stdcall GetStreamIDs(
|
|
DWORD dwInputIDArraySize,
|
|
DWORD* pdwInputIDs,
|
|
DWORD dwOutputIDArraySize,
|
|
DWORD* pdwOutputIDs
|
|
);
|
|
HRESULT __stdcall GetStreamLimits(
|
|
DWORD* pdwInputMinimum,
|
|
DWORD* pdwInputMaximum,
|
|
DWORD* pdwOutputMinimum,
|
|
DWORD* pdwOutputMaximum
|
|
);
|
|
HRESULT __stdcall ProcessEvent(
|
|
DWORD dwInputStreamID,
|
|
IMFMediaEvent* pEvent
|
|
);
|
|
HRESULT __stdcall ProcessInput(
|
|
DWORD dwInputStreamID,
|
|
IMFSample* pSample,
|
|
DWORD dwFlags
|
|
);
|
|
HRESULT __stdcall ProcessMessage(
|
|
MFT_MESSAGE_TYPE eMessage,
|
|
ULONG_PTR ulParam
|
|
);
|
|
HRESULT __stdcall ProcessOutput(
|
|
DWORD dwFlags,
|
|
DWORD dwOutputBufferCount,
|
|
MFT_OUTPUT_DATA_BUFFER* pOutputSamples,
|
|
DWORD* pdwStatus
|
|
);
|
|
HRESULT __stdcall SetInputType(
|
|
DWORD dwInputStreamID,
|
|
IMFMediaType* pType,
|
|
DWORD dwFlags
|
|
);
|
|
HRESULT __stdcall SetOutputBounds(
|
|
LONGLONG hnsLowerBound,
|
|
LONGLONG hnsUpperBound
|
|
);
|
|
HRESULT __stdcall SetOutputType(
|
|
DWORD dwOutputStreamID,
|
|
IMFMediaType* pType,
|
|
DWORD dwFlags
|
|
);
|
|
#pragma endregion IMFTransform
|
|
|
|
#pragma region IMFShutdown
|
|
// IMFShutdown Implementations
|
|
HRESULT __stdcall GetShutdownStatus(
|
|
MFSHUTDOWN_STATUS* pStatus
|
|
);
|
|
HRESULT __stdcall Shutdown(void);
|
|
#pragma endregion IMFShutdown
|
|
|
|
#pragma region IMFMediaEventGenerator
|
|
// IMFMediaEventGenerator Implementations
|
|
HRESULT __stdcall BeginGetEvent(
|
|
IMFAsyncCallback* pCallback,
|
|
IUnknown* punkState
|
|
);
|
|
HRESULT __stdcall EndGetEvent(
|
|
IMFAsyncResult* pResult,
|
|
IMFMediaEvent** ppEvent
|
|
);
|
|
HRESULT __stdcall GetEvent(
|
|
DWORD dwFlags,
|
|
IMFMediaEvent** ppEvent
|
|
);
|
|
HRESULT __stdcall QueueEvent(
|
|
MediaEventType met,
|
|
REFGUID guidExtendedType,
|
|
HRESULT hrStatus,
|
|
const PROPVARIANT* pvValue
|
|
);
|
|
#pragma endregion IMFMediaEventGenerator
|
|
|
|
#pragma region IMFAsyncCallback
|
|
// IMFAsyncCallback Implementations
|
|
HRESULT __stdcall GetParameters(
|
|
DWORD* pdwFlags,
|
|
DWORD* pdwQueue
|
|
);
|
|
HRESULT __stdcall Invoke(
|
|
IMFAsyncResult *pAsyncResult
|
|
);
|
|
#pragma endregion IMFAsyncCallback
|
|
|
|
// IMYMFT Implementations
|
|
HRESULT __stdcall DecodeInputFrame(
|
|
IMFSample* pInputSample
|
|
);
|
|
|
|
protected:
|
|
CHWMFT(void);
|
|
~CHWMFT(void);
|
|
|
|
HRESULT InitializeTransform(void);
|
|
HRESULT CheckInputType(
|
|
IMFMediaType* pMT
|
|
);
|
|
HRESULT CheckOutputType(
|
|
IMFMediaType* pMT
|
|
);
|
|
HRESULT ShutdownEventQueue(void);
|
|
|
|
/******* MFT Media Event Handlers**********/
|
|
HRESULT OnStartOfStream(void);
|
|
HRESULT OnEndOfStream(void);
|
|
HRESULT OnDrain(
|
|
const UINT32 un32StreamID
|
|
);
|
|
HRESULT OnFlush(void);
|
|
HRESULT OnMarker(
|
|
const ULONG_PTR pulID
|
|
);
|
|
/***********End Event Handlers************/
|
|
HRESULT RequestSample(
|
|
const UINT32 un32StreamID
|
|
);
|
|
HRESULT FlushSamples(void);
|
|
HRESULT ScheduleFrameDecode(void);
|
|
HRESULT SendEvent(void);
|
|
BOOL IsLocked(void);
|
|
BOOL IsMFTReady(void);
|
|
|
|
// Member variables
|
|
volatile ULONG m_ulRef;
|
|
volatile ULONG m_ulSampleCounter;
|
|
IMFMediaType* m_pInputMT;
|
|
IMFMediaType* m_pOutputMT;
|
|
IMFAttributes* m_pAttributes;
|
|
IMFMediaEventQueue* m_pEventQueue;
|
|
DWORD m_dwStatus;
|
|
DWORD m_dwNeedInputCount;
|
|
DWORD m_dwHaveOutputCount;
|
|
DWORD m_dwDecodeWorkQueueID;
|
|
LONGLONG m_llCurrentSampleTime;
|
|
BOOL m_bFirstSample;
|
|
BOOL m_bShutdown;
|
|
BOOL m_bDXVA;
|
|
CSampleQueue* m_pInputSampleQueue;
|
|
CSampleQueue* m_pOutputSampleQueue;
|
|
CRITICAL_SECTION m_csLock;
|
|
};
|
|
|
|
HRESULT DuplicateAttributes(
|
|
IMFAttributes* pDest,
|
|
IMFAttributes* pSource
|
|
); |