1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2017 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // A permission to use the source code is granted as long as reference to |
---|
6 | // source website http://alax.info is retained. |
---|
7 | |
---|
8 | #pragma once |
---|
9 | |
---|
10 | #include "rodshow.h" |
---|
11 | #include "romf.h" |
---|
12 | #include "rod3d11.h" |
---|
13 | |
---|
14 | //////////////////////////////////////////////////////////// |
---|
15 | // CModule |
---|
16 | |
---|
17 | class CModule : |
---|
18 | public CAtlExeModuleT<CModule> |
---|
19 | { |
---|
20 | public: |
---|
21 | |
---|
22 | public: |
---|
23 | static CEvent g_TerminationEvent; |
---|
24 | |
---|
25 | public: |
---|
26 | // CModule |
---|
27 | CModule() |
---|
28 | { |
---|
29 | AtlTraceSetDefaultSettings(); |
---|
30 | _Z4_THIS(); |
---|
31 | //_W(CExceptionFilter::Initialize()); |
---|
32 | } |
---|
33 | ~CModule() |
---|
34 | { |
---|
35 | _Z4_THIS(); |
---|
36 | //CExceptionFilter::Terminate(); |
---|
37 | } |
---|
38 | bool ParseCommandLine(LPCTSTR pszCommandLine, HRESULT* pnResult) |
---|
39 | { |
---|
40 | _A(pnResult); |
---|
41 | _ATLTRY |
---|
42 | { |
---|
43 | CCommandLineArguments Arguments(pszCommandLine); |
---|
44 | CCommandLineArguments::CArgument Argument; |
---|
45 | while(Arguments.Next(Argument)) |
---|
46 | { |
---|
47 | __D(!Argument.m_bSwitch, E_UNNAMED); |
---|
48 | #pragma region help |
---|
49 | if(Argument.m_sValue.CompareNoCase(_T("help")) == 0) |
---|
50 | { |
---|
51 | _tprintf( |
---|
52 | _T("Syntax: %s argument [argument...]") _T("\n") |
---|
53 | _T("\n") |
---|
54 | _T("Arguments:") _T("\n") |
---|
55 | _T("\t") _T("help - displays syntax") _T("\n"), |
---|
56 | FindFileName(GetModulePath())); |
---|
57 | return false; |
---|
58 | } else |
---|
59 | #pragma endregion |
---|
60 | __C(E_UNNAMED); |
---|
61 | } |
---|
62 | } |
---|
63 | _ATLCATCH(Exception) |
---|
64 | { |
---|
65 | *pnResult = Exception; |
---|
66 | return false; |
---|
67 | } |
---|
68 | *pnResult = S_OK; |
---|
69 | return true; |
---|
70 | } |
---|
71 | HRESULT PreMessageLoop(INT nShowCommand) |
---|
72 | { |
---|
73 | const HRESULT nResult = __super::PreMessageLoop(nShowCommand); |
---|
74 | return SUCCEEDED(nResult) ? S_OK : nResult; |
---|
75 | } |
---|
76 | BOOL InternalHandlerRoutine(DWORD nType) |
---|
77 | { |
---|
78 | _W(g_TerminationEvent.Set()); |
---|
79 | return TRUE; |
---|
80 | } |
---|
81 | static BOOL WINAPI HandlerRoutine(DWORD nType) |
---|
82 | { |
---|
83 | return static_cast<CModule*>(_pAtlModule)->InternalHandlerRoutine(nType); |
---|
84 | } |
---|
85 | VOID ProcessTransform(ID3D11Device* pDevice, const CComPtr<IMFTransform>& pTransform) |
---|
86 | { |
---|
87 | _A(pTransform); |
---|
88 | MF::CAttributes pAttributes; |
---|
89 | __C(pTransform->GetAttributes(&pAttributes)); |
---|
90 | pAttributes.Trace(); |
---|
91 | pAttributes[MF_TRANSFORM_ASYNC_UNLOCK] = (UINT32) 1; |
---|
92 | if(pDevice) |
---|
93 | { |
---|
94 | MF::CDxgiDeviceManager pDxgiDeviceManager; |
---|
95 | pDxgiDeviceManager.Create(); |
---|
96 | pDxgiDeviceManager.Reset(pDevice); |
---|
97 | __C(pTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR) (IMFDXGIDeviceManager*) pDxgiDeviceManager)); |
---|
98 | } |
---|
99 | #pragma region Output Media Type |
---|
100 | // Video Media Types https://msdn.microsoft.com/en-us/library/windows/desktop/aa473818 |
---|
101 | MF::CMediaType pOutputMediaType; |
---|
102 | pOutputMediaType.Create(); |
---|
103 | pOutputMediaType[MF_MT_MAJOR_TYPE] = MFMediaType_Video; |
---|
104 | pOutputMediaType[MF_MT_SUBTYPE] = MFVideoFormat_H264; |
---|
105 | pOutputMediaType[MF_MT_FRAME_SIZE].SetSize(1280, 720); |
---|
106 | pOutputMediaType[MF_MT_PIXEL_ASPECT_RATIO].SetRatio(1, 1); |
---|
107 | pOutputMediaType[MF_MT_INTERLACE_MODE] = (UINT32) MFVideoInterlace_Progressive; |
---|
108 | pOutputMediaType[MF_MT_FRAME_RATE].SetRatio(60000, 1001); |
---|
109 | pOutputMediaType[MF_MT_AVG_BITRATE] = (UINT32) ((5 << 10) * 1000); |
---|
110 | __C(pTransform->SetOutputType(0, pOutputMediaType, 0)); |
---|
111 | #pragma endregion |
---|
112 | #pragma region Available Input Media Type |
---|
113 | for(DWORD nTypeIndex = 0; ; nTypeIndex++) |
---|
114 | { |
---|
115 | MF::CMediaType pMediaType; |
---|
116 | if(FAILED(pTransform->GetInputAvailableType(0, nTypeIndex, &pMediaType))) |
---|
117 | break; |
---|
118 | pMediaType.Trace(); |
---|
119 | } |
---|
120 | #pragma endregion |
---|
121 | #pragma region Input Media Type |
---|
122 | // NOTE: Uncompressed Video Media Types https://msdn.microsoft.com/en-us/library/windows/desktop/ff485865 |
---|
123 | MF::CMediaType pInputMediaType; |
---|
124 | pInputMediaType.Create(); |
---|
125 | pInputMediaType[MF_MT_MAJOR_TYPE] = MFMediaType_Video; |
---|
126 | pInputMediaType[MF_MT_SUBTYPE] = MFVideoFormat_NV12; |
---|
127 | pInputMediaType[MF_MT_FRAME_SIZE] = pOutputMediaType.GetUINT64(MF_MT_FRAME_SIZE); |
---|
128 | pInputMediaType[MF_MT_PIXEL_ASPECT_RATIO] = pOutputMediaType.GetUINT64(MF_MT_PIXEL_ASPECT_RATIO); |
---|
129 | pInputMediaType[MF_MT_INTERLACE_MODE] = (UINT32) MFVideoInterlace_Progressive; |
---|
130 | pInputMediaType[MF_MT_FRAME_RATE] = pOutputMediaType.GetUINT64(MF_MT_FRAME_RATE); |
---|
131 | __C(pTransform->SetInputType(0, pInputMediaType, 0)); |
---|
132 | #pragma endregion |
---|
133 | #pragma region Actual Input Media Type |
---|
134 | MFT_INPUT_STREAM_INFO InputStreamInformation; |
---|
135 | __C(pTransform->GetInputStreamInfo(0, &InputStreamInformation)); |
---|
136 | #pragma endregion |
---|
137 | #pragma region Actual Output Media Type |
---|
138 | { |
---|
139 | MF::CMediaType pOutputMediaType; |
---|
140 | __C(pTransform->GetOutputCurrentType(0, &pOutputMediaType)); |
---|
141 | pOutputMediaType.Trace(); |
---|
142 | _tprintf(_T("MF_MT_MPEG_SEQUENCE_HEADER: %d\n"), pOutputMediaType.GetType(MF_MT_MPEG_SEQUENCE_HEADER)); |
---|
143 | } |
---|
144 | MFT_OUTPUT_STREAM_INFO OutputStreamInformation; |
---|
145 | __C(pTransform->GetOutputStreamInfo(0, &OutputStreamInformation)); |
---|
146 | _A(OutputStreamInformation.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)); |
---|
147 | #pragma endregion |
---|
148 | __C(pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0)); |
---|
149 | __C(pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0)); |
---|
150 | } |
---|
151 | VOID RunMessageLoop() |
---|
152 | { |
---|
153 | MF::CStartup Startup; |
---|
154 | MFT_REGISTER_TYPE_INFO Information = { MFMediaType_Video, MFVideoFormat_H264 }; |
---|
155 | CComHeapPtr<IMFActivate*> ppActivates; |
---|
156 | UINT32 nActivateCount = 0; |
---|
157 | __C(MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, MFT_ENUM_FLAG_HARDWARE, NULL, &Information, &ppActivates, &nActivateCount)); |
---|
158 | if(!nActivateCount) |
---|
159 | return; |
---|
160 | MF::CActivateArray ActivateArray; |
---|
161 | ActivateArray.SetCount(nActivateCount); |
---|
162 | memcpy(ActivateArray.GetData(), ppActivates, nActivateCount * sizeof *ppActivates); |
---|
163 | #pragma region DXGI |
---|
164 | DXGI::CFactory2 pFactory2; |
---|
165 | CRoArrayT<DXGI::CAdapter1> AdapterArray; |
---|
166 | { |
---|
167 | UINT nFlags = 0; |
---|
168 | #if defined(_DEBUG) |
---|
169 | nFlags |= DXGI_CREATE_FACTORY_DEBUG; |
---|
170 | #endif // defined(_DEBUG) |
---|
171 | __C(CreateDXGIFactory2(nFlags, __uuidof(IDXGIFactory2), (VOID**) &pFactory2.m_p)); |
---|
172 | for(UINT nAdapterIndex = 0; ; nAdapterIndex++) |
---|
173 | { |
---|
174 | DXGI::CAdapter1 pAdapter1; |
---|
175 | const HRESULT nResult = pFactory2->EnumAdapters1(nAdapterIndex, &pAdapter1.m_p); |
---|
176 | _Z45_MFHRESULT(nResult); |
---|
177 | if(FAILED(nResult)) |
---|
178 | break; |
---|
179 | pAdapter1.Trace(); |
---|
180 | //DXGI_ADAPTER_DESC1 Description; |
---|
181 | //__C(pAdapter1->GetDesc1(&Description)); |
---|
182 | //if(Description.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) |
---|
183 | // continue; |
---|
184 | AdapterArray.Add(pAdapter1); |
---|
185 | } |
---|
186 | } |
---|
187 | #pragma endregion |
---|
188 | for(auto&& pActivate: ActivateArray) |
---|
189 | { |
---|
190 | pActivate.Trace(); |
---|
191 | //if(pActivate.GetString(MFT_FRIENDLY_NAME_Attribute).Find(L"Quick Sync Video H.264 Encoder MFT") < 0) |
---|
192 | // continue; |
---|
193 | _tprintf(_T("Friendly Name: %ls\n"), (LPCWSTR) pActivate.GetString(MFT_FRIENDLY_NAME_Attribute)); |
---|
194 | _tprintf(_T("\n")); |
---|
195 | const CLSID ClassIdentifier = pActivate.GetGUID(MFT_TRANSFORM_CLSID_Attribute); |
---|
196 | for(SIZE_T nIndex = 0; ; nIndex++) |
---|
197 | { |
---|
198 | _ATLTRY |
---|
199 | { |
---|
200 | CComPtr<ID3D11Device> pDevice; |
---|
201 | CComPtr<ID3D11DeviceContext> pDeviceContext; |
---|
202 | if(nIndex >= 1) |
---|
203 | { |
---|
204 | if(nIndex - 1 >= AdapterArray.GetCount()) |
---|
205 | break; |
---|
206 | DXGI::CAdapter1& pAdapter1 = AdapterArray[nIndex - 1]; |
---|
207 | DXGI_ADAPTER_DESC1 Description; |
---|
208 | __C(pAdapter1->GetDesc1(&Description)); |
---|
209 | //if(CStringW(Description.Description).Find(L" Intel(R) HD Graphics") < 0) |
---|
210 | // continue; |
---|
211 | _tprintf(_T("Adapter Description: %ls\n"), Description.Description); |
---|
212 | _tprintf(_T("\n")); |
---|
213 | UINT nFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; |
---|
214 | #if defined(_DEBUG) |
---|
215 | nFlags |= D3D11_CREATE_DEVICE_DEBUG; |
---|
216 | #endif // defined(_DEBUG) |
---|
217 | static const D3D_FEATURE_LEVEL g_pFeatureLevels[] = |
---|
218 | { |
---|
219 | D3D_FEATURE_LEVEL_12_1, |
---|
220 | D3D_FEATURE_LEVEL_12_0, |
---|
221 | D3D_FEATURE_LEVEL_11_1, |
---|
222 | D3D_FEATURE_LEVEL_11_0, |
---|
223 | D3D_FEATURE_LEVEL_10_1, |
---|
224 | D3D_FEATURE_LEVEL_10_0, |
---|
225 | D3D_FEATURE_LEVEL_9_3, |
---|
226 | D3D_FEATURE_LEVEL_9_2, |
---|
227 | D3D_FEATURE_LEVEL_9_1, |
---|
228 | }; |
---|
229 | D3D_FEATURE_LEVEL FeatureLevel; |
---|
230 | __C(D3D11CreateDevice(pAdapter1, D3D_DRIVER_TYPE_UNKNOWN, NULL, nFlags, g_pFeatureLevels, DIM(g_pFeatureLevels), D3D11_SDK_VERSION, &pDevice, &FeatureLevel, &pDeviceContext)); |
---|
231 | } |
---|
232 | _ATLTRY |
---|
233 | { |
---|
234 | ProcessTransform(pDevice, pActivate.Activate<IMFTransform>()); |
---|
235 | } |
---|
236 | _ATLCATCH(Exception) |
---|
237 | { |
---|
238 | _Z_ATLEXCEPTION(Exception); |
---|
239 | _tprintf(_T("Exception: %s\n"), (LPCTSTR) MF::FormatResult(Exception, _T("Error 0x%08X"))); |
---|
240 | } |
---|
241 | _tprintf(_T("\n")); |
---|
242 | _ATLTRY |
---|
243 | { |
---|
244 | CComPtr<IMFTransform> pTransform; |
---|
245 | __C(pTransform.CoCreateInstance(ClassIdentifier)); |
---|
246 | ProcessTransform(pDevice, pTransform); |
---|
247 | } |
---|
248 | _ATLCATCH(Exception) |
---|
249 | { |
---|
250 | _Z_ATLEXCEPTION(Exception); |
---|
251 | _tprintf(_T("Exception: %s\n"), (LPCTSTR) MF::FormatResult(Exception, _T("Error 0x%08X"))); |
---|
252 | } |
---|
253 | _tprintf(_T("\n")); |
---|
254 | } |
---|
255 | _ATLCATCHALL() |
---|
256 | { |
---|
257 | _Z_EXCEPTION(); |
---|
258 | } |
---|
259 | } |
---|
260 | } |
---|
261 | } |
---|
262 | }; |
---|
263 | |
---|
264 | __declspec(selectany) CEvent CModule::g_TerminationEvent; |
---|
265 | |
---|