source: trunk/Utilities/DirectShowReferenceSource/Sample/MfGenerate2/Application.cpp @ 937

Last change on this file since 937 was 823, checked in by roman, 6 years ago

Sync and added MfGenerateFlac? sample

File size: 8.2 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2015-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#include "stdafx.h"
9#include "romf.h"
10#import "libid:9E3ABA93-C8D8-41D3-B39E-29508FDE5757" raw_interfaces_only // AlaxInfoDirectShowReferenceSource
11
12////////////////////////////////////////////////////////////
13// CModule
14
15class CModule :
16        public CAtlExeModuleT<CModule>
17{
18public:
19// CModule
20        bool ParseCommandLine(LPCTSTR pszCommandLine, HRESULT* pnResult)
21        {
22                _A(pnResult);
23                pszCommandLine;
24                *pnResult = S_OK;
25                return true;
26        }
27        HRESULT PreMessageLoop(int nShowCommand)
28        {
29                // NOTE: Suppress S_FALSE
30                _C(__super::PreMessageLoop(nShowCommand));
31                return S_OK;
32        }
33        VOID RunMessageLoop()
34        {
35                MF::CStartup Statup;
36                CComPtr<IMFSourceResolver> pSourceResolver;
37                __C(MFCreateSourceResolver(&pSourceResolver));
38                #pragma region Media Source
39                CComPtr<IMFMediaSource> pMediaSource;
40                //{
41                //      static const LPCTSTR g_pszPath =
42                //              _T("D:\\Projects\\Alax.Info\\Repository-Private\\Utilities\\DirectShow\\ReferenceSource\\_Media\\720p50-Small-V.mp4");
43                //      MF_OBJECT_TYPE ObjectType;
44                //      CComPtr<IUnknown> pMediaSourceUnknown;
45                //      __C(pSourceResolver->CreateObjectFromURL(CStringW(g_pszPath), MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, &pMediaSourceUnknown));
46                //      _A(ObjectType == MF_OBJECT_MEDIASOURCE);
47                //      pMediaSource = pMediaSourceUnknown;
48                //      __D(pMediaSource, E_NOINTERFACE);
49                //}
50                CComPtr<IMFMediaSource> pVideoMediaSource, pAudioMediaSource;
51                const BOOL g_bVideo = TRUE;
52                const SIZE g_Extent = 
53                        { 1920, 1080 };
54                        //{ 7680 / 2, 4320 / 2 };
55                        //{ 7680, 4320 };
56                const LONG g_nFrameRateNumerator = 50000;
57                const LONG g_nFrameRateDenominator = 1000;
58                const LONG g_nVideoBitrate = (10 * 1000) * 1000; // MBps
59                const BOOL g_bAudio = FALSE;
60                const LONG g_nSampleRate = 48000;
61                const LONG g_nChannelCount = 1;
62                const LONG g_nBitDepth = 16;
63                const LONG g_nAudioBitrate = 20 * 1000; // kBps
64                const LONG g_nDuration = 1 * 60; // minutes
65                #pragma region Video
66                if(g_bVideo)
67                {
68                        using namespace AlaxInfoDirectShowReferenceSource;
69                        CComPtr<IVideoMediaSource> pSource;
70                        __C(pSource.CoCreateInstance(__uuidof(VideoMediaSource)));
71                        __C(pSource->SetMediaType(g_Extent.cx, g_Extent.cy, CComVariant(_PersistHelper::StringFromIdentifier(MEDIASUBTYPE_RGB32))));
72                        //__C(pSource->SetMediaTypeAspectRatio(...));
73                        __C(pSource->SetMediaTypeRate(g_nFrameRateNumerator, g_nFrameRateDenominator));
74                        __C(pSource->put_Duration((DOUBLE) g_nDuration));
75                        pVideoMediaSource = pSource;
76                }
77                #pragma endregion
78                #pragma region Audio
79                if(g_bAudio)
80                {
81                        using namespace AlaxInfoDirectShowReferenceSource;
82                        CComPtr<IAudioMediaSource> pSource;
83                        __C(pSource.CoCreateInstance(__uuidof(AudioMediaSource)));
84                        __C(pSource->SetMediaType(NULL, g_nSampleRate, g_nChannelCount, g_nBitDepth));
85                        __C(pSource->put_Duration((DOUBLE) g_nDuration));
86                        pAudioMediaSource = pSource;
87                }
88                #pragma endregion
89                __D(pVideoMediaSource || pAudioMediaSource, E_UNNAMED);
90                if(pVideoMediaSource && pAudioMediaSource)
91                {
92                    CComPtr<IMFCollection> pCollection;
93                    __C(MFCreateCollection(&pCollection));
94                __C(pCollection->AddElement(pVideoMediaSource));
95                __C(pCollection->AddElement(pAudioMediaSource));
96                __C(MFCreateAggregateSource(pCollection, &pMediaSource));
97                } else
98                        pMediaSource = pVideoMediaSource ? pVideoMediaSource : pAudioMediaSource;
99                _A(pMediaSource);
100                #pragma endregion
101                CPath sFilePath;
102                {
103                        SYSTEMTIME Time;
104                        GetLocalTime(&Time);
105                        const CString sFileName = AtlFormatString(_T("%04d%02d%02d-%02d%02d%02d.mp4"), Time.wYear, Time.wMonth, Time.wDay, Time.wHour, Time.wMinute, Time.wSecond);
106                        sFilePath = Combine(GetPathDirectory(GetModulePath()), sFileName);
107                }
108                #pragma region Topology
109                // NOTE: Creating Topologies https://msdn.microsoft.com/en-us/library/windows/desktop/ms702144
110                //       Topology Node Attributes https://msdn.microsoft.com/en-us/library/windows/desktop/aa369728
111                //       Tutorial: Encoding an MP4 File https://msdn.microsoft.com/en-us/library/ff819476
112                MF::CTopology pTopology;
113                //pTopology.Create();
114                #pragma region Profile
115                CComPtr<IMFTranscodeProfile> pTranscodeProfile;
116                {
117                        __C(MFCreateTranscodeProfile(&pTranscodeProfile));
118                        #pragma region Video
119                        if(pVideoMediaSource)
120                        {
121                                MF::CAttributes pAttributes;
122                                pAttributes.Create(8);
123                                pAttributes[MF_MT_SUBTYPE] = 
124                                        MFVideoFormat_H264;
125                                        //MFVideoFormat_HEVC;
126                                pAttributes[MF_MT_AVG_BITRATE] = (UINT32) g_nVideoBitrate;
127                                pAttributes[MF_MT_FRAME_SIZE].SetSize(g_Extent.cx, g_Extent.cy);
128                                pAttributes[MF_MT_FRAME_RATE].SetRatio(g_nFrameRateNumerator, g_nFrameRateDenominator);
129                                __C(pTranscodeProfile->SetVideoAttributes(pAttributes));
130                                pAttributes.Trace();
131                        }
132                        #pragma endregion
133                        #pragma region Audio
134                        if(pAudioMediaSource)
135                        {
136                                // NOTE: The following audio attributes can be set: https://msdn.microsoft.com/en-us/library/windows/desktop/dd369143
137                                //   Audio Media Types
138                                //   MF_TRANSCODE_DONOT_INSERT_ENCODER
139                                //   MF_TRANSCODE_ENCODINGPROFILE
140                                //   MF_TRANSCODE_QUALITYVSSPEED
141                                MF::CAttributes pAttributes;
142                                pAttributes.Create(8);
143                                pAttributes[MF_MT_SUBTYPE] = MFAudioFormat_AAC;
144                                pAttributes[MF_MT_AUDIO_SAMPLES_PER_SECOND] = (UINT32) g_nSampleRate;
145                                pAttributes[MF_MT_AUDIO_NUM_CHANNELS] = (UINT32) g_nChannelCount;
146                                pAttributes[MF_MT_AUDIO_BITS_PER_SAMPLE] = (UINT32) g_nBitDepth;
147                                pAttributes[MF_MT_AUDIO_AVG_BYTES_PER_SECOND] = (UINT32) g_nAudioBitrate;
148                                __C(pTranscodeProfile->SetAudioAttributes(pAttributes));
149                                pAttributes.Trace();
150                        }
151                        #pragma endregion
152                        MF::CAttributes pAttributes;
153                        pAttributes.Create(2);
154                        pAttributes[MF_TRANSCODE_CONTAINERTYPE] = 
155                                MFTranscodeContainerType_MPEG4;
156                                //MFTranscodeContainerType_FMPEG4;
157                        pAttributes[MF_TRANSCODE_TOPOLOGYMODE] = (UINT32) MF_TRANSCODE_TOPOLOGYMODE_HARDWARE_ALLOWED;
158                        __C(pTranscodeProfile->SetContainerAttributes(pAttributes));
159                }
160                #pragma endregion
161                __C(MFCreateTranscodeTopology(pMediaSource, CT2CW((LPCTSTR) sFilePath), pTranscodeProfile, &pTopology.m_p));
162                pTopology.Trace();
163                #pragma endregion
164                #pragma region Session
165                CComPtr<IMFMediaSession> pMediaSession;
166                __C(MFCreateMediaSession(NULL, &pMediaSession));
167                __C(pMediaSession->SetTopology(0, pTopology));
168                for(BOOL bDone = FALSE; !bDone; )
169                {
170                        MF::CMediaEvent pMediaEvent;
171                        __C(pMediaSession->GetEvent(0, &pMediaEvent));
172                        pMediaEvent.Trace();
173                        MediaEventType Type;
174                        __C(pMediaEvent->GetType(&Type));
175                        HRESULT nStatus;
176                        __C(pMediaEvent->GetStatus(&nStatus));
177                        switch(Type)
178                        {
179                        case MESessionTopologySet:
180                                {
181                                        MF::CPropVariant vValue;
182                                        if(SUCCEEDED(pMediaEvent->GetValue(&vValue)) && vValue.vt == VT_UNKNOWN)
183                                        {
184                                                MF::CTopology pTopology;
185                                                pTopology.m_p = CComQIPtr<IMFTopology>(vValue.punkVal);
186                                                pTopology.Trace();
187                                        }
188                                }
189                                break;
190                        case MESessionTopologyStatus:
191                                {
192                                        const MF_TOPOSTATUS TopoStatus = (MF_TOPOSTATUS) pMediaEvent.GetUINT32(MF_EVENT_TOPOLOGY_STATUS);
193                                        _Z4(atlTraceGeneral, 4, _T("TopoStatus %s\n"), MF::FormatTopologyStatus(TopoStatus));
194                                        switch(TopoStatus)
195                                        {
196                                        case MF_TOPOSTATUS_READY:
197                                                {
198                                                        pTopology.Trace();
199                                                        MF::CPropVariant vStartPosition;
200                                                        //vStartPosition.vt = VT_I8;
201                                                        //vStartPosition.hVal.QuadPart = 2 * 1000 * 10000i64;
202                                                        __C(pMediaSession->Start(&GUID_NULL, &vStartPosition));
203                                                }
204                                                break;
205                                        case MF_TOPOSTATUS_ENDED:
206                                                break;
207                                        }
208                                }
209                                break;
210                        case MESessionStarted:
211                                break;
212                        case MESessionEnded:
213                                __C(pMediaSession->Stop());
214                                break;
215                        case MESessionStopped:
216                                __C(pMediaSession->Close());
217                                break;
218                        case MESessionClosed:
219                                bDone = TRUE;
220                                break;
221                        }
222                        if(FAILED(nStatus))
223                                bDone = TRUE;
224                }
225                __C(pMediaSession->Shutdown());
226                #pragma endregion
227        }
228};
229
230int _tmain(int argc, _TCHAR* argv[])
231{
232        _ATLTRY
233        {
234                CModule Module;
235                Module.WinMain(SW_SHOWNORMAL);
236        }
237        _ATLCATCH(Exception)
238        {
239                _tprintf(_T("Fatal Error 0x%08X\n"), (HRESULT) Exception);
240        }
241        return 0;
242}
Note: See TracBrowser for help on using the repository browser.