[svn] / trunk / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1605 - (view) (download)

1 : edgomez 1384 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - XviD Decoder part of the DShow Filter -
5 :     *
6 :     * Copyright(C) 2002-2004 Peter Ross <pross@xvid.org>
7 :     *
8 :     * This program is free software ; you can redistribute it and/or modify
9 :     * it under the terms of the GNU General Public License as published by
10 :     * the Free Software Foundation ; either version 2 of the License, or
11 :     * (at your option) any later version.
12 :     *
13 :     * This program is distributed in the hope that it will be useful,
14 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     * GNU General Public License for more details.
17 :     *
18 :     * You should have received a copy of the GNU General Public License
19 :     * along with this program ; if not, write to the Free Software
20 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 :     *
22 : Isibaar 1605 * $Id: CXvidDecoder.cpp,v 1.14 2005-03-14 01:18:20 Isibaar Exp $
23 : edgomez 1384 *
24 :     ****************************************************************************/
25 :    
26 :     /****************************************************************************
27 :     *
28 :     * 2003/12/11 - added some additional options, mainly to make the deblocking
29 :     * code from xvidcore available. Most of the new code is taken
30 :     * from Nic's dshow filter, (C) Nic, http://nic.dnsalias.com
31 :     *
32 :     ****************************************************************************/
33 :    
34 :     /*
35 :     this requires the directx sdk
36 :     place these paths at the top of the Tools|Options|Directories list
37 :    
38 :     headers:
39 : suxen_drol 1521 C:\DX90SDK\Include
40 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses
41 : edgomez 1384
42 : suxen_drol 1521 C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Release
43 :     C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug
44 : edgomez 1384 */
45 :    
46 :    
47 :    
48 :     #include <windows.h>
49 :    
50 :     #include <streams.h>
51 :     #include <initguid.h>
52 :     #include <olectl.h>
53 :     #if (1100 > _MSC_VER)
54 :     #include <olectlid.h>
55 :     #endif
56 :     #include <dvdmedia.h> // VIDEOINFOHEADER2
57 :    
58 :     #include <xvid.h> // XviD API
59 :    
60 :     #include "IXvidDecoder.h"
61 :     #include "CXvidDecoder.h"
62 :     #include "CAbout.h"
63 :     #include "config.h"
64 :     #include "debug.h"
65 :    
66 :     static bool USE_IYUV;
67 :     static bool USE_YV12;
68 :     static bool USE_YUY2;
69 :     static bool USE_YVYU;
70 :     static bool USE_UYVY;
71 :     static bool USE_RGB32;
72 :     static bool USE_RGB24;
73 :     static bool USE_RG555;
74 :     static bool USE_RG565;
75 :    
76 :     const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
77 :     {
78 :     { &MEDIATYPE_Video, &CLSID_XVID },
79 :     { &MEDIATYPE_Video, &CLSID_XVID_UC },
80 :     { &MEDIATYPE_Video, &CLSID_DIVX },
81 :     { &MEDIATYPE_Video, &CLSID_DIVX_UC },
82 :     { &MEDIATYPE_Video, &CLSID_DX50 },
83 :     { &MEDIATYPE_Video, &CLSID_DX50_UC },
84 :     { &MEDIATYPE_Video, &CLSID_MP4V },
85 :     };
86 :    
87 :     const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
88 :     {
89 :     { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
90 :     };
91 :    
92 :    
93 :     const AMOVIESETUP_PIN psudPins[] =
94 :     {
95 :     {
96 :     L"Input", // String pin name
97 :     FALSE, // Is it rendered
98 :     FALSE, // Is it an output
99 :     FALSE, // Allowed none
100 :     FALSE, // Allowed many
101 :     &CLSID_NULL, // Connects to filter
102 :     L"Output", // Connects to pin
103 :     sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
104 :     &sudInputPinTypes[0] // The pin details
105 :     },
106 :     {
107 :     L"Output", // String pin name
108 :     FALSE, // Is it rendered
109 :     TRUE, // Is it an output
110 :     FALSE, // Allowed none
111 :     FALSE, // Allowed many
112 :     &CLSID_NULL, // Connects to filter
113 :     L"Input", // Connects to pin
114 :     sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
115 :     sudOutputPinTypes // The pin details
116 :     }
117 :     };
118 :    
119 :    
120 :     const AMOVIESETUP_FILTER sudXvidDecoder =
121 :     {
122 :     &CLSID_XVID, // Filter CLSID
123 :     XVID_NAME_L, // Filter name
124 :     MERIT_PREFERRED, // Its merit
125 :     sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins
126 :     psudPins // Pin details
127 :     };
128 :    
129 :    
130 :     // List of class IDs and creator functions for the class factory. This
131 :     // provides the link between the OLE entry point in the DLL and an object
132 :     // being created. The class factory will call the static CreateInstance
133 :    
134 :     CFactoryTemplate g_Templates[] =
135 :     {
136 :     {
137 :     XVID_NAME_L,
138 :     &CLSID_XVID,
139 :     CXvidDecoder::CreateInstance,
140 :     NULL,
141 :     &sudXvidDecoder
142 :     },
143 :     {
144 :     XVID_NAME_L L"About",
145 :     &CLSID_CABOUT,
146 :     CAbout::CreateInstance
147 :     }
148 :    
149 :     };
150 :    
151 :    
152 :     /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */
153 :     int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);
154 :    
155 :    
156 :     STDAPI DllRegisterServer()
157 :     {
158 :     return AMovieDllRegisterServer2( TRUE );
159 :     }
160 :    
161 :    
162 :     STDAPI DllUnregisterServer()
163 :     {
164 :     return AMovieDllRegisterServer2( FALSE );
165 :     }
166 :    
167 :    
168 :     /* create instance */
169 :    
170 :     CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
171 :     {
172 :     CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr);
173 :     if (pNewObject == NULL)
174 :     {
175 :     *phr = E_OUTOFMEMORY;
176 :     }
177 :     return pNewObject;
178 :     }
179 :    
180 :    
181 :     /* query interfaces */
182 :    
183 :     STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
184 :     {
185 :     CheckPointer(ppv, E_POINTER);
186 :    
187 :     if (riid == IID_IXvidDecoder)
188 :     {
189 :     return GetInterface((IXvidDecoder *) this, ppv);
190 :     }
191 :    
192 :     if (riid == IID_ISpecifyPropertyPages)
193 :     {
194 :     return GetInterface((ISpecifyPropertyPages *) this, ppv);
195 :     }
196 :    
197 :     return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv);
198 :     }
199 :    
200 :    
201 :    
202 :     /* constructor */
203 :    
204 :     #define XVID_DLL_NAME "xvidcore.dll"
205 :    
206 :     CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
207 : Isibaar 1605 CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL)
208 : edgomez 1384 {
209 :     DPRINTF("Constructor");
210 :    
211 : Isibaar 1605 xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize...
212 :     xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here.
213 :    
214 :     LoadRegistryInfo();
215 :    
216 :     *phr = OpenLib();
217 :     }
218 :    
219 :     HRESULT CXvidDecoder::OpenLib()
220 :     {
221 :     DPRINTF("OpenLib");
222 :    
223 :     if (m_hdll != NULL)
224 :     return E_UNEXPECTED; // Seems, that library already opened.
225 :    
226 : edgomez 1384 xvid_gbl_init_t init;
227 :     memset(&init, 0, sizeof(init));
228 :     init.version = XVID_VERSION;
229 :    
230 :     m_hdll = LoadLibrary(XVID_DLL_NAME);
231 :     if (m_hdll == NULL) {
232 :     DPRINTF("dll load failed");
233 : syskin 1498 MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST);
234 : Isibaar 1605 return E_FAIL;
235 : edgomez 1384 }
236 :    
237 :     xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
238 :     if (xvid_global_func == NULL) {
239 : Isibaar 1605 FreeLibrary(m_hdll);
240 :     m_hdll = NULL;
241 : syskin 1498 MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST);
242 : Isibaar 1605 return E_FAIL;
243 : edgomez 1384 }
244 :    
245 :     xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
246 :     if (xvid_decore_func == NULL) {
247 : Isibaar 1605 xvid_global_func = NULL;
248 :     FreeLibrary(m_hdll);
249 :     m_hdll = NULL;
250 : syskin 1498 MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST);
251 : Isibaar 1605 return E_FAIL;
252 : edgomez 1384 }
253 :    
254 :     if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0)
255 :     {
256 : Isibaar 1605 xvid_global_func = NULL;
257 :     xvid_decore_func = NULL;
258 :     FreeLibrary(m_hdll);
259 :     m_hdll = NULL;
260 : syskin 1498 MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
261 : Isibaar 1605 return E_FAIL;
262 : edgomez 1384 }
263 :    
264 :     memset(&m_create, 0, sizeof(m_create));
265 :     m_create.version = XVID_VERSION;
266 :     m_create.handle = NULL;
267 :    
268 :     memset(&m_frame, 0, sizeof(m_frame));
269 :     m_frame.version = XVID_VERSION;
270 :    
271 :     USE_IYUV = false;
272 :     USE_YV12 = false;
273 :     USE_YUY2 = false;
274 :     USE_YVYU = false;
275 :     USE_UYVY = false;
276 :     USE_RGB32 = false;
277 :     USE_RGB24 = false;
278 :     USE_RG555 = false;
279 :     USE_RG565 = false;
280 :    
281 :     switch ( g_config.nForceColorspace )
282 :     {
283 :     case FORCE_NONE:
284 :     USE_IYUV = true;
285 :     USE_YV12 = true;
286 :     USE_YUY2 = true;
287 :     USE_YVYU = true;
288 :     USE_UYVY = true;
289 :     USE_RGB32 = true;
290 :     USE_RGB24 = true;
291 :     USE_RG555 = true;
292 :     USE_RG565 = true;
293 :     break;
294 :     case FORCE_YV12:
295 :     USE_IYUV = true;
296 :     USE_YV12 = true;
297 :     break;
298 :     case FORCE_YUY2:
299 :     USE_YUY2 = true;
300 :     break;
301 :     case FORCE_RGB24:
302 :     USE_RGB24 = true;
303 :     break;
304 :     case FORCE_RGB32:
305 :     USE_RGB32 = true;
306 :     break;
307 :     }
308 : syskin 1488
309 :     switch (g_config.aspect_ratio)
310 :     {
311 : syskin 1498 case 0:
312 :     case 1:
313 : syskin 1488 break;
314 : syskin 1498 case 2:
315 : syskin 1488 ar_x = 4;
316 :     ar_y = 3;
317 :     break;
318 : syskin 1498 case 3:
319 : syskin 1488 ar_x = 16;
320 :     ar_y = 9;
321 :     break;
322 : syskin 1498 case 4:
323 : syskin 1488 ar_x = 47;
324 :     ar_y = 20;
325 :     break;
326 :     }
327 : Isibaar 1605
328 :     return S_OK;
329 : edgomez 1384 }
330 :    
331 : syskin 1428 void CXvidDecoder::CloseLib()
332 : edgomez 1384 {
333 : Isibaar 1605 DPRINTF("CloseLib");
334 : edgomez 1384
335 : Isibaar 1605 if ((m_create.handle != NULL) && (xvid_decore_func != NULL))
336 :     {
337 : edgomez 1384 xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
338 :     m_create.handle = NULL;
339 :     }
340 :    
341 : syskin 1428 if (m_hdll != NULL) {
342 : edgomez 1384 FreeLibrary(m_hdll);
343 :     m_hdll = NULL;
344 :     }
345 : Isibaar 1605 xvid_decore_func = NULL;
346 :     xvid_global_func = NULL;
347 : edgomez 1384 }
348 :    
349 : syskin 1428 /* destructor */
350 : edgomez 1384
351 : syskin 1428 CXvidDecoder::~CXvidDecoder()
352 :     {
353 : Isibaar 1605 DPRINTF("Destructor");
354 : syskin 1428 CloseLib();
355 :     }
356 : edgomez 1384
357 : syskin 1428
358 :    
359 : edgomez 1384 /* check input type */
360 :    
361 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
362 :     {
363 :     DPRINTF("CheckInputType");
364 :     BITMAPINFOHEADER * hdr;
365 : syskin 1498
366 :     ar_x = ar_y = 0;
367 : edgomez 1384
368 :     if (*mtIn->Type() != MEDIATYPE_Video)
369 :     {
370 :     DPRINTF("Error: Unknown Type");
371 : syskin 1428 CloseLib();
372 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
373 :     }
374 :    
375 : Isibaar 1605 if (m_hdll == NULL)
376 :     {
377 :     HRESULT hr = OpenLib();
378 :    
379 :     if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks.
380 :     return VFW_E_TYPE_NOT_ACCEPTED;
381 :     }
382 :    
383 : edgomez 1384 if (*mtIn->FormatType() == FORMAT_VideoInfo)
384 :     {
385 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
386 :     hdr = &vih->bmiHeader;
387 :     }
388 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
389 :     {
390 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
391 :     hdr = &vih2->bmiHeader;
392 : syskin 1498 if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) {
393 : syskin 1488 ar_x = vih2->dwPictAspectRatioX;
394 :     ar_y = vih2->dwPictAspectRatioY;
395 :     }
396 : edgomez 1384 DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
397 :     }
398 :     else
399 :     {
400 :     DPRINTF("Error: Unknown FormatType");
401 : syskin 1428 CloseLib();
402 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
403 :     }
404 :    
405 :     if (hdr->biHeight < 0)
406 :     {
407 :     DPRINTF("colorspace: inverted input format not supported");
408 :     }
409 :    
410 :     m_create.width = hdr->biWidth;
411 :     m_create.height = hdr->biHeight;
412 :    
413 :     switch(hdr->biCompression)
414 :     {
415 :    
416 :     case FOURCC_MP4V:
417 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
418 :     CloseLib();
419 :     return VFW_E_TYPE_NOT_ACCEPTED;
420 :     }
421 : edgomez 1384 break;
422 :     case FOURCC_DIVX :
423 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
424 :     CloseLib();
425 :     return VFW_E_TYPE_NOT_ACCEPTED;
426 :     }
427 : edgomez 1384 break;
428 :     case FOURCC_DX50 :
429 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DX50)) {
430 :     CloseLib();
431 :     return VFW_E_TYPE_NOT_ACCEPTED;
432 :     }
433 : edgomez 1384 case FOURCC_XVID :
434 :     break;
435 :    
436 :    
437 :     default :
438 :     DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
439 :     hdr->biCompression,
440 :     (hdr->biCompression)&0xff,
441 :     (hdr->biCompression>>8)&0xff,
442 :     (hdr->biCompression>>16)&0xff,
443 :     (hdr->biCompression>>24)&0xff);
444 : syskin 1428 CloseLib();
445 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
446 :     }
447 :     return S_OK;
448 :     }
449 :    
450 :    
451 :     /* get list of supported output colorspaces */
452 :    
453 :    
454 :     HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
455 :     {
456 :     BITMAPINFOHEADER * bmih;
457 :     DPRINTF("GetMediaType");
458 :    
459 :     if (m_pInput->IsConnected() == FALSE)
460 :     {
461 :     return E_UNEXPECTED;
462 :     }
463 :    
464 :     if (!g_config.videoinfo_compat) {
465 :     VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
466 :     if (vih == NULL) return E_OUTOFMEMORY;
467 :    
468 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER2));
469 :     bmih = &(vih->bmiHeader);
470 :     mtOut->SetFormatType(&FORMAT_VideoInfo2);
471 :    
472 :     if (ar_x != 0 && ar_y != 0) {
473 :     vih->dwPictAspectRatioX = ar_x;
474 :     vih->dwPictAspectRatioY = ar_y;
475 : syskin 1498 forced_ar = true;
476 : edgomez 1384 } else { // just to be safe
477 :     vih->dwPictAspectRatioX = m_create.width;
478 :     vih->dwPictAspectRatioY = abs(m_create.height);
479 : syskin 1498 forced_ar = false;
480 :     }
481 : edgomez 1384 } else {
482 :    
483 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
484 :     if (vih == NULL) return E_OUTOFMEMORY;
485 :    
486 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
487 :     bmih = &(vih->bmiHeader);
488 :     mtOut->SetFormatType(&FORMAT_VideoInfo);
489 :     }
490 :    
491 :     bmih->biSize = sizeof(BITMAPINFOHEADER);
492 :     bmih->biWidth = m_create.width;
493 :     bmih->biHeight = m_create.height;
494 :     bmih->biPlanes = 1;
495 :    
496 :     if (iPosition < 0) return E_INVALIDARG;
497 :    
498 :     switch(iPosition)
499 :     {
500 :    
501 :     case 0:
502 :     if ( USE_YUY2 )
503 :     {
504 :     bmih->biCompression = MEDIASUBTYPE_YUY2.Data1;
505 :     bmih->biBitCount = 16;
506 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
507 :     break;
508 :     }
509 :     case 1 :
510 :     if ( USE_YVYU )
511 :     {
512 :     bmih->biCompression = MEDIASUBTYPE_YVYU.Data1;
513 :     bmih->biBitCount = 16;
514 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
515 :     break;
516 :     }
517 :     case 2 :
518 :     if ( USE_UYVY )
519 :     {
520 :     bmih->biCompression = MEDIASUBTYPE_UYVY.Data1;
521 :     bmih->biBitCount = 16;
522 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
523 :     break;
524 :     }
525 :     case 3 :
526 :     if ( USE_IYUV )
527 :     {
528 :     bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
529 :     bmih->biBitCount = 12;
530 :     mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
531 :     break;
532 :     }
533 :     case 4 :
534 :     if ( USE_YV12 )
535 :     {
536 :     bmih->biCompression = MEDIASUBTYPE_YV12.Data1;
537 :     bmih->biBitCount = 12;
538 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
539 :     break;
540 :     }
541 :     case 5 :
542 :     if ( USE_RGB32 )
543 :     {
544 :     bmih->biCompression = BI_RGB;
545 :     bmih->biBitCount = 32;
546 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
547 :     break;
548 :     }
549 :     case 6 :
550 :     if ( USE_RGB24 )
551 :     {
552 :     bmih->biCompression = BI_RGB;
553 :     bmih->biBitCount = 24;
554 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
555 :     break;
556 :     }
557 :     case 7 :
558 :     if ( USE_RG555 )
559 :     {
560 :     bmih->biCompression = BI_RGB;
561 :     bmih->biBitCount = 16;
562 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
563 :     break;
564 :     }
565 :     case 8 :
566 :     if ( USE_RG565 )
567 :     {
568 :     bmih->biCompression = BI_RGB;
569 :     bmih->biBitCount = 16;
570 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
571 :     break;
572 :     }
573 :     default :
574 :     return VFW_S_NO_MORE_ITEMS;
575 :     }
576 :    
577 :     bmih->biSizeImage = GetBitmapSize(bmih);
578 :    
579 :     mtOut->SetType(&MEDIATYPE_Video);
580 :     mtOut->SetTemporalCompression(FALSE);
581 :     mtOut->SetSampleSize(bmih->biSizeImage);
582 :    
583 :     return S_OK;
584 :     }
585 :    
586 :    
587 :     /* (internal function) change colorspace */
588 : suxen_drol 1558 #define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3)
589 : edgomez 1384
590 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
591 :     {
592 : suxen_drol 1558 DWORD biWidth;
593 :    
594 : edgomez 1384 if (formattype == FORMAT_VideoInfo)
595 :     {
596 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
597 : suxen_drol 1558 biWidth = vih->bmiHeader.biWidth;
598 :     m_frame.output.stride[0] = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);
599 : edgomez 1384 rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
600 :     }
601 :     else if (formattype == FORMAT_VideoInfo2)
602 :     {
603 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
604 : suxen_drol 1558 biWidth = vih2->bmiHeader.biWidth;
605 :     m_frame.output.stride[0] = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);
606 : edgomez 1384 rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
607 :     }
608 :     else
609 :     {
610 :     return S_FALSE;
611 :     }
612 :    
613 :     if (subtype == CLSID_MEDIASUBTYPE_IYUV)
614 :     {
615 :     DPRINTF("IYUV");
616 :     rgb_flip = 0;
617 :     m_frame.output.csp = XVID_CSP_I420;
618 : suxen_drol 1558 m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
619 : edgomez 1384 }
620 :     else if (subtype == MEDIASUBTYPE_YV12)
621 :     {
622 :     DPRINTF("YV12");
623 :     rgb_flip = 0;
624 :     m_frame.output.csp = XVID_CSP_YV12;
625 : suxen_drol 1558 m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */
626 : edgomez 1384 }
627 :     else if (subtype == MEDIASUBTYPE_YUY2)
628 :     {
629 :     DPRINTF("YUY2");
630 :     rgb_flip = 0;
631 :     m_frame.output.csp = XVID_CSP_YUY2;
632 :     }
633 :     else if (subtype == MEDIASUBTYPE_YVYU)
634 :     {
635 :     DPRINTF("YVYU");
636 :     rgb_flip = 0;
637 :     m_frame.output.csp = XVID_CSP_YVYU;
638 :     }
639 :     else if (subtype == MEDIASUBTYPE_UYVY)
640 :     {
641 :     DPRINTF("UYVY");
642 :     rgb_flip = 0;
643 :     m_frame.output.csp = XVID_CSP_UYVY;
644 :     }
645 :     else if (subtype == MEDIASUBTYPE_RGB32)
646 :     {
647 :     DPRINTF("RGB32");
648 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
649 :     }
650 :     else if (subtype == MEDIASUBTYPE_RGB24)
651 :     {
652 :     DPRINTF("RGB24");
653 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
654 :     }
655 :     else if (subtype == MEDIASUBTYPE_RGB555)
656 :     {
657 :     DPRINTF("RGB555");
658 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
659 :     }
660 :     else if (subtype == MEDIASUBTYPE_RGB565)
661 :     {
662 :     DPRINTF("RGB565");
663 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
664 :     }
665 :     else if (subtype == GUID_NULL)
666 :     {
667 :     m_frame.output.csp = XVID_CSP_NULL;
668 :     }
669 :     else
670 :     {
671 :     return S_FALSE;
672 :     }
673 :    
674 :     return S_OK;
675 :     }
676 :    
677 :    
678 :     /* set output colorspace */
679 :    
680 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
681 :     {
682 :     DPRINTF("SetMediaType");
683 :    
684 :     if (direction == PINDIR_OUTPUT)
685 :     {
686 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
687 :     }
688 :    
689 :     return S_OK;
690 :     }
691 :    
692 :    
693 :     /* check input<->output compatiblity */
694 :    
695 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
696 :     {
697 :     DPRINTF("CheckTransform");
698 :     return S_OK;
699 :     }
700 :    
701 :    
702 :     /* alloc output buffer */
703 :    
704 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
705 :     {
706 :     DPRINTF("DecideBufferSize");
707 :     HRESULT result;
708 :     ALLOCATOR_PROPERTIES ppropActual;
709 :    
710 :     if (m_pInput->IsConnected() == FALSE)
711 :     {
712 :     return E_UNEXPECTED;
713 :     }
714 :    
715 :     ppropInputRequest->cBuffers = 1;
716 :     ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
717 :     // cbAlign causes problems with the resize filter */
718 :     // ppropInputRequest->cbAlign = 16;
719 :     ppropInputRequest->cbPrefix = 0;
720 :    
721 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
722 :     if (result != S_OK)
723 :     {
724 :     return result;
725 :     }
726 :    
727 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
728 :     {
729 :     return E_FAIL;
730 :     }
731 :    
732 :     return S_OK;
733 :     }
734 :    
735 :    
736 :     /* decode frame */
737 :    
738 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
739 :     {
740 :     DPRINTF("Transform");
741 :     xvid_dec_stats_t stats;
742 :     int length;
743 :    
744 :     memset(&stats, 0, sizeof(stats));
745 :     stats.version = XVID_VERSION;
746 :    
747 :     if (m_create.handle == NULL)
748 :     {
749 : Isibaar 1605 if (xvid_decore_func == NULL)
750 :     return E_FAIL;
751 :    
752 : edgomez 1384 if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
753 :     {
754 :     DPRINTF("*** XVID_DEC_CREATE error");
755 :     return S_FALSE;
756 :     }
757 :     }
758 :    
759 :     AM_MEDIA_TYPE * mtOut;
760 :     pOut->GetMediaType(&mtOut);
761 :     if (mtOut != NULL)
762 :     {
763 :     HRESULT result;
764 :    
765 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
766 :     DeleteMediaType(mtOut);
767 :    
768 :     if (result != S_OK)
769 :     {
770 :     DPRINTF("*** ChangeColorspace error");
771 :     return result;
772 :     }
773 :     }
774 :    
775 :     m_frame.length = pIn->GetActualDataLength();
776 :     if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
777 :     {
778 :     return S_FALSE;
779 :     }
780 :    
781 :     if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
782 :     {
783 :     return S_FALSE;
784 :     }
785 :    
786 :     m_frame.general = XVID_LOWDELAY;
787 :    
788 :     if (pIn->IsDiscontinuity() == S_OK)
789 : syskin 1427 m_frame.general |= XVID_DISCONTINUITY;
790 : edgomez 1384
791 :     if (g_config.nDeblock_Y)
792 :     m_frame.general |= XVID_DEBLOCKY;
793 :    
794 :     if (g_config.nDeblock_UV)
795 :     m_frame.general |= XVID_DEBLOCKUV;
796 : syskin 1437
797 :     if (g_config.nDering_Y)
798 :     m_frame.general |= XVID_DERINGY;
799 :    
800 :     if (g_config.nDering_UV)
801 :     m_frame.general |= XVID_DERINGUV;
802 :    
803 : edgomez 1384 if (g_config.nFilmEffect)
804 :     m_frame.general |= XVID_FILMEFFECT;
805 :    
806 : suxen_drol 1397 m_frame.brightness = g_config.nBrightness;
807 :    
808 : edgomez 1384 m_frame.output.csp &= ~XVID_CSP_VFLIP;
809 :     m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
810 :    
811 : Isibaar 1605 // Paranoid check.
812 :     if (xvid_decore_func == NULL)
813 :     return E_FAIL;
814 : syskin 1498
815 :    
816 :    
817 : edgomez 1384 repeat :
818 :    
819 :     if (pIn->IsPreroll() != S_OK)
820 :     {
821 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
822 :    
823 :     if (length < 0)
824 :     {
825 :     DPRINTF("*** XVID_DEC_DECODE");
826 :     return S_FALSE;
827 : syskin 1498 } else
828 :     if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) {
829 :     // inspired by minolta! works for VMR 7 + 9
830 :    
831 :     IMediaSample2 *pOut2 = NULL;
832 :     AM_SAMPLE2_PROPERTIES outProp2;
833 :     if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) &&
834 :     SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2)))
835 :     {
836 :     CMediaType mtOut2 = m_pOutput->CurrentMediaType();
837 :     VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();
838 : suxen_drol 1502
839 :     if (*mtOut2.FormatType() == FORMAT_VideoInfo2 &&
840 :     vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)
841 : syskin 1498 {
842 :     vihOut2->dwPictAspectRatioX = ar_x;
843 :     vihOut2->dwPictAspectRatioY = ar_y;
844 :     pOut2->SetMediaType(&mtOut2);
845 :     m_pOutput->SetMediaType(&mtOut2);
846 :     }
847 :     pOut2->Release();
848 :     }
849 : edgomez 1384 }
850 :     }
851 :     else
852 :     { /* Preroll frame - won't be displayed */
853 :     int tmp = m_frame.output.csp;
854 :     int tmp_gen = m_frame.general;
855 :    
856 :     m_frame.output.csp = XVID_CSP_NULL;
857 :    
858 :     /* Disable postprocessing to speed-up seeking */
859 :     m_frame.general &= ~XVID_DEBLOCKY;
860 :     m_frame.general &= ~XVID_DEBLOCKUV;
861 : Isibaar 1605 /*m_frame.general &= ~XVID_DERING;*/
862 : edgomez 1384 m_frame.general &= ~XVID_FILMEFFECT;
863 :    
864 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
865 :     if (length < 0)
866 :     {
867 :     DPRINTF("*** XVID_DEC_DECODE");
868 :     return S_FALSE;
869 :     }
870 :    
871 :     m_frame.output.csp = tmp;
872 :     m_frame.general = tmp_gen;
873 :     }
874 :    
875 :     if (stats.type == XVID_TYPE_NOTHING && length > 0) {
876 : edgomez 1432 DPRINTF(" B-Frame decoder lag");
877 : edgomez 1384 return S_FALSE;
878 :     }
879 :    
880 :    
881 :     if (stats.type == XVID_TYPE_VOL)
882 :     {
883 :     if (stats.data.vol.width != m_create.width ||
884 :     stats.data.vol.height != m_create.height)
885 :     {
886 :     DPRINTF("TODO: auto-resize");
887 :     return S_FALSE;
888 :     }
889 : syskin 1498
890 : edgomez 1384 pOut->SetSyncPoint(TRUE);
891 :    
892 : syskin 1498 if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */
893 :     int par_x, par_y;
894 :     if (stats.data.vol.par == XVID_PAR_EXT) {
895 :     par_x = stats.data.vol.par_width;
896 :     par_y = stats.data.vol.par_height;
897 :     } else {
898 : syskin 1529 par_x = PARS[stats.data.vol.par-1][0];
899 :     par_y = PARS[stats.data.vol.par-1][1];
900 : syskin 1498 }
901 :    
902 :     ar_x = par_x * stats.data.vol.width;
903 :     ar_y = par_y * stats.data.vol.height;
904 :     }
905 :    
906 : edgomez 1384 m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
907 :     m_frame.length -= length;
908 :     goto repeat;
909 :     }
910 :    
911 :     if (pIn->IsPreroll() == S_OK) {
912 :     return S_FALSE;
913 :     }
914 :    
915 :     return S_OK;
916 :     }
917 :    
918 :    
919 :     /* get property page list */
920 :    
921 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
922 :     {
923 :     DPRINTF("GetPages");
924 :    
925 :     pPages->cElems = 1;
926 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
927 :     if (pPages->pElems == NULL)
928 :     {
929 :     return E_OUTOFMEMORY;
930 :     }
931 :     pPages->pElems[0] = CLSID_CABOUT;
932 :    
933 :     return S_OK;
934 :     }
935 :    
936 :    
937 :     /* cleanup pages */
938 :    
939 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
940 :     {
941 :     DPRINTF("FreePages");
942 :     CoTaskMemFree(pPages->pElems);
943 :     return S_OK;
944 :     }

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