[svn] / branches / release-1_3-branch / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /branches/release-1_3-branch/xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2006 - (view) (download)

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

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