source: trunk/Utilities/MediaFoundation/VideoProcessor01/Module.h @ 937

Last change on this file since 937 was 651, checked in by roman, 6 years ago
File size: 7.8 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2016
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
13////////////////////////////////////////////////////////////
14// CModule
15
16class CModule :
17        public CAtlExeModuleT<CModule>
18{
19public:
20
21public:
22        static CEvent g_TerminationEvent;
23        CString m_sVideoIdentifier;
24        UINT32 m_nBitrate;
25        CString m_sAudioIdentifier;
26        UINT m_nDuration;
27
28public:
29// CModule
30        CModule()
31        {
32                AtlTraceSetDefaultSettings();
33                _Z4_THIS();
34                //_W(CExceptionFilter::Initialize());
35                m_nBitrate = 0;
36                m_nDuration = 10;
37        }
38        ~CModule()
39        {
40                _Z4_THIS();
41                //CExceptionFilter::Terminate();
42        }
43        bool ParseCommandLine(LPCTSTR pszCommandLine, HRESULT* pnResult)
44        {
45                _A(pnResult);
46                _ATLTRY
47                {
48                        CCommandLineArguments Arguments(pszCommandLine);
49                        CCommandLineArguments::CArgument Argument;
50                        while(Arguments.Next(Argument))
51                        {
52                                __D(!Argument.m_bSwitch, E_UNNAMED);
53                                #pragma region help
54                                if(Argument.m_sValue.CompareNoCase(_T("help")) == 0)
55                                {
56                                        _tprintf(
57                                                _T("Syntax: %s argument [argument...]") _T("\n")
58                                                _T("\n")
59                                                _T("Arguments:") _T("\n")
60                                                _T("\t") _T("help - displays syntax") _T("\n"),
61                                                FindFileName(GetModulePath()));
62                                        return false;
63                                } else
64                                #pragma endregion
65                                        __C(E_UNNAMED);
66                        }
67                }
68                _ATLCATCH(Exception)
69                {
70                        *pnResult = Exception;
71                        return false;
72                }
73                *pnResult = S_OK;
74                return true;
75        }
76        HRESULT PreMessageLoop(INT nShowCommand)
77        {
78                const HRESULT nResult = __super::PreMessageLoop(nShowCommand);
79                return SUCCEEDED(nResult) ? S_OK : nResult;
80        }
81        BOOL InternalHandlerRoutine(DWORD nType)
82        {
83                _W(g_TerminationEvent.Set());
84                return TRUE;
85        }
86        static BOOL WINAPI HandlerRoutine(DWORD nType)
87        {
88                return static_cast<CModule*>(_pAtlModule)->InternalHandlerRoutine(nType);
89        }
90        VOID ProcessInput(const CComPtr<IMFTransform>& pTransform, const MFT_INPUT_STREAM_INFO& InputStreamInformation, LONGLONG nSampleDuration, UINT nSampleIndex)
91        {
92                _A(pTransform);
93                MF::CSample pSample;
94                pSample.Create();
95                CComPtr<IMFMediaBuffer> pMediaBuffer;
96                __C(MFCreateMemoryBuffer(InputStreamInformation.cbSize, &pMediaBuffer));
97                __C(pMediaBuffer->SetCurrentLength(InputStreamInformation.cbSize));
98                __C(pSample->AddBuffer(pMediaBuffer));
99                const LONGLONG nTime = nSampleIndex * nSampleDuration;
100                __C(pSample->SetSampleTime(nTime));
101                __C(pSample->SetSampleDuration(1)); //nSampleDuration));
102                pSample[MFSampleExtension_CleanPoint] = (UINT32) 1;
103                pSample[MFSampleExtension_Discontinuity] = (UINT32) (!nTime ? 1 : 0);
104                pSample.Trace();
105                for(; ; )
106                {
107                        const HRESULT nProcessInputResult = pTransform->ProcessInput(0, pSample, 0);
108                        _Z45_MFHRESULT(nProcessInputResult);
109                        _tprintf(_T("Line %d: nTime %s, nProcessInputResult %s\n"), __LINE__, (LPCTSTR) MF::FormatNanoTime(nTime), (LPCTSTR) MF::FormatResult(nProcessInputResult));
110                        if(nProcessInputResult == MF_E_NOTACCEPTING)
111                        {
112                                Sleep(200);
113                                continue;
114                        }
115                        if(nProcessInputResult == S_OK)
116                                break;
117                        __C(nProcessInputResult);
118                }
119        }
120        VOID ProcessOutput(const CComPtr<IMFTransform>& pTransform, const MFT_OUTPUT_STREAM_INFO& OutputStreamInformation, UINT nAttemptCount = 1)
121        {
122                _A(pTransform);
123                MF::CSample pSample;
124                pSample.Create();
125                CComPtr<IMFMediaBuffer> pMediaBuffer;
126                __C(MFCreateMemoryBuffer(OutputStreamInformation.cbSize, &pMediaBuffer));
127                __C(pSample->AddBuffer(pMediaBuffer));
128                for(UINT nAttemptIndex = 0; nAttemptIndex < nAttemptCount; nAttemptIndex++)
129                {
130                        MFT_OUTPUT_DATA_BUFFER Buffer = { 0 };
131                        Buffer.pSample = pSample;
132                        DWORD nStatus = 0;
133                        HRESULT nProcessOutputResult = pTransform->ProcessOutput(0, 1, &Buffer, &nStatus);
134                        _Z4_MFHRESULT(nProcessOutputResult);
135                        _tprintf(_T("Line %d: nProcessOutputResult %s\n"), __LINE__, (LPCTSTR) MF::FormatResult(nProcessOutputResult));
136                        if(nProcessOutputResult == MF_E_TRANSFORM_NEED_MORE_INPUT)
137                        {
138                                Sleep(200);
139                                continue;
140                        }
141                        if(nProcessOutputResult == S_OK)
142                        {
143                                pSample.Trace();
144                                LONGLONG nTime, nDuration;
145                                __C(pSample->GetSampleTime(&nTime));
146                                __C(pSample->GetSampleDuration(&nDuration));
147                                DWORD nLength;
148                                __C(pSample->GetTotalLength(&nLength));
149                                _tprintf(_T("Line %d: nTime %s, nDuration %s, nLength %d\n"), __LINE__, (LPCTSTR) MF::FormatNanoTime(nTime), (LPCTSTR) MF::FormatNanoTime(nDuration), nLength);
150                                break;
151                        }
152                        __C(nProcessOutputResult);
153                }
154        }
155        VOID RunMessageLoop()
156        {
157                MF::CStartup Startup;
158                //__E(g_TerminationEvent.Create(NULL, TRUE, FALSE, NULL));
159                //__E(SetConsoleCtrlHandler(&CModule::HandlerRoutine, TRUE));
160
161                CComPtr<IMFTransform> pTransform;
162                // NOTE: Video Processor MFT https://msdn.microsoft.com/en-us/library/windows/desktop/hh162913
163                __C(pTransform.CoCreateInstance(CLSID_VideoProcessorMFT));
164                MF::CMediaType pInputMediaType;
165                pInputMediaType.Create();
166                pInputMediaType[MF_MT_MAJOR_TYPE] = MFMediaType_Video;
167                pInputMediaType[MF_MT_SUBTYPE] = MFVideoFormat_RGB32;
168                pInputMediaType[MF_MT_ALL_SAMPLES_INDEPENDENT] = (UINT32) 1;
169                pInputMediaType[MF_MT_FRAME_SIZE].SetSize(720, 480);
170                pInputMediaType[MF_MT_DEFAULT_STRIDE] = (UINT32) 2880;
171                pInputMediaType[MF_MT_PIXEL_ASPECT_RATIO].SetRatio(1, 1);
172                pInputMediaType[MF_MT_INTERLACE_MODE] = (UINT32) MFVideoInterlace_Progressive; 
173                pInputMediaType[MF_MT_FRAME_RATE].SetRatio(5, 1);
174                pInputMediaType[MF_MT_FIXED_SIZE_SAMPLES] = (UINT32) 1;
175                pInputMediaType[MF_MT_SAMPLE_SIZE] = (UINT32) 1382400;
176                pInputMediaType[MF_MT_AVG_BITRATE] = (UINT32) 55296000;
177                static const BYTE g_pnAperture[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x02, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00 };
178                pInputMediaType[MF_MT_MINIMUM_DISPLAY_APERTURE].SetBlob(g_pnAperture, DIM(g_pnAperture));
179                pInputMediaType[MF_MT_PAN_SCAN_APERTURE].SetBlob(g_pnAperture, DIM(g_pnAperture));
180                pInputMediaType[MF_MT_PAN_SCAN_ENABLED] = (UINT32) 1;
181                __C(pTransform->SetInputType(0, pInputMediaType, 0));
182                MF::CMediaType pOutputMediaType;
183                pOutputMediaType.Create();
184                pOutputMediaType[MF_MT_MAJOR_TYPE] = MFMediaType_Video;
185                pOutputMediaType[MF_MT_SUBTYPE] = MFVideoFormat_IYUV;
186                pOutputMediaType[MF_MT_FRAME_SIZE].SetSize(720, 480);
187                pOutputMediaType[MF_MT_PIXEL_ASPECT_RATIO].SetRatio(1, 1);
188                pOutputMediaType[MF_MT_INTERLACE_MODE] = (UINT32) MFVideoInterlace_Progressive; 
189                pOutputMediaType[MF_MT_FRAME_RATE].SetRatio(5, 1);
190                pOutputMediaType[MF_MT_VIDEO_NOMINAL_RANGE] = (UINT32) MFNominalRange_Wide;
191                __C(pTransform->SetOutputType(0, pOutputMediaType, 0));
192
193                MFT_INPUT_STREAM_INFO InputStreamInformation = { 0 };
194                __C(pTransform->GetInputStreamInfo(0, &InputStreamInformation));
195                MFT_OUTPUT_STREAM_INFO OutputStreamInformation = { 0 };
196                __C(pTransform->GetOutputStreamInfo(0, &OutputStreamInformation));
197                MF::CAttributes pAttributes;
198                __C(pTransform->GetAttributes(&pAttributes));
199                pAttributes[MF_XVP_DISABLE_FRC] = (UINT32) 0;
200                pAttributes[MF_VIDEO_PROCESSOR_ALGORITHM] = (UINT32) 0;
201                pAttributes[MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT] = (UINT32) 6;
202                pAttributes.Trace();
203                __C(pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0));
204                __C(pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0));
205
206                const LONGLONG nSampleDuration = 200 * 10000i64;
207
208                ProcessOutput(pTransform, OutputStreamInformation, 1);
209                ProcessInput(pTransform, InputStreamInformation, nSampleDuration, 0);
210                ProcessOutput(pTransform, OutputStreamInformation);
211                ProcessOutput(pTransform, OutputStreamInformation, 1);
212                ProcessInput(pTransform, InputStreamInformation, nSampleDuration, 1);
213                ProcessOutput(pTransform, OutputStreamInformation);
214
215                // TODO: Termination/Cleanup
216        }
217};
218
219__declspec(selectany) CEvent CModule::g_TerminationEvent;
220
Note: See TracBrowser for help on using the repository browser.