source: trunk/Utilities/MediaFoundation/HardwareEncoderMediaType01/Module.h @ 759

Last change on this file since 759 was 759, checked in by roman, 6 years ago
File size: 8.8 KB
Line 
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
17class CModule :
18        public CAtlExeModuleT<CModule>
19{
20public:
21
22public:
23        static CEvent g_TerminationEvent;
24
25public:
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
Note: See TracBrowser for help on using the repository browser.