[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 1896 - (view) (download)
Original Path: trunk/xvidcore/dshow/src/CXvidDecoder.cpp

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 1896 * $Id: CXvidDecoder.cpp,v 1.19 2010-10-16 12:20:30 Isibaar Exp $
24 : edgomez 1384 *
25 :     ****************************************************************************/
26 :    
27 :     /****************************************************************************
28 :     *
29 :     * 2003/12/11 - added some additional options, mainly to make the deblocking
30 :     * code from xvidcore available. Most of the new code is taken
31 :     * from Nic's dshow filter, (C) Nic, http://nic.dnsalias.com
32 :     *
33 :     ****************************************************************************/
34 :    
35 :     /*
36 :     this requires the directx sdk
37 :     place these paths at the top of the Tools|Options|Directories list
38 :    
39 :     headers:
40 : suxen_drol 1521 C:\DX90SDK\Include
41 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses
42 : edgomez 1384
43 : suxen_drol 1521 C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Release
44 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug
45 : edgomez 1384 */
46 :    
47 : Isibaar 1896 //#define XVID_USE_TRAYICON
48 : edgomez 1384
49 :     #include <windows.h>
50 :    
51 :     #include <streams.h>
52 :     #include <initguid.h>
53 :     #include <olectl.h>
54 :     #if (1100 > _MSC_VER)
55 :     #include <olectlid.h>
56 :     #endif
57 :     #include <dvdmedia.h> // VIDEOINFOHEADER2
58 :    
59 : Isibaar 1896 #include <shellapi.h>
60 : edgomez 1384
61 : Isibaar 1896 #include <xvid.h> // Xvid API
62 :    
63 :     #include "resource.h"
64 :    
65 : edgomez 1384 #include "IXvidDecoder.h"
66 :     #include "CXvidDecoder.h"
67 :     #include "CAbout.h"
68 :     #include "config.h"
69 :     #include "debug.h"
70 :    
71 :     static bool USE_IYUV;
72 :     static bool USE_YV12;
73 :     static bool USE_YUY2;
74 :     static bool USE_YVYU;
75 :     static bool USE_UYVY;
76 :     static bool USE_RGB32;
77 :     static bool USE_RGB24;
78 :     static bool USE_RG555;
79 :     static bool USE_RG565;
80 :    
81 :     const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
82 :     {
83 :     { &MEDIATYPE_Video, &CLSID_XVID },
84 :     { &MEDIATYPE_Video, &CLSID_XVID_UC },
85 :     { &MEDIATYPE_Video, &CLSID_DIVX },
86 :     { &MEDIATYPE_Video, &CLSID_DIVX_UC },
87 :     { &MEDIATYPE_Video, &CLSID_DX50 },
88 :     { &MEDIATYPE_Video, &CLSID_DX50_UC },
89 :     { &MEDIATYPE_Video, &CLSID_MP4V },
90 : suxen_drol 1647 { &MEDIATYPE_Video, &CLSID_MP4V_UC },
91 : edgomez 1384 };
92 :    
93 :     const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
94 :     {
95 :     { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
96 :     };
97 :    
98 :    
99 :     const AMOVIESETUP_PIN psudPins[] =
100 :     {
101 :     {
102 :     L"Input", // String pin name
103 :     FALSE, // Is it rendered
104 :     FALSE, // Is it an output
105 :     FALSE, // Allowed none
106 :     FALSE, // Allowed many
107 :     &CLSID_NULL, // Connects to filter
108 :     L"Output", // Connects to pin
109 :     sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
110 :     &sudInputPinTypes[0] // The pin details
111 :     },
112 :     {
113 :     L"Output", // String pin name
114 :     FALSE, // Is it rendered
115 :     TRUE, // Is it an output
116 :     FALSE, // Allowed none
117 :     FALSE, // Allowed many
118 :     &CLSID_NULL, // Connects to filter
119 :     L"Input", // Connects to pin
120 :     sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
121 :     sudOutputPinTypes // The pin details
122 :     }
123 :     };
124 :    
125 :    
126 :     const AMOVIESETUP_FILTER sudXvidDecoder =
127 :     {
128 :     &CLSID_XVID, // Filter CLSID
129 :     XVID_NAME_L, // Filter name
130 :     MERIT_PREFERRED, // Its merit
131 :     sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins
132 :     psudPins // Pin details
133 :     };
134 :    
135 :    
136 :     // List of class IDs and creator functions for the class factory. This
137 :     // provides the link between the OLE entry point in the DLL and an object
138 :     // being created. The class factory will call the static CreateInstance
139 :    
140 :     CFactoryTemplate g_Templates[] =
141 :     {
142 :     {
143 :     XVID_NAME_L,
144 :     &CLSID_XVID,
145 :     CXvidDecoder::CreateInstance,
146 :     NULL,
147 :     &sudXvidDecoder
148 :     },
149 :     {
150 :     XVID_NAME_L L"About",
151 :     &CLSID_CABOUT,
152 :     CAbout::CreateInstance
153 :     }
154 :    
155 :     };
156 :    
157 :     /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */
158 :     int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);
159 :    
160 : Isibaar 1896 #ifdef XVID_USE_TRAYICON
161 :     extern HINSTANCE g_xvid_hInst;
162 : edgomez 1384
163 : Isibaar 1896 static int GUI_Page = 0;
164 :     extern "C" void CALLBACK Configure(HWND hWndParent, HINSTANCE hInstParent, LPSTR lpCmdLine, int nCmdShow );
165 :    
166 :     LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
167 :     {
168 :     switch ( uMsg )
169 :     {
170 :     case WM_ICONMESSAGE:
171 :     switch(lParam)
172 :     {
173 :     case WM_LBUTTONDBLCLK:
174 :     if (!GUI_Page) {
175 :     GUI_Page = 1;
176 :     Configure(hwnd, g_xvid_hInst, "", 1);
177 :     GUI_Page = 0;
178 :     }
179 :     break;
180 :     default:
181 :     return DefWindowProc(hwnd, uMsg, wParam, lParam);
182 :     };
183 :     break;
184 :    
185 :     default:
186 :     return DefWindowProc(hwnd, uMsg, wParam, lParam);
187 :     }
188 :    
189 :     return TRUE; /* ok */
190 :     }
191 :     #endif
192 :    
193 : edgomez 1384 STDAPI DllRegisterServer()
194 :     {
195 :     return AMovieDllRegisterServer2( TRUE );
196 :     }
197 :    
198 :    
199 :     STDAPI DllUnregisterServer()
200 :     {
201 :     return AMovieDllRegisterServer2( FALSE );
202 :     }
203 :    
204 :    
205 :     /* create instance */
206 :    
207 :     CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
208 :     {
209 :     CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr);
210 :     if (pNewObject == NULL)
211 :     {
212 :     *phr = E_OUTOFMEMORY;
213 :     }
214 :     return pNewObject;
215 :     }
216 :    
217 :    
218 :     /* query interfaces */
219 :    
220 :     STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
221 :     {
222 :     CheckPointer(ppv, E_POINTER);
223 :    
224 :     if (riid == IID_IXvidDecoder)
225 :     {
226 :     return GetInterface((IXvidDecoder *) this, ppv);
227 :     }
228 :    
229 :     if (riid == IID_ISpecifyPropertyPages)
230 :     {
231 :     return GetInterface((ISpecifyPropertyPages *) this, ppv);
232 :     }
233 :    
234 :     return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv);
235 :     }
236 :    
237 :    
238 :    
239 :     /* constructor */
240 :    
241 :     #define XVID_DLL_NAME "xvidcore.dll"
242 :    
243 :     CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
244 : Isibaar 1605 CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL)
245 : edgomez 1384 {
246 :     DPRINTF("Constructor");
247 :    
248 : Isibaar 1605 xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize...
249 :     xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here.
250 :    
251 : Isibaar 1896 #ifdef XVID_USE_TRAYICON
252 :     MSG_hwnd = NULL;
253 :     #endif
254 :    
255 : Isibaar 1605 LoadRegistryInfo();
256 :    
257 :     *phr = OpenLib();
258 :     }
259 :    
260 :     HRESULT CXvidDecoder::OpenLib()
261 :     {
262 :     DPRINTF("OpenLib");
263 :    
264 :     if (m_hdll != NULL)
265 :     return E_UNEXPECTED; // Seems, that library already opened.
266 :    
267 : edgomez 1384 xvid_gbl_init_t init;
268 :     memset(&init, 0, sizeof(init));
269 :     init.version = XVID_VERSION;
270 :    
271 :     m_hdll = LoadLibrary(XVID_DLL_NAME);
272 :     if (m_hdll == NULL) {
273 :     DPRINTF("dll load failed");
274 : syskin 1498 MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST);
275 : Isibaar 1605 return E_FAIL;
276 : edgomez 1384 }
277 :    
278 :     xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
279 :     if (xvid_global_func == NULL) {
280 : Isibaar 1605 FreeLibrary(m_hdll);
281 :     m_hdll = NULL;
282 : syskin 1498 MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST);
283 : Isibaar 1605 return E_FAIL;
284 : edgomez 1384 }
285 :    
286 :     xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
287 :     if (xvid_decore_func == NULL) {
288 : Isibaar 1605 xvid_global_func = NULL;
289 :     FreeLibrary(m_hdll);
290 :     m_hdll = NULL;
291 : syskin 1498 MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST);
292 : Isibaar 1605 return E_FAIL;
293 : edgomez 1384 }
294 :    
295 :     if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0)
296 :     {
297 : Isibaar 1605 xvid_global_func = NULL;
298 :     xvid_decore_func = NULL;
299 :     FreeLibrary(m_hdll);
300 :     m_hdll = NULL;
301 : syskin 1498 MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
302 : Isibaar 1605 return E_FAIL;
303 : edgomez 1384 }
304 :    
305 :     memset(&m_create, 0, sizeof(m_create));
306 :     m_create.version = XVID_VERSION;
307 :     m_create.handle = NULL;
308 :    
309 :     memset(&m_frame, 0, sizeof(m_frame));
310 :     m_frame.version = XVID_VERSION;
311 :    
312 :     USE_IYUV = false;
313 :     USE_YV12 = false;
314 :     USE_YUY2 = false;
315 :     USE_YVYU = false;
316 :     USE_UYVY = false;
317 :     USE_RGB32 = false;
318 :     USE_RGB24 = false;
319 :     USE_RG555 = false;
320 :     USE_RG565 = false;
321 :    
322 :     switch ( g_config.nForceColorspace )
323 :     {
324 :     case FORCE_NONE:
325 :     USE_IYUV = true;
326 :     USE_YV12 = true;
327 :     USE_YUY2 = true;
328 :     USE_YVYU = true;
329 :     USE_UYVY = true;
330 :     USE_RGB32 = true;
331 :     USE_RGB24 = true;
332 :     USE_RG555 = true;
333 :     USE_RG565 = true;
334 :     break;
335 :     case FORCE_YV12:
336 :     USE_IYUV = true;
337 :     USE_YV12 = true;
338 :     break;
339 :     case FORCE_YUY2:
340 :     USE_YUY2 = true;
341 :     break;
342 :     case FORCE_RGB24:
343 :     USE_RGB24 = true;
344 :     break;
345 :     case FORCE_RGB32:
346 :     USE_RGB32 = true;
347 :     break;
348 :     }
349 : syskin 1488
350 :     switch (g_config.aspect_ratio)
351 :     {
352 : syskin 1498 case 0:
353 :     case 1:
354 : syskin 1488 break;
355 : syskin 1498 case 2:
356 : syskin 1488 ar_x = 4;
357 :     ar_y = 3;
358 :     break;
359 : syskin 1498 case 3:
360 : syskin 1488 ar_x = 16;
361 :     ar_y = 9;
362 :     break;
363 : syskin 1498 case 4:
364 : syskin 1488 ar_x = 47;
365 :     ar_y = 20;
366 :     break;
367 :     }
368 : Isibaar 1605
369 :     return S_OK;
370 : edgomez 1384 }
371 :    
372 : syskin 1428 void CXvidDecoder::CloseLib()
373 : edgomez 1384 {
374 : Isibaar 1605 DPRINTF("CloseLib");
375 : edgomez 1384
376 : Isibaar 1605 if ((m_create.handle != NULL) && (xvid_decore_func != NULL))
377 :     {
378 : edgomez 1384 xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
379 :     m_create.handle = NULL;
380 :     }
381 :    
382 : syskin 1428 if (m_hdll != NULL) {
383 : edgomez 1384 FreeLibrary(m_hdll);
384 :     m_hdll = NULL;
385 :     }
386 : Isibaar 1605 xvid_decore_func = NULL;
387 :     xvid_global_func = NULL;
388 : edgomez 1384 }
389 :    
390 : syskin 1428 /* destructor */
391 : edgomez 1384
392 : syskin 1428 CXvidDecoder::~CXvidDecoder()
393 :     {
394 : Isibaar 1605 DPRINTF("Destructor");
395 : syskin 1428 CloseLib();
396 : Isibaar 1896
397 :     #ifdef XVID_USE_TRAYICON
398 :     if (MSG_hwnd != NULL) {
399 :     NOTIFYICONDATA nid;
400 :     nid.cbSize = sizeof(NOTIFYICONDATA);
401 :     nid.hWnd = MSG_hwnd;
402 :     nid.uID = 100;
403 :    
404 :     Shell_NotifyIcon(NIM_DELETE, &nid);
405 :    
406 :     DestroyWindow(MSG_hwnd);
407 :     MSG_hwnd = NULL;
408 :     }
409 :     #endif
410 : syskin 1428 }
411 : edgomez 1384
412 : syskin 1428
413 :    
414 : edgomez 1384 /* check input type */
415 :    
416 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
417 :     {
418 :     DPRINTF("CheckInputType");
419 :     BITMAPINFOHEADER * hdr;
420 : syskin 1498
421 :     ar_x = ar_y = 0;
422 : edgomez 1384
423 :     if (*mtIn->Type() != MEDIATYPE_Video)
424 :     {
425 :     DPRINTF("Error: Unknown Type");
426 : syskin 1428 CloseLib();
427 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
428 :     }
429 :    
430 : Isibaar 1605 if (m_hdll == NULL)
431 :     {
432 :     HRESULT hr = OpenLib();
433 :    
434 :     if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks.
435 :     return VFW_E_TYPE_NOT_ACCEPTED;
436 :     }
437 :    
438 : edgomez 1384 if (*mtIn->FormatType() == FORMAT_VideoInfo)
439 :     {
440 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
441 :     hdr = &vih->bmiHeader;
442 :     }
443 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
444 :     {
445 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
446 :     hdr = &vih2->bmiHeader;
447 : syskin 1498 if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
448 : syskin 1488 ar_x = vih2->dwPictAspectRatioX;
449 :     ar_y = vih2->dwPictAspectRatioY;
450 :     }
451 : edgomez 1384 DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
452 :     }
453 : suxen_drol 1647 else if (*mtIn->FormatType() == FORMAT_MPEG2Video) {
454 :     MPEG2VIDEOINFO * mpgvi = (MPEG2VIDEOINFO*)mtIn->Format();
455 :     VIDEOINFOHEADER2 * vih2 = &mpgvi->hdr;
456 :     hdr = &vih2->bmiHeader;
457 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
458 :     ar_x = vih2->dwPictAspectRatioX;
459 :     ar_y = vih2->dwPictAspectRatioY;
460 :     }
461 :     DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
462 :    
463 :     /* haali media splitter reports VOL information in the format header */
464 :    
465 :     if (mpgvi->cbSequenceHeader>0) {
466 :    
467 :     xvid_dec_stats_t stats;
468 :     memset(&stats, 0, sizeof(stats));
469 :     stats.version = XVID_VERSION;
470 :    
471 :     if (m_create.handle == NULL) {
472 :     if (xvid_decore_func == NULL)
473 :     return E_FAIL;
474 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) {
475 :     DPRINTF("*** XVID_DEC_CREATE error");
476 : Isibaar 1868 return E_FAIL;
477 : suxen_drol 1647 }
478 :     }
479 :    
480 :     m_frame.general = 0;
481 :     m_frame.bitstream = (void*)mpgvi->dwSequenceHeader;
482 :     m_frame.length = mpgvi->cbSequenceHeader;
483 :     m_frame.output.csp = XVID_CSP_NULL;
484 :    
485 : Isibaar 1868 int ret = 0;
486 :     if ((ret=xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats)) >= 0) {
487 : suxen_drol 1647 /* honour video dimensions reported in VOL header */
488 :     if (stats.type == XVID_TYPE_VOL) {
489 :     hdr->biWidth = stats.data.vol.width;
490 :     hdr->biHeight = stats.data.vol.height;
491 :     }
492 :     }
493 : Isibaar 1868 if (ret == XVID_ERR_MEMORY) return E_FAIL;
494 : suxen_drol 1647 }
495 :     }
496 : edgomez 1384 else
497 :     {
498 :     DPRINTF("Error: Unknown FormatType");
499 : syskin 1428 CloseLib();
500 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
501 :     }
502 :    
503 :     if (hdr->biHeight < 0)
504 :     {
505 :     DPRINTF("colorspace: inverted input format not supported");
506 :     }
507 :    
508 :     m_create.width = hdr->biWidth;
509 :     m_create.height = hdr->biHeight;
510 :    
511 :     switch(hdr->biCompression)
512 :     {
513 : suxen_drol 1647 case FOURCC_mp4v:
514 : edgomez 1384 case FOURCC_MP4V:
515 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
516 :     CloseLib();
517 :     return VFW_E_TYPE_NOT_ACCEPTED;
518 :     }
519 : edgomez 1384 break;
520 :     case FOURCC_DIVX :
521 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
522 :     CloseLib();
523 :     return VFW_E_TYPE_NOT_ACCEPTED;
524 :     }
525 : edgomez 1384 break;
526 :     case FOURCC_DX50 :
527 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DX50)) {
528 :     CloseLib();
529 :     return VFW_E_TYPE_NOT_ACCEPTED;
530 :     }
531 : edgomez 1384 case FOURCC_XVID :
532 :     break;
533 :    
534 :    
535 :     default :
536 :     DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
537 :     hdr->biCompression,
538 :     (hdr->biCompression)&0xff,
539 :     (hdr->biCompression>>8)&0xff,
540 :     (hdr->biCompression>>16)&0xff,
541 :     (hdr->biCompression>>24)&0xff);
542 : syskin 1428 CloseLib();
543 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
544 :     }
545 : Isibaar 1890
546 :     m_create.fourcc = hdr->biCompression;
547 :    
548 : edgomez 1384 return S_OK;
549 :     }
550 :    
551 :    
552 :     /* get list of supported output colorspaces */
553 :    
554 :    
555 :     HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
556 :     {
557 :     BITMAPINFOHEADER * bmih;
558 :     DPRINTF("GetMediaType");
559 :    
560 :     if (m_pInput->IsConnected() == FALSE)
561 :     {
562 :     return E_UNEXPECTED;
563 :     }
564 :    
565 :     if (!g_config.videoinfo_compat) {
566 :     VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
567 :     if (vih == NULL) return E_OUTOFMEMORY;
568 :    
569 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER2));
570 :     bmih = &(vih->bmiHeader);
571 :     mtOut->SetFormatType(&FORMAT_VideoInfo2);
572 :    
573 :     if (ar_x != 0 && ar_y != 0) {
574 :     vih->dwPictAspectRatioX = ar_x;
575 :     vih->dwPictAspectRatioY = ar_y;
576 : syskin 1498 forced_ar = true;
577 : edgomez 1384 } else { // just to be safe
578 :     vih->dwPictAspectRatioX = m_create.width;
579 :     vih->dwPictAspectRatioY = abs(m_create.height);
580 : syskin 1498 forced_ar = false;
581 :     }
582 : edgomez 1384 } else {
583 :    
584 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
585 :     if (vih == NULL) return E_OUTOFMEMORY;
586 :    
587 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
588 :     bmih = &(vih->bmiHeader);
589 :     mtOut->SetFormatType(&FORMAT_VideoInfo);
590 :     }
591 :    
592 :     bmih->biSize = sizeof(BITMAPINFOHEADER);
593 :     bmih->biWidth = m_create.width;
594 :     bmih->biHeight = m_create.height;
595 :     bmih->biPlanes = 1;
596 :    
597 :     if (iPosition < 0) return E_INVALIDARG;
598 :    
599 :     switch(iPosition)
600 :     {
601 :    
602 :     case 0:
603 :     if ( USE_YUY2 )
604 :     {
605 :     bmih->biCompression = MEDIASUBTYPE_YUY2.Data1;
606 :     bmih->biBitCount = 16;
607 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
608 :     break;
609 :     }
610 :     case 1 :
611 :     if ( USE_YVYU )
612 :     {
613 :     bmih->biCompression = MEDIASUBTYPE_YVYU.Data1;
614 :     bmih->biBitCount = 16;
615 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
616 :     break;
617 :     }
618 :     case 2 :
619 :     if ( USE_UYVY )
620 :     {
621 :     bmih->biCompression = MEDIASUBTYPE_UYVY.Data1;
622 :     bmih->biBitCount = 16;
623 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
624 :     break;
625 :     }
626 :     case 3 :
627 :     if ( USE_IYUV )
628 :     {
629 :     bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
630 :     bmih->biBitCount = 12;
631 :     mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
632 :     break;
633 :     }
634 :     case 4 :
635 :     if ( USE_YV12 )
636 :     {
637 :     bmih->biCompression = MEDIASUBTYPE_YV12.Data1;
638 :     bmih->biBitCount = 12;
639 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
640 :     break;
641 :     }
642 :     case 5 :
643 :     if ( USE_RGB32 )
644 :     {
645 :     bmih->biCompression = BI_RGB;
646 :     bmih->biBitCount = 32;
647 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
648 :     break;
649 :     }
650 :     case 6 :
651 :     if ( USE_RGB24 )
652 :     {
653 :     bmih->biCompression = BI_RGB;
654 :     bmih->biBitCount = 24;
655 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
656 :     break;
657 :     }
658 :     case 7 :
659 :     if ( USE_RG555 )
660 :     {
661 :     bmih->biCompression = BI_RGB;
662 :     bmih->biBitCount = 16;
663 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
664 :     break;
665 :     }
666 :     case 8 :
667 :     if ( USE_RG565 )
668 :     {
669 :     bmih->biCompression = BI_RGB;
670 :     bmih->biBitCount = 16;
671 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
672 :     break;
673 :     }
674 :     default :
675 :     return VFW_S_NO_MORE_ITEMS;
676 :     }
677 :    
678 :     bmih->biSizeImage = GetBitmapSize(bmih);
679 :    
680 :     mtOut->SetType(&MEDIATYPE_Video);
681 :     mtOut->SetTemporalCompression(FALSE);
682 :     mtOut->SetSampleSize(bmih->biSizeImage);
683 :    
684 :     return S_OK;
685 :     }
686 :    
687 :    
688 :     /* (internal function) change colorspace */
689 : suxen_drol 1558 #define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3)
690 : edgomez 1384
691 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
692 :     {
693 : suxen_drol 1558 DWORD biWidth;
694 :    
695 : edgomez 1384 if (formattype == FORMAT_VideoInfo)
696 :     {
697 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
698 : suxen_drol 1558 biWidth = vih->bmiHeader.biWidth;
699 :     m_frame.output.stride[0] = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);
700 : edgomez 1384 rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
701 :     }
702 :     else if (formattype == FORMAT_VideoInfo2)
703 :     {
704 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
705 : suxen_drol 1558 biWidth = vih2->bmiHeader.biWidth;
706 :     m_frame.output.stride[0] = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);
707 : edgomez 1384 rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
708 :     }
709 :     else
710 :     {
711 :     return S_FALSE;
712 :     }
713 :    
714 :     if (subtype == CLSID_MEDIASUBTYPE_IYUV)
715 :     {
716 :     DPRINTF("IYUV");
717 :     rgb_flip = 0;
718 :     m_frame.output.csp = XVID_CSP_I420;
719 : suxen_drol 1558 m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
720 : edgomez 1384 }
721 :     else if (subtype == MEDIASUBTYPE_YV12)
722 :     {
723 :     DPRINTF("YV12");
724 :     rgb_flip = 0;
725 :     m_frame.output.csp = XVID_CSP_YV12;
726 : suxen_drol 1558 m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
727 : edgomez 1384 }
728 :     else if (subtype == MEDIASUBTYPE_YUY2)
729 :     {
730 :     DPRINTF("YUY2");
731 :     rgb_flip = 0;
732 :     m_frame.output.csp = XVID_CSP_YUY2;
733 :     }
734 :     else if (subtype == MEDIASUBTYPE_YVYU)
735 :     {
736 :     DPRINTF("YVYU");
737 :     rgb_flip = 0;
738 :     m_frame.output.csp = XVID_CSP_YVYU;
739 :     }
740 :     else if (subtype == MEDIASUBTYPE_UYVY)
741 :     {
742 :     DPRINTF("UYVY");
743 :     rgb_flip = 0;
744 :     m_frame.output.csp = XVID_CSP_UYVY;
745 :     }
746 :     else if (subtype == MEDIASUBTYPE_RGB32)
747 :     {
748 :     DPRINTF("RGB32");
749 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
750 :     }
751 :     else if (subtype == MEDIASUBTYPE_RGB24)
752 :     {
753 :     DPRINTF("RGB24");
754 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
755 :     }
756 :     else if (subtype == MEDIASUBTYPE_RGB555)
757 :     {
758 :     DPRINTF("RGB555");
759 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
760 :     }
761 :     else if (subtype == MEDIASUBTYPE_RGB565)
762 :     {
763 :     DPRINTF("RGB565");
764 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
765 :     }
766 :     else if (subtype == GUID_NULL)
767 :     {
768 :     m_frame.output.csp = XVID_CSP_NULL;
769 :     }
770 :     else
771 :     {
772 :     return S_FALSE;
773 :     }
774 :    
775 :     return S_OK;
776 :     }
777 :    
778 :    
779 :     /* set output colorspace */
780 :    
781 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
782 :     {
783 :     DPRINTF("SetMediaType");
784 :    
785 :     if (direction == PINDIR_OUTPUT)
786 :     {
787 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
788 :     }
789 :    
790 :     return S_OK;
791 :     }
792 :    
793 :    
794 :     /* check input<->output compatiblity */
795 :    
796 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
797 :     {
798 :     DPRINTF("CheckTransform");
799 : Isibaar 1896
800 : edgomez 1384 return S_OK;
801 :     }
802 :    
803 : Isibaar 1896 /* input/output pin connection complete */
804 : edgomez 1384
805 : Isibaar 1896 HRESULT CXvidDecoder::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
806 :     {
807 :     DPRINTF("CompleteConnect");
808 :    
809 :     #ifdef XVID_USE_TRAYICON
810 :     if ((direction == PINDIR_OUTPUT) && (MSG_hwnd == NULL))
811 :     {
812 :     WNDCLASSEX wc;
813 :    
814 :     wc.cbSize = sizeof(WNDCLASSEX);
815 :     wc.lpfnWndProc = msg_proc;
816 :     wc.style = CS_HREDRAW | CS_VREDRAW;
817 :     wc.cbWndExtra = 0;
818 :     wc.cbClsExtra = 0;
819 :     wc.hInstance = (HINSTANCE) g_xvid_hInst;
820 :     wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH);
821 :     wc.lpszMenuName = NULL;
822 :     wc.lpszClassName = "XVID_MSG_WINDOW";
823 :     wc.hIcon = NULL;
824 :     wc.hIconSm = NULL;
825 :     wc.hCursor = NULL;
826 :     RegisterClassEx(&wc);
827 :    
828 :     MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,
829 :     CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE) g_xvid_hInst, NULL);
830 :    
831 :     /* display the tray icon */
832 :     NOTIFYICONDATA nid;
833 :    
834 :     nid.cbSize = sizeof(NOTIFYICONDATA);
835 :     nid.hWnd = MSG_hwnd;
836 :     nid.uID = 100;
837 :     nid.uVersion = NOTIFYICON_VERSION;
838 :     nid.uCallbackMessage = WM_ICONMESSAGE;
839 :     nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
840 :     strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
841 :     nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
842 :    
843 :     Shell_NotifyIcon(NIM_ADD, &nid);
844 :     }
845 :     #endif
846 :    
847 :     return S_OK;
848 :     }
849 :    
850 :     /* input/output pin disconnected */
851 :     HRESULT CXvidDecoder::BreakConnect(PIN_DIRECTION direction)
852 :     {
853 :     DPRINTF("BreakConnect");
854 :    
855 :     #ifdef XVID_USE_TRAYICON
856 :     if ((direction == PINDIR_OUTPUT) && (MSG_hwnd != NULL)) {
857 :     NOTIFYICONDATA nid;
858 :    
859 :     nid.cbSize = sizeof(NOTIFYICONDATA);
860 :     nid.hWnd = MSG_hwnd;
861 :     nid.uID = 100;
862 :     nid.uVersion = NOTIFYICON_VERSION;
863 :    
864 :     if(Shell_NotifyIcon(NIM_DELETE, &nid) == TRUE) {
865 :     DestroyWindow(MSG_hwnd);
866 :     MSG_hwnd = NULL;
867 :     }
868 :     }
869 :     #endif
870 :    
871 :     return S_OK;
872 :     }
873 :    
874 : edgomez 1384 /* alloc output buffer */
875 :    
876 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
877 :     {
878 :     DPRINTF("DecideBufferSize");
879 :     HRESULT result;
880 :     ALLOCATOR_PROPERTIES ppropActual;
881 :    
882 :     if (m_pInput->IsConnected() == FALSE)
883 :     {
884 :     return E_UNEXPECTED;
885 :     }
886 :    
887 :     ppropInputRequest->cBuffers = 1;
888 :     ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
889 :     // cbAlign causes problems with the resize filter */
890 :     // ppropInputRequest->cbAlign = 16;
891 :     ppropInputRequest->cbPrefix = 0;
892 :    
893 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
894 :     if (result != S_OK)
895 :     {
896 :     return result;
897 :     }
898 :    
899 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
900 :     {
901 :     return E_FAIL;
902 :     }
903 :    
904 :     return S_OK;
905 :     }
906 :    
907 :    
908 :     /* decode frame */
909 :    
910 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
911 :     {
912 :     DPRINTF("Transform");
913 :     xvid_dec_stats_t stats;
914 :     int length;
915 :    
916 :     memset(&stats, 0, sizeof(stats));
917 :     stats.version = XVID_VERSION;
918 :    
919 :     if (m_create.handle == NULL)
920 :     {
921 : Isibaar 1605 if (xvid_decore_func == NULL)
922 :     return E_FAIL;
923 :    
924 : edgomez 1384 if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
925 :     {
926 :     DPRINTF("*** XVID_DEC_CREATE error");
927 : Isibaar 1868 return E_FAIL;
928 : edgomez 1384 }
929 :     }
930 :    
931 :     AM_MEDIA_TYPE * mtOut;
932 :     pOut->GetMediaType(&mtOut);
933 :     if (mtOut != NULL)
934 :     {
935 :     HRESULT result;
936 :    
937 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
938 :     DeleteMediaType(mtOut);
939 :    
940 :     if (result != S_OK)
941 :     {
942 :     DPRINTF("*** ChangeColorspace error");
943 :     return result;
944 :     }
945 :     }
946 :    
947 :     m_frame.length = pIn->GetActualDataLength();
948 :     if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
949 :     {
950 :     return S_FALSE;
951 :     }
952 :    
953 :     if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
954 :     {
955 :     return S_FALSE;
956 :     }
957 :    
958 :     m_frame.general = XVID_LOWDELAY;
959 :    
960 :     if (pIn->IsDiscontinuity() == S_OK)
961 : syskin 1427 m_frame.general |= XVID_DISCONTINUITY;
962 : edgomez 1384
963 :     if (g_config.nDeblock_Y)
964 :     m_frame.general |= XVID_DEBLOCKY;
965 :    
966 :     if (g_config.nDeblock_UV)
967 :     m_frame.general |= XVID_DEBLOCKUV;
968 : syskin 1437
969 :     if (g_config.nDering_Y)
970 :     m_frame.general |= XVID_DERINGY;
971 :    
972 :     if (g_config.nDering_UV)
973 :     m_frame.general |= XVID_DERINGUV;
974 :    
975 : edgomez 1384 if (g_config.nFilmEffect)
976 :     m_frame.general |= XVID_FILMEFFECT;
977 :    
978 : suxen_drol 1397 m_frame.brightness = g_config.nBrightness;
979 :    
980 : edgomez 1384 m_frame.output.csp &= ~XVID_CSP_VFLIP;
981 :     m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
982 :    
983 : Isibaar 1605 // Paranoid check.
984 :     if (xvid_decore_func == NULL)
985 :     return E_FAIL;
986 : syskin 1498
987 :    
988 :    
989 : edgomez 1384 repeat :
990 :    
991 :     if (pIn->IsPreroll() != S_OK)
992 :     {
993 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
994 : Isibaar 1868
995 :     if (length == XVID_ERR_MEMORY)
996 :     return E_FAIL;
997 :     else if (length < 0)
998 : edgomez 1384 {
999 :     DPRINTF("*** XVID_DEC_DECODE");
1000 :     return S_FALSE;
1001 : syskin 1498 } else
1002 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) {
1003 : suxen_drol 1633
1004 :     if (stats.type != XVID_TYPE_NOTHING) { /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */
1005 : syskin 1498 // inspired by minolta! works for VMR 7 + 9
1006 :     IMediaSample2 *pOut2 = NULL;
1007 :     AM_SAMPLE2_PROPERTIES outProp2;
1008 :     if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) &&
1009 :     SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2)))
1010 :     {
1011 :     CMediaType mtOut2 = m_pOutput->CurrentMediaType();
1012 :     VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();
1013 : suxen_drol 1502
1014 :     if (*mtOut2.FormatType() == FORMAT_VideoInfo2 &&
1015 :     vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)
1016 : syskin 1498 {
1017 :     vihOut2->dwPictAspectRatioX = ar_x;
1018 :     vihOut2->dwPictAspectRatioY = ar_y;
1019 :     pOut2->SetMediaType(&mtOut2);
1020 :     m_pOutput->SetMediaType(&mtOut2);
1021 :     }
1022 :     pOut2->Release();
1023 :     }
1024 : suxen_drol 1633 }
1025 : edgomez 1384 }
1026 :     }
1027 :     else
1028 :     { /* Preroll frame - won't be displayed */
1029 :     int tmp = m_frame.output.csp;
1030 :     int tmp_gen = m_frame.general;
1031 :    
1032 :     m_frame.output.csp = XVID_CSP_NULL;
1033 :    
1034 :     /* Disable postprocessing to speed-up seeking */
1035 :     m_frame.general &= ~XVID_DEBLOCKY;
1036 :     m_frame.general &= ~XVID_DEBLOCKUV;
1037 : Isibaar 1605 /*m_frame.general &= ~XVID_DERING;*/
1038 : edgomez 1384 m_frame.general &= ~XVID_FILMEFFECT;
1039 :    
1040 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
1041 : Isibaar 1868 if (length == XVID_ERR_MEMORY)
1042 :     return E_FAIL;
1043 :     else if (length < 0)
1044 : edgomez 1384 {
1045 :     DPRINTF("*** XVID_DEC_DECODE");
1046 :     return S_FALSE;
1047 :     }
1048 :    
1049 :     m_frame.output.csp = tmp;
1050 :     m_frame.general = tmp_gen;
1051 :     }
1052 :    
1053 :     if (stats.type == XVID_TYPE_NOTHING && length > 0) {
1054 : edgomez 1432 DPRINTF(" B-Frame decoder lag");
1055 : edgomez 1384 return S_FALSE;
1056 :     }
1057 :    
1058 :    
1059 :     if (stats.type == XVID_TYPE_VOL)
1060 :     {
1061 :     if (stats.data.vol.width != m_create.width ||
1062 :     stats.data.vol.height != m_create.height)
1063 :     {
1064 :     DPRINTF("TODO: auto-resize");
1065 :     return S_FALSE;
1066 :     }
1067 : syskin 1498
1068 : edgomez 1384 pOut->SetSyncPoint(TRUE);
1069 :    
1070 : syskin 1498 if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */
1071 :     int par_x, par_y;
1072 :     if (stats.data.vol.par == XVID_PAR_EXT) {
1073 :     par_x = stats.data.vol.par_width;
1074 :     par_y = stats.data.vol.par_height;
1075 :     } else {
1076 : syskin 1529 par_x = PARS[stats.data.vol.par-1][0];
1077 :     par_y = PARS[stats.data.vol.par-1][1];
1078 : syskin 1498 }
1079 :    
1080 :     ar_x = par_x * stats.data.vol.width;
1081 :     ar_y = par_y * stats.data.vol.height;
1082 :     }
1083 :    
1084 : edgomez 1384 m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
1085 :     m_frame.length -= length;
1086 :     goto repeat;
1087 :     }
1088 :    
1089 :     if (pIn->IsPreroll() == S_OK) {
1090 :     return S_FALSE;
1091 :     }
1092 :    
1093 :     return S_OK;
1094 :     }
1095 :    
1096 :    
1097 :     /* get property page list */
1098 :    
1099 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
1100 :     {
1101 :     DPRINTF("GetPages");
1102 :    
1103 :     pPages->cElems = 1;
1104 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
1105 :     if (pPages->pElems == NULL)
1106 :     {
1107 :     return E_OUTOFMEMORY;
1108 :     }
1109 :     pPages->pElems[0] = CLSID_CABOUT;
1110 :    
1111 :     return S_OK;
1112 :     }
1113 :    
1114 :    
1115 :     /* cleanup pages */
1116 :    
1117 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
1118 :     {
1119 :     DPRINTF("FreePages");
1120 :     CoTaskMemFree(pPages->pElems);
1121 :     return S_OK;
1122 :     }

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