[svn] / branches / release-1_0-branch / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /branches/release-1_0-branch/xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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