[svn] / trunk / xvidextra / src / apps / miniconvert / recompress.cpp Repository:
ViewVC logotype

Annotation of /trunk/xvidextra/src/apps/miniconvert/recompress.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2014 - (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 :     #define Pass_FILE "xvid_2pass.stats"
45 :     #define Pass_FILE_W L"xvid_2pass.stats"
46 :    
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 :     swprintf(wsz, STRING_LENGTH, TEXT("FilterGraph %08x pid %08x"),
125 :     (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
126 :    
127 :     HRESULT hr = CreateItemMoniker(TEXT("!"), wsz, &pMoniker);
128 :     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 :     if (hr == S_OK) hr = m_pGraph->AddFilter(m_pVideoMeter, TEXT("Video meter"));
361 :     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 :     if (hr == S_OK) hr = m_pGraph->AddFilter(m_pXvidEncoder, TEXT("Encoder"));
431 :    
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 :     strcpy(m_pXvidCfgRec->stats, Pass_FILE);
516 :    
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 :     if (hr == S_OK) hr = m_pGraph->AddFilter(m_pChgType, TEXT("ChgToxvid"));
528 :     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 :     TCHAR buf[MAX_PATH+50];
568 :     swprintf(buf, MAX_PATH+50, TEXT("Converting %s..."), m_szSourceFilePath);
569 :     ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_HIDE);
570 :     ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_HIDE);
571 :     ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_HIDE);
572 :     ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_HIDE);
573 :     ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_HIDE);
574 :     ShowWindow(m_ProgressWnd, SW_SHOW);
575 :     SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, buf);
576 :     }
577 :    
578 :     return hr;
579 :     }
580 :    
581 :     HRESULT
582 :     RecompressGraph::AddAudioStreams(int check_only)
583 :     {
584 :     IPin *pOutPin=0, *pInPin = 0;
585 :     PIN_INFO PinInfo = {NULL};
586 :     HRESULT hr = S_OK;
587 :     int bFraunhoferPro = 0;
588 :    
589 :     HKEY hKey;
590 :     DWORD size = MAX_PATH;
591 :     TCHAR kvalue[MAX_PATH];
592 :     RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"), 0, KEY_READ, &hKey);
593 :     if (RegQueryValueEx(hKey, TEXT("msacm.l3acm"), 0, 0, (LPBYTE)kvalue, &size) != ERROR_SUCCESS)
594 :     bFraunhoferPro = 0;
595 :     else {
596 :     // C:\WINDOWS\System32\l3codecp.acm was not recognized
597 :     int sLen = wcslen(kvalue);
598 :     if ((sLen >= 12) && (wcscmp(&(kvalue[sLen - 12]), TEXT("l3codecp.acm")) == 0))
599 :     bFraunhoferPro = 1;
600 :     }
601 :    
602 :     if (m_pVideoMeter) {
603 :     if (GetFilterPin(m_pVideoMeter, PINDIR_INPUT, 1, &pInPin,
604 :     MEDIATYPE_Video, GUID_NULL) == S_OK)
605 :     {
606 :     hr = pInPin->ConnectedTo(&pOutPin);
607 :     if (hr == S_OK) hr = pOutPin->QueryPinInfo(&PinInfo);
608 :     if (pOutPin) pOutPin->Release();
609 :     if (pInPin) pInPin->Release();
610 :     }
611 :     } else hr = m_pSrcFilter->QueryInterface(IID_IBaseFilter, (void **)&PinInfo.pFilter);
612 :    
613 :     IPin *pAudioPin = 0;
614 :     if (check_only) {
615 :     if ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0,
616 :     &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK))
617 :     {
618 :     AM_MEDIA_TYPE *paomt = 0;
619 :     int bNeedsRecompression = 0;
620 :     IEnumMediaTypes *pAmtEnum = 0;
621 :     hr = pAudioPin->EnumMediaTypes(&pAmtEnum);
622 :    
623 :     if (hr == S_OK) {
624 :     hr = pAmtEnum->Reset();
625 :     if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0);
626 :     if (hr == S_OK && paomt->subtype.Data1 != 0x55 &&
627 :     (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3
628 :     {
629 :     bNeedsRecompression = 1;
630 :     m_bFileCopy = 0; // file copy strategy cannot be used on this input
631 :     }
632 :     else if (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags & 4) { // VBR
633 :     bNeedsRecompression = 1;
634 :     }
635 :     if (pAmtEnum) pAmtEnum->Release();
636 :     pAmtEnum = 0;
637 :     if (paomt) DeleteMediaType(paomt);
638 :     if (hr == S_OK && bNeedsRecompression && !bFraunhoferPro) {
639 :     //MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0);
640 :     hr = VFW_E_CANNOT_CONNECT;
641 :     }
642 :     }
643 :     pAudioPin->Release();
644 :     }
645 :     }
646 :     else {
647 :     while ((hr == S_OK) && (GetFilterPin(PinInfo.pFilter, PINDIR_OUTPUT, 0,
648 :     &pAudioPin, MEDIATYPE_Audio, GUID_NULL) == S_OK))
649 :     {
650 :     AM_MEDIA_TYPE *paomt = 0;
651 :     int bNeedsRecompression = 0;
652 :     IEnumMediaTypes *pAmtEnum = 0;
653 :     hr = pAudioPin->EnumMediaTypes(&pAmtEnum);
654 :     if (hr == S_OK) {
655 :     hr = pAmtEnum->Reset();
656 :     if (hr == S_OK) hr = pAmtEnum->Next(1, &paomt, 0);
657 :     if ((hr == S_OK) && (paomt->subtype.Data1 != 0x55) &&
658 :     (paomt->subtype.Data1 != 0x2000)) // don't recompress MP3/AC3
659 :     {
660 :     bNeedsRecompression = 1;
661 :     m_bFileCopy = 0; // file copy strategy cannot be used on this input
662 :     }
663 :     else if (((MPEGLAYER3WAVEFORMAT *)paomt->pbFormat)->fdwFlags & 4) { // VBR
664 :     bNeedsRecompression = 1;
665 :     }
666 :     if (pAmtEnum) pAmtEnum->Release();
667 :     pAmtEnum = 0;
668 :    
669 :     if (paomt) DeleteMediaType(paomt);
670 :     if (hr == S_OK && bNeedsRecompression) {
671 :    
672 :     IBaseFilter *pAudioCompressor = 0;
673 :     hr = AddDirectXFilterByMoniker(CLSID_AudioCompressorCategory, "MPEG Layer-3", &pAudioCompressor, 0);
674 :     if (hr == S_OK) hr = m_pGraph->AddFilter(pAudioCompressor, 0);
675 :    
676 :     if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pAudioCompressor, MEDIATYPE_Audio, GUID_NULL, 0);
677 :    
678 :     IPin *pMp3Pin = 0;
679 :     if (hr == S_OK) hr = GetFilterPin(pAudioCompressor, PINDIR_OUTPUT, 0, &pMp3Pin, MEDIATYPE_Audio, GUID_NULL);
680 :     IEnumMediaTypes *pMp3MtEnum = 0;
681 :    
682 :     if (hr == S_OK) hr = pMp3Pin->EnumMediaTypes(&pMp3MtEnum);
683 :     AM_MEDIA_TYPE *pMp3mt = 0;
684 :     int bConnected = 0;
685 :    
686 :     if (hr == S_OK) {
687 :     while (!bConnected && (hr = pMp3MtEnum->Next(1, &pMp3mt, 0)) == S_OK) {
688 :     MPEGLAYER3WAVEFORMAT *pMp3cb = (MPEGLAYER3WAVEFORMAT *)pMp3mt->pbFormat;
689 :     if (
690 :     //pMp3cb->nSamplesPerSec == 44100 &&
691 :     pMp3cb->wfx.nAvgBytesPerSec == 16000)
692 :     {
693 :     CUnknown *pMp3Normalizer = 0;
694 :     IBaseFilter *pIMp3Normalizer = 0;
695 :     // Type 2 - only 16000 Bps = 128kbit audio
696 :     if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 2);
697 :     if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter,
698 :     (void **)&pIMp3Normalizer);
699 :     if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0);
700 :    
701 :     IPin *pNormMp3Pin = 0;
702 :     if (hr == S_OK) hr = GetFilterPin(pIMp3Normalizer, PINDIR_INPUT, 0, &pNormMp3Pin, GUID_NULL, GUID_NULL);
703 :     if (hr == S_OK) hr = m_pGraph->ConnectDirect(pMp3Pin, pNormMp3Pin, pMp3mt);
704 :     if (pNormMp3Pin) pNormMp3Pin->Release();
705 :    
706 :     if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, GUID_NULL, GUID_NULL, 1);
707 :     if (pIMp3Normalizer) pIMp3Normalizer->Release();
708 :     if (hr == S_OK) bConnected = 1;
709 :     }
710 :     DeleteMediaType(pMp3mt);
711 :     }
712 :     }
713 :     if ((!bConnected || !bFraunhoferPro) && hr == S_OK) hr = VFW_E_CANNOT_CONNECT;
714 :     //if (hr == S_OK && !bFraunhoferPro) MessageBox(0, "Error: Windows Media Player 11 needs to be installed to convert this Source File", APP_NAME, 0);
715 :     if (pMp3Pin) pMp3Pin->Release();
716 :     if (pMp3MtEnum) pMp3MtEnum->Release();
717 :     if (pAudioCompressor) pAudioCompressor->Release();
718 :     }
719 :     else {
720 :     CUnknown *pMp3Normalizer = 0;
721 :     IBaseFilter *pIMp3Normalizer = 0;
722 :    
723 :     if (hr == S_OK) pMp3Normalizer = CProgressNotifyFilter::CreateInstance(0, &hr, 1);
724 :     if (hr == S_OK) hr = pMp3Normalizer->NonDelegatingQueryInterface(IID_IBaseFilter, (void **)&pIMp3Normalizer);
725 :     if (hr == S_OK) hr = m_pGraph->AddFilter(pIMp3Normalizer, 0);
726 :     if (hr == S_OK) hr = ConnectFilters(m_pGraph, pAudioPin, pIMp3Normalizer, MEDIATYPE_Audio, GUID_NULL, 0);
727 :     if (hr == S_OK) hr = ConnectFilters(m_pGraph, pIMp3Normalizer, m_pMuxer, MEDIATYPE_Audio, GUID_NULL, 0);
728 :     if (pIMp3Normalizer) pIMp3Normalizer->Release();
729 :     }
730 :     if (hr == S_OK && PinInfo.pFilter == m_pSrcFilter) m_UsedStreamsCnt++;
731 :     }
732 :     pAudioPin->Release();
733 :     }
734 :     }
735 :    
736 :     if (PinInfo.pFilter) PinInfo.pFilter->Release();
737 :     return hr;
738 :     }
739 :    
740 :     HRESULT
741 :     RecompressGraph::AddFilterByCLSID(GUID *in_Filter, IBaseFilter **out_pFilter)
742 :     {
743 :     HRESULT hr = CoCreateInstance(*in_Filter, NULL, CLSCTX_INPROC_SERVER,
744 :     IID_IBaseFilter, (void **)out_pFilter);
745 :     if (hr == S_OK) hr = m_pGraph->AddFilter(*out_pFilter, NULL);
746 :    
747 :     return hr;
748 :     }
749 :    
750 :     HRESULT
751 :     RecompressGraph::SetDstFileName(LPCTSTR in_szFilePath)
752 :     {
753 :     if (m_pGraph)
754 :     return E_UNEXPECTED;
755 :    
756 :     if (m_szDstFilePath)
757 :     free (m_szDstFilePath);
758 :    
759 :     m_szDstFilePath = _wcsdup(in_szFilePath);
760 :    
761 :     return S_OK;
762 :     }
763 :    
764 :     HRESULT
765 :     RecompressGraph::AddFileWriter(LPCTSTR in_szFilePath)
766 :     {
767 :     if (!m_pGraph || m_pFileWriter)
768 :     return E_UNEXPECTED;
769 :    
770 :     HRESULT hr = AddFilterByCLSID((GUID *)&CLSID_FileWriter, &m_pFileWriter);
771 :     IFileSinkFilter* pDst=0;
772 :     if (hr == S_OK) hr = m_pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)(&pDst));
773 :     if (hr == S_OK) hr = pDst->SetFileName(in_szFilePath, &m_DstFileMediaType);
774 :    
775 :     if (pDst)
776 :     pDst->Release();
777 :    
778 :     return hr;
779 :     }
780 :    
781 :     HRESULT
782 :     RecompressGraph::AddSourceFile(LPCTSTR in_szFilePath)
783 :     {
784 :     if (m_pGraph) return E_UNEXPECTED;
785 :    
786 :     if (m_szSourceFilePath)
787 :     free (m_szSourceFilePath);
788 :    
789 :     m_szSourceFilePath = _wcsdup(in_szFilePath);
790 :    
791 :     return S_OK;
792 :     }
793 :    
794 :     HRESULT
795 :     RecompressGraph::AddSourceFilter(LPCTSTR in_szFilePath)
796 :     {
797 :     if (!m_pGraph || m_pSrcFilter) return E_UNEXPECTED;
798 :    
799 :     HRESULT hr = m_pGraph->AddSourceFilter(in_szFilePath, TEXT("Source filter"), &m_pSrcFilter);
800 :    
801 :     #if 0
802 :     HRESULT hr = AddFilterByCLSID((GUID *)&CLSID_AsyncReader, &this->m_pSrcFilter);
803 :     IFileSourceFilter* pSrc =0 ;
804 :     if (hr == S_OK) hr = m_pSrcFilter->QueryInterface(IID_IFileSourceFilter, (void **)(&pSrc));
805 :     if (hr == S_OK) hr = pSrc->Load(pwName, &m_SrcFileMediaType);
806 :     if (pSrc) pSrc->Release();
807 :     #endif
808 :    
809 :     return hr;
810 :     }
811 :    
812 :     HRESULT
813 :     RecompressGraph::SetProgress(int elapsedSize, int totalSize)
814 :     {
815 :    
816 :     m_elapsedSize = elapsedSize;
817 :     m_totalSize = totalSize;
818 :    
819 :     return S_OK;
820 :     }
821 :    
822 :     HRESULT
823 :     RecompressGraph::Recompress()
824 :     {
825 :     if (!m_pGraph) return E_UNEXPECTED;
826 :    
827 :     IMediaEvent *pEvent = 0;
828 :     IMediaControl *pControl = 0;
829 :     HRESULT hr = S_OK;
830 :    
831 :     if (hr == S_OK && m_bFileCopy == 1 &&
832 :     fourcc_helper(m_szSourceFilePath, NULL, NULL, 1)==0) // check input is AVI !
833 :     {
834 :     if (!CopyFileEx(m_szSourceFilePath, m_szDstFilePath,
835 :     CopyProgressRoutine, this, FALSE, 0) || m_bBreakRequested) {
836 :     hr = E_FAIL;
837 :     DeleteFile(m_szDstFilePath);
838 :     }
839 :    
840 :     goto finish_recompress;
841 :     }
842 :    
843 :     hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
844 :     if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
845 :    
846 :     IRecProgressNotify *pBitrateProgressNotify=0;
847 :     OAFilterState oas;
848 :     long E=0;
849 :    
850 :     if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify,
851 :     (void **)&pBitrateProgressNotify);
852 :    
853 :     //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify);
854 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_TotalFrames);
855 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd);
856 :    
857 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize);
858 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize);
859 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize);
860 :    
861 :     if (m_pXvidEncoder) {
862 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(0);
863 :    
864 :     m_pXvidConfig->Release();
865 :     m_pXvidConfig = 0;
866 :    
867 :     if (hr == S_OK) {
868 :     hr = pControl->Run();
869 :     if (hr == S_OK) {
870 :     do hr = pControl->GetState(1000, &oas);
871 :     while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE);
872 :     }
873 :     }
874 :    
875 :     //long Evt, P1, P2;
876 :     //if (hr == S_OK) do hr = pEvent->GetEvent(&Evt, &P1, &P2, INFINITE);
877 :     //while (Evt != EC_COMPLETE && Evt != 3 && Evt != 2);
878 :     if (hr == S_OK) hr = pEvent->WaitForCompletion(INFINITE, &E);
879 :    
880 :     if (pControl) {
881 :     HRESULT hrTmp;
882 :     if (E == EC_USERABORT) m_pSrcFilter->Stop();
883 :     hrTmp = pControl->Stop();
884 :     do hrTmp = pControl->GetState(1000, &oas);
885 :     while ((oas != State_Stopped && hrTmp == S_OK ) ||
886 :     hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE);
887 :     if (hr == S_OK) hr = hrTmp;
888 :     }
889 :     if (E == EC_ERRORABORT) hr = E_FAIL;
890 :    
891 :     // End of pass 1
892 :     pBitrateProgressNotify->GetDimensions(m_Width, m_Height);
893 :     pBitrateProgressNotify->GetBitrate(m_CountedFrames, m_TotalFramesSize);
894 :     pBitrateProgressNotify->Release();
895 :     pBitrateProgressNotify = 0;
896 :     TCHAR *pSrcStr = _wcsdup(m_szSourceFilePath);
897 :     TCHAR *pDstStr = _wcsdup(m_szDstFilePath);
898 :    
899 :     pControl->Release();
900 :     pEvent->Release();
901 :     pControl = 0;
902 :     pEvent = 0;
903 :     int bBreakRequested = m_bBreakRequested;
904 :     //if (hr == S_OK)
905 :     CleanUp();
906 :     m_szSourceFilePath = pSrcStr;
907 :     m_szDstFilePath = pDstStr;
908 :    
909 :     if (bBreakRequested || hr != S_OK) {
910 :     DeleteFile(m_szDstFilePath);
911 :     DeleteFile(Pass_FILE_W);
912 :     hr = E_FAIL;
913 :     goto finish_recompress;
914 :     }
915 :    
916 :     if (hr == S_OK) hr = CreateGraph(m_ProgressWnd, 2);
917 :     if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
918 :     if (hr == S_OK) hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
919 :    
920 :     if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : m_pChgType)->QueryInterface(IID_IRecProgressNotify,
921 :     (void **)&pBitrateProgressNotify);
922 :     //if (hr == S_OK) hr = (m_pVideoMeter ? m_pVideoMeter : (m_pEmmsDummy ? m_pEmmsDummy : m_pChgType))->QueryInterface(IID_IRecProgressNotify, (void **)&pBitrateProgressNotify);
923 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalFrames(m_CountedFrames);
924 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetNotifyWnd(m_ProgressWnd);
925 :    
926 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(2);
927 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetTotalSize(m_totalSize);
928 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetElapsedSize(m_elapsedSize);
929 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetCurSize(m_curSize);
930 :     }
931 :     else {
932 :     if (hr == S_OK) hr = pBitrateProgressNotify->SetPass(1);
933 :     }
934 :    
935 :     DeleteFile(m_szDstFilePath);
936 :    
937 :     if (hr == S_OK) {
938 :     hr = pControl->Run();
939 :     if (hr == S_OK) {
940 :     do hr = pControl->GetState(1000, &oas);
941 :     while ((oas != State_Running && hr == S_OK ) || hr == VFW_S_STATE_INTERMEDIATE || hr == S_FALSE);
942 :     }
943 :     }
944 :    
945 :     #if 0
946 :     long Evt, P1, P2;
947 :     if (hr == S_OK) do hr = pEvent->GetEvent(&Evt, &P1, &P2, INFINITE);
948 :     while (Evt != EC_COMPLETE && Evt != 3 && Evt != 2);
949 :    
950 :     for (int iCnt=0; (iCnt < m_UsedStreamsCnt) && (hr == S_OK); iCnt++) {
951 :     if (hr == S_OK) do hr = pEvent->WaitForCompletion(INFINITE, &E);
952 :     while (hr == S_OK && E != 1);
953 :     }
954 :     #endif
955 :     if (hr == S_OK) hr = pEvent->WaitForCompletion(INFINITE, &E);
956 :    
957 :     if (pControl) {
958 :     if (E == EC_USERABORT) m_pSrcFilter->Stop();
959 :     HRESULT hrTmp = pControl->Stop();
960 :     do hrTmp = pControl->GetState(1000, &oas);
961 :     while ((oas != State_Stopped && hrTmp == S_OK ) ||
962 :     hrTmp == VFW_S_STATE_INTERMEDIATE || hrTmp == S_FALSE);
963 :     if (hr == S_OK) hr = hrTmp;
964 :     }
965 :     if (E == EC_ERRORABORT) hr = E_FAIL;
966 :    
967 :     if (pControl) pControl->Release();
968 :     if (pEvent) pEvent->Release();
969 :     if (pBitrateProgressNotify) pBitrateProgressNotify->Release();
970 :    
971 :     DeleteFile(Pass_FILE_W);
972 :    
973 :     finish_recompress:
974 :    
975 :     if (m_bFileCopy && (hr != E_FAIL))
976 :     fourcc_helper(m_szDstFilePath, "XVID", "xvid", 0);
977 :    
978 :     if ((E == EC_COMPLETE || (m_bFileCopy && hr != E_FAIL)) &&
979 :     ((int)(m_elapsedSize+m_curSize) >= m_totalSize))
980 :     {
981 :     MessageBox(ghDlg, TEXT("Conversion finished!"), APP_NAME, 0);
982 :     }
983 :    
984 :     m_Width = m_Height = 0;
985 :    
986 :     if ((int)(m_elapsedSize+m_curSize) >= m_totalSize)
987 :     {
988 :     SetDlgItemText(ghDlg, IDC_SOURCE_LABEL, TEXT("Source file:"));
989 :     SetDlgItemText(ghDlg, IDC_EDIT_SRC, TEXT(""));
990 :     SetDlgItemText(ghDlg, IDC_EDIT_DST, TEXT(""));
991 :     ShowWindow(m_ProgressWnd, SW_HIDE);
992 :     ShowWindow(GetDlgItem(ghDlg, IDC_TARGET_LABEL), SW_SHOW);
993 :     ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_SRC), SW_SHOW);
994 :     ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_SRC), SW_SHOW);
995 :     ShowWindow(GetDlgItem(ghDlg, IDC_EDIT_DST), SW_SHOW);
996 :     ShowWindow(GetDlgItem(ghDlg, IDC_BUTTON_DST), SW_SHOW);
997 :     OpenFilePath[0] = TEXT('\0');
998 :     OpenFilePath[1] = TEXT('\0');
999 :     sOfn.lpstrFile[0] = TEXT('\0');
1000 :     sOfn.lpstrFile[1] = TEXT('\0');
1001 :     SaveFilePath[0] = TEXT('\0');
1002 :     }
1003 :    
1004 :     return hr;
1005 :     }
1006 :    
1007 :     void
1008 :     RecompressGraph::BreakConversion()
1009 :     {
1010 :     m_bBreakRequested = 1;
1011 :     if (m_pGraph) {
1012 :     IMediaEventSink *pSink = 0;
1013 :     m_pGraph->QueryInterface(IID_IMediaEventSink, (void **)&pSink);
1014 :    
1015 :     if (pSink) {
1016 :     pSink->Notify(EC_USERABORT, 0, 0);
1017 :     pSink->Release();
1018 :     }
1019 :     }
1020 :     }
1021 :    
1022 :    
1023 :     ////////////////////////////////////////////////////////////////////////////////
1024 :     // main.cpp
1025 :    
1026 :     DWORD WINAPI
1027 :     RecompressThreadProc(LPVOID xParam)
1028 :     {
1029 :     CoInitialize(0);
1030 :    
1031 :     int error = 0;
1032 :     int nbInputFiles = 1;
1033 :     int totalSize = 0;
1034 :     int elapsedSize = 0;
1035 :     TCHAR *NextFileName = SrcFile;
1036 :     TCHAR tempFile[2*MAX_PATH];
1037 :    
1038 :     if(SrcFile[wcslen(SrcFile) + 1] != TEXT('\0')) // Multiple input files?
1039 :     {
1040 :     nbInputFiles = 0;
1041 :     NextFileName = &NextFileName[wcslen(NextFileName) + 1];
1042 :    
1043 :     while(NextFileName[0] != L'\0') // Count total filesize and number of source files
1044 :     {
1045 :     DWORD filesize;
1046 :     PathCombine(tempFile, SrcFile, NextFileName);
1047 :     DetermineFileSize(tempFile, &filesize);
1048 :     totalSize += filesize;
1049 :    
1050 :     NextFileName = &NextFileName[wcslen(NextFileName) + 1];
1051 :     nbInputFiles++;
1052 :     }
1053 :     }
1054 :    
1055 :     NextFileName = SrcFile;
1056 :     if (nbInputFiles > 1) {
1057 :     NextFileName = &NextFileName[wcslen(NextFileName) + 1]; // Bypass dir and jump to first filename
1058 :     }
1059 :    
1060 :     HRESULT hr = S_OK;
1061 :     int count = 0;
1062 :    
1063 :     while ((count < nbInputFiles) && (hr == S_OK)) {
1064 :     TCHAR szDstPath[2*MAX_PATH];
1065 :    
1066 :     count++;
1067 :    
1068 :     if (nbInputFiles == 1) {
1069 :     wcscpy(tempFile, SrcFile); // Src
1070 :    
1071 :     PathStripPath(SrcFile);
1072 :    
1073 :     LPWSTR ext = PathFindExtension(SrcFile);
1074 :     TCHAR sztmpPath[2*MAX_PATH];
1075 :     wcsncpy(sztmpPath, SrcFile, (ext-SrcFile));
1076 :     sztmpPath[ext-SrcFile] = TEXT('\0');
1077 :     swprintf(sztmpPath, 2*MAX_PATH, TEXT("%s_Xvid%s"), sztmpPath, ext);
1078 :    
1079 :     PathCombine(szDstPath, DstFile, sztmpPath); // Dst
1080 :     }
1081 :     else {
1082 :     PathCombine(tempFile, SrcFile, NextFileName); // Src
1083 :    
1084 :     LPWSTR ext = PathFindExtension(NextFileName);
1085 :     TCHAR sztmpPath[2*MAX_PATH];
1086 :     wcsncpy(sztmpPath, NextFileName, (ext-NextFileName));
1087 :     sztmpPath[ext-NextFileName] = TEXT('\0');
1088 :     swprintf(sztmpPath, 2*MAX_PATH, TEXT("%s_Xvid%s"), sztmpPath, ext);
1089 :    
1090 :     PathCombine(szDstPath, DstFile, sztmpPath); // Dst
1091 :    
1092 :     NextFileName = &NextFileName[wcslen(NextFileName) + 1];
1093 :     }
1094 :    
1095 :     pRec->CleanUp();
1096 :    
1097 :     pRec->AddSourceFile(tempFile);
1098 :     pRec->SetDstFileName(szDstPath);
1099 :     pRec->SetProgress(elapsedSize, totalSize);
1100 :    
1101 :     hr = pRec->CreateGraph((HWND)xParam, 1);
1102 :    
1103 :     if (hr == S_OK) {
1104 :     hr = pRec->Recompress();
1105 :    
1106 :     if (hr != S_OK) {
1107 :     MessageBox((HWND)xParam, TEXT("Error: Conversion failure."), APP_NAME, MB_OK);
1108 :     goto finish_thread;
1109 :     }
1110 :     }
1111 :     else {
1112 :     if (nbInputFiles == 1)
1113 :     MessageBox((HWND)xParam, TEXT("Error: Source file not supported."), APP_NAME, MB_OK);
1114 :     else
1115 :     error = 1; // show message later
1116 :     }
1117 :    
1118 :     DWORD filesize;
1119 :     DetermineFileSize(tempFile, &filesize);
1120 :    
1121 :     elapsedSize += filesize;
1122 :     }
1123 :    
1124 :     finish_thread:
1125 :     pRec->CleanUp();
1126 :    
1127 :     if (error)
1128 :     MessageBox((HWND)xParam,
1129 :     TEXT("Error: One or more input files could not be successfully converted!"), APP_NAME, MB_OK);
1130 :    
1131 :     EnableWindow(GetDlgItem(ghDlg, IDC_BUTTON_START), 1);
1132 :    
1133 :     CoUninitialize();
1134 :     return 0;
1135 :     }
1136 :    
1137 :     //////////////////////////////////////////////////////////////////////////////
1138 :    
1139 :     // Callback for GetOpenFileName hook
1140 :     unsigned int CALLBACK
1141 :     DialogHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1142 :     {
1143 :     static HWND hwndParentDialog;
1144 :     LPOFNOTIFY lpofn;
1145 :     int cbLength;
1146 :     static LPTSTR lpsz;
1147 :     static int LastLen;
1148 :    
1149 :     switch (uMsg)
1150 :     {
1151 :     case WM_INITDIALOG:
1152 :     if(!SetProp(GetParent(hwnd), TEXT("OFN"), (void *) lParam))
1153 :     MessageBox(0, TEXT("SetProp() Failed"), APP_NAME, MB_OK);
1154 :     return 0;
1155 :    
1156 :     case WM_COMMAND:
1157 :     break;
1158 :    
1159 :     case WM_NOTIFY:
1160 :     lpofn = (LPOFNOTIFY) lParam;
1161 :    
1162 :     switch (lpofn->hdr.code)
1163 :     {
1164 :     case CDN_SELCHANGE:
1165 :     LPOPENFILENAME lpofn;
1166 :     cbLength = CommDlg_OpenSave_GetSpec(GetParent(hwnd), NULL, 0);
1167 :     cbLength += _MAX_PATH;
1168 :    
1169 :     lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd), TEXT("OFN"));
1170 :    
1171 :     if ((int)lpofn->nMaxFile < cbLength)
1172 :     {
1173 :     // Free any previously allocated buffer.
1174 :     if(lpsz) {
1175 :     HeapFree(GetProcessHeap(), 0, lpsz);
1176 :     }
1177 :     // Allocate a new buffer
1178 :     lpsz = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength*sizeof(TCHAR));
1179 :     if (lpsz)
1180 :     {
1181 :     lpofn->lpstrFile = lpsz;
1182 :     lpofn->nMaxFile = cbLength;
1183 :     }
1184 :     }
1185 :     break;
1186 :     }
1187 :     return 0;
1188 :    
1189 :     case WM_DESTROY:
1190 :     RemoveProp(GetParent(hwnd), TEXT("OFN"));
1191 :     return 0;
1192 :     }
1193 :    
1194 :     return 0;
1195 :     }
1196 :    
1197 :     //////////////////////////////////////////////////////////////////////////////
1198 :    
1199 :     BOOL
1200 :     GetFolderSelection(HWND hWnd, LPTSTR szBuf, LPCTSTR szTitle)
1201 :     {
1202 :     LPITEMIDLIST pidl = NULL;
1203 :     BROWSEINFO bi = { 0 };
1204 :     BOOL bResult = FALSE;
1205 :    
1206 :     bi.hwndOwner = hWnd;
1207 :     bi.pszDisplayName = szBuf;
1208 :     bi.pidlRoot = NULL;
1209 :     bi.lpszTitle = szTitle;
1210 :     bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
1211 :    
1212 :     if ((pidl = SHBrowseForFolder(&bi)) != NULL)
1213 :     {
1214 :     bResult = SHGetPathFromIDList(pidl, szBuf);
1215 :     CoTaskMemFree(pidl);
1216 :     }
1217 :    
1218 :     return bResult;
1219 :     }
1220 :    
1221 :     //////////////////////////////////////////////////////////////////////////////
1222 :    
1223 :     LRESULT CALLBACK
1224 :     DIALOG_MAIN(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1225 :     {
1226 :     static HICON hIcon;
1227 :    
1228 :     switch (message)
1229 :     {
1230 :     case WM_INITDIALOG:
1231 :     HWND hwndOwner;
1232 :     RECT rc, rcDlg, rcOwner;
1233 :    
1234 :     if ((hwndOwner = GetParent(hDlg)) == NULL)
1235 :     {
1236 :     hwndOwner = GetDesktopWindow();
1237 :     }
1238 :    
1239 :     GetWindowRect(hwndOwner, &rcOwner);
1240 :     GetWindowRect(hDlg, &rcDlg);
1241 :     CopyRect(&rc, &rcOwner);
1242 :    
1243 :     OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
1244 :     OffsetRect(&rc, -rc.left, -rc.top);
1245 :     OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
1246 :    
1247 :     SetWindowPos(hDlg, HWND_TOP,
1248 :     rcOwner.left + (rc.right / 2),
1249 :     rcOwner.top + (rc.bottom / 2),
1250 :     0, 0, SWP_NOSIZE);
1251 :    
1252 :     hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 32, 32, 0);
1253 :     SendMessage(hDlg, WM_SETICON, ICON_BIG , (LPARAM)hIcon);
1254 :     ghDlg = hDlg;
1255 :     return TRUE;
1256 :    
1257 :     case WM_DESTROY:
1258 :     DestroyIcon(hIcon);
1259 :     PostQuitMessage(0);
1260 :     break;
1261 :    
1262 :     case WM_COMMAND:
1263 :     if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
1264 :     EndDialog(hDlg, LOWORD(wParam));
1265 :     return TRUE;
1266 :     }
1267 :     else if (LOWORD(wParam) == IDC_BUTTON_SRC) {
1268 :     sOfn.hwndOwner = hDlg;
1269 :    
1270 :     GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath));
1271 :    
1272 :     if (wcslen(sOfn.lpstrFile) == 0) {
1273 :     swprintf(sOfn.lpstrFile, 2*MAX_PATH, TEXT("%s"), OpenFilePath);
1274 :     }
1275 :    
1276 :     if (GetOpenFileName(&sOfn)) {
1277 :     if(sOfn.lpstrFile[wcslen(sOfn.lpstrFile) + 1] != TEXT('\0')) // Multiple input files?
1278 :     swprintf(OpenFilePath, 2*MAX_PATH, TEXT("%s (multiselect)"), sOfn.lpstrFile);
1279 :     else
1280 :     swprintf(OpenFilePath, 2*MAX_PATH, TEXT("%s"), sOfn.lpstrFile);
1281 :    
1282 :     SetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath);
1283 :     }
1284 :     }
1285 :     else if (LOWORD(wParam) == IDC_BUTTON_DST) {
1286 :     sSfn.hwndOwner = hDlg;
1287 :     GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0]));
1288 :     if (GetFolderSelection(hDlg, SaveFilePath, TEXT("Please select the output folder"))) {
1289 :     SetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath);
1290 :     }
1291 :     }
1292 :     else if (LOWORD(wParam) == IDC_BUTTON_START) {
1293 :     GetDlgItemText(hDlg, IDC_EDIT_DST, SaveFilePath, sizeof(SaveFilePath)/sizeof(SaveFilePath[0]));
1294 :     GetDlgItemText(hDlg, IDC_EDIT_SRC, OpenFilePath, sizeof(OpenFilePath)/sizeof(OpenFilePath[0]));
1295 :    
1296 :     if ((wcslen(OpenFilePath) > 0 || wcslen(sOfn.lpstrFile) > 0) && wcslen(SaveFilePath) > 0) {
1297 :     EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), 0);
1298 :     if (wcslen(sOfn.lpstrFile) > 0)
1299 :     SrcFile = sOfn.lpstrFile;
1300 :     else {
1301 :     OpenFilePath[wcslen(OpenFilePath)+1] = TEXT('\0');
1302 :     SrcFile = OpenFilePath;
1303 :     }
1304 :    
1305 :     wcscpy(DstFile, SaveFilePath);
1306 :     hConvertThread = CreateThread(0, 0, RecompressThreadProc, GetDlgItem(hDlg, IDC_PROGRESSBAR), 0, 0);
1307 :     }
1308 :     else
1309 :     MessageBox(ghDlg, TEXT("Error: You need to select a source file and output directory first!"), APP_NAME, 0);
1310 :     }
1311 :     break;
1312 :     }
1313 :     return FALSE;
1314 :     }
1315 :    
1316 :    
1317 :     int APIENTRY
1318 :     _tWinMain(HINSTANCE hInstance,
1319 :     HINSTANCE hPrevInstance,
1320 :     LPTSTR lpCmdLine,
1321 :     int nCmdShow)
1322 :     {
1323 :     CoInitialize(0);
1324 :    
1325 :     static TCHAR buf[2*MAX_PATH+1];
1326 :    
1327 :     sOfn.lStructSize = sizeof (OPENFILENAME);
1328 :     sOfn.hInstance = hInstance;
1329 :     #ifdef ALLOW_ONLY_AVI_INPUT
1330 :     sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx)\0*.avi;*.divx\0All files\0*.*\0");
1331 :     #else
1332 :     sOfn.lpstrFilter = TEXT("Media files (*.avi;*.divx;*.mp4;*.mov;*.wmv;*.asf;*.mkv)\0*.avi;*.mp4;*.mov;*.wmv;*.asf;*.divx;*.mkv\0All files\0*.*\0");
1333 :     #endif
1334 :     sOfn.lpstrCustomFilter = 0;
1335 :     sOfn.nMaxCustFilter = 0;
1336 :     sOfn.nFilterIndex = 1;
1337 :     sOfn.lpstrFileTitle = 0;
1338 :     sOfn.nMaxFileTitle = 0;
1339 :     sOfn.lpstrInitialDir = 0;
1340 :     sOfn.lpstrTitle = TEXT("Select source file");
1341 :     sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
1342 :     sOfn.nFileOffset = 0;
1343 :     sOfn.nFileExtension = 0;
1344 :     sOfn.lpstrDefExt = TEXT(".avi");
1345 :     sOfn.lCustData = (LPARAM)(&sOfn);
1346 :     sOfn.lpfnHook = DialogHook;
1347 :     sOfn.lpTemplateName = 0;
1348 :     sOfn.pvReserved = 0;
1349 :     sOfn.dwReserved = 0;
1350 :     sOfn.FlagsEx = 0;
1351 :     sOfn.lpstrFile = buf;
1352 :     sOfn.nMaxFile = 2*MAX_PATH;
1353 :     sOfn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_ENABLEHOOK;
1354 :    
1355 :    
1356 :     sSfn.lStructSize = sizeof (OPENFILENAME);
1357 :     sSfn.hInstance = hInstance;
1358 :     sSfn.lpstrFilter = TEXT("Avi files (*.avi)\0*.avi\0");
1359 :     sSfn.lpstrCustomFilter = 0;
1360 :     sSfn.nMaxCustFilter = 0;
1361 :     sSfn.nFilterIndex = 1;
1362 :     sSfn.lpstrFileTitle = 0;
1363 :     sSfn.nMaxFileTitle = 0;
1364 :     sSfn.lpstrInitialDir = 0;
1365 :     sSfn.lpstrTitle = TEXT("Select target file");
1366 :     sSfn.nFileOffset = 0;
1367 :     sSfn.nFileExtension = 0;
1368 :     sSfn.lpstrDefExt = TEXT(".avi");
1369 :     sSfn.lpTemplateName = 0;
1370 :     sSfn.pvReserved = 0;
1371 :     sSfn.dwReserved = 0;
1372 :     sSfn.FlagsEx = 0;
1373 :    
1374 :     pRec = new RecompressGraph();
1375 :     DialogBox(hInstance, (LPCTSTR)IDD_DIALOG_MAIN, NULL, (DLGPROC)DIALOG_MAIN);
1376 :     pRec->BreakConversion();
1377 :     if (hConvertThread != NULL) {
1378 :     WaitForSingleObject(hConvertThread, INFINITE);
1379 :     CloseHandle(hConvertThread);
1380 :     }
1381 :    
1382 :     delete pRec;
1383 :     CoUninitialize();
1384 :    
1385 :     return 0;
1386 :     }
1387 :    

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4