Parent Directory | Revision Log
Revision 2049 - (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 : | Isibaar | 2029 | m_pVideoMeter = m_pSplitter = m_pSrcFilter = m_pXvidEncoder = 0; |
163 : | Irhall | 2014 | //m_pEmmsDummy = 0; |
164 : | m_pMuxer = m_pFileWriter = m_pChgType = 0; | ||
165 : | Isibaar | 2045 | m_pIChgTypeNorm = 0; |
166 : | Irhall | 2014 | m_pXvidConfig = 0; |
167 : | m_bBreakRequested = 0; | ||
168 : | |||
169 : | Isibaar | 2029 | m_pEvent = 0; |
170 : | m_pControl = 0; | ||
171 : | Irhall | 2014 | m_elapsedSize = m_curSize = m_totalSize = 0; |
172 : | } | ||
173 : | |||
174 : | RecompressGraph::~RecompressGraph() | ||
175 : | { | ||
176 : | CleanUp(); | ||
177 : | } | ||
178 : | |||
179 : | void | ||
180 : | RecompressGraph::CleanUp() | ||
181 : | { | ||
182 : | m_UsedStreamsCnt = 0; | ||
183 : | |||
184 : | if (m_szSourceFilePath) | ||
185 : | free (m_szSourceFilePath); | ||
186 : | |||
187 : | if (m_szDstFilePath) | ||
188 : | free (m_szDstFilePath); | ||
189 : | |||
190 : | if (m_pXvidCfgRec) | ||
191 : | free(m_pXvidCfgRec); | ||
192 : | |||
193 : | m_pXvidCfgRec = 0; | ||
194 : | m_bBreakRequested = 0; | ||
195 : | |||
196 : | m_szSourceFilePath = m_szDstFilePath = 0; | ||
197 : | m_curSize = 0; | ||
198 : | |||
199 : | if (m_pVideoMeter) { | ||
200 : | m_pGraph->RemoveFilter(m_pVideoMeter); | ||
201 : | m_pVideoMeter->Release(); | ||
202 : | m_pVideoMeter=0; | ||
203 : | } | ||
204 : | |||
205 : | if (m_pSrcFilter) { | ||
206 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
207 : | m_pSrcFilter->Release(); | ||
208 : | m_pSrcFilter = 0; | ||
209 : | } | ||
210 : | |||
211 : | Isibaar | 2029 | if (m_pSplitter) { |
212 : | m_pGraph->RemoveFilter(m_pSplitter); | ||
213 : | m_pSplitter->Release(); | ||
214 : | m_pSplitter = 0; | ||
215 : | } | ||
216 : | |||
217 : | Irhall | 2014 | if (m_pXvidEncoder) { |
218 : | m_pGraph->RemoveFilter(m_pXvidEncoder); | ||
219 : | m_pXvidEncoder->Release(); | ||
220 : | m_pXvidEncoder=0; | ||
221 : | } | ||
222 : | |||
223 : | if (m_pXvidConfig) { | ||
224 : | m_pXvidConfig->Release(); | ||
225 : | m_pXvidConfig = 0; | ||
226 : | } | ||
227 : | |||
228 : | Isibaar | 2045 | if (m_pIChgTypeNorm) { |
229 : | m_pIChgTypeNorm->Release(); | ||
230 : | m_pIChgTypeNorm = 0; | ||
231 : | } | ||
232 : | |||
233 : | Irhall | 2014 | if (m_pChgType) { |
234 : | m_pGraph->RemoveFilter(m_pChgType); | ||
235 : | m_pChgType->Release(); | ||
236 : | m_pChgType=0; | ||
237 : | } | ||
238 : | |||
239 : | if (m_pMuxer) { | ||
240 : | m_pGraph->RemoveFilter(m_pMuxer); | ||
241 : | m_pMuxer->Release(); | ||
242 : | m_pMuxer = 0; | ||
243 : | } | ||
244 : | |||
245 : | if (m_pFileWriter) { | ||
246 : | m_pGraph->RemoveFilter(m_pFileWriter); | ||
247 : | m_pFileWriter->Release(); | ||
248 : | m_pFileWriter = 0; | ||
249 : | } | ||
250 : | |||
251 : | IEnumFilters *pIEnumFilters = 0; | ||
252 : | |||
253 : | if (m_pGraph) { | ||
254 : | m_pGraph->EnumFilters(&pIEnumFilters); | ||
255 : | IBaseFilter *pFilter = 0; | ||
256 : | |||
257 : | if (pIEnumFilters) { | ||
258 : | while (pIEnumFilters->Next(1, &pFilter, 0) == S_OK) { | ||
259 : | m_pGraph->RemoveFilter(pFilter); | ||
260 : | pFilter->Release(); | ||
261 : | pIEnumFilters->Reset(); | ||
262 : | } | ||
263 : | } | ||
264 : | } | ||
265 : | |||
266 : | if (pIEnumFilters) | ||
267 : | pIEnumFilters->Release(); | ||
268 : | |||
269 : | while (m_vOtherFilters.size() > 0) { | ||
270 : | IBaseFilter *pFlt = m_vOtherFilters.back(); | ||
271 : | m_vOtherFilters.pop_back(); | ||
272 : | m_pGraph->RemoveFilter(pFlt); | ||
273 : | pFlt->Release(); | ||
274 : | } | ||
275 : | |||
276 : | if (m_pGraph) { | ||
277 : | m_pGraph->Release(); | ||
278 : | m_pGraph = 0; | ||
279 : | } | ||
280 : | |||
281 : | if (m_pBuilder) { | ||
282 : | m_pBuilder->Release(); | ||
283 : | m_pBuilder = 0; | ||
284 : | } | ||
285 : | } | ||
286 : | |||
287 : | HRESULT | ||
288 : | RecompressGraph::CreateGraph(HWND in_ProgressWnd, int in_Pass) | ||
289 : | { | ||
290 : | Isibaar | 2049 | int remux_only = 0; |
291 : | |||
292 : | Irhall | 2014 | m_FpsNom = m_FpsDen = 0; |
293 : | m_ProgressWnd = in_ProgressWnd; | ||
294 : | |||
295 : | m_bFileCopy = 1; // Initial guess: File copy strategy possible | ||
296 : | |||
297 : | #ifdef ALLOW_ONLY_AVI_INPUT | ||
298 : | if (fourcc_helper(m_szSourceFilePath, NULL, NULL, 1) != 0) return S_FALSE; // No AVI? -> fail | ||
299 : | #endif | ||
300 : | |||
301 : | DetermineFileSize(m_szSourceFilePath, &m_curSize); | ||
302 : | |||
303 : | if (in_ProgressWnd && (in_Pass == 1) && (m_elapsedSize == 0)) | ||
304 : | PostMessage(in_ProgressWnd, PBM_SETPOS, 0, 0); // Reset progress bar | ||
305 : | |||
306 : | HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, | ||
307 : | IID_ICaptureGraphBuilder2, (void **)&m_pBuilder); | ||
308 : | |||
309 : | if (hr == S_OK) hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, | ||
310 : | IID_IGraphBuilder, (void **)&m_pGraph); | ||
311 : | |||
312 : | if (hr == S_OK) hr = m_pBuilder->SetFiltergraph(m_pGraph); | ||
313 : | Isibaar | 2029 | m_bIsWMV = 0; |
314 : | Irhall | 2014 | if (hr == S_OK) hr = AddSourceFilter(m_szSourceFilePath); |
315 : | |||
316 : | m_UsedStreamsCnt = 1; | ||
317 : | m_vDuration = 0; | ||
318 : | IMediaSeeking *pSeek = 0; | ||
319 : | IPin *pOutVideoPin = 0; | ||
320 : | CMediaType vMt; | ||
321 : | |||
322 : | Isibaar | 2029 | if (hr == S_OK && m_bIsWMV) { |
323 : | Irhall | 2014 | if (GetFilterPin(m_pSrcFilter, PINDIR_OUTPUT, 0, &pOutVideoPin, |
324 : | Isibaar | 2029 | MEDIATYPE_Video, GUID_NULL) == S_OK) { |
325 : | Irhall | 2014 | IEnumMediaTypes *pIEnumMediaTypes = 0; |
326 : | |||
327 : | Isibaar | 2029 | if (pOutVideoPin->EnumMediaTypes(&pIEnumMediaTypes) == S_OK) { |
328 : | Irhall | 2014 | AM_MEDIA_TYPE *ppMt; |
329 : | |||
330 : | Isibaar | 2029 | if (pIEnumMediaTypes->Next(1, &ppMt, 0) == S_OK) { |
331 : | Irhall | 2014 | vMt = *ppMt; |
332 : | DeleteMediaType(ppMt); | ||
333 : | } | ||
334 : | pIEnumMediaTypes->Release(); | ||
335 : | } | ||
336 : | pOutVideoPin->QueryInterface(IID_IMediaSeeking, (void **)&pSeek); | ||
337 : | } | ||
338 : | } | ||
339 : | |||
340 : | IPin* pVMeterInVideoPin = 0; | ||
341 : | if ((hr == S_OK)) { | ||
342 : | Isibaar | 2029 | //if (!m_bIsWMV && (hr == S_OK)) { |
343 : | Irhall | 2014 | CUnknown *pVidMeter = 0; |
344 : | |||
345 : | if (hr == S_OK) pVidMeter = CProgressNotifyFilter::CreateInstance(0, &hr, 0); | ||
346 : | if (hr == S_OK) hr = pVidMeter->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&m_pVideoMeter); | ||
347 : | //hr = CoCreateInstance(CLSID_ProgressNotifyFilter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pVideoMeter); | ||
348 : | Isibaar | 2019 | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pVideoMeter, L"Video meter"); |
349 : | Irhall | 2014 | if (hr == S_OK) hr = GetFilterPin(m_pVideoMeter, PINDIR_INPUT, 0, &pVMeterInVideoPin, GUID_NULL, GUID_NULL); |
350 : | |||
351 : | if (pOutVideoPin) { | ||
352 : | hr = m_pGraph->Connect(pOutVideoPin, pVMeterInVideoPin); | ||
353 : | pOutVideoPin->Release(); | ||
354 : | pOutVideoPin = 0; | ||
355 : | } | ||
356 : | else { | ||
357 : | IPin *pVideoPin = 0; | ||
358 : | hr = m_pBuilder->RenderStream(NULL, NULL, m_pSrcFilter, NULL, m_pVideoMeter); | ||
359 : | if (hr == S_OK) hr = GetFilterPin(m_pVideoMeter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); | ||
360 : | if (hr == S_OK) pVideoPin->QueryInterface(IID_IMediaSeeking, (void **)&pSeek); | ||
361 : | if (pVideoPin) pVideoPin->Release(); | ||
362 : | } | ||
363 : | GetFilterPin(m_pVideoMeter, PINDIR_OUTPUT, 0, &pOutVideoPin, GUID_NULL, GUID_NULL); | ||
364 : | } | ||
365 : | |||
366 : | if (pSeek && (hr == S_OK)) { | ||
367 : | LONGLONG Duration = 0; | ||
368 : | hr = pSeek->GetDuration(&Duration); | ||
369 : | if (hr == S_OK) m_vDuration = Duration; | ||
370 : | } | ||
371 : | if (pSeek) pSeek->Release(); | ||
372 : | |||
373 : | IBaseFilter *pCompressedVideoFilter = 0; | ||
374 : | int m_bRecompress = 1; | ||
375 : | GUID gSubtype; | ||
376 : | Isibaar | 2049 | CUnknown *pChgUnk = NULL; |
377 : | Irhall | 2014 | |
378 : | if (hr == S_OK) { | ||
379 : | m_TotalFrames = 0; | ||
380 : | |||
381 : | Isibaar | 2029 | if (hr == S_OK && !m_bIsWMV) hr = pVMeterInVideoPin->ConnectionMediaType(&vMt); |
382 : | Irhall | 2014 | |
383 : | if (m_vDuration != 0) { | ||
384 : | if (vMt.formattype != FORMAT_None) { | ||
385 : | if (vMt.formattype == FORMAT_VideoInfo || vMt.formattype == FORMAT_MPEGVideo) { | ||
386 : | m_AvgTimeForFrame = (DWORD) ((VIDEOINFOHEADER *)vMt.pbFormat)->AvgTimePerFrame; | ||
387 : | Isibaar | 2029 | if (m_bIsWMV) m_Bitrate = ((VIDEOINFOHEADER *)vMt.pbFormat)->dwBitRate; |
388 : | Irhall | 2014 | } |
389 : | else if (vMt.formattype == FORMAT_VideoInfo2 || vMt.formattype == FORMAT_MPEG2Video) { | ||
390 : | m_AvgTimeForFrame = (DWORD) (((VIDEOINFOHEADER2 *)vMt.pbFormat)->AvgTimePerFrame); | ||
391 : | Isibaar | 2029 | if (m_bIsWMV) m_Bitrate = ((VIDEOINFOHEADER2 *)vMt.pbFormat)->dwBitRate; |
392 : | Irhall | 2014 | } |
393 : | else return VFW_E_TYPE_NOT_ACCEPTED; | ||
394 : | } | ||
395 : | m_TotalFrames = (DWORD) (m_AvgTimeForFrame ? (m_vDuration + (m_AvgTimeForFrame/2)) / m_AvgTimeForFrame : 0); | ||
396 : | } | ||
397 : | |||
398 : | gSubtype = vMt.subtype; | ||
399 : | if (hr == S_OK) { | ||
400 : | if (gSubtype == FOURCCMap('DIVX') || gSubtype == FOURCCMap('XVID') | ||
401 : | || gSubtype == FOURCCMap('divx') || gSubtype == FOURCCMap('xvid') | ||
402 : | || gSubtype == FOURCCMap('05XD') || gSubtype == FOURCCMap('V4PM') | ||
403 : | || gSubtype == FOURCCMap('05xd') || gSubtype == FOURCCMap('v4pm') | ||
404 : | || gSubtype == FOURCCMap('4PMR') || gSubtype == FOURCCMap('4pmr') | ||
405 : | || gSubtype == FOURCCMap('4XDH') || gSubtype == FOURCCMap('4xdh') | ||
406 : | || gSubtype == FOURCCMap('XVI3') || gSubtype == FOURCCMap('xvi3') | ||
407 : | || gSubtype == FOURCCMap('0VI3') || gSubtype == FOURCCMap('0vi3') | ||
408 : | || gSubtype == FOURCCMap('1VI3') || gSubtype == FOURCCMap('1vi3') | ||
409 : | || gSubtype == FOURCCMap('2VI3') || gSubtype == FOURCCMap('2vi3') | ||
410 : | || gSubtype == FOURCCMap('4PML') || gSubtype == FOURCCMap('4pml') | ||
411 : | || gSubtype == FOURCCMap('4PMS') || gSubtype == FOURCCMap('4pms')) | ||
412 : | { | ||
413 : | Isibaar | 2029 | pCompressedVideoFilter = m_pVideoMeter ? m_pVideoMeter : (m_pSplitter ? m_pSplitter : m_pSrcFilter); |
414 : | Isibaar | 2049 | remux_only = 1; |
415 : | Irhall | 2014 | } |
416 : | Isibaar | 2049 | else |
417 : | full_recompress: | ||
418 : | { | ||
419 : | Irhall | 2014 | m_bFileCopy = 0; |
420 : | Isibaar | 2049 | if (remux_only==1) remux_only = 2; |
421 : | Irhall | 2014 | |
422 : | if (hr == S_OK) hr = AddDirectXFilterByMoniker(CLSID_VideoCompressorCategory, "xvid", &m_pXvidEncoder, 1); | ||
423 : | Isibaar | 2019 | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pXvidEncoder, L"Encoder"); |
424 : | Irhall | 2014 | |
425 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pOutVideoPin, m_pXvidEncoder, GUID_NULL, GUID_NULL, 0); | ||
426 : | if (hr == S_OK) pCompressedVideoFilter = m_pXvidEncoder; | ||
427 : | |||
428 : | m_ToAlloc = 0; | ||
429 : | if (hr == S_OK) hr = m_pXvidEncoder->QueryInterface(IID_IAMVfwCompressDialogs, (void **)&m_pXvidConfig); | ||
430 : | |||
431 : | if (hr == S_OK) m_ToAlloc = m_pXvidConfig->SendDriverMessage(ICM_GETSTATE, NULL, 0); | ||
432 : | if (hr == S_OK) m_pXvidCfgRec = (CONFIG *)malloc(m_ToAlloc +10); | ||
433 : | if (hr == S_OK) m_pXvidConfig->SendDriverMessage(ICM_GETSTATE, (LONG)m_pXvidCfgRec, 0); | ||
434 : | |||
435 : | if (hr == S_OK) { | ||
436 : | if (in_Pass == 1) { | ||
437 : | m_pXvidCfgRec->mode = RC_MODE_2PASS1; | ||
438 : | } | ||
439 : | else { | ||
440 : | m_pXvidCfgRec->mode = RC_MODE_2PASS2; | ||
441 : | |||
442 : | if (m_Bitrate > 0) { | ||
443 : | m_pXvidCfgRec->use_2pass_bitrate = 1; | ||
444 : | m_pXvidCfgRec->bitrate = m_Bitrate/1000; // in kbps | ||
445 : | } | ||
446 : | else if (m_TotalFramesSize > 0) { | ||
447 : | m_pXvidCfgRec->desired_size = (int) (m_TotalFramesSize/1024); // in KB | ||
448 : | m_pXvidCfgRec->use_2pass_bitrate = 0; | ||
449 : | } | ||
450 : | else { | ||
451 : | m_pXvidCfgRec->desired_size = (int) (.9f*m_curSize); // in KB | ||
452 : | m_pXvidCfgRec->use_2pass_bitrate = 0; | ||
453 : | } | ||
454 : | |||
455 : | #if 1 // select a profile matching the input dimensions | ||
456 : | if (m_Width == 0 || m_Height == 0) { // not detected | ||
457 : | m_pXvidCfgRec->profile = 0x11; | ||
458 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
459 : | } | ||
460 : | else if (m_Width <= 352 && m_Height <= 288) { | ||
461 : | m_pXvidCfgRec->profile = 0x0; | ||
462 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid Mobile"); | ||
463 : | } | ||
464 : | else if (m_Width <= 720 && m_Height <= 576) { | ||
465 : | m_pXvidCfgRec->profile = 0x1; | ||
466 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid Home"); | ||
467 : | } | ||
468 : | else if (m_Width <= 1280 && m_Height <= 720) { | ||
469 : | m_pXvidCfgRec->profile = 0x2; | ||
470 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid HD 720"); | ||
471 : | } | ||
472 : | else if (m_Width <= 1920 && m_Height <= 1080) { | ||
473 : | m_pXvidCfgRec->profile = 0x3; | ||
474 : | strcpy(m_pXvidCfgRec->profile_name, "Xvid HD 1080"); | ||
475 : | } | ||
476 : | else { | ||
477 : | m_pXvidCfgRec->profile = 0x11; | ||
478 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
479 : | } | ||
480 : | #else | ||
481 : | m_pXvidCfgRec->profile = 0xE; | ||
482 : | strcpy(m_pXvidCfgRec->profile_name, "(unrestricted)"); | ||
483 : | #endif | ||
484 : | } | ||
485 : | |||
486 : | Isibaar | 2019 | strcpy(m_pXvidCfgRec->stats, Pass_FILE_A); |
487 : | Irhall | 2014 | |
488 : | m_pXvidCfgRec->display_status = 0; | ||
489 : | |||
490 : | if (hr == S_OK) m_pXvidConfig->SendDriverMessage(ICM_SETSTATE, (LONG)m_pXvidCfgRec, 0); | ||
491 : | } | ||
492 : | } | ||
493 : | } | ||
494 : | } | ||
495 : | |||
496 : | Isibaar | 2049 | if (remux_only != 2) { |
497 : | pChgUnk = ChangeSubtypeT::CreateInstance(0, &hr); | ||
498 : | if (hr == S_OK) hr = pChgUnk->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&m_pChgType); | ||
499 : | if (hr == S_OK) hr = m_pGraph->AddFilter(m_pChgType, L"ChgToxvid"); | ||
500 : | } | ||
501 : | Irhall | 2014 | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pCompressedVideoFilter, m_pChgType, GUID_NULL, GUID_NULL, 1); |
502 : | Isibaar | 2049 | if (hr != S_OK && remux_only==1) { hr = S_OK; goto full_recompress; } // retry with full recompress |
503 : | Irhall | 2014 | if (hr == S_OK) hr = AddFilterByCLSID((GUID *)&CLSID_AviDest, &m_pMuxer); |
504 : | |||
505 : | #if 0 | ||
506 : | IConfigInterleaving *pIConfigInterleaving = 0; | ||
507 : | if (hr == S_OK) hr = m_pMuxer->QueryInterface(IID_IConfigInterleaving, (void **)&pIConfigInterleaving); | ||
508 : | REFERENCE_TIME InterleaveRate = 10000000LL, Preroll = 100000000LL; | ||
509 : | if (hr == S_OK) hr = pIConfigInterleaving->put_Mode(INTERLEAVE_FULL); | ||
510 : | if (hr == S_OK) hr = pIConfigInterleaving->put_Interleaving(&InterleaveRate, &Preroll); | ||
511 : | if (pIConfigInterleaving) pIConfigInterleaving->Release(); | ||
512 : | #endif | ||
513 : | |||
514 : | Isibaar | 2045 | if (hr == S_OK) hr = m_pChgType->QueryInterface(IID_IRecProgressNotify, (void **)&m_pIChgTypeNorm); |
515 : | if (hr == S_OK) hr = m_pIChgTypeNorm->SetTotalFrames(m_TotalFrames); | ||
516 : | if (hr == S_OK) m_pIChgTypeNorm->SetPass(in_Pass); | ||
517 : | |||
518 : | if (in_Pass == 2) { | ||
519 : | LONGLONG FpsNom = m_MaxETime - m_MinETime, FpsDen = m_CountedFrames > 1 ? m_CountedFrames-1 : 1; | ||
520 : | LONGLONG cAvgTimeForFrame = FpsNom/FpsDen; | ||
521 : | //if (((ULONGLONG)m_AvgTimeForFrame*m_CountedFrames - FpsNom) > m_AvgTimeForFrame + m_CountedFrames) { | ||
522 : | if (!m_AvgTimeForFrame) { | ||
523 : | m_pIChgTypeNorm->SetForceTimeParams(m_MinSTime, FpsNom, FpsDen); | ||
524 : | } | ||
525 : | } | ||
526 : | |||
527 : | Irhall | 2014 | if (hr == S_OK) hr = ConnectFilters(m_pGraph, m_pChgType, m_pMuxer, MEDIATYPE_Video, GUID_NULL, 1); |
528 : | |||
529 : | if (hr == S_OK) hr = AddFileWriter(m_szDstFilePath); | ||
530 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, m_pMuxer, m_pFileWriter, GUID_NULL, GUID_NULL, 1); | ||
531 : | |||
532 : | if ((hr == S_OK) && ((in_Pass ==2) || (!m_pXvidEncoder))) hr = AddAudioStreams(0); | ||
533 : | else if (hr == S_OK) hr = AddAudioStreams(1); | ||
534 : | |||
535 : | if (pVMeterInVideoPin) pVMeterInVideoPin->Release(); | ||
536 : | if (pOutVideoPin) pOutVideoPin->Release(); | ||
537 : | DeleteFile(m_szDstFilePath); | ||
538 : | //AddToRot(m_pGraph, &dwReg); | ||
539 : | |||
540 : | if (hr == S_OK && in_Pass != 2) { // Make progress bar visible | ||
541 : | Isibaar | 2017 | TCHAR buf[MAX_PATH+50], buf2[MAX_PATH]; |
542 : | Isibaar | 2019 | if (_tcslen(m_szSourceFilePath) > 60) { |
543 : | Isibaar | 2017 | PathCompactPathEx(buf2, m_szSourceFilePath, 60, 0); |
544 : | Isibaar | 2019 | _stprintf(buf, TEXT("Converting %s"), buf2); |
545 : | Isibaar | 2017 | } |
546 : | else | ||
547 : | Isibaar | 2019 | _stprintf(buf, TEXT("Converting %s..."), m_szSourceFilePath); |
548 : | Isibaar | 2017 | |
549 : | Irhall | 2014 | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_HIDE); |
550 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_HIDE); | ||
551 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_HIDE); | ||
552 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_HIDE); | ||
553 : | ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_HIDE); | ||
554 : | ShowWindow(m_ProgressWnd, SW_SHOW); | ||
555 : | SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, buf); | ||
556 : | } | ||
557 : | |||
558 : | return hr; | ||
559 : | } | ||
560 : | |||
561 : | HRESULT | ||
562 : | RecompressGraph::AddAudioStreams(int check_only) | ||
563 : | { | ||
564 : | IPin *pOutPin=0, *pInPin = 0; | ||
565 : | PIN_INFO PinInfo = {NULL}; | ||
566 : | HRESULT hr = S_OK; | ||
567 : | int bFraunhoferPro = 0; | ||
568 : | |||
569 : | HKEY hKey; | ||
570 : | DWORD size = MAX_PATH; | ||
571 : | TCHAR kvalue[MAX_PATH]; | ||
572 : | RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"), 0, KEY_READ, &hKey); | ||
573 : | if (RegQueryValueEx(hKey, TEXT("msacm.l3acm"), 0, 0, (LPBYTE)kvalue, &size) != ERROR_SUCCESS) | ||
574 : | bFraunhoferPro = 0; | ||
575 : | else { | ||
576 : | // C:\WINDOWS\System32\l3codecp.acm was not recognized | ||
577 : | Isibaar | 2019 | int sLen = _tcslen(kvalue); |
578 : | if ((sLen >= 12) && (_tcscmp(&(kvalue[sLen - 12]), TEXT("l3codecp.acm")) == 0)) | ||
579 : | Irhall | 2014 | bFraunhoferPro = 1; |
580 : | } | ||
581 : | |||
582 : | if (m_pVideoMeter) { | ||
583 : | if (GetFilterPin(m_pVideoMeter, PINDIR_INPUT, 1, &pInPin, | ||
584 : | MEDIATYPE_Video, GUID_NULL) == S_OK) | ||
585 : | { | ||
586 : | hr = pInPin->ConnectedTo(&pOutPin); | ||
587 : | if (hr == S_OK) hr = pOutPin->QueryPinInfo(&PinInfo); | ||
588 : | if (pOutPin) pOutPin->Release(); | ||
589 : | if (pInPin) pInPin->Release(); | ||
590 : | } | ||
591 : | Isibaar | 2029 | } else if (m_pSplitter) hr = m_pSplitter->QueryInterface(IID_IBaseFilter, (void **)&PinInfo.pFilter); |
592 : | else hr = m_pSrcFilter->QueryInterface(IID_IBaseFilter, (void **)&PinInfo.pFilter); | ||
593 : | Irhall | 2014 | |
594 : | IPin *pAudioPin = 0; | ||
595 : | if (check_only) { | ||
596 : | if ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0, | ||
597 : | &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK)) | ||
598 : | { | ||
599 : | AM_MEDIA_TYPE *paomt = 0; | ||
600 : | int bNeedsRecompression = 0; | ||
601 : | IEnumMediaTypes *pAmtEnum = 0; | ||
602 : | hr = pAudioPin->EnumMediaTypes(&pAmtEnum); | ||
603 : | |||
604 : | if (hr == S_OK) { | ||
605 : | hr = pAmtEnum->Reset(); | ||
606 : | if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0); | ||
607 : | if (hr == S_OK && paomt->subtype.Data1 != 0x55 && | ||
608 : | (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3 | ||
609 : | { | ||
610 : | bNeedsRecompression = 1; | ||
611 : | m_bFileCopy = 0; // file copy strategy cannot be used on this input | ||
612 : | } | ||
613 : | else if (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags & 4) { // VBR | ||
614 : | bNeedsRecompression = 1; | ||
615 : | } | ||
616 : | if (pAmtEnum) pAmtEnum->Release(); | ||
617 : | pAmtEnum = 0; | ||
618 : | if (paomt) DeleteMediaType(paomt); | ||
619 : | if (hr == S_OK && bNeedsRecompression && !bFraunhoferPro) { | ||
620 : | //MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0); | ||
621 : | hr = VFW_E_CANNOT_CONNECT; | ||
622 : | } | ||
623 : | } | ||
624 : | pAudioPin->Release(); | ||
625 : | } | ||
626 : | } | ||
627 : | else { | ||
628 : | while ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0, | ||
629 : | &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK)) | ||
630 : | { | ||
631 : | AM_MEDIA_TYPE *paomt = 0; | ||
632 : | int bNeedsRecompression = 0; | ||
633 : | IEnumMediaTypes *pAmtEnum = 0; | ||
634 : | hr = pAudioPin->EnumMediaTypes(&pAmtEnum); | ||
635 : | if (hr == S_OK) { | ||
636 : | hr = pAmtEnum->Reset(); | ||
637 : | if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0); | ||
638 : | if ((hr == S_OK) && (paomt->subtype.Data1 != 0x55) && | ||
639 : | (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3 | ||
640 : | { | ||
641 : | bNeedsRecompression = 1; | ||
642 : | m_bFileCopy = 0; // file copy strategy cannot be used on this input | ||
643 : | } | ||
644 : | Isibaar | 2029 | else if ((paomt->subtype.Data1 == 0x55) && |
645 : | (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags != MPEGLAYER3_FLAG_PADDING_ON)){ // VBR | ||
646 : | Irhall | 2014 | bNeedsRecompression = 1; |
647 : | } | ||
648 : | if (pAmtEnum) pAmtEnum->Release(); | ||
649 : | pAmtEnum = 0; | ||
650 : | |||
651 : | if (paomt) DeleteMediaType(paomt); | ||
652 : | if (hr == S_OK && bNeedsRecompression) { | ||
653 : | |||
654 : | IBaseFilter *pAudioCompressor = 0; | ||
655 : | hr = AddDirectXFilterByMoniker(CLSID_AudioCompressorCategory, "MPEG Layer-3", &pAudioCompressor, 0); | ||
656 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pAudioCompressor, 0); | ||
657 : | |||
658 : | Isibaar | 2029 | IBaseFilter *pFFdA=0; |
659 : | if (hr == S_OK) AddFilterByCLSID((GUID *)&CLSID_FFDshowAudioDecoder, &pFFdA); | ||
660 : | |||
661 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pAudioCompressor, GUID_NULL, GUID_NULL, 0); | ||
662 : | |||
663 : | RemoveIfUnconnectedInput(pFFdA); | ||
664 : | if (pFFdA) pFFdA->Release(); | ||
665 : | Irhall | 2014 | |
666 : | IPin *pMp3Pin = 0; | ||
667 : | if (hr == S_OK) hr = GetFilterPin(pAudioCompressor, PINDIR_OUTPUT, 0, &pMp3Pin, MEDIATYPE_Audio, GUID_NULL); | ||
668 : | IEnumMediaTypes *pMp3MtEnum = 0; | ||
669 : | |||
670 : | if (hr == S_OK) hr = pMp3Pin->EnumMediaTypes(&pMp3MtEnum); | ||
671 : | AM_MEDIA_TYPE *pMp3mt = 0; | ||
672 : | int bConnected = 0; | ||
673 : | |||
674 : | if (hr == S_OK) { | ||
675 : | Isibaar | 2029 | DWORD UsedDataRate = 0, MaxDataRate=0; |
676 : | // Some files have mono track 8kHz, it's not possible to obtain 128kbps datarate | ||
677 : | while (UsedDataRate != 16000 && (pMp3MtEnum->Next(1, &pMp3mt, 0) == S_OK)) { | ||
678 : | Irhall | 2014 | MPEGLAYER3WAVEFORMAT *pMp3cb = (MPEGLAYER3WAVEFORMAT *)pMp3mt->pbFormat; |
679 : | if ( | ||
680 : | //pMp3cb->nSamplesPerSec == 44100 && | ||
681 : | Isibaar | 2029 | pMp3cb->wfx.nAvgBytesPerSec == 16000) { |
682 : | UsedDataRate = 16000; | ||
683 : | } | ||
684 : | if (MaxDataRate < pMp3cb->wfx.nAvgBytesPerSec) | ||
685 : | MaxDataRate = pMp3cb->wfx.nAvgBytesPerSec; | ||
686 : | DeleteMediaType(pMp3mt); | ||
687 : | } | ||
688 : | pMp3MtEnum->Reset(); | ||
689 : | if (UsedDataRate != 16000) UsedDataRate = MaxDataRate; | ||
690 : | |||
691 : | while (!bConnected && (pMp3MtEnum->Next(1, &pMp3mt, 0) == S_OK)) { | ||
692 : | MPEGLAYER3WAVEFORMAT *pMp3cb = (MPEGLAYER3WAVEFORMAT *)pMp3mt->pbFormat; | ||
693 : | if ( | ||
694 : | //pMp3cb->nSamplesPerSec == 44100 && | ||
695 : | pMp3cb->wfx.nAvgBytesPerSec == UsedDataRate) { | ||
696 : | |||
697 : | CUnknown *pMp3Normalizer = 0; | ||
698 : | Irhall | 2014 | IBaseFilter *pIMp3Normalizer = 0; |
699 : | // Type 2 - only 16000 Bps = 128kbit audio | ||
700 : | if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 2); | ||
701 : | if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter, | ||
702 : | (void **)&pIMp3Normalizer); | ||
703 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0); | ||
704 : | |||
705 : | Isibaar | 2045 | IRecProgressNotify *pAudioRecNotify = 0; |
706 : | pIMp3Normalizer->QueryInterface(IID_IRecProgressNotify, (void **)&pAudioRecNotify); | ||
707 : | pAudioRecNotify->SetAudioBitrate(UsedDataRate); | ||
708 : | pAudioRecNotify->Release(); | ||
709 : | |||
710 : | Irhall | 2014 | IPin *pNormMp3Pin = 0; |
711 : | if (hr == S_OK) hr = GetFilterPin(pIMp3Normalizer, PINDIR_INPUT, 0, &pNormMp3Pin, GUID_NULL, GUID_NULL); | ||
712 : | if (hr == S_OK) hr = m_pGraph->ConnectDirect(pMp3Pin, pNormMp3Pin, pMp3mt); | ||
713 : | if (pNormMp3Pin) pNormMp3Pin->Release(); | ||
714 : | |||
715 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, GUID_NULL, GUID_NULL, 1); | ||
716 : | if (pIMp3Normalizer) pIMp3Normalizer->Release(); | ||
717 : | if (hr == S_OK) bConnected = 1; | ||
718 : | } | ||
719 : | DeleteMediaType(pMp3mt); | ||
720 : | } | ||
721 : | } | ||
722 : | if ((!bConnected || !bFraunhoferPro) && hr == S_OK) hr = VFW_E_CANNOT_CONNECT; | ||
723 : | //if (hr == S_OK && !bFraunhoferPro) MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0); | ||
724 : | if (pMp3Pin) pMp3Pin->Release(); | ||
725 : | if (pMp3MtEnum) pMp3MtEnum->Release(); | ||
726 : | if (pAudioCompressor) pAudioCompressor->Release(); | ||
727 : | } | ||
728 : | else { | ||
729 : | CUnknown *pMp3Normalizer = 0; | ||
730 : | IBaseFilter *pIMp3Normalizer = 0; | ||
731 : | |||
732 : | if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 1); | ||
733 : | if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&pIMp3Normalizer); | ||
734 : | if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0); | ||
735 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pIMp3Normalizer, MEDIATYPE_Audio, GUID_NULL, 0); | ||
736 : | if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, MEDIATYPE_Audio, GUID_NULL, 0); | ||
737 : | if (pIMp3Normalizer) pIMp3Normalizer->Release(); | ||
738 : | } | ||
739 : | if (hr == S_OK && PinInfo.pFilter == m_pSrcFilter) m_UsedStreamsCnt++; | ||
740 : | Isibaar | 2029 | if (hr == S_OK && PinInfo.pFilter == m_pSplitter) m_UsedStreamsCnt++; |
741 : | Irhall | 2014 | } |
742 : | pAudioPin->Release(); | ||
743 : | } | ||
744 : | } | ||
745 : | |||
746 : | if (PinInfo.pFilter) PinInfo.pFilter->Release(); | ||
747 : | return hr; | ||
748 : | } | ||
749 : | |||
750 : | HRESULT | ||
751 : | RecompressGraph::AddFilterByCLSID(GUID *in_Filter, IBaseFilter **out_pFilter) | ||
752 : | { | ||
753 : | HRESULT hr = CoCreateInstance(*in_Filter, NULL, CLSCTX_INPROC_SERVER, | ||
754 : | IID_IBaseFilter, (void **)out_pFilter); | ||
755 : | if (hr == S_OK) hr = m_pGraph->AddFilter(*out_pFilter, NULL); | ||
756 : | |||
757 : | return hr; | ||
758 : | } | ||
759 : | |||
760 : | HRESULT | ||
761 : | RecompressGraph::SetDstFileName(LPCTSTR in_szFilePath) | ||
762 : | { | ||
763 : | if (m_pGraph) | ||
764 : | return E_UNEXPECTED; | ||
765 : | |||
766 : | if (m_szDstFilePath) | ||
767 : | free (m_szDstFilePath); | ||
768 : | |||
769 : | Isibaar | 2019 | m_szDstFilePath = _tcsdup(in_szFilePath); |
770 : | Irhall | 2014 | |
771 : | return S_OK; | ||
772 : | } | ||
773 : | |||
774 : | HRESULT | ||
775 : | RecompressGraph::AddFileWriter(LPCTSTR in_szFilePath) | ||
776 : | { | ||
777 : | if (!m_pGraph || m_pFileWriter) | ||
778 : | return E_UNEXPECTED; | ||
779 : | |||
780 : | Isibaar | 2019 | int sLen = _tcslen(in_szFilePath); |
781 : | OLECHAR *pwName = new OLECHAR [sLen+1]; | ||
782 : | #ifndef UNICODE | ||
783 : | mbstowcs(pwName, in_szFilePath, sLen+1); | ||
784 : | #else | ||
785 : | wcsncpy(pwName, in_szFilePath, sLen+1); | ||
786 : | #endif | ||
787 : | |||
788 : | Irhall | 2014 | HRESULT hr = AddFilterByCLSID((GUID *)&CLSID_FileWriter, &m_pFileWriter); |
789 : | IFileSinkFilter* pDst=0; | ||
790 : | if (hr == S_OK) hr = m_pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)(&pDst)); | ||
791 : | Isibaar | 2019 | if (hr == S_OK) hr = pDst->SetFileName(pwName, &m_DstFileMediaType); |
792 : | delete [] pwName; | ||
793 : | Irhall | 2014 | if (pDst) |
794 : | pDst->Release(); | ||
795 : | |||
796 : | return hr; | ||
797 : | } | ||
798 : | |||
799 : | HRESULT | ||
800 : | RecompressGraph::AddSourceFile(LPCTSTR in_szFilePath) | ||
801 : | { | ||
802 : | if (m_pGraph) return E_UNEXPECTED; | ||
803 : | |||
804 : | if (m_szSourceFilePath) | ||
805 : | free (m_szSourceFilePath); | ||
806 : | |||
807 : | Isibaar | 2019 | m_szSourceFilePath = _tcsdup(in_szFilePath); |
808 : | Irhall | 2014 | |
809 : | return S_OK; | ||
810 : | } | ||
811 : | |||
812 : | HRESULT | ||
813 : | RecompressGraph::AddSourceFilter(LPCTSTR in_szFilePath) | ||
814 : | { | ||
815 : | Isibaar | 2045 | HRESULT hr = S_OK; |
816 : | Irhall | 2014 | if (!m_pGraph || m_pSrcFilter) return E_UNEXPECTED; |
817 : | |||
818 : | Isibaar | 2045 | BYTE StartBytes[512]; |
819 : | DWORD cbReadHdr=0; | ||
820 : | int ExpectedType=0; | ||
821 : | HANDLE hFile = CreateFile(in_szFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); | ||
822 : | if (hFile != INVALID_HANDLE_VALUE) { | ||
823 : | if (ReadFile(hFile, StartBytes, sizeof(StartBytes), &cbReadHdr, 0) && cbReadHdr == sizeof(StartBytes)) { | ||
824 : | if ((*(int *)StartBytes) == 'FFIR') ExpectedType = 1; // AVI | ||
825 : | else if (((int *)StartBytes)[1] == 'pytf' || ((int *)StartBytes)[1] == 'tadm' || ((int *)StartBytes)[1] == 'voom') ExpectedType = 2; // MOV/MP4 | ||
826 : | else if (((int *)StartBytes)[0] == 0xA3DF451A) { | ||
827 : | for (int iPos = 4; (ExpectedType == 0 && iPos +11 < sizeof(StartBytes)); iPos++) { | ||
828 : | if ((*(int *)&(StartBytes[iPos]) == 0x6D888242) && (*(int *)&(StartBytes[iPos+3]) == 'rtam') | ||
829 : | && (*(int *)&(StartBytes[iPos+7]) == 'akso')) { | ||
830 : | ExpectedType = 3; // MKV | ||
831 : | } | ||
832 : | } | ||
833 : | } else if (((int *)StartBytes)[0] == 0x75B22630) ExpectedType = 4; // WMV/ASF | ||
834 : | } else hr = VFW_E_FILE_TOO_SHORT; | ||
835 : | CloseHandle(hFile); | ||
836 : | } else return VFW_E_NOT_FOUND; | ||
837 : | if (hr != S_OK) return hr; | ||
838 : | |||
839 : | Isibaar | 2019 | int sLen = _tcslen(in_szFilePath); |
840 : | OLECHAR *pwName = new OLECHAR [sLen+1]; | ||
841 : | #ifndef UNICODE | ||
842 : | mbstowcs(pwName, in_szFilePath, sLen+1); | ||
843 : | #else | ||
844 : | wcsncpy(pwName, in_szFilePath, sLen+1); | ||
845 : | #endif | ||
846 : | Irhall | 2014 | |
847 : | Isibaar | 2045 | // preferred configuration: |
848 : | // ASF/WMV : WM ASF Reader | ||
849 : | // AVI: Async Reader -> Avi Splitter | ||
850 : | // MOV/MP4: Async Reader -> Lav splitter (secondary Haali splitter) (Haali has problems with some movs and mp4 files) | ||
851 : | // MKV: Async Reader -> Haali splitter (secondary Lav splitter) | ||
852 : | // if configuration Reader->Splitter is not available for mov/mp4/mkv, then reader+splitter is tried. | ||
853 : | // if everything fails, we let the GraphBuilder to choose filters by default. | ||
854 : | Isibaar | 2019 | |
855 : | Isibaar | 2029 | IPin* pOutSrcPin=0, *pVideoPin=0; |
856 : | Isibaar | 2045 | if (ExpectedType == 4) m_bIsWMV = 1; |
857 : | else { | ||
858 : | hr = TrySourceFilter(pwName, (GUID *)&CLSID_AsyncReader); | ||
859 : | |||
860 : | if (hr == S_OK) hr = GetFilterPin(m_pSrcFilter, PINDIR_OUTPUT, 0, &pOutSrcPin, GUID_NULL, GUID_NULL); | ||
861 : | IEnumMediaTypes* pEnumSrcMediaTypes=0; | ||
862 : | if (hr == S_OK) hr = pOutSrcPin->EnumMediaTypes(&pEnumSrcMediaTypes); | ||
863 : | AM_MEDIA_TYPE *pMt =0; | ||
864 : | if (hr == S_OK) hr = pEnumSrcMediaTypes->Next(1, &pMt, 0); | ||
865 : | while (hr == S_OK && (pMt->majortype != MEDIATYPE_Stream || pMt->subtype == GUID_NULL)) { | ||
866 : | DeleteMediaType(pMt); | ||
867 : | pMt = 0; | ||
868 : | hr = pEnumSrcMediaTypes->Next(1, &pMt, 0); | ||
869 : | } | ||
870 : | if (hr == S_OK) m_SrcFileMediaType = *pMt; | ||
871 : | if (pMt) DeleteMediaType(pMt); | ||
872 : | if (pEnumSrcMediaTypes) pEnumSrcMediaTypes->Release(); | ||
873 : | if (hr == S_OK) { | ||
874 : | if (m_SrcFileMediaType.majortype == MEDIATYPE_Stream) { | ||
875 : | if (m_SrcFileMediaType.subtype == MEDIASUBTYPE_Asf || | ||
876 : | m_SrcFileMediaType.subtype == MEDIASUBTYPE_ASF) { | ||
877 : | m_bIsWMV = 1; | ||
878 : | } else if (m_SrcFileMediaType.subtype == MEDIASUBTYPE_Avi) | ||
879 : | hr = AddFilterByCLSID((GUID *)&CLSID_AviSplitter, &m_pSplitter); | ||
880 : | else { | ||
881 : | hr = AddFilterByCLSID((GUID *)((ExpectedType == 3) ? &CLSID_HaaliMediaSplitter_AR : &CLSID_LAVSplitter), &m_pSplitter); | ||
882 : | Isibaar | 2029 | if (hr == S_OK) { |
883 : | hr = ConnectFilters(m_pGraph, pOutSrcPin, m_pSplitter); | ||
884 : | if (hr == S_OK) hr = GetFilterPin(m_pSplitter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); | ||
885 : | Isibaar | 2045 | if (m_pSplitter && !pVideoPin) { |
886 : | Isibaar | 2029 | m_pGraph->RemoveFilter(m_pSplitter); |
887 : | m_pSplitter->Release(); | ||
888 : | m_pSplitter = 0; | ||
889 : | } | ||
890 : | if (pVideoPin) {pVideoPin->Release(); pVideoPin = 0;} | ||
891 : | } | ||
892 : | Isibaar | 2045 | if (!m_pSplitter) { |
893 : | hr = AddFilterByCLSID((GUID *)((ExpectedType != 3) ? &CLSID_HaaliMediaSplitter_AR : &CLSID_LAVSplitter), &m_pSplitter); | ||
894 : | if (hr == S_OK) { | ||
895 : | hr = ConnectFilters(m_pGraph, pOutSrcPin, m_pSplitter); | ||
896 : | if (hr == S_OK) hr = GetFilterPin(m_pSplitter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); | ||
897 : | if (m_pSplitter && !pVideoPin) { | ||
898 : | m_pGraph->RemoveFilter(m_pSplitter); | ||
899 : | m_pSplitter->Release(); | ||
900 : | m_pSplitter = 0; | ||
901 : | } | ||
902 : | if (pVideoPin) {pVideoPin->Release(); pVideoPin = 0;} | ||
903 : | } | ||
904 : | } | ||
905 : | Isibaar | 2029 | } |
906 : | Isibaar | 2045 | } else hr = VFW_E_TYPE_NOT_ACCEPTED; |
907 : | } | ||
908 : | Isibaar | 2029 | } |
909 : | |||
910 : | if (m_bIsWMV || !m_pSplitter) { | ||
911 : | if (m_pSrcFilter) { | ||
912 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
913 : | m_pSrcFilter->Release(); | ||
914 : | } | ||
915 : | m_pSrcFilter = 0; | ||
916 : | if (m_bIsWMV) hr = TrySourceFilter(pwName, (GUID *)&CLSID_WMAsfReader ); | ||
917 : | else { | ||
918 : | Isibaar | 2045 | hr = TrySourceFilter(pwName, (GUID *)(ExpectedType == 3 ? &CLSID_HaaliMediaSplitter : &CLSID_LAVSource)); |
919 : | Isibaar | 2029 | if (hr == S_OK) hr = GetFilterPin(m_pSrcFilter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); |
920 : | if (!m_pSrcFilter || !pVideoPin) { | ||
921 : | if (!pVideoPin && m_pSrcFilter) { | ||
922 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
923 : | m_pSrcFilter->Release(); | ||
924 : | m_pSrcFilter = 0; | ||
925 : | } | ||
926 : | Isibaar | 2045 | if (!m_pSrcFilter) hr = TrySourceFilter(pwName, (GUID *)(ExpectedType != 3 ? &CLSID_HaaliMediaSplitter : &CLSID_LAVSource)); |
927 : | Isibaar | 2029 | if (hr == S_OK) hr = GetFilterPin(m_pSrcFilter, PINDIR_OUTPUT, 0, &pVideoPin, MEDIATYPE_Video, GUID_NULL); |
928 : | if (!pVideoPin && m_pSrcFilter) { | ||
929 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
930 : | m_pSrcFilter->Release(); | ||
931 : | m_pSrcFilter = 0; | ||
932 : | } | ||
933 : | } | ||
934 : | if (pVideoPin) { | ||
935 : | pVideoPin->Release(); | ||
936 : | pVideoPin = 0; | ||
937 : | } | ||
938 : | } | ||
939 : | if (!m_pSrcFilter) hr = m_pGraph->AddSourceFilter(pwName, 0, &m_pSrcFilter); | ||
940 : | } | ||
941 : | if (pOutSrcPin) pOutSrcPin->Release(); | ||
942 : | Irhall | 2014 | |
943 : | return hr; | ||
944 : | } | ||
945 : | |||
946 : | HRESULT | ||
947 : | Isibaar | 2029 | RecompressGraph::TrySourceFilter(LPCOLESTR pwName, GUID *in_Clsid) |
948 : | { | ||
949 : | HRESULT hr = AddFilterByCLSID(in_Clsid, &m_pSrcFilter); | ||
950 : | IFileSourceFilter* pSrc =0 ; | ||
951 : | if (hr == S_OK) hr = m_pSrcFilter->QueryInterface(IID_IFileSourceFilter, (void **)(&pSrc)); | ||
952 : | if (hr == S_OK) hr = pSrc->Load(pwName, 0);//&m_SrcFileMediaType); | ||
953 : | if (pSrc) pSrc->Release(); | ||
954 : | if (hr != S_OK && m_pSrcFilter) { | ||
955 : | m_pGraph->RemoveFilter(m_pSrcFilter); | ||
956 : | m_pSrcFilter->Release(); | ||
957 : | m_pSrcFilter = 0; | ||
958 : | } | ||
959 : | return hr; | ||
960 : | } | ||
961 : | |||
962 : | HRESULT | ||
963 : | Irhall | 2014 | RecompressGraph::SetProgress(int elapsedSize, int totalSize) |
964 : | { | ||
965 : | |||
966 : | m_elapsedSize = elapsedSize; | ||
967 : | m_totalSize = totalSize; | ||
968 : | |||
969 : | return S_OK; | ||
970 : | } | ||
971 : | |||
972 : | HRESULT | ||
973 : | Isibaar | 2029 | RecompressGraph::WaitForCompletion(long *out_Evt) |
974 : | { | ||
975 : | long Evt, P1, P2; | ||
976 : | Isibaar | 2045 | // TCHAR szErrorStr[150]; |
977 : | Isibaar | 2029 | HRESULT hr = S_OK; |
978 : | do { | ||
979 : | hr = m_pEvent->GetEvent(&Evt, &P1, &P2, INFINITE); | ||
980 : | if (Evt == EC_ERRORABORT) { | ||
981 : | Isibaar | 2045 | // _stprintf(szErrorStr, _TEXT("Error ocurred\nCode=%08X, %08X\nContinue?"), P1, P2); |
982 : | // if (MessageBox(ghDlg, szErrorStr, 0, MB_YESNO) == IDYES) Evt = 0; | ||
983 : | if (P1 == 0xC00D002F && m_bIsWMV) | ||
984 : | Evt = 0; | ||
985 : | Isibaar | 2029 | } |
986 : | } while (Evt != EC_COMPLETE && Evt != EC_STREAM_ERROR_STOPPED && Evt != EC_USERABORT && Evt != EC_ERRORABORT); | ||
987 : | *out_Evt = Evt; | ||
988 : | return S_OK; | ||
989 : | } | ||
990 : | |||
991 : | HRESULT | ||
992 : | Irhall | 2014 | RecompressGraph::Recompress() |
993 : | { | ||
994 : | if (!m_pGraph) return E_UNEXPECTED; | ||
995 : | |||
996 : | Isibaar | 2029 | long E = 0; |
997 : | Irhall | 2014 | HRESULT hr = S_OK; |
998 : | |||
999 : | if (hr == S_OK && m_bFileCopy == 1 && | ||
1000 : | fourcc_helper(m_szSourceFilePath, NULL, NULL, 1)==0) // check input is AVI ! | ||
1001 : | { | ||
1002 : | if (!CopyFileEx(m_szSourceFilePath, m_szDstFilePath, | ||
1003 : | CopyProgressRoutine, this, FALSE, 0) || m_bBreakRequested) { | ||
1004 : | hr = E_FAIL; | ||
1005 : | DeleteFile(m_szDstFilePath); | ||
1006 : | } | ||
1007 : | |||
1008 : | goto finish_recompress; | ||
1009 : | } | ||
1010 : | |||
1011 : | Isibaar | 2029 | hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pControl); |
1012 : | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pEvent); | ||
1013 : | Irhall | 2014 | |
1014 : | IRecProgressNotify *pBitrateProgressNotify=0; | ||
1015 : | OAFilterState oas; | ||
1016 : | |||
1017 : | if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify, | ||
1018 : | (void **)&pBitrateProgressNotify); | ||
1019 : | |||
1020 : | //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify); | ||
1021 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_TotalFrames); | ||
1022 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd); | ||
1023 : | |||
1024 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize); | ||
1025 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize); | ||
1026 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize); | ||
1027 : | |||
1028 : | if (m_pXvidEncoder) { | ||
1029 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(0); | ||
1030 : | |||
1031 : | m_pXvidConfig->Release(); | ||
1032 : | m_pXvidConfig = 0; | ||
1033 : | |||
1034 : | if (hr == S_OK) { | ||
1035 : | Isibaar | 2029 | hr = m_pControl->Run(); |
1036 : | Irhall | 2014 | if (hr == S_OK) { |
1037 : | Isibaar | 2029 | do hr = m_pControl->GetState(1000, &oas); |
1038 : | Irhall | 2014 | while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE); |
1039 : | } | ||
1040 : | } | ||
1041 : | |||
1042 : | //long Evt, P1, P2; | ||
1043 : | //if (hr == S_OK) do hr = pEvent->GetEvent(&Evt, &P1, &P2, INFINITE); | ||
1044 : | //while (Evt != EC_COMPLETE && Evt != 3 && Evt != 2); | ||
1045 : | Isibaar | 2029 | //if (hr == S_OK) hr = m_pEvent->WaitForCompletion(INFINITE, &E); |
1046 : | hr = WaitForCompletion(&E); | ||
1047 : | Irhall | 2014 | |
1048 : | Isibaar | 2029 | if (m_pControl) { |
1049 : | Irhall | 2014 | HRESULT hrTmp; |
1050 : | if (E == EC_USERABORT) m_pSrcFilter->Stop(); | ||
1051 : | Isibaar | 2029 | hrTmp = m_pControl->Stop(); |
1052 : | do hrTmp = m_pControl->GetState(1000, &oas); | ||
1053 : | Irhall | 2014 | while ((oas != State_Stopped && hrTmp == S_OK ) || |
1054 : | hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE); | ||
1055 : | if (hr == S_OK) hr = hrTmp; | ||
1056 : | } | ||
1057 : | if (E == EC_ERRORABORT) hr = E_FAIL; | ||
1058 : | |||
1059 : | // End of pass 1 | ||
1060 : | pBitrateProgressNotify->GetDimensions(m_Width, m_Height); | ||
1061 : | pBitrateProgressNotify->GetBitrate(m_CountedFrames, m_TotalFramesSize); | ||
1062 : | pBitrateProgressNotify->Release(); | ||
1063 : | pBitrateProgressNotify = 0; | ||
1064 : | Isibaar | 2019 | TCHAR *pSrcStr = _tcsdup(m_szSourceFilePath); |
1065 : | TCHAR *pDstStr = _tcsdup(m_szDstFilePath); | ||
1066 : | Irhall | 2014 | |
1067 : | Isibaar | 2029 | m_pControl->Release(); |
1068 : | m_pEvent->Release(); | ||
1069 : | m_pControl = 0; | ||
1070 : | m_pEvent = 0; | ||
1071 : | Irhall | 2014 | int bBreakRequested = m_bBreakRequested; |
1072 : | //if (hr == S_OK) | ||
1073 : | Isibaar | 2045 | |
1074 : | m_pIChgTypeNorm->GetMeasuredTimes(m_MinETime, m_MaxETime, m_MinSTime, m_MaxSTime); | ||
1075 : | |||
1076 : | CleanUp(); | ||
1077 : | Irhall | 2014 | m_szSourceFilePath = pSrcStr; |
1078 : | m_szDstFilePath = pDstStr; | ||
1079 : | |||
1080 : | if (bBreakRequested || hr != S_OK) { | ||
1081 : | DeleteFile(m_szDstFilePath); | ||
1082 : | Isibaar | 2019 | DeleteFile(Pass_FILE); |
1083 : | Irhall | 2014 | hr = E_FAIL; |
1084 : | goto finish_recompress; | ||
1085 : | } | ||
1086 : | |||
1087 : | if (hr == S_OK) hr = CreateGraph(m_ProgressWnd, 2); | ||
1088 : | Isibaar | 2029 | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pControl); |
1089 : | if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pEvent); | ||
1090 : | Irhall | 2014 | |
1091 : | if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify, | ||
1092 : | (void **)&pBitrateProgressNotify); | ||
1093 : | //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify); | ||
1094 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_CountedFrames); | ||
1095 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd); | ||
1096 : | |||
1097 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(2); | ||
1098 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize); | ||
1099 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize); | ||
1100 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize); | ||
1101 : | } | ||
1102 : | else { | ||
1103 : | if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(1); | ||
1104 : | } | ||
1105 : | |||
1106 : | DeleteFile(m_szDstFilePath); | ||
1107 : | |||
1108 : | if (hr == S_OK) { | ||
1109 : | Isibaar | 2029 | hr = m_pControl->Run(); |
1110 : | Irhall | 2014 | if (hr == S_OK) { |
1111 : | Isibaar | 2029 | do hr = m_pControl->GetState(1000, &oas); |
1112 : | Irhall | 2014 | while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE); |
1113 : | } | ||
1114 : | } | ||
1115 : | |||
1116 : | Isibaar | 2029 | //#if 0 |
1117 : | // long Evt, P1, P2; | ||
1118 : | //if (hr == S_OK) do hr = m_pEvent->GetEvent(&Evt, &P1, &P2, INFINITE); | ||
1119 : | //while (Evt != EC_COMPLETE && (Evt != 3 || P1 == 0xC00D002F) && Evt != 2); | ||
1120 : | Irhall | 2014 | |
1121 : | Isibaar | 2029 | //for (int iCnt=0; (iCnt < m_UsedStreamsCnt) && (hr == S_OK); iCnt++) { |
1122 : | // if (hr == S_OK) do hr = pEvent->WaitForCompletion(INFINITE, &E); | ||
1123 : | // while (hr == S_OK && E != 1); | ||
1124 : | //} | ||
1125 : | //#endif | ||
1126 : | //if (hr == S_OK) hr = pEvent->WaitForCompletion(INFINITE, &E); | ||
1127 : | // long Evt; | ||
1128 : | if (hr == S_OK) hr = WaitForCompletion(&E); | ||
1129 : | Irhall | 2014 | |
1130 : | Isibaar | 2029 | if (m_pControl) { |
1131 : | Irhall | 2014 | if (E == EC_USERABORT) m_pSrcFilter->Stop(); |
1132 : | Isibaar | 2029 | HRESULT hrTmp = m_pControl->Stop(); |
1133 : | do hrTmp = m_pControl->GetState(1000, &oas); | ||
1134 : | Irhall | 2014 | while ((oas != State_Stopped && hrTmp == S_OK ) || |
1135 : | hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE); | ||
1136 : | if (hr == S_OK) hr = hrTmp; | ||
1137 : | } | ||
1138 : | if (E == EC_ERRORABORT) hr = E_FAIL; | ||
1139 : | |||
1140 : | Isibaar | 2029 | if (m_pControl) m_pControl->Release(); |
1141 : | if (m_pEvent) m_pEvent->Release(); | ||
1142 : | Irhall | 2014 | if (pBitrateProgressNotify) pBitrateProgressNotify->Release(); |
1143 : | |||
1144 : | Isibaar | 2019 | DeleteFile(Pass_FILE); |
1145 : | Irhall | 2014 | |
1146 : | finish_recompress: | ||
1147 : | |||
1148 : | if (m_bFileCopy && (hr != E_FAIL)) | ||
1149 : | fourcc_helper(m_szDstFilePath, "XVID", "xvid", 0); | ||
1150 : | |||
1151 : | if ((E == EC_COMPLETE || (m_bFileCopy && hr != E_FAIL)) && | ||
1152 : | ((int)(m_elapsedSize+m_curSize) >= m_totalSize)) | ||
1153 : | { | ||
1154 : | MessageBox(ghDlg, TEXT("Conversion finished!"), APP_NAME, 0); | ||
1155 : | } | ||
1156 : | |||
1157 : | m_Width = m_Height = 0; | ||
1158 : | |||
1159 : | if ((int)(m_elapsedSize+m_curSize) >= m_totalSize) | ||
1160 : | { | ||
1161 : | SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, TEXT("Source file:")); | ||
1162 : | SetDlgItemText(ghDlg, IDC_EDIT_SRC, TEXT("")); | ||
1163 : | SetDlgItemText(ghDlg, IDC_EDIT_DST, TEXT("")); | ||
1164 : | ShowWindow(m_ProgressWnd, SW_HIDE); | ||
1165 : | ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_SHOW); | ||
1166 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_SHOW); | ||
1167 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_SHOW); | ||
1168 : | ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_SHOW); | ||
1169 : | ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_SHOW); | ||
1170 : | OpenFilePath[0] = TEXT('\0'); | ||
1171 : | OpenFilePath[1] = TEXT('\0'); | ||
1172 : | sOfn.lpstrFile[0] = TEXT('\0'); | ||
1173 : | sOfn.lpstrFile[1] = TEXT('\0'); | ||
1174 : | SaveFilePath[0] = TEXT('\0'); | ||
1175 : | } | ||
1176 : | |||
1177 : | return hr; | ||
1178 : | } | ||
1179 : | |||
1180 : | void | ||
1181 : | RecompressGraph::BreakConversion() | ||
1182 : | { | ||
1183 : | m_bBreakRequested = 1; | ||
1184 : | if (m_pGraph) { | ||
1185 : | IMediaEventSink *pSink = 0; | ||
1186 : | m_pGraph->QueryInterface(IID_IMediaEventSink, (void **)&pSink); | ||
1187 : | |||
1188 : | if (pSink) { | ||
1189 : | pSink->Notify(EC_USERABORT, 0, 0); | ||
1190 : | pSink->Release(); | ||
1191 : | } | ||
1192 : | } | ||
1193 : | } | ||
1194 : | |||
1195 : | Isibaar | 2029 | void |
1196 : | RecompressGraph::RemoveIfUnconnectedInput(IBaseFilter *in_pFilter) | ||
1197 : | { | ||
1198 : | IPin *pPin; | ||
1199 : | HRESULT hr = GetFilterPin(in_pFilter, PINDIR_INPUT, 0, &pPin, GUID_NULL, GUID_NULL); | ||
1200 : | if (hr == S_OK && pPin) { | ||
1201 : | pPin->Release(); | ||
1202 : | m_pGraph->RemoveFilter(in_pFilter); | ||
1203 : | } | ||
1204 : | } | ||
1205 : | Irhall | 2014 | |
1206 : | //////////////////////////////////////////////////////////////////////////////// | ||
1207 : | // main.cpp | ||
1208 : | |||
1209 : | DWORD WINAPI | ||
1210 : | RecompressThreadProc(LPVOID xParam) | ||
1211 : | { | ||
1212 : | CoInitialize(0); | ||
1213 : | |||
1214 : | int error = 0; | ||
1215 : | int nbInputFiles = 1; | ||
1216 : | int totalSize = 0; | ||
1217 : | int elapsedSize = 0; | ||
1218 : | TCHAR *NextFileName = SrcFile; | ||
1219 : | TCHAR tempFile[2*MAX_PATH]; | ||
1220 : | |||
1221 : | Isibaar | 2019 | if(SrcFile[_tcslen(SrcFile) + 1] != TEXT('\0')) // Multiple input files? |
1222 : | Irhall | 2014 | { |
1223 : | nbInputFiles = 0; | ||
1224 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1225 : | Irhall | 2014 | |
1226 : | while(NextFileName[0] != L'\0') // Count total filesize and number of source files | ||
1227 : | { | ||
1228 : | DWORD filesize; | ||
1229 : | PathCombine(tempFile, SrcFile, NextFileName); | ||
1230 : | DetermineFileSize(tempFile, &filesize); | ||
1231 : | totalSize += filesize; | ||
1232 : | |||
1233 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1234 : | Irhall | 2014 | nbInputFiles++; |
1235 : | } | ||
1236 : | } | ||
1237 : | |||
1238 : | NextFileName = SrcFile; | ||
1239 : | if (nbInputFiles > 1) { | ||
1240 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; // Bypass dir and jump to first filename |
1241 : | Irhall | 2014 | } |
1242 : | |||
1243 : | HRESULT hr = S_OK; | ||
1244 : | int count = 0; | ||
1245 : | |||
1246 : | while ((count < nbInputFiles) && (hr == S_OK)) { | ||
1247 : | TCHAR szDstPath[2*MAX_PATH]; | ||
1248 : | |||
1249 : | count++; | ||
1250 : | |||
1251 : | if (nbInputFiles == 1) { | ||
1252 : | Isibaar | 2019 | _tcscpy(tempFile, SrcFile); // Src |
1253 : | Irhall | 2014 | |
1254 : | PathStripPath(SrcFile); | ||
1255 : | |||
1256 : | Isibaar | 2019 | LPTSTR ext = PathFindExtension(SrcFile); |
1257 : | Irhall | 2014 | TCHAR sztmpPath[2*MAX_PATH]; |
1258 : | Isibaar | 2019 | _tcsncpy(sztmpPath, SrcFile, (ext-SrcFile)); |
1259 : | Irhall | 2014 | sztmpPath[ext-SrcFile] = TEXT('\0'); |
1260 : | Isibaar | 2019 | _stprintf(sztmpPath, TEXT("%s_Xvid.avi"), sztmpPath); |
1261 : | Irhall | 2014 | |
1262 : | PathCombine(szDstPath, DstFile, sztmpPath); // Dst | ||
1263 : | } | ||
1264 : | else { | ||
1265 : | PathCombine(tempFile, SrcFile, NextFileName); // Src | ||
1266 : | |||
1267 : | Isibaar | 2019 | LPTSTR ext = PathFindExtension(NextFileName); |
1268 : | Irhall | 2014 | TCHAR sztmpPath[2*MAX_PATH]; |
1269 : | Isibaar | 2019 | _tcsncpy(sztmpPath, NextFileName, (ext-NextFileName)); |
1270 : | Irhall | 2014 | sztmpPath[ext-NextFileName] = TEXT('\0'); |
1271 : | Isibaar | 2019 | _stprintf(sztmpPath, TEXT("%s_Xvid.avi"), sztmpPath); |
1272 : | Irhall | 2014 | |
1273 : | PathCombine(szDstPath, DstFile, sztmpPath); // Dst | ||
1274 : | |||
1275 : | Isibaar | 2019 | NextFileName = &NextFileName[_tcslen(NextFileName) + 1]; |
1276 : | Irhall | 2014 | } |
1277 : | |||
1278 : | pRec->CleanUp(); | ||
1279 : | |||
1280 : | pRec->AddSourceFile(tempFile); | ||
1281 : | pRec->SetDstFileName(szDstPath); | ||
1282 : | pRec->SetProgress(elapsedSize, totalSize); | ||
1283 : | |||
1284 : | hr = pRec->CreateGraph((HWND)xParam, 1); | ||
1285 : | |||
1286 : | if (hr == S_OK) { | ||
1287 : | hr = pRec->Recompress(); | ||
1288 : | |||
1289 : | if (hr != S_OK) { | ||
1290 : | MessageBox((HWND)xParam, TEXT("Error: Conversion failure."), APP_NAME, MB_OK); | ||
1291 : | goto finish_thread; | ||
1292 : | } | ||
1293 : | } | ||
1294 : | else { | ||
1295 : | if (nbInputFiles == 1) | ||
1296 : | MessageBox((HWND)xParam, TEXT("Error: Source file not supported."), APP_NAME, MB_OK); | ||
1297 : | else | ||
1298 : | error = 1; // show message later | ||
1299 : | } | ||
1300 : | |||
1301 : | DWORD filesize; | ||
1302 : | DetermineFileSize(tempFile, &filesize); | ||
1303 : | |||
1304 : | elapsedSize += filesize; | ||
1305 : | } | ||
1306 : | |||
1307 : | finish_thread: | ||
1308 : | pRec->CleanUp(); | ||
1309 : | |||
1310 : | if (error) | ||
1311 : | MessageBox((HWND)xParam, | ||
1312 : | TEXT("Error: One or more input files could not be successfully converted!"), APP_NAME, MB_OK); | ||
1313 : | |||
1314 : | EnableWindow(GetDlgItem(ghDlg, IDC_BUTTON_START), 1); | ||
1315 : | |||
1316 : | CoUninitialize(); | ||
1317 : | return 0; | ||
1318 : | } | ||
1319 : | |||
1320 : | ////////////////////////////////////////////////////////////////////////////// | ||
1321 : | |||
1322 : | // Callback for GetOpenFileName hook | ||
1323 : | unsigned int CALLBACK | ||
1324 : | DialogHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | ||
1325 : | { | ||
1326 : | static HWND hwndParentDialog; | ||
1327 : | LPOFNOTIFY lpofn; | ||
1328 : | int cbLength; | ||
1329 : | static LPTSTR lpsz; | ||
1330 : | static int LastLen; | ||
1331 : | |||
1332 : | switch (uMsg) | ||
1333 : | { | ||
1334 : | case WM_INITDIALOG: | ||
1335 : | if(!SetProp(GetParent(hwnd), TEXT("OFN"), (void *) lParam)) | ||
1336 : | MessageBox(0, TEXT("SetProp() Failed"), APP_NAME, MB_OK); | ||
1337 : | return 0; | ||
1338 : | |||
1339 : | case WM_COMMAND: | ||
1340 : | break; | ||
1341 : | |||
1342 : | case WM_NOTIFY: | ||
1343 : | lpofn = (LPOFNOTIFY) lParam; | ||
1344 : | |||
1345 : | switch (lpofn->hdr.code) | ||
1346 : | { | ||
1347 : | case CDN_SELCHANGE: | ||
1348 : | LPOPENFILENAME lpofn; | ||
1349 : | cbLength = CommDlg_OpenSave_GetSpec(GetParent(hwnd), NULL, 0); | ||
1350 : | cbLength += _MAX_PATH; | ||
1351 : | |||
1352 : | lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd), TEXT("OFN")); | ||
1353 : | |||
1354 : | if ((int)lpofn->nMaxFile < cbLength) | ||
1355 : | { | ||
1356 : | // Free any previously allocated buffer. | ||
1357 : | if(lpsz) { | ||
1358 : | HeapFree(GetProcessHeap(), 0, lpsz); | ||
1359 : | } | ||
1360 : | // Allocate a new buffer | ||
1361 : | lpsz = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength*sizeof(TCHAR)); | ||
1362 : | if (lpsz) | ||
1363 : | { | ||
1364 : | lpofn->lpstrFile = lpsz; | ||
1365 : | lpofn->nMaxFile = cbLength; | ||
1366 : | } | ||
1367 : | } | ||
1368 : | break; | ||
1369 : | } | ||
1370 : | return 0; | ||
1371 : | |||
1372 : | case WM_DESTROY: | ||
1373 : | RemoveProp(GetParent(hwnd), TEXT("OFN")); | ||
1374 : | return 0; | ||
1375 : | } | ||
1376 : | |||
1377 : | return 0; | ||
1378 : | } | ||
1379 : | |||
1380 : | ////////////////////////////////////////////////////////////////////////////// | ||
1381 : | |||
1382 : | BOOL | ||
1383 : | GetFolderSelection(HWND hWnd, LPTSTR szBuf, LPCTSTR szTitle) | ||
1384 : | { | ||
1385 : | LPITEMIDLIST pidl = NULL; | ||
1386 : | BROWSEINFO bi = { 0 }; | ||
1387 : | BOOL bResult = FALSE; | ||
1388 : | |||
1389 : | bi.hwndOwner = hWnd; | ||
1390 : | bi.pszDisplayName = szBuf; | ||
1391 : | bi.pidlRoot = NULL; | ||
1392 : | bi.lpszTitle = szTitle; | ||
1393 : | bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; | ||
1394 : | |||
1395 : | if ((pidl = SHBrowseForFolder(&bi)) != NULL) | ||
1396 : | { | ||
1397 : | bResult = SHGetPathFromIDList(pidl, szBuf); | ||
1398 : | CoTaskMemFree(pidl); | ||
1399 : | } | ||
1400 : | |||
1401 : | return bResult; | ||
1402 : | } | ||
1403 : | |||
1404 : | ////////////////////////////////////////////////////////////////////////////// | ||
1405 : | |||
1406 : | LRESULT CALLBACK | ||
1407 : | DIALOG_MAIN(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | ||
1408 : | { | ||
1409 : | static HICON hIcon; | ||
1410 : | |||
1411 : | switch (message) | ||
1412 : | { | ||
1413 : | case WM_INITDIALOG: | ||
1414 : | HWND hwndOwner; | ||
1415 : | RECT rc, rcDlg, rcOwner; | ||
1416 : | |||
1417 : | if ((hwndOwner = GetParent(hDlg)) == NULL) | ||
1418 : | { | ||
1419 : | hwndOwner = GetDesktopWindow(); | ||
1420 : | } | ||
1421 : | |||
1422 : | GetWindowRect(hwndOwner, &rcOwner); | ||
1423 : | GetWindowRect(hDlg, &rcDlg); | ||
1424 : | CopyRect(&rc, &rcOwner); | ||
1425 : | |||
1426 : | OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); | ||
1427 : | OffsetRect(&rc, -rc.left, -rc.top); | ||
1428 : | OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); | ||
1429 : | |||
1430 : | SetWindowPos(hDlg, HWND_TOP, | ||
1431 : | rcOwner.left + (rc.right / 2), | ||
1432 : | rcOwner.top + (rc.bottom / 2), | ||
1433 : | 0, 0, SWP_NOSIZE); | ||
1434 : | |||
1435 : | hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 32, 32, 0); | ||
1436 : | SendMessage(hDlg, WM_SETICON, ICON_BIG , (LPARAM)hIcon); | ||
1437 : | ghDlg = hDlg; | ||
1438 : | return TRUE; | ||
1439 : | |||
1440 : | case WM_DESTROY: | ||
1441 : | DestroyIcon(hIcon); | ||
1442 : | PostQuitMessage(0); | ||
1443 : | break; | ||
1444 : | |||
1445 : | case WM_COMMAND: | ||
1446 : | Isibaar | 2029 | if (LOWORD(wParam) == IDCANCEL) { |
1447 : | Irhall | 2014 | EndDialog(hDlg, LOWORD(wParam)); |
1448 : | return TRUE; | ||
1449 : | } | ||
1450 : | else if (LOWORD(wParam) == IDC_BUTTON_SRC) { | ||
1451 : | sOfn.hwndOwner = hDlg; | ||
1452 : | |||
1453 : | GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath)); | ||
1454 : | |||
1455 : | Isibaar | 2019 | if (_tcslen(sOfn.lpstrFile) == 0) { |
1456 : | _stprintf(sOfn.lpstrFile, TEXT("%s"), OpenFilePath); | ||
1457 : | Irhall | 2014 | } |
1458 : | |||
1459 : | if (GetOpenFileName(&sOfn)) { | ||
1460 : | Isibaar | 2019 | if(sOfn.lpstrFile[_tcslen(sOfn.lpstrFile) + 1] != TEXT('\0')) // Multiple input files? |
1461 : | _stprintf(OpenFilePath, TEXT("%s (multiselect)"), sOfn.lpstrFile); | ||
1462 : | Irhall | 2014 | else |
1463 : | Isibaar | 2019 | _stprintf(OpenFilePath, TEXT("%s"), sOfn.lpstrFile); |
1464 : | Irhall | 2014 | |
1465 : | SetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath); | ||
1466 : | } | ||
1467 : | } | ||
1468 : | else if (LOWORD(wParam) == IDC_BUTTON_DST) { | ||
1469 : | sSfn.hwndOwner = hDlg; | ||
1470 : | GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0])); | ||
1471 : | if (GetFolderSelection(hDlg, SaveFilePath, TEXT("Please select the output folder"))) { | ||
1472 : | SetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath); | ||
1473 : | } | ||
1474 : | } | ||
1475 : | else if (LOWORD(wParam) == IDC_BUTTON_START) { | ||
1476 : | GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0])); | ||
1477 : | GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath[0])); | ||
1478 : | |||
1479 : | Isibaar | 2019 | if ((_tcslen(OpenFilePath) > 0 || _tcslen(sOfn.lpstrFile) > 0) && _tcslen(SaveFilePath) > 0) { |
1480 : | Irhall | 2014 | EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), 0); |
1481 : | Isibaar | 2019 | if (_tcslen(sOfn.lpstrFile) > 0) |
1482 : | Irhall | 2014 | SrcFile = sOfn.lpstrFile; |
1483 : | else { | ||
1484 : | Isibaar | 2019 | OpenFilePath[_tcslen(OpenFilePath)+1] = TEXT('\0'); |
1485 : | Irhall | 2014 | SrcFile = OpenFilePath; |
1486 : | } | ||
1487 : | |||
1488 : | Isibaar | 2019 | _tcscpy(DstFile, SaveFilePath); |
1489 : | Irhall | 2014 | hConvertThread = CreateThread(0, 0, RecompressThreadProc, GetDlgItem(hDlg, IDC_PROGRESSBAR), 0, 0); |
1490 : | } | ||
1491 : | else | ||
1492 : | MessageBox(ghDlg, TEXT("Error: You need to select a source file and output directory first!"), APP_NAME, 0); | ||
1493 : | } | ||
1494 : | break; | ||
1495 : | } | ||
1496 : | return FALSE; | ||
1497 : | } | ||
1498 : | |||
1499 : | |||
1500 : | int APIENTRY | ||
1501 : | _tWinMain(HINSTANCE hInstance, | ||
1502 : | HINSTANCE hPrevInstance, | ||
1503 : | LPTSTR lpCmdLine, | ||
1504 : | int nCmdShow) | ||
1505 : | { | ||
1506 : | CoInitialize(0); | ||
1507 : | |||
1508 : | static TCHAR buf[2*MAX_PATH+1]; | ||
1509 : | |||
1510 : | sOfn.lStructSize = sizeof (OPENFILENAME); | ||
1511 : | sOfn.hInstance = hInstance; | ||
1512 : | #ifdef ALLOW_ONLY_AVI_INPUT | ||
1513 : | sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx)\0*.avi;*.divx\0All files\0*.*\0"); | ||
1514 : | #else | ||
1515 : | sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx;*.mp4;*.mov;*.wmv;*.asf;*.mkv)\0*.avi;*.mp4;*.mov;*.wmv;*.asf;*.divx;*.mkv\0All files\0*.*\0"); | ||
1516 : | #endif | ||
1517 : | sOfn.lpstrCustomFilter = 0; | ||
1518 : | sOfn.nMaxCustFilter = 0; | ||
1519 : | sOfn.nFilterIndex = 1; | ||
1520 : | sOfn.lpstrFileTitle = 0; | ||
1521 : | sOfn.nMaxFileTitle = 0; | ||
1522 : | sOfn.lpstrInitialDir = 0; | ||
1523 : | sOfn.lpstrTitle = TEXT("Select source file"); | ||
1524 : | sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; | ||
1525 : | sOfn.nFileOffset = 0; | ||
1526 : | sOfn.nFileExtension = 0; | ||
1527 : | sOfn.lpstrDefExt = TEXT(".avi"); | ||
1528 : | sOfn.lCustData = (LPARAM)(&sOfn); | ||
1529 : | sOfn.lpfnHook = DialogHook; | ||
1530 : | sOfn.lpTemplateName = 0; | ||
1531 : | sOfn.pvReserved = 0; | ||
1532 : | sOfn.dwReserved = 0; | ||
1533 : | sOfn.FlagsEx = 0; | ||
1534 : | sOfn.lpstrFile = buf; | ||
1535 : | sOfn.nMaxFile = 2*MAX_PATH; | ||
1536 : | sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_ENABLEHOOK; | ||
1537 : | |||
1538 : | |||
1539 : | sSfn.lStructSize = sizeof (OPENFILENAME); | ||
1540 : | sSfn.hInstance = hInstance; | ||
1541 : | sSfn.lpstrFilter = TEXT("Avi files (*.avi)\0*.avi\0"); | ||
1542 : | sSfn.lpstrCustomFilter = 0; | ||
1543 : | sSfn.nMaxCustFilter = 0; | ||
1544 : | sSfn.nFilterIndex = 1; | ||
1545 : | sSfn.lpstrFileTitle = 0; | ||
1546 : | sSfn.nMaxFileTitle = 0; | ||
1547 : | sSfn.lpstrInitialDir = 0; | ||
1548 : | sSfn.lpstrTitle = TEXT("Select target file"); | ||
1549 : | sSfn.nFileOffset = 0; | ||
1550 : | sSfn.nFileExtension = 0; | ||
1551 : | sSfn.lpstrDefExt = TEXT(".avi"); | ||
1552 : | sSfn.lpTemplateName = 0; | ||
1553 : | sSfn.pvReserved = 0; | ||
1554 : | sSfn.dwReserved = 0; | ||
1555 : | sSfn.FlagsEx = 0; | ||
1556 : | |||
1557 : | pRec = new RecompressGraph(); | ||
1558 : | DialogBox(hInstance, (LPCTSTR)IDD_DIALOG_MAIN, NULL, (DLGPROC)DIALOG_MAIN); | ||
1559 : | pRec->BreakConversion(); | ||
1560 : | if (hConvertThread != NULL) { | ||
1561 : | WaitForSingleObject(hConvertThread, INFINITE); | ||
1562 : | CloseHandle(hConvertThread); | ||
1563 : | } | ||
1564 : | |||
1565 : | delete pRec; | ||
1566 : | CoUninitialize(); | ||
1567 : | |||
1568 : | return 0; | ||
1569 : | } | ||
1570 : |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |