[svn] / trunk / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2157 - (view) (download)

1 : Isibaar 2113 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Xvid Decoder part of the DShow Filter -
5 :     *
6 :     * Copyright(C) 2002-2011 Peter Ross <pross@xvid.org>
7 :     * 2003-2012 Michael Militzer <michael@xvid.org>
8 :     *
9 :     * This program is free software ; you can redistribute it and/or modify
10 :     * it under the terms of the GNU General Public License as published by
11 :     * the Free Software Foundation ; either version 2 of the License, or
12 :     * (at your option) any later version.
13 :     *
14 :     * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 :     *
19 :     * You should have received a copy of the GNU General Public License
20 :     * along with this program ; if not, write to the Free Software
21 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     *
23 :     * $Id$
24 :     *
25 :     ****************************************************************************/
26 :    
27 :     /*
28 :     this requires the directx sdk
29 :     place these paths at the top of the Tools|Options|Directories list
30 :    
31 :     headers:
32 :     C:\DX90SDK\Include
33 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses
34 :    
35 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Release
36 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug
37 :     */
38 :    
39 :     #ifdef ENABLE_MFT
40 :     #define XVID_USE_MFT
41 :     #endif
42 :    
43 :     #include <windows.h>
44 :    
45 :     #include <streams.h>
46 :     #include <initguid.h>
47 :     #include <olectl.h>
48 :     #if (1100 > _MSC_VER)
49 :     #include <olectlid.h>
50 :     #endif
51 :     #include <dvdmedia.h> // VIDEOINFOHEADER2
52 :    
53 :     #if defined(XVID_USE_MFT)
54 :     #define MFT_UNIQUE_METHOD_NAMES
55 :     #include <mftransform.h>
56 :     #include <mfapi.h>
57 :     #include <mferror.h>
58 :     #include <shlwapi.h>
59 :     #endif
60 :    
61 :     #include <shellapi.h>
62 :    
63 :     #include <xvid.h> // Xvid API
64 :    
65 :     #include "resource.h"
66 :    
67 :     #include "IXvidDecoder.h"
68 :     #include "CXvidDecoder.h"
69 :     #include "CAbout.h"
70 :     #include "config.h"
71 :     #include "debug.h"
72 :    
73 :     static bool USE_IYUV;
74 :     static bool USE_YV12;
75 :     static bool USE_YUY2;
76 :     static bool USE_YVYU;
77 :     static bool USE_UYVY;
78 :     static bool USE_RGB32;
79 :     static bool USE_RGB24;
80 :     static bool USE_RG555;
81 :     static bool USE_RG565;
82 :    
83 :     const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
84 :     {
85 :     { &MEDIATYPE_Video, &CLSID_XVID },
86 :     { &MEDIATYPE_Video, &CLSID_XVID_UC },
87 :     { &MEDIATYPE_Video, &CLSID_DIVX },
88 :     { &MEDIATYPE_Video, &CLSID_DIVX_UC },
89 :     { &MEDIATYPE_Video, &CLSID_DX50 },
90 :     { &MEDIATYPE_Video, &CLSID_DX50_UC },
91 :     { &MEDIATYPE_Video, &CLSID_3IVX },
92 :     { &MEDIATYPE_Video, &CLSID_3IVX_UC },
93 :     { &MEDIATYPE_Video, &CLSID_3IV0 },
94 :     { &MEDIATYPE_Video, &CLSID_3IV0_UC },
95 :     { &MEDIATYPE_Video, &CLSID_3IV1 },
96 :     { &MEDIATYPE_Video, &CLSID_3IV1_UC },
97 :     { &MEDIATYPE_Video, &CLSID_3IV2 },
98 :     { &MEDIATYPE_Video, &CLSID_3IV2_UC },
99 :     { &MEDIATYPE_Video, &CLSID_LMP4 },
100 :     { &MEDIATYPE_Video, &CLSID_LMP4_UC },
101 :     { &MEDIATYPE_Video, &CLSID_RMP4 },
102 :     { &MEDIATYPE_Video, &CLSID_RMP4_UC },
103 :     { &MEDIATYPE_Video, &CLSID_SMP4 },
104 :     { &MEDIATYPE_Video, &CLSID_SMP4_UC },
105 :     { &MEDIATYPE_Video, &CLSID_HDX4 },
106 :     { &MEDIATYPE_Video, &CLSID_HDX4_UC },
107 :     { &MEDIATYPE_Video, &CLSID_MP4V },
108 :     { &MEDIATYPE_Video, &CLSID_MP4V_UC },
109 :     };
110 :    
111 :     const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
112 :     {
113 :     { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
114 :     };
115 :    
116 :    
117 :     const AMOVIESETUP_PIN psudPins[] =
118 :     {
119 :     {
120 :     L"Input", // String pin name
121 :     FALSE, // Is it rendered
122 :     FALSE, // Is it an output
123 :     FALSE, // Allowed none
124 :     FALSE, // Allowed many
125 :     &CLSID_NULL, // Connects to filter
126 :     L"Output", // Connects to pin
127 :     sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
128 :     &sudInputPinTypes[0] // The pin details
129 :     },
130 :     {
131 :     L"Output", // String pin name
132 :     FALSE, // Is it rendered
133 :     TRUE, // Is it an output
134 :     FALSE, // Allowed none
135 :     FALSE, // Allowed many
136 :     &CLSID_NULL, // Connects to filter
137 :     L"Input", // Connects to pin
138 :     sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
139 :     sudOutputPinTypes // The pin details
140 :     }
141 :     };
142 :    
143 :    
144 :     const AMOVIESETUP_FILTER sudXvidDecoder =
145 :     {
146 :     &CLSID_XVID, // Filter CLSID
147 :     XVID_NAME_L, // Filter name
148 :     MERIT_PREFERRED+2, // Its merit
149 :     sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins
150 :     psudPins // Pin details
151 :     };
152 :    
153 :    
154 :     // List of class IDs and creator functions for the class factory. This
155 :     // provides the link between the OLE entry point in the DLL and an object
156 :     // being created. The class factory will call the static CreateInstance
157 :    
158 :     CFactoryTemplate g_Templates[] =
159 :     {
160 :     {
161 :     XVID_NAME_L,
162 :     &CLSID_XVID,
163 :     CXvidDecoder::CreateInstance,
164 :     NULL,
165 :     &sudXvidDecoder
166 :     },
167 :     {
168 :     XVID_NAME_L L"About",
169 :     &CLSID_CABOUT,
170 :     CAbout::CreateInstance
171 :     }
172 :    
173 :     };
174 :    
175 :     /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */
176 :     int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);
177 :    
178 :     extern HINSTANCE g_xvid_hInst;
179 :    
180 :     static int GUI_Page = 0;
181 :     static HWND MSG_hwnd = NULL; /* message handler window */
182 :    
183 :     extern "C" void CALLBACK Configure(HWND hWndParent, HINSTANCE hInstParent, LPSTR lpCmdLine, int nCmdShow );
184 :    
185 :     LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
186 :     {
187 :     switch ( uMsg )
188 :     {
189 :     case WM_ICONMESSAGE:
190 :     switch(lParam)
191 :     {
192 :     case WM_LBUTTONUP:
193 :     case WM_LBUTTONDBLCLK:
194 :     if (!GUI_Page) {
195 :     GUI_Page = 1;
196 :     Configure(hwnd, g_xvid_hInst, "", 1);
197 :     GUI_Page = 0;
198 :     }
199 :     break;
200 :     default:
201 :     return DefWindowProc(hwnd, uMsg, wParam, lParam);
202 :     };
203 :     break;
204 :    
205 :     case WM_DESTROY:
206 :     NOTIFYICONDATA nid;
207 :     ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
208 :    
209 :     nid.cbSize = sizeof(NOTIFYICONDATA);
210 :     nid.hWnd = hwnd;
211 :     nid.uID = 1456;
212 :     Shell_NotifyIcon(NIM_DELETE, &nid);
213 :     default:
214 :     return DefWindowProc(hwnd, uMsg, wParam, lParam);
215 :     }
216 :    
217 :     return TRUE; /* ok */
218 :     }
219 :    
220 :     STDAPI DllRegisterServer()
221 :     {
222 :     #if defined(XVID_USE_MFT)
223 :     int inputs_num = sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE);
224 :     int outputs_num = sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE);
225 :     MFT_REGISTER_TYPE_INFO * mft_bs = new MFT_REGISTER_TYPE_INFO[inputs_num];
226 :     MFT_REGISTER_TYPE_INFO * mft_csp = new MFT_REGISTER_TYPE_INFO[outputs_num];
227 :    
228 :     {
229 :     int i;
230 :     for(i=0;i<inputs_num;i++) {
231 :     mft_bs[i].guidMajorType = *sudInputPinTypes[i].clsMajorType;
232 :     mft_bs[i].guidSubtype = *sudInputPinTypes[i].clsMinorType;
233 :     }
234 :     for(i=0;i<outputs_num;i++) {
235 :     mft_csp[i].guidMajorType = *sudOutputPinTypes[i].clsMajorType;
236 :     mft_csp[i].guidSubtype = *sudOutputPinTypes[i].clsMinorType; // MFT and AM GUIDs really the same?
237 :     }
238 :     }
239 :    
240 :     /* Register the MFT decoder */
241 :     MFTRegister(CLSID_XVID, // CLSID
242 :     MFT_CATEGORY_VIDEO_DECODER, // Category
243 :     const_cast<LPWSTR>(XVID_NAME_MFT_L), // Friendly name
244 :     0, // Flags
245 :     inputs_num, // Number of input types
246 :     mft_bs, // Input types
247 :     outputs_num, // Number of output types
248 :     mft_csp, // Output types
249 :     NULL // Attributes (optional)
250 :     );
251 :    
252 :     delete[] mft_bs;
253 :     delete[] mft_csp;
254 :     #endif /* XVID_USE_MFT */
255 :    
256 :     return AMovieDllRegisterServer2( TRUE );
257 :     }
258 :    
259 :    
260 :     STDAPI DllUnregisterServer()
261 :     {
262 :     #if defined(XVID_USE_MFT)
263 :     MFTUnregister(CLSID_XVID);
264 :     #endif
265 :     return AMovieDllRegisterServer2( FALSE );
266 :     }
267 :    
268 :    
269 :     /* create instance */
270 :    
271 :     CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
272 :     {
273 :     CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr);
274 :     if (pNewObject == NULL)
275 :     {
276 :     *phr = E_OUTOFMEMORY;
277 :     }
278 :     return pNewObject;
279 :     }
280 :    
281 :    
282 :     /* query interfaces */
283 :    
284 :     STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
285 :     {
286 :     CheckPointer(ppv, E_POINTER);
287 :    
288 :     if (riid == IID_IXvidDecoder)
289 :     {
290 :     return GetInterface((IXvidDecoder *) this, ppv);
291 :     }
292 :    
293 :     if (riid == IID_ISpecifyPropertyPages)
294 :     {
295 :     return GetInterface((ISpecifyPropertyPages *) this, ppv);
296 :     }
297 :    
298 :     #if defined(XVID_USE_MFT)
299 :     if (riid == IID_IMFTransform)
300 :     {
301 :     return GetInterface((IMFTransform *) this, ppv);
302 :     }
303 :     #endif
304 :    
305 :     return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv);
306 :     }
307 :    
308 :    
309 :    
310 :     /* constructor */
311 :    
312 :     CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
313 :     CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL)
314 :     {
315 :     DPRINTF("Constructor");
316 :    
317 :     xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize...
318 :     xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here.
319 :    
320 :     m_tray_icon = 0;
321 :     m_startClock = clock();
322 : Isibaar 2133 interlaced = 0;
323 : Isibaar 2113
324 :     #if defined(XVID_USE_MFT)
325 :     InitializeCriticalSection(&m_mft_lock);
326 :     m_pInputType = NULL;
327 :     m_pOutputType = NULL;
328 :     m_pOutputTypeBPP = 32;
329 :     m_rtFrame = 0;
330 :     m_duration = 0;
331 :     m_discont = 0;
332 :     m_frameRate.Denominator = 1;
333 :     m_frameRate.Numerator = 1;
334 :     m_thread_handle = NULL;
335 :     #endif
336 :    
337 :     LoadRegistryInfo();
338 :    
339 :     *phr = OpenLib();
340 :    
341 :     {
342 :     TCHAR lpFilename[MAX_PATH];
343 :     int sLen = GetModuleFileName(NULL, lpFilename, MAX_PATH);
344 :     #ifdef _UNICODE
345 :     if ((sLen >= 11) && (_wcsnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
346 : Isibaar 2024 #else
347 : Isibaar 2113 if ((sLen >= 11) && (_strnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
348 : Isibaar 2024 #endif
349 : Isibaar 2113 if (m_tray_icon == 0) m_tray_icon = -1; // create no tray icon upon thumbnail generation
350 :     }
351 :     }
352 :    
353 :     }
354 :    
355 :     HRESULT CXvidDecoder::OpenLib()
356 :     {
357 :     DPRINTF("OpenLib");
358 :    
359 :     if (m_hdll != NULL)
360 :     return E_UNEXPECTED; // Seems, that library already opened.
361 :    
362 :     xvid_gbl_init_t init;
363 :     memset(&init, 0, sizeof(init));
364 :     init.version = XVID_VERSION;
365 :     init.cpu_flags = g_config.cpu;
366 :    
367 :     xvid_gbl_info_t info;
368 :     memset(&info, 0, sizeof(info));
369 :     info.version = XVID_VERSION;
370 :    
371 :     m_hdll = LoadLibrary(XVID_DLL_NAME);
372 :     if (m_hdll == NULL) {
373 :     DPRINTF("dll load failed");
374 :     MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST);
375 :     return E_FAIL;
376 :     }
377 :    
378 :     xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
379 :     if (xvid_global_func == NULL) {
380 :     FreeLibrary(m_hdll);
381 :     m_hdll = NULL;
382 :     MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST);
383 :     return E_FAIL;
384 :     }
385 :    
386 :     xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
387 :     if (xvid_decore_func == NULL) {
388 :     xvid_global_func = NULL;
389 :     FreeLibrary(m_hdll);
390 :     m_hdll = NULL;
391 :     MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST);
392 :     return E_FAIL;
393 :     }
394 :    
395 :     if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0)
396 :     {
397 :     xvid_global_func = NULL;
398 :     xvid_decore_func = NULL;
399 :     FreeLibrary(m_hdll);
400 :     m_hdll = NULL;
401 :     MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
402 :     return E_FAIL;
403 :     }
404 :    
405 :     if (xvid_global_func(0, XVID_GBL_INFO, &info, NULL) < 0)
406 :     {
407 :     xvid_global_func = NULL;
408 :     xvid_decore_func = NULL;
409 :     FreeLibrary(m_hdll);
410 :     m_hdll = NULL;
411 :     MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
412 :     return E_FAIL;
413 :     }
414 :    
415 :     memset(&m_create, 0, sizeof(m_create));
416 :     m_create.version = XVID_VERSION;
417 :     m_create.handle = NULL;
418 :     /* Decoder threads */
419 :     if (g_config.cpu & XVID_CPU_FORCE) {
420 :     m_create.num_threads = g_config.num_threads;
421 :     }
422 :     else {
423 :     m_create.num_threads = info.num_threads; /* Autodetect */
424 :     g_config.num_threads = info.num_threads;
425 :     }
426 :    
427 :     memset(&m_frame, 0, sizeof(m_frame));
428 :     m_frame.version = XVID_VERSION;
429 :    
430 :     USE_IYUV = false;
431 :     USE_YV12 = false;
432 :     USE_YUY2 = false;
433 :     USE_YVYU = false;
434 :     USE_UYVY = false;
435 :     USE_RGB32 = false;
436 :     USE_RGB24 = false;
437 :     USE_RG555 = false;
438 :     USE_RG565 = false;
439 :    
440 :     switch ( g_config.nForceColorspace )
441 :     {
442 :     case FORCE_NONE:
443 :     USE_IYUV = true;
444 :     USE_YV12 = true;
445 :     USE_YUY2 = true;
446 :     USE_YVYU = true;
447 :     USE_UYVY = true;
448 :     USE_RGB32 = true;
449 :     USE_RGB24 = true;
450 :     USE_RG555 = true;
451 :     USE_RG565 = true;
452 :     break;
453 :     case FORCE_YV12:
454 :     USE_IYUV = true;
455 :     USE_YV12 = true;
456 :     break;
457 :     case FORCE_YUY2:
458 :     USE_YUY2 = true;
459 :     break;
460 :     case FORCE_RGB24:
461 :     USE_RGB24 = true;
462 :     break;
463 :     case FORCE_RGB32:
464 :     USE_RGB32 = true;
465 :     break;
466 :     }
467 :    
468 :     switch (g_config.aspect_ratio)
469 :     {
470 :     case 0:
471 :     case 1:
472 :     break;
473 :     case 2:
474 :     ar_x = 4;
475 :     ar_y = 3;
476 :     break;
477 :     case 3:
478 :     ar_x = 16;
479 :     ar_y = 9;
480 :     break;
481 :     case 4:
482 :     ar_x = 47;
483 :     ar_y = 20;
484 :     break;
485 :     }
486 :    
487 :     return S_OK;
488 :     }
489 :    
490 :     void CXvidDecoder::CloseLib()
491 :     {
492 :     DPRINTF("CloseLib");
493 :    
494 :     if ((m_create.handle != NULL) && (xvid_decore_func != NULL))
495 :     {
496 :     xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
497 :     m_create.handle = NULL;
498 :     }
499 :    
500 :     if (m_hdll != NULL) {
501 :     FreeLibrary(m_hdll);
502 :     m_hdll = NULL;
503 :     }
504 :     xvid_decore_func = NULL;
505 :     xvid_global_func = NULL;
506 :     }
507 :    
508 :     /* destructor */
509 :    
510 :     CXvidDecoder::~CXvidDecoder()
511 :     {
512 :     DPRINTF("Destructor");
513 :    
514 :     if ((MSG_hwnd != NULL) && (m_tray_icon == 1)) { /* Destroy tray icon */
515 :     SendMessage(MSG_hwnd, WM_CLOSE, 0, 0);
516 :     }
517 :    
518 :     /* Close xvidcore library */
519 :     CloseLib();
520 :    
521 :     clock_t endClock = clock();
522 :     if (((endClock - m_startClock) / CLOCKS_PER_SEC) > 3) {
523 :     SaveRegistryInfo((endClock - m_startClock) / (CLOCKS_PER_SEC / 10));
524 :     }
525 :    
526 :     if ((MSG_hwnd != 0) && (m_tray_icon == 1)) { /* Final clean-up */
527 :     MSG_hwnd = 0;
528 :     Sleep(200);
529 :     m_tray_icon = 0;
530 :     #if defined(XVID_USE_MFT)
531 :     if (m_thread_handle) {
532 :     TerminateThread(m_thread_handle, 0);
533 :     CloseHandle(m_thread_handle);
534 :     m_thread_handle = NULL;
535 :     }
536 :     #endif
537 :     }
538 :    
539 :     #if defined(XVID_USE_MFT)
540 :     DeleteCriticalSection(&m_mft_lock);
541 :     #endif
542 :     }
543 :    
544 :    
545 :    
546 :     /* check input type */
547 :    
548 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
549 :     {
550 :     DPRINTF("CheckInputType");
551 :     BITMAPINFOHEADER * hdr;
552 :    
553 :     ar_x = ar_y = 0;
554 :    
555 :     if (*mtIn->Type() != MEDIATYPE_Video)
556 :     {
557 :     DPRINTF("Error: Unknown Type");
558 :     CloseLib();
559 :     return VFW_E_TYPE_NOT_ACCEPTED;
560 :     }
561 :    
562 :     if (m_hdll == NULL)
563 :     {
564 :     HRESULT hr = OpenLib();
565 :    
566 :     if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks.
567 :     return VFW_E_TYPE_NOT_ACCEPTED;
568 :     }
569 :    
570 :     if (*mtIn->FormatType() == FORMAT_VideoInfo)
571 :     {
572 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
573 :     hdr = &vih->bmiHeader;
574 :     }
575 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
576 :     {
577 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
578 :     hdr = &vih2->bmiHeader;
579 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
580 :     ar_x = vih2->dwPictAspectRatioX;
581 :     ar_y = vih2->dwPictAspectRatioY;
582 :     }
583 :     DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
584 :     }
585 :     else if (*mtIn->FormatType() == FORMAT_MPEG2Video) {
586 :     MPEG2VIDEOINFO * mpgvi = (MPEG2VIDEOINFO*)mtIn->Format();
587 :     VIDEOINFOHEADER2 * vih2 = &mpgvi->hdr;
588 :     hdr = &vih2->bmiHeader;
589 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
590 :     ar_x = vih2->dwPictAspectRatioX;
591 :     ar_y = vih2->dwPictAspectRatioY;
592 :     }
593 :     DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
594 :    
595 :     /* haali media splitter reports VOL information in the format header */
596 :    
597 :     if (mpgvi->cbSequenceHeader>0) {
598 :    
599 :     xvid_dec_stats_t stats;
600 :     memset(&stats, 0, sizeof(stats));
601 :     stats.version = XVID_VERSION;
602 :    
603 :     if (m_create.handle == NULL) {
604 :     if (xvid_decore_func == NULL)
605 :     return E_FAIL;
606 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) {
607 :     DPRINTF("*** XVID_DEC_CREATE error");
608 :     return E_FAIL;
609 :     }
610 :     }
611 :    
612 :     m_frame.general = 0;
613 :     m_frame.bitstream = (void*)mpgvi->dwSequenceHeader;
614 :     m_frame.length = mpgvi->cbSequenceHeader;
615 :     m_frame.output.csp = XVID_CSP_NULL;
616 :    
617 :     int ret = 0;
618 :     if ((ret=xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats)) >= 0) {
619 :     /* honour video dimensions reported in VOL header */
620 :     if (stats.type == XVID_TYPE_VOL) {
621 :     hdr->biWidth = stats.data.vol.width;
622 :     hdr->biHeight = stats.data.vol.height;
623 :     }
624 :     }
625 :     if (ret == XVID_ERR_MEMORY) return E_FAIL;
626 :     }
627 :     }
628 :     else
629 :     {
630 :     DPRINTF("Error: Unknown FormatType");
631 :     CloseLib();
632 :     return VFW_E_TYPE_NOT_ACCEPTED;
633 :     }
634 :     if (hdr->biHeight < 0)
635 :     {
636 :     DPRINTF("colorspace: inverted input format not supported");
637 :     }
638 :    
639 :     m_create.width = hdr->biWidth;
640 :     m_create.height = hdr->biHeight;
641 :    
642 :     switch(hdr->biCompression)
643 :     {
644 :     case FOURCC_mp4v :
645 :     case FOURCC_MP4V :
646 :     case FOURCC_lmp4 :
647 :     case FOURCC_LMP4 :
648 :     case FOURCC_rmp4 :
649 :     case FOURCC_RMP4 :
650 :     case FOURCC_smp4 :
651 :     case FOURCC_SMP4 :
652 :     case FOURCC_hdx4 :
653 :     case FOURCC_HDX4 :
654 :     if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
655 :     CloseLib();
656 :     return VFW_E_TYPE_NOT_ACCEPTED;
657 :     }
658 :     break;
659 :     case FOURCC_divx :
660 :     case FOURCC_DIVX :
661 :     case FOURCC_dx50 :
662 :     case FOURCC_DX50 :
663 :     if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
664 :     CloseLib();
665 :     return VFW_E_TYPE_NOT_ACCEPTED;
666 :     }
667 :     break;
668 :     case FOURCC_3ivx :
669 :     case FOURCC_3IVX :
670 :     case FOURCC_3iv0 :
671 :     case FOURCC_3IV0 :
672 :     case FOURCC_3iv1 :
673 :     case FOURCC_3IV1 :
674 :     case FOURCC_3iv2 :
675 :     case FOURCC_3IV2 :
676 :     if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
677 :     CloseLib();
678 :     return VFW_E_TYPE_NOT_ACCEPTED;
679 :     }
680 :     case FOURCC_xvid :
681 :     case FOURCC_XVID :
682 :     break;
683 :    
684 :    
685 :     default :
686 :     DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
687 :     hdr->biCompression,
688 :     (hdr->biCompression)&0xff,
689 :     (hdr->biCompression>>8)&0xff,
690 :     (hdr->biCompression>>16)&0xff,
691 :     (hdr->biCompression>>24)&0xff);
692 :     CloseLib();
693 :     return VFW_E_TYPE_NOT_ACCEPTED;
694 :     }
695 :    
696 :     m_create.fourcc = hdr->biCompression;
697 :    
698 :     return S_OK;
699 :     }
700 :    
701 :    
702 :     /* get list of supported output colorspaces */
703 :    
704 :    
705 :     HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
706 :     {
707 :     BITMAPINFOHEADER * bmih;
708 :     DPRINTF("GetMediaType");
709 :    
710 :     if (m_pInput->IsConnected() == FALSE)
711 :     {
712 :     return E_UNEXPECTED;
713 :     }
714 :    
715 :     if (!g_config.videoinfo_compat) {
716 :     VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
717 :     if (vih == NULL) return E_OUTOFMEMORY;
718 :    
719 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER2));
720 :     bmih = &(vih->bmiHeader);
721 :     mtOut->SetFormatType(&FORMAT_VideoInfo2);
722 :    
723 :     if (ar_x != 0 && ar_y != 0) {
724 :     vih->dwPictAspectRatioX = ar_x;
725 :     vih->dwPictAspectRatioY = ar_y;
726 :     forced_ar = true;
727 :     } else { // just to be safe
728 :     vih->dwPictAspectRatioX = m_create.width;
729 :     vih->dwPictAspectRatioY = abs(m_create.height);
730 :     forced_ar = false;
731 :     }
732 : Isibaar 2133 if (interlaced) {
733 :     vih->dwInterlaceFlags = AMINTERLACE_IsInterlaced;
734 :     if (interlaced > 1) {
735 :     vih->dwInterlaceFlags |= AMINTERLACE_Field1First;
736 :     }
737 :     }
738 :     else {
739 :     vih->dwInterlaceFlags = 0;
740 :     }
741 : Isibaar 2113 } else {
742 :    
743 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
744 :     if (vih == NULL) return E_OUTOFMEMORY;
745 :    
746 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
747 :     bmih = &(vih->bmiHeader);
748 :     mtOut->SetFormatType(&FORMAT_VideoInfo);
749 :     }
750 :    
751 :     bmih->biSize = sizeof(BITMAPINFOHEADER);
752 :     bmih->biWidth = m_create.width;
753 :     bmih->biHeight = m_create.height;
754 :     bmih->biPlanes = 1;
755 :    
756 :     if (iPosition < 0) return E_INVALIDARG;
757 :    
758 :     switch(iPosition)
759 :     {
760 :    
761 :     case 0:
762 :     if ( USE_YUY2 )
763 :     {
764 :     bmih->biCompression = MEDIASUBTYPE_YUY2.Data1;
765 :     bmih->biBitCount = 16;
766 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
767 :     break;
768 :     }
769 :     case 1 :
770 :     if ( USE_YVYU )
771 :     {
772 :     bmih->biCompression = MEDIASUBTYPE_YVYU.Data1;
773 :     bmih->biBitCount = 16;
774 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
775 :     break;
776 :     }
777 :     case 2 :
778 :     if ( USE_UYVY )
779 :     {
780 :     bmih->biCompression = MEDIASUBTYPE_UYVY.Data1;
781 :     bmih->biBitCount = 16;
782 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
783 :     break;
784 :     }
785 :     case 3 :
786 :     if ( USE_IYUV )
787 :     {
788 :     bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
789 :     bmih->biBitCount = 12;
790 :     mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
791 :     break;
792 :     }
793 :     case 4 :
794 :     if ( USE_YV12 )
795 :     {
796 :     bmih->biCompression = MEDIASUBTYPE_YV12.Data1;
797 :     bmih->biBitCount = 12;
798 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
799 :     break;
800 :     }
801 :     case 5 :
802 :     if ( USE_RGB32 )
803 :     {
804 :     bmih->biCompression = BI_RGB;
805 :     bmih->biBitCount = 32;
806 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
807 :     break;
808 :     }
809 :     case 6 :
810 :     if ( USE_RGB24 )
811 :     {
812 :     bmih->biCompression = BI_RGB;
813 :     bmih->biBitCount = 24;
814 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
815 :     break;
816 :     }
817 :     case 7 :
818 :     if ( USE_RG555 )
819 :     {
820 :     bmih->biCompression = BI_RGB;
821 :     bmih->biBitCount = 16;
822 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
823 :     break;
824 :     }
825 :     case 8 :
826 :     if ( USE_RG565 )
827 :     {
828 :     bmih->biCompression = BI_RGB;
829 :     bmih->biBitCount = 16;
830 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
831 :     break;
832 :     }
833 :     default :
834 :     return VFW_S_NO_MORE_ITEMS;
835 :     }
836 :    
837 :     bmih->biSizeImage = GetBitmapSize(bmih);
838 :    
839 :     mtOut->SetType(&MEDIATYPE_Video);
840 :     mtOut->SetTemporalCompression(FALSE);
841 :     mtOut->SetSampleSize(bmih->biSizeImage);
842 :    
843 :     return S_OK;
844 :     }
845 :    
846 :    
847 :     /* (internal function) change colorspace */
848 :     #define CALC_BI_STRIDE(width, bitcount) ((((width * bitcount) + 31) & ~31) >> 3)
849 :    
850 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void *format, int *bitdepth, int noflip)
851 :     {
852 :     DWORD biWidth;
853 :     *bitdepth = 32;
854 :    
855 :     if (formattype == FORMAT_VideoInfo)
856 :     {
857 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
858 :     biWidth = vih->bmiHeader.biWidth;
859 :     *bitdepth = vih->bmiHeader.biBitCount;
860 :     out_stride = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);
861 :     rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
862 :     }
863 :     else if (formattype == FORMAT_VideoInfo2)
864 :     {
865 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
866 :     biWidth = vih2->bmiHeader.biWidth;
867 :     *bitdepth = vih2->bmiHeader.biBitCount;
868 :     out_stride = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);
869 :     rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
870 :     }
871 :     else
872 :     {
873 :     return S_FALSE;
874 :     }
875 :    
876 :     if (noflip) rgb_flip = 0;
877 :    
878 :     if (subtype == CLSID_MEDIASUBTYPE_IYUV)
879 :     {
880 :     DPRINTF("IYUV");
881 :     rgb_flip = 0;
882 :     m_frame.output.csp = XVID_CSP_I420;
883 :     out_stride = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
884 :     }
885 :     else if (subtype == MEDIASUBTYPE_YV12)
886 :     {
887 :     DPRINTF("YV12");
888 :     rgb_flip = 0;
889 :     m_frame.output.csp = XVID_CSP_YV12;
890 :     out_stride = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
891 :     }
892 :     else if (subtype == MEDIASUBTYPE_YUY2)
893 :     {
894 :     DPRINTF("YUY2");
895 :     rgb_flip = 0;
896 :     m_frame.output.csp = XVID_CSP_YUY2;
897 :     }
898 :     else if (subtype == MEDIASUBTYPE_YVYU)
899 :     {
900 :     DPRINTF("YVYU");
901 :     rgb_flip = 0;
902 :     m_frame.output.csp = XVID_CSP_YVYU;
903 :     }
904 :     else if (subtype == MEDIASUBTYPE_UYVY)
905 :     {
906 :     DPRINTF("UYVY");
907 :     rgb_flip = 0;
908 :     m_frame.output.csp = XVID_CSP_UYVY;
909 :     }
910 :     else if (subtype == MEDIASUBTYPE_RGB32)
911 :     {
912 :     DPRINTF("RGB32");
913 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
914 :     }
915 :     else if (subtype == MEDIASUBTYPE_RGB24)
916 :     {
917 :     DPRINTF("RGB24");
918 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
919 :     }
920 :     else if (subtype == MEDIASUBTYPE_RGB555)
921 :     {
922 :     DPRINTF("RGB555");
923 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
924 :     }
925 :     else if (subtype == MEDIASUBTYPE_RGB565)
926 :     {
927 :     DPRINTF("RGB565");
928 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
929 :     }
930 :     else if (subtype == GUID_NULL)
931 :     {
932 :     m_frame.output.csp = XVID_CSP_NULL;
933 :     }
934 :     else
935 :     {
936 :     return S_FALSE;
937 :     }
938 :    
939 :     return S_OK;
940 :     }
941 :    
942 :    
943 :     /* set output colorspace */
944 :    
945 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
946 :     {
947 :     int bitdepth;
948 :     DPRINTF("SetMediaType");
949 :    
950 :     if (direction == PINDIR_OUTPUT)
951 :     {
952 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format(), &bitdepth, 0);
953 :     }
954 :    
955 :     return S_OK;
956 :     }
957 :    
958 :    
959 :     /* check input<->output compatiblity */
960 :    
961 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
962 :     {
963 :     DPRINTF("CheckTransform");
964 :    
965 :     return S_OK;
966 :     }
967 :    
968 :     /* input/output pin connection complete */
969 :    
970 :     HRESULT CXvidDecoder::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
971 :     {
972 :     DPRINTF("CompleteConnect");
973 :    
974 :     if ((direction == PINDIR_OUTPUT) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
975 :     {
976 :     WNDCLASSEX wc;
977 :    
978 :     wc.cbSize = sizeof(WNDCLASSEX);
979 :     wc.lpfnWndProc = msg_proc;
980 :     wc.style = CS_HREDRAW | CS_VREDRAW;
981 :     wc.cbWndExtra = 0;
982 :     wc.cbClsExtra = 0;
983 :     wc.hInstance = (HINSTANCE) g_xvid_hInst;
984 :     wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH);
985 :     wc.lpszMenuName = NULL;
986 :     wc.lpszClassName = "XVID_MSG_WINDOW";
987 :     wc.hIcon = NULL;
988 :     wc.hIconSm = NULL;
989 :     wc.hCursor = NULL;
990 :     RegisterClassEx(&wc);
991 :    
992 :     MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,
993 :     CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE) g_xvid_hInst, NULL);
994 :    
995 :     /* display the tray icon */
996 :     NOTIFYICONDATA nid;
997 :     ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
998 :    
999 :     nid.cbSize = sizeof(NOTIFYICONDATA);
1000 :     nid.hWnd = MSG_hwnd;
1001 :     nid.uID = 1456;
1002 :     nid.uVersion = NOTIFYICON_VERSION;
1003 :     nid.uCallbackMessage = WM_ICONMESSAGE;
1004 :     nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
1005 :     strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
1006 :     nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
1007 :    
1008 :     Shell_NotifyIcon(NIM_ADD, &nid);
1009 :     Shell_NotifyIcon(NIM_SETVERSION, &nid);
1010 :    
1011 :     DestroyIcon(nid.hIcon);
1012 :     m_tray_icon = 1;
1013 :     }
1014 :    
1015 :     return S_OK;
1016 :     }
1017 :    
1018 :     /* input/output pin disconnected */
1019 :     HRESULT CXvidDecoder::BreakConnect(PIN_DIRECTION direction)
1020 :     {
1021 :     DPRINTF("BreakConnect");
1022 :    
1023 :     return S_OK;
1024 :     }
1025 :    
1026 :     /* alloc output buffer */
1027 :    
1028 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
1029 :     {
1030 :     DPRINTF("DecideBufferSize");
1031 :     HRESULT result;
1032 :     ALLOCATOR_PROPERTIES ppropActual;
1033 :    
1034 :     if (m_pInput->IsConnected() == FALSE)
1035 :     {
1036 :     return E_UNEXPECTED;
1037 :     }
1038 :    
1039 :     ppropInputRequest->cBuffers = 1;
1040 :     ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
1041 :     // cbAlign causes problems with the resize filter */
1042 :     // ppropInputRequest->cbAlign = 16;
1043 :     ppropInputRequest->cbPrefix = 0;
1044 :    
1045 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
1046 :     if (result != S_OK)
1047 :     {
1048 :     return result;
1049 :     }
1050 :    
1051 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
1052 :     {
1053 :     return E_FAIL;
1054 :     }
1055 :    
1056 :     return S_OK;
1057 :     }
1058 :    
1059 :    
1060 :     /* decode frame */
1061 :    
1062 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
1063 :     {
1064 :     DPRINTF("Transform");
1065 :     xvid_dec_stats_t stats;
1066 :     int length;
1067 :    
1068 :     memset(&stats, 0, sizeof(stats));
1069 :     stats.version = XVID_VERSION;
1070 :    
1071 :     if (m_create.handle == NULL)
1072 :     {
1073 :     if (xvid_decore_func == NULL)
1074 :     return E_FAIL;
1075 :    
1076 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
1077 :     {
1078 :     DPRINTF("*** XVID_DEC_CREATE error");
1079 :     return E_FAIL;
1080 :     }
1081 :     }
1082 :    
1083 :     AM_MEDIA_TYPE * mtOut;
1084 :     pOut->GetMediaType(&mtOut);
1085 :     if (mtOut != NULL)
1086 :     {
1087 :     int bitdepth;
1088 :     HRESULT result;
1089 :    
1090 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat, &bitdepth, 0);
1091 :     DeleteMediaType(mtOut);
1092 :    
1093 :     if (result != S_OK)
1094 :     {
1095 :     DPRINTF("*** ChangeColorspace error");
1096 :     return result;
1097 :     }
1098 :     }
1099 :    
1100 :     m_frame.length = pIn->GetActualDataLength();
1101 :     if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
1102 :     {
1103 :     return S_FALSE;
1104 :     }
1105 :    
1106 :     if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
1107 :     {
1108 :     return S_FALSE;
1109 :     }
1110 :    
1111 :     m_frame.general = XVID_LOWDELAY;
1112 :    
1113 :     if (pIn->IsDiscontinuity() == S_OK)
1114 :     m_frame.general |= XVID_DISCONTINUITY;
1115 :    
1116 :     if (g_config.nDeblock_Y)
1117 :     m_frame.general |= XVID_DEBLOCKY;
1118 :    
1119 :     if (g_config.nDeblock_UV)
1120 :     m_frame.general |= XVID_DEBLOCKUV;
1121 :    
1122 :     if (g_config.nDering_Y)
1123 :     m_frame.general |= XVID_DERINGY;
1124 :    
1125 :     if (g_config.nDering_UV)
1126 :     m_frame.general |= XVID_DERINGUV;
1127 :    
1128 :     if (g_config.nFilmEffect)
1129 :     m_frame.general |= XVID_FILMEFFECT;
1130 :    
1131 :     m_frame.brightness = g_config.nBrightness;
1132 :    
1133 :     m_frame.output.csp &= ~XVID_CSP_VFLIP;
1134 :     m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
1135 :     m_frame.output.stride[0] = out_stride;
1136 :    
1137 :     // Paranoid check.
1138 :     if (xvid_decore_func == NULL)
1139 :     return E_FAIL;
1140 :    
1141 :    
1142 :     repeat :
1143 :    
1144 :     if (pIn->IsPreroll() != S_OK)
1145 :     {
1146 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
1147 :    
1148 :     if (length == XVID_ERR_MEMORY)
1149 :     return E_FAIL;
1150 :     else if (length < 0)
1151 :     {
1152 :     DPRINTF("*** XVID_DEC_DECODE");
1153 :     return S_FALSE;
1154 : Isibaar 2134 } else if ((g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) || !!(interlaced)) {
1155 : Isibaar 2113
1156 : Isibaar 2134 if (stats.type != XVID_TYPE_NOTHING) { /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */
1157 :     // inspired by minolta! works for VMR 7 + 9
1158 :     IMediaSample2 *pOut2 = NULL;
1159 :     AM_SAMPLE2_PROPERTIES outProp2;
1160 :     if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) &&
1161 :     SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2)))
1162 :     {
1163 :     CMediaType mtOut2 = m_pOutput->CurrentMediaType();
1164 :     VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();
1165 : Isibaar 2113
1166 : Isibaar 2134 if (*mtOut2.FormatType() == FORMAT_VideoInfo2)
1167 :     {
1168 :     int need_format_change = 0;
1169 :    
1170 :     if (vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)
1171 :     {
1172 :     vihOut2->dwPictAspectRatioX = ar_x;
1173 :     vihOut2->dwPictAspectRatioY = ar_y;
1174 :     int format_change;
1175 : Isibaar 2133 }
1176 : Isibaar 2134
1177 :     if ((interlaced) && !(vihOut2->dwInterlaceFlags & AMINTERLACE_IsInterlaced))
1178 :     {
1179 :     vihOut2->dwInterlaceFlags = AMINTERLACE_IsInterlaced;
1180 :     if (interlaced > 2) {
1181 :     vihOut2->dwInterlaceFlags |= AMINTERLACE_Field1First;
1182 :     }
1183 :     need_format_change = 1;
1184 :     }
1185 :     else if (!interlaced && !!(vihOut2->dwInterlaceFlags & AMINTERLACE_IsInterlaced)){
1186 :     vihOut2->dwInterlaceFlags = 0;
1187 :     need_format_change = 1;
1188 :     }
1189 :    
1190 :     if (need_format_change) {
1191 :     pOut2->SetMediaType(&mtOut2);
1192 :     m_pOutput->SetMediaType(&mtOut2);
1193 :     }
1194 : Isibaar 2133 }
1195 : Isibaar 2134 pOut2->Release();
1196 : Isibaar 2113 }
1197 :     }
1198 :     }
1199 :     }
1200 :     else
1201 :     { /* Preroll frame - won't be displayed */
1202 :     int tmp = m_frame.output.csp;
1203 :     int tmp_gen = m_frame.general;
1204 :    
1205 :     m_frame.output.csp = XVID_CSP_NULL;
1206 :    
1207 :     /* Disable postprocessing to speed-up seeking */
1208 :     m_frame.general &= ~XVID_DEBLOCKY;
1209 :     m_frame.general &= ~XVID_DEBLOCKUV;
1210 :     /*m_frame.general &= ~XVID_DERING;*/
1211 :     m_frame.general &= ~XVID_FILMEFFECT;
1212 :    
1213 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
1214 :     if (length == XVID_ERR_MEMORY)
1215 :     return E_FAIL;
1216 :     else if (length < 0)
1217 :     {
1218 :     DPRINTF("*** XVID_DEC_DECODE");
1219 :     return S_FALSE;
1220 :     }
1221 :    
1222 :     m_frame.output.csp = tmp;
1223 :     m_frame.general = tmp_gen;
1224 :     }
1225 :    
1226 :     if (stats.type == XVID_TYPE_NOTHING && length > 0) {
1227 :     DPRINTF(" B-Frame decoder lag");
1228 :     return S_FALSE;
1229 :     }
1230 :    
1231 :    
1232 :     if (stats.type == XVID_TYPE_VOL)
1233 :     {
1234 :     if (stats.data.vol.width != m_create.width ||
1235 :     stats.data.vol.height != m_create.height)
1236 :     {
1237 :     DPRINTF("TODO: auto-resize");
1238 :     return S_FALSE;
1239 :     }
1240 :    
1241 :     pOut->SetSyncPoint(TRUE);
1242 :    
1243 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */
1244 :     int par_x, par_y;
1245 :     if (stats.data.vol.par == XVID_PAR_EXT) {
1246 :     par_x = stats.data.vol.par_width;
1247 :     par_y = stats.data.vol.par_height;
1248 :     } else {
1249 :     par_x = PARS[stats.data.vol.par-1][0];
1250 :     par_y = PARS[stats.data.vol.par-1][1];
1251 :     }
1252 :    
1253 :     ar_x = par_x * stats.data.vol.width;
1254 :     ar_y = par_y * stats.data.vol.height;
1255 :     }
1256 :    
1257 : Isibaar 2134 if (!!(stats.data.vol.general & XVID_VOL_INTERLACING)) {
1258 :     interlaced = (stats.data.vop.general & XVID_VOP_TOPFIELDFIRST) ? 2 : 1;
1259 :     }
1260 :     else if (interlaced > 0) {
1261 :     interlaced = 0;
1262 :     }
1263 :    
1264 : Isibaar 2113 m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
1265 :     m_frame.length -= length;
1266 :     goto repeat;
1267 :     }
1268 :    
1269 :     if (pIn->IsPreroll() == S_OK) {
1270 :     return S_FALSE;
1271 :     }
1272 :    
1273 :     return S_OK;
1274 :     }
1275 :    
1276 :    
1277 :     /* get property page list */
1278 :    
1279 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
1280 :     {
1281 :     DPRINTF("GetPages");
1282 :    
1283 :     pPages->cElems = 1;
1284 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
1285 :     if (pPages->pElems == NULL)
1286 :     {
1287 :     return E_OUTOFMEMORY;
1288 :     }
1289 :     pPages->pElems[0] = CLSID_CABOUT;
1290 :    
1291 :     return S_OK;
1292 :     }
1293 :    
1294 :    
1295 :     /* cleanup pages */
1296 :    
1297 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
1298 :     {
1299 :     DPRINTF("FreePages");
1300 :     CoTaskMemFree(pPages->pElems);
1301 :     return S_OK;
1302 :     }
1303 :    
1304 :     /*===============================================================================
1305 :     // MFT Interface
1306 :     //=============================================================================*/
1307 :     #if defined(XVID_USE_MFT)
1308 :     #include <limits.h> // _I64_MAX
1309 :     #define INVALID_TIME _I64_MAX
1310 :    
1311 :     HRESULT CXvidDecoder::MFTGetStreamLimits(DWORD *pdwInputMinimum, DWORD *pdwInputMaximum, DWORD *pdwOutputMinimum, DWORD *pdwOutputMaximum)
1312 :     {
1313 :     DPRINTF("(MFT)GetStreamLimits");
1314 :    
1315 :     if ((pdwInputMinimum == NULL) || (pdwInputMaximum == NULL) || (pdwOutputMinimum == NULL) || (pdwOutputMaximum == NULL))
1316 :     return E_POINTER;
1317 :    
1318 :     /* Just a fixed number of streams allowed */
1319 :     *pdwInputMinimum = *pdwInputMaximum = 1;
1320 :     *pdwOutputMinimum = *pdwOutputMaximum = 1;
1321 :    
1322 :     return S_OK;
1323 :     }
1324 :    
1325 :     HRESULT CXvidDecoder::MFTGetStreamCount(DWORD *pcInputStreams, DWORD *pcOutputStreams)
1326 :     {
1327 :     DPRINTF("(MFT)GetStreamCount");
1328 :    
1329 :     if ((pcInputStreams == NULL) || (pcOutputStreams == NULL))
1330 :     return E_POINTER;
1331 :    
1332 :     /* We have a fixed number of streams */
1333 :     *pcInputStreams = 1;
1334 :     *pcOutputStreams = 1;
1335 :    
1336 :     return S_OK;
1337 :     }
1338 :    
1339 :     HRESULT CXvidDecoder::MFTGetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, DWORD *pdwOutputIDs)
1340 :     {
1341 :     DPRINTF("(MFT)GetStreamIDs");
1342 :     return E_NOTIMPL; /* We have fixed number of streams, so stream ID match stream index */
1343 :     }
1344 :    
1345 :     HRESULT CXvidDecoder::MFTGetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo)
1346 :     {
1347 :     DPRINTF("(MFT)GetInputStreamInfo");
1348 :    
1349 :     if (pStreamInfo == NULL)
1350 :     return E_POINTER;
1351 :    
1352 :     if (dwInputStreamID != 0)
1353 :     return MF_E_INVALIDSTREAMNUMBER;
1354 :    
1355 :     EnterCriticalSection(&m_mft_lock);
1356 :    
1357 :     pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER;
1358 :     pStreamInfo->hnsMaxLatency = 0;
1359 :    
1360 :     pStreamInfo->cbSize = 1; /* Need atleast 1 byte input */
1361 :     pStreamInfo->cbMaxLookahead = 0;
1362 :     pStreamInfo->cbAlignment = 1;
1363 :    
1364 :     LeaveCriticalSection(&m_mft_lock);
1365 :     return S_OK;
1366 :     }
1367 :    
1368 :     HRESULT CXvidDecoder::MFTGetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo)
1369 :     {
1370 :     DPRINTF("(MFT)GetOutputStreamInfo");
1371 :    
1372 :     if (pStreamInfo == NULL)
1373 :     return E_POINTER;
1374 :    
1375 :     if (dwOutputStreamID != 0)
1376 :     return MF_E_INVALIDSTREAMNUMBER;
1377 :    
1378 :     EnterCriticalSection(&m_mft_lock);
1379 :    
1380 :     pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_OUTPUT_STREAM_DISCARDABLE;
1381 :    
1382 :     if (m_pOutputType == NULL) {
1383 :     pStreamInfo->cbSize = 0;
1384 :     pStreamInfo->cbAlignment = 0;
1385 :     }
1386 :     else {
1387 :     pStreamInfo->cbSize = (m_create.width * abs(m_create.height) * m_pOutputTypeBPP) >> 3;
1388 :     pStreamInfo->cbAlignment = 1;
1389 :     }
1390 :    
1391 :     LeaveCriticalSection(&m_mft_lock);
1392 :     return S_OK;
1393 :     }
1394 :    
1395 :     HRESULT CXvidDecoder::GetAttributes(IMFAttributes** pAttributes)
1396 :     {
1397 :     DPRINTF("(MFT)GetAttributes");
1398 :     return E_NOTIMPL; /* We don't support any attributes */
1399 :     }
1400 :    
1401 :     HRESULT CXvidDecoder::GetInputStreamAttributes(DWORD dwInputStreamID, IMFAttributes **ppAttributes)
1402 :     {
1403 :     DPRINTF("(MFT)GetInputStreamAttributes");
1404 :     return E_NOTIMPL; /* We don't support any attributes */
1405 :     }
1406 :    
1407 :     HRESULT CXvidDecoder::GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes **ppAttributes)
1408 :     {
1409 :     DPRINTF("(MFT)GetOutputStreamAttributes");
1410 :     return E_NOTIMPL; /* We don't support any attributes */
1411 :     }
1412 :    
1413 :     HRESULT CXvidDecoder::MFTDeleteInputStream(DWORD dwStreamID)
1414 :     {
1415 :     DPRINTF("(MFT)DeleteInputStream");
1416 :     return E_NOTIMPL; /* We have a fixed number of streams */
1417 :     }
1418 :    
1419 :     HRESULT CXvidDecoder::MFTAddInputStreams(DWORD cStreams, DWORD *adwStreamIDs)
1420 :     {
1421 :     DPRINTF("(MFT)AddInputStreams");
1422 :     return E_NOTIMPL; /* We have a fixed number of streams */
1423 :     }
1424 :    
1425 :     HRESULT CXvidDecoder::MFTGetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
1426 :     {
1427 :     DPRINTF("(MFT)GetInputAvailableType");
1428 :    
1429 :     if (dwInputStreamID != 0)
1430 :     return MF_E_INVALIDSTREAMNUMBER;
1431 :    
1432 :     DWORD i = 0;
1433 : Isibaar 2115 GUID *bs_guid_table[32];
1434 : Isibaar 2113
1435 :     bs_guid_table[i++] = (GUID *)&CLSID_XVID;
1436 :     bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC;
1437 :    
1438 :     if (g_config.supported_4cc & SUPPORT_3IVX) {
1439 :     bs_guid_table[i++] = (GUID *)&CLSID_3IVX;
1440 :     bs_guid_table[i++] = (GUID *)&CLSID_3IVX_UC;
1441 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV0;
1442 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV0_UC;
1443 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV1;
1444 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV1_UC;
1445 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV2;
1446 :     bs_guid_table[i++] = (GUID *)&CLSID_3IV2_UC;
1447 :     }
1448 :     if (g_config.supported_4cc & SUPPORT_DIVX) {
1449 :     bs_guid_table[i++] = (GUID *)&CLSID_DIVX;
1450 :     bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC;
1451 :     bs_guid_table[i++] = (GUID *)&CLSID_DX50;
1452 :     bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC;
1453 :     }
1454 :     if (g_config.supported_4cc & SUPPORT_MP4V) {
1455 :     bs_guid_table[i++] = (GUID *)&CLSID_MP4V;
1456 :     bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC;
1457 :     bs_guid_table[i++] = (GUID *)&CLSID_LMP4;
1458 :     bs_guid_table[i++] = (GUID *)&CLSID_LMP4_UC;
1459 :     bs_guid_table[i++] = (GUID *)&CLSID_RMP4;
1460 :     bs_guid_table[i++] = (GUID *)&CLSID_RMP4_UC;
1461 :     bs_guid_table[i++] = (GUID *)&CLSID_SMP4;
1462 :     bs_guid_table[i++] = (GUID *)&CLSID_SMP4_UC;
1463 :     bs_guid_table[i++] = (GUID *)&CLSID_HDX4;
1464 :     bs_guid_table[i++] = (GUID *)&CLSID_HDX4_UC;
1465 :     }
1466 :    
1467 :     const GUID *subtype;
1468 :     if (dwTypeIndex < i) {
1469 :     subtype = bs_guid_table[dwTypeIndex];
1470 :     }
1471 :     else {
1472 :     return MF_E_NO_MORE_TYPES;
1473 :     }
1474 :    
1475 :     EnterCriticalSection(&m_mft_lock);
1476 :    
1477 :     HRESULT hr = S_OK;
1478 :    
1479 :     if (ppType) {
1480 :     IMFMediaType *pInputType = NULL;
1481 :     hr = MFCreateMediaType(&pInputType);
1482 :    
1483 :     if (SUCCEEDED(hr))
1484 :     hr = pInputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
1485 :    
1486 :     if (SUCCEEDED(hr))
1487 :     hr = pInputType->SetGUID(MF_MT_SUBTYPE, *subtype);
1488 :    
1489 :     if (SUCCEEDED(hr)) {
1490 :     *ppType = pInputType;
1491 :     (*ppType)->AddRef();
1492 :     }
1493 :     if (pInputType) pInputType->Release();
1494 :     }
1495 :    
1496 :     LeaveCriticalSection(&m_mft_lock);
1497 :    
1498 :     return hr;
1499 :     }
1500 :    
1501 :     HRESULT CXvidDecoder::MFTGetOutputAvailableType(DWORD dwOutputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
1502 :     {
1503 :     DPRINTF("(MFT)GetOutputAvailableType");
1504 :    
1505 :     if (ppType == NULL)
1506 :     return E_INVALIDARG;
1507 :    
1508 :     if (dwOutputStreamID != 0)
1509 :     return MF_E_INVALIDSTREAMNUMBER;
1510 :    
1511 :     if (dwTypeIndex < 0) return E_INVALIDARG;
1512 :    
1513 :     GUID csp;
1514 :     int bitdepth = 8;
1515 :     switch(dwTypeIndex)
1516 :     {
1517 :     case 0:
1518 :     if ( USE_YUY2 )
1519 :     {
1520 :     csp = MFVideoFormat_YUY2;
1521 :     bitdepth = 4;
1522 :     break;
1523 :     }
1524 :     case 1:
1525 :     if ( USE_YVYU )
1526 :     {
1527 :     csp = MFVideoFormat_YVYU;
1528 :     bitdepth = 4;
1529 :     break;
1530 :     }
1531 :     case 2 :
1532 :     if ( USE_UYVY )
1533 :     {
1534 :     csp = MFVideoFormat_UYVY;
1535 :     bitdepth = 4;
1536 :     break;
1537 :     }
1538 :     case 3 :
1539 :     if ( USE_IYUV )
1540 :     {
1541 :     csp = MFVideoFormat_IYUV;
1542 :     bitdepth = 3;
1543 :     break;
1544 :     }
1545 :     case 4 :
1546 :     if ( USE_YV12 )
1547 :     {
1548 :     csp = MFVideoFormat_YV12;
1549 :     bitdepth = 3;
1550 :     break;
1551 :     }
1552 :     case 5 :
1553 :     if ( USE_RGB32 )
1554 :     {
1555 :     csp = MFVideoFormat_RGB32;
1556 :     bitdepth = 8;
1557 :     break;
1558 :     }
1559 :     case 6 :
1560 :     if ( USE_RGB24 )
1561 :     {
1562 :     csp = MFVideoFormat_RGB24;
1563 :     bitdepth = 6;
1564 :     break;
1565 :     }
1566 :     case 7 :
1567 :     if ( USE_RG555 )
1568 :     {
1569 :     csp = MFVideoFormat_RGB555;
1570 :     bitdepth = 4;
1571 :     break;
1572 :     }
1573 :     case 8 :
1574 :     if ( USE_RG565 )
1575 :     {
1576 :     csp = MFVideoFormat_RGB565;
1577 :     bitdepth = 4;
1578 :     break;
1579 :     }
1580 :     default :
1581 :     return MF_E_NO_MORE_TYPES;
1582 :     }
1583 :    
1584 :     if (m_pInputType == NULL)
1585 :     return MF_E_TRANSFORM_TYPE_NOT_SET;
1586 :    
1587 :     EnterCriticalSection(&m_mft_lock);
1588 :    
1589 :     HRESULT hr = S_OK;
1590 :    
1591 :     IMFMediaType *pOutputType = NULL;
1592 :     hr = MFCreateMediaType(&pOutputType);
1593 :    
1594 :     if (SUCCEEDED(hr)) {
1595 :     hr = pOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
1596 :     }
1597 :    
1598 :     if (SUCCEEDED(hr)) {
1599 :     hr = pOutputType->SetGUID(MF_MT_SUBTYPE, csp);
1600 :     }
1601 :    
1602 :     if (SUCCEEDED(hr)) {
1603 :     hr = pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE);
1604 :     }
1605 :    
1606 :     if (SUCCEEDED(hr)) {
1607 :     hr = pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1608 :     }
1609 :    
1610 :     if (SUCCEEDED(hr)) {
1611 :     hr = pOutputType->SetUINT32(MF_MT_SAMPLE_SIZE, (abs(m_create.height) * m_create.width * bitdepth) >> 1);
1612 :     }
1613 :    
1614 :     if (SUCCEEDED(hr)) {
1615 :     hr = MFSetAttributeSize(pOutputType, MF_MT_FRAME_SIZE, m_create.width, abs(m_create.height));
1616 :     }
1617 :    
1618 :     if (SUCCEEDED(hr)) {
1619 :     hr = MFSetAttributeRatio(pOutputType, MF_MT_FRAME_RATE, m_frameRate.Numerator, m_frameRate.Denominator);
1620 :     }
1621 :    
1622 :     if (SUCCEEDED(hr)) {
1623 : Isibaar 2133 if (interlaced > 1) {
1624 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedUpperFirst);
1625 :     }
1626 :     else if (interlaced) {
1627 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedLowerFirst);
1628 :     }
1629 :     else {
1630 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
1631 :     }
1632 : Isibaar 2113 }
1633 :    
1634 :     if (SUCCEEDED(hr)) {
1635 :     hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, ar_x, ar_y);
1636 :     }
1637 :    
1638 :     if (SUCCEEDED(hr)) {
1639 :     *ppType = pOutputType;
1640 :     (*ppType)->AddRef();
1641 :     }
1642 :    
1643 :     if (pOutputType) pOutputType->Release();
1644 :    
1645 :     LeaveCriticalSection(&m_mft_lock);
1646 :     return hr;
1647 :     }
1648 :    
1649 :     HRESULT CXvidDecoder::MFTSetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags)
1650 :     {
1651 :     DPRINTF("(MFT)SetInputType");
1652 :    
1653 :     if (dwInputStreamID != 0)
1654 :     return MF_E_INVALIDSTREAMNUMBER;
1655 :    
1656 :     if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
1657 :     return E_INVALIDARG;
1658 :    
1659 :     EnterCriticalSection(&m_mft_lock);
1660 :    
1661 :     HRESULT hr = S_OK;
1662 :    
1663 :     /* Actually set the type or just test it? */
1664 :     BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
1665 :    
1666 :     /* If we have samples pending the type can't be changed right now */
1667 :     if (HasPendingOutput())
1668 :     hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1669 :    
1670 :     if (SUCCEEDED(hr)) {
1671 :     if (pType) { /* Check the type */
1672 :     hr = OnCheckInputType(pType);
1673 :     }
1674 :     }
1675 :    
1676 :     if (SUCCEEDED(hr)) {
1677 :     if (bReallySet) { /* Set the type if needed */
1678 :     hr = OnSetInputType(pType);
1679 :     }
1680 :     }
1681 :    
1682 :     LeaveCriticalSection(&m_mft_lock);
1683 :     return hr;
1684 :     }
1685 :    
1686 :     DWORD WINAPI CreateTrayIcon(LPVOID lpParameter)
1687 :     {
1688 :     WNDCLASSEX wc;
1689 :    
1690 :     wc.cbSize = sizeof(WNDCLASSEX);
1691 :     wc.lpfnWndProc = msg_proc;
1692 :     wc.style = CS_HREDRAW | CS_VREDRAW;
1693 :     wc.cbWndExtra = 0;
1694 :     wc.cbClsExtra = 0;
1695 :     wc.hInstance = (HINSTANCE)g_xvid_hInst;
1696 :     wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
1697 :     wc.lpszMenuName = NULL;
1698 :     wc.lpszClassName = "XVID_MSG_WINDOW";
1699 :     wc.hIcon = NULL;
1700 :     wc.hIconSm = NULL;
1701 :     wc.hCursor = NULL;
1702 :     RegisterClassEx(&wc);
1703 :    
1704 :     MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,
1705 :     CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE)g_xvid_hInst, NULL);
1706 :    
1707 :     /* display the tray icon */
1708 :     NOTIFYICONDATA nid;
1709 :     ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
1710 :    
1711 :     nid.cbSize = sizeof(NOTIFYICONDATA);
1712 :     nid.hWnd = MSG_hwnd;
1713 :     nid.uID = 1456;
1714 :     nid.uVersion = NOTIFYICON_VERSION;
1715 :     nid.uCallbackMessage = WM_ICONMESSAGE;
1716 :     nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
1717 :     strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
1718 :     nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
1719 :    
1720 :     Shell_NotifyIcon(NIM_ADD, &nid);
1721 :     Shell_NotifyIcon(NIM_SETVERSION, &nid);
1722 :    
1723 :     DestroyIcon(nid.hIcon);
1724 :    
1725 :     MSG msg;
1726 :     while (MSG_hwnd && GetMessage(&msg, MSG_hwnd, 0, 0)) {
1727 :     TranslateMessage(&msg);
1728 :     DispatchMessage(&msg);
1729 :     }
1730 :    
1731 :     return 0;
1732 :     }
1733 :    
1734 :     HRESULT CXvidDecoder::MFTSetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)
1735 :     {
1736 :     DPRINTF("(MFT)SetOutputType");
1737 :    
1738 :     if (dwOutputStreamID != 0)
1739 :     return MF_E_INVALIDSTREAMNUMBER;
1740 :    
1741 :     if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
1742 :     return E_INVALIDARG;
1743 :    
1744 :     HRESULT hr = S_OK;
1745 :    
1746 :     EnterCriticalSection(&m_mft_lock);
1747 :    
1748 :     /* Actually set the type or just test it? */
1749 :     BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
1750 :    
1751 :     /* If we have samples pending the type can't be changed right now */
1752 :     if (HasPendingOutput())
1753 :     hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1754 :    
1755 :     int bitdepth;
1756 :     if (SUCCEEDED(hr)) {
1757 :     if (pType) { /* Check the type */
1758 :     AM_MEDIA_TYPE *am;
1759 :     hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am);
1760 :    
1761 :     if (SUCCEEDED(hr)) {
1762 :     if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat, &bitdepth, 1))) {
1763 :     DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)");
1764 :     return MF_E_INVALIDTYPE;
1765 :     }
1766 :    
1767 :     CoTaskMemFree(am->pbFormat);
1768 :     CoTaskMemFree(am);
1769 :     }
1770 :     }
1771 :     }
1772 :    
1773 :     if (SUCCEEDED(hr)) {
1774 :     if (bReallySet) { /* Set the type if needed */
1775 :     hr = OnSetOutputType(pType, bitdepth);
1776 :     }
1777 :     }
1778 :    
1779 :     if (SUCCEEDED(hr) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
1780 :     {
1781 :     m_thread_handle = CreateThread(NULL, 0, CreateTrayIcon, NULL, 0, NULL); /* Create message passing window */
1782 :    
1783 :     if (m_thread_handle)
1784 :     m_tray_icon = 1;
1785 :     }
1786 :    
1787 :     LeaveCriticalSection(&m_mft_lock);
1788 :    
1789 :     return hr;
1790 :     }
1791 :    
1792 :     HRESULT CXvidDecoder::MFTGetInputCurrentType(DWORD dwInputStreamID, IMFMediaType **ppType)
1793 :     {
1794 :     DPRINTF("(MFT)GetInputCurrentType");
1795 :    
1796 :     if (ppType == NULL)
1797 :     return E_POINTER;
1798 :    
1799 :     if (dwInputStreamID != 0)
1800 :     return MF_E_INVALIDSTREAMNUMBER;
1801 :    
1802 :     EnterCriticalSection(&m_mft_lock);
1803 :    
1804 :     HRESULT hr = S_OK;
1805 :    
1806 :     if (!m_pInputType)
1807 :     hr = MF_E_TRANSFORM_TYPE_NOT_SET;
1808 :    
1809 :     if (SUCCEEDED(hr)) {
1810 :     *ppType = m_pInputType;
1811 :     (*ppType)->AddRef();
1812 :     }
1813 :    
1814 :     LeaveCriticalSection(&m_mft_lock);
1815 :     return hr;
1816 :     }
1817 :    
1818 :     HRESULT CXvidDecoder::MFTGetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType)
1819 :     {
1820 :     DPRINTF("(MFT)GetOutputCurrentType");
1821 :    
1822 :     if (ppType == NULL)
1823 :     return E_POINTER;
1824 :    
1825 :     if (dwOutputStreamID != 0)
1826 :     return MF_E_INVALIDSTREAMNUMBER;
1827 :    
1828 :     EnterCriticalSection(&m_mft_lock);
1829 :    
1830 :     HRESULT hr = S_OK;
1831 :    
1832 :     if (!m_pOutputType)
1833 :     hr = MF_E_TRANSFORM_TYPE_NOT_SET;
1834 :    
1835 :     if (SUCCEEDED(hr)) {
1836 :     *ppType = m_pOutputType;
1837 :     (*ppType)->AddRef();
1838 :     }
1839 :    
1840 :     LeaveCriticalSection(&m_mft_lock);
1841 :     return hr;
1842 :     }
1843 :    
1844 :     HRESULT CXvidDecoder::MFTGetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags)
1845 :     {
1846 :     DPRINTF("(MFT)GetInputStatus");
1847 :    
1848 :     if (pdwFlags == NULL)
1849 :     return E_POINTER;
1850 :    
1851 :     if (dwInputStreamID != 0)
1852 :     return MF_E_INVALIDSTREAMNUMBER;
1853 :    
1854 :     EnterCriticalSection(&m_mft_lock);
1855 :    
1856 :     /* If there's pending output samples we don't accept new
1857 :     input data until ProcessOutput() or Flush() was called */
1858 :     if (!HasPendingOutput()) {
1859 :     *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
1860 :     }
1861 :     else {
1862 :     *pdwFlags = 0;
1863 :     }
1864 :    
1865 :     LeaveCriticalSection(&m_mft_lock);
1866 :    
1867 :     return S_OK;
1868 :     }
1869 :    
1870 :     HRESULT CXvidDecoder::MFTGetOutputStatus(DWORD *pdwFlags)
1871 :     {
1872 :     DPRINTF("(MFT)GetOutputStatus");
1873 :    
1874 :     if (pdwFlags == NULL)
1875 :     return E_POINTER;
1876 :    
1877 :     EnterCriticalSection(&m_mft_lock);
1878 :    
1879 :     /* We can render an output sample only after we
1880 :     have decoded one */
1881 :     if (HasPendingOutput()) {
1882 :     *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY;
1883 :     }
1884 :     else {
1885 :     *pdwFlags = 0;
1886 :     }
1887 :    
1888 :     LeaveCriticalSection(&m_mft_lock);
1889 :    
1890 :     return S_OK;
1891 :     }
1892 :    
1893 :     HRESULT CXvidDecoder::MFTSetOutputBounds(LONGLONG hnsLowerBound, LONGLONG hnsUpperBound)
1894 :     {
1895 :     DPRINTF("(MFT)SetOutputBounds");
1896 :     return E_NOTIMPL;
1897 :     }
1898 :    
1899 :     HRESULT CXvidDecoder::MFTProcessEvent(DWORD dwInputStreamID, IMFMediaEvent *pEvent)
1900 :     {
1901 :     DPRINTF("(MFT)ProcessEvent");
1902 :     return E_NOTIMPL; /* We don't handle any stream events */
1903 :     }
1904 :    
1905 :     HRESULT CXvidDecoder::MFTProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
1906 :     {
1907 :     DPRINTF("(MFT)ProcessMessage");
1908 :     HRESULT hr = S_OK;
1909 :    
1910 :     EnterCriticalSection(&m_mft_lock);
1911 :    
1912 :     switch (eMessage)
1913 :     {
1914 :     case MFT_MESSAGE_COMMAND_FLUSH:
1915 :     if (m_create.handle != NULL) {
1916 :     DPRINTF("(MFT)CommandFlush");
1917 :    
1918 :     xvid_dec_stats_t stats;
1919 :     int used_bytes;
1920 :    
1921 :     memset(&stats, 0, sizeof(stats));
1922 :     stats.version = XVID_VERSION;
1923 :    
1924 :     int csp = m_frame.output.csp;
1925 :    
1926 :     m_frame.output.csp = XVID_CSP_INTERNAL;
1927 :     m_frame.bitstream = NULL;
1928 :     m_frame.length = -1;
1929 :     m_frame.general = XVID_LOWDELAY;
1930 :    
1931 :     do {
1932 :     used_bytes = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
1933 :     } while(used_bytes>=0 && stats.type <= 0);
1934 :    
1935 :     m_frame.output.csp = csp;
1936 :     m_frame.output.plane[1] = NULL; /* Don't display flushed samples */
1937 :    
1938 :     //m_timestamp = INVALID_TIME;
1939 :     //m_timelength = INVALID_TIME;
1940 :     //m_rtFrame = 0;
1941 :     }
1942 :     break;
1943 :    
1944 :     case MFT_MESSAGE_COMMAND_DRAIN:
1945 :     m_discont = 1; /* Set discontinuity flag */
1946 :     m_rtFrame = 0;
1947 :     break;
1948 :    
1949 :     case MFT_MESSAGE_SET_D3D_MANAGER:
1950 :     hr = E_NOTIMPL;
1951 :     break;
1952 :    
1953 :     case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
1954 :     case MFT_MESSAGE_NOTIFY_END_STREAMING:
1955 :     break;
1956 :    
1957 :     case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
1958 :     case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
1959 :     break;
1960 :     }
1961 :    
1962 :     LeaveCriticalSection(&m_mft_lock);
1963 :    
1964 :     return hr;
1965 :     }
1966 :    
1967 :     HRESULT CXvidDecoder::MFTProcessInput(DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags)
1968 :     {
1969 :     DPRINTF("(MFT)ProcessInput");
1970 :    
1971 :     if (pSample == NULL)
1972 :     return E_POINTER;
1973 :    
1974 :     if (dwInputStreamID != 0)
1975 :     return MF_E_INVALIDSTREAMNUMBER;
1976 :    
1977 :     if (dwFlags != 0)
1978 :     return E_INVALIDARG;
1979 :    
1980 :     if (!m_pInputType || !m_pOutputType) {
1981 :     return MF_E_NOTACCEPTING; /* Must have set input and output types */
1982 :     }
1983 :     else if (HasPendingOutput()) {
1984 :     return MF_E_NOTACCEPTING; /* We still have output samples to render */
1985 :     }
1986 :    
1987 :     xvid_dec_stats_t stats;
1988 :     int length;
1989 :    
1990 :     memset(&stats, 0, sizeof(stats));
1991 :     stats.version = XVID_VERSION;
1992 :    
1993 :     if (m_create.handle == NULL)
1994 :     {
1995 :     if (xvid_decore_func == NULL)
1996 :     return E_FAIL;
1997 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
1998 :     {
1999 :     DPRINTF("*** XVID_DEC_CREATE error");
2000 :     return E_FAIL;
2001 :     }
2002 :     }
2003 :    
2004 :     EnterCriticalSection(&m_mft_lock);
2005 :    
2006 :     HRESULT hr = S_OK;
2007 :     IMFMediaBuffer *pBuffer;
2008 :    
2009 : Isibaar 2134 int need_format_change = 0;
2010 :    
2011 : Isibaar 2113 if (SUCCEEDED(hr)) {
2012 :     hr = pSample->ConvertToContiguousBuffer(&pBuffer);
2013 :     }
2014 :    
2015 :     if (SUCCEEDED(hr)) {
2016 :     hr = pBuffer->Lock((BYTE**)&m_frame.bitstream, NULL, (DWORD *)&m_frame.length);
2017 :     }
2018 :    
2019 :     m_frame.general = XVID_LOWDELAY;
2020 :    
2021 :     if (m_discont == 1) {
2022 :     m_frame.general |= XVID_DISCONTINUITY;
2023 :     m_discont = 0;
2024 :     }
2025 :    
2026 :     if (g_config.nDeblock_Y)
2027 :     m_frame.general |= XVID_DEBLOCKY;
2028 :    
2029 :     if (g_config.nDeblock_UV)
2030 :     m_frame.general |= XVID_DEBLOCKUV;
2031 :    
2032 :     if (g_config.nDering_Y)
2033 :     m_frame.general |= XVID_DERINGY;
2034 :    
2035 :     if (g_config.nDering_UV)
2036 :     m_frame.general |= XVID_DERINGUV;
2037 :    
2038 :     if (g_config.nFilmEffect)
2039 :     m_frame.general |= XVID_FILMEFFECT;
2040 :    
2041 :     m_frame.brightness = g_config.nBrightness;
2042 :    
2043 :     m_frame.output.csp &= ~XVID_CSP_VFLIP;
2044 :     m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
2045 :    
2046 :     int csp = m_frame.output.csp;
2047 :     m_frame.output.csp = XVID_CSP_INTERNAL;
2048 :    
2049 :     // Paranoid check.
2050 :     if (xvid_decore_func == NULL) {
2051 :     hr = E_FAIL;
2052 :     goto END_LOOP;
2053 :     }
2054 :    
2055 :     repeat :
2056 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
2057 :    
2058 :     if (length == XVID_ERR_MEMORY) {
2059 :     hr = E_FAIL;
2060 :     goto END_LOOP;
2061 :     }
2062 :     else if (length < 0)
2063 :     {
2064 :     DPRINTF("*** XVID_DEC_DECODE");
2065 :     goto END_LOOP;
2066 :     }
2067 :    
2068 :     if (stats.type == XVID_TYPE_NOTHING && length > 0) {
2069 :     DPRINTF(" B-Frame decoder lag");
2070 :     m_frame.output.plane[1] = NULL;
2071 :     goto END_LOOP;
2072 :     }
2073 :    
2074 :     if (stats.type == XVID_TYPE_VOL)
2075 :     {
2076 :     if (stats.data.vol.width != m_create.width ||
2077 :     stats.data.vol.height != m_create.height)
2078 :     {
2079 :     DPRINTF("TODO: auto-resize");
2080 :     m_frame.output.plane[1] = NULL;
2081 :     hr = E_FAIL;
2082 :     }
2083 :    
2084 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */
2085 :     int par_x, par_y;
2086 :     if (stats.data.vol.par == XVID_PAR_EXT) {
2087 :     par_x = stats.data.vol.par_width;
2088 :     par_y = stats.data.vol.par_height;
2089 :     } else {
2090 :     par_x = PARS[stats.data.vol.par-1][0];
2091 :     par_y = PARS[stats.data.vol.par-1][1];
2092 :     }
2093 :    
2094 : Isibaar 2136 ar_x = par_x;
2095 :     ar_y = par_y;
2096 : Isibaar 2134
2097 :     need_format_change = 1;
2098 : Isibaar 2113 }
2099 :    
2100 : Isibaar 2134 if (!!(stats.data.vol.general & XVID_VOL_INTERLACING)) {
2101 : Isibaar 2133 interlaced = (stats.data.vop.general & XVID_VOP_TOPFIELDFIRST) ? 2 : 1;
2102 : Isibaar 2134 need_format_change = 1;
2103 : Isibaar 2133 }
2104 :     else {
2105 : Isibaar 2134 if (interlaced > 0) {
2106 :     interlaced = 0;
2107 :     need_format_change = 1;
2108 :     }
2109 : Isibaar 2133 }
2110 :    
2111 : Isibaar 2113 m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
2112 :     m_frame.length -= length;
2113 :     goto repeat;
2114 :     }
2115 :    
2116 :     END_LOOP:
2117 :     m_frame.output.csp = csp;
2118 :    
2119 :     if (pBuffer) {
2120 :     pBuffer->Unlock();
2121 :     pBuffer->Release();
2122 :     }
2123 :    
2124 :     if (SUCCEEDED(hr)) {
2125 :     /* Try to get a timestamp */
2126 :     if (FAILED(pSample->GetSampleTime(&m_timestamp)))
2127 :     m_timestamp = INVALID_TIME;
2128 :    
2129 :     if (FAILED(pSample->GetSampleDuration(&m_timelength))) {
2130 :     m_timelength = INVALID_TIME;
2131 :     }
2132 :     if (m_timestamp != INVALID_TIME && stats.type == XVID_TYPE_IVOP) {
2133 :     m_rtFrame = m_timestamp;
2134 :     }
2135 :     }
2136 :    
2137 : Isibaar 2134 if (need_format_change) {
2138 :     IMFMediaType *pOutputType = NULL;
2139 :     hr = MFTGetOutputCurrentType(0, &pOutputType);
2140 :    
2141 :     if (SUCCEEDED(hr)) {
2142 :     if (interlaced > 1) {
2143 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedUpperFirst);
2144 :     }
2145 :     else if (interlaced) {
2146 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedLowerFirst);
2147 :     }
2148 :     else {
2149 :     hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
2150 :     }
2151 :     }
2152 :    
2153 :     if (SUCCEEDED(hr)) {
2154 :     hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, ar_x, ar_y);
2155 :     }
2156 :    
2157 :     if (SUCCEEDED(hr)) {
2158 :     MFTSetOutputType(0, pOutputType, 0);
2159 :     }
2160 :    
2161 :     if (pOutputType) pOutputType->Release();
2162 :     }
2163 :    
2164 : Isibaar 2113 LeaveCriticalSection(&m_mft_lock);
2165 :    
2166 :     return hr;
2167 :     }
2168 :    
2169 :     HRESULT CXvidDecoder::MFTProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER *pOutputSamples, DWORD *pdwStatus)
2170 :     {
2171 :     DPRINTF("(MFT)ProcessOutput");
2172 :    
2173 :     /* Preroll in MFT ??
2174 :     Flags ?? -> TODO... */
2175 :     if (dwFlags != 0)
2176 :     return E_INVALIDARG;
2177 :    
2178 :     if (pOutputSamples == NULL || pdwStatus == NULL)
2179 :     return E_POINTER;
2180 :    
2181 :     if (cOutputBufferCount != 1) /* Must be exactly one output buffer */
2182 :     return E_INVALIDARG;
2183 :    
2184 :     if (pOutputSamples[0].pSample == NULL) /* Must have a sample */
2185 :     return E_INVALIDARG;
2186 :    
2187 :     if (!HasPendingOutput()) { /* If there's no sample we need to decode one first */
2188 :     return MF_E_TRANSFORM_NEED_MORE_INPUT;
2189 :     }
2190 :    
2191 :     EnterCriticalSection(&m_mft_lock);
2192 :    
2193 :     HRESULT hr = S_OK;
2194 :    
2195 :     BYTE *Dst = NULL;
2196 :     DWORD buffer_size;
2197 : Isibaar 2157 LONG stride = (m_pOutputTypeBPP < 15) ? CALC_BI_STRIDE(m_create.width, 8) : CALC_BI_STRIDE(m_create.width, m_pOutputTypeBPP);
2198 : Isibaar 2113 IMFMediaBuffer *pOutput = NULL;
2199 :     IMF2DBuffer *pOutput2D = NULL;
2200 :    
2201 :     if (SUCCEEDED(hr)) {
2202 :     hr = pOutputSamples[0].pSample->GetBufferByIndex(0, &pOutput); /* Get output buffer */
2203 :     }
2204 :    
2205 :     if (SUCCEEDED(hr)) {
2206 :     hr = pOutput->GetMaxLength(&buffer_size);
2207 :     }
2208 :    
2209 :     if (SUCCEEDED(hr)) {
2210 :     hr = pOutput->QueryInterface(IID_IMF2DBuffer, (void **)&pOutput2D);
2211 :     }
2212 :    
2213 :     if (SUCCEEDED(hr)) {
2214 :     hr = pOutput2D->Lock2D(&Dst, &stride);
2215 :     }
2216 :     else {
2217 :     hr = pOutput->Lock(&Dst, NULL, NULL);
2218 :     }
2219 :    
2220 :     if (SUCCEEDED(hr)) {
2221 :     xvid_gbl_convert_t convert;
2222 :    
2223 :     memset(&convert, 0, sizeof(convert));
2224 :     convert.version = XVID_VERSION;
2225 :    
2226 :     convert.input.csp = XVID_CSP_INTERNAL;
2227 :     convert.input.plane[0] = m_frame.output.plane[0];
2228 :     convert.input.plane[1] = m_frame.output.plane[1];
2229 :     convert.input.plane[2] = m_frame.output.plane[2];
2230 :     convert.input.stride[0] = m_frame.output.stride[0];
2231 :     convert.input.stride[1] = m_frame.output.stride[1];
2232 :     convert.input.stride[2] = m_frame.output.stride[2];
2233 :    
2234 :     convert.output.csp = m_frame.output.csp;
2235 :     convert.output.plane[0] = Dst;
2236 :     convert.output.stride[0] = stride;
2237 :    
2238 :     convert.width = m_create.width;
2239 :     convert.height = m_create.height;
2240 : Isibaar 2133 convert.interlacing = (interlaced > 0) ? 1 : 0;
2241 : Isibaar 2113
2242 :     if (m_frame.output.plane[1] != NULL && Dst != NULL && xvid_global_func != NULL)
2243 :     if (xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0) /* CSP convert into output buffer */
2244 :     hr = E_FAIL;
2245 :     m_frame.output.plane[1] = NULL;
2246 :     }
2247 :    
2248 :     *pdwStatus = 0;
2249 :    
2250 :     if (SUCCEEDED(hr)) {
2251 :     if (SUCCEEDED(hr))
2252 :     hr = pOutputSamples[0].pSample->SetUINT32(MFSampleExtension_CleanPoint, TRUE); // key frame
2253 :    
2254 :     if (SUCCEEDED(hr)) { /* Set timestamp of output sample */
2255 :     if (m_timestamp != INVALID_TIME)
2256 :     hr = pOutputSamples[0].pSample->SetSampleTime(m_timestamp);
2257 :     else
2258 :     hr = pOutputSamples[0].pSample->SetSampleTime(m_rtFrame);
2259 :    
2260 :     if (m_timelength != INVALID_TIME)
2261 :     hr = pOutputSamples[0].pSample->SetSampleDuration(m_timelength);
2262 :     else
2263 :     hr = pOutputSamples[0].pSample->SetSampleDuration(m_duration);
2264 :    
2265 :     m_rtFrame += m_duration;
2266 :     }
2267 :    
2268 :     if (SUCCEEDED(hr))
2269 :     hr = pOutput->SetCurrentLength((m_create.width * abs(m_create.height) * m_pOutputTypeBPP) >> 3);
2270 :     }
2271 :    
2272 :     if (pOutput2D) {
2273 :     pOutput2D->Unlock2D();
2274 :     pOutput2D->Release();
2275 :     if (pOutput)
2276 :     pOutput->Release();
2277 :     }
2278 :     else if (pOutput) {
2279 :     pOutput->Unlock();
2280 :     pOutput->Release();
2281 :     }
2282 :    
2283 :     LeaveCriticalSection(&m_mft_lock);
2284 :    
2285 :     return hr;
2286 :     }
2287 :    
2288 :     HRESULT CXvidDecoder::OnCheckInputType(IMFMediaType *pmt)
2289 :     {
2290 :     DPRINTF("(MFT)CheckInputType");
2291 :    
2292 :     HRESULT hr = S_OK;
2293 :    
2294 :     /* Check if input type is already set. Reject any type that is not identical */
2295 :     if (m_pInputType) {
2296 :     DWORD dwFlags = 0;
2297 :     if (S_OK == m_pInputType->IsEqual(pmt, &dwFlags)) {
2298 :     return S_OK;
2299 :     }
2300 :     else {
2301 :     return MF_E_INVALIDTYPE;
2302 :     }
2303 :     }
2304 :    
2305 :     GUID majortype = {0}, subtype = {0};
2306 :     UINT32 width = 0, height = 0;
2307 :    
2308 :     hr = pmt->GetMajorType(&majortype);
2309 :    
2310 :     if (SUCCEEDED(hr)) {
2311 :     if (majortype != MFMediaType_Video) { /* Must be Video */
2312 :     hr = MF_E_INVALIDTYPE;
2313 :     }
2314 :     }
2315 :    
2316 :     if (m_hdll == NULL) {
2317 :     HRESULT hr = OpenLib();
2318 :    
2319 :     if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks.
2320 :     hr = MF_E_INVALIDTYPE;
2321 :     }
2322 :    
2323 :     if (SUCCEEDED(hr)) {
2324 :     hr = MFGetAttributeSize(pmt, MF_MT_FRAME_SIZE, &width, &height);
2325 :     }
2326 :    
2327 :     /* Check the frame size */
2328 :     if (SUCCEEDED(hr)) {
2329 :     if (width > 4096 || height > 4096) {
2330 :     hr = MF_E_INVALIDTYPE;
2331 :     }
2332 :     }
2333 :     m_create.width = width;
2334 :     m_create.height = height;
2335 :    
2336 :     if (SUCCEEDED(hr)) {
2337 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
2338 :     hr = MFGetAttributeRatio(pmt, MF_MT_PIXEL_ASPECT_RATIO, (UINT32*)&ar_x, (UINT32*)&ar_y);
2339 :     }
2340 :     }
2341 :    
2342 :     /* TODO1: Make sure there really is a frame rate after all!
2343 :     TODO2: Use the framerate for something! */
2344 :     MFRatio fps = {0};
2345 :     if (SUCCEEDED(hr)) {
2346 :     hr = MFGetAttributeRatio(pmt, MF_MT_FRAME_RATE, (UINT32*)&fps.Numerator, (UINT32*)&fps.Denominator);
2347 :     }
2348 :    
2349 :     if (SUCCEEDED(hr)) {
2350 :     hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);
2351 :     }
2352 :    
2353 :     if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC ||
2354 :     subtype == CLSID_LMP4 || subtype == CLSID_LMP4_UC ||
2355 :     subtype == CLSID_RMP4 || subtype == CLSID_RMP4_UC ||
2356 :     subtype == CLSID_SMP4 || subtype == CLSID_SMP4_UC ||
2357 :     subtype == CLSID_HDX4 || subtype == CLSID_HDX4_UC) {
2358 :     if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
2359 :     CloseLib();
2360 :     hr = MF_E_INVALIDTYPE;
2361 :     }
2362 :     else m_create.fourcc = FOURCC_MP4V;
2363 :     }
2364 :     else if (subtype == CLSID_DIVX || subtype == CLSID_DIVX_UC) {
2365 :     if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
2366 :     CloseLib();
2367 :     hr = MF_E_INVALIDTYPE;
2368 :     }
2369 :     else m_create.fourcc = FOURCC_DIVX;
2370 :     }
2371 :     else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) {
2372 :     if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
2373 :     CloseLib();
2374 :     hr = MF_E_INVALIDTYPE;
2375 :     }
2376 :     else m_create.fourcc = FOURCC_DX50;
2377 :     }
2378 :     else if (subtype == CLSID_3IVX || subtype == CLSID_3IVX_UC ||
2379 :     subtype == CLSID_3IV0 || subtype == CLSID_3IV0_UC ||
2380 :     subtype == CLSID_3IV1 || subtype == CLSID_3IV1_UC ||
2381 :     subtype == CLSID_3IV2 || subtype == CLSID_3IV2_UC) {
2382 :     if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
2383 :     CloseLib();
2384 :     hr = MF_E_INVALIDTYPE;
2385 :     }
2386 :     else m_create.fourcc = FOURCC_3IVX;
2387 :     }
2388 :     else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) {
2389 :     m_create.fourcc = FOURCC_XVID;
2390 :     }
2391 :     else {
2392 :     DPRINTF("Unknown subtype!");
2393 :     CloseLib();
2394 :     hr = MF_E_INVALIDTYPE;
2395 :     }
2396 : Isibaar 2115
2397 : Isibaar 2113 /* haali media splitter reports VOL information in the format header */
2398 :     if (SUCCEEDED(hr))
2399 :     {
2400 :     UINT32 cbSeqHeader = 0;
2401 :    
2402 :     (void)pmt->GetBlobSize(MF_MT_MPEG_SEQUENCE_HEADER, &cbSeqHeader);
2403 :    
2404 :     if (cbSeqHeader>0) {
2405 :     xvid_dec_stats_t stats;
2406 :     memset(&stats, 0, sizeof(stats));
2407 :     stats.version = XVID_VERSION;
2408 :    
2409 :     if (m_create.handle == NULL) {
2410 :     if (xvid_decore_func == NULL)
2411 :     hr = E_FAIL;
2412 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) {
2413 :     DPRINTF("*** XVID_DEC_CREATE error");
2414 :     hr = E_FAIL;
2415 :     }
2416 :     }
2417 :    
2418 :     if (SUCCEEDED(hr)) {
2419 :     (void)pmt->GetAllocatedBlob(MF_MT_MPEG_SEQUENCE_HEADER, (UINT8 **)&m_frame.bitstream, (UINT32 *)&m_frame.length);
2420 :     m_frame.general = 0;
2421 :     m_frame.output.csp = XVID_CSP_NULL;
2422 :    
2423 :     int ret = 0;
2424 :     if ((ret=xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats)) >= 0) {
2425 :     /* honour video dimensions reported in VOL header */
2426 :     if (stats.type == XVID_TYPE_VOL) {
2427 :     m_create.width = stats.data.vol.width;
2428 :     m_create.height = stats.data.vol.height;
2429 :     }
2430 :     }
2431 :    
2432 :     if (ret == XVID_ERR_MEMORY) hr = E_FAIL;
2433 :     CoTaskMemFree(m_frame.bitstream);
2434 :     }
2435 :     }
2436 :     }
2437 :    
2438 :     return hr;
2439 :     }
2440 :    
2441 :     HRESULT CXvidDecoder::OnSetInputType(IMFMediaType *pmt)
2442 :     {
2443 :     HRESULT hr = S_OK;
2444 :     UINT32 w, h;
2445 :    
2446 :     if (m_pInputType) m_pInputType->Release();
2447 :    
2448 :     hr = MFGetAttributeSize(pmt, MF_MT_FRAME_SIZE, &w, &h);
2449 :     m_create.width = w; m_create.height = h;
2450 :    
2451 :     if (SUCCEEDED(hr))
2452 :     hr = MFGetAttributeRatio(pmt, MF_MT_FRAME_RATE, (UINT32*)&m_frameRate.Numerator, (UINT32*)&m_frameRate.Denominator);
2453 :    
2454 :     if (SUCCEEDED(hr)) { /* Store frame duration, derived from the frame rate */
2455 :     hr = MFFrameRateToAverageTimePerFrame(m_frameRate.Numerator, m_frameRate.Denominator, &m_duration);
2456 :     }
2457 :    
2458 :     if (SUCCEEDED(hr)) {
2459 :     m_pInputType = pmt;
2460 :     m_pInputType->AddRef();
2461 :     }
2462 :    
2463 :     return hr;
2464 :     }
2465 :    
2466 :     HRESULT CXvidDecoder::OnSetOutputType(IMFMediaType *pmt, int bitdepth)
2467 :     {
2468 :     if (m_pOutputType) m_pOutputType->Release();
2469 :    
2470 :     m_pOutputType = pmt;
2471 :     m_pOutputType->AddRef();
2472 :     m_pOutputTypeBPP = bitdepth;
2473 :    
2474 :     return S_OK;
2475 :     }
2476 :    
2477 :     #endif /* XVID_USE_MFT */

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