├── AudioSourceReaderSeek
├── AudioSourceReaderSeek.sln
├── AudioSourceReaderSeek.vcxproj
├── AudioSourceReaderSeek.vcxproj.filters
├── AudioSourceReaderSeek.vcxproj.user
└── Main.cpp
├── CustomVideoMixer
├── Common
│ ├── MFClassFactory.h
│ ├── MFCriticSection.h
│ ├── MFGuid.h
│ ├── MFLogCommon.h
│ ├── MFLogMediaType.h
│ ├── MFLogging.h
│ ├── MFMacro.h
│ ├── MFRegistry.h
│ ├── MFTExternTrace.h
│ └── MFTrace.h
├── CustomVideoMixer.sln
├── CustomVideoMixer
│ ├── CustomVideoMixer.cpp
│ ├── CustomVideoMixer.def
│ ├── CustomVideoMixer.h
│ ├── CustomVideoMixer.vcxproj
│ ├── CustomVideoMixer.vcxproj.filters
│ ├── CustomVideoMixer.vcxproj.user
│ ├── CustomVideoMixer_Attributes.cpp
│ ├── CustomVideoMixer_Bitmap.cpp
│ ├── CustomVideoMixer_Mixer.cpp
│ ├── CustomVideoMixer_Transform.cpp
│ ├── CustomVideoMixer_Type.cpp
│ ├── DllMain.cpp
│ ├── Dxva2Manager.cpp
│ ├── Dxva2Manager.h
│ ├── StdAfx.cpp
│ └── StdAfx.h
└── TestCustomVideoMixer
│ ├── Main.cpp
│ ├── TestCustomVideoMixer.vcxproj
│ ├── TestCustomVideoMixer.vcxproj.filters
│ └── TestCustomVideoMixer.vcxproj.user
├── EncodeWithSourceReaderSinkWriter
├── EncodeWithSourceReaderSinkWriter.sln
├── EncodeWithSourceReaderSinkWriter.vcxproj
├── EncodeWithSourceReaderSinkWriter.vcxproj.filters
├── EncodeWithSourceReaderSinkWriter.vcxproj.user
├── MFGuid.h
├── MFLogCommon.h
├── MFLogMediaType.h
├── MFLogging.h
├── MFMacro.h
├── MFTExternTrace.h
├── MFTime.h
├── MFTrace.h
├── Main.cpp
├── StdAfx.cpp
└── StdAfx.h
├── FrameRateConverterDSP
├── FrameRateConverterDSP.sln
├── FrameRateConverterDSP.vcxproj
└── Main.cpp
├── IMFSinkWriterCallback
├── IMFSinkWriterCallback.sln
├── IMFSinkWriterCallback.vcxproj
└── Main.cpp
├── LICENSE
├── MFMultiVideo
├── Common
│ ├── MFLogging.h
│ ├── MFMacro.h
│ ├── MFTExternTrace.h
│ └── MFTrace.h
├── MFMultiVideo.sln
├── MFMultiVideo.vcxproj
├── MFMultiVideo.vcxproj.filters
├── MFMultiVideo.vcxproj.user
├── Player.cpp
├── Player.h
├── StdAfx.cpp
├── StdAfx.h
└── WinMain.cpp
├── MFVideoCaptureEVR
├── MFVideoCaptureEVR.sln
├── MFVideoCaptureEVR.vcxproj
├── MFVideoCaptureEVR.vcxproj.filters
├── MFVideoCaptureEVR.vcxproj.user
└── Main.cpp
├── MFVideoEVR
├── MFVideoEVR.sln
├── MFVideoEVR.vcxproj
├── MFVideoEVR.vcxproj.user
└── Main.cpp
├── Media
├── CustomVideoMixer.jpg
├── IMFSinkWriterCallback.jpg
├── MFMultiVideo.jpg
└── ScreenCaptureEncode.jpg
├── MinimalSinkRenderer
├── Common
│ ├── MFClassFactory.h
│ ├── MFCriticSection.h
│ ├── MFGuid.h
│ ├── MFLogCommon.h
│ ├── MFLogMediaType.h
│ ├── MFLogging.h
│ ├── MFMacro.h
│ ├── MFRegistry.h
│ ├── MFState.h
│ ├── MFTExternTrace.h
│ ├── MFTime.h
│ └── MFTrace.h
├── MinimalSinkRenderer.sln
├── MinimalSinkRenderer
│ ├── DllMain.cpp
│ ├── MinimalSinkRenderer.vcxproj
│ ├── MinimalSinkRenderer.vcxproj.filters
│ ├── MinimalSinkRenderer.vcxproj.user
│ ├── MinimalSkinkRenderer.cpp
│ ├── MinimalSkinkRenderer.def
│ ├── MinimalSkinkRenderer.h
│ ├── MinimalSkinkRenderer_Clock.cpp
│ ├── MinimalSkinkRenderer_Sink.cpp
│ ├── StdAfx.cpp
│ ├── StdAfx.h
│ ├── StreamSkinkRenderer.cpp
│ ├── StreamSkinkRenderer.h
│ ├── StreamSkinkRenderer_Event.cpp
│ ├── StreamSkinkRenderer_Sink.cpp
│ └── StreamSkinkRenderer_Type.cpp
└── TestMinimalSinkRenderer
│ ├── Main.cpp
│ ├── TestMinimalSinkRenderer.vcxproj
│ ├── TestMinimalSinkRenderer.vcxproj.filters
│ └── TestMinimalSinkRenderer.vcxproj.user
├── README.md
├── ScreenCaptureEncode
├── Main.cpp
├── ScreenCaptureEncode.sln
└── ScreenCaptureEncode.vcxproj
├── TranscodeMp4ToMp4
├── Main.cpp
├── TranscodeMp4ToMp4.sln
└── TranscodeMp4ToMp4.vcxproj
├── VideoStabilizationMFT
├── MFGuid.h
├── MFLogCommon.h
├── MFLogMediaType.h
├── MFLogging.h
├── MFMacro.h
├── MFTExternTrace.h
├── MFTime.h
├── MFTrace.h
├── Main.cpp
├── StdAfx.cpp
├── StdAfx.h
├── VideoStabilizationMFT.sln
├── VideoStabilizationMFT.vcxproj
├── VideoStabilizationMFT.vcxproj.filters
└── VideoStabilizationMFT.vcxproj.user
└── WasapiCapture
├── MFLogging.h
├── MFMacro.h
├── MFTExternTrace.h
├── MFTrace.h
├── MFWaveWriter.cpp
├── MFWaveWriter.h
├── Main.cpp
├── StdAfx.cpp
├── StdAfx.h
├── WasapiCapture.sln
├── WasapiCapture.vcxproj
├── WasapiCapture.vcxproj.filters
└── WasapiCapture.vcxproj.user
/AudioSourceReaderSeek/AudioSourceReaderSeek.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioSourceReaderSeek", "AudioSourceReaderSeek.vcxproj", "{943C81EA-088B-4969-A03C-A990C9BD3E91}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Debug|x64.ActiveCfg = Debug|x64
17 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Debug|x64.Build.0 = Debug|x64
18 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Debug|x86.ActiveCfg = Debug|Win32
19 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Debug|x86.Build.0 = Debug|Win32
20 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Release|x64.ActiveCfg = Release|x64
21 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Release|x64.Build.0 = Release|x64
22 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Release|x86.ActiveCfg = Release|Win32
23 | {943C81EA-088B-4969-A03C-A990C9BD3E91}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {75EFBF0E-754D-4692-92FF-397497359B12}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/AudioSourceReaderSeek/AudioSourceReaderSeek.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers sources
20 |
21 |
22 |
--------------------------------------------------------------------------------
/AudioSourceReaderSeek/AudioSourceReaderSeek.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFClassFactory.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFClassFactory.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFCLASSFACTORY_H
5 | #define MFCLASSFACTORY_H
6 |
7 | typedef HRESULT (*CreateInstanceFn)(IUnknown*, REFIID, void**);
8 |
9 | struct ClassFactoryData{
10 |
11 | const GUID* pclsid;
12 | CreateInstanceFn pfnCreate;
13 | };
14 |
15 | class ClassFactory : public IClassFactory{
16 |
17 | private:
18 |
19 | volatile long m_refCount; // Reference count.
20 | static volatile long m_serverLocks; // Number of server locks
21 |
22 | CreateInstanceFn m_pfnCreation; // Function to create an instance of the object.
23 |
24 | public:
25 |
26 | ClassFactory(CreateInstanceFn pfnCreation) : m_pfnCreation(pfnCreation), m_refCount(1){}
27 |
28 | static bool IsLocked(){ return (m_serverLocks != 0); }
29 |
30 | STDMETHODIMP_(ULONG) AddRef(){ return InterlockedIncrement(&m_refCount); }
31 | STDMETHODIMP_(ULONG) Release(){
32 |
33 | assert(m_refCount >= 0);
34 | ULONG uCount = InterlockedDecrement(&m_refCount);
35 |
36 | if(uCount == 0){
37 | delete this;
38 | }
39 |
40 | return uCount;
41 | }
42 |
43 | STDMETHODIMP QueryInterface(REFIID riid, void** ppv){
44 |
45 | if(NULL == ppv){
46 | return E_POINTER;
47 | }
48 | else if(riid == __uuidof(IUnknown)){
49 | *ppv = static_cast(this);
50 | }
51 | else if(riid == __uuidof(IClassFactory)){
52 | *ppv = static_cast(this);
53 | }
54 | else{
55 | *ppv = NULL;
56 | return E_NOINTERFACE;
57 | }
58 |
59 | AddRef();
60 | return S_OK;
61 | }
62 |
63 | STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv){
64 |
65 | if(pUnkOuter != NULL){
66 |
67 | if(riid != __uuidof(IUnknown)){
68 | return E_NOINTERFACE;
69 | }
70 | }
71 |
72 | return m_pfnCreation(pUnkOuter, riid, ppv);
73 | }
74 |
75 | STDMETHODIMP LockServer(BOOL lock){
76 |
77 | if(lock){
78 | LockServer();
79 | }
80 | else{
81 | UnlockServer();
82 | }
83 | return S_OK;
84 | }
85 |
86 | static void LockServer(){ InterlockedIncrement(&m_serverLocks); }
87 | static void UnlockServer(){ InterlockedDecrement(&m_serverLocks); }
88 | };
89 |
90 | class BaseObject{
91 |
92 | public:
93 |
94 | BaseObject(){ ClassFactory::LockServer(); }
95 | virtual ~BaseObject(){ ClassFactory::UnlockServer(); }
96 | };
97 |
98 | #define DEFINE_CLASSFACTORY_SERVER_LOCK volatile long ClassFactory::m_serverLocks = 0;
99 |
100 | #endif
101 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFCriticSection.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFCriticSection.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFCRITICSECTION_H
5 | #define MFCRITICSECTION_H
6 |
7 | class CriticSection{
8 |
9 | private:
10 |
11 | CRITICAL_SECTION m_Section;
12 |
13 | public:
14 |
15 | CriticSection(){ InitializeCriticalSection(&m_Section); }
16 | ~CriticSection(){ DeleteCriticalSection(&m_Section); }
17 |
18 | void Lock(){ EnterCriticalSection(&m_Section); }
19 | void Unlock(){ LeaveCriticalSection(&m_Section); }
20 | };
21 |
22 | class AutoLock{
23 |
24 | private:
25 |
26 | CriticSection* m_pSection;
27 |
28 | public:
29 |
30 | AutoLock(CriticSection& critic){ m_pSection = &critic; m_pSection->Lock(); }
31 | ~AutoLock(){ m_pSection->Unlock(); }
32 | };
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFGuid.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFGuid.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFGUID_H
5 | #define MFGUID_H
6 |
7 | // {B2F74C92-79DF-45DE-9C55-A99DE8276679}
8 | DEFINE_GUID(CLSID_CustomVideoMixer, 0xb2f74c92, 0x79df, 0x45de, 0x9c, 0x55, 0xa9, 0x9d, 0xe8, 0x27, 0x66, 0x79);
9 |
10 | //----------------------------------------------------------------------------------------------
11 | // Media subType guid
12 |
13 | // {7634706D-0000-0010-8000-00AA00389B71}
14 | DEFINE_GUID(MEDIASUBTYPE_mp4v, 0x7634706d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
15 |
16 | // 56564D41-0000-0010-8000-00AA00389B71
17 | DEFINE_GUID(MEDIASUBTYPE_XVID, 0x44495658, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
18 |
19 | // {64697678-0000-0010-8000-00AA00389B71}
20 | DEFINE_GUID(MEDIASUBTYPE_xvid, 0x64697678, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
21 |
22 | // {58564944-0000-0010-8000-00AA00389B71}
23 | DEFINE_GUID(MEDIASUBTYPE_DIVX, 0x58564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
24 |
25 | // {78766964-0000-0010-8000-00AA00389B71}
26 | DEFINE_GUID(MEDIASUBTYPE_divx, 0x78766964, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
27 |
28 | // {30355844-0000-0010-8000-00aa00389b71}
29 | DEFINE_GUID(MEDIASUBTYPE_DX50, 0x30355844, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
30 |
31 | // {30357864-0000-0010-8000-00AA00389B71}
32 | DEFINE_GUID(MEDIASUBTYPE_dx50, 0x30357864, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
33 |
34 | // {1D4A45F2-E5F6-4B44-8388-F0AE5C0E0C37}
35 | DEFINE_GUID(MEDIASUBTYPE_VIDEOIMAGE, 0x1D4A45F2, 0xE5F6, 0x4B44, 0x83, 0x88, 0xF0, 0xAE, 0x5C, 0x0E, 0x0C, 0x37);
36 |
37 | // {00000031-0000-0010-8000-00AA00389B71}
38 | DEFINE_GUID(MEDIASUBTYPE_GSM, 0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
39 |
40 | // {00000011-0000-0010-8000-00AA00389B71}
41 | DEFINE_GUID(MEDIASUBTYPE_IMAADPCMACM, 0x00000011, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
42 |
43 | #endif
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFLogCommon.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogCommon.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGCOMMON_H
5 | #define MFLOGCOMMON_H
6 |
7 | #if (_DEBUG && MF_USE_LOGGING)
8 |
9 | typedef LPCWSTR(*GetGUIDStringName)(const GUID&);
10 |
11 | inline void LogGuidHexa(const GUID& guid, const BOOL bFirst){
12 |
13 | HRESULT hr;
14 | WCHAR pBuffer[39] = {0};
15 |
16 | hr = StringCchPrintf(pBuffer, 39, L"{%.8lX-%.4hX-%.4hX-%.2hhX%.2hhX-%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX}",
17 | guid.Data1,
18 | guid.Data2,
19 | guid.Data3,
20 | guid.Data4[0],
21 | guid.Data4[1],
22 | guid.Data4[2],
23 | guid.Data4[3],
24 | guid.Data4[4],
25 | guid.Data4[5],
26 | guid.Data4[6],
27 | guid.Data4[7]
28 | );
29 |
30 | if(SUCCEEDED(hr)){
31 |
32 | if(bFirst)
33 | TRACE_NO_END_LINE((L"\t%s\t", pBuffer));
34 | else
35 | TRACE((L"%s", pBuffer));
36 | }
37 | else{
38 |
39 | TRACE((L"Guid problem"));
40 | }
41 | }
42 |
43 | inline void LogUINT32AsUINT64(const PROPVARIANT& var){
44 |
45 | UINT32 uHigh = 0, uLow = 0;
46 |
47 | Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
48 |
49 | TRACE((L"%u x %u", uHigh, uLow));
50 | }
51 |
52 | inline HRESULT SpecialCaseAttributeValue(GUID guid, const PROPVARIANT& var){
53 |
54 | if(guid == MF_MT_FRAME_RATE){
55 | LogUINT32AsUINT64(var);
56 | }
57 | else if(guid == MF_MT_FRAME_SIZE){
58 | LogUINT32AsUINT64(var);
59 | }
60 | else if(guid == MF_MT_PIXEL_ASPECT_RATIO){
61 | LogUINT32AsUINT64(var);
62 | }
63 | else{
64 | return S_FALSE;
65 | }
66 |
67 | return S_OK;
68 | }
69 |
70 | inline void LogPropertyVariant(const GUID* pGuid, const PROPVARIANT& var, GetGUIDStringName pGetGUIDString){
71 |
72 | HRESULT hr = S_FALSE;
73 |
74 | if(pGuid != NULL)
75 | hr = SpecialCaseAttributeValue(*pGuid, var);
76 |
77 | if(hr == S_FALSE){
78 |
79 | switch(var.vt){
80 |
81 | case VT_UI4:
82 | TRACE((L"%lu", var.ulVal));
83 | break;
84 |
85 | case VT_I4:
86 | TRACE((L"%ld", var.lVal));
87 | break;
88 |
89 | case VT_UI8:
90 | TRACE((L"%I64u", var.uhVal));
91 | break;
92 |
93 | case VT_BOOL:
94 | TRACE((L"%s", var.boolVal == -1 ? "true" : "false"));
95 | break;
96 |
97 | case VT_R8:
98 | TRACE((L"%f", var.dblVal));
99 | break;
100 |
101 | case VT_CLSID:
102 | {
103 | LPCWSTR pwszGuidName = pGetGUIDString(*var.puuid);
104 |
105 | if(pwszGuidName != NULL){
106 | TRACE((L"%s", pwszGuidName));
107 | }
108 | else{
109 | LogGuidHexa(*var.puuid, FALSE);
110 | }
111 | }
112 | break;
113 |
114 | case VT_LPWSTR:
115 | // Log : var.pwszVal
116 | TRACE((L"VT_LPWSTR = todo"));
117 | break;
118 |
119 | case VT_VECTOR | VT_UI1:
120 | TRACE((L"(VT_VECTOR|VT_UI1) = <>"));
121 | break;
122 |
123 | case VT_UNKNOWN:
124 | TRACE((L"VT_UNKNOWN = IUnknown"));
125 | break;
126 |
127 | case VT_EMPTY:
128 | TRACE((L"VT_EMPTY"));
129 | break;
130 |
131 | case VT_R4:
132 | TRACE((L"VT_R4 = %f", var.fltVal));
133 | break;
134 |
135 | // 8195 = VT_ARRAY | VT_I4
136 |
137 | default:
138 | TRACE((L"Unexpected attribute type (vt = %hu)", var.vt));
139 | break;
140 | }
141 | }
142 | }
143 |
144 | inline void LogAttributeValueByIndex(IMFAttributes* pAttributes, UINT32 uiIndex, GetGUIDStringName pGetGUIDString){
145 |
146 | HRESULT hr;
147 | PROPVARIANT var;
148 | GUID guid = GUID_NULL;
149 |
150 | PropVariantInit(&var);
151 |
152 | hr = pAttributes->GetItemByIndex(uiIndex, &guid, &var);
153 |
154 | if(SUCCEEDED(hr)){
155 |
156 | LPCWSTR pwszGUIDNameAttributes = pGetGUIDString(guid);
157 |
158 | if(pwszGUIDNameAttributes != NULL){
159 | TRACE_NO_END_LINE((L"\t%s\t", pwszGUIDNameAttributes));
160 | }
161 | else{
162 |
163 | LogGuidHexa(guid, TRUE);
164 | }
165 |
166 | LogPropertyVariant(&guid, var, pGetGUIDString);
167 | }
168 | else{
169 | TRACE((L"\tGetItemByIndex (Index = %u) hr = %s", uiIndex, MFErrorString(hr)));
170 | }
171 |
172 | PropVariantClear(&var);
173 | }
174 |
175 | #endif
176 |
177 | #endif
178 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(155);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #ifdef MF_USE_LOGREFCOUNT
87 | #define TRACE_REFCOUNT(x) DebugLog::Trace x
88 | #else
89 | #define TRACE_REFCOUNT(x)
90 | #endif
91 |
92 | #ifdef MF_TRACE_TRANSFORM
93 | #define TRACE_TRANSFORM(x) DebugLog::Trace x
94 | #else
95 | #define TRACE_TRANSFORM(x)
96 | #endif
97 |
98 | #else
99 | #define TRACE_INIT()
100 | #define TRACE(x)
101 | #define TRACE_NO_END_LINE(x)
102 | #define TRACE_CLOSE()
103 | #define LOG_HRESULT(hr) hr
104 | #define LOG_LAST_ERROR()
105 | #define TRACE_REFCOUNT(x)
106 | #define TRACE_TRANSFORM(x)
107 | #endif
108 |
109 | #endif
110 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | // Need to use other macro. When error, multiple call.
41 | #ifndef IF_FAILED_RETURN
42 | #if(_DEBUG && MF_USE_LOGGING)
43 | #define IF_FAILED_RETURN(hr) if(FAILED(hr)){ LOG_HRESULT(hr); return hr; }
44 | #else
45 | #define IF_FAILED_RETURN(hr) if(FAILED(hr)){ return hr; }
46 | #endif
47 | #endif
48 |
49 | #ifndef IF_FAILED_THROW
50 | #if(_DEBUG && MF_USE_LOGGING)
51 | #define IF_FAILED_THROW(hr) if(FAILED(hr)){ LOG_HRESULT(hr); throw hr; }
52 | #else
53 | #define IF_FAILED_THROW(hr) if(FAILED(hr)){ throw hr; }
54 | #endif
55 | #endif
56 |
57 | #ifndef ARRAY_SIZE
58 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]) )
59 | #endif
60 |
61 | #ifndef RETURN_STRING
62 | #define RETURN_STRING(x) case x: return L#x
63 | #endif
64 |
65 | #ifndef IF_EQUAL_RETURN
66 | #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
67 | #endif
68 |
69 | #ifndef VALUE_NOT_FOUND
70 | #define VALUE_NOT_FOUND(val) return L#val
71 | #endif
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/CustomVideoMixer/Common/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomVideoMixer", "CustomVideoMixer\CustomVideoMixer.vcxproj", "{465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{97ADAD4A-E363-42CE-95D8-AFE2939F1DE5}"
9 | ProjectSection(SolutionItems) = preProject
10 | Common\MFClassFactory.h = Common\MFClassFactory.h
11 | Common\MFCriticSection.h = Common\MFCriticSection.h
12 | Common\MFGuid.h = Common\MFGuid.h
13 | Common\MFLogCommon.h = Common\MFLogCommon.h
14 | Common\MFLogging.h = Common\MFLogging.h
15 | Common\MFLogMediaType.h = Common\MFLogMediaType.h
16 | Common\MFMacro.h = Common\MFMacro.h
17 | Common\MFRegistry.h = Common\MFRegistry.h
18 | Common\MFTExternTrace.h = Common\MFTExternTrace.h
19 | Common\MFTrace.h = Common\MFTrace.h
20 | EndProjectSection
21 | EndProject
22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCustomVideoMixer", "TestCustomVideoMixer\TestCustomVideoMixer.vcxproj", "{DC45D0F4-780B-4B9E-A449-A9B27E176029}"
23 | EndProject
24 | Global
25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
26 | Debug|x64 = Debug|x64
27 | Debug|x86 = Debug|x86
28 | Release|x64 = Release|x64
29 | Release|x86 = Release|x86
30 | EndGlobalSection
31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
32 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Debug|x64.ActiveCfg = Debug|x64
33 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Debug|x64.Build.0 = Debug|x64
34 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Debug|x86.ActiveCfg = Debug|Win32
35 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Debug|x86.Build.0 = Debug|Win32
36 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Release|x64.ActiveCfg = Release|x64
37 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Release|x64.Build.0 = Release|x64
38 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Release|x86.ActiveCfg = Release|Win32
39 | {465730C8-22A8-4E4C-A3B6-B7D1F8F6D359}.Release|x86.Build.0 = Release|Win32
40 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Debug|x64.ActiveCfg = Debug|x64
41 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Debug|x64.Build.0 = Debug|x64
42 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Debug|x86.ActiveCfg = Debug|Win32
43 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Debug|x86.Build.0 = Debug|Win32
44 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Release|x64.ActiveCfg = Release|x64
45 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Release|x64.Build.0 = Release|x64
46 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Release|x86.ActiveCfg = Release|Win32
47 | {DC45D0F4-780B-4B9E-A449-A9B27E176029}.Release|x86.Build.0 = Release|Win32
48 | EndGlobalSection
49 | GlobalSection(SolutionProperties) = preSolution
50 | HideSolutionNode = FALSE
51 | EndGlobalSection
52 | GlobalSection(ExtensibilityGlobals) = postSolution
53 | SolutionGuid = {836B91E2-F32C-4E61-9DCD-53B3BF5BD9D8}
54 | EndGlobalSection
55 | EndGlobal
56 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 | DllCanUnloadNow PRIVATE
3 | DllRegisterServer PRIVATE
4 | DllUnregisterServer PRIVATE
5 | DllGetClassObject PRIVATE
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers sources
20 |
21 |
22 | Fichiers sources
23 |
24 |
25 | Fichiers sources
26 |
27 |
28 | Fichiers sources
29 |
30 |
31 | Fichiers sources
32 |
33 |
34 | Fichiers sources
35 |
36 |
37 | Fichiers sources
38 |
39 |
40 | Fichiers sources
41 |
42 |
43 | Fichiers sources
44 |
45 |
46 |
47 |
48 | Fichiers d%27en-tête
49 |
50 |
51 | Fichiers d%27en-tête
52 |
53 |
54 | Fichiers d%27en-tête
55 |
56 |
57 |
58 |
59 | Fichiers de ressources
60 |
61 |
62 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer_Bitmap.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // CustomVideoMixer_Bitmap.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CCustomVideoMixer::ClearAlphaBitmap() {
7 |
8 | TRACE_TRANSFORM((L"CustomVideoMixer::ClearAlphaBitmap"));
9 |
10 | return E_NOTIMPL;
11 | }
12 |
13 | HRESULT CCustomVideoMixer::GetAlphaBitmapParameters(MFVideoAlphaBitmapParams* /*pBmpParms*/) {
14 |
15 | TRACE_TRANSFORM((L"CustomVideoMixer::GetAlphaBitmapParameters"));
16 |
17 | return E_NOTIMPL;
18 | }
19 |
20 | HRESULT CCustomVideoMixer::SetAlphaBitmap(const MFVideoAlphaBitmap* /*pBmpParms*/) {
21 |
22 | TRACE_TRANSFORM((L"CustomVideoMixer::SetAlphaBitmap"));
23 |
24 | return E_NOTIMPL;
25 | }
26 |
27 | HRESULT CCustomVideoMixer::UpdateAlphaBitmapParameters(const MFVideoAlphaBitmapParams* /*pBmpParms*/) {
28 |
29 | TRACE_TRANSFORM((L"CustomVideoMixer::UpdateAlphaBitmapParameters"));
30 |
31 | return E_NOTIMPL;
32 | }
33 |
34 | HRESULT CCustomVideoMixer::MapOutputCoordinateToInputStream(float /*xOut*/, float /*yOut*/, DWORD /*dwOutputStreamIndex*/, DWORD /*dwInputStreamIndex*/, float* /*pxIn*/, float* /*pyIn*/) {
35 |
36 | TRACE_TRANSFORM((L"CustomVideoMixer::MapOutputCoordinateToInputStream"));
37 |
38 | return E_NOTIMPL;
39 | }
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer_Mixer.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // CustomVideoMixer_Transform.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CCustomVideoMixer::GetStreamOutputRect(DWORD, MFVideoNormalizedRect*) {
7 |
8 | TRACE_TRANSFORM((L"CustomVideoMixer::GetStreamOutputRect"));
9 |
10 | return S_OK;
11 | }
12 |
13 | HRESULT CCustomVideoMixer::GetStreamZOrder(DWORD, DWORD*) {
14 |
15 | TRACE_TRANSFORM((L"CustomVideoMixer::GetStreamZOrder"));
16 |
17 | return S_OK;
18 | }
19 |
20 | HRESULT CCustomVideoMixer::SetStreamOutputRect(DWORD, const MFVideoNormalizedRect*) {
21 |
22 | TRACE_TRANSFORM((L"CustomVideoMixer::SetStreamOutputRect"));
23 |
24 | return S_OK;
25 | }
26 |
27 | HRESULT CCustomVideoMixer::SetStreamZOrder(DWORD, DWORD) {
28 |
29 | TRACE_TRANSFORM((L"CustomVideoMixer::SetStreamZOrder"));
30 |
31 | return S_OK;
32 | }
33 |
34 | HRESULT CCustomVideoMixer::GetAvailableVideoProcessorModes(UINT*, GUID**) {
35 |
36 | TRACE_TRANSFORM((L"CustomVideoMixer::GetAvailableVideoProcessorModes"));
37 |
38 | return S_OK;
39 | }
40 |
41 | HRESULT CCustomVideoMixer::GetBackgroundColor(COLORREF*) {
42 |
43 | TRACE_TRANSFORM((L"CustomVideoMixer::GetBackgroundColor"));
44 |
45 | return S_OK;
46 | }
47 |
48 | HRESULT CCustomVideoMixer::GetFilteringRange(DWORD, DXVA2_ValueRange*) {
49 |
50 | TRACE_TRANSFORM((L"CustomVideoMixer::GetFilteringRange"));
51 |
52 | return S_OK;
53 | }
54 |
55 | HRESULT CCustomVideoMixer::GetFilteringValue(DWORD, DXVA2_Fixed32*) {
56 |
57 | TRACE_TRANSFORM((L"CustomVideoMixer::GetFilteringValue"));
58 |
59 | return S_OK;
60 | }
61 |
62 | HRESULT CCustomVideoMixer::GetProcAmpRange(DWORD, DXVA2_ValueRange*) {
63 |
64 | TRACE_TRANSFORM((L"CustomVideoMixer::GetProcAmpRange"));
65 |
66 | return S_OK;
67 | }
68 |
69 | HRESULT CCustomVideoMixer::GetProcAmpValues(DWORD, DXVA2_ProcAmpValues*) {
70 |
71 | TRACE_TRANSFORM((L"CustomVideoMixer::GetProcAmpValues"));
72 |
73 | return S_OK;
74 | }
75 |
76 | HRESULT CCustomVideoMixer::GetVideoProcessorCaps(LPGUID, DXVA2_VideoProcessorCaps*) {
77 |
78 | TRACE_TRANSFORM((L"CustomVideoMixer::GetVideoProcessorCaps"));
79 |
80 | return S_OK;
81 | }
82 |
83 | HRESULT CCustomVideoMixer::GetVideoProcessorMode(LPGUID) {
84 |
85 | TRACE_TRANSFORM((L"CustomVideoMixer::GetVideoProcessorMode"));
86 |
87 | return S_OK;
88 | }
89 |
90 | HRESULT CCustomVideoMixer::SetBackgroundColor(COLORREF) {
91 |
92 | TRACE_TRANSFORM((L"CustomVideoMixer::SetBackgroundColor"));
93 |
94 | return S_OK;
95 | }
96 |
97 | HRESULT CCustomVideoMixer::SetFilteringValue(DWORD, DXVA2_Fixed32*) {
98 |
99 | TRACE_TRANSFORM((L"CustomVideoMixer::SetFilteringValue"));
100 |
101 | return S_OK;
102 | }
103 |
104 | HRESULT CCustomVideoMixer::SetProcAmpValues(DWORD, DXVA2_ProcAmpValues*) {
105 |
106 | TRACE_TRANSFORM((L"CustomVideoMixer::SetProcAmpValues"));
107 |
108 | return S_OK;
109 | }
110 |
111 | HRESULT CCustomVideoMixer::SetVideoProcessorMode(LPGUID) {
112 |
113 | TRACE_TRANSFORM((L"CustomVideoMixer::SetVideoProcessorMode"));
114 |
115 | return S_OK;
116 | }
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/CustomVideoMixer_Type.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // CustomVideoMixer_Type.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CCustomVideoMixer::GetOutputType(IMFMediaType** ppType) {
7 |
8 | TRACE_TRANSFORM((L"CustomVideoMixer::GetOutputType"));
9 |
10 | HRESULT hr = S_OK;
11 | IMFMediaType* pOutputType = NULL;
12 |
13 | try {
14 |
15 | IF_FAILED_THROW(hr = MFCreateMediaType(&pOutputType));
16 |
17 | IF_FAILED_THROW(hr = pOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
18 | // MFVideoFormat_ARGB32 MFVideoFormat_RGB32
19 | IF_FAILED_THROW(hr = pOutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32));
20 | IF_FAILED_THROW(hr = pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE));
21 | IF_FAILED_THROW(hr = pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE));
22 | IF_FAILED_THROW(hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
23 | IF_FAILED_THROW(hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
24 |
25 | *ppType = pOutputType;
26 | (*ppType)->AddRef();
27 | }
28 | catch (HRESULT) {}
29 |
30 | SAFE_RELEASE(pOutputType);
31 | return hr;
32 | }
33 |
34 | HRESULT CCustomVideoMixer::OnCheckInputType(IMFMediaType** ppInptuType, IMFMediaType* pmt, const GUID gFormatSubType) {
35 |
36 | TRACE_TRANSFORM((L"CustomVideoMixer::OnCheckInputType"));
37 |
38 | HRESULT hr = S_OK;
39 |
40 | if (ppInptuType && *ppInptuType) {
41 |
42 | DWORD dwFlags = 0;
43 |
44 | if ((*ppInptuType)->IsEqual(pmt, &dwFlags) == S_OK) {
45 | return hr;
46 | }
47 | else {
48 | IF_FAILED_RETURN(hr = MF_E_INVALIDTYPE);
49 | // Todo
50 | //SAFE_RELEASE(pInptuType);
51 | //SAFE_RELEASE(m_pOutputType);
52 | //Flush();
53 | }
54 | }
55 |
56 | GUID majortype = { 0 };
57 | GUID subtype = { 0 };
58 | UINT32 width = 0;
59 | UINT32 height = 0;
60 |
61 | IF_FAILED_RETURN(hr = pmt->GetMajorType(&majortype));
62 | IF_FAILED_RETURN(hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype));
63 | IF_FAILED_RETURN(hr = MFGetAttributeSize(pmt, MF_MT_FRAME_SIZE, &width, &height));
64 |
65 | IF_FAILED_RETURN(hr = (majortype != MFMediaType_Video ? MF_E_INVALIDTYPE : S_OK));
66 | IF_FAILED_RETURN(hr = (subtype != gFormatSubType ? MF_E_INVALIDTYPE : S_OK));
67 |
68 | // Todo : check width = 0/height = 0
69 | IF_FAILED_RETURN(hr = ((width > MAX_VIDEO_WIDTH_HEIGHT || height > MAX_VIDEO_WIDTH_HEIGHT) ? MF_E_INVALIDTYPE : S_OK));
70 |
71 | return hr;
72 | }
73 |
74 | HRESULT CCustomVideoMixer::OnSetInputType(IMFMediaType** ppInptuType, IMFMediaType* pType) {
75 |
76 | TRACE_TRANSFORM((L"CustomVideoMixer::OnSetInputType"));
77 |
78 | HRESULT hr = S_OK;
79 | GUID subtype = { 0 };
80 |
81 | SAFE_RELEASE(*ppInptuType);
82 |
83 | IF_FAILED_RETURN(hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype));
84 |
85 | *ppInptuType = pType;
86 | (*ppInptuType)->AddRef();
87 |
88 | return hr;
89 | }
90 |
91 | HRESULT CCustomVideoMixer::OnCheckOutputType(IMFMediaType* pType) {
92 |
93 | TRACE_TRANSFORM((L"CustomVideoMixer::OnCheckOutputType"));
94 |
95 | LogMediaType(pType);
96 |
97 | HRESULT hr = S_OK;
98 |
99 | if (m_pOutputType) {
100 |
101 | DWORD dwFlags = 0;
102 |
103 | if (m_pOutputType->IsEqual(pType, &dwFlags) == S_OK) {
104 | return hr;
105 | }
106 | else {
107 | IF_FAILED_RETURN(hr = MF_E_INVALIDTYPE);
108 | // Todo
109 | //SAFE_RELEASE(m_pInputType);
110 | //Flush();
111 | }
112 | }
113 |
114 | // Todo : not here, but before call to OnCheckOutputType
115 | if (m_pRefInputType == NULL) {
116 | return MF_E_TRANSFORM_TYPE_NOT_SET;
117 | }
118 |
119 | IMFMediaType* pOurType = NULL;
120 | BOOL bMatch = FALSE;
121 |
122 | try {
123 |
124 | IF_FAILED_THROW(hr = GetOutputType(&pOurType));
125 |
126 | IF_FAILED_THROW(hr = pOurType->Compare(pType, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &bMatch));
127 |
128 | IF_FAILED_THROW(hr = (!bMatch ? MF_E_INVALIDTYPE : S_OK));
129 | }
130 | catch (HRESULT) {}
131 |
132 | SAFE_RELEASE(pOurType);
133 | return hr;
134 | }
135 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/DllMain.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // DllMain.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HMODULE g_hModule;
7 |
8 | DEFINE_CLASSFACTORY_SERVER_LOCK
9 |
10 | const WCHAR SZ_DECODER_NAME[] = L"Custom Video Mixer";
11 |
12 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/){
13 |
14 | switch(ul_reason_for_call){
15 |
16 | case DLL_PROCESS_ATTACH:
17 | DisableThreadLibraryCalls((HMODULE)hModule);
18 | g_hModule = (HMODULE)hModule;
19 | break;
20 |
21 | case DLL_PROCESS_DETACH:
22 | case DLL_THREAD_ATTACH:
23 | case DLL_THREAD_DETACH:
24 | break;
25 | }
26 |
27 | return TRUE;
28 | }
29 |
30 | STDAPI DllCanUnloadNow(){
31 |
32 | if(!ClassFactory::IsLocked()){
33 | return S_OK;
34 | }
35 | else{
36 | return S_FALSE;
37 | }
38 | }
39 |
40 | STDAPI DllRegisterServer(){
41 |
42 | HRESULT hr = S_OK;
43 |
44 | if(SUCCEEDED(hr = RegisterObject(g_hModule, CLSID_CustomVideoMixer, SZ_DECODER_NAME, TEXT("Both")))){
45 |
46 | MFT_REGISTER_TYPE_INFO InputTypesInfo[] = { { MFMediaType_Video, MFVideoFormat_NV12 }, { MFMediaType_Video, MFVideoFormat_AYUV } };
47 | MFT_REGISTER_TYPE_INFO OutputTypesInfo[] = { { MFMediaType_Video, MFVideoFormat_RGB32 } };
48 |
49 | hr = MFTRegister(CLSID_CustomVideoMixer, MFT_CATEGORY_VIDEO_DECODER, const_cast(SZ_DECODER_NAME), 0, ARRAY_SIZE(InputTypesInfo),
50 | InputTypesInfo, ARRAY_SIZE(OutputTypesInfo), OutputTypesInfo, NULL);
51 | }
52 |
53 | return hr;
54 | }
55 |
56 | STDAPI DllUnregisterServer(){
57 |
58 | UnregisterObject(CLSID_CustomVideoMixer);
59 | MFTUnregister(CLSID_CustomVideoMixer);
60 |
61 | return S_OK;
62 | }
63 |
64 | STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv){
65 |
66 | HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
67 |
68 | if(clsid == CLSID_CustomVideoMixer){
69 |
70 | ClassFactory* pFactory = NULL;
71 |
72 | pFactory = new (std::nothrow)ClassFactory(CCustomVideoMixer::CreateInstance);
73 |
74 | if(pFactory){
75 |
76 | hr = pFactory->QueryInterface(riid, ppv);
77 |
78 | SAFE_RELEASE(pFactory);
79 | }
80 | else{
81 |
82 | hr = E_OUTOFMEMORY;
83 | }
84 | }
85 |
86 | return hr;
87 | }
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/Dxva2Manager.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // Dxva2Manager.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef DXVA2MANAGER_H
5 | #define DXVA2MANAGER_H
6 |
7 | class CDxva2Manager {
8 |
9 | public:
10 |
11 | CDxva2Manager();
12 | ~CDxva2Manager() { ReleaseDxva2(); }
13 |
14 | HRESULT InitDxva2(IDirect3DDeviceManager9*, IMFMediaType*, IMFMediaType*, IMFMediaType*);
15 | void ReleaseDxva2();
16 | HRESULT ProcessInput(IMFSample*, const DWORD);
17 | HRESULT ProcessOutput(IMFSample*);
18 |
19 | private:
20 |
21 | IDirectXVideoProcessor* m_pVideoProcessor;
22 | IDirect3DSurface9* m_pRefSurface9;
23 | IDirect3DSurface9* m_pSubSurface9;
24 |
25 | LONGLONG m_llDuration;
26 | LONGLONG m_llTime;
27 |
28 | UINT32 m_uiRefWidth;
29 | UINT32 m_uiRefHeight;
30 | UINT32 m_uiRefLine;
31 | UINT32 m_uiSubWidth;
32 | UINT32 m_uiSubHeight;
33 | UINT32 m_uiSubLine;
34 |
35 | HRESULT GetDxva2VideoDesc(DXVA2_VideoDesc*, IMFMediaType*);
36 |
37 | void LogVideoProcessBltParams(DXVA2_VideoProcessBltParams&);
38 | void LogVideoSample(DXVA2_VideoSample&);
39 | };
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
--------------------------------------------------------------------------------
/CustomVideoMixer/CustomVideoMixer/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | #pragma comment(lib, "mf")
12 | #pragma comment(lib, "mfplat")
13 | #pragma comment(lib, "mfuuid")
14 | #pragma comment(lib, "shlwapi")
15 | #pragma comment(lib, "strmiids")
16 |
17 | //----------------------------------------------------------------------------------------------
18 | // Microsoft Windows SDK for Windows 7
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #ifdef _DEBUG
26 | #include
27 | #endif
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 | //----------------------------------------------------------------------------------------------
44 | // Common Project Files
45 | #ifdef _DEBUG
46 | #define MF_USE_LOGGING 1
47 | //#define MF_USE_LOGREFCOUNT
48 | //#define MF_TRACE_TRANSFORM
49 | #else
50 | #define MF_USE_LOGGING 0
51 | #endif
52 |
53 | #include "..\Common\MFMacro.h"
54 | #include "..\Common\MFTrace.h"
55 | #include "..\Common\MFLogging.h"
56 | #include "..\Common\MFTExternTrace.h"
57 | #include "..\Common\MFGuid.h"
58 | #include "..\Common\MFClassFactory.h"
59 | #include "..\Common\MFCriticSection.h"
60 | #include "..\Common\MFRegistry.h"
61 | #include "..\Common\MFLogCommon.h"
62 | #include "..\Common\MFLogMediaType.h"
63 |
64 | //----------------------------------------------------------------------------------------------
65 | // Project Files
66 | #include "Dxva2Manager.h"
67 | #include "CustomVideoMixer.h"
68 |
69 | #define MAX_VIDEO_WIDTH_HEIGHT 4095
70 |
71 | const DWORD D3DFMT_NV12 = MAKEFOURCC('N', 'V', '1', '2');
72 |
73 | #endif
--------------------------------------------------------------------------------
/CustomVideoMixer/TestCustomVideoMixer/TestCustomVideoMixer.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers sources
20 |
21 |
22 |
--------------------------------------------------------------------------------
/CustomVideoMixer/TestCustomVideoMixer/TestCustomVideoMixer.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/EncodeWithSourceReaderSinkWriter.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EncodeWithSourceReaderSinkWriter", "EncodeWithSourceReaderSinkWriter.vcxproj", "{20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Debug|x64.ActiveCfg = Debug|x64
17 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Debug|x64.Build.0 = Debug|x64
18 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Debug|x86.ActiveCfg = Debug|Win32
19 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Debug|x86.Build.0 = Debug|Win32
20 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Release|x64.ActiveCfg = Release|x64
21 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Release|x64.Build.0 = Release|x64
22 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Release|x86.ActiveCfg = Release|Win32
23 | {20CF3858-CBE6-4AFE-8FD0-934D8B1DCFF9}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {930C5FFD-60CD-4FC2-98AD-258D6B62DBF3}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/EncodeWithSourceReaderSinkWriter.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers d%27en-tête
20 |
21 |
22 | Fichiers d%27en-tête
23 |
24 |
25 | Fichiers d%27en-tête
26 |
27 |
28 | Fichiers d%27en-tête
29 |
30 |
31 | Fichiers d%27en-tête
32 |
33 |
34 | Fichiers d%27en-tête
35 |
36 |
37 | Fichiers d%27en-tête
38 |
39 |
40 | Fichiers d%27en-tête
41 |
42 |
43 | Fichiers d%27en-tête
44 |
45 |
46 |
47 |
48 | Fichiers sources
49 |
50 |
51 | Fichiers sources
52 |
53 |
54 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/EncodeWithSourceReaderSinkWriter.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFGuid.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFGuid.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFGUID_H
5 | #define MFGUID_H
6 |
7 | // {B2F74C92-79DF-45DE-9C55-A99DE8276679}
8 | DEFINE_GUID(CLSID_CustomVideoMixer, 0xb2f74c92, 0x79df, 0x45de, 0x9c, 0x55, 0xa9, 0x9d, 0xe8, 0x27, 0x66, 0x79);
9 |
10 | //----------------------------------------------------------------------------------------------
11 | // Media subType guid
12 |
13 | // {7634706D-0000-0010-8000-00AA00389B71}
14 | DEFINE_GUID(MEDIASUBTYPE_mp4v, 0x7634706d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
15 |
16 | // 56564D41-0000-0010-8000-00AA00389B71
17 | DEFINE_GUID(MEDIASUBTYPE_XVID, 0x44495658, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
18 |
19 | // {64697678-0000-0010-8000-00AA00389B71}
20 | DEFINE_GUID(MEDIASUBTYPE_xvid, 0x64697678, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
21 |
22 | // {58564944-0000-0010-8000-00AA00389B71}
23 | DEFINE_GUID(MEDIASUBTYPE_DIVX, 0x58564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
24 |
25 | // {78766964-0000-0010-8000-00AA00389B71}
26 | DEFINE_GUID(MEDIASUBTYPE_divx, 0x78766964, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
27 |
28 | // {30355844-0000-0010-8000-00aa00389b71}
29 | DEFINE_GUID(MEDIASUBTYPE_DX50, 0x30355844, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
30 |
31 | // {30357864-0000-0010-8000-00AA00389B71}
32 | DEFINE_GUID(MEDIASUBTYPE_dx50, 0x30357864, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
33 |
34 | // {1D4A45F2-E5F6-4B44-8388-F0AE5C0E0C37}
35 | DEFINE_GUID(MEDIASUBTYPE_VIDEOIMAGE, 0x1D4A45F2, 0xE5F6, 0x4B44, 0x83, 0x88, 0xF0, 0xAE, 0x5C, 0x0E, 0x0C, 0x37);
36 |
37 | // {00000031-0000-0010-8000-00AA00389B71}
38 | DEFINE_GUID(MEDIASUBTYPE_GSM, 0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
39 |
40 | // {00000011-0000-0010-8000-00AA00389B71}
41 | DEFINE_GUID(MEDIASUBTYPE_IMAADPCMACM, 0x00000011, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
42 |
43 | #endif
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFLogCommon.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogCommon.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGCOMMON_H
5 | #define MFLOGCOMMON_H
6 |
7 | #if (_DEBUG && MF_USE_LOGGING)
8 |
9 | typedef LPCWSTR(*GetGUIDStringName)(const GUID&);
10 |
11 | inline void LogGuidHexa(const GUID& guid, const BOOL bFirst){
12 |
13 | HRESULT hr;
14 | WCHAR pBuffer[39] = {0};
15 |
16 | hr = StringCchPrintf(pBuffer, 39, L"{%.8lX-%.4hX-%.4hX-%.2hhX%.2hhX-%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX}",
17 | guid.Data1,
18 | guid.Data2,
19 | guid.Data3,
20 | guid.Data4[0],
21 | guid.Data4[1],
22 | guid.Data4[2],
23 | guid.Data4[3],
24 | guid.Data4[4],
25 | guid.Data4[5],
26 | guid.Data4[6],
27 | guid.Data4[7]
28 | );
29 |
30 | if(SUCCEEDED(hr)){
31 |
32 | if(bFirst)
33 | TRACE_NO_END_LINE((L"\t%s\t", pBuffer));
34 | else
35 | TRACE((L"%s", pBuffer));
36 | }
37 | else{
38 |
39 | TRACE((L"Guid problem"));
40 | }
41 | }
42 |
43 | inline void LogUINT32AsUINT64(const PROPVARIANT& var){
44 |
45 | UINT32 uHigh = 0, uLow = 0;
46 |
47 | Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
48 |
49 | TRACE((L"%u x %u", uHigh, uLow));
50 | }
51 |
52 | inline HRESULT SpecialCaseAttributeValue(GUID guid, const PROPVARIANT& var){
53 |
54 | if(guid == MF_MT_FRAME_RATE){
55 | LogUINT32AsUINT64(var);
56 | }
57 | else if(guid == MF_MT_FRAME_SIZE){
58 | LogUINT32AsUINT64(var);
59 | }
60 | else if(guid == MF_MT_PIXEL_ASPECT_RATIO){
61 | LogUINT32AsUINT64(var);
62 | }
63 | else{
64 | return S_FALSE;
65 | }
66 |
67 | return S_OK;
68 | }
69 |
70 | inline void LogPropertyVariant(const GUID* pGuid, const PROPVARIANT& var, GetGUIDStringName pGetGUIDString){
71 |
72 | HRESULT hr = S_FALSE;
73 |
74 | if(pGuid != NULL)
75 | hr = SpecialCaseAttributeValue(*pGuid, var);
76 |
77 | if(hr == S_FALSE){
78 |
79 | switch(var.vt){
80 |
81 | case VT_UI4:
82 | TRACE((L"%lu", var.ulVal));
83 | break;
84 |
85 | case VT_I4:
86 | TRACE((L"%ld", var.lVal));
87 | break;
88 |
89 | case VT_UI8:
90 | TRACE((L"%I64u", var.uhVal));
91 | break;
92 |
93 | case VT_BOOL:
94 | TRACE((L"%s", var.boolVal == -1 ? "true" : "false"));
95 | break;
96 |
97 | case VT_R8:
98 | TRACE((L"%f", var.dblVal));
99 | break;
100 |
101 | case VT_CLSID:
102 | {
103 | LPCWSTR pwszGuidName = pGetGUIDString(*var.puuid);
104 |
105 | if(pwszGuidName != NULL){
106 | TRACE((L"%s", pwszGuidName));
107 | }
108 | else{
109 | LogGuidHexa(*var.puuid, FALSE);
110 | }
111 | }
112 | break;
113 |
114 | case VT_LPWSTR:
115 | // Log : var.pwszVal
116 | TRACE((L"VT_LPWSTR = todo"));
117 | break;
118 |
119 | case VT_VECTOR | VT_UI1:
120 | TRACE((L"(VT_VECTOR|VT_UI1) = <>"));
121 | break;
122 |
123 | case VT_UNKNOWN:
124 | TRACE((L"VT_UNKNOWN = IUnknown"));
125 | break;
126 |
127 | case VT_EMPTY:
128 | TRACE((L"VT_EMPTY"));
129 | break;
130 |
131 | case VT_R4:
132 | TRACE((L"VT_R4 = %f", var.fltVal));
133 | break;
134 |
135 | // 8195 = VT_ARRAY | VT_I4
136 |
137 | default:
138 | TRACE((L"Unexpected attribute type (vt = %hu)", var.vt));
139 | break;
140 | }
141 | }
142 | }
143 |
144 | inline void LogAttributeValueByIndex(IMFAttributes* pAttributes, UINT32 uiIndex, GetGUIDStringName pGetGUIDString){
145 |
146 | HRESULT hr;
147 | PROPVARIANT var;
148 | GUID guid = GUID_NULL;
149 |
150 | PropVariantInit(&var);
151 |
152 | hr = pAttributes->GetItemByIndex(uiIndex, &guid, &var);
153 |
154 | if(SUCCEEDED(hr)){
155 |
156 | LPCWSTR pwszGUIDNameAttributes = pGetGUIDString(guid);
157 |
158 | if(pwszGUIDNameAttributes != NULL){
159 | TRACE_NO_END_LINE((L"\t%s\t", pwszGUIDNameAttributes));
160 | }
161 | else{
162 |
163 | LogGuidHexa(guid, TRUE);
164 | }
165 |
166 | LogPropertyVariant(&guid, var, pGetGUIDString);
167 | }
168 | else{
169 | TRACE((L"\tGetItemByIndex (Index = %u) hr = %s", uiIndex, MFErrorString(hr)));
170 | }
171 |
172 | PropVariantClear(&var);
173 | }
174 |
175 | #endif
176 |
177 | #endif
178 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(171);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #else
87 | #define TRACE_INIT()
88 | #define TRACE(x)
89 | #define TRACE_NO_END_LINE(x)
90 | #define TRACE_CLOSE()
91 | #define LOG_HRESULT(hr) hr
92 | #define LOG_LAST_ERROR()
93 | #endif
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | #ifndef IF_FAILED_RETURN
41 | #if(_DEBUG && MF_USE_LOGGING)
42 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); return hr; }
43 | #else
44 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ return hr; }
45 | #endif
46 | #endif
47 |
48 | #ifndef IF_FAILED_THROW
49 | #if(_DEBUG && MF_USE_LOGGING)
50 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); throw hr; }
51 | #else
52 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ throw hr; }
53 | #endif
54 | #endif
55 |
56 | #ifndef IF_ERROR_RETURN
57 | #if (_DEBUG && MF_USE_LOGGING)
58 | #define IF_ERROR_RETURN(b) if(b == FALSE){ LOG_LAST_ERROR(); return b; }
59 | #else
60 | #define IF_ERROR_RETURN(b) if(b == FALSE){ return b; }
61 | #endif
62 | #endif
63 |
64 | #ifndef CLOSE_HANDLE_IF
65 | #if (_DEBUG && MF_USE_LOGGING)
66 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ if(CloseHandle(h) == FALSE){ LOG_LAST_ERROR(); } h = INVALID_HANDLE_VALUE; }
67 | #else
68 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ CloseHandle(h); h = INVALID_HANDLE_VALUE; }
69 | #endif
70 | #endif
71 |
72 | #ifndef RETURN_STRING
73 | #define RETURN_STRING(x) case x: return L#x
74 | #endif
75 |
76 | #ifndef IF_EQUAL_RETURN
77 | #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
78 | #endif
79 |
80 | #ifndef VALUE_NOT_FOUND
81 | #define VALUE_NOT_FOUND(val) return L#val
82 | #endif
83 |
84 | #ifndef MIN
85 | #define MIN(a, b) (((a) < (b)) ? (a) : (b))
86 | #endif
87 |
88 | #endif
89 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/MFTime.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTime.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTIME_H
5 | #define MFTIME_H
6 |
7 | // One second in hns
8 | const MFTIME ONE_SECOND = 10000000;
9 |
10 | // One msec in hns
11 | const LONG ONE_MSEC = 1000;
12 |
13 | inline LONG MFTimeToMilliSec(const LONGLONG& time){
14 |
15 | return (LONG)(time / (ONE_SECOND / ONE_MSEC));
16 | }
17 |
18 | inline LONG MFTimeToSec(const LONGLONG& time){
19 |
20 | return (LONG)(time / ONE_SECOND);
21 | }
22 |
23 | #if (_DEBUG && MF_USE_LOGGING)
24 |
25 | inline void MFTimeString(const MFTIME& Duration){
26 |
27 | MFTIME DurationInMilliSec = 0;
28 | MFTIME DurationInSec = 0;
29 | MFTIME Hours = 0;
30 | MFTIME Minutes = 0;
31 | MFTIME Seconds = 0;
32 |
33 | DurationInSec = MFTimeToSec(Duration);
34 | DurationInMilliSec = MFTimeToMilliSec(Duration);
35 |
36 | if(DurationInSec > 60){
37 |
38 | Minutes = DurationInSec / 60;
39 |
40 | if(Minutes > 60){
41 |
42 | Hours = Minutes / 60;
43 | Minutes = Minutes % 60;
44 | }
45 |
46 | Seconds = (DurationInSec % 60);
47 | }
48 | else{
49 |
50 | Seconds = DurationInSec;
51 | }
52 |
53 | if(Seconds){
54 | DurationInMilliSec = DurationInMilliSec % (Seconds * ONE_MSEC);
55 | }
56 |
57 | TRACE((L"%02dh:%02dmn:%02ds:%03dms", (int)Hours, (int)Minutes, (int)Seconds, DurationInMilliSec));
58 | }
59 |
60 | #else
61 | #define MFTimeString(x)
62 | #endif
63 |
64 | #endif
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
--------------------------------------------------------------------------------
/EncodeWithSourceReaderSinkWriter/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | #pragma comment(lib, "mf")
12 | #pragma comment(lib, "mfplat")
13 | #pragma comment(lib, "mfuuid")
14 | #pragma comment(lib, "mfreadwrite")
15 | #pragma comment(lib, "strmiids")
16 |
17 | //----------------------------------------------------------------------------------------------
18 | // Microsoft Windows SDK for Windows 7
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #ifdef _DEBUG
26 | #include
27 | #endif
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 |
44 | //----------------------------------------------------------------------------------------------
45 | // Common Project Files
46 | #ifdef _DEBUG
47 | #define MF_USE_LOGGING 1
48 | #else
49 | #define MF_USE_LOGGING 0
50 | #endif
51 |
52 | #include "MFMacro.h"
53 | #include "MFTrace.h"
54 | #include "MFLogging.h"
55 | #include "MFTExternTrace.h"
56 | #include "MFGuid.h"
57 | #include "MFLogCommon.h"
58 | #include "MFLogMediaType.h"
59 | #include "MFTime.h"
60 |
61 | #endif
--------------------------------------------------------------------------------
/FrameRateConverterDSP/FrameRateConverterDSP.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FrameRateConverterDSP", "FrameRateConverterDSP.vcxproj", "{832CA548-40B4-45C7-BFF5-B68F6C85ED82}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Debug|x64.ActiveCfg = Debug|x64
17 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Debug|x64.Build.0 = Debug|x64
18 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Debug|x86.ActiveCfg = Debug|Win32
19 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Debug|x86.Build.0 = Debug|Win32
20 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Release|x64.ActiveCfg = Release|x64
21 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Release|x64.Build.0 = Release|x64
22 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Release|x86.ActiveCfg = Release|Win32
23 | {832CA548-40B4-45C7-BFF5-B68F6C85ED82}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {C35FB983-8745-44D3-BE78-579D379694C1}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/IMFSinkWriterCallback/IMFSinkWriterCallback.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IMFSinkWriterCallback", "IMFSinkWriterCallback.vcxproj", "{4F362AC8-B517-4382-A943-33CEC77CBC95}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {4F362AC8-B517-4382-A943-33CEC77CBC95}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {4F362AC8-B517-4382-A943-33CEC77CBC95}.Debug|Win32.Build.0 = Debug|Win32
16 | {4F362AC8-B517-4382-A943-33CEC77CBC95}.Release|Win32.ActiveCfg = Release|Win32
17 | {4F362AC8-B517-4382-A943-33CEC77CBC95}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/IMFSinkWriterCallback/IMFSinkWriterCallback.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {4F362AC8-B517-4382-A943-33CEC77CBC95}
15 | Win32Proj
16 | IMFSinkWriterCallback
17 | 10.0.15063.0
18 |
19 |
20 |
21 | Application
22 | true
23 | v141
24 | Unicode
25 |
26 |
27 | Application
28 | false
29 | v141
30 | true
31 | Unicode
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | true
45 |
46 |
47 | false
48 |
49 |
50 |
51 |
52 |
53 | Level4
54 | Disabled
55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
56 | ProgramDatabase
57 |
58 |
59 | Console
60 | true
61 |
62 |
63 |
64 |
65 | Level3
66 |
67 |
68 | MaxSpeed
69 | true
70 | true
71 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
72 |
73 |
74 | Console
75 | false
76 | true
77 | true
78 | UseLinkTimeCodeGeneration
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/MFMultiVideo/Common/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(223);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #ifdef MF_USE_LOGREFCOUNT
87 | #define TRACE_REFCOUNT(x) DebugLog::Trace x
88 | #else
89 | #define TRACE_REFCOUNT(x)
90 | #endif
91 |
92 | #ifdef MF_TRACE_PLAYER
93 | #define TRACE_PLAYER(x) DebugLog::Trace x
94 | #else
95 | #define TRACE_PLAYER(x)
96 | #endif
97 |
98 | #else
99 | #define TRACE_INIT()
100 | #define TRACE(x)
101 | #define TRACE_NO_END_LINE(x)
102 | #define TRACE_CLOSE()
103 | #define LOG_HRESULT(hr) hr
104 | #define LOG_LAST_ERROR()
105 | #define TRACE_REFCOUNT(x)
106 | #define TRACE_PLAYER(x)
107 | #endif
108 |
109 | #endif
110 |
--------------------------------------------------------------------------------
/MFMultiVideo/Common/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | #ifndef IF_FAILED_RETURN
41 | #if(_DEBUG && MF_USE_LOGGING)
42 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); return hr; }
43 | #else
44 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ return hr; }
45 | #endif
46 | #endif
47 |
48 | #ifndef IF_FAILED_THROW
49 | #if(_DEBUG && MF_USE_LOGGING)
50 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); throw hr; }
51 | #else
52 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ throw hr; }
53 | #endif
54 | #endif
55 |
56 | #ifndef IF_ERROR_RETURN
57 | #if (_DEBUG && MF_USE_LOGGING)
58 | #define IF_ERROR_RETURN(b) if(b == FALSE){ LOG_LAST_ERROR(); return b; }
59 | #else
60 | #define IF_ERROR_RETURN(b) if(b == FALSE){ return b; }
61 | #endif
62 | #endif
63 |
64 | #ifndef CLOSE_HANDLE_IF
65 | #if (_DEBUG && MF_USE_LOGGING)
66 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ if(CloseHandle(h) == FALSE){ LOG_LAST_ERROR(); } h = INVALID_HANDLE_VALUE; }
67 | #else
68 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ CloseHandle(h); h = INVALID_HANDLE_VALUE; }
69 | #endif
70 | #endif
71 |
72 | #ifndef CLOSE_HANDLE_NULL_IF
73 | #if (_DEBUG && MF_USE_LOGGING)
74 | #define CLOSE_HANDLE_NULL_IF(h) if(h != NULL){ if(CloseHandle(h) == FALSE){ LOG_LAST_ERROR(); } h = NULL; }
75 | #else
76 | #define CLOSE_HANDLE_NULL_IF(h) if(h != NULL){ CloseHandle(h); h = NULL; }
77 | #endif
78 | #endif
79 |
80 | #ifndef RETURN_STRING
81 | #define RETURN_STRING(x) case x: return L#x
82 | #endif
83 |
84 | #ifndef IF_EQUAL_RETURN
85 | #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
86 | #endif
87 |
88 | #ifndef VALUE_NOT_FOUND
89 | #define VALUE_NOT_FOUND(val) return L#val
90 | #endif
91 |
92 | #ifndef MIN
93 | #define MIN(a, b) (((a) < (b)) ? (a) : (b))
94 | #endif
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/MFMultiVideo/Common/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/MFMultiVideo/MFMultiVideo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MFMultiVideo", "MFMultiVideo.vcxproj", "{8817B8D0-718A-4E5E-A216-AC08A9A8F679}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Debug|x64.ActiveCfg = Debug|x64
17 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Debug|x64.Build.0 = Debug|x64
18 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Debug|x86.ActiveCfg = Debug|Win32
19 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Debug|x86.Build.0 = Debug|Win32
20 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Release|x64.ActiveCfg = Release|x64
21 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Release|x64.Build.0 = Release|x64
22 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Release|x86.ActiveCfg = Release|Win32
23 | {8817B8D0-718A-4E5E-A216-AC08A9A8F679}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {367D630C-FC0C-4155-9CBF-89DA4CC9DE76}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/MFMultiVideo/MFMultiVideo.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {39dccb02-dd0a-4587-9597-98feb56c17a9}
18 |
19 |
20 |
21 |
22 | Fichiers sources
23 |
24 |
25 | Fichiers sources
26 |
27 |
28 | Fichiers sources
29 |
30 |
31 |
32 |
33 | Fichiers d%27en-tête
34 |
35 |
36 | Fichiers d%27en-tête
37 |
38 |
39 | Common
40 |
41 |
42 | Common
43 |
44 |
45 | Common
46 |
47 |
48 | Common
49 |
50 |
51 |
--------------------------------------------------------------------------------
/MFMultiVideo/MFMultiVideo.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/MFMultiVideo/Player.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // Player.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef PLAYER_H
5 | #define PLAYER_H
6 |
7 | enum PlayerState
8 | {
9 | Closed = 0, // No session.
10 | Ready, // Session was created, ready to open a file.
11 | OpenPending, // Session is opening a file.
12 | Started, // Session is playing a file.
13 | Paused, // Session is paused.
14 | Stopped, // Session is stopped (ready to play).
15 | Closing // Application has closed the session, but is waiting for MESessionClosed.
16 | };
17 |
18 | class CPlayer : public IMFAsyncCallback{
19 |
20 | public:
21 |
22 | static HRESULT CreateInstance(const HWND, const int, CPlayer**);
23 |
24 | // IUnknown - Player.cpp
25 | STDMETHODIMP QueryInterface(REFIID, void**);
26 | STDMETHODIMP_(ULONG) AddRef();
27 | STDMETHODIMP_(ULONG) Release();
28 |
29 | // IMFAsyncCallback - Player.cpp
30 | STDMETHODIMP GetParameters(DWORD*, DWORD*);
31 | STDMETHODIMP Invoke(IMFAsyncResult*);
32 |
33 | HRESULT OpenUrl(LPCWSTR);
34 | HRESULT Shutdown();
35 |
36 | private:
37 |
38 | CPlayer(HRESULT&, const HWND, const int);
39 | virtual ~CPlayer();
40 |
41 | volatile long m_lRefCount;
42 | HWND m_hwndVideo = NULL;
43 | int m_iIndex = 0;
44 | PlayerState m_state = Closed;
45 | std::mutex m_mtx;
46 | std::condition_variable m_cv_open;
47 | std::condition_variable m_cv_close;
48 | CComPtr m_pSource = NULL;
49 | CComPtr m_pDecoder = NULL;
50 | IMFMediaSession* m_pSession = NULL;
51 | DWORD m_dwQueue = MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
52 |
53 | HRESULT HandleEvent(IMFMediaEvent*);
54 | HRESULT OnTopologyStatus(IMFMediaEvent*);
55 | HRESULT OnPresentationEnded(IMFMediaEvent*);
56 | HRESULT StartPlayback();
57 | HRESULT CreateSession();
58 | HRESULT CreateMediaSource(LPCWSTR, IMFMediaSource**);
59 | HRESULT CreatePlaybackTopology(IMFMediaSource*, IMFPresentationDescriptor*, const HWND, IMFTopology**, IMFTransform**);
60 | HRESULT AddBranchToPartialTopology(IMFTopology*, IMFMediaSource*, IMFPresentationDescriptor*, const DWORD, const HWND, IMFTransform**, const bool withOverlay = false);
61 | HRESULT AddOutputNode(IMFTopology*, IMFActivate*, const DWORD, IMFTopologyNode**);
62 | HRESULT AddSourceNode(IMFTopology*, IMFMediaSource*, IMFPresentationDescriptor*, IMFStreamDescriptor*, IMFTopologyNode**);
63 | HRESULT CreateVideoDecoderTopology(IMFTopology*, IMFTopologyNode*, IMFTopologyNode*, IMFTransform**);
64 | HRESULT AddTransformNode(IMFTopology*, const CLSID&, IMFTopologyNode**, IMFTransform**);
65 | };
66 |
67 | #endif
--------------------------------------------------------------------------------
/MFMultiVideo/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
--------------------------------------------------------------------------------
/MFMultiVideo/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | //----------------------------------------------------------------------------------------------
12 | // Pragma
13 | #pragma comment(lib, "mfplat")
14 | #pragma comment(lib, "shlwapi")
15 | #pragma comment(lib, "dxva2")
16 | #pragma comment(lib, "d3d9")
17 | #pragma comment(lib, "Mf")
18 | #pragma comment(lib, "strmiids")
19 | #pragma comment(lib, "mfuuid")
20 |
21 | //----------------------------------------------------------------------------------------------
22 | // Microsoft Windows SDK for Windows 7
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #ifdef _DEBUG
30 | #include
31 | #endif
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 |
51 | //----------------------------------------------------------------------------------------------
52 | // Common Project Files
53 | #ifdef _DEBUG
54 | #define MF_USE_LOGGING 1
55 | //#define MF_USE_LOGREFCOUNT
56 | //#define TRACE_PLAYER
57 | #else
58 | #define MF_USE_LOGGING 0
59 | #endif
60 |
61 | #include ".\Common\MFMacro.h"
62 | #include ".\Common\MFTrace.h"
63 | #include ".\Common\MFLogging.h"
64 | #include ".\Common\MFTExternTrace.h"
65 |
66 | //----------------------------------------------------------------------------------------------
67 | // Project Files
68 | #include "Player.h"
69 |
70 | #endif
--------------------------------------------------------------------------------
/MFMultiVideo/WinMain.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | #define WINDOWSFORM_CLASS L"MFMultiVideo"
7 | #define PLAYER_COUNT 16
8 | #define PLAYER_PER_LINE 4
9 | #define MAX_PLAYER_PLAY 4
10 | #define VIDEO_INPUT_FILE L"big_buck_bunny_240p_5mb.mp4"
11 | #define VIDEO_INPUT_TIME 60000
12 |
13 | HWND g_hWnd = NULL;
14 | HWND g_hWndPlayers[PLAYER_COUNT] = {0};
15 | CPlayer* g_pPlayer[PLAYER_COUNT] = {0};
16 |
17 | BOOL InitInstance(HINSTANCE, int);
18 | void AutoStartPlayback();
19 | LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
20 |
21 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
22 | {
23 | if(!InitInstance(hInstance, nCmdShow))
24 | {
25 | return -1;
26 | }
27 |
28 | MSG msg;
29 | ZeroMemory(&msg, sizeof(msg));
30 |
31 | while(GetMessage(&msg, NULL, 0, 0) > 0)
32 | {
33 | TranslateMessage(&msg);
34 | DispatchMessage(&msg);
35 | }
36 |
37 | if(IsWindow(g_hWnd)){
38 | DestroyWindow(g_hWnd);
39 | }
40 |
41 | UnregisterClass(WINDOWSFORM_CLASS, hInstance);
42 |
43 | MFShutdown();
44 | CoUninitialize();
45 |
46 | return 0;
47 | }
48 |
49 | BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
50 | {
51 | WNDCLASSEX wcex;
52 |
53 | ZeroMemory(&wcex, sizeof(WNDCLASSEX));
54 | wcex.cbSize = sizeof(WNDCLASSEX);
55 | wcex.style = CS_HREDRAW | CS_VREDRAW;
56 | wcex.lpfnWndProc = WndProc;
57 | wcex.hInstance = hInst;
58 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
59 | wcex.lpszClassName = WINDOWSFORM_CLASS;
60 |
61 | if(RegisterClassEx(&wcex) == 0)
62 | {
63 | return FALSE;
64 | }
65 |
66 | // Create the application window.
67 | g_hWnd = CreateWindow(WINDOWSFORM_CLASS, WINDOWSFORM_CLASS, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
68 |
69 | if(g_hWnd == 0)
70 | {
71 | return FALSE;
72 | }
73 |
74 | ShowWindow(g_hWnd, nCmdShow);
75 | UpdateWindow(g_hWnd);
76 |
77 | CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
78 | MFStartup(MF_VERSION, MFSTARTUP_LITE);
79 |
80 | for(int i = 0; i < PLAYER_COUNT; i++)
81 | {
82 | g_hWndPlayers[i] = CreateWindowEx(0, WINDOWSFORM_CLASS, L"Player Window", WS_VISIBLE | WS_CHILD, (i % PLAYER_PER_LINE) * 164, int((i / PLAYER_PER_LINE)) * 117, 164, 117, g_hWnd, (HMENU)1, hInst, NULL);
83 |
84 | assert(g_hWndPlayers[i] != NULL);
85 |
86 | HRESULT hr = CPlayer::CreateInstance(g_hWndPlayers[i], i, &g_pPlayer[i]);
87 |
88 | assert(hr == S_OK && g_pPlayer[i] != NULL);
89 | }
90 |
91 | std::thread t(AutoStartPlayback);
92 | t.detach();
93 |
94 | return TRUE;
95 | }
96 |
97 | void AutoStartPlayback()
98 | {
99 | int iCount = 0;
100 |
101 | do
102 | {
103 | for(int i = 0; i < PLAYER_COUNT; i++)
104 | {
105 | LOG_HRESULT(g_pPlayer[i]->OpenUrl(VIDEO_INPUT_FILE));
106 | }
107 |
108 | Sleep(VIDEO_INPUT_TIME);
109 |
110 | for(int i = 0; i < PLAYER_COUNT; i++)
111 | {
112 | LOG_HRESULT(g_pPlayer[i]->Shutdown());
113 | }
114 |
115 | iCount++;
116 | }
117 | while(iCount < MAX_PLAYER_PLAY);
118 |
119 | for(int i = 0; i < PLAYER_COUNT; i++)
120 | {
121 | LOG_HRESULT(g_pPlayer[i]->Shutdown());
122 | SAFE_RELEASE(g_pPlayer[i]);
123 | }
124 |
125 | for(int i = 0; i < PLAYER_COUNT; i++)
126 | {
127 | DestroyWindow(g_hWndPlayers[i]);
128 | }
129 | }
130 |
131 | LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
132 | {
133 | switch(message)
134 | {
135 | case WM_ERASEBKGND:
136 | return 1L;
137 |
138 | case WM_DESTROY:
139 | PostQuitMessage(0);
140 | break;
141 |
142 | default:
143 | return DefWindowProc(hwnd, message, wParam, lParam);
144 | }
145 |
146 | return 0L;
147 | }
--------------------------------------------------------------------------------
/MFVideoCaptureEVR/MFVideoCaptureEVR.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MFVideoCaptureEVR", "MFVideoCaptureEVR.vcxproj", "{91E6311D-6613-4E32-B635-0719DA39446A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {91E6311D-6613-4E32-B635-0719DA39446A}.Debug|x64.ActiveCfg = Debug|x64
17 | {91E6311D-6613-4E32-B635-0719DA39446A}.Debug|x64.Build.0 = Debug|x64
18 | {91E6311D-6613-4E32-B635-0719DA39446A}.Debug|x86.ActiveCfg = Debug|Win32
19 | {91E6311D-6613-4E32-B635-0719DA39446A}.Debug|x86.Build.0 = Debug|Win32
20 | {91E6311D-6613-4E32-B635-0719DA39446A}.Release|x64.ActiveCfg = Release|x64
21 | {91E6311D-6613-4E32-B635-0719DA39446A}.Release|x64.Build.0 = Release|x64
22 | {91E6311D-6613-4E32-B635-0719DA39446A}.Release|x86.ActiveCfg = Release|Win32
23 | {91E6311D-6613-4E32-B635-0719DA39446A}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {28A88B0D-F66C-40FE-BF9A-A688A3344B77}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/MFVideoCaptureEVR/MFVideoCaptureEVR.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers sources
20 |
21 |
22 |
--------------------------------------------------------------------------------
/MFVideoCaptureEVR/MFVideoCaptureEVR.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/MFVideoEVR/MFVideoEVR.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MFVideoEVR", "MFVideoEVR.vcxproj", "{005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Debug|Win32.Build.0 = Debug|Win32
16 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Release|Win32.ActiveCfg = Release|Win32
17 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/MFVideoEVR/MFVideoEVR.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}
15 | Win32Proj
16 | MFVideoEVR
17 | 10.0.15063.0
18 |
19 |
20 |
21 | Application
22 | true
23 | v141
24 | Unicode
25 |
26 |
27 | Application
28 | false
29 | v141
30 | true
31 | Unicode
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | true
45 |
46 |
47 | false
48 |
49 |
50 |
51 |
52 |
53 | Level4
54 | Disabled
55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
56 |
57 |
58 | Console
59 | true
60 |
61 |
62 |
63 |
64 | Level3
65 |
66 |
67 | MaxSpeed
68 | true
69 | true
70 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
71 |
72 |
73 | Console
74 | false
75 | true
76 | true
77 | UseLinkTimeCodeGeneration
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/MFVideoEVR/MFVideoEVR.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Media/CustomVideoMixer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mofo7777/Stackoverflow/20aeebb815f6b9c1492abd54127dfe6b9be65b77/Media/CustomVideoMixer.jpg
--------------------------------------------------------------------------------
/Media/IMFSinkWriterCallback.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mofo7777/Stackoverflow/20aeebb815f6b9c1492abd54127dfe6b9be65b77/Media/IMFSinkWriterCallback.jpg
--------------------------------------------------------------------------------
/Media/MFMultiVideo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mofo7777/Stackoverflow/20aeebb815f6b9c1492abd54127dfe6b9be65b77/Media/MFMultiVideo.jpg
--------------------------------------------------------------------------------
/Media/ScreenCaptureEncode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mofo7777/Stackoverflow/20aeebb815f6b9c1492abd54127dfe6b9be65b77/Media/ScreenCaptureEncode.jpg
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFClassFactory.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFClassFactory.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFCLASSFACTORY_H
5 | #define MFCLASSFACTORY_H
6 |
7 | typedef HRESULT (*CreateInstanceFn)(IUnknown*, REFIID, void**);
8 |
9 | struct ClassFactoryData{
10 |
11 | const GUID* pclsid;
12 | CreateInstanceFn pfnCreate;
13 | };
14 |
15 | class ClassFactory : public IClassFactory{
16 |
17 | private:
18 |
19 | volatile long m_refCount; // Reference count.
20 | static volatile long m_serverLocks; // Number of server locks
21 |
22 | CreateInstanceFn m_pfnCreation; // Function to create an instance of the object.
23 |
24 | public:
25 |
26 | ClassFactory(CreateInstanceFn pfnCreation) : m_pfnCreation(pfnCreation), m_refCount(1){}
27 |
28 | static bool IsLocked(){ return (m_serverLocks != 0); }
29 |
30 | STDMETHODIMP_(ULONG) AddRef(){ return InterlockedIncrement(&m_refCount); }
31 | STDMETHODIMP_(ULONG) Release(){
32 |
33 | assert(m_refCount >= 0);
34 | ULONG uCount = InterlockedDecrement(&m_refCount);
35 |
36 | if(uCount == 0){
37 | delete this;
38 | }
39 |
40 | return uCount;
41 | }
42 |
43 | STDMETHODIMP QueryInterface(REFIID riid, void** ppv){
44 |
45 | if(NULL == ppv){
46 | return E_POINTER;
47 | }
48 | else if(riid == __uuidof(IUnknown)){
49 | *ppv = static_cast(this);
50 | }
51 | else if(riid == __uuidof(IClassFactory)){
52 | *ppv = static_cast(this);
53 | }
54 | else{
55 | *ppv = NULL;
56 | return E_NOINTERFACE;
57 | }
58 |
59 | AddRef();
60 | return S_OK;
61 | }
62 |
63 | STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv){
64 |
65 | if(pUnkOuter != NULL){
66 |
67 | if(riid != __uuidof(IUnknown)){
68 | return E_NOINTERFACE;
69 | }
70 | }
71 |
72 | return m_pfnCreation(pUnkOuter, riid, ppv);
73 | }
74 |
75 | STDMETHODIMP LockServer(BOOL lock){
76 |
77 | if(lock){
78 | LockServer();
79 | }
80 | else{
81 | UnlockServer();
82 | }
83 | return S_OK;
84 | }
85 |
86 | static void LockServer(){ InterlockedIncrement(&m_serverLocks); }
87 | static void UnlockServer(){ InterlockedDecrement(&m_serverLocks); }
88 | };
89 |
90 | class BaseObject{
91 |
92 | public:
93 |
94 | BaseObject(){ ClassFactory::LockServer(); }
95 | virtual ~BaseObject(){ ClassFactory::UnlockServer(); }
96 | };
97 |
98 | #define DEFINE_CLASSFACTORY_SERVER_LOCK volatile long ClassFactory::m_serverLocks = 0;
99 |
100 | #endif
101 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFCriticSection.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFCriticSection.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFCRITICSECTION_H
5 | #define MFCRITICSECTION_H
6 |
7 | class CriticSection{
8 |
9 | private:
10 |
11 | CRITICAL_SECTION m_Section;
12 |
13 | public:
14 |
15 | CriticSection(){ InitializeCriticalSection(&m_Section); }
16 | ~CriticSection(){ DeleteCriticalSection(&m_Section); }
17 |
18 | void Lock(){ EnterCriticalSection(&m_Section); }
19 | void Unlock(){ LeaveCriticalSection(&m_Section); }
20 | };
21 |
22 | class AutoLock{
23 |
24 | private:
25 |
26 | CriticSection* m_pSection;
27 |
28 | public:
29 |
30 | AutoLock(CriticSection& critic){ m_pSection = &critic; m_pSection->Lock(); }
31 | ~AutoLock(){ m_pSection->Unlock(); }
32 | };
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFGuid.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFGuid.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFGUID_H
5 | #define MFGUID_H
6 |
7 | // {2F181C36-36CC-4527-AAA5-4F46720194EE}
8 | DEFINE_GUID(CLSID_MinimalSinkRenderer, 0x2f181c36, 0x36cc, 0x4527, 0xaa, 0xa5, 0x4f, 0x46, 0x72, 0x1, 0x94, 0xee);
9 |
10 | //----------------------------------------------------------------------------------------------
11 | // Media subType guid
12 |
13 | // {7634706D-0000-0010-8000-00AA00389B71}
14 | DEFINE_GUID(MEDIASUBTYPE_mp4v, 0x7634706d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
15 |
16 | // 56564D41-0000-0010-8000-00AA00389B71
17 | DEFINE_GUID(MEDIASUBTYPE_XVID, 0x44495658, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
18 |
19 | // {64697678-0000-0010-8000-00AA00389B71}
20 | DEFINE_GUID(MEDIASUBTYPE_xvid, 0x64697678, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
21 |
22 | // {58564944-0000-0010-8000-00AA00389B71}
23 | DEFINE_GUID(MEDIASUBTYPE_DIVX, 0x58564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
24 |
25 | // {78766964-0000-0010-8000-00AA00389B71}
26 | DEFINE_GUID(MEDIASUBTYPE_divx, 0x78766964, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
27 |
28 | // {30355844-0000-0010-8000-00aa00389b71}
29 | DEFINE_GUID(MEDIASUBTYPE_DX50, 0x30355844, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
30 |
31 | // {30357864-0000-0010-8000-00AA00389B71}
32 | DEFINE_GUID(MEDIASUBTYPE_dx50, 0x30357864, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
33 |
34 | // {1D4A45F2-E5F6-4B44-8388-F0AE5C0E0C37}
35 | DEFINE_GUID(MEDIASUBTYPE_VIDEOIMAGE, 0x1D4A45F2, 0xE5F6, 0x4B44, 0x83, 0x88, 0xF0, 0xAE, 0x5C, 0x0E, 0x0C, 0x37);
36 |
37 | // {00000031-0000-0010-8000-00AA00389B71}
38 | DEFINE_GUID(MEDIASUBTYPE_GSM, 0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
39 |
40 | // {00000011-0000-0010-8000-00AA00389B71}
41 | DEFINE_GUID(MEDIASUBTYPE_IMAADPCMACM, 0x00000011, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
42 |
43 | #endif
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFLogCommon.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogCommon.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGCOMMON_H
5 | #define MFLOGCOMMON_H
6 |
7 | #if (_DEBUG && MF_USE_LOGGING)
8 |
9 | typedef LPCWSTR(*GetGUIDStringName)(const GUID&);
10 |
11 | inline void LogGuidHexa(const GUID& guid, const BOOL bFirst){
12 |
13 | HRESULT hr;
14 | WCHAR pBuffer[39] = {0};
15 |
16 | hr = StringCchPrintf(pBuffer, 39, L"{%.8lX-%.4hX-%.4hX-%.2hhX%.2hhX-%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX}",
17 | guid.Data1,
18 | guid.Data2,
19 | guid.Data3,
20 | guid.Data4[0],
21 | guid.Data4[1],
22 | guid.Data4[2],
23 | guid.Data4[3],
24 | guid.Data4[4],
25 | guid.Data4[5],
26 | guid.Data4[6],
27 | guid.Data4[7]
28 | );
29 |
30 | if(SUCCEEDED(hr)){
31 |
32 | if(bFirst)
33 | TRACE_NO_END_LINE((L"\t%s\t", pBuffer));
34 | else
35 | TRACE((L"%s", pBuffer));
36 | }
37 | else{
38 |
39 | TRACE((L"Guid problem"));
40 | }
41 | }
42 |
43 | inline void LogUINT32AsUINT64(const PROPVARIANT& var){
44 |
45 | UINT32 uHigh = 0, uLow = 0;
46 |
47 | Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
48 |
49 | TRACE((L"%u x %u", uHigh, uLow));
50 | }
51 |
52 | inline HRESULT SpecialCaseAttributeValue(GUID guid, const PROPVARIANT& var){
53 |
54 | if(guid == MF_MT_FRAME_RATE){
55 | LogUINT32AsUINT64(var);
56 | }
57 | else if(guid == MF_MT_FRAME_SIZE){
58 | LogUINT32AsUINT64(var);
59 | }
60 | else if(guid == MF_MT_PIXEL_ASPECT_RATIO){
61 | LogUINT32AsUINT64(var);
62 | }
63 | else{
64 | return S_FALSE;
65 | }
66 |
67 | return S_OK;
68 | }
69 |
70 | inline void LogPropertyVariant(const GUID* pGuid, const PROPVARIANT& var, GetGUIDStringName pGetGUIDString){
71 |
72 | HRESULT hr = S_FALSE;
73 |
74 | if(pGuid != NULL)
75 | hr = SpecialCaseAttributeValue(*pGuid, var);
76 |
77 | if(hr == S_FALSE){
78 |
79 | switch(var.vt){
80 |
81 | case VT_UI4:
82 | TRACE((L"%lu", var.ulVal));
83 | break;
84 |
85 | case VT_I4:
86 | TRACE((L"%ld", var.lVal));
87 | break;
88 |
89 | case VT_UI8:
90 | TRACE((L"%I64u", var.uhVal));
91 | break;
92 |
93 | case VT_BOOL:
94 | TRACE((L"%s", var.boolVal == -1 ? "true" : "false"));
95 | break;
96 |
97 | case VT_R8:
98 | TRACE((L"%f", var.dblVal));
99 | break;
100 |
101 | case VT_CLSID:
102 | {
103 | LPCWSTR pwszGuidName = pGetGUIDString(*var.puuid);
104 |
105 | if(pwszGuidName != NULL){
106 | TRACE((L"%s", pwszGuidName));
107 | }
108 | else{
109 | LogGuidHexa(*var.puuid, FALSE);
110 | }
111 | }
112 | break;
113 |
114 | case VT_LPWSTR:
115 | // Log : var.pwszVal
116 | TRACE((L"VT_LPWSTR = todo"));
117 | break;
118 |
119 | case VT_VECTOR | VT_UI1:
120 | TRACE((L"(VT_VECTOR|VT_UI1) = <>"));
121 | break;
122 |
123 | case VT_UNKNOWN:
124 | TRACE((L"VT_UNKNOWN = IUnknown"));
125 | break;
126 |
127 | case VT_EMPTY:
128 | TRACE((L"VT_EMPTY"));
129 | break;
130 |
131 | case VT_R4:
132 | TRACE((L"VT_R4 = %f", var.fltVal));
133 | break;
134 |
135 | // 8195 = VT_ARRAY | VT_I4
136 |
137 | default:
138 | TRACE((L"Unexpected attribute type (vt = %hu)", var.vt));
139 | break;
140 | }
141 | }
142 | }
143 |
144 | inline void LogAttributeValueByIndex(IMFAttributes* pAttributes, UINT32 uiIndex, GetGUIDStringName pGetGUIDString){
145 |
146 | HRESULT hr;
147 | PROPVARIANT var;
148 | GUID guid = GUID_NULL;
149 |
150 | PropVariantInit(&var);
151 |
152 | hr = pAttributes->GetItemByIndex(uiIndex, &guid, &var);
153 |
154 | if(SUCCEEDED(hr)){
155 |
156 | LPCWSTR pwszGUIDNameAttributes = pGetGUIDString(guid);
157 |
158 | if(pwszGUIDNameAttributes != NULL){
159 | TRACE_NO_END_LINE((L"\t%s\t", pwszGUIDNameAttributes));
160 | }
161 | else{
162 |
163 | LogGuidHexa(guid, TRUE);
164 | }
165 |
166 | LogPropertyVariant(&guid, var, pGetGUIDString);
167 | }
168 | else{
169 | TRACE((L"\tGetItemByIndex (Index = %u) hr = %s", uiIndex, MFErrorString(hr)));
170 | }
171 |
172 | PropVariantClear(&var);
173 | }
174 |
175 | #endif
176 |
177 | #endif
178 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(155);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #ifdef MF_USE_LOGREFCOUNT
87 | #define TRACE_REFCOUNT(x) DebugLog::Trace x
88 | #else
89 | #define TRACE_REFCOUNT(x)
90 | #endif
91 |
92 | #ifdef MF_TRACE_SINK
93 | #define TRACE_SINK(x) DebugLog::Trace x
94 | #else
95 | #define TRACE_SINK(x)
96 | #endif
97 |
98 | #ifdef MF_TRACE_STREAM
99 | #define TRACE_STREAM(x) DebugLog::Trace x
100 | #else
101 | #define TRACE_STREAM(x)
102 | #endif
103 |
104 | #else
105 | #define TRACE_INIT()
106 | #define TRACE(x)
107 | #define TRACE_NO_END_LINE(x)
108 | #define TRACE_CLOSE()
109 | #define LOG_HRESULT(hr) hr
110 | #define LOG_LAST_ERROR()
111 | #define TRACE_REFCOUNT(x)
112 | #define TRACE_SINK(x)
113 | #define TRACE_STREAM(x)
114 | #endif
115 |
116 | #endif
117 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | // Need to use other macro. When error, multiple call.
41 | #ifndef IF_FAILED_RETURN
42 | #if(_DEBUG && MF_USE_LOGGING)
43 | #define IF_FAILED_RETURN(hr) if(FAILED(hr)){ LOG_HRESULT(hr); return hr; }
44 | #else
45 | #define IF_FAILED_RETURN(hr) if(FAILED(hr)){ return hr; }
46 | #endif
47 | #endif
48 |
49 | #ifndef IF_FAILED_THROW
50 | #if(_DEBUG && MF_USE_LOGGING)
51 | #define IF_FAILED_THROW(hr) if(FAILED(hr)){ LOG_HRESULT(hr); throw hr; }
52 | #else
53 | #define IF_FAILED_THROW(hr) if(FAILED(hr)){ throw hr; }
54 | #endif
55 | #endif
56 |
57 | #ifndef ARRAY_SIZE
58 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]) )
59 | #endif
60 |
61 | #ifndef RETURN_STRING
62 | #define RETURN_STRING(x) case x: return L#x
63 | #endif
64 |
65 | #ifndef IF_EQUAL_RETURN
66 | #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
67 | #endif
68 |
69 | #ifndef VALUE_NOT_FOUND
70 | #define VALUE_NOT_FOUND(val) return L#val
71 | #endif
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFState.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFState.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFSTATE_H
5 | #define MFSTATE_H
6 |
7 | enum SessionState{
8 |
9 | SessionClosed = 0,
10 | SessionReady,
11 | SessionOpenPending,
12 | SessionStarted,
13 | SessionPaused,
14 | SessionStopped,
15 | SessionClosing,
16 | SessionAbort
17 | };
18 |
19 | enum StreamState{
20 |
21 | StreamTypeNotSet = 0,
22 | StreamReady,
23 | StreamStarted,
24 | StreamStopped,
25 | StreamPaused,
26 | StreamFinalized,
27 |
28 | StreamCount = StreamFinalized + 1
29 | };
30 |
31 | enum StreamRequest{
32 |
33 | RequestSetMediaType = 0,
34 | RequestStart,
35 | RequestRestart,
36 | RequestPause,
37 | RequestStop,
38 | RequestProcessSample,
39 | RequestPlaceMarker,
40 | RequestFinalize,
41 |
42 | RequestCount = RequestFinalize + 1
43 | };
44 |
45 | enum SourceState{
46 |
47 | SourceInvalid,
48 | SourceOpening,
49 | SourceStopped,
50 | SourcePaused,
51 | SourceStarted,
52 | SourceShutdown
53 | };
54 |
55 | enum RendererState{
56 |
57 | RendererStarted,
58 | RendererStopped,
59 | RendererPaused,
60 | RendererShutdown
61 | };
62 |
63 | #if (_DEBUG && MF_USE_LOGGING)
64 |
65 | inline LPCWSTR ClockStateString(MFCLOCK_STATE State){
66 |
67 | switch(State){
68 |
69 | RETURN_STRING(MFCLOCK_STATE_INVALID);
70 | RETURN_STRING(MFCLOCK_STATE_RUNNING);
71 | RETURN_STRING(MFCLOCK_STATE_STOPPED);
72 | RETURN_STRING(MFCLOCK_STATE_PAUSED);
73 |
74 | default:
75 | return L"Unknown Clock State";
76 | }
77 | }
78 |
79 | inline LPCWSTR SessionStateString(SessionState State){
80 |
81 | switch(State){
82 |
83 | RETURN_STRING(SessionClosed);
84 | RETURN_STRING(SessionReady);
85 | RETURN_STRING(SessionOpenPending);
86 | RETURN_STRING(SessionStarted);
87 | RETURN_STRING(SessionPaused);
88 | RETURN_STRING(SessionStopped);
89 | RETURN_STRING(SessionClosing);
90 |
91 | default:
92 | return L"Unknown Session State";
93 | }
94 | }
95 |
96 | inline LPCWSTR StreamStateString(StreamState State){
97 |
98 | switch(State){
99 |
100 | RETURN_STRING(StreamTypeNotSet);
101 | RETURN_STRING(StreamReady);
102 | RETURN_STRING(StreamStarted);
103 | RETURN_STRING(StreamStopped);
104 | RETURN_STRING(StreamPaused);
105 | RETURN_STRING(StreamFinalized);
106 | RETURN_STRING(StreamCount);
107 |
108 | default:
109 | return L"Unknown Stream State";
110 | }
111 | }
112 |
113 | inline LPCWSTR StreamRequestStateString(StreamRequest State){
114 |
115 | switch(State){
116 |
117 | RETURN_STRING(RequestSetMediaType);
118 | RETURN_STRING(RequestStart);
119 | RETURN_STRING(RequestRestart);
120 | RETURN_STRING(RequestPause);
121 | RETURN_STRING(RequestStop);
122 | RETURN_STRING(RequestProcessSample);
123 | RETURN_STRING(RequestPlaceMarker);
124 | RETURN_STRING(RequestFinalize);
125 | RETURN_STRING(RequestCount);
126 |
127 | default:
128 | return L"Unknown StreamRequest State";
129 | }
130 | }
131 |
132 | inline LPCWSTR SourceStateString(SourceState State){
133 |
134 | switch(State){
135 |
136 | RETURN_STRING(SourceInvalid);
137 | RETURN_STRING(SourceOpening);
138 | RETURN_STRING(SourceStopped);
139 | RETURN_STRING(SourcePaused);
140 | RETURN_STRING(SourceStarted);
141 | RETURN_STRING(SourceShutdown);
142 |
143 | default:
144 | return L"Unknown Source State";
145 | }
146 | }
147 |
148 | inline LPCWSTR RendererStateString(RendererState State){
149 |
150 | switch(State){
151 |
152 | RETURN_STRING(RendererStarted);
153 | RETURN_STRING(RendererStopped);
154 | RETURN_STRING(RendererPaused);
155 | RETURN_STRING(RendererShutdown);
156 |
157 | default:
158 | return L"Unknown Renderer State";
159 | }
160 | }
161 |
162 | #else
163 |
164 | #define ClockStateString(x) L""
165 | #define SessionStateString(x) L""
166 | #define StreamStateString(x) L""
167 | #define StreamRequestStateString(x) L""
168 | #define SourceStateString(x) L""
169 | #define RendererStateString(x) L""
170 |
171 | #endif
172 |
173 | #endif
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/Common/MFTime.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTime.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTIME_H
5 | #define MFTIME_H
6 |
7 | // One second in hns
8 | const MFTIME ONE_SECOND = 10000000;
9 |
10 | // One msec in hns
11 | const LONG ONE_MSEC = 1000;
12 |
13 | inline LONG MFTimeToMilliSec(const LONGLONG& time){
14 |
15 | return (LONG)(time / (ONE_SECOND / ONE_MSEC));
16 | }
17 |
18 | inline LONG MFTimeToSec(const LONGLONG& time){
19 |
20 | return (LONG)(time / ONE_SECOND);
21 | }
22 |
23 | #if (_DEBUG && MF_USE_LOGGING)
24 |
25 | inline void MFTimeString(const MFTIME& Duration){
26 |
27 | MFTIME DurationInMilliSec = 0;
28 | MFTIME DurationInSec = 0;
29 | MFTIME Hours = 0;
30 | MFTIME Minutes = 0;
31 | MFTIME Seconds = 0;
32 |
33 | DurationInSec = MFTimeToSec(Duration);
34 | DurationInMilliSec = MFTimeToMilliSec(Duration);
35 |
36 | if(DurationInSec > 60){
37 |
38 | Minutes = DurationInSec / 60;
39 |
40 | if(Minutes > 60){
41 |
42 | Hours = Minutes / 60;
43 | Minutes = Minutes % 60;
44 | }
45 |
46 | Seconds = (DurationInSec % 60);
47 | }
48 | else{
49 |
50 | Seconds = DurationInSec;
51 | }
52 |
53 | if(Seconds){
54 | DurationInMilliSec = DurationInMilliSec % (Seconds * ONE_MSEC);
55 | }
56 |
57 | TRACE((L"%02dh:%02dmn:%02ds:%03dms", (int)Hours, (int)Minutes, (int)Seconds, DurationInMilliSec));
58 | }
59 |
60 | #else
61 | #define MFTimeString(x)
62 | #endif
63 |
64 | #endif
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinimalSinkRenderer", "MinimalSinkRenderer\MinimalSinkRenderer.vcxproj", "{78024A78-8995-47A3-821A-FDDA40B0D8A5}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{050C0987-83ED-4019-9CC7-C08B71091EF7}"
9 | ProjectSection(SolutionItems) = preProject
10 | Common\MFClassFactory.h = Common\MFClassFactory.h
11 | Common\MFCriticSection.h = Common\MFCriticSection.h
12 | Common\MFGuid.h = Common\MFGuid.h
13 | Common\MFLogCommon.h = Common\MFLogCommon.h
14 | Common\MFLogging.h = Common\MFLogging.h
15 | Common\MFLogMediaType.h = Common\MFLogMediaType.h
16 | Common\MFMacro.h = Common\MFMacro.h
17 | Common\MFRegistry.h = Common\MFRegistry.h
18 | Common\MFState.h = Common\MFState.h
19 | Common\MFTExternTrace.h = Common\MFTExternTrace.h
20 | Common\MFTime.h = Common\MFTime.h
21 | Common\MFTrace.h = Common\MFTrace.h
22 | EndProjectSection
23 | EndProject
24 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestMinimalSinkRenderer", "TestMinimalSinkRenderer\TestMinimalSinkRenderer.vcxproj", "{C404D8DA-ACC9-454C-AE54-E83235C475F9}"
25 | EndProject
26 | Global
27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
28 | Debug|x64 = Debug|x64
29 | Debug|x86 = Debug|x86
30 | Release|x64 = Release|x64
31 | Release|x86 = Release|x86
32 | EndGlobalSection
33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
34 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Debug|x64.ActiveCfg = Debug|x64
35 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Debug|x64.Build.0 = Debug|x64
36 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Debug|x86.ActiveCfg = Debug|Win32
37 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Debug|x86.Build.0 = Debug|Win32
38 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Release|x64.ActiveCfg = Release|x64
39 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Release|x64.Build.0 = Release|x64
40 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Release|x86.ActiveCfg = Release|Win32
41 | {78024A78-8995-47A3-821A-FDDA40B0D8A5}.Release|x86.Build.0 = Release|Win32
42 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Debug|x64.ActiveCfg = Debug|x64
43 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Debug|x64.Build.0 = Debug|x64
44 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Debug|x86.ActiveCfg = Debug|Win32
45 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Debug|x86.Build.0 = Debug|Win32
46 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Release|x64.ActiveCfg = Release|x64
47 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Release|x64.Build.0 = Release|x64
48 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Release|x86.ActiveCfg = Release|Win32
49 | {C404D8DA-ACC9-454C-AE54-E83235C475F9}.Release|x86.Build.0 = Release|Win32
50 | EndGlobalSection
51 | GlobalSection(SolutionProperties) = preSolution
52 | HideSolutionNode = FALSE
53 | EndGlobalSection
54 | GlobalSection(ExtensibilityGlobals) = postSolution
55 | SolutionGuid = {D190FCBF-ABCD-4253-9682-D32ADF6F7FEB}
56 | EndGlobalSection
57 | EndGlobal
58 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/DllMain.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // DllMain.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HMODULE g_hModule;
7 |
8 | DEFINE_CLASSFACTORY_SERVER_LOCK
9 |
10 | WCHAR SZ_RENDERER_NAME[] = L"Minimal Sink Renderer";
11 |
12 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/){
13 |
14 | switch(ul_reason_for_call){
15 |
16 | case DLL_PROCESS_ATTACH:
17 | DisableThreadLibraryCalls((HMODULE)hModule);
18 | g_hModule = (HMODULE)hModule;
19 | break;
20 |
21 | case DLL_PROCESS_DETACH:
22 | case DLL_THREAD_ATTACH:
23 | case DLL_THREAD_DETACH:
24 | break;
25 | }
26 | return TRUE;
27 | }
28 |
29 | STDAPI DllCanUnloadNow(){
30 |
31 | if(!ClassFactory::IsLocked()){
32 | return S_OK;
33 | }
34 | else{
35 | return S_FALSE;
36 | }
37 | }
38 |
39 | STDAPI DllRegisterServer(){
40 |
41 | HRESULT hr;
42 |
43 | hr = RegisterObject(g_hModule, CLSID_MinimalSinkRenderer, SZ_RENDERER_NAME, TEXT("Both"));
44 |
45 | if(SUCCEEDED(hr)){
46 |
47 | MFT_REGISTER_TYPE_INFO tInInfo [] = { { MFMediaType_Video, MFVideoFormat_RGB32 } };
48 |
49 | hr = MFTRegister(CLSID_MinimalSinkRenderer, MFT_CATEGORY_OTHER, SZ_RENDERER_NAME, 0, ARRAY_SIZE(tInInfo), tInInfo, 0, NULL, NULL);
50 | }
51 |
52 | return hr;
53 | }
54 |
55 | STDAPI DllUnregisterServer(){
56 |
57 | UnregisterObject(CLSID_MinimalSinkRenderer);
58 | MFTUnregister(CLSID_MinimalSinkRenderer);
59 | return S_OK;
60 | }
61 |
62 | STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv){
63 |
64 | HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
65 |
66 | if(clsid == CLSID_MinimalSinkRenderer){
67 |
68 | ClassFactory* pFactory = NULL;
69 |
70 | pFactory = new (std::nothrow)ClassFactory(CMinimalSkinkRenderer::CreateInstance);
71 |
72 | if(pFactory){
73 |
74 | hr = pFactory->QueryInterface(riid, ppv);
75 |
76 | SAFE_RELEASE(pFactory);
77 | }
78 | else{
79 |
80 | hr = E_OUTOFMEMORY;
81 | }
82 | }
83 |
84 | return hr;
85 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSinkRenderer.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Fichiers sources
6 |
7 |
8 | Fichiers sources
9 |
10 |
11 | Fichiers sources
12 |
13 |
14 | Fichiers sources
15 |
16 |
17 | Fichiers sources
18 |
19 |
20 | Fichiers sources
21 |
22 |
23 | Fichiers sources
24 |
25 |
26 | Fichiers sources
27 |
28 |
29 | Fichiers sources
30 |
31 |
32 |
33 |
34 | Fichiers d%27en-tête
35 |
36 |
37 | Fichiers d%27en-tête
38 |
39 |
40 | Fichiers d%27en-tête
41 |
42 |
43 |
44 |
45 | {5134eb78-c9fc-440d-89b1-0cf8df0e5c8d}
46 |
47 |
48 | {5508b7ae-2491-4e6a-a0a6-87861da137f3}
49 |
50 |
51 | {95f1c72f-5685-4a20-bfc3-972744c68e54}
52 |
53 |
54 |
55 |
56 | Fichiers de ressources
57 |
58 |
59 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSinkRenderer.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSkinkRenderer.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 | DllCanUnloadNow PRIVATE
3 | DllRegisterServer PRIVATE
4 | DllUnregisterServer PRIVATE
5 | DllGetClassObject PRIVATE
6 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSkinkRenderer.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MinimalSkinkRenderer.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MINIMALSINKRENDERER_H
5 | #define MINIMALSINKRENDERER_H
6 |
7 | class CMinimalSkinkRenderer : BaseObject, public IMFMediaSink, public IMFClockStateSink{
8 |
9 | public:
10 |
11 | // MinimalSkinkRenderer.cpp
12 | static HRESULT CreateInstance(IUnknown*, REFIID, void**);
13 |
14 | // IUnknown - MinimalSkinkRenderer.cpp
15 | STDMETHODIMP QueryInterface(REFIID, void**);
16 | STDMETHODIMP_(ULONG) AddRef();
17 | STDMETHODIMP_(ULONG) Release();
18 |
19 | // IMFMediaSink - MinimalSkinkRenderer_Sink.cpp
20 | STDMETHODIMP GetCharacteristics(DWORD*);
21 | STDMETHODIMP AddStreamSink(DWORD, IMFMediaType*, IMFStreamSink**);
22 | STDMETHODIMP RemoveStreamSink(DWORD);
23 | STDMETHODIMP GetStreamSinkCount(DWORD*);
24 | STDMETHODIMP GetStreamSinkByIndex(DWORD, IMFStreamSink**);
25 | STDMETHODIMP GetStreamSinkById(DWORD, IMFStreamSink**);
26 | STDMETHODIMP SetPresentationClock(IMFPresentationClock*);
27 | STDMETHODIMP GetPresentationClock(IMFPresentationClock**);
28 | STDMETHODIMP Shutdown();
29 |
30 | // IMFClockStateSink - MinimalSkinkRenderer_Clock.cpp
31 | STDMETHODIMP OnClockStart(MFTIME, LONGLONG);
32 | STDMETHODIMP OnClockStop(MFTIME);
33 | STDMETHODIMP OnClockPause(MFTIME);
34 | STDMETHODIMP OnClockRestart(MFTIME);
35 | STDMETHODIMP OnClockSetRate(MFTIME, float);
36 |
37 | // MinimalSkinkRenderer.cpp
38 | HRESULT ProcessSample(IMFSample*);
39 |
40 | private:
41 |
42 | // MinimalSkinkRenderer.cpp
43 | CMinimalSkinkRenderer(HRESULT&);
44 | virtual ~CMinimalSkinkRenderer();
45 |
46 | CriticSection m_CriticSection;
47 | volatile long m_nRefCount;
48 | BOOL m_bShutdown;
49 | DWORD m_dwCurrentFrame;
50 |
51 | CStreamSkinkRenderer* m_pStreamSkinkRenderer;
52 | IMFPresentationClock* m_pClock;
53 |
54 | // MinimalSkinkRenderer.cpp
55 | void SaveSampleToBmpFile(IMFSample*);
56 | void CreateBmpFile(LPCWSTR, BYTE*, const UINT32, const UINT32, const UINT32, const UINT32);
57 |
58 | // Inline
59 | HRESULT CheckShutdown() const{ return (m_bShutdown ? MF_E_SHUTDOWN : S_OK); }
60 | };
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSkinkRenderer_Clock.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MinimalSkinkRenderer_Clock.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
5 |
6 | HRESULT CMinimalSkinkRenderer::OnClockStart(MFTIME /*hnsSystemTime*/, LONGLONG llClockStartOffset){
7 |
8 | TRACE_SINK((L"SinkRenderer::OnClockStart"));
9 |
10 | AutoLock lock(m_CriticSection);
11 |
12 | HRESULT hr;
13 | IF_FAILED_RETURN(hr = CheckShutdown());
14 |
15 | IF_FAILED_RETURN(hr = m_pStreamSkinkRenderer->Start(llClockStartOffset));
16 |
17 | m_dwCurrentFrame = 0;
18 |
19 | return hr;
20 | }
21 |
22 | HRESULT CMinimalSkinkRenderer::OnClockStop(MFTIME /*hnsSystemTime*/){
23 |
24 | TRACE_SINK((L"SinkRenderer::OnClockStop"));
25 |
26 | AutoLock lock(m_CriticSection);
27 |
28 | HRESULT hr;
29 | IF_FAILED_RETURN(hr = CheckShutdown());
30 |
31 | IF_FAILED_RETURN(hr = m_pStreamSkinkRenderer->Stop());
32 |
33 | return hr;
34 | }
35 |
36 | HRESULT CMinimalSkinkRenderer::OnClockPause(MFTIME /*hnsSystemTime*/){
37 |
38 | TRACE_SINK((L"SinkRenderer::OnClockPause"));
39 |
40 | AutoLock lock(m_CriticSection);
41 |
42 | HRESULT hr;
43 | IF_FAILED_RETURN(hr = CheckShutdown());
44 |
45 | IF_FAILED_RETURN(hr = m_pStreamSkinkRenderer->Pause());
46 |
47 | return hr;
48 | }
49 |
50 | HRESULT CMinimalSkinkRenderer::OnClockRestart(MFTIME /*hnsSystemTime*/){
51 |
52 | TRACE_SINK((L"SinkRenderer::OnClockRestart"));
53 |
54 | AutoLock lock(m_CriticSection);
55 |
56 | HRESULT hr;
57 | IF_FAILED_RETURN(hr = CheckShutdown());
58 |
59 | IF_FAILED_RETURN(hr = m_pStreamSkinkRenderer->Restart());
60 |
61 | return hr;
62 | }
63 |
64 | HRESULT CMinimalSkinkRenderer::OnClockSetRate(MFTIME /*hnsSystemTime*/, float /*flRate*/){
65 |
66 | TRACE_SINK((L"SinkRenderer::OnClockSetRate"));
67 |
68 | HRESULT hr;
69 | IF_FAILED_RETURN(hr = CheckShutdown());
70 |
71 | return hr;
72 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/MinimalSkinkRenderer_Sink.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MinimalSkinkRenderer_Sink.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
5 |
6 | HRESULT CMinimalSkinkRenderer::GetCharacteristics(DWORD* pdwCharacteristics){
7 |
8 | TRACE_SINK((L"SinkRenderer::GetCharacteristics"));
9 |
10 | HRESULT hr;
11 | IF_FAILED_RETURN(hr = (pdwCharacteristics == NULL ? E_INVALIDARG : S_OK));
12 |
13 | AutoLock lock(m_CriticSection);
14 |
15 | IF_FAILED_RETURN(hr = CheckShutdown());
16 |
17 | *pdwCharacteristics = MEDIASINK_FIXED_STREAMS;
18 |
19 | return hr;
20 | }
21 |
22 | HRESULT CMinimalSkinkRenderer::AddStreamSink(DWORD /*dwStreamSinkIdentifier*/, IMFMediaType* /*pMediaType*/, IMFStreamSink** /*ppStreamSink*/){
23 |
24 | TRACE_SINK((L"SinkRenderer::AddStreamSink"));
25 | return MF_E_STREAMSINKS_FIXED;
26 | }
27 |
28 | HRESULT CMinimalSkinkRenderer::RemoveStreamSink(DWORD /*dwStreamSinkIdentifier*/){
29 |
30 | TRACE_SINK((L"SinkRenderer::RemoveStreamSink"));
31 | return MF_E_STREAMSINKS_FIXED;
32 | }
33 |
34 | HRESULT CMinimalSkinkRenderer::GetStreamSinkCount(DWORD* pcStreamSinkCount){
35 |
36 | TRACE_SINK((L"SinkRenderer::GetStreamSinkCount"));
37 |
38 | HRESULT hr;
39 | IF_FAILED_RETURN(hr = (pcStreamSinkCount == NULL ? E_INVALIDARG : S_OK));
40 |
41 | AutoLock lock(m_CriticSection);
42 |
43 | IF_FAILED_RETURN(hr = CheckShutdown());
44 |
45 | *pcStreamSinkCount = 1;
46 |
47 | return hr;
48 | }
49 |
50 | HRESULT CMinimalSkinkRenderer::GetStreamSinkByIndex(DWORD dwIndex, IMFStreamSink** ppStreamSink){
51 |
52 | TRACE_SINK((L"SinkRenderer::GetStreamSinkByIndex"));
53 |
54 | HRESULT hr;
55 | IF_FAILED_RETURN(hr = (ppStreamSink == NULL ? E_INVALIDARG : S_OK));
56 | IF_FAILED_RETURN(hr = (dwIndex != 0 ? MF_E_INVALIDINDEX : S_OK));
57 |
58 | AutoLock lock(m_CriticSection);
59 |
60 | IF_FAILED_RETURN(hr = CheckShutdown());
61 |
62 | *ppStreamSink = m_pStreamSkinkRenderer;
63 | (*ppStreamSink)->AddRef();
64 |
65 | return hr;
66 | }
67 |
68 | HRESULT CMinimalSkinkRenderer::GetStreamSinkById(DWORD dwStreamSinkIdentifier, IMFStreamSink** ppStreamSink){
69 |
70 | TRACE_SINK((L"SinkRenderer::GetStreamSinkById"));
71 |
72 | HRESULT hr;
73 | IF_FAILED_RETURN(hr = (ppStreamSink == NULL ? E_INVALIDARG : S_OK));
74 | IF_FAILED_RETURN(hr = (dwStreamSinkIdentifier != 0 ? MF_E_INVALIDSTREAMNUMBER : S_OK));
75 |
76 | AutoLock lock(m_CriticSection);
77 |
78 | IF_FAILED_RETURN(hr = CheckShutdown());
79 |
80 | *ppStreamSink = m_pStreamSkinkRenderer;
81 | (*ppStreamSink)->AddRef();
82 |
83 | return hr;
84 | }
85 |
86 | HRESULT CMinimalSkinkRenderer::SetPresentationClock(IMFPresentationClock* pPresentationClock){
87 |
88 | TRACE_SINK((L"SinkRenderer::SetPresentationClock"));
89 |
90 | HRESULT hr;
91 |
92 | AutoLock lock(m_CriticSection);
93 |
94 | IF_FAILED_RETURN(hr = CheckShutdown());
95 |
96 | if(m_pClock){
97 | IF_FAILED_RETURN(hr = m_pClock->RemoveClockStateSink(this));
98 | }
99 |
100 | if(pPresentationClock){
101 | IF_FAILED_RETURN(hr = pPresentationClock->AddClockStateSink(this));
102 | }
103 |
104 | SAFE_RELEASE(m_pClock);
105 |
106 | if(pPresentationClock){
107 |
108 | m_pClock = pPresentationClock;
109 | m_pClock->AddRef();
110 | }
111 |
112 | return hr;
113 | }
114 |
115 | HRESULT CMinimalSkinkRenderer::GetPresentationClock(IMFPresentationClock** ppPresentationClock){
116 |
117 | TRACE_SINK((L"SinkRenderer::GetPresentationClock"));
118 |
119 | HRESULT hr;
120 | IF_FAILED_RETURN(hr = (ppPresentationClock == NULL ? E_INVALIDARG : S_OK));
121 |
122 | AutoLock lock(m_CriticSection);
123 |
124 | IF_FAILED_RETURN(hr = CheckShutdown());
125 |
126 | if(m_pClock == NULL){
127 |
128 | hr = MF_E_NO_CLOCK;
129 | }
130 | else{
131 |
132 | *ppPresentationClock = m_pClock;
133 | (*ppPresentationClock)->AddRef();
134 | }
135 |
136 | return hr;
137 | }
138 |
139 | HRESULT CMinimalSkinkRenderer::Shutdown(){
140 |
141 | TRACE_SINK((L"SinkRenderer::Shutdown"));
142 |
143 | AutoLock lock(m_CriticSection);
144 |
145 | HRESULT hr;
146 | IF_FAILED_RETURN(hr = CheckShutdown());
147 |
148 | if(m_pStreamSkinkRenderer){
149 | IF_FAILED_RETURN(hr = m_pStreamSkinkRenderer->Shutdown());
150 | SAFE_RELEASE(m_pStreamSkinkRenderer);
151 | }
152 |
153 | SAFE_RELEASE(m_pClock);
154 |
155 | m_bShutdown = TRUE;
156 | m_dwCurrentFrame = 0;
157 |
158 | return hr;
159 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | #pragma comment(lib, "mfplat")
12 | #pragma comment(lib, "shlwapi")
13 | #pragma comment(lib, "mfuuid")
14 | #pragma comment(lib, "strmiids")
15 |
16 | //----------------------------------------------------------------------------------------------
17 | // Microsoft Windows SDK for Windows 7
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #ifdef _DEBUG
25 | #include
26 | #endif
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | //----------------------------------------------------------------------------------------------
43 | // Common Project Files
44 | #ifdef _DEBUG
45 | #define MF_USE_LOGGING 1
46 | //#define MF_USE_LOGREFCOUNT
47 | //#define MF_TRACE_SINK
48 | //#define MF_TRACE_STREAM
49 | #else
50 | #define MF_USE_LOGGING 0
51 | #endif
52 |
53 | #include "..\Common\MFMacro.h"
54 | #include "..\Common\MFTrace.h"
55 | #include "..\Common\MFLogging.h"
56 | #include "..\Common\MFTExternTrace.h"
57 | #include "..\Common\MFClassFactory.h"
58 | #include "..\Common\MFGuid.h"
59 | #include "..\Common\MFRegistry.h"
60 | #include "..\Common\MFLogCommon.h"
61 | #include "..\Common\MFLogMediaType.h"
62 | #include "..\Common\MFCriticSection.h"
63 | #include "..\Common\MFState.h"
64 | #include "..\Common\MFTime.h"
65 |
66 | //----------------------------------------------------------------------------------------------
67 | // Project Files
68 | class CMinimalSkinkRenderer;
69 |
70 | #define TRACE_FRAME_NUMBER 1
71 | #define BMP_IMAGE_FILE L"Image.bmp"
72 |
73 | #include "StreamSkinkRenderer.h"
74 | #include "MinimalSkinkRenderer.h"
75 |
76 | #endif
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StreamSkinkRenderer.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StreamSkinkRenderer.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | CStreamSkinkRenderer::CStreamSkinkRenderer(CMinimalSkinkRenderer* pMinimalSkinkRenderer, HRESULT& hr)
7 | : m_nRefCount(1),
8 | m_State(StreamTypeNotSet),
9 | m_pEventQueue(NULL),
10 | m_pMediaType(NULL),
11 | m_pMinimalSkinkRenderer(NULL)
12 | {
13 | TRACE_STREAM((L"StreamRenderer::CTOR"));
14 |
15 | LOG_HRESULT(hr = MFCreateEventQueue(&m_pEventQueue));
16 |
17 | m_pMinimalSkinkRenderer = pMinimalSkinkRenderer;
18 | m_pMinimalSkinkRenderer->AddRef();
19 | }
20 |
21 | CStreamSkinkRenderer::~CStreamSkinkRenderer(){
22 |
23 | TRACE_STREAM((L"StreamRenderer::DTOR"));
24 |
25 | Shutdown();
26 | }
27 |
28 | HRESULT CStreamSkinkRenderer::CreateInstance(CMinimalSkinkRenderer* pSink, CStreamSkinkRenderer** ppStream, HRESULT& hr){
29 |
30 | TRACE_SINK((L"StreamRenderer::CreateInstance"));
31 |
32 | IF_FAILED_RETURN(hr = (ppStream == NULL ? E_INVALIDARG : S_OK));
33 |
34 | CStreamSkinkRenderer* pStream = new (std::nothrow)CStreamSkinkRenderer(pSink, hr);
35 |
36 | IF_FAILED_RETURN(pStream == NULL ? E_OUTOFMEMORY : S_OK);
37 |
38 | *ppStream = pStream;
39 | (*ppStream)->AddRef();
40 |
41 | SAFE_RELEASE(pStream);
42 |
43 | return hr;
44 | }
45 |
46 | HRESULT CStreamSkinkRenderer::QueryInterface(REFIID riid, void** ppv){
47 |
48 | TRACE_STREAM((L"StreamRenderer::QI : riid = %s", GetIIDString(riid)));
49 |
50 | static const QITAB qit[] = {
51 | QITABENT(CStreamSkinkRenderer, IMFStreamSink),
52 | QITABENT(CStreamSkinkRenderer, IMFMediaEventGenerator),
53 | QITABENT(CStreamSkinkRenderer, IMFMediaTypeHandler),
54 | {0}
55 | };
56 |
57 | return QISearch(this, qit, riid, ppv);
58 | }
59 |
60 | ULONG CStreamSkinkRenderer::AddRef(){
61 |
62 | LONG lRef = InterlockedIncrement(&m_nRefCount);
63 |
64 | TRACE_REFCOUNT((L"StreamRenderer::AddRef m_nRefCount = %d", lRef));
65 |
66 | return lRef;
67 | }
68 |
69 | ULONG CStreamSkinkRenderer::Release(){
70 |
71 | ULONG uCount = InterlockedDecrement(&m_nRefCount);
72 |
73 | TRACE_REFCOUNT((L"StreamRenderer::Release m_nRefCount = %d", uCount));
74 |
75 | if(uCount == 0){
76 | delete this;
77 | }
78 |
79 | return uCount;
80 | }
81 |
82 | HRESULT CStreamSkinkRenderer::Shutdown(){
83 |
84 | TRACE_STREAM((L"StreamRenderer::Shutdown"));
85 |
86 | AutoLock lock(m_CriticSection);
87 |
88 | HRESULT hr;
89 | IF_FAILED_RETURN(hr = CheckShutdown());
90 |
91 | if(m_pEventQueue){
92 | LOG_HRESULT(m_pEventQueue->Shutdown());
93 | }
94 |
95 | SAFE_RELEASE(m_pMediaType);
96 | SAFE_RELEASE(m_pMinimalSkinkRenderer);
97 | SAFE_RELEASE(m_pEventQueue);
98 |
99 | m_State = StreamFinalized;
100 |
101 | return S_OK;
102 | }
103 |
104 | HRESULT CStreamSkinkRenderer::Start(MFTIME){
105 |
106 | TRACE_STREAM((L"StreamRenderer::Start"));
107 |
108 | AutoLock lock(m_CriticSection);
109 |
110 | HRESULT hr;
111 | IF_FAILED_RETURN(hr = CheckShutdown());
112 |
113 | IF_FAILED_RETURN(hr = (m_State == StreamTypeNotSet || m_State == StreamFinalized ? MF_E_INVALIDREQUEST : S_OK));
114 |
115 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL));
116 |
117 | if(m_State != StreamStarted){
118 |
119 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, hr, NULL));
120 | m_State = StreamStarted;
121 | }
122 |
123 | return hr;
124 | }
125 |
126 | HRESULT CStreamSkinkRenderer::Stop(){
127 |
128 | TRACE_STREAM((L"StreamRenderer::Stop"));
129 |
130 | AutoLock lock(m_CriticSection);
131 |
132 | HRESULT hr;
133 | IF_FAILED_RETURN(hr = CheckShutdown());
134 |
135 | IF_FAILED_RETURN(hr = (m_State == StreamTypeNotSet || m_State == StreamFinalized ? MF_E_INVALIDREQUEST : S_OK));
136 |
137 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL));
138 |
139 | m_State = StreamStopped;
140 |
141 | return hr;
142 | }
143 |
144 | HRESULT CStreamSkinkRenderer::Pause(){
145 |
146 | TRACE_STREAM((L"StreamRenderer::Pause"));
147 |
148 | AutoLock lock(m_CriticSection);
149 |
150 | HRESULT hr;
151 | IF_FAILED_RETURN(hr = CheckShutdown());
152 |
153 | IF_FAILED_RETURN(hr = (m_State == StreamTypeNotSet || m_State == StreamFinalized || m_State == StreamStopped ? MF_E_INVALIDREQUEST : S_OK));
154 |
155 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkPaused, GUID_NULL, hr, NULL));
156 |
157 | m_State = StreamPaused;
158 |
159 | return hr;
160 | }
161 |
162 | HRESULT CStreamSkinkRenderer::Restart(){
163 |
164 | TRACE_STREAM((L"StreamRenderer::Restart"));
165 |
166 | AutoLock lock(m_CriticSection);
167 |
168 | HRESULT hr;
169 | IF_FAILED_RETURN(hr = CheckShutdown());
170 |
171 | IF_FAILED_RETURN(hr = (m_State != StreamPaused ? MF_E_INVALIDREQUEST : S_OK));
172 |
173 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL));
174 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, hr, NULL));
175 |
176 | m_State = StreamStarted;
177 |
178 | return hr;
179 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StreamSkinkRenderer.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StreamSkinkRenderer.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STREAMSINKRENDERER_H
5 | #define STREAMSINKRENDERER_H
6 |
7 | class CStreamSkinkRenderer : BaseObject, public IMFStreamSink, public IMFMediaTypeHandler{
8 |
9 | public:
10 |
11 | // StreamSkinkRenderer.cpp
12 | static HRESULT CreateInstance(CMinimalSkinkRenderer*, CStreamSkinkRenderer**, HRESULT&);
13 |
14 | // IUnknown - StreamSkinkRenderer.cpp
15 | STDMETHODIMP QueryInterface(REFIID, void**);
16 | STDMETHODIMP_(ULONG) AddRef();
17 | STDMETHODIMP_(ULONG) Release();
18 |
19 | // IMFStreamSink - StreamSkinkRenderer_Sink.cpp
20 | STDMETHODIMP GetMediaSink(IMFMediaSink**);
21 | STDMETHODIMP GetIdentifier(DWORD*);
22 | STDMETHODIMP GetMediaTypeHandler(IMFMediaTypeHandler**);
23 | STDMETHODIMP ProcessSample(IMFSample*);
24 | STDMETHODIMP PlaceMarker(MFSTREAMSINK_MARKER_TYPE, const PROPVARIANT*, const PROPVARIANT*);
25 | STDMETHODIMP Flush();
26 |
27 | // IMFMediaEventGenerator - StreamSkinkRenderer_Event.cpp
28 | STDMETHODIMP GetEvent(DWORD, IMFMediaEvent**);
29 | STDMETHODIMP BeginGetEvent(IMFAsyncCallback*, IUnknown*);
30 | STDMETHODIMP EndGetEvent(IMFAsyncResult*, IMFMediaEvent**);
31 | STDMETHODIMP QueueEvent(MediaEventType, REFGUID, HRESULT, const PROPVARIANT*);
32 |
33 | // IMFMediaTypeHandler - StreamSkinkRenderer_Type.cpp
34 | STDMETHODIMP IsMediaTypeSupported(IMFMediaType*, IMFMediaType**);
35 | STDMETHODIMP GetMediaTypeCount(DWORD*);
36 | STDMETHODIMP GetMediaTypeByIndex(DWORD, IMFMediaType**);
37 | STDMETHODIMP SetCurrentMediaType(IMFMediaType*);
38 | STDMETHODIMP GetCurrentMediaType(IMFMediaType**);
39 | STDMETHODIMP GetMajorType(GUID*);
40 |
41 | // StreamSkinkRenderer.cpp
42 | HRESULT Start(MFTIME);
43 | HRESULT Stop();
44 | HRESULT Pause();
45 | HRESULT Restart();
46 | HRESULT Shutdown();
47 |
48 | private:
49 |
50 | // StreamSkinkRenderer.cpp
51 | CStreamSkinkRenderer(CMinimalSkinkRenderer*, HRESULT&);
52 | virtual ~CStreamSkinkRenderer();
53 |
54 | CriticSection m_CriticSection;
55 | volatile long m_nRefCount;
56 | StreamState m_State;
57 |
58 | IMFMediaEventQueue* m_pEventQueue;
59 | IMFMediaType* m_pMediaType;
60 | CMinimalSkinkRenderer* m_pMinimalSkinkRenderer;
61 |
62 | // Inline
63 | HRESULT CheckShutdown() const{ return (m_State == StreamFinalized ? MF_E_SHUTDOWN : S_OK); }
64 | };
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StreamSkinkRenderer_Event.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StreamSkinkRenderer_Event.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CStreamSkinkRenderer::GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent){
7 |
8 | TRACE_STREAM((L"StreamRenderer::GetEvent"));
9 |
10 | HRESULT hr;
11 |
12 | IMFMediaEventQueue* pQueue = NULL;
13 |
14 | {
15 | AutoLock lock(m_CriticSection);
16 |
17 | LOG_HRESULT(hr = CheckShutdown());
18 |
19 | if(SUCCEEDED(hr)){
20 | pQueue = m_pEventQueue;
21 | pQueue->AddRef();
22 | }
23 | }
24 |
25 | if(SUCCEEDED(hr)){
26 | LOG_HRESULT(hr = pQueue->GetEvent(dwFlags, ppEvent));
27 | }
28 |
29 | SAFE_RELEASE(pQueue);
30 |
31 | return hr;
32 | }
33 |
34 | HRESULT CStreamSkinkRenderer::BeginGetEvent(IMFAsyncCallback* pCallback, IUnknown* punkState){
35 |
36 | TRACE_STREAM((L"StreamRenderer::BeginGetEvent"));
37 |
38 | HRESULT hr;
39 |
40 | AutoLock lock(m_CriticSection);
41 |
42 | IF_FAILED_RETURN(hr = CheckShutdown());
43 |
44 | LOG_HRESULT(hr = m_pEventQueue->BeginGetEvent(pCallback, punkState));
45 |
46 | return hr;
47 | }
48 |
49 | HRESULT CStreamSkinkRenderer::EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** ppEvent){
50 |
51 | TRACE_STREAM((L"StreamRenderer::EndGetEvent"));
52 |
53 | HRESULT hr;
54 |
55 | AutoLock lock(m_CriticSection);
56 |
57 | IF_FAILED_RETURN(hr = CheckShutdown());
58 |
59 | LOG_HRESULT(hr = m_pEventQueue->EndGetEvent(pResult, ppEvent));
60 |
61 | return hr;
62 | }
63 |
64 | HRESULT CStreamSkinkRenderer::QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue){
65 |
66 | TRACE_STREAM((L"StreamRenderer::QueueEvent : %s", MFEventString(met)));
67 |
68 | HRESULT hr;
69 |
70 | AutoLock lock(m_CriticSection);
71 |
72 | IF_FAILED_RETURN(hr = CheckShutdown());
73 |
74 | LOG_HRESULT(hr = m_pEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue));
75 |
76 | return hr;
77 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StreamSkinkRenderer_Sink.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StreamSkinkRenderer_Sink.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CStreamSkinkRenderer::GetMediaSink(IMFMediaSink** ppMediaSink){
7 |
8 | TRACE_STREAM((L"StreamRenderer::GetMediaSink"));
9 |
10 | HRESULT hr;
11 | IF_FAILED_RETURN(hr = (ppMediaSink == NULL ? E_INVALIDARG : S_OK));
12 |
13 | AutoLock lock(m_CriticSection);
14 |
15 | IF_FAILED_RETURN(hr = CheckShutdown());
16 |
17 | *ppMediaSink = m_pMinimalSkinkRenderer;
18 | (*ppMediaSink)->AddRef();
19 |
20 | return hr;
21 | }
22 |
23 | HRESULT CStreamSkinkRenderer::GetIdentifier(DWORD* pdwIdentifier){
24 |
25 | TRACE_STREAM((L"StreamRenderer::GetIdentifier"));
26 |
27 | HRESULT hr;
28 | IF_FAILED_RETURN(hr = (pdwIdentifier == NULL ? E_INVALIDARG : S_OK));
29 |
30 | AutoLock lock(m_CriticSection);
31 |
32 | IF_FAILED_RETURN(hr = CheckShutdown());
33 |
34 | *pdwIdentifier = 0;
35 |
36 | return hr;
37 | }
38 |
39 | HRESULT CStreamSkinkRenderer::GetMediaTypeHandler(IMFMediaTypeHandler** ppHandler){
40 |
41 | TRACE_STREAM((L"StreamRenderer::GetMediaTypeHandler"));
42 |
43 | HRESULT hr;
44 | IF_FAILED_RETURN(hr = (ppHandler == NULL ? E_INVALIDARG : S_OK));
45 |
46 | AutoLock lock(m_CriticSection);
47 |
48 | IF_FAILED_RETURN(hr = CheckShutdown());
49 |
50 | IF_FAILED_RETURN(hr = this->QueryInterface(IID_IMFMediaTypeHandler, reinterpret_cast(ppHandler)));
51 |
52 | return hr;
53 | }
54 |
55 | HRESULT CStreamSkinkRenderer::ProcessSample(IMFSample* pSample){
56 |
57 | TRACE_STREAM((L"StreamRenderer::ProcessSample"));
58 |
59 | HRESULT hr;
60 | IF_FAILED_RETURN(hr = (pSample == NULL ? E_INVALIDARG : S_OK));
61 |
62 | AutoLock lock(m_CriticSection);
63 |
64 | IF_FAILED_RETURN(hr = CheckShutdown());
65 |
66 | IF_FAILED_RETURN(hr = m_pMinimalSkinkRenderer->ProcessSample(pSample));
67 |
68 | IF_FAILED_RETURN(hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, hr, NULL));
69 |
70 | return hr;
71 | }
72 |
73 | HRESULT CStreamSkinkRenderer::PlaceMarker(MFSTREAMSINK_MARKER_TYPE /*eMarkerType*/, const PROPVARIANT* /*pvarMarkerValue*/, const PROPVARIANT* /*pvarContextValue*/){
74 |
75 | TRACE_STREAM((L"StreamRenderer::PlaceMarker"));
76 |
77 | // Todo check marker.
78 | return E_NOTIMPL;
79 | }
80 |
81 | HRESULT CStreamSkinkRenderer::Flush(){
82 |
83 | TRACE_STREAM((L"StreamRenderer::Flush"));
84 |
85 | // if CStreamSkinkRenderer::PlaceMarker is implemented, see :
86 | // http://msdn.microsoft.com/en-us/library/windows/desktop/ms701626(v=vs.85).aspx
87 |
88 | return S_OK;
89 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/MinimalSinkRenderer/StreamSkinkRenderer_Type.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StreamSkinkRenderer_Type.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
5 |
6 | HRESULT CStreamSkinkRenderer::IsMediaTypeSupported(IMFMediaType* pMediaType, IMFMediaType** ppMediaType){
7 |
8 | TRACE_STREAM((L"StreamRenderer::IsMediaTypeSupported"));
9 |
10 | HRESULT hr;
11 | IF_FAILED_RETURN(hr = (pMediaType == NULL ? E_INVALIDARG : S_OK));
12 |
13 | AutoLock lock(m_CriticSection);
14 |
15 | IF_FAILED_RETURN(hr = CheckShutdown());
16 |
17 | GUID MajorType = GUID_NULL;
18 | GUID SubType = GUID_NULL;
19 |
20 | //LogMediaType(pMediaType);
21 |
22 | IF_FAILED_RETURN(hr = pMediaType->GetGUID(MF_MT_MAJOR_TYPE, &MajorType));
23 | IF_FAILED_RETURN(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &SubType));
24 |
25 | IF_FAILED_RETURN(hr = (MajorType != MFMediaType_Video ? MF_E_INVALIDTYPE : S_OK));
26 | IF_FAILED_RETURN(hr = (SubType != MFVideoFormat_RGB32 ? MF_E_INVALIDTYPE : S_OK));
27 |
28 | if(ppMediaType){
29 | *ppMediaType = NULL;
30 | }
31 |
32 | return hr;
33 | }
34 |
35 | HRESULT CStreamSkinkRenderer::GetMediaTypeCount(DWORD* pdwTypeCount){
36 |
37 | TRACE_STREAM((L"StreamRenderer::GetMediaTypeCount"));
38 |
39 | HRESULT hr;
40 | IF_FAILED_RETURN(hr = (pdwTypeCount == NULL ? E_INVALIDARG : S_OK));
41 |
42 | AutoLock lock(m_CriticSection);
43 |
44 | IF_FAILED_RETURN(hr = CheckShutdown());
45 |
46 | *pdwTypeCount = 1;
47 |
48 | return hr;
49 | }
50 |
51 | HRESULT CStreamSkinkRenderer::GetMediaTypeByIndex(DWORD dwIndex, IMFMediaType** ppType){
52 |
53 | TRACE_STREAM((L"StreamRenderer::GetMediaTypeByIndex"));
54 |
55 | HRESULT hr;
56 | IF_FAILED_RETURN(hr = (ppType == NULL ? E_INVALIDARG : S_OK));
57 | IF_FAILED_RETURN(hr = (dwIndex != 0 ? MF_E_NO_MORE_TYPES : S_OK));
58 |
59 | AutoLock lock(m_CriticSection);
60 |
61 | IF_FAILED_RETURN(hr = CheckShutdown());
62 |
63 | IMFMediaType* pType = NULL;
64 |
65 | try{
66 |
67 | IF_FAILED_THROW(hr = MFCreateMediaType(&pType));
68 | IF_FAILED_THROW(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
69 | IF_FAILED_THROW(hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32));
70 |
71 | *ppType = pType;
72 | (*ppType)->AddRef();
73 | }
74 | catch(HRESULT){}
75 |
76 | SAFE_RELEASE(pType);
77 |
78 | return hr;
79 | }
80 |
81 | HRESULT CStreamSkinkRenderer::SetCurrentMediaType(IMFMediaType* pMediaType){
82 |
83 | TRACE_STREAM((L"StreamRenderer::SetCurrentMediaType"));
84 |
85 | HRESULT hr;
86 | IF_FAILED_RETURN(hr = (pMediaType == NULL ? E_INVALIDARG : S_OK));
87 |
88 | AutoLock lock(m_CriticSection);
89 |
90 | IF_FAILED_RETURN(hr = CheckShutdown());
91 |
92 | IF_FAILED_RETURN(hr = IsMediaTypeSupported(pMediaType, NULL));
93 |
94 | // Todo check valid size...
95 |
96 | SAFE_RELEASE(m_pMediaType);
97 | m_pMediaType = pMediaType;
98 | m_pMediaType->AddRef();
99 |
100 | if(m_State != StreamPaused)
101 | m_State = StreamReady;
102 |
103 | return hr;
104 | }
105 |
106 | HRESULT CStreamSkinkRenderer::GetCurrentMediaType(IMFMediaType** ppMediaType){
107 |
108 | TRACE_STREAM((L"StreamRenderer::GetCurrentMediaType"));
109 |
110 | HRESULT hr;
111 | IF_FAILED_RETURN(hr = (ppMediaType == NULL ? E_INVALIDARG : S_OK));
112 |
113 | AutoLock lock(m_CriticSection);
114 |
115 | IF_FAILED_RETURN(hr = CheckShutdown());
116 |
117 | IF_FAILED_RETURN(hr = (m_pMediaType == NULL ? MF_E_NOT_INITIALIZED : S_OK));
118 |
119 | *ppMediaType = m_pMediaType;
120 | (*ppMediaType)->AddRef();
121 |
122 | return hr;
123 | }
124 |
125 | HRESULT CStreamSkinkRenderer::GetMajorType(GUID* pguidMajorType){
126 |
127 | TRACE_STREAM((L"StreamRenderer::GetMajorType"));
128 |
129 | HRESULT hr;
130 | IF_FAILED_RETURN(hr = (pguidMajorType == NULL ? E_INVALIDARG : S_OK));
131 |
132 | *pguidMajorType = MFMediaType_Video;
133 |
134 | return hr;
135 | }
--------------------------------------------------------------------------------
/MinimalSinkRenderer/TestMinimalSinkRenderer/TestMinimalSinkRenderer.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {c62268e7-bd22-459b-8754-378766040134}
6 |
7 |
8 | {bd5646bc-a4af-491d-b809-ecf3c5d0610e}
9 |
10 |
11 | {54d2df31-6844-4485-9a7c-5f6e3385d4bf}
12 |
13 |
14 |
15 |
16 | Fichiers sources
17 |
18 |
19 |
--------------------------------------------------------------------------------
/MinimalSinkRenderer/TestMinimalSinkRenderer/TestMinimalSinkRenderer.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stackoverflow
2 | All source codes I've provided on stackoverflow as an answer, usually under tags ms-media-foundation. Most of the source codes here are quick fixes to source code from people asking for help. So be careful, it's not necessarily the most appropriate way to do it. That just answers the question. It' s up to the user to improve the code.
3 |
4 | In the programs below, some values are harcoded, like video file path for example :
5 |
6 | #define VIDEO_FILE L"C:\\\\Users\\\\Public\\\\Videos\\\\Sample Videos\\\\Wildlife.wmv"
7 |
8 | Dont't forget to change them, if you use a different video file, in a different path.
9 |
10 |
11 | ## AudioSourceReaderSeek
12 | This program uses SourceReader to check seek position with audio file.
13 |
14 | stackoverflow question : https://stackoverflow.com/questions/49739170/imfsourcereader-m4a-audio-accurate-frame-seek
15 |
16 | ## CustomVideoMixer
17 | This program shows the basic essentials for implementing a custom video mixer, to be used by a media session.
18 |
19 | You must register the CustomVideoMixer.dll with this command, and with the administrator rights : regsrv32 CustomVideoMixer.dll.
20 |
21 | Be careful, the width and height of both videos are hardcoded (320x240). See VIDEO_WIDTH_1 and VIDEO_HEIGHT_1, change it if necessary.
22 |
23 | In this example, I use two identical mp4 files, big_buck_bunny_240p_5mb.mp4 and a copy of itself. the two videos use NV12 video format as input. therefore, there is no real alpha mix, but both videos can be displayed next to each other, as the picture below.
24 |
25 | stackoverflow question : https://stackoverflow.com/questions/42946608/media-foundation-custom-mixer-mft-getting-error-mf-e-cannot-create-sink
26 |
27 | 
28 |
29 | ## EncodeWithSourceReaderSinkWriter
30 |
31 | Encode a video file using SourceReader and SinkWriter manually.
32 |
33 | stackoverflow question : https://stackoverflow.com/questions/55054531/media-foundation-video-re-encoding-producing-audio-stream-sync-offset
34 |
35 | ## FrameRateConverterDSP
36 |
37 | This program shows how to use the Frame Rate Converter DSP (CLSID_CFrameRateConvertDmo), using a Source Reader. You can change the frame rate of a video stream. For example, if the video has 30 fps, you can get 60 fps.
38 |
39 | stackoverflow question : https://stackoverflow.com/questions/8412343/how-to-use-frame-rate-convertor-dmo-in-mf-app
40 |
41 | ## IMFSinkWriterCallback
42 |
43 | This program shows how to use an IMFSinkWriterCallback and event to wait for the Finalize method on the Sink Writer. The program simply create a wmv video file with blue frames, using the Sink Writer.
44 |
45 | stackoverflow question : https://stackoverflow.com/questions/34189440/imfsinkwritercallback-never-happens
46 |
47 | 
48 |
49 | ## MFVideoCaptureEVR
50 |
51 | This program shows how to setup EVR (enhanced video renderer), and how to provide video capture samples to it, using a Source Reader.
52 | Same as MFVideoEVR, but with video capture card source.
53 |
54 | stackoverflow question : https://stackoverflow.com/questions/59616228/webcam-source-to-evr-sink
55 |
56 | ## MFVideoEVR
57 |
58 | This program shows how to setup EVR (enhanced video renderer), and how to provide video samples to it, using a Source Reader.
59 | Same as MFVideoCaptureEVR, but with video file source.
60 |
61 | stackoverflow question : https://stackoverflow.com/questions/32739558/media-foundation-evr-no-video-displaying
62 |
63 | ## MFMultiVideo
64 |
65 | A program to see if there are memory leaks using 1 to 16 MediaSession.
66 |
67 | stackoverflow question : https://stackoverflow.com/questions/58912803/media-foundation-multiple-videos-playback-results-in-memory-leak-crash-after-u
68 |
69 | 
70 |
71 | ## MinimalSinkRenderer
72 |
73 | This program shows the basic essentials for implementing a custom sink renderer, to be used by a Media Session. The stream sink format is MFVideoFormat_RGB32.
74 |
75 | You must register the MinimalSinkRenderer.dll with this command, and with the administrator rights : regsrv32 MinimalSinkRenderer.dll.
76 |
77 | stackoverflow question : https://stackoverflow.com/questions/52198300/how-to-have-custom-video-media-stream-sink-request-rgb32-frames-in-media-foundat
78 |
79 | ## ScreenCaptureEncode
80 |
81 | This program takes screenshots using Directx9, and create a mp4 video file with Mediafoundation API. In this example, the video duration is 5 seconds, see VIDEO_FRAME_COUNT to change it.
82 |
83 | stackoverflow question : https://stackoverflow.com/questions/33753912/directx-screen-capture-and-output-as-video
84 |
85 | 
86 |
87 | ## TranscodeMp4ToMp4
88 | This program transcode a mp4 video file into a new mp4 file, using mp4 Sink Writer and a Media Session with topology. There is no real encoding process, because output file has the same format as input file.
89 | The concept was to show how to setup IMFTopologyNode for both audio and video.
90 |
91 | stackoverflow question : https://stackoverflow.com/questions/52025546/configuring-the-mpeg4mediasink
92 |
93 | ## VideoStabilizationMFT
94 |
95 | Using the Video Stabilization MFT with Source Reader and Sink Writer.
96 |
97 | stackoverflow question : https://stackoverflow.com/questions/59471641/trying-to-use-a-mft-in-media-foundation-encoding
98 |
99 | ## WasapiCapture
100 |
101 | A program to capture sound with Wasapi, and record the captured audio in a wav file. Handle PCM format and Extensible Format.
102 |
103 | stackoverflow question : https://stackoverflow.com/questions/59483071/trying-to-create-a-wav-file-with-capturing-a-stream-from-win32-wasapi-c
104 |
--------------------------------------------------------------------------------
/ScreenCaptureEncode/ScreenCaptureEncode.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScreenCaptureEncode", "ScreenCaptureEncode.vcxproj", "{005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Debug|Win32.Build.0 = Debug|Win32
16 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Release|Win32.ActiveCfg = Release|Win32
17 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/ScreenCaptureEncode/ScreenCaptureEncode.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {005DA1A0-9F56-4F1D-980F-4EAB2AECFC08}
15 | Win32Proj
16 | ScreenCaptureEncode
17 | 10.0.15063.0
18 |
19 |
20 |
21 | Application
22 | true
23 | v141
24 | Unicode
25 |
26 |
27 | Application
28 | false
29 | v141
30 | true
31 | Unicode
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | true
45 |
46 |
47 | false
48 |
49 |
50 |
51 |
52 |
53 | Level3
54 | Disabled
55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
56 |
57 |
58 | Console
59 | true
60 |
61 |
62 |
63 |
64 | Level3
65 |
66 |
67 | MaxSpeed
68 | true
69 | true
70 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
71 |
72 |
73 | Console
74 | false
75 | true
76 | true
77 | UseLinkTimeCodeGeneration
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/TranscodeMp4ToMp4/TranscodeMp4ToMp4.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TranscodeMp4ToMp4", "TranscodeMp4ToMp4.vcxproj", "{77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Debug|x64.ActiveCfg = Debug|x64
17 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Debug|x64.Build.0 = Debug|x64
18 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Debug|x86.ActiveCfg = Debug|Win32
19 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Debug|x86.Build.0 = Debug|Win32
20 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Release|x64.ActiveCfg = Release|x64
21 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Release|x64.Build.0 = Release|x64
22 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Release|x86.ActiveCfg = Release|Win32
23 | {77A8C6AD-2FE2-4ADE-AEA9-EF76F8BBFF08}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {BB5E2610-EE74-40AD-852E-E315115C6537}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFGuid.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFGuid.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFGUID_H
5 | #define MFGUID_H
6 |
7 | // {B2F74C92-79DF-45DE-9C55-A99DE8276679}
8 | DEFINE_GUID(CLSID_CustomVideoMixer, 0xb2f74c92, 0x79df, 0x45de, 0x9c, 0x55, 0xa9, 0x9d, 0xe8, 0x27, 0x66, 0x79);
9 |
10 | //----------------------------------------------------------------------------------------------
11 | // Media subType guid
12 |
13 | // {7634706D-0000-0010-8000-00AA00389B71}
14 | DEFINE_GUID(MEDIASUBTYPE_mp4v, 0x7634706d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
15 |
16 | // 56564D41-0000-0010-8000-00AA00389B71
17 | DEFINE_GUID(MEDIASUBTYPE_XVID, 0x44495658, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
18 |
19 | // {64697678-0000-0010-8000-00AA00389B71}
20 | DEFINE_GUID(MEDIASUBTYPE_xvid, 0x64697678, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
21 |
22 | // {58564944-0000-0010-8000-00AA00389B71}
23 | DEFINE_GUID(MEDIASUBTYPE_DIVX, 0x58564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
24 |
25 | // {78766964-0000-0010-8000-00AA00389B71}
26 | DEFINE_GUID(MEDIASUBTYPE_divx, 0x78766964, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
27 |
28 | // {30355844-0000-0010-8000-00aa00389b71}
29 | DEFINE_GUID(MEDIASUBTYPE_DX50, 0x30355844, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
30 |
31 | // {30357864-0000-0010-8000-00AA00389B71}
32 | DEFINE_GUID(MEDIASUBTYPE_dx50, 0x30357864, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
33 |
34 | // {1D4A45F2-E5F6-4B44-8388-F0AE5C0E0C37}
35 | DEFINE_GUID(MEDIASUBTYPE_VIDEOIMAGE, 0x1D4A45F2, 0xE5F6, 0x4B44, 0x83, 0x88, 0xF0, 0xAE, 0x5C, 0x0E, 0x0C, 0x37);
36 |
37 | // {00000031-0000-0010-8000-00AA00389B71}
38 | DEFINE_GUID(MEDIASUBTYPE_GSM, 0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
39 |
40 | // {00000011-0000-0010-8000-00AA00389B71}
41 | DEFINE_GUID(MEDIASUBTYPE_IMAADPCMACM, 0x00000011, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
42 |
43 | #endif
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFLogCommon.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogCommon.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGCOMMON_H
5 | #define MFLOGCOMMON_H
6 |
7 | #if (_DEBUG && MF_USE_LOGGING)
8 |
9 | typedef LPCWSTR(*GetGUIDStringName)(const GUID&);
10 |
11 | inline void LogGuidHexa(const GUID& guid, const BOOL bFirst){
12 |
13 | HRESULT hr;
14 | WCHAR pBuffer[39] = {0};
15 |
16 | hr = StringCchPrintf(pBuffer, 39, L"{%.8lX-%.4hX-%.4hX-%.2hhX%.2hhX-%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX}",
17 | guid.Data1,
18 | guid.Data2,
19 | guid.Data3,
20 | guid.Data4[0],
21 | guid.Data4[1],
22 | guid.Data4[2],
23 | guid.Data4[3],
24 | guid.Data4[4],
25 | guid.Data4[5],
26 | guid.Data4[6],
27 | guid.Data4[7]
28 | );
29 |
30 | if(SUCCEEDED(hr)){
31 |
32 | if(bFirst)
33 | TRACE_NO_END_LINE((L"\t%s\t", pBuffer));
34 | else
35 | TRACE((L"%s", pBuffer));
36 | }
37 | else{
38 |
39 | TRACE((L"Guid problem"));
40 | }
41 | }
42 |
43 | inline void LogUINT32AsUINT64(const PROPVARIANT& var){
44 |
45 | UINT32 uHigh = 0, uLow = 0;
46 |
47 | Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
48 |
49 | TRACE((L"%u x %u", uHigh, uLow));
50 | }
51 |
52 | inline HRESULT SpecialCaseAttributeValue(GUID guid, const PROPVARIANT& var){
53 |
54 | if(guid == MF_MT_FRAME_RATE){
55 | LogUINT32AsUINT64(var);
56 | }
57 | else if(guid == MF_MT_FRAME_SIZE){
58 | LogUINT32AsUINT64(var);
59 | }
60 | else if(guid == MF_MT_PIXEL_ASPECT_RATIO){
61 | LogUINT32AsUINT64(var);
62 | }
63 | else{
64 | return S_FALSE;
65 | }
66 |
67 | return S_OK;
68 | }
69 |
70 | inline void LogPropertyVariant(const GUID* pGuid, const PROPVARIANT& var, GetGUIDStringName pGetGUIDString){
71 |
72 | HRESULT hr = S_FALSE;
73 |
74 | if(pGuid != NULL)
75 | hr = SpecialCaseAttributeValue(*pGuid, var);
76 |
77 | if(hr == S_FALSE){
78 |
79 | switch(var.vt){
80 |
81 | case VT_UI4:
82 | TRACE((L"%lu", var.ulVal));
83 | break;
84 |
85 | case VT_I4:
86 | TRACE((L"%ld", var.lVal));
87 | break;
88 |
89 | case VT_UI8:
90 | TRACE((L"%I64u", var.uhVal));
91 | break;
92 |
93 | case VT_BOOL:
94 | TRACE((L"%s", var.boolVal == -1 ? "true" : "false"));
95 | break;
96 |
97 | case VT_R8:
98 | TRACE((L"%f", var.dblVal));
99 | break;
100 |
101 | case VT_CLSID:
102 | {
103 | LPCWSTR pwszGuidName = pGetGUIDString(*var.puuid);
104 |
105 | if(pwszGuidName != NULL){
106 | TRACE((L"%s", pwszGuidName));
107 | }
108 | else{
109 | LogGuidHexa(*var.puuid, FALSE);
110 | }
111 | }
112 | break;
113 |
114 | case VT_LPWSTR:
115 | // Log : var.pwszVal
116 | TRACE((L"VT_LPWSTR = todo"));
117 | break;
118 |
119 | case VT_VECTOR | VT_UI1:
120 | TRACE((L"(VT_VECTOR|VT_UI1) = <>"));
121 | break;
122 |
123 | case VT_UNKNOWN:
124 | TRACE((L"VT_UNKNOWN = IUnknown"));
125 | break;
126 |
127 | case VT_EMPTY:
128 | TRACE((L"VT_EMPTY"));
129 | break;
130 |
131 | case VT_R4:
132 | TRACE((L"VT_R4 = %f", var.fltVal));
133 | break;
134 |
135 | // 8195 = VT_ARRAY | VT_I4
136 |
137 | default:
138 | TRACE((L"Unexpected attribute type (vt = %hu)", var.vt));
139 | break;
140 | }
141 | }
142 | }
143 |
144 | inline void LogAttributeValueByIndex(IMFAttributes* pAttributes, UINT32 uiIndex, GetGUIDStringName pGetGUIDString){
145 |
146 | HRESULT hr;
147 | PROPVARIANT var;
148 | GUID guid = GUID_NULL;
149 |
150 | PropVariantInit(&var);
151 |
152 | hr = pAttributes->GetItemByIndex(uiIndex, &guid, &var);
153 |
154 | if(SUCCEEDED(hr)){
155 |
156 | LPCWSTR pwszGUIDNameAttributes = pGetGUIDString(guid);
157 |
158 | if(pwszGUIDNameAttributes != NULL){
159 | TRACE_NO_END_LINE((L"\t%s\t", pwszGUIDNameAttributes));
160 | }
161 | else{
162 |
163 | LogGuidHexa(guid, TRUE);
164 | }
165 |
166 | LogPropertyVariant(&guid, var, pGetGUIDString);
167 | }
168 | else{
169 | TRACE((L"\tGetItemByIndex (Index = %u) hr = %s", uiIndex, MFErrorString(hr)));
170 | }
171 |
172 | PropVariantClear(&var);
173 | }
174 |
175 | #endif
176 |
177 | #endif
178 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(171);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #else
87 | #define TRACE_INIT()
88 | #define TRACE(x)
89 | #define TRACE_NO_END_LINE(x)
90 | #define TRACE_CLOSE()
91 | #define LOG_HRESULT(hr) hr
92 | #define LOG_LAST_ERROR()
93 | #endif
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | #ifndef IF_FAILED_RETURN
41 | #if(_DEBUG && MF_USE_LOGGING)
42 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); return hr; }
43 | #else
44 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ return hr; }
45 | #endif
46 | #endif
47 |
48 | #ifndef IF_FAILED_THROW
49 | #if(_DEBUG && MF_USE_LOGGING)
50 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); throw hr; }
51 | #else
52 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ throw hr; }
53 | #endif
54 | #endif
55 |
56 | #ifndef IF_ERROR_RETURN
57 | #if (_DEBUG && MF_USE_LOGGING)
58 | #define IF_ERROR_RETURN(b) if(b == FALSE){ LOG_LAST_ERROR(); return b; }
59 | #else
60 | #define IF_ERROR_RETURN(b) if(b == FALSE){ return b; }
61 | #endif
62 | #endif
63 |
64 | #ifndef CLOSE_HANDLE_IF
65 | #if (_DEBUG && MF_USE_LOGGING)
66 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ if(CloseHandle(h) == FALSE){ LOG_LAST_ERROR(); } h = INVALID_HANDLE_VALUE; }
67 | #else
68 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ CloseHandle(h); h = INVALID_HANDLE_VALUE; }
69 | #endif
70 | #endif
71 |
72 | #ifndef RETURN_STRING
73 | #define RETURN_STRING(x) case x: return L#x
74 | #endif
75 |
76 | #ifndef IF_EQUAL_RETURN
77 | #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
78 | #endif
79 |
80 | #ifndef VALUE_NOT_FOUND
81 | #define VALUE_NOT_FOUND(val) return L#val
82 | #endif
83 |
84 | #ifndef MIN
85 | #define MIN(a, b) (((a) < (b)) ? (a) : (b))
86 | #endif
87 |
88 | #endif
89 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/MFTime.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTime.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTIME_H
5 | #define MFTIME_H
6 |
7 | // One second in hns
8 | const MFTIME ONE_SECOND = 10000000;
9 |
10 | // One msec in hns
11 | const LONG ONE_MSEC = 1000;
12 |
13 | inline LONG MFTimeToMilliSec(const LONGLONG& time){
14 |
15 | return (LONG)(time / (ONE_SECOND / ONE_MSEC));
16 | }
17 |
18 | inline LONG MFTimeToSec(const LONGLONG& time){
19 |
20 | return (LONG)(time / ONE_SECOND);
21 | }
22 |
23 | #if (_DEBUG && MF_USE_LOGGING)
24 |
25 | inline void MFTimeString(const MFTIME& Duration){
26 |
27 | MFTIME DurationInMilliSec = 0;
28 | MFTIME DurationInSec = 0;
29 | MFTIME Hours = 0;
30 | MFTIME Minutes = 0;
31 | MFTIME Seconds = 0;
32 |
33 | DurationInSec = MFTimeToSec(Duration);
34 | DurationInMilliSec = MFTimeToMilliSec(Duration);
35 |
36 | if(DurationInSec > 60){
37 |
38 | Minutes = DurationInSec / 60;
39 |
40 | if(Minutes > 60){
41 |
42 | Hours = Minutes / 60;
43 | Minutes = Minutes % 60;
44 | }
45 |
46 | Seconds = (DurationInSec % 60);
47 | }
48 | else{
49 |
50 | Seconds = DurationInSec;
51 | }
52 |
53 | if(Seconds){
54 | DurationInMilliSec = DurationInMilliSec % (Seconds * ONE_MSEC);
55 | }
56 |
57 | TRACE((L"%02dh:%02dmn:%02ds:%03dms", (int)Hours, (int)Minutes, (int)Seconds, DurationInMilliSec));
58 | }
59 |
60 | #else
61 | #define MFTimeString(x)
62 | #endif
63 |
64 | #endif
--------------------------------------------------------------------------------
/VideoStabilizationMFT/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
--------------------------------------------------------------------------------
/VideoStabilizationMFT/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | #pragma comment(lib, "mf")
12 | #pragma comment(lib, "mfplat")
13 | #pragma comment(lib, "mfuuid")
14 | #pragma comment(lib, "mfreadwrite")
15 | #pragma comment(lib, "strmiids")
16 | #pragma comment(lib, "wmcodecdspuuid")
17 |
18 | //----------------------------------------------------------------------------------------------
19 | // Microsoft Windows SDK for Windows 7
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #ifdef _DEBUG
27 | #include
28 | #endif
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #pragma warning(push)
40 | #pragma warning(disable:4201)
41 | #include
42 | #pragma warning(pop)
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | //----------------------------------------------------------------------------------------------
49 | // Common Project Files
50 | #ifdef _DEBUG
51 | #define MF_USE_LOGGING 1
52 | #else
53 | #define MF_USE_LOGGING 0
54 | #endif
55 |
56 | #include "MFMacro.h"
57 | #include "MFTrace.h"
58 | #include "MFLogging.h"
59 | #include "MFTExternTrace.h"
60 | #include "MFGuid.h"
61 | #include "MFLogCommon.h"
62 | #include "MFLogMediaType.h"
63 | #include "MFTime.h"
64 |
65 | #endif
--------------------------------------------------------------------------------
/VideoStabilizationMFT/VideoStabilizationMFT.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoStabilizationMFT", "VideoStabilizationMFT.vcxproj", "{60D1E64A-55AB-482F-A523-FD02C5D00ACC}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Debug|x64.ActiveCfg = Debug|x64
17 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Debug|x64.Build.0 = Debug|x64
18 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Debug|x86.ActiveCfg = Debug|Win32
19 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Debug|x86.Build.0 = Debug|Win32
20 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Release|x64.ActiveCfg = Release|x64
21 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Release|x64.Build.0 = Release|x64
22 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Release|x86.ActiveCfg = Release|Win32
23 | {60D1E64A-55AB-482F-A523-FD02C5D00ACC}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {602CAF08-27F6-4E46-A576-1C00B673BB0A}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/VideoStabilizationMFT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers d%27en-tête
20 |
21 |
22 | Fichiers d%27en-tête
23 |
24 |
25 | Fichiers d%27en-tête
26 |
27 |
28 | Fichiers d%27en-tête
29 |
30 |
31 | Fichiers d%27en-tête
32 |
33 |
34 | Fichiers d%27en-tête
35 |
36 |
37 | Fichiers d%27en-tête
38 |
39 |
40 | Fichiers d%27en-tête
41 |
42 |
43 | Fichiers d%27en-tête
44 |
45 |
46 |
47 |
48 | Fichiers sources
49 |
50 |
51 | Fichiers sources
52 |
53 |
54 |
--------------------------------------------------------------------------------
/VideoStabilizationMFT/VideoStabilizationMFT.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/WasapiCapture/MFLogging.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFLogging.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFLOGGING_H
5 | #define MFLOGGING_H
6 |
7 | #ifdef _DEBUG
8 |
9 | class DebugLog{
10 |
11 | public:
12 |
13 | static void Initialize(){
14 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
15 | //_CrtSetBreakAlloc(171);
16 | }
17 |
18 | static void Trace(const WCHAR* sFormatString, ...){
19 |
20 | HRESULT hr = S_OK;
21 | va_list va;
22 |
23 | const DWORD TRACE_STRING_LEN = 512;
24 |
25 | WCHAR message[TRACE_STRING_LEN];
26 |
27 | va_start(va, sFormatString);
28 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
29 | va_end(va);
30 |
31 | if(SUCCEEDED(hr)){
32 |
33 | size_t size = _tcslen(message);
34 |
35 | if(size != 0 && size < TRACE_STRING_LEN){
36 | message[size] = '\n';
37 | message[size + 1] = '\0';
38 | }
39 |
40 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
41 | }
42 | }
43 |
44 | static void TraceNoEndLine(const WCHAR* sFormatString, ...){
45 |
46 | HRESULT hr = S_OK;
47 | va_list va;
48 |
49 | const DWORD TRACE_STRING_LEN = 512;
50 |
51 | WCHAR message[TRACE_STRING_LEN];
52 |
53 | va_start(va, sFormatString);
54 | hr = StringCchVPrintf(message, TRACE_STRING_LEN, sFormatString, va);
55 | va_end(va);
56 |
57 | if(SUCCEEDED(hr)){
58 |
59 | _CrtDbgReport(_CRT_WARN, NULL, NULL, NULL, "%S", message);
60 | }
61 | }
62 |
63 | static void Close(){
64 | int bLeak = _CrtDumpMemoryLeaks();
65 | assert(bLeak == FALSE);
66 | }
67 | };
68 |
69 | #define TRACE_INIT() DebugLog::Initialize()
70 | #define TRACE(x) DebugLog::Trace x
71 | #define TRACE_NO_END_LINE(x) DebugLog::TraceNoEndLine x
72 | #define TRACE_CLOSE() DebugLog::Close()
73 |
74 | inline HRESULT _LOG_HRESULT(HRESULT hr, const char* sFileName, long lLineNo){
75 |
76 | if(FAILED(hr)){
77 | TRACE((L"\n%S - Line: %d hr = %s\n", sFileName, lLineNo, MFErrorString(hr)));
78 | }
79 |
80 | return hr;
81 | }
82 |
83 | #define LOG_HRESULT(hr) _LOG_HRESULT(hr, __FILE__, __LINE__)
84 | #define LOG_LAST_ERROR() _LOG_HRESULT(HRESULT_FROM_WIN32(GetLastError()), __FILE__, __LINE__)
85 |
86 | #else
87 | #define TRACE_INIT()
88 | #define TRACE(x)
89 | #define TRACE_NO_END_LINE(x)
90 | #define TRACE_CLOSE()
91 | #define LOG_HRESULT(hr) hr
92 | #define LOG_LAST_ERROR()
93 | #endif
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/WasapiCapture/MFMacro.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFMacro.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFMACRO_H
5 | #define MFMACRO_H
6 |
7 | #ifndef MF_SAFE_RELEASE
8 | #define MF_SAFE_RELEASE
9 | template inline void SAFE_RELEASE(T*& p){
10 |
11 | if(p){
12 | p->Release();
13 | p = NULL;
14 | }
15 | }
16 | #endif
17 |
18 | #ifndef MF_SAFE_DELETE
19 | #define MF_SAFE_DELETE
20 | template inline void SAFE_DELETE(T*& p){
21 |
22 | if(p){
23 | delete p;
24 | p = NULL;
25 | }
26 | }
27 | #endif
28 |
29 | #ifndef MF_SAFE_DELETE_ARRAY
30 | #define MF_SAFE_DELETE_ARRAY
31 | template inline void SAFE_DELETE_ARRAY(T*& p){
32 |
33 | if(p){
34 | delete[] p;
35 | p = NULL;
36 | }
37 | }
38 | #endif
39 |
40 | #ifndef IF_FAILED_RETURN
41 | #if(_DEBUG && MF_USE_LOGGING)
42 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); return hr; }
43 | #else
44 | #define IF_FAILED_RETURN(X) if(FAILED(hr = (X))){ return hr; }
45 | #endif
46 | #endif
47 |
48 | #ifndef IF_FAILED_THROW
49 | #if(_DEBUG && MF_USE_LOGGING)
50 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ LOG_HRESULT(hr); throw hr; }
51 | #else
52 | #define IF_FAILED_THROW(X) if(FAILED(hr = (X))){ throw hr; }
53 | #endif
54 | #endif
55 |
56 | #ifndef IF_ERROR_RETURN
57 | #if (_DEBUG && MF_USE_LOGGING)
58 | #define IF_ERROR_RETURN(b) if(b == FALSE){ LOG_LAST_ERROR(); return b; }
59 | #else
60 | #define IF_ERROR_RETURN(b) if(b == FALSE){ return b; }
61 | #endif
62 | #endif
63 |
64 | #ifndef CLOSE_HANDLE_IF
65 | #if (_DEBUG && MF_USE_LOGGING)
66 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ if(CloseHandle(h) == FALSE){ LOG_LAST_ERROR(); } h = INVALID_HANDLE_VALUE; }
67 | #else
68 | #define CLOSE_HANDLE_IF(h) if(h != INVALID_HANDLE_VALUE){ CloseHandle(h); h = INVALID_HANDLE_VALUE; }
69 | #endif
70 | #endif
71 |
72 | #ifndef RETURN_STRING
73 | #define RETURN_STRING(x) case x: return L#x
74 | #endif
75 |
76 | #endif
77 |
--------------------------------------------------------------------------------
/WasapiCapture/MFTExternTrace.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFTExternTrace.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFTEXTERNTRACE_H
5 | #define MFTEXTERNTRACE_H
6 |
7 | // CExternTrace initializes the memory leaks detection (see "crtdbg.h").
8 | // CExternTrace ensures that no object is allocated before TRACE_INIT is called.
9 | // Because DllMain.cpp contains external objects, you will see "FAKE" memory leaks.
10 | #ifdef _DEBUG
11 |
12 | class CExternTrace{
13 |
14 | public:
15 |
16 | CExternTrace(){ TRACE_INIT(); };
17 | ~CExternTrace(){ TRACE_CLOSE(); };
18 | };
19 |
20 | CExternTrace cExternTrace;
21 |
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/WasapiCapture/MFWaveWriter.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFWaveWriter.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
5 |
6 | BOOL CMFWaveWriter::Initialize(const WCHAR* wszFile, const BOOL bExtensibleFormat)
7 | {
8 | BOOL bRet = FALSE;
9 | const UINT32 bHeaderLenght = bExtensibleFormat ? WAVE_HEAD_EXT_LEN : WAVE_HEAD_LEN;
10 | CLOSE_HANDLE_IF(m_hFile);
11 |
12 | m_hFile = CreateFile(wszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
13 |
14 | if(m_hFile == INVALID_HANDLE_VALUE)
15 | {
16 | IF_ERROR_RETURN(bRet);
17 | }
18 |
19 | BYTE WavHeader[WAVE_HEAD_EXT_LEN];
20 | memset(WavHeader, 0, sizeof(WavHeader));
21 |
22 | DWORD dwWritten;
23 |
24 | if(!WriteFile(m_hFile, (LPCVOID)WavHeader, bHeaderLenght, &dwWritten, 0) || dwWritten != bHeaderLenght)
25 | {
26 | IF_ERROR_RETURN(bRet);
27 | }
28 |
29 | return bRet = TRUE;
30 | }
31 |
32 | BOOL CMFWaveWriter::WriteWaveData(const BYTE* pData, const DWORD dwLength)
33 | {
34 | BOOL bRet = FALSE;
35 | DWORD dwWritten;
36 |
37 | if(!WriteFile(m_hFile, (LPCVOID)pData, dwLength, &dwWritten, 0) || dwWritten != dwLength)
38 | {
39 | IF_ERROR_RETURN(bRet);
40 | }
41 |
42 | return bRet = TRUE;
43 | }
44 |
45 | BOOL CMFWaveWriter::FinalizeHeader(WAVEFORMATEX* pwfx, const UINT32 uiFileLength, const BOOL bExtensibleFormat)
46 | {
47 | BOOL bRet = FALSE;
48 | DWORD dwMove;
49 | DWORD dwWritten;
50 | const UINT32 bHeaderLenght = bExtensibleFormat ? WAVE_HEAD_EXT_LEN : WAVE_HEAD_LEN;
51 |
52 | BYTE WavHeader[WAVE_HEAD_EXT_LEN];
53 | memset(WavHeader, 0, sizeof(WavHeader));
54 |
55 | if((dwMove = SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN)) == INVALID_SET_FILE_POINTER)
56 | {
57 | IF_ERROR_RETURN(bRet);
58 | }
59 |
60 | if(bExtensibleFormat)
61 | {
62 | if(!SetWaveHeaderExt(pwfx, uiFileLength, WavHeader))
63 | {
64 | IF_ERROR_RETURN(bRet);
65 | }
66 | }
67 | else
68 | {
69 | if(!SetWaveHeader(pwfx, uiFileLength, WavHeader))
70 | {
71 | IF_ERROR_RETURN(bRet);
72 | }
73 | }
74 |
75 | if(!WriteFile(m_hFile, (LPCVOID)WavHeader, bHeaderLenght, &dwWritten, 0) || dwWritten != bHeaderLenght)
76 | {
77 | IF_ERROR_RETURN(bRet);
78 | }
79 |
80 | return bRet = TRUE;
81 | }
82 |
83 | BOOL CMFWaveWriter::SetWaveHeaderExt(WAVEFORMATEX* pwfx, const UINT32 uiDataLen, BYTE* head)
84 | {
85 | if(uiDataLen == 0)
86 | return FALSE;
87 |
88 | assert((uiDataLen * pwfx->nBlockAlign) % 2 == 0);
89 |
90 | RIFFCHUNK* pch;
91 | RIFFLIST *priff;
92 | WAVEFORM_EXT *pwaveExt;
93 | FACT* pFact;
94 | WAVEFORMATEXTENSIBLE *pWaveFormatExtensible = reinterpret_cast(pwfx);
95 |
96 | priff = (RIFFLIST*)head;
97 | priff->fcc = SWAP32('RIFF');
98 |
99 | priff->cb = (uiDataLen * pwfx->nBlockAlign) + WAVE_HEAD_EXT_LEN - sizeof(RIFFCHUNK);
100 | priff->fccListType = SWAP32('WAVE');
101 |
102 | pwaveExt = (WAVEFORM_EXT*)(priff + 1);
103 | pwaveExt->fcc = SWAP32('fmt ');
104 | pwaveExt->cb = sizeof(WAVEFORM_EXT) - sizeof(RIFFCHUNK);
105 | pwaveExt->wFormatTag = pwfx->wFormatTag;
106 | pwaveExt->nChannels = pwfx->nChannels;
107 | pwaveExt->nSamplesPerSec = pwfx->nSamplesPerSec;
108 | pwaveExt->nAvgBytesPerSec = pwfx->nAvgBytesPerSec;
109 | pwaveExt->nBlockAlign = pwfx->nBlockAlign;
110 | pwaveExt->wBitsPerSample = pwfx->wBitsPerSample;
111 | pwaveExt->cbSize = pwfx->cbSize;
112 | pwaveExt->wValidBitsPerSample = pWaveFormatExtensible->Samples.wValidBitsPerSample;
113 | pwaveExt->dwChannelMask = pWaveFormatExtensible->dwChannelMask;
114 | pwaveExt->SubFormat = pWaveFormatExtensible->SubFormat;
115 |
116 | pFact = (FACT*)(pwaveExt + 1);
117 | pFact->fcc = SWAP32('fact');
118 | pFact->cb = 4;
119 | pFact->lenght = uiDataLen * pwaveExt->nChannels;
120 |
121 | pch = (RIFFCHUNK*)(pFact + 1);
122 | pch->fcc = SWAP32('data');
123 | pch->cb = (uiDataLen * pwfx->nBlockAlign);
124 |
125 | return TRUE;
126 | }
127 |
128 | BOOL CMFWaveWriter::SetWaveHeader(const WAVEFORMATEX* pwfx, const UINT32 uiDataLen, BYTE* head)
129 | {
130 | if(uiDataLen == 0)
131 | return FALSE;
132 |
133 | RIFFCHUNK* pch;
134 | RIFFLIST *priff;
135 | WAVEFORM *pwave;
136 |
137 | priff = (RIFFLIST*)head;
138 | priff->fcc = SWAP32('RIFF');
139 |
140 | priff->cb = (uiDataLen * pwfx->nBlockAlign) + WAVE_HEAD_LEN - sizeof(RIFFCHUNK);
141 | priff->fccListType = SWAP32('WAVE');
142 |
143 | pwave = (WAVEFORM*)(priff + 1);
144 | pwave->fcc = SWAP32('fmt ');
145 | pwave->cb = sizeof(WAVEFORM) - sizeof(RIFFCHUNK);
146 | pwave->wFormatTag = pwfx->wFormatTag;
147 | pwave->nChannels = pwfx->nChannels;
148 | pwave->nSamplesPerSec = pwfx->nSamplesPerSec;
149 | pwave->nAvgBytesPerSec = pwfx->nAvgBytesPerSec;
150 | pwave->nBlockAlign = pwfx->nBlockAlign;
151 | pwave->wBitsPerSample = pwfx->wBitsPerSample;
152 |
153 | pch = (RIFFCHUNK*)(pwave + 1);
154 | pch->fcc = SWAP32('data');
155 | pch->cb = (uiDataLen * pwfx->nBlockAlign);
156 |
157 | return TRUE;
158 | }
--------------------------------------------------------------------------------
/WasapiCapture/MFWaveWriter.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // MFWaveWriter.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef MFWAVEWRITER_H
5 | #define MFWAVEWRITER_H
6 |
7 | const UINT32 WAVE_HEAD_LEN = 44;
8 | const UINT32 WAVE_HEAD_EXT_LEN = 80;
9 |
10 | #define SWAP32(val) (UINT32)((((UINT32)(val)) & 0x000000FF)<<24 | (((UINT32)(val)) & 0x0000FF00)<<8 | (((UINT32)(val)) & 0x00FF0000)>>8 | (((UINT32)(val)) & 0xFF000000)>>24)
11 |
12 | #pragma pack(push, 1)
13 |
14 | struct RIFFCHUNK
15 | {
16 | UINT32 fcc;
17 | UINT32 cb;
18 | };
19 |
20 | struct RIFFLIST
21 | {
22 | UINT32 fcc;
23 | UINT32 cb;
24 | UINT32 fccListType;
25 |
26 | };
27 |
28 | struct WAVEFORM
29 | {
30 | UINT32 fcc;
31 | UINT32 cb;
32 | UINT16 wFormatTag;
33 | UINT16 nChannels;
34 | UINT32 nSamplesPerSec;
35 | UINT32 nAvgBytesPerSec;
36 | UINT16 nBlockAlign;
37 | UINT16 wBitsPerSample;
38 | };
39 |
40 | struct WAVEFORM_EXT : public WAVEFORM
41 | {
42 | UINT16 cbSize;
43 | UINT16 wValidBitsPerSample;
44 | UINT32 dwChannelMask;
45 | GUID SubFormat;
46 | };
47 |
48 | struct FACT
49 | {
50 | UINT32 fcc;
51 | UINT32 cb;
52 | UINT32 lenght;
53 |
54 | };
55 |
56 | #pragma pack(pop)
57 |
58 | class CMFWaveWriter
59 | {
60 | public:
61 |
62 | CMFWaveWriter() : m_hFile(INVALID_HANDLE_VALUE){}
63 | ~CMFWaveWriter(){ CLOSE_HANDLE_IF(m_hFile); }
64 |
65 | BOOL Initialize(const WCHAR*, const BOOL);
66 | BOOL WriteWaveData(const BYTE*, const DWORD);
67 | BOOL FinalizeHeader(WAVEFORMATEX*, const UINT32, const BOOL);
68 |
69 | private:
70 |
71 | HANDLE m_hFile;
72 |
73 | BOOL SetWaveHeader(const WAVEFORMATEX*, const UINT32, BYTE*);
74 | BOOL SetWaveHeaderExt(WAVEFORMATEX*, const UINT32, BYTE*);
75 | };
76 |
77 | #endif
--------------------------------------------------------------------------------
/WasapiCapture/Main.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // Main.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "Stdafx.h"
5 |
6 | #define AUDIO_CAPTURE_FILE L"Capture.wav"
7 | #define REFTIMES_PER_SEC 10000000
8 | #define REFTIMES_PER_MILLISEC 10000
9 | #define MAX_LOOP_BEFORE_STOP 20
10 |
11 | const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
12 | const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
13 | const IID IID_IAudioClient = __uuidof(IAudioClient);
14 | const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
15 |
16 | HRESULT RecordAudioStream();
17 |
18 | void main()
19 | {
20 | HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
21 |
22 | if(SUCCEEDED(hr))
23 | {
24 | LOG_HRESULT(RecordAudioStream());
25 |
26 | CoUninitialize();
27 | }
28 | }
29 |
30 | HRESULT RecordAudioStream()
31 | {
32 | HRESULT hr = S_OK;
33 | IMMDeviceEnumerator* pEnumerator = NULL;
34 | IMMDevice* pDevice = NULL;
35 | IAudioClient* pAudioClient = NULL;
36 | IAudioCaptureClient* pCaptureClient = NULL;
37 | WAVEFORMATEX* pwfx = NULL;
38 | REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
39 | REFERENCE_TIME hnsActualDuration;
40 | UINT32 bufferFrameCount;
41 | CMFWaveWriter cMFWaveWriter;
42 | UINT32 uiFileLength = 0;
43 | BOOL bExtensibleFormat = FALSE;
44 |
45 | try
46 | {
47 | IF_FAILED_THROW(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator));
48 | IF_FAILED_THROW(pEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice));
49 | IF_FAILED_THROW(pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient));
50 |
51 | IF_FAILED_THROW(pAudioClient->GetMixFormat(&pwfx));
52 |
53 | switch(pwfx->wFormatTag)
54 | {
55 | case WAVE_FORMAT_PCM:
56 | TRACE((L"WAVE_FORMAT_PCM"));
57 | break;
58 |
59 | case WAVE_FORMAT_IEEE_FLOAT:
60 | TRACE((L"WAVE_FORMAT_IEEE_FLOAT"));
61 | break;
62 |
63 | case WAVE_FORMAT_EXTENSIBLE:
64 | TRACE((L"WAVE_FORMAT_EXTENSIBLE"));
65 | bExtensibleFormat = TRUE;
66 |
67 | WAVEFORMATEXTENSIBLE *pWaveFormatExtensible = reinterpret_cast(pwfx);
68 |
69 | if(pWaveFormatExtensible->SubFormat == KSDATAFORMAT_SUBTYPE_PCM)
70 | {
71 | TRACE((L"KSDATAFORMAT_SUBTYPE_PCM"));
72 | }
73 | else if(pWaveFormatExtensible->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)
74 | {
75 | TRACE((L"KSDATAFORMAT_SUBTYPE_IEEE_FLOAT"));
76 | }
77 | break;
78 | }
79 |
80 | IF_FAILED_THROW(pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, hnsRequestedDuration, 0, pwfx, NULL));
81 | IF_FAILED_THROW(pAudioClient->GetBufferSize(&bufferFrameCount));
82 | IF_FAILED_THROW(pAudioClient->GetService(IID_IAudioCaptureClient, (void**)&pCaptureClient));
83 |
84 | IF_FAILED_THROW(cMFWaveWriter.Initialize(AUDIO_CAPTURE_FILE, bExtensibleFormat) ? S_OK : E_FAIL);
85 |
86 | hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;
87 |
88 | IF_FAILED_THROW(pAudioClient->Start());
89 |
90 | BOOL bDone = FALSE;
91 | UINT32 packetLength = 0;
92 | UINT32 numFramesAvailable;
93 | BYTE* pData;
94 | DWORD flags;
95 | int iLoop = 0;
96 |
97 | while(bDone == FALSE)
98 | {
99 | Sleep(hnsActualDuration / REFTIMES_PER_MILLISEC / 2);
100 |
101 | IF_FAILED_THROW(pCaptureClient->GetNextPacketSize(&packetLength));
102 |
103 | while(packetLength != 0)
104 | {
105 | IF_FAILED_THROW(pCaptureClient->GetBuffer(&pData, &numFramesAvailable, &flags, NULL, NULL));
106 |
107 | if(flags & AUDCLNT_BUFFERFLAGS_SILENT)
108 | {
109 | TRACE((L"AUDCLNT_BUFFERFLAGS_SILENT"));
110 | break;
111 | }
112 |
113 | if(flags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY)
114 | {
115 | TRACE((L"AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY"));
116 | }
117 |
118 | if(flags & AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR)
119 | {
120 | TRACE((L"AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR"));
121 | }
122 |
123 | //TRACE((L"numFramesAvailable : %u", numFramesAvailable));
124 |
125 | assert(packetLength == numFramesAvailable);
126 |
127 | IF_FAILED_THROW(cMFWaveWriter.WriteWaveData(pData, numFramesAvailable * pwfx->nBlockAlign) ? S_OK : E_FAIL);
128 |
129 | uiFileLength += numFramesAvailable;
130 |
131 | IF_FAILED_THROW(pCaptureClient->ReleaseBuffer(numFramesAvailable));
132 |
133 | IF_FAILED_THROW(pCaptureClient->GetNextPacketSize(&packetLength));
134 | }
135 |
136 | if(iLoop++ == MAX_LOOP_BEFORE_STOP)
137 | bDone = TRUE;
138 | }
139 | }
140 | catch(HRESULT){}
141 |
142 | TRACE((L"uiFileLength : %u", uiFileLength));
143 |
144 | if(hr == S_OK && pwfx != NULL)
145 | cMFWaveWriter.FinalizeHeader(pwfx, uiFileLength, bExtensibleFormat);
146 |
147 | if(pAudioClient)
148 | {
149 | LOG_HRESULT(pAudioClient->Stop());
150 | SAFE_RELEASE(pAudioClient);
151 | }
152 |
153 | CoTaskMemFree(pwfx);
154 | SAFE_RELEASE(pCaptureClient);
155 | SAFE_RELEASE(pEnumerator);
156 | SAFE_RELEASE(pDevice);
157 |
158 | return hr;
159 | }
--------------------------------------------------------------------------------
/WasapiCapture/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.cpp
3 | //----------------------------------------------------------------------------------------------
4 | #include "StdAfx.h"
--------------------------------------------------------------------------------
/WasapiCapture/StdAfx.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------------------------
2 | // StdAfx.h
3 | //----------------------------------------------------------------------------------------------
4 | #ifndef STDAFX_H
5 | #define STDAFX_H
6 |
7 | #pragma once
8 | #define WIN32_LEAN_AND_MEAN
9 | #define STRICT
10 |
11 | //----------------------------------------------------------------------------------------------
12 | // Microsoft Windows SDK for Windows 7
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #ifdef _DEBUG
20 | #include
21 | #endif
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #pragma warning(push)
33 | #pragma warning(disable:4201)
34 | #include
35 | #pragma warning(pop)
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 | //----------------------------------------------------------------------------------------------
44 | // Common Project Files
45 | #ifdef _DEBUG
46 | #define MF_USE_LOGGING 1
47 | #else
48 | #define MF_USE_LOGGING 0
49 | #endif
50 |
51 | #include "MFMacro.h"
52 | #include "MFTrace.h"
53 | #include "MFLogging.h"
54 | #include "MFTExternTrace.h"
55 | #include "MFWaveWriter.h"
56 |
57 | #endif
--------------------------------------------------------------------------------
/WasapiCapture/WasapiCapture.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2037
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WasapiCapture", "WasapiCapture.vcxproj", "{CD9AB404-9765-487C-8718-AC7F710D0663}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Debug|x64.ActiveCfg = Debug|x64
17 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Debug|x64.Build.0 = Debug|x64
18 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Debug|x86.ActiveCfg = Debug|Win32
19 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Debug|x86.Build.0 = Debug|Win32
20 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Release|x64.ActiveCfg = Release|x64
21 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Release|x64.Build.0 = Release|x64
22 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Release|x86.ActiveCfg = Release|Win32
23 | {CD9AB404-9765-487C-8718-AC7F710D0663}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {F4F8E561-87BC-44BC-8C6A-341B7BEDF42D}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/WasapiCapture/WasapiCapture.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Fichiers sources
20 |
21 |
22 | Fichiers sources
23 |
24 |
25 | Fichiers sources
26 |
27 |
28 |
29 |
30 | Fichiers d%27en-tête
31 |
32 |
33 | Fichiers d%27en-tête
34 |
35 |
36 | Fichiers d%27en-tête
37 |
38 |
39 | Fichiers d%27en-tête
40 |
41 |
42 | Fichiers d%27en-tête
43 |
44 |
45 | Fichiers d%27en-tête
46 |
47 |
48 |
--------------------------------------------------------------------------------
/WasapiCapture/WasapiCapture.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------