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

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