[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 2059 - (view) (download)

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

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