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

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