[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 1488 - (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 : syskin 1488 * $Id: CXvidDecoder.cpp,v 1.8 2004-07-11 10:22:47 syskin 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 :     C:\DXVCSDK\include
40 :     C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses
41 :    
42 :     libraries (optional):
43 :     C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release
44 :     */
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 :     CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID)
208 :     {
209 :     DPRINTF("Constructor");
210 :    
211 :     xvid_gbl_init_t init;
212 :     memset(&init, 0, sizeof(init));
213 :     init.version = XVID_VERSION;
214 :    
215 :     m_hdll = LoadLibrary(XVID_DLL_NAME);
216 :     if (m_hdll == NULL) {
217 :     DPRINTF("dll load failed");
218 :     MessageBox(0, XVID_DLL_NAME " not found","Error", 0);
219 :     return;
220 :     }
221 :    
222 :     xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
223 :     if (xvid_global_func == NULL) {
224 :     MessageBox(0, "xvid_global() not found", "Error", 0);
225 :     return;
226 :     }
227 :    
228 :     xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
229 :     if (xvid_decore_func == NULL) {
230 :     MessageBox(0, "xvid_decore() not found", "Error", 0);
231 :     return;
232 :     }
233 :    
234 :     if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0)
235 :     {
236 :     MessageBox(0, "xvid_global() failed", "Error", 0);
237 :     return;
238 :     }
239 :    
240 :     memset(&m_create, 0, sizeof(m_create));
241 :     m_create.version = XVID_VERSION;
242 :     m_create.handle = NULL;
243 :    
244 :     memset(&m_frame, 0, sizeof(m_frame));
245 :     m_frame.version = XVID_VERSION;
246 :    
247 :     LoadRegistryInfo();
248 :    
249 :     USE_IYUV = false;
250 :     USE_YV12 = false;
251 :     USE_YUY2 = false;
252 :     USE_YVYU = false;
253 :     USE_UYVY = false;
254 :     USE_RGB32 = false;
255 :     USE_RGB24 = false;
256 :     USE_RG555 = false;
257 :     USE_RG565 = false;
258 :    
259 :     switch ( g_config.nForceColorspace )
260 :     {
261 :     case FORCE_NONE:
262 :     USE_IYUV = true;
263 :     USE_YV12 = true;
264 :     USE_YUY2 = true;
265 :     USE_YVYU = true;
266 :     USE_UYVY = true;
267 :     USE_RGB32 = true;
268 :     USE_RGB24 = true;
269 :     USE_RG555 = true;
270 :     USE_RG565 = true;
271 :     break;
272 :     case FORCE_YV12:
273 :     USE_IYUV = true;
274 :     USE_YV12 = true;
275 :     break;
276 :     case FORCE_YUY2:
277 :     USE_YUY2 = true;
278 :     break;
279 :     case FORCE_RGB24:
280 :     USE_RGB24 = true;
281 :     break;
282 :     case FORCE_RGB32:
283 :     USE_RGB32 = true;
284 :     break;
285 :     }
286 : syskin 1488
287 :     switch (g_config.aspect_ratio)
288 :     {
289 :     case 0: // Auto mode
290 :     ar_x = ar_y = 0;
291 :     break;
292 :     case 1:
293 :     ar_x = 4;
294 :     ar_y = 3;
295 :     break;
296 :     case 2:
297 :     ar_x = 16;
298 :     ar_y = 9;
299 :     break;
300 :     case 3:
301 :     ar_x = 47;
302 :     ar_y = 20;
303 :     break;
304 :     }
305 : edgomez 1384 }
306 :    
307 : syskin 1428 void CXvidDecoder::CloseLib()
308 : edgomez 1384 {
309 :     DPRINTF("Destructor");
310 :    
311 : syskin 1428 if (m_create.handle != NULL) {
312 : edgomez 1384 xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
313 :     m_create.handle = NULL;
314 :     }
315 :    
316 : syskin 1428 if (m_hdll != NULL) {
317 : edgomez 1384 FreeLibrary(m_hdll);
318 :     m_hdll = NULL;
319 :     }
320 :     }
321 :    
322 : syskin 1428 /* destructor */
323 : edgomez 1384
324 : syskin 1428 CXvidDecoder::~CXvidDecoder()
325 :     {
326 :     CloseLib();
327 :     }
328 : edgomez 1384
329 : syskin 1428
330 :    
331 : edgomez 1384 /* check input type */
332 :    
333 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
334 :     {
335 :     DPRINTF("CheckInputType");
336 :     BITMAPINFOHEADER * hdr;
337 :    
338 :     if (*mtIn->Type() != MEDIATYPE_Video)
339 :     {
340 :     DPRINTF("Error: Unknown Type");
341 : syskin 1428 CloseLib();
342 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
343 :     }
344 :    
345 :     if (*mtIn->FormatType() == FORMAT_VideoInfo)
346 :     {
347 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
348 :     hdr = &vih->bmiHeader;
349 :     /* PAR (x:y) is (1/ppm_X):(1/ppm_Y) where ppm is pixels-per-meter
350 :     which is equal to ppm_Y:ppm_X */
351 : syskin 1488 if ((ar_x == 0) && (ar_y == 0)) // selected Auto-mode
352 :     {
353 :     ar_x = vih->bmiHeader.biYPelsPerMeter * abs(hdr->biWidth);
354 :     ar_y = vih->bmiHeader.biXPelsPerMeter * abs(hdr->biHeight);
355 :     }
356 : edgomez 1384 DPRINTF("VIDEOINFOHEADER PAR: %d:%d -> AR %d:%d",
357 :     vih->bmiHeader.biYPelsPerMeter,vih->bmiHeader.biXPelsPerMeter, ar_x, ar_y);
358 :     }
359 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
360 :     {
361 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
362 :     hdr = &vih2->bmiHeader;
363 : syskin 1488 if ((ar_x == 0) && (ar_y == 0)) // selected Auto-mode
364 :     {
365 :     ar_x = vih2->dwPictAspectRatioX;
366 :     ar_y = vih2->dwPictAspectRatioY;
367 :     }
368 : edgomez 1384 DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y);
369 :     }
370 :     else
371 :     {
372 :     DPRINTF("Error: Unknown FormatType");
373 : syskin 1428 CloseLib();
374 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
375 :     }
376 :    
377 :     if (hdr->biHeight < 0)
378 :     {
379 :     DPRINTF("colorspace: inverted input format not supported");
380 :     }
381 :    
382 :     m_create.width = hdr->biWidth;
383 :     m_create.height = hdr->biHeight;
384 :    
385 :     switch(hdr->biCompression)
386 :     {
387 :    
388 :     case FOURCC_MP4V:
389 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
390 :     CloseLib();
391 :     return VFW_E_TYPE_NOT_ACCEPTED;
392 :     }
393 : edgomez 1384 break;
394 :     case FOURCC_DIVX :
395 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
396 :     CloseLib();
397 :     return VFW_E_TYPE_NOT_ACCEPTED;
398 :     }
399 : edgomez 1384 break;
400 :     case FOURCC_DX50 :
401 : syskin 1428 if (!(g_config.supported_4cc & SUPPORT_DX50)) {
402 :     CloseLib();
403 :     return VFW_E_TYPE_NOT_ACCEPTED;
404 :     }
405 : edgomez 1384 case FOURCC_XVID :
406 :     break;
407 :    
408 :    
409 :     default :
410 :     DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
411 :     hdr->biCompression,
412 :     (hdr->biCompression)&0xff,
413 :     (hdr->biCompression>>8)&0xff,
414 :     (hdr->biCompression>>16)&0xff,
415 :     (hdr->biCompression>>24)&0xff);
416 : syskin 1428 CloseLib();
417 : edgomez 1384 return VFW_E_TYPE_NOT_ACCEPTED;
418 :     }
419 :     return S_OK;
420 :     }
421 :    
422 :    
423 :     /* get list of supported output colorspaces */
424 :    
425 :    
426 :     HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
427 :     {
428 :     BITMAPINFOHEADER * bmih;
429 :     DPRINTF("GetMediaType");
430 :    
431 :     if (m_pInput->IsConnected() == FALSE)
432 :     {
433 :     return E_UNEXPECTED;
434 :     }
435 :    
436 :     if (!g_config.videoinfo_compat) {
437 :     VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
438 :     if (vih == NULL) return E_OUTOFMEMORY;
439 :    
440 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER2));
441 :     bmih = &(vih->bmiHeader);
442 :     mtOut->SetFormatType(&FORMAT_VideoInfo2);
443 :    
444 :     if (ar_x != 0 && ar_y != 0) {
445 :     vih->dwPictAspectRatioX = ar_x;
446 :     vih->dwPictAspectRatioY = ar_y;
447 :     } else { // just to be safe
448 :     vih->dwPictAspectRatioX = m_create.width;
449 :     vih->dwPictAspectRatioY = abs(m_create.height);
450 :     }
451 :    
452 :     } else {
453 :    
454 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
455 :     if (vih == NULL) return E_OUTOFMEMORY;
456 :    
457 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
458 :     bmih = &(vih->bmiHeader);
459 :     mtOut->SetFormatType(&FORMAT_VideoInfo);
460 :     }
461 :    
462 :     bmih->biSize = sizeof(BITMAPINFOHEADER);
463 :     bmih->biWidth = m_create.width;
464 :     bmih->biHeight = m_create.height;
465 :     bmih->biPlanes = 1;
466 :    
467 :     if (iPosition < 0) return E_INVALIDARG;
468 :    
469 :     switch(iPosition)
470 :     {
471 :    
472 :     case 0:
473 :     if ( USE_YUY2 )
474 :     {
475 :     bmih->biCompression = MEDIASUBTYPE_YUY2.Data1;
476 :     bmih->biBitCount = 16;
477 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
478 :     break;
479 :     }
480 :     case 1 :
481 :     if ( USE_YVYU )
482 :     {
483 :     bmih->biCompression = MEDIASUBTYPE_YVYU.Data1;
484 :     bmih->biBitCount = 16;
485 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
486 :     break;
487 :     }
488 :     case 2 :
489 :     if ( USE_UYVY )
490 :     {
491 :     bmih->biCompression = MEDIASUBTYPE_UYVY.Data1;
492 :     bmih->biBitCount = 16;
493 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
494 :     break;
495 :     }
496 :     case 3 :
497 :     if ( USE_IYUV )
498 :     {
499 :     bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
500 :     bmih->biBitCount = 12;
501 :     mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
502 :     break;
503 :     }
504 :     case 4 :
505 :     if ( USE_YV12 )
506 :     {
507 :     bmih->biCompression = MEDIASUBTYPE_YV12.Data1;
508 :     bmih->biBitCount = 12;
509 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
510 :     break;
511 :     }
512 :     case 5 :
513 :     if ( USE_RGB32 )
514 :     {
515 :     bmih->biCompression = BI_RGB;
516 :     bmih->biBitCount = 32;
517 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
518 :     break;
519 :     }
520 :     case 6 :
521 :     if ( USE_RGB24 )
522 :     {
523 :     bmih->biCompression = BI_RGB;
524 :     bmih->biBitCount = 24;
525 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
526 :     break;
527 :     }
528 :     case 7 :
529 :     if ( USE_RG555 )
530 :     {
531 :     bmih->biCompression = BI_RGB;
532 :     bmih->biBitCount = 16;
533 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
534 :     break;
535 :     }
536 :     case 8 :
537 :     if ( USE_RG565 )
538 :     {
539 :     bmih->biCompression = BI_RGB;
540 :     bmih->biBitCount = 16;
541 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
542 :     break;
543 :     }
544 :     default :
545 :     return VFW_S_NO_MORE_ITEMS;
546 :     }
547 :    
548 :     bmih->biSizeImage = GetBitmapSize(bmih);
549 :    
550 :     mtOut->SetType(&MEDIATYPE_Video);
551 :     mtOut->SetTemporalCompression(FALSE);
552 :     mtOut->SetSampleSize(bmih->biSizeImage);
553 :    
554 :     return S_OK;
555 :     }
556 :    
557 :    
558 :     /* (internal function) change colorspace */
559 :    
560 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
561 :     {
562 :     if (formattype == FORMAT_VideoInfo)
563 :     {
564 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
565 :     m_frame.output.stride[0] = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3;
566 :     rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
567 :     }
568 :     else if (formattype == FORMAT_VideoInfo2)
569 :     {
570 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
571 :     m_frame.output.stride[0] = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3;
572 :     rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
573 :     }
574 :     else
575 :     {
576 :     return S_FALSE;
577 :     }
578 :    
579 :     if (subtype == CLSID_MEDIASUBTYPE_IYUV)
580 :     {
581 :     DPRINTF("IYUV");
582 :     rgb_flip = 0;
583 :     m_frame.output.csp = XVID_CSP_I420;
584 :     m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */
585 :     }
586 :     else if (subtype == MEDIASUBTYPE_YV12)
587 :     {
588 :     DPRINTF("YV12");
589 :     rgb_flip = 0;
590 :     m_frame.output.csp = XVID_CSP_YV12;
591 :     m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */
592 :     }
593 :     else if (subtype == MEDIASUBTYPE_YUY2)
594 :     {
595 :     DPRINTF("YUY2");
596 :     rgb_flip = 0;
597 :     m_frame.output.csp = XVID_CSP_YUY2;
598 :     }
599 :     else if (subtype == MEDIASUBTYPE_YVYU)
600 :     {
601 :     DPRINTF("YVYU");
602 :     rgb_flip = 0;
603 :     m_frame.output.csp = XVID_CSP_YVYU;
604 :     }
605 :     else if (subtype == MEDIASUBTYPE_UYVY)
606 :     {
607 :     DPRINTF("UYVY");
608 :     rgb_flip = 0;
609 :     m_frame.output.csp = XVID_CSP_UYVY;
610 :     }
611 :     else if (subtype == MEDIASUBTYPE_RGB32)
612 :     {
613 :     DPRINTF("RGB32");
614 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
615 :     }
616 :     else if (subtype == MEDIASUBTYPE_RGB24)
617 :     {
618 :     DPRINTF("RGB24");
619 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
620 :     }
621 :     else if (subtype == MEDIASUBTYPE_RGB555)
622 :     {
623 :     DPRINTF("RGB555");
624 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
625 :     }
626 :     else if (subtype == MEDIASUBTYPE_RGB565)
627 :     {
628 :     DPRINTF("RGB565");
629 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
630 :     }
631 :     else if (subtype == GUID_NULL)
632 :     {
633 :     m_frame.output.csp = XVID_CSP_NULL;
634 :     }
635 :     else
636 :     {
637 :     return S_FALSE;
638 :     }
639 :    
640 :     return S_OK;
641 :     }
642 :    
643 :    
644 :     /* set output colorspace */
645 :    
646 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
647 :     {
648 :     DPRINTF("SetMediaType");
649 :    
650 :     if (direction == PINDIR_OUTPUT)
651 :     {
652 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
653 :     }
654 :    
655 :     return S_OK;
656 :     }
657 :    
658 :    
659 :     /* check input<->output compatiblity */
660 :    
661 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
662 :     {
663 :     DPRINTF("CheckTransform");
664 :     return S_OK;
665 :     }
666 :    
667 :    
668 :     /* alloc output buffer */
669 :    
670 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
671 :     {
672 :     DPRINTF("DecideBufferSize");
673 :     HRESULT result;
674 :     ALLOCATOR_PROPERTIES ppropActual;
675 :    
676 :     if (m_pInput->IsConnected() == FALSE)
677 :     {
678 :     return E_UNEXPECTED;
679 :     }
680 :    
681 :     ppropInputRequest->cBuffers = 1;
682 :     ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
683 :     // cbAlign causes problems with the resize filter */
684 :     // ppropInputRequest->cbAlign = 16;
685 :     ppropInputRequest->cbPrefix = 0;
686 :    
687 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
688 :     if (result != S_OK)
689 :     {
690 :     return result;
691 :     }
692 :    
693 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
694 :     {
695 :     return E_FAIL;
696 :     }
697 :    
698 :     return S_OK;
699 :     }
700 :    
701 :    
702 :     /* decode frame */
703 :    
704 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
705 :     {
706 :     DPRINTF("Transform");
707 :     xvid_dec_stats_t stats;
708 :     int length;
709 :    
710 :     memset(&stats, 0, sizeof(stats));
711 :     stats.version = XVID_VERSION;
712 :    
713 :     if (m_create.handle == NULL)
714 :     {
715 :     if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
716 :     {
717 :     DPRINTF("*** XVID_DEC_CREATE error");
718 :     return S_FALSE;
719 :     }
720 :     }
721 :    
722 :     AM_MEDIA_TYPE * mtOut;
723 :     pOut->GetMediaType(&mtOut);
724 :     if (mtOut != NULL)
725 :     {
726 :     HRESULT result;
727 :    
728 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
729 :     DeleteMediaType(mtOut);
730 :    
731 :     if (result != S_OK)
732 :     {
733 :     DPRINTF("*** ChangeColorspace error");
734 :     return result;
735 :     }
736 :     }
737 :    
738 :     m_frame.length = pIn->GetActualDataLength();
739 :     if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
740 :     {
741 :     return S_FALSE;
742 :     }
743 :    
744 :     if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
745 :     {
746 :     return S_FALSE;
747 :     }
748 :    
749 :     m_frame.general = XVID_LOWDELAY;
750 :    
751 :     if (pIn->IsDiscontinuity() == S_OK)
752 : syskin 1427 m_frame.general |= XVID_DISCONTINUITY;
753 : edgomez 1384
754 :     if (g_config.nDeblock_Y)
755 :     m_frame.general |= XVID_DEBLOCKY;
756 :    
757 :     if (g_config.nDeblock_UV)
758 :     m_frame.general |= XVID_DEBLOCKUV;
759 : syskin 1437
760 :     if (g_config.nDering_Y)
761 :     m_frame.general |= XVID_DERINGY;
762 :    
763 :     if (g_config.nDering_UV)
764 :     m_frame.general |= XVID_DERINGUV;
765 :    
766 : edgomez 1384 if (g_config.nFilmEffect)
767 :     m_frame.general |= XVID_FILMEFFECT;
768 :    
769 : suxen_drol 1397 m_frame.brightness = g_config.nBrightness;
770 :    
771 : edgomez 1384 m_frame.output.csp &= ~XVID_CSP_VFLIP;
772 :     m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
773 :    
774 :     repeat :
775 :    
776 :     if (pIn->IsPreroll() != S_OK)
777 :     {
778 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
779 :    
780 :     if (length < 0)
781 :     {
782 :     DPRINTF("*** XVID_DEC_DECODE");
783 :     return S_FALSE;
784 :     }
785 :     }
786 :     else
787 :     { /* Preroll frame - won't be displayed */
788 :     int tmp = m_frame.output.csp;
789 :     int tmp_gen = m_frame.general;
790 :    
791 :     m_frame.output.csp = XVID_CSP_NULL;
792 :    
793 :     /* Disable postprocessing to speed-up seeking */
794 :     m_frame.general &= ~XVID_DEBLOCKY;
795 :     m_frame.general &= ~XVID_DEBLOCKUV;
796 :     /* m_frame.general &= ~XVID_DERING; */
797 :     m_frame.general &= ~XVID_FILMEFFECT;
798 :    
799 :     length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
800 :     if (length < 0)
801 :     {
802 :     DPRINTF("*** XVID_DEC_DECODE");
803 :     return S_FALSE;
804 :     }
805 :    
806 :     m_frame.output.csp = tmp;
807 :     m_frame.general = tmp_gen;
808 :     }
809 :    
810 :     if (stats.type == XVID_TYPE_NOTHING && length > 0) {
811 : edgomez 1432 DPRINTF(" B-Frame decoder lag");
812 : edgomez 1384 return S_FALSE;
813 :     }
814 :    
815 :    
816 :     if (stats.type == XVID_TYPE_VOL)
817 :     {
818 :     if (stats.data.vol.width != m_create.width ||
819 :     stats.data.vol.height != m_create.height)
820 :     {
821 :     DPRINTF("TODO: auto-resize");
822 :     return S_FALSE;
823 :     }
824 :    
825 :     // pOut->SetDiscontinuity(TRUE);
826 :     pOut->SetSyncPoint(TRUE);
827 :    
828 :     m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
829 :     m_frame.length -= length;
830 :     goto repeat;
831 :     }
832 :    
833 :     if (pIn->IsPreroll() == S_OK) {
834 :     return S_FALSE;
835 :     }
836 :    
837 :     return S_OK;
838 :     }
839 :    
840 :    
841 :     /* get property page list */
842 :    
843 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
844 :     {
845 :     DPRINTF("GetPages");
846 :    
847 :     pPages->cElems = 1;
848 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
849 :     if (pPages->pElems == NULL)
850 :     {
851 :     return E_OUTOFMEMORY;
852 :     }
853 :     pPages->pElems[0] = CLSID_CABOUT;
854 :    
855 :     return S_OK;
856 :     }
857 :    
858 :    
859 :     /* cleanup pages */
860 :    
861 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
862 :     {
863 :     DPRINTF("FreePages");
864 :     CoTaskMemFree(pPages->pElems);
865 :     return S_OK;
866 :     }

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