Parent Directory | Revision Log
Revision 2019 - (view) (download)
1 : | Irhall | 2014 | /***************************************************************************** |
2 : | * | ||
3 : | * Xvid MiniConvert | ||
4 : | * - RecompressGraph class and WinMain() - | ||
5 : | * | ||
6 : | * Copyright(C) 2011 Xvid Solutions GmbH | ||
7 : | * | ||
8 : | * This program is free software ; you can redistribute it and/or modify | ||
9 : | * it under the terms of the GNU General Public License as published by | ||
10 : | * the Free Software Foundation ; either version 2 of the License, or | ||
11 : | * (at your option) any later version. | ||
12 : | * | ||
13 : | * This program is distributed in the hope that it will be useful, | ||
14 : | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
15 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 : | * GNU General Public License for more details. | ||
17 : | * | ||
18 : | * You should have received a copy of the GNU General Public License | ||
19 : | * along with this program ; if not, write to the Free Software | ||
20 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 : | * | ||
22 : | * $Id$ | ||
23 : | * | ||
24 : | ****************************************************************************/ | ||
25 : | /* | ||
26 : | * Author(s): Ireneusz Hallmann | ||
27 : | * | ||
28 : | ****************************************************************************/ | ||
29 : | |||
30 : | #include "stdafx.h" | ||
31 : | |||
32 : | #include "utils.h" | ||
33 : | #include "filters.h" | ||
34 : | #include "recompress.h" | ||
35 : | #include "resource.h" | ||
36 : | #include <stdio.h> | ||
37 : | #include <vfw.h> | ||
38 : | #include <wmsdk.h> | ||
39 : | |||
40 : | //#define ALLOW_ONLY_AVI_INPUT | ||
41 : | |||
42 : | #define APP_NAME TEXT("Xvid MiniConvert") | ||
43 : | |||
44 : | Isibaar | 2019 | #define Pass_FILE_A "xvid_2pass.stats" |
45 : | #define Pass_FILE TEXT("xvid_2pass.stats") | ||
46 : | Irhall | 2014 | |
47 : | // Todo: Avoid global vars... | ||
48 : | OPENFILENAME sOfn, sSfn; | ||
49 : | TCHAR OpenFilePath[MAX_PATH *2] = TEXT("\0"); | ||
50 : | TCHAR SaveFilePath[MAX_PATH *2] = TEXT("\0"); | ||
51 : | HWND ghDlg; | ||
52 : | |||
53 : | TCHAR *SrcFile, DstFile[MAX_PATH *2]; | ||
54 : | RecompressGraph *pRec; | ||
55 : | HANDLE hConvertThread = 0; | ||
56 : | |||
57 : | ////////////////////////////////////////////////////////////////////////////// | ||
58 : | |||
59 : | // Callback for FileCopyEx progress notification | ||
60 : | DWORD CALLBACK | ||
61 : | CopyProgressRoutine(LARGE_INTEGER TotalFileSize, | ||
62 : | LARGE_INTEGER TotalBytesTransferred, | ||
63 : | LARGE_INTEGER StreamSize, | ||
64 : | LARGE_INTEGER StreamBytesTransferred, | ||
65 : | DWORD dwStreamNumber, | ||
66 : | DWORD dwCallbackReason, | ||
67 : | HANDLE hSourceFile, | ||
68 : | HANDLE hDestinationFile, | ||
69 : | LPVOID lpData ) | ||
70 : | { | ||
71 : | RecompressGraph *pRecGraph = (RecompressGraph *) lpData; | ||
72 : | double Progress = ((double)(TotalBytesTransferred.QuadPart) / | ||
73 : | (double)(TotalFileSize.QuadPart) ) * 100.; | ||
74 : | |||
75 : | if (pRecGraph->GetTotalSize() > 0) { // Have multiple input files? | ||
76 : | Progress *= ((double)pRecGraph->GetCurSize() / (double) pRecGraph->GetTotalSize()); | ||
77 : | Progress += (100*(pRecGraph->GetElapsedSize()) / pRecGraph->GetTotalSize()); | ||
78 : | } | ||
79 : | |||
80 : | // Update progress bar | ||
81 : | PostMessage((HWND)pRecGraph->GetProgressWnd(), PBM_SETPOS, (WPARAM)Progress, 0); | ||
82 : | |||
83 : | if (pRecGraph->IsBreakRequested()) | ||
84 : | return PROGRESS_STOP; | ||
85 : | else | ||
86 : | return PROGRESS_CONTINUE; // Continue the file copy | ||
87 : | } | ||
88 : | |||
89 : | // Helper function to determine size (in KB) of a given file | ||
90 : | BOOL | ||
91 : | DetermineFileSize(const TCHAR *fileName, DWORD *fileSizeOut) | ||
92 : | { | ||
93 : | BOOL ret; | ||
94 : | WIN32_FILE_ATTRIBUTE_DATA fileInfo; | ||
95 : | |||
96 : | if (fileName == NULL) | ||
97 : | return FALSE; | ||
98 : | |||
99 : | ret = GetFileAttributesEx(fileName, GetFileExInfoStandard, (void*)&fileInfo); | ||
100 : | |||
101 : | if (!ret) | ||
102 : | return FALSE; | ||
103 : | |||
104 : | *fileSizeOut = (fileInfo.nFileSizeHigh<<22) | | ||
105 : | (fileInfo.nFileSizeLow>>10); // Should work up to 4 TB file size... | ||
106 : | |||
107 : | return TRUE; | ||
108 : | } | ||
109 : | |||
110 : | ////////////////////////////////////////////////////////////////////////////// | ||
111 : | |||
112 : | HRESULT | ||
113 : | AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) | ||
114 : | { | ||
115 : | IMoniker * pMoniker = NULL; | ||
116 : | IRunningObjectTable *pROT = NULL; | ||
117 : | |||
118 : | if (FAILED(GetRunningObjectTable(0, &pROT))) { | ||
119 : | return E_FAIL; | ||
120 : | } | ||
121 : | |||
122 : | const size_t STRING_LENGTH = 256; | ||
123 : | WCHAR wsz[STRING_LENGTH]; | ||
124 : | Isibaar | 2019 | swprintf(wsz, STRING_LENGTH, L"FilterGraph %08x pid %08x", |
125 : | Irhall | 2014 | (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); |
126 : | |||
127 : | Isibaar | 2019 | HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); |
128 : | Irhall | 2014 | if (SUCCEEDED(hr)) { |
129 : | hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, | ||
130 : | pMoniker, pdwRegister); | ||
131 : | pMoniker->Release(); | ||
132 : | } | ||
133 : | |||
134 : | pROT->Release(); | ||
135 : | return hr; | ||
136 : | } | ||
137 : | |||
138 : | |||
139 : | void RemoveFromRot(DWORD pdwRegister) | ||
140 : | { | ||
141 : | IRunningObjectTable *pROT; | ||
142 : | |||
143 : | if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { | ||
144 : | pROT->Revoke(pdwRegister); | ||
145 : | pROT->Release(); | ||
146 : | } | ||
147 : | } | ||
148 : | |||
149 : | RecompressGraph::RecompressGraph() | ||
150 : | { | ||
151 : | m_szSourceFilePath = 0; | ||
152 : | m_szDstFilePath = 0; | ||
153 : | |||
154 : | m_UsedStreamsCnt = 0; | ||
155 : | m_pGraph = 0; | ||
156 : | m_pBuilder = 0; | ||
157 : | m_pXvidCfgRec = 0; | ||
158 : | |||
159 : | m_Bitrate = m_bFileCopy = 0; | ||
160 : | m_Width = m_Height = 0; | ||
161 : | |||
162 : | m_pVideoMeter = m_pSrcFilter = m_pXvidEncoder = 0; | ||
163 : | //m_pEmmsDummy = 0; | ||
164 : | m_pMuxer = m_pFileWriter = m_pChgType = 0; | ||
165 : | m_pXvidConfig = 0; | ||
166 : | m_bBreakRequested = 0; | ||
167 : | |||
168 : | m_elapsedSize = m_curSize = m_totalSize = 0; | ||
169 : | } | ||
170 : | |||
171 : | RecompressGraph::~RecompressGraph() | ||
172 : | { | ||
173 : | CleanUp(); | ||
174 : | } | ||
175 : | |||
176 : | void | ||
177 : | RecompressGraph::CleanUp() | ||
178 : | { | ||
179 : | m_UsedStreamsCnt = 0; | ||
180 : | |||
181 : | if (m_szSourceFilePath) | ||
182 : | free (m_szSourceFilePath); | ||
183 : | |||
184 : | if (m_szDstFilePath) | ||
185 : | free (m_szDstFilePath); | ||
186 : | |||
187 : | if (m_pXvidCfgRec) | ||
188 : | free(m_pXvidCfgRec); | ||
189 : | |||
190 : | m_pXvidCfgRec = 0; | ||
191 : | m_bBreakRequested = 0; | ||
192 : | |||
193 : | m_szSourceFilePath = m_szDstFilePath = 0; | ||
194 : | m_curSize = 0; | ||
195 : | |||
196 : | #if 0 | ||
197 : | if (m_pEmmsDummy) { | ||
198 : | m_pGraph->RemoveFilter(m_pEmmsDummy); | ||
199 : | m_pEmmsDummy->Release(); | ||
200 : | m_pEmmsDummy = 0; | ||
201 : | } | ||
202 : | #endif | ||
203 : | |||
204 : | if (m_pVideoMeter) { | ||
205 : | m_pGraph->RemoveFilter(m_pVideoMeter); | ||
206 : | m_pVideoMeter->Release(); | ||
207 : | m_pVideoMeter=0; | ||
208 : | } | ||
209 : | |||
210 : | if (m_pSrcFilter) { | ||
211 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
212 : | m_pSrcFilter->Release(); | ||
213 : | m_pSrcFilter = 0; | ||
214 : | } | ||
215 : | |||
216 : | if (m_pXvidEncoder) { | ||
217 : | m_pGraph->RemoveFilter(m_pXvidEncoder); | ||
218 : | m_pXvidEncoder->Release(); | ||
219 : | m_pXvidEncoder=0; | ||
220 : | } | ||
221 : | |||
222 : | if (m_pXvidConfig) { | ||
223 : | m_pXvidConfig->Release(); | ||
224 : | m_pXvidConfig = 0; | ||
225 : | } | ||
226 : | |||
227 : | if (m_pChgType) { | ||
228 : | m_pGraph->RemoveFilter(m_pChgType); | ||
229 : | m_pChgType->Release(); | ||
230 : | m_pChgType=0; | ||
231 : | } | ||
232 : | |||
233 : | if (m_pMuxer) { | ||
234 : | m_pGraph->RemoveFilter(m_pMuxer); | ||
235 : | m_pMuxer->Release(); | ||
236 : | m_pMuxer = 0; | ||
237 : | } | ||
238 : | |||
239 : | if (m_pFileWriter) { | ||
240 : | m_pGraph->RemoveFilter(m_pFileWriter); | ||
241 : | m_pFileWriter->Release(); | ||
242 : | m_pFileWriter = 0; | ||
243 : | } | ||
244 : | |||
245 : | IEnumFilters *pIEnumFilters = 0; | ||
246 : | |||
247 : | if (m_pGraph) { | ||
248 : | m_pGraph->EnumFilters(&pIEnumFilters); | ||
249 : | IBaseFilter *pFilter = 0; | ||
250 : | |||
251 : | if (pIEnumFilters) { | ||
252 : | while (pIEnumFilters->Next(1, &pFilter, 0) == S_OK) { | ||
253 : | m_pGraph->RemoveFilter(pFilter); | ||
254 : | pFilter->Release(); | ||
255 : | pIEnumFilters->Reset(); | ||
256 : | } | ||
257 : | } | ||
258 : | } | ||
259 : | |||
260 : | if (pIEnumFilters) | ||
261 : | pIEnumFilters->Release(); | ||
262 : | |||
263 : | while (m_vOtherFilters.size() > 0) { | ||
264 : | IBaseFilter *pFlt = m_vOtherFilters.back(); | ||
265 : | m_vOtherFilters.pop_back(); | ||
266 : | m_pGraph->RemoveFilter(pFlt); | ||
267 : | pFlt->Release(); | ||
268 : | } | ||
269 : | |||
270 : | if (m_pGraph) { | ||
271 : | m_pGraph->Release(); | ||
272 : | m_pGraph = 0; | ||
273 : | } | ||
274 : | |||
275 : | if (m_pBuilder) { | ||
276 : | m_pBuilder->Release(); | ||
277 : | m_pBuilder = 0; | ||
278 : | } | ||
279 : | } | ||
280 : | |||
281 : | HRESULT | ||
282 : | RecompressGraph::CreateGraph(HWND in_ProgressWnd, int in_Pass) | ||
283 : | { | ||
284 : | m_FpsNom = m_FpsDen = 0; | ||
285 : | m_ProgressWnd = in_ProgressWnd; | ||
286 : | |||
287 : | m_bFileCopy = 1; // Initial guess: File copy strategy possible | ||
288 : | |||
289 : | #ifdef ALLOW_ONLY_AVI_INPUT | ||
290 : | if (fourcc_helper(m_szSourceFilePath, NULL, NULL, 1) != 0) return S_FALSE; // No AVI? -> fail | ||
291 : | #endif | ||
292 : | |||
293 : | DetermineFileSize(m_szSourceFilePath, &m_curSize); | ||
294 : | |||
295 : | if (in_ProgressWnd && (in_Pass == 1) && (m_elapsedSize == 0)) | ||
296 : | PostMessage(in_ProgressWnd, PBM_SETPOS, 0, 0); // Reset progress bar | ||
297 : | |||
298 : | HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, | ||
299 : | IID_ICaptureGraphBuilder2, (void **)&m_pBuilder); | ||
300 : | |||
301 : | if (hr == S_OK) hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, | ||
302 : | IID_IGraphBuilder, (void **)&m_pGraph); | ||
303 : | |||
304 : | if (hr == S_OK) hr = m_pBuilder->SetFiltergraph(m_pGraph); | ||
305 : | if (hr == S_OK) hr = AddSourceFilter(m_szSourceFilePath); | ||
306 : | |||
307 : | m_bIsWM = 0; | ||
308 : | |||
309 : | m_UsedStreamsCnt = 1; | ||
310 : | m_vDuration = 0; | ||
311 : | IMediaSeeking *pSeek = 0; | ||
312 : | IPin *pOutVideoPin = 0; | ||
313 : | CMediaType vMt; | ||
314 : | |||
315 : | if (hr == S_OK) { | ||
316 : | if (GetFilterPin(m_pSrcFilter, PINDIR_OUTPUT, 0, &pOutVideoPin, | ||
317 : | MEDIATYPE_Video, GUID_NULL) == S_OK) | ||
318 : | { | ||
319 : | IServiceProvider *pSrcServiceProvider = 0; | ||
320 : | |||
321 : | if (m_pSrcFilter->QueryInterface(IID_IServiceProvider, | ||
322 : | (void **)&pSrcServiceProvider) == S_OK) | ||
323 : | { | ||
324 : | IWMReaderAdvanced2 *pRdrAdv2 = 0; | ||
325 : | |||
326 : | if (pSrcServiceProvider->QueryInterface(IID_IWMReaderAdvanced2, | ||
327 : | (void **)&pRdrAdv2) == S_OK) | ||
328 : | { | ||
329 : | m_bIsWM = 1; | ||
330 : | |||
331 : | IEnumMediaTypes *pIEnumMediaTypes = 0; | ||
332 : | |||
333 : | if (pOutVideoPin->EnumMediaTypes(&pIEnumMediaTypes) == S_OK) | ||
334 : | { | ||
335 : | AM_MEDIA_TYPE *ppMt; | ||
336 : | |||
337 : | if (pIEnumMediaTypes->Next(1, &ppMt, 0) == S_OK) | ||
338 : | { | ||
339 : | vMt = *ppMt; | ||
340 : | DeleteMediaType(ppMt); | ||
341 : | } | ||
342 : | pIEnumMediaTypes->Release(); | ||
343 : | } | ||
344 : | pRdrAdv2->Release(); | ||
345 : | } | ||
346 : | pSrcServiceProvider->Release(); | ||
347 : | } | ||
348 : | pOutVideoPin->QueryInterface(IID_IMediaSeeking, (void **)&pSeek); | ||
349 : | } | ||
350 : | } | ||
351 : | |||
352 : | IPin* pVMeterInVideoPin = 0; | ||
353 : | if ((hr == S_OK)) { | ||
354 : | //if (!m_bIsWM && (hr == S_OK)) { | ||
355 : | CUnknown *pVidMeter = 0; | ||
356 : | |||
357 : | if (hr == S_OK) pVidMeter = CProgressNotifyFilter::CreateInstance(0, &hr, 0); | ||
358 : | if (hr == S_OK) hr = pVidMeter->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&m_pVideoMeter); | ||
359 : | //hr = CoCreateInstance(CLSID_ProgressNotifyFilter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pVideoMeter); | ||
360 : | Isibaar | 2019 | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pVideoMeter, L"Video meter"); |
361 : | Irhall | 2014 | if (hr == S_OK) hr = GetFilterPin(m_pVideoMeter, PINDIR_INPUT, 0, &pVMeterInVideoPin, GUID_NULL, GUID_NULL); |
362 : | |||
363 : | if (pOutVideoPin) { | ||
364 : | hr = m_pGraph->Connect(pOutVideoPin, pVMeterInVideoPin); | ||
365 : | pOutVideoPin->Release(); | ||
366 : | pOutVideoPin = 0; | ||
367 : | } | ||
368 : | else { | ||
369 : | IPin *pVideoPin = 0; | ||
370 : | hr = m_pBuilder->RenderStream(NULL, NULL, m_pSrcFilter, NULL, m_pVideoMeter); | ||
371 : | if (hr == S_OK) hr = GetFilterPin(m_pVideoMeter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); | ||
372 : | if (hr == S_OK) pVideoPin->QueryInterface(IID_IMediaSeeking, (void **)&pSeek); | ||
373 : | if (pVideoPin) pVideoPin->Release(); | ||
374 : | } | ||
375 : | GetFilterPin(m_pVideoMeter, PINDIR_OUTPUT, 0, &pOutVideoPin, GUID_NULL, GUID_NULL); | ||
376 : | } | ||
377 : | |||
378 : | if (pSeek && (hr == S_OK)) { | ||
379 : | LONGLONG Duration = 0; | ||
380 : | hr = pSeek->GetDuration(&Duration); | ||
381 : | if (hr == S_OK) m_vDuration = Duration; | ||
382 : | } | ||
383 : | if (pSeek) pSeek->Release(); | ||
384 : | |||
385 : | IBaseFilter *pCompressedVideoFilter = 0; | ||
386 : | int m_bRecompress = 1; | ||
387 : | GUID gSubtype; | ||
388 : | |||
389 : | if (hr == S_OK) { | ||
390 : | m_TotalFrames = 0; | ||
391 : | |||
392 : | if (hr == S_OK && !m_bIsWM) hr = pVMeterInVideoPin->ConnectionMediaType(&vMt); | ||
393 : | |||
394 : | if (m_vDuration != 0) { | ||
395 : | if (vMt.formattype != FORMAT_None) { | ||
396 : | if (vMt.formattype == FORMAT_VideoInfo || vMt.formattype == FORMAT_MPEGVideo) { | ||
397 : | m_AvgTimeForFrame = (DWORD) ((VIDEOINFOHEADER *)vMt.pbFormat)->AvgTimePerFrame; | ||
398 : | if (m_bIsWM) m_Bitrate = ((VIDEOINFOHEADER *)vMt.pbFormat)->dwBitRate; | ||
399 : | } | ||
400 : | else if (vMt.formattype == FORMAT_VideoInfo2 || vMt.formattype == FORMAT_MPEG2Video) { | ||
401 : | m_AvgTimeForFrame = (DWORD) (((VIDEOINFOHEADER2 *)vMt.pbFormat)->AvgTimePerFrame); | ||
402 : | if (m_bIsWM) m_Bitrate = ((VIDEOINFOHEADER2 *)vMt.pbFormat)->dwBitRate; | ||
403 : | } | ||
404 : | else return VFW_E_TYPE_NOT_ACCEPTED; | ||
405 : | } | ||
406 : | m_TotalFrames = (DWORD) (m_AvgTimeForFrame ? (m_vDuration + (m_AvgTimeForFrame/2)) / m_AvgTimeForFrame : 0); | ||
407 : | } | ||
408 : | |||
409 : | gSubtype = vMt.subtype; | ||
410 : | if (hr == S_OK) { | ||
411 : | if (gSubtype == FOURCCMap('DIVX') || gSubtype == FOURCCMap('XVID') | ||
412 : | || gSubtype == FOURCCMap('divx') || gSubtype == FOURCCMap('xvid') | ||
413 : | || gSubtype == FOURCCMap('05XD') || gSubtype == FOURCCMap('V4PM') | ||
414 : | || gSubtype == FOURCCMap('05xd') || gSubtype == FOURCCMap('v4pm') | ||
415 : | || gSubtype == FOURCCMap('4PMR') || gSubtype == FOURCCMap('4pmr') | ||
416 : | || gSubtype == FOURCCMap('4XDH') || gSubtype == FOURCCMap('4xdh') | ||
417 : | || gSubtype == FOURCCMap('XVI3') || gSubtype == FOURCCMap('xvi3') | ||
418 : | || gSubtype == FOURCCMap('0VI3') || gSubtype == FOURCCMap('0vi3') | ||
419 : | || gSubtype == FOURCCMap('1VI3') || gSubtype == FOURCCMap('1vi3') | ||
420 : | || gSubtype == FOURCCMap('2VI3') || gSubtype == FOURCCMap('2vi3') | ||
421 : | || gSubtype == FOURCCMap('4PML') || gSubtype == FOURCCMap('4pml') | ||
422 : | || gSubtype == FOURCCMap('4PMS') || gSubtype == FOURCCMap('4pms')) | ||
423 : | { | ||
424 : | pCompressedVideoFilter = m_pVideoMeter ? m_pVideoMeter : m_pSrcFilter; | ||
425 : | } | ||
426 : | else { | ||
427 : | m_bFileCopy = 0; | ||
428 : | |||
429 : | if (hr == S_OK) hr = AddDirectXFilterByMoniker(CLSID_VideoCompressorCategory, "xvid", &m_pXvidEncoder, 1); | ||
430 : | Isibaar | 2019 | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pXvidEncoder, L"Encoder"); |
431 : | Irhall | 2014 | |
432 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pOutVideoPin, m_pXvidEncoder, GUID_NULL, GUID_NULL, 0); | ||
433 : | if (hr == S_OK) pCompressedVideoFilter = m_pXvidEncoder; | ||
434 : | |||
435 : | #if 0 | ||
436 : | if (!m_bIsWM) { | ||
437 : | // dummy filter - emms instruction only | ||
438 : | CUnknown *pVidMeterEmms = 0; | ||
439 : | if (hr == S_OK) pVidMeterEmms = CProgressNotifyFilter::CreateInstance(0, &hr, 0); | ||
440 : | if (hr == S_OK) hr = pVidMeterEmms->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&m_pEmmsDummy); | ||
441 : | //if (hr == S_OK) hr = CoCreateInstance(CLSID_ProgressNotifyFilter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pEmmsDummy); | ||
442 : | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pEmmsDummy, TEXT("Video meter emms")); | ||
443 : | IPin *pOutPin = 0, *pInPin=0; | ||
444 : | |||
445 : | if (hr == S_OK) hr = GetFilterPin(m_pXvidEncoder, PINDIR_INPUT, 1, &pInPin, GUID_NULL, GUID_NULL); | ||
446 : | if (hr == S_OK) hr = pInPin->ConnectedTo(&pOutPin); | ||
447 : | if (hr == S_OK) hr = m_pGraph->Disconnect(pInPin); | ||
448 : | if (hr == S_OK) hr = m_pGraph->Disconnect(pOutPin); | ||
449 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pOutPin, m_pEmmsDummy, GUID_NULL, GUID_NULL, 1); | ||
450 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, m_pEmmsDummy, pInPin, GUID_NULL, GUID_NULL, 1); | ||
451 : | |||
452 : | if (pInPin) pInPin->Release(); | ||
453 : | if (pOutPin) pOutPin->Release(); | ||
454 : | } | ||
455 : | #endif | ||
456 : | |||
457 : | m_ToAlloc = 0; | ||
458 : | if (hr == S_OK) hr = m_pXvidEncoder->QueryInterface(IID_IAMVfwCompressDialogs, (void **)&m_pXvidConfig); | ||
459 : | |||
460 : | if (hr == S_OK) m_ToAlloc = m_pXvidConfig->SendDriverMessage(ICM_GETSTATE, NULL, 0); | ||
461 : | if (hr == S_OK) m_pXvidCfgRec = (CONFIG *)malloc(m_ToAlloc +10); | ||
462 : | if (hr == S_OK) m_pXvidConfig->SendDriverMessage(ICM_GETSTATE, (LONG)m_pXvidCfgRec, 0); | ||
463 : | |||
464 : | if (hr == S_OK) { | ||
465 : | if (in_Pass == 1) { | ||
466 : | m_pXvidCfgRec->mode = RC_MODE_2PASS1; | ||
467 : | } | ||
468 : | else { | ||
469 : | m_pXvidCfgRec->mode = RC_MODE_2PASS2; | ||
470 : | |||
471 : | if (m_Bitrate > 0) { | ||
472 : | m_pXvidCfgRec->use_2pass_bitrate = 1; | ||
473 : | m_pXvidCfgRec->bitrate = m_Bitrate/1000; // in kbps | ||
474 : | } | ||
475 : | else if (m_TotalFramesSize > 0) { | ||
476 : | m_pXvidCfgRec->desired_size = (int) (m_TotalFramesSize/1024); // in KB | ||
477 : | m_pXvidCfgRec->use_2pass_bitrate = 0; | ||
478 : | } | ||
479 : | else { | ||
480 : | m_pXvidCfgRec->desired_size = (int) (.9f*m_curSize); // in KB | ||
481 : | m_pXvidCfgRec->use_2pass_bitrate = 0; | ||
482 : | } | ||
483 : | |||
484 : | #if 1 // select a profile matching the input dimensions | ||
485 : | if (m_Width == 0 || m_Height == 0) { // not detected | ||
486 : | m_pXvidCfgRec->profile = 0x11; | ||
487 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
488 : | } | ||
489 : | else if (m_Width <= 352 && m_Height <= 288) { | ||
490 : | m_pXvidCfgRec->profile = 0x0; | ||
491 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid Mobile"); | ||
492 : | } | ||
493 : | else if (m_Width <= 720 && m_Height <= 576) { | ||
494 : | m_pXvidCfgRec->profile = 0x1; | ||
495 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid Home"); | ||
496 : | } | ||
497 : | else if (m_Width <= 1280 && m_Height <= 720) { | ||
498 : | m_pXvidCfgRec->profile = 0x2; | ||
499 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid HD 720"); | ||
500 : | } | ||
501 : | else if (m_Width <= 1920 && m_Height <= 1080) { | ||
502 : | m_pXvidCfgRec->profile = 0x3; | ||
503 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid HD 1080"); | ||
504 : | } | ||
505 : | else { | ||
506 : | m_pXvidCfgRec->profile = 0x11; | ||
507 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
508 : | } | ||
509 : | #else | ||
510 : | m_pXvidCfgRec->profile = 0xE; | ||
511 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
512 : | #endif | ||
513 : | } | ||
514 : | |||
515 : | Isibaar | 2019 | strcpy(m_pXvidCfgRec->stats, Pass_FILE_A); |
516 : | Irhall | 2014 | |
517 : | m_pXvidCfgRec->display_status = 0; | ||
518 : | |||
519 : | if (hr == S_OK) m_pXvidConfig->SendDriverMessage(ICM_SETSTATE, (LONG)m_pXvidCfgRec, 0); | ||
520 : | } | ||
521 : | } | ||
522 : | } | ||
523 : | } | ||
524 : | |||
525 : | CUnknown *pChgUnk = ChangeSubtypeT::CreateInstance(0, &hr); | ||
526 : | if (hr == S_OK) hr = pChgUnk->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&m_pChgType); | ||
527 : | Isibaar | 2019 | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pChgType, L"ChgToxvid"); |
528 : | Irhall | 2014 | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pCompressedVideoFilter, m_pChgType, GUID_NULL, GUID_NULL, 1); |
529 : | |||
530 : | if (hr == S_OK) hr = AddFilterByCLSID((GUID *)&CLSID_AviDest, &m_pMuxer); | ||
531 : | |||
532 : | #if 0 | ||
533 : | IConfigInterleaving *pIConfigInterleaving = 0; | ||
534 : | if (hr == S_OK) hr = m_pMuxer->QueryInterface(IID_IConfigInterleaving, (void **)&pIConfigInterleaving); | ||
535 : | REFERENCE_TIME InterleaveRate = 10000000LL, Preroll = 100000000LL; | ||
536 : | if (hr == S_OK) hr = pIConfigInterleaving->put_Mode(INTERLEAVE_FULL); | ||
537 : | if (hr == S_OK) hr = pIConfigInterleaving->put_Interleaving(&InterleaveRate, &Preroll); | ||
538 : | if (pIConfigInterleaving) pIConfigInterleaving->Release(); | ||
539 : | #endif | ||
540 : | |||
541 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, m_pChgType, m_pMuxer, MEDIATYPE_Video, GUID_NULL, 1); | ||
542 : | |||
543 : | IRecProgressNotify *pChgN = 0; | ||
544 : | if (hr == S_OK) hr = m_pChgType->QueryInterface(IID_IRecProgressNotify, (void **)&pChgN); | ||
545 : | if (hr == S_OK) hr = pChgN->SetTotalFrames(m_TotalFrames); | ||
546 : | if (pChgN) pChgN->Release(); | ||
547 : | |||
548 : | if (hr == S_OK) hr = AddFileWriter(m_szDstFilePath); | ||
549 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, m_pMuxer, m_pFileWriter, GUID_NULL, GUID_NULL, 1); | ||
550 : | |||
551 : | if ((hr == S_OK) && ((in_Pass ==2) || (!m_pXvidEncoder))) hr = AddAudioStreams(0); | ||
552 : | else if (hr == S_OK) hr = AddAudioStreams(1); | ||
553 : | |||
554 : | #if 0 | ||
555 : | IConfigAviMux *pIConfigAviMux = 0; | ||
556 : | if (hr == S_OK) hr = m_pMuxer->QueryInterface(IID_IConfigAviMux, (void **)&pIConfigAviMux); | ||
557 : | pIConfigAviMux->SetMasterStream(0); | ||
558 : | if (pIConfigAviMux) pIConfigAviMux->Release(); | ||
559 : | #endif | ||
560 : | |||
561 : | if (pVMeterInVideoPin) pVMeterInVideoPin->Release(); | ||
562 : | if (pOutVideoPin) pOutVideoPin->Release(); | ||
563 : | DeleteFile(m_szDstFilePath); | ||
564 : | //AddToRot(m_pGraph, &dwReg); | ||
565 : | |||
566 : | if (hr == S_OK && in_Pass != 2) { // Make progress bar visible | ||
567 : | Isibaar | 2017 | TCHAR buf[MAX_PATH+50], buf2[MAX_PATH]; |
568 : | Isibaar | 2019 | if (_tcslen(m_szSourceFilePath) > 60) { |
569 : | Isibaar | 2017 | PathCompactPathEx(buf2, m_szSourceFilePath, 60, 0); |
570 : | Isibaar | 2019 | _stprintf(buf, TEXT("Converting %s"), buf2); |
571 : | Isibaar | 2017 | } |
572 : | else | ||
573 : | Isibaar | 2019 | _stprintf(buf, TEXT("Converting %s..."), m_szSourceFilePath); |
574 : | Isibaar | 2017 | |
575 : | Irhall | 2014 | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_HIDE); |
576 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_HIDE); | ||
577 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_HIDE); | ||
578 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_HIDE); | ||
579 : | ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_HIDE); | ||
580 : | ShowWindow(m_ProgressWnd, SW_SHOW); | ||
581 : | SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, buf); | ||
582 : | } | ||
583 : | |||
584 : | return hr; | ||
585 : | } | ||
586 : | |||
587 : | HRESULT | ||
588 : | RecompressGraph::AddAudioStreams(int check_only) | ||
589 : | { | ||
590 : | IPin *pOutPin=0, *pInPin = 0; | ||
591 : | PIN_INFO PinInfo = {NULL}; | ||
592 : | HRESULT hr = S_OK; | ||
593 : | int bFraunhoferPro = 0; | ||
594 : | |||
595 : | HKEY hKey; | ||
596 : | DWORD size = MAX_PATH; | ||
597 : | TCHAR kvalue[MAX_PATH]; | ||
598 : | RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"), 0, KEY_READ, &hKey); | ||
599 : | if (RegQueryValueEx(hKey, TEXT("msacm.l3acm"), 0, 0, (LPBYTE)kvalue, &size) != ERROR_SUCCESS) | ||
600 : | bFraunhoferPro = 0; | ||
601 : | else { | ||
602 : | // C:\WINDOWS\System32\l3codecp.acm was not recognized | ||
603 : | Isibaar | 2019 | int sLen = _tcslen(kvalue); |
604 : | if ((sLen >= 12) && (_tcscmp(&(kvalue[sLen - 12]), TEXT("l3codecp.acm")) == 0)) | ||
605 : | Irhall | 2014 | bFraunhoferPro = 1; |
606 : | } | ||
607 : | |||
608 : | if (m_pVideoMeter) { | ||
609 : | if (GetFilterPin(m_pVideoMeter, PINDIR_INPUT, 1, &pInPin, | ||
610 : | MEDIATYPE_Video, GUID_NULL) == S_OK) | ||
611 : | { | ||
612 : | hr = pInPin->ConnectedTo(&pOutPin); | ||
613 : | if (hr == S_OK) hr = pOutPin->QueryPinInfo(&PinInfo); | ||
614 : | if (pOutPin) pOutPin->Release(); | ||
615 : | if (pInPin) pInPin->Release(); | ||
616 : | } | ||
617 : | } else hr = m_pSrcFilter->QueryInterface(IID_IBaseFilter, (void **)&PinInfo.pFilter); | ||
618 : | |||
619 : | IPin *pAudioPin = 0; | ||
620 : | if (check_only) { | ||
621 : | if ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0, | ||
622 : | &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK)) | ||
623 : | { | ||
624 : | AM_MEDIA_TYPE *paomt = 0; | ||
625 : | int bNeedsRecompression = 0; | ||
626 : | IEnumMediaTypes *pAmtEnum = 0; | ||
627 : | hr = pAudioPin->EnumMediaTypes(&pAmtEnum); | ||
628 : | |||
629 : | if (hr == S_OK) { | ||
630 : | hr = pAmtEnum->Reset(); | ||
631 : | if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0); | ||
632 : | if (hr == S_OK && paomt->subtype.Data1 != 0x55 && | ||
633 : | (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3 | ||
634 : | { | ||
635 : | bNeedsRecompression = 1; | ||
636 : | m_bFileCopy = 0; // file copy strategy cannot be used on this input | ||
637 : | } | ||
638 : | else if (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags & 4) { // VBR | ||
639 : | bNeedsRecompression = 1; | ||
640 : | } | ||
641 : | if (pAmtEnum) pAmtEnum->Release(); | ||
642 : | pAmtEnum = 0; | ||
643 : | if (paomt) DeleteMediaType(paomt); | ||
644 : | if (hr == S_OK && bNeedsRecompression && !bFraunhoferPro) { | ||
645 : | //MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0); | ||
646 : | hr = VFW_E_CANNOT_CONNECT; | ||
647 : | } | ||
648 : | } | ||
649 : | pAudioPin->Release(); | ||
650 : | } | ||
651 : | } | ||
652 : | else { | ||
653 : | while ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0, | ||
654 : | &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK)) | ||
655 : | { | ||
656 : | AM_MEDIA_TYPE *paomt = 0; | ||
657 : | int bNeedsRecompression = 0; | ||
658 : | IEnumMediaTypes *pAmtEnum = 0; | ||
659 : | hr = pAudioPin->EnumMediaTypes(&pAmtEnum); | ||
660 : | if (hr == S_OK) { | ||
661 : | hr = pAmtEnum->Reset(); | ||
662 : | if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0); | ||
663 : | if ((hr == S_OK) && (paomt->subtype.Data1 != 0x55) && | ||
664 : | (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3 | ||
665 : | { | ||
666 : | bNeedsRecompression = 1; | ||
667 : | m_bFileCopy = 0; // file copy strategy cannot be used on this input | ||
668 : | } | ||
669 : | else if (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags & 4) { // VBR | ||
670 : | bNeedsRecompression = 1; | ||
671 : | } | ||
672 : | if (pAmtEnum) pAmtEnum->Release(); | ||
673 : | pAmtEnum = 0; | ||
674 : | |||
675 : | if (paomt) DeleteMediaType(paomt); | ||
676 : | if (hr == S_OK && bNeedsRecompression) { | ||
677 : | |||
678 : | IBaseFilter *pAudioCompressor = 0; | ||
679 : | hr = AddDirectXFilterByMoniker(CLSID_AudioCompressorCategory, "MPEG Layer-3", &pAudioCompressor, 0); | ||
680 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pAudioCompressor, 0); | ||
681 : | |||
682 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pAudioCompressor, MEDIATYPE_Audio, GUID_NULL, 0); | ||
683 : | |||
684 : | IPin *pMp3Pin = 0; | ||
685 : | if (hr == S_OK) hr = GetFilterPin(pAudioCompressor, PINDIR_OUTPUT, 0, &pMp3Pin, MEDIATYPE_Audio, GUID_NULL); | ||
686 : | IEnumMediaTypes *pMp3MtEnum = 0; | ||
687 : | |||
688 : | if (hr == S_OK) hr = pMp3Pin->EnumMediaTypes(&pMp3MtEnum); | ||
689 : | AM_MEDIA_TYPE *pMp3mt = 0; | ||
690 : | int bConnected = 0; | ||
691 : | |||
692 : | if (hr == S_OK) { | ||
693 : | while (!bConnected && (hr = pMp3MtEnum->Next(1, &pMp3mt, 0)) == S_OK) { | ||
694 : | MPEGLAYER3WAVEFORMAT *pMp3cb = (MPEGLAYER3WAVEFORMAT *)pMp3mt->pbFormat; | ||
695 : | if ( | ||
696 : | //pMp3cb->nSamplesPerSec == 44100 && | ||
697 : | pMp3cb->wfx.nAvgBytesPerSec == 16000) | ||
698 : | { | ||
699 : | CUnknown *pMp3Normalizer = 0; | ||
700 : | IBaseFilter *pIMp3Normalizer = 0; | ||
701 : | // Type 2 - only 16000 Bps = 128kbit audio | ||
702 : | if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 2); | ||
703 : | if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter, | ||
704 : | (void **)&pIMp3Normalizer); | ||
705 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0); | ||
706 : | |||
707 : | IPin *pNormMp3Pin = 0; | ||
708 : | if (hr == S_OK) hr = GetFilterPin(pIMp3Normalizer, PINDIR_INPUT, 0, &pNormMp3Pin, GUID_NULL, GUID_NULL); | ||
709 : | if (hr == S_OK) hr = m_pGraph->ConnectDirect(pMp3Pin, pNormMp3Pin, pMp3mt); | ||
710 : | if (pNormMp3Pin) pNormMp3Pin->Release(); | ||
711 : | |||
712 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, GUID_NULL, GUID_NULL, 1); | ||
713 : | if (pIMp3Normalizer) pIMp3Normalizer->Release(); | ||
714 : | if (hr == S_OK) bConnected = 1; | ||
715 : | } | ||
716 : | DeleteMediaType(pMp3mt); | ||
717 : | } | ||
718 : | } | ||
719 : | if ((!bConnected || !bFraunhoferPro) && hr == S_OK) hr = VFW_E_CANNOT_CONNECT; | ||
720 : | //if (hr == S_OK && !bFraunhoferPro) MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0); | ||
721 : | if (pMp3Pin) pMp3Pin->Release(); | ||
722 : | if (pMp3MtEnum) pMp3MtEnum->Release(); | ||
723 : | if (pAudioCompressor) pAudioCompressor->Release(); | ||
724 : | } | ||
725 : | else { | ||
726 : | CUnknown *pMp3Normalizer = 0; | ||
727 : | IBaseFilter *pIMp3Normalizer = 0; | ||
728 : | |||
729 : | if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 1); | ||
730 : | if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&pIMp3Normalizer); | ||
731 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0); | ||
732 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pIMp3Normalizer, MEDIATYPE_Audio, GUID_NULL, 0); | ||
733 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, MEDIATYPE_Audio, GUID_NULL, 0); | ||
734 : | if (pIMp3Normalizer) pIMp3Normalizer->Release(); | ||
735 : | } | ||
736 : | if (hr == S_OK && PinInfo.pFilter == m_pSrcFilter) m_UsedStreamsCnt++; | ||
737 : | } | ||
738 : | pAudioPin->Release(); | ||
739 : | } | ||
740 : | } | ||
741 : | |||
742 : | if (PinInfo.pFilter) PinInfo.pFilter->Release(); | ||
743 : | return hr; | ||
744 : | } | ||
745 : | |||
746 : | HRESULT | ||
747 : | RecompressGraph::AddFilterByCLSID(GUID *in_Filter, IBaseFilter **out_pFilter) | ||
748 : | { | ||
749 : | HRESULT hr = CoCreateInstance(*in_Filter, NULL, CLSCTX_INPROC_SERVER, | ||
750 : | IID_IBaseFilter, (void **)out_pFilter); | ||
751 : | if (hr == S_OK) hr = m_pGraph->AddFilter(*out_pFilter, NULL); | ||
752 : | |||
753 : | return hr; | ||
754 : | } | ||
755 : | |||
756 : | HRESULT | ||
757 : | RecompressGraph::SetDstFileName(LPCTSTR in_szFilePath) | ||
758 : | { | ||
759 : | if (m_pGraph) | ||
760 : | return E_UNEXPECTED; | ||
761 : | |||
762 : | if (m_szDstFilePath) | ||
763 : | free (m_szDstFilePath); | ||
764 : | |||
765 : | Isibaar | 2019 | m_szDstFilePath = _tcsdup(in_szFilePath); |
766 : | Irhall | 2014 | |
767 : | return S_OK; | ||
768 : | } | ||
769 : | |||
770 : | HRESULT | ||
771 : | RecompressGraph::AddFileWriter(LPCTSTR in_szFilePath) | ||
772 : | { | ||
773 : | if (!m_pGraph || m_pFileWriter) | ||
774 : | return E_UNEXPECTED; | ||
775 : | |||
776 : | Isibaar | 2019 | int sLen = _tcslen(in_szFilePath); |
777 : | OLECHAR *pwName = new OLECHAR [sLen+1]; | ||
778 : | #ifndef UNICODE | ||
779 : | mbstowcs(pwName, in_szFilePath, sLen+1); | ||
780 : | #else | ||
781 : | wcsncpy(pwName, in_szFilePath, sLen+1); | ||
782 : | #endif | ||
783 : | |||
784 : | Irhall | 2014 | HRESULT hr = AddFilterByCLSID((GUID *)&CLSID_FileWriter, &m_pFileWriter); |
785 : | IFileSinkFilter* pDst=0; | ||
786 : | if (hr == S_OK) hr = m_pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)(&pDst)); | ||
787 : | Isibaar | 2019 | if (hr == S_OK) hr = pDst->SetFileName(pwName, &m_DstFileMediaType); |
788 : | delete [] pwName; | ||
789 : | Irhall | 2014 | if (pDst) |
790 : | pDst->Release(); | ||
791 : | |||
792 : | return hr; | ||
793 : | } | ||
794 : | |||
795 : | HRESULT | ||
796 : | RecompressGraph::AddSourceFile(LPCTSTR in_szFilePath) | ||
797 : | { | ||
798 : | if (m_pGraph) return E_UNEXPECTED; | ||
799 : | |||
800 : | if (m_szSourceFilePath) | ||
801 : | free (m_szSourceFilePath); | ||
802 : | |||
803 : | Isibaar | 2019 | m_szSourceFilePath = _tcsdup(in_szFilePath); |
804 : | Irhall | 2014 | |
805 : | return S_OK; | ||
806 : | } | ||
807 : | |||
808 : | HRESULT | ||
809 : | RecompressGraph::AddSourceFilter(LPCTSTR in_szFilePath) | ||
810 : | { | ||
811 : | if (!m_pGraph || m_pSrcFilter) return E_UNEXPECTED; | ||
812 : | |||
813 : | Isibaar | 2019 | int sLen = _tcslen(in_szFilePath); |
814 : | OLECHAR *pwName = new OLECHAR [sLen+1]; | ||
815 : | #ifndef UNICODE | ||
816 : | mbstowcs(pwName, in_szFilePath, sLen+1); | ||
817 : | #else | ||
818 : | wcsncpy(pwName, in_szFilePath, sLen+1); | ||
819 : | #endif | ||
820 : | Irhall | 2014 | |
821 : | Isibaar | 2019 | HRESULT hr = m_pGraph->AddSourceFilter(pwName, L"Source filter", &m_pSrcFilter); |
822 : | |||
823 : | Irhall | 2014 | #if 0 |
824 : | HRESULT hr = AddFilterByCLSID((GUID *)&CLSID_AsyncReader, &this->m_pSrcFilter); | ||
825 : | IFileSourceFilter* pSrc =0 ; | ||
826 : | if (hr == S_OK) hr = m_pSrcFilter->QueryInterface(IID_IFileSourceFilter, (void **)(&pSrc)); | ||
827 : | if (hr == S_OK) hr = pSrc->Load(pwName, &m_SrcFileMediaType); | ||
828 : | if (pSrc) pSrc->Release(); | ||
829 : | #endif | ||
830 : | |||
831 : | Isibaar | 2019 | delete [] pwName; |
832 : | |||
833 : | Irhall | 2014 | return hr; |
834 : | } | ||
835 : | |||
836 : | HRESULT | ||
837 : | RecompressGraph::SetProgress(int elapsedSize, int totalSize) | ||
838 : | { | ||
839 : | |||
840 : | m_elapsedSize = elapsedSize; | ||
841 : | m_totalSize = totalSize; | ||
842 : | |||
843 : | return S_OK; | ||
844 : | } | ||
845 : | |||
846 : | HRESULT | ||
847 : | RecompressGraph::Recompress() | ||
848 : | { | ||
849 : | if (!m_pGraph) return E_UNEXPECTED; | ||
850 : | |||
851 : | IMediaEvent *pEvent = 0; | ||
852 : | IMediaControl *pControl = 0; | ||
853 : | HRESULT hr = S_OK; | ||
854 : | |||
855 : | if (hr == S_OK && m_bFileCopy == 1 && | ||
856 : | fourcc_helper(m_szSourceFilePath, NULL, NULL, 1)==0) // check input is AVI ! | ||
857 : | { | ||
858 : | if (!CopyFileEx(m_szSourceFilePath, m_szDstFilePath, | ||
859 : | CopyProgressRoutine, this, FALSE, 0) || m_bBreakRequested) { | ||
860 : | hr = E_FAIL; | ||
861 : | DeleteFile(m_szDstFilePath); | ||
862 : | } | ||
863 : | |||
864 : | goto finish_recompress; | ||
865 : | } | ||
866 : | |||
867 : | hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); | ||
868 : | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); | ||
869 : | |||
870 : | IRecProgressNotify *pBitrateProgressNotify=0; | ||
871 : | OAFilterState oas; | ||
872 : | long E=0; | ||
873 : | |||
874 : | if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify, | ||
875 : | (void **)&pBitrateProgressNotify); | ||
876 : | |||
877 : | //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify); | ||
878 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_TotalFrames); | ||
879 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd); | ||
880 : | |||
881 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize); | ||
882 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize); | ||
883 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize); | ||
884 : | |||
885 : | if (m_pXvidEncoder) { | ||
886 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(0); | ||
887 : | |||
888 : | m_pXvidConfig->Release(); | ||
889 : | m_pXvidConfig = 0; | ||
890 : | |||
891 : | if (hr == S_OK) { | ||
892 : | hr = pControl->Run(); | ||
893 : | if (hr == S_OK) { | ||
894 : | do hr = pControl->GetState(1000, &oas); | ||
895 : | while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE); | ||
896 : | } | ||
897 : | } | ||
898 : | |||
899 : | //long Evt, P1, P2; | ||
900 : | //if (hr == S_OK) do hr = pEvent->GetEvent(&Evt, &P1, &P2, INFINITE); | ||
901 : | //while (Evt != EC_COMPLETE && Evt != 3 && Evt != 2); | ||
902 : | if (hr == S_OK) hr = pEvent->WaitForCompletion(INFINITE, &E); | ||
903 : | |||
904 : | if (pControl) { | ||
905 : | HRESULT hrTmp; | ||
906 : | if (E == EC_USERABORT) m_pSrcFilter->Stop(); | ||
907 : | hrTmp = pControl->Stop(); | ||
908 : | do hrTmp = pControl->GetState(1000, &oas); | ||
909 : | while ((oas != State_Stopped && hrTmp == S_OK ) || | ||
910 : | hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE); | ||
911 : | if (hr == S_OK) hr = hrTmp; | ||
912 : | } | ||
913 : | if (E == EC_ERRORABORT) hr = E_FAIL; | ||
914 : | |||
915 : | // End of pass 1 | ||
916 : | pBitrateProgressNotify->GetDimensions(m_Width, m_Height); | ||
917 : | pBitrateProgressNotify->GetBitrate(m_CountedFrames, m_TotalFramesSize); | ||
918 : | pBitrateProgressNotify->Release(); | ||
919 : | pBitrateProgressNotify = 0; | ||
920 : | Isibaar | 2019 | TCHAR *pSrcStr = _tcsdup(m_szSourceFilePath); |
921 : | TCHAR *pDstStr = _tcsdup(m_szDstFilePath); | ||
922 : | Irhall | 2014 | |
923 : | pControl->Release(); | ||
924 : | pEvent->Release(); | ||
925 : | pControl = 0; | ||
926 : | pEvent = 0; | ||
927 : | int bBreakRequested = m_bBreakRequested; | ||
928 : | //if (hr == S_OK) | ||
929 : | CleanUp(); | ||
930 : | m_szSourceFilePath = pSrcStr; | ||
931 : | m_szDstFilePath = pDstStr; | ||
932 : | |||
933 : | if (bBreakRequested || hr != S_OK) { | ||
934 : | DeleteFile(m_szDstFilePath); | ||
935 : | Isibaar | 2019 | DeleteFile(Pass_FILE); |
936 : | Irhall | 2014 | hr = E_FAIL; |
937 : | goto finish_recompress; | ||
938 : | } | ||
939 : | |||
940 : | if (hr == S_OK) hr = CreateGraph(m_ProgressWnd, 2); | ||
941 : | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); | ||
942 : | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); | ||
943 : | |||
944 : | if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify, | ||
945 : | (void **)&pBitrateProgressNotify); | ||
946 : | //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify); | ||
947 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_CountedFrames); | ||
948 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd); | ||
949 : | |||
950 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(2); | ||
951 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize); | ||
952 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize); | ||
953 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize); | ||
954 : | } | ||
955 : | else { | ||
956 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(1); | ||
957 : | } | ||
958 : | |||
959 : | DeleteFile(m_szDstFilePath); | ||
960 : | |||
961 : | if (hr == S_OK) { | ||
962 : | hr = pControl->Run(); | ||
963 : | if (hr == S_OK) { | ||
964 : | do hr = pControl->GetState(1000, &oas); | ||
965 : | while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE); | ||
966 : | } | ||
967 : | } | ||
968 : | |||
969 : | #if 0 | ||
970 : | long Evt, P1, P2; | ||
971 : | if (hr == S_OK) do hr = pEvent->GetEvent(&Evt, &P1, &P2, INFINITE); | ||
972 : | while (Evt != EC_COMPLETE && Evt != 3 && Evt != 2); | ||
973 : | |||
974 : | for (int iCnt=0; (iCnt < m_UsedStreamsCnt) && (hr == S_OK); iCnt++) { | ||
975 : | if (hr == S_OK) do hr = pEvent->WaitForCompletion(INFINITE, &E); | ||
976 : | while (hr == S_OK && E != 1); | ||
977 : | } | ||
978 : | #endif | ||
979 : | if (hr == S_OK) hr = pEvent->WaitForCompletion(INFINITE, &E); | ||
980 : | |||
981 : | if (pControl) { | ||
982 : | if (E == EC_USERABORT) m_pSrcFilter->Stop(); | ||
983 : | HRESULT hrTmp = pControl->Stop(); | ||
984 : | do hrTmp = pControl->GetState(1000, &oas); | ||
985 : | while ((oas != State_Stopped && hrTmp == S_OK ) || | ||
986 : | hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE); | ||
987 : | if (hr == S_OK) hr = hrTmp; | ||
988 : | } | ||
989 : | if (E == EC_ERRORABORT) hr = E_FAIL; | ||
990 : | |||
991 : | if (pControl) pControl->Release(); | ||
992 : | if (pEvent) pEvent->Release(); | ||
993 : | if (pBitrateProgressNotify) pBitrateProgressNotify->Release(); | ||
994 : | |||
995 : | Isibaar | 2019 | DeleteFile(Pass_FILE); |
996 : | Irhall | 2014 | |
997 : | finish_recompress: | ||
998 : | |||
999 : | if (m_bFileCopy && (hr != E_FAIL)) | ||
1000 : | fourcc_helper(m_szDstFilePath, "XVID", "xvid", 0); | ||
1001 : | |||
1002 : | if ((E == EC_COMPLETE || (m_bFileCopy && hr != E_FAIL)) && | ||
1003 : | ((int)(m_elapsedSize+m_curSize) >= m_totalSize)) | ||
1004 : | { | ||
1005 : | MessageBox(ghDlg, TEXT("Conversion finished!"), APP_NAME, 0); | ||
1006 : | } | ||
1007 : | |||
1008 : | m_Width = m_Height = 0; | ||
1009 : | |||
1010 : | if ((int)(m_elapsedSize+m_curSize) >= m_totalSize) | ||
1011 : | { | ||
1012 : | SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, TEXT("Source file:")); | ||
1013 : | SetDlgItemText(ghDlg, IDC_EDIT_SRC, TEXT("")); | ||
1014 : | SetDlgItemText(ghDlg, IDC_EDIT_DST, TEXT("")); | ||
1015 : | ShowWindow(m_ProgressWnd, SW_HIDE); | ||
1016 : | ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_SHOW); | ||
1017 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_SHOW); | ||
1018 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_SHOW); | ||
1019 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_SHOW); | ||
1020 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_SHOW); | ||
1021 : | OpenFilePath[0] = TEXT('\0'); | ||
1022 : | OpenFilePath[1] = TEXT('\0'); | ||
1023 : | sOfn.lpstrFile[0] = TEXT('\0'); | ||
1024 : | sOfn.lpstrFile[1] = TEXT('\0'); | ||
1025 : | SaveFilePath[0] = TEXT('\0'); | ||
1026 : | } | ||
1027 : | |||
1028 : | return hr; | ||
1029 : | } | ||
1030 : | |||
1031 : | void | ||
1032 : | RecompressGraph::BreakConversion() | ||
1033 : | { | ||
1034 : | m_bBreakRequested = 1; | ||
1035 : | if (m_pGraph) { | ||
1036 : | IMediaEventSink *pSink = 0; | ||
1037 : | m_pGraph->QueryInterface(IID_IMediaEventSink, (void **)&pSink); | ||
1038 : | |||
1039 : | if (pSink) { | ||
1040 : | pSink->Notify(EC_USERABORT, 0, 0); | ||
1041 : | pSink->Release(); | ||
1042 : | } | ||
1043 : | } | ||
1044 : | } | ||
1045 : | |||
1046 : | |||
1047 : | //////////////////////////////////////////////////////////////////////////////// | ||
1048 : | // main.cpp | ||
1049 : | |||
1050 : | DWORD WINAPI | ||
1051 : | RecompressThreadProc(LPVOID xParam) | ||
1052 : | { | ||
1053 : | CoInitialize(0); | ||
1054 : | |||
1055 : | int error = 0; | ||
1056 : | int nbInputFiles = 1; | ||
1057 : | int totalSize = 0; | ||
1058 : | int elapsedSize = 0; | ||
1059 : | TCHAR *NextFileName = SrcFile; | ||
1060 : | TCHAR tempFile[2*MAX_PATH]; | ||
1061 : | |||
1062 : | Isibaar | 2019 | if(SrcFile[_tcslen(SrcFile) + 1] != TEXT('\0')) // Multiple input files? |
1063 : | Irhall | 2014 | { |
1064 : | nbInputFiles = 0; | ||
1065 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1066 : | Irhall | 2014 | |
1067 : | while(NextFileName[0] != L'\0') // Count total filesize and number of source files | ||
1068 : | { | ||
1069 : | DWORD filesize; | ||
1070 : | PathCombine(tempFile, SrcFile, NextFileName); | ||
1071 : | DetermineFileSize(tempFile, &filesize); | ||
1072 : | totalSize += filesize; | ||
1073 : | |||
1074 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1075 : | Irhall | 2014 | nbInputFiles++; |
1076 : | } | ||
1077 : | } | ||
1078 : | |||
1079 : | NextFileName = SrcFile; | ||
1080 : | if (nbInputFiles > 1) { | ||
1081 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; // Bypass dir and jump to first filename |
1082 : | Irhall | 2014 | } |
1083 : | |||
1084 : | HRESULT hr = S_OK; | ||
1085 : | int count = 0; | ||
1086 : | |||
1087 : | while ((count < nbInputFiles) && (hr == S_OK)) { | ||
1088 : | TCHAR szDstPath[2*MAX_PATH]; | ||
1089 : | |||
1090 : | count++; | ||
1091 : | |||
1092 : | if (nbInputFiles == 1) { | ||
1093 : | Isibaar | 2019 | _tcscpy(tempFile, SrcFile); // Src |
1094 : | Irhall | 2014 | |
1095 : | PathStripPath(SrcFile); | ||
1096 : | |||
1097 : | Isibaar | 2019 | LPTSTR ext = PathFindExtension(SrcFile); |
1098 : | Irhall | 2014 | TCHAR sztmpPath[2*MAX_PATH]; |
1099 : | Isibaar | 2019 | _tcsncpy(sztmpPath, SrcFile, (ext-SrcFile)); |
1100 : | Irhall | 2014 | sztmpPath[ext-SrcFile] = TEXT('\0'); |
1101 : | Isibaar | 2019 | _stprintf(sztmpPath, TEXT("%s_Xvid.avi"), sztmpPath); |
1102 : | Irhall | 2014 | |
1103 : | PathCombine(szDstPath, DstFile, sztmpPath); // Dst | ||
1104 : | } | ||
1105 : | else { | ||
1106 : | PathCombine(tempFile, SrcFile, NextFileName); // Src | ||
1107 : | |||
1108 : | Isibaar | 2019 | LPTSTR ext = PathFindExtension(NextFileName); |
1109 : | Irhall | 2014 | TCHAR sztmpPath[2*MAX_PATH]; |
1110 : | Isibaar | 2019 | _tcsncpy(sztmpPath, NextFileName, (ext-NextFileName)); |
1111 : | Irhall | 2014 | sztmpPath[ext-NextFileName] = TEXT('\0'); |
1112 : | Isibaar | 2019 | _stprintf(sztmpPath, TEXT("%s_Xvid.avi"), sztmpPath); |
1113 : | Irhall | 2014 | |
1114 : | PathCombine(szDstPath, DstFile, sztmpPath); // Dst | ||
1115 : | |||
1116 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1117 : | Irhall | 2014 | } |
1118 : | |||
1119 : | pRec->CleanUp(); | ||
1120 : | |||
1121 : | pRec->AddSourceFile(tempFile); | ||
1122 : | pRec->SetDstFileName(szDstPath); | ||
1123 : | pRec->SetProgress(elapsedSize, totalSize); | ||
1124 : | |||
1125 : | hr = pRec->CreateGraph((HWND)xParam, 1); | ||
1126 : | |||
1127 : | if (hr == S_OK) { | ||
1128 : | hr = pRec->Recompress(); | ||
1129 : | |||
1130 : | if (hr != S_OK) { | ||
1131 : | MessageBox((HWND)xParam, TEXT("Error: Conversion failure."), APP_NAME, MB_OK); | ||
1132 : | goto finish_thread; | ||
1133 : | } | ||
1134 : | } | ||
1135 : | else { | ||
1136 : | if (nbInputFiles == 1) | ||
1137 : | MessageBox((HWND)xParam, TEXT("Error: Source file not supported."), APP_NAME, MB_OK); | ||
1138 : | else | ||
1139 : | error = 1; // show message later | ||
1140 : | } | ||
1141 : | |||
1142 : | DWORD filesize; | ||
1143 : | DetermineFileSize(tempFile, &filesize); | ||
1144 : | |||
1145 : | elapsedSize += filesize; | ||
1146 : | } | ||
1147 : | |||
1148 : | finish_thread: | ||
1149 : | pRec->CleanUp(); | ||
1150 : | |||
1151 : | if (error) | ||
1152 : | MessageBox((HWND)xParam, | ||
1153 : | TEXT("Error: One or more input files could not be successfully converted!"), APP_NAME, MB_OK); | ||
1154 : | |||
1155 : | EnableWindow(GetDlgItem(ghDlg, IDC_BUTTON_START), 1); | ||
1156 : | |||
1157 : | CoUninitialize(); | ||
1158 : | return 0; | ||
1159 : | } | ||
1160 : | |||
1161 : | ////////////////////////////////////////////////////////////////////////////// | ||
1162 : | |||
1163 : | // Callback for GetOpenFileName hook | ||
1164 : | unsigned int CALLBACK | ||
1165 : | DialogHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | ||
1166 : | { | ||
1167 : | static HWND hwndParentDialog; | ||
1168 : | LPOFNOTIFY lpofn; | ||
1169 : | int cbLength; | ||
1170 : | static LPTSTR lpsz; | ||
1171 : | static int LastLen; | ||
1172 : | |||
1173 : | switch (uMsg) | ||
1174 : | { | ||
1175 : | case WM_INITDIALOG: | ||
1176 : | if(!SetProp(GetParent(hwnd), TEXT("OFN"), (void *) lParam)) | ||
1177 : | MessageBox(0, TEXT("SetProp() Failed"), APP_NAME, MB_OK); | ||
1178 : | return 0; | ||
1179 : | |||
1180 : | case WM_COMMAND: | ||
1181 : | break; | ||
1182 : | |||
1183 : | case WM_NOTIFY: | ||
1184 : | lpofn = (LPOFNOTIFY) lParam; | ||
1185 : | |||
1186 : | switch (lpofn->hdr.code) | ||
1187 : | { | ||
1188 : | case CDN_SELCHANGE: | ||
1189 : | LPOPENFILENAME lpofn; | ||
1190 : | cbLength = CommDlg_OpenSave_GetSpec(GetParent(hwnd), NULL, 0); | ||
1191 : | cbLength += _MAX_PATH; | ||
1192 : | |||
1193 : | lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd), TEXT("OFN")); | ||
1194 : | |||
1195 : | if ((int)lpofn->nMaxFile < cbLength) | ||
1196 : | { | ||
1197 : | // Free any previously allocated buffer. | ||
1198 : | if(lpsz) { | ||
1199 : | HeapFree(GetProcessHeap(), 0, lpsz); | ||
1200 : | } | ||
1201 : | // Allocate a new buffer | ||
1202 : | lpsz = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength*sizeof(TCHAR)); | ||
1203 : | if (lpsz) | ||
1204 : | { | ||
1205 : | lpofn->lpstrFile = lpsz; | ||
1206 : | lpofn->nMaxFile = cbLength; | ||
1207 : | } | ||
1208 : | } | ||
1209 : | break; | ||
1210 : | } | ||
1211 : | return 0; | ||
1212 : | |||
1213 : | case WM_DESTROY: | ||
1214 : | RemoveProp(GetParent(hwnd), TEXT("OFN")); | ||
1215 : | return 0; | ||
1216 : | } | ||
1217 : | |||
1218 : | return 0; | ||
1219 : | } | ||
1220 : | |||
1221 : | ////////////////////////////////////////////////////////////////////////////// | ||
1222 : | |||
1223 : | BOOL | ||
1224 : | GetFolderSelection(HWND hWnd, LPTSTR szBuf, LPCTSTR szTitle) | ||
1225 : | { | ||
1226 : | LPITEMIDLIST pidl = NULL; | ||
1227 : | BROWSEINFO bi = { 0 }; | ||
1228 : | BOOL bResult = FALSE; | ||
1229 : | |||
1230 : | bi.hwndOwner = hWnd; | ||
1231 : | bi.pszDisplayName = szBuf; | ||
1232 : | bi.pidlRoot = NULL; | ||
1233 : | bi.lpszTitle = szTitle; | ||
1234 : | bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; | ||
1235 : | |||
1236 : | if ((pidl = SHBrowseForFolder(&bi)) != NULL) | ||
1237 : | { | ||
1238 : | bResult = SHGetPathFromIDList(pidl, szBuf); | ||
1239 : | CoTaskMemFree(pidl); | ||
1240 : | } | ||
1241 : | |||
1242 : | return bResult; | ||
1243 : | } | ||
1244 : | |||
1245 : | ////////////////////////////////////////////////////////////////////////////// | ||
1246 : | |||
1247 : | LRESULT CALLBACK | ||
1248 : | DIALOG_MAIN(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | ||
1249 : | { | ||
1250 : | static HICON hIcon; | ||
1251 : | |||
1252 : | switch (message) | ||
1253 : | { | ||
1254 : | case WM_INITDIALOG: | ||
1255 : | HWND hwndOwner; | ||
1256 : | RECT rc, rcDlg, rcOwner; | ||
1257 : | |||
1258 : | if ((hwndOwner = GetParent(hDlg)) == NULL) | ||
1259 : | { | ||
1260 : | hwndOwner = GetDesktopWindow(); | ||
1261 : | } | ||
1262 : | |||
1263 : | GetWindowRect(hwndOwner, &rcOwner); | ||
1264 : | GetWindowRect(hDlg, &rcDlg); | ||
1265 : | CopyRect(&rc, &rcOwner); | ||
1266 : | |||
1267 : | OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); | ||
1268 : | OffsetRect(&rc, -rc.left, -rc.top); | ||
1269 : | OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); | ||
1270 : | |||
1271 : | SetWindowPos(hDlg, HWND_TOP, | ||
1272 : | rcOwner.left + (rc.right / 2), | ||
1273 : | rcOwner.top + (rc.bottom / 2), | ||
1274 : | 0, 0, SWP_NOSIZE); | ||
1275 : | |||
1276 : | hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 32, 32, 0); | ||
1277 : | SendMessage(hDlg, WM_SETICON, ICON_BIG , (LPARAM)hIcon); | ||
1278 : | ghDlg = hDlg; | ||
1279 : | return TRUE; | ||
1280 : | |||
1281 : | case WM_DESTROY: | ||
1282 : | DestroyIcon(hIcon); | ||
1283 : | PostQuitMessage(0); | ||
1284 : | break; | ||
1285 : | |||
1286 : | case WM_COMMAND: | ||
1287 : | if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { | ||
1288 : | EndDialog(hDlg, LOWORD(wParam)); | ||
1289 : | return TRUE; | ||
1290 : | } | ||
1291 : | else if (LOWORD(wParam) == IDC_BUTTON_SRC) { | ||
1292 : | sOfn.hwndOwner = hDlg; | ||
1293 : | |||
1294 : | GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath)); | ||
1295 : | |||
1296 : | Isibaar | 2019 | if (_tcslen(sOfn.lpstrFile) == 0) { |
1297 : | _stprintf(sOfn.lpstrFile, TEXT("%s"), OpenFilePath); | ||
1298 : | Irhall | 2014 | } |
1299 : | |||
1300 : | if (GetOpenFileName(&sOfn)) { | ||
1301 : | Isibaar | 2019 | if(sOfn.lpstrFile[_tcslen(sOfn.lpstrFile) + 1] != TEXT('\0')) // Multiple input files? |
1302 : | _stprintf(OpenFilePath, TEXT("%s (multiselect)"), sOfn.lpstrFile); | ||
1303 : | Irhall | 2014 | else |
1304 : | Isibaar | 2019 | _stprintf(OpenFilePath, TEXT("%s"), sOfn.lpstrFile); |
1305 : | Irhall | 2014 | |
1306 : | SetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath); | ||
1307 : | } | ||
1308 : | } | ||
1309 : | else if (LOWORD(wParam) == IDC_BUTTON_DST) { | ||
1310 : | sSfn.hwndOwner = hDlg; | ||
1311 : | GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0])); | ||
1312 : | if (GetFolderSelection(hDlg, SaveFilePath, TEXT("Please select the output folder"))) { | ||
1313 : | SetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath); | ||
1314 : | } | ||
1315 : | } | ||
1316 : | else if (LOWORD(wParam) == IDC_BUTTON_START) { | ||
1317 : | GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0])); | ||
1318 : | GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath[0])); | ||
1319 : | |||
1320 : | Isibaar | 2019 | if ((_tcslen(OpenFilePath) > 0 || _tcslen(sOfn.lpstrFile) > 0) && _tcslen(SaveFilePath) > 0) { |
1321 : | Irhall | 2014 | EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), 0); |
1322 : | Isibaar | 2019 | if (_tcslen(sOfn.lpstrFile) > 0) |
1323 : | Irhall | 2014 | SrcFile = sOfn.lpstrFile; |
1324 : | else { | ||
1325 : | Isibaar | 2019 | OpenFilePath[_tcslen(OpenFilePath)+1] = TEXT('\0'); |
1326 : | Irhall | 2014 | SrcFile = OpenFilePath; |
1327 : | } | ||
1328 : | |||
1329 : | Isibaar | 2019 | _tcscpy(DstFile, SaveFilePath); |
1330 : | Irhall | 2014 | hConvertThread = CreateThread(0, 0, RecompressThreadProc, GetDlgItem(hDlg, IDC_PROGRESSBAR), 0, 0); |
1331 : | } | ||
1332 : | else | ||
1333 : | MessageBox(ghDlg, TEXT("Error: You need to select a source file and output directory first!"), APP_NAME, 0); | ||
1334 : | } | ||
1335 : | break; | ||
1336 : | } | ||
1337 : | return FALSE; | ||
1338 : | } | ||
1339 : | |||
1340 : | |||
1341 : | int APIENTRY | ||
1342 : | _tWinMain(HINSTANCE hInstance, | ||
1343 : | HINSTANCE hPrevInstance, | ||
1344 : | LPTSTR lpCmdLine, | ||
1345 : | int nCmdShow) | ||
1346 : | { | ||
1347 : | CoInitialize(0); | ||
1348 : | |||
1349 : | static TCHAR buf[2*MAX_PATH+1]; | ||
1350 : | |||
1351 : | sOfn.lStructSize = sizeof (OPENFILENAME); | ||
1352 : | sOfn.hInstance = hInstance; | ||
1353 : | #ifdef ALLOW_ONLY_AVI_INPUT | ||
1354 : | sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx)\0*.avi;*.divx\0All files\0*.*\0"); | ||
1355 : | #else | ||
1356 : | sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx;*.mp4;*.mov;*.wmv;*.asf;*.mkv)\0*.avi;*.mp4;*.mov;*.wmv;*.asf;*.divx;*.mkv\0All files\0*.*\0"); | ||
1357 : | #endif | ||
1358 : | sOfn.lpstrCustomFilter = 0; | ||
1359 : | sOfn.nMaxCustFilter = 0; | ||
1360 : | sOfn.nFilterIndex = 1; | ||
1361 : | sOfn.lpstrFileTitle = 0; | ||
1362 : | sOfn.nMaxFileTitle = 0; | ||
1363 : | sOfn.lpstrInitialDir = 0; | ||
1364 : | sOfn.lpstrTitle = TEXT("Select source file"); | ||
1365 : | sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; | ||
1366 : | sOfn.nFileOffset = 0; | ||
1367 : | sOfn.nFileExtension = 0; | ||
1368 : | sOfn.lpstrDefExt = TEXT(".avi"); | ||
1369 : | sOfn.lCustData = (LPARAM)(&sOfn); | ||
1370 : | sOfn.lpfnHook = DialogHook; | ||
1371 : | sOfn.lpTemplateName = 0; | ||
1372 : | sOfn.pvReserved = 0; | ||
1373 : | sOfn.dwReserved = 0; | ||
1374 : | sOfn.FlagsEx = 0; | ||
1375 : | sOfn.lpstrFile = buf; | ||
1376 : | sOfn.nMaxFile = 2*MAX_PATH; | ||
1377 : | sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_ENABLEHOOK; | ||
1378 : | |||
1379 : | |||
1380 : | sSfn.lStructSize = sizeof (OPENFILENAME); | ||
1381 : | sSfn.hInstance = hInstance; | ||
1382 : | sSfn.lpstrFilter = TEXT("Avi files (*.avi)\0*.avi\0"); | ||
1383 : | sSfn.lpstrCustomFilter = 0; | ||
1384 : | sSfn.nMaxCustFilter = 0; | ||
1385 : | sSfn.nFilterIndex = 1; | ||
1386 : | sSfn.lpstrFileTitle = 0; | ||
1387 : | sSfn.nMaxFileTitle = 0; | ||
1388 : | sSfn.lpstrInitialDir = 0; | ||
1389 : | sSfn.lpstrTitle = TEXT("Select target file"); | ||
1390 : | sSfn.nFileOffset = 0; | ||
1391 : | sSfn.nFileExtension = 0; | ||
1392 : | sSfn.lpstrDefExt = TEXT(".avi"); | ||
1393 : | sSfn.lpTemplateName = 0; | ||
1394 : | sSfn.pvReserved = 0; | ||
1395 : | sSfn.dwReserved = 0; | ||
1396 : | sSfn.FlagsEx = 0; | ||
1397 : | |||
1398 : | pRec = new RecompressGraph(); | ||
1399 : | DialogBox(hInstance, (LPCTSTR)IDD_DIALOG_MAIN, NULL, (DLGPROC)DIALOG_MAIN); | ||
1400 : | pRec->BreakConversion(); | ||
1401 : | if (hConvertThread != NULL) { | ||
1402 : | WaitForSingleObject(hConvertThread, INFINITE); | ||
1403 : | CloseHandle(hConvertThread); | ||
1404 : | } | ||
1405 : | |||
1406 : | delete pRec; | ||
1407 : | CoUninitialize(); | ||
1408 : | |||
1409 : | return 0; | ||
1410 : | } | ||
1411 : |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |