1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2015-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 | #include "stdafx.h" |
---|
9 | #include "romf.h" |
---|
10 | #import "libid:9E3ABA93-C8D8-41D3-B39E-29508FDE5757" raw_interfaces_only // AlaxInfoDirectShowReferenceSource |
---|
11 | |
---|
12 | //////////////////////////////////////////////////////////// |
---|
13 | // CModule |
---|
14 | |
---|
15 | class CModule : |
---|
16 | public CAtlExeModuleT<CModule> |
---|
17 | { |
---|
18 | public: |
---|
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 | CComQIPtr<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 | { |
---|
51 | using namespace AlaxInfoDirectShowReferenceSource; |
---|
52 | CComPtr<IVideoMediaSource> pVideoMediaSource; |
---|
53 | __C(pVideoMediaSource.CoCreateInstance(__uuidof(VideoMediaSource))); |
---|
54 | __C(pVideoMediaSource->SetMediaType(640, 480, CComVariant(_PersistHelper::StringFromIdentifier(MEDIASUBTYPE_ARGB32)))); |
---|
55 | //__C(pVideoMediaSource->SetMediaTypeAspectRatio(...)); |
---|
56 | __C(pVideoMediaSource->SetMediaTypeRate(10000, 1000)); |
---|
57 | __C(pVideoMediaSource->put_Duration(5.0)); |
---|
58 | pMediaSource = pVideoMediaSource; |
---|
59 | } |
---|
60 | #pragma endregion |
---|
61 | CPath sFilePath; |
---|
62 | { |
---|
63 | SYSTEMTIME Time; |
---|
64 | GetLocalTime(&Time); |
---|
65 | const CString sFileName = AtlFormatString(_T("%04d%02d%02d-%02d%02d%02d.mp4"), Time.wYear, Time.wMonth, Time.wDay, Time.wHour, Time.wMinute, Time.wSecond); |
---|
66 | sFilePath = Combine(GetPathDirectory(GetModulePath()), sFileName); |
---|
67 | } |
---|
68 | #pragma region Topology |
---|
69 | // NOTE: Creating Topologies https://msdn.microsoft.com/en-us/library/windows/desktop/ms702144 |
---|
70 | // Topology Node Attributes https://msdn.microsoft.com/en-us/library/windows/desktop/aa369728 |
---|
71 | // Tutorial: Encoding an MP4 File https://msdn.microsoft.com/en-us/library/ff819476 |
---|
72 | MF::CTopology pTopology; |
---|
73 | //pTopology.Create(); |
---|
74 | CComPtr<IMFTranscodeProfile> pTranscodeProfile; |
---|
75 | { |
---|
76 | __C(MFCreateTranscodeProfile(&pTranscodeProfile)); |
---|
77 | { |
---|
78 | MF::CAttributes pAttributes; |
---|
79 | pAttributes.Create(8); |
---|
80 | pAttributes[MF_MT_SUBTYPE] = MFVideoFormat_H264; |
---|
81 | pAttributes[MF_MT_AVG_BITRATE] = (UINT32) (5 << 10) * 1000; // 12 MBps |
---|
82 | pAttributes[MF_MT_FRAME_SIZE].SetSize(640, 480); |
---|
83 | pAttributes[MF_MT_FRAME_RATE].SetRatio(10000, 1000); |
---|
84 | __C(pTranscodeProfile->SetVideoAttributes(pAttributes)); |
---|
85 | } |
---|
86 | { |
---|
87 | MF::CAttributes pAttributes; |
---|
88 | pAttributes.Create(1); |
---|
89 | pAttributes[MF_TRANSCODE_CONTAINERTYPE] = MFTranscodeContainerType_MPEG4; |
---|
90 | __C(pTranscodeProfile->SetContainerAttributes(pAttributes)); |
---|
91 | } |
---|
92 | } |
---|
93 | __C(MFCreateTranscodeTopology(pMediaSource, CT2CW((LPCTSTR) sFilePath), pTranscodeProfile, &pTopology.m_p)); |
---|
94 | pTopology.Trace(); |
---|
95 | #pragma endregion |
---|
96 | #pragma region Session |
---|
97 | CComPtr<IMFMediaSession> pMediaSession; |
---|
98 | __C(MFCreateMediaSession(NULL, &pMediaSession)); |
---|
99 | __C(pMediaSession->SetTopology(0, pTopology)); |
---|
100 | for(BOOL bDone = FALSE; !bDone; ) |
---|
101 | { |
---|
102 | MF::CMediaEvent pMediaEvent; |
---|
103 | __C(pMediaSession->GetEvent(0, &pMediaEvent)); |
---|
104 | MediaEventType Type; |
---|
105 | __C(pMediaEvent->GetType(&Type)); |
---|
106 | HRESULT nStatus; |
---|
107 | __C(pMediaEvent->GetStatus(&nStatus)); |
---|
108 | _Z4(atlTraceGeneral, 4, _T("Type %s, nStatus %s\n"), MF::CMediaEvent::FormatType(Type), MF::FormatResult(nStatus)); |
---|
109 | switch(Type) |
---|
110 | { |
---|
111 | case MESessionTopologySet: |
---|
112 | break; |
---|
113 | case MESessionTopologyStatus: |
---|
114 | { |
---|
115 | const MF_TOPOSTATUS TopoStatus = (MF_TOPOSTATUS) pMediaEvent.GetUINT32(MF_EVENT_TOPOLOGY_STATUS); |
---|
116 | _Z4(atlTraceGeneral, 4, _T("TopoStatus %s\n"), MF::FormatTopologyStatus(TopoStatus)); |
---|
117 | switch(TopoStatus) |
---|
118 | { |
---|
119 | case MF_TOPOSTATUS_READY: |
---|
120 | { |
---|
121 | pTopology.Trace(); |
---|
122 | MF::CPropVariant vStartPosition; |
---|
123 | //vStartPosition.vt = VT_I8; |
---|
124 | //vStartPosition.hVal.QuadPart = 2 * 1000 * 10000i64; |
---|
125 | __C(pMediaSession->Start(&GUID_NULL, &vStartPosition)); |
---|
126 | } |
---|
127 | break; |
---|
128 | case MF_TOPOSTATUS_ENDED: |
---|
129 | break; |
---|
130 | } |
---|
131 | } |
---|
132 | break; |
---|
133 | case MESessionStarted: |
---|
134 | break; |
---|
135 | case MESessionEnded: |
---|
136 | __C(pMediaSession->Stop()); |
---|
137 | break; |
---|
138 | case MESessionStopped: |
---|
139 | __C(pMediaSession->Close()); |
---|
140 | break; |
---|
141 | case MESessionClosed: |
---|
142 | bDone = TRUE; |
---|
143 | break; |
---|
144 | } |
---|
145 | if(FAILED(nStatus)) |
---|
146 | bDone = TRUE; |
---|
147 | } |
---|
148 | __C(pMediaSession->Shutdown()); |
---|
149 | #pragma endregion |
---|
150 | } |
---|
151 | }; |
---|
152 | |
---|
153 | int _tmain(int argc, _TCHAR* argv[]) |
---|
154 | { |
---|
155 | _ATLTRY |
---|
156 | { |
---|
157 | CModule Module; |
---|
158 | Module.WinMain(SW_SHOWNORMAL); |
---|
159 | } |
---|
160 | _ATLCATCH(Exception) |
---|
161 | { |
---|
162 | _tprintf(_T("Fatal Error 0x%08X\n"), (HRESULT) Exception); |
---|
163 | } |
---|
164 | return 0; |
---|
165 | } |
---|
166 | |
---|