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

Last change on this file since 770 was 770, checked in by roman, 7 years ago

Added audio MF source; added audio track support in MfGenerate2 sample application

File size: 8.0 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 SIZE g_Extent = { 640, 360 };
52                const LONG g_nFrameRateNumerator = 30000;
53                const LONG g_nFrameRateDenominator = 1001;
54                const LONG g_nDuration = 1 * 60; // minutes
55                const LONG g_nVideoBitrate = (2 << 10) * 1000; // 2 MBps
56                const LONG g_nSampleRate = 48000;
57                const LONG g_nChannelCount = 1;
58                const LONG g_nBitDepth = 16;
59                const LONG g_nAudioBitrate = 20 * 1000;
60                #pragma region Video
61                if(TRUE)
62                {
63                        using namespace AlaxInfoDirectShowReferenceSource;
64                        CComPtr<IVideoMediaSource> pSource;
65                        __C(pSource.CoCreateInstance(__uuidof(VideoMediaSource)));
66                        __C(pSource->SetMediaType(g_Extent.cx, g_Extent.cy, CComVariant(_PersistHelper::StringFromIdentifier(MEDIASUBTYPE_ARGB32))));
67                        //__C(pSource->SetMediaTypeAspectRatio(...));
68                        __C(pSource->SetMediaTypeRate(g_nFrameRateNumerator, g_nFrameRateDenominator));
69                        __C(pSource->put_Duration((DOUBLE) g_nDuration));
70                        pVideoMediaSource = pSource;
71                }
72                #pragma endregion
73                #pragma region Audio
74                if(TRUE)
75                {
76                        using namespace AlaxInfoDirectShowReferenceSource;
77                        CComPtr<IAudioMediaSource> pSource;
78                        __C(pSource.CoCreateInstance(__uuidof(AudioMediaSource)));
79                        __C(pSource->SetMediaType(NULL, g_nSampleRate, g_nChannelCount, g_nBitDepth));
80                        __C(pSource->put_Duration((DOUBLE) g_nDuration));
81                        pAudioMediaSource = pSource;
82                }
83                #pragma endregion
84                __D(pVideoMediaSource || pAudioMediaSource, E_UNNAMED);
85                if(pVideoMediaSource && pAudioMediaSource)
86                {
87                    CComPtr<IMFCollection> pCollection;
88                    __C(MFCreateCollection(&pCollection));
89                __C(pCollection->AddElement(pVideoMediaSource));
90                __C(pCollection->AddElement(pAudioMediaSource));
91                __C(MFCreateAggregateSource(pCollection, &pMediaSource));
92                } else
93                        pMediaSource = pVideoMediaSource ? pVideoMediaSource : pAudioMediaSource;
94                _A(pMediaSource);
95                #pragma endregion
96                CPath sFilePath;
97                {
98                        SYSTEMTIME Time;
99                        GetLocalTime(&Time);
100                        const CString sFileName = AtlFormatString(_T("%04d%02d%02d-%02d%02d%02d.mp4"), Time.wYear, Time.wMonth, Time.wDay, Time.wHour, Time.wMinute, Time.wSecond);
101                        sFilePath = Combine(GetPathDirectory(GetModulePath()), sFileName);
102                }
103                #pragma region Topology
104                // NOTE: Creating Topologies https://msdn.microsoft.com/en-us/library/windows/desktop/ms702144
105                //       Topology Node Attributes https://msdn.microsoft.com/en-us/library/windows/desktop/aa369728
106                //       Tutorial: Encoding an MP4 File https://msdn.microsoft.com/en-us/library/ff819476
107                MF::CTopology pTopology;
108                //pTopology.Create();
109                #pragma region Profile
110                CComPtr<IMFTranscodeProfile> pTranscodeProfile;
111                {
112                        __C(MFCreateTranscodeProfile(&pTranscodeProfile));
113                        #pragma region Video
114                        if(pVideoMediaSource)
115                        {
116                                MF::CAttributes pAttributes;
117                                pAttributes.Create(8);
118                                pAttributes[MF_MT_SUBTYPE] = 
119                                        MFVideoFormat_H264;
120                                        //MFVideoFormat_HEVC;
121                                pAttributes[MF_MT_AVG_BITRATE] = (UINT32) g_nVideoBitrate;
122                                pAttributes[MF_MT_FRAME_SIZE].SetSize(g_Extent.cx, g_Extent.cy);
123                                pAttributes[MF_MT_FRAME_RATE].SetRatio(g_nFrameRateNumerator, g_nFrameRateDenominator);
124                                __C(pTranscodeProfile->SetVideoAttributes(pAttributes));
125                                pAttributes.Trace();
126                        }
127                        #pragma endregion
128                        #pragma region Audio
129                        if(pAudioMediaSource)
130                        {
131                                // NOTE: The following audio attributes can be set: https://msdn.microsoft.com/en-us/library/windows/desktop/dd369143
132                                //   Audio Media Types
133                                //   MF_TRANSCODE_DONOT_INSERT_ENCODER
134                                //   MF_TRANSCODE_ENCODINGPROFILE
135                                //   MF_TRANSCODE_QUALITYVSSPEED
136                                MF::CAttributes pAttributes;
137                                pAttributes.Create(8);
138                                pAttributes[MF_MT_SUBTYPE] = MFAudioFormat_AAC;
139                                pAttributes[MF_MT_AUDIO_SAMPLES_PER_SECOND] = (UINT32) g_nSampleRate;
140                                pAttributes[MF_MT_AUDIO_NUM_CHANNELS] = (UINT32) g_nChannelCount;
141                                pAttributes[MF_MT_AUDIO_BITS_PER_SAMPLE] = (UINT32) g_nBitDepth;
142                                pAttributes[MF_MT_AUDIO_AVG_BYTES_PER_SECOND] = (UINT32) g_nAudioBitrate;
143                                __C(pTranscodeProfile->SetAudioAttributes(pAttributes));
144                                pAttributes.Trace();
145                        }
146                        #pragma endregion
147                        MF::CAttributes pAttributes;
148                        pAttributes.Create(1);
149                        pAttributes[MF_TRANSCODE_CONTAINERTYPE] = MFTranscodeContainerType_MPEG4;
150                        __C(pTranscodeProfile->SetContainerAttributes(pAttributes));
151                }
152                #pragma endregion
153                __C(MFCreateTranscodeTopology(pMediaSource, CT2CW((LPCTSTR) sFilePath), pTranscodeProfile, &pTopology.m_p));
154                pTopology.Trace();
155                #pragma endregion
156                #pragma region Session
157                CComPtr<IMFMediaSession> pMediaSession;
158                __C(MFCreateMediaSession(NULL, &pMediaSession));
159                __C(pMediaSession->SetTopology(0, pTopology));
160                for(BOOL bDone = FALSE; !bDone; )
161                {
162                        MF::CMediaEvent pMediaEvent;
163                        __C(pMediaSession->GetEvent(0, &pMediaEvent));
164                        pMediaEvent.Trace();
165                        MediaEventType Type;
166                        __C(pMediaEvent->GetType(&Type));
167                        HRESULT nStatus;
168                        __C(pMediaEvent->GetStatus(&nStatus));
169                        switch(Type)
170                        {
171                        case MESessionTopologySet:
172                                {
173                                        MF::CPropVariant vValue;
174                                        if(SUCCEEDED(pMediaEvent->GetValue(&vValue)) && vValue.vt == VT_UNKNOWN)
175                                        {
176                                                MF::CTopology pTopology;
177                                                pTopology.m_p = CComQIPtr<IMFTopology>(vValue.punkVal);
178                                                pTopology.Trace();
179                                        }
180                                }
181                                break;
182                        case MESessionTopologyStatus:
183                                {
184                                        const MF_TOPOSTATUS TopoStatus = (MF_TOPOSTATUS) pMediaEvent.GetUINT32(MF_EVENT_TOPOLOGY_STATUS);
185                                        _Z4(atlTraceGeneral, 4, _T("TopoStatus %s\n"), MF::FormatTopologyStatus(TopoStatus));
186                                        switch(TopoStatus)
187                                        {
188                                        case MF_TOPOSTATUS_READY:
189                                                {
190                                                        pTopology.Trace();
191                                                        MF::CPropVariant vStartPosition;
192                                                        //vStartPosition.vt = VT_I8;
193                                                        //vStartPosition.hVal.QuadPart = 2 * 1000 * 10000i64;
194                                                        __C(pMediaSession->Start(&GUID_NULL, &vStartPosition));
195                                                }
196                                                break;
197                                        case MF_TOPOSTATUS_ENDED:
198                                                break;
199                                        }
200                                }
201                                break;
202                        case MESessionStarted:
203                                break;
204                        case MESessionEnded:
205                                __C(pMediaSession->Stop());
206                                break;
207                        case MESessionStopped:
208                                __C(pMediaSession->Close());
209                                break;
210                        case MESessionClosed:
211                                bDone = TRUE;
212                                break;
213                        }
214                        if(FAILED(nStatus))
215                                bDone = TRUE;
216                }
217                __C(pMediaSession->Shutdown());
218                #pragma endregion
219        }
220};
221
222int _tmain(int argc, _TCHAR* argv[])
223{
224        _ATLTRY
225        {
226                CModule Module;
227                Module.WinMain(SW_SHOWNORMAL);
228        }
229        _ATLCATCH(Exception)
230        {
231                _tprintf(_T("Fatal Error 0x%08X\n"), (HRESULT) Exception);
232        }
233        return 0;
234}
235
Note: See TracBrowser for help on using the repository browser.