[svn] / branches / dev-api-4 / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1307 - (view) (download)

1 : edgomez 1054 /*****************************************************************************
2 : suxen_drol 888 *
3 : edgomez 1054 * XVID MPEG-4 VIDEO CODEC
4 :     * - XviD Decoder part of the DShow Filter -
5 : suxen_drol 888 *
6 : edgomez 1054 * Copyright(C) 2002-2003 Peter Ross <pross@xvid.org>
7 : suxen_drol 888 *
8 : edgomez 1054 * 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 : suxen_drol 888 *
13 : edgomez 1054 * 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 : suxen_drol 888 *
18 : edgomez 1054 * 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 1307 * $Id: CXvidDecoder.cpp,v 1.1.2.9 2004-01-07 13:50:28 syskin Exp $
23 : edgomez 1054 *
24 :     ****************************************************************************/
25 : suxen_drol 888
26 : Isibaar 1260 /****************************************************************************
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 : suxen_drol 888 /*
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 :    
64 : Isibaar 1260 // Externs defined here
65 :     PostProcessing_Settings PPSettings;
66 : suxen_drol 888
67 : Isibaar 1260 int rgb_flip;
68 : suxen_drol 1208
69 : Isibaar 1260 bool USE_IYUV;
70 :     bool USE_YV12;
71 :     bool USE_YUY2;
72 :     bool USE_YVYU;
73 :     bool USE_UYVY;
74 :     bool USE_RGB32;
75 :     bool USE_RGB24;
76 :     bool USE_RG555;
77 :     bool USE_RG565;
78 :    
79 : suxen_drol 888 const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
80 :     {
81 :     { &MEDIATYPE_Video, &CLSID_XVID },
82 :     { &MEDIATYPE_Video, &CLSID_XVID_UC },
83 :     { &MEDIATYPE_Video, &CLSID_DIVX },
84 :     { &MEDIATYPE_Video, &CLSID_DIVX_UC },
85 :     { &MEDIATYPE_Video, &CLSID_DX50 },
86 :     { &MEDIATYPE_Video, &CLSID_DX50_UC },
87 :     };
88 :    
89 :     const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
90 :     {
91 :     { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
92 :     };
93 :    
94 :    
95 :     const AMOVIESETUP_PIN psudPins[] =
96 :     {
97 :     {
98 :     L"Input", // String pin name
99 :     FALSE, // Is it rendered
100 :     FALSE, // Is it an output
101 :     FALSE, // Allowed none
102 :     FALSE, // Allowed many
103 :     &CLSID_NULL, // Connects to filter
104 :     L"Output", // Connects to pin
105 :     sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
106 :     &sudInputPinTypes[0] // The pin details
107 :     },
108 :     {
109 :     L"Output", // String pin name
110 :     FALSE, // Is it rendered
111 :     TRUE, // Is it an output
112 :     FALSE, // Allowed none
113 :     FALSE, // Allowed many
114 :     &CLSID_NULL, // Connects to filter
115 :     L"Input", // Connects to pin
116 :     sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
117 :     sudOutputPinTypes // The pin details
118 :     }
119 :     };
120 :    
121 :    
122 :     const AMOVIESETUP_FILTER sudXvidDecoder =
123 :     {
124 :     &CLSID_XVID, // Filter CLSID
125 :     XVID_NAME_L, // Filter name
126 :     MERIT_PREFERRED, // Its merit
127 :     sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins
128 :     psudPins // Pin details
129 :     };
130 :    
131 :    
132 :     // List of class IDs and creator functions for the class factory. This
133 :     // provides the link between the OLE entry point in the DLL and an object
134 :     // being created. The class factory will call the static CreateInstance
135 :    
136 :     CFactoryTemplate g_Templates[] =
137 :     {
138 :     {
139 :     XVID_NAME_L,
140 :     &CLSID_XVID,
141 :     CXvidDecoder::CreateInstance,
142 :     NULL,
143 :     &sudXvidDecoder
144 :     },
145 :     {
146 :     XVID_NAME_L L"About",
147 :     &CLSID_CABOUT,
148 :     CAbout::CreateInstance
149 :     }
150 :    
151 :     };
152 :    
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 : syskin 1301 #define XVID_DLL_NAME "xvidcore.dll"
205 :    
206 : suxen_drol 888 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 : syskin 1301
215 : syskin 1307 ar_x = ar_y = 0;
216 :    
217 : syskin 1301 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 : suxen_drol 888 {
238 : suxen_drol 1208 MessageBox(0, "xvid_global() failed", "Error", 0);
239 : suxen_drol 888 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 : Isibaar 1260
249 :     HKEY hKey;
250 :     DWORD size;
251 :     RegOpenKeyEx(XVID_REG_KEY, XVID_REG_SUBKEY, 0, KEY_READ, &hKey);
252 :    
253 :     // Set the default post-processing settings
254 :     REG_GET_N("Brightness", PPSettings.nBrightness, 25)
255 : Isibaar 1300 REG_GET_N("Deblock_Y", PPSettings.bDeblock_Y, 1)
256 :     REG_GET_N("Deblock_UV", PPSettings.bDeblock_UV, 1)
257 :     REG_GET_N("Dering", PPSettings.bDering, 1)
258 :     REG_GET_N("FilmEffect", PPSettings.bFilmEffect, 1)
259 : Isibaar 1260 REG_GET_N("ForceColorspace", PPSettings.nForceColorspace, 0)
260 :    
261 :     RegCloseKey(hKey);
262 :    
263 :     USE_IYUV = false;
264 :     USE_YV12 = false;
265 :     USE_YUY2 = false;
266 :     USE_YVYU = false;
267 :     USE_UYVY = false;
268 :     USE_RGB32 = false;
269 :     USE_RGB24 = false;
270 :     USE_RG555 = false;
271 :     USE_RG565 = false;
272 :    
273 :     switch ( PPSettings.nForceColorspace )
274 :     {
275 :     case FORCE_NONE:
276 :     USE_IYUV = true;
277 :     USE_YV12 = true;
278 :     USE_YUY2 = true;
279 :     USE_YVYU = true;
280 :     USE_UYVY = true;
281 :     USE_RGB32 = true;
282 :     USE_RGB24 = true;
283 :     USE_RG555 = true;
284 :     USE_RG565 = true;
285 :     break;
286 :     case FORCE_YV12:
287 :     USE_IYUV = true;
288 :     USE_YV12 = true;
289 :     break;
290 :     case FORCE_YUY2:
291 :     USE_YUY2 = true;
292 :     break;
293 :     case FORCE_RGB24:
294 :     USE_RGB24 = true;
295 :     break;
296 :     case FORCE_RGB32:
297 :     USE_RGB32 = true;
298 :     break;
299 :     }
300 : suxen_drol 888 }
301 :    
302 :    
303 :    
304 :     /* destructor */
305 :    
306 :     CXvidDecoder::~CXvidDecoder()
307 :     {
308 :     DPRINTF("Destructor");
309 :    
310 :     if (m_create.handle != NULL)
311 :     {
312 : syskin 1301 xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
313 : suxen_drol 888 m_create.handle = NULL;
314 :     }
315 : syskin 1301
316 :     if (m_hdll != NULL)
317 :     {
318 :     FreeLibrary(m_hdll);
319 :     m_hdll = NULL;
320 :     }
321 : suxen_drol 888 }
322 :    
323 :    
324 :    
325 :     /* check input type */
326 :    
327 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
328 :     {
329 :     DPRINTF("CheckInputType");
330 :     BITMAPINFOHEADER * hdr;
331 :    
332 :     if (*mtIn->Type() != MEDIATYPE_Video)
333 :     {
334 :     DPRINTF("Error: Unknown Type");
335 :     return VFW_E_TYPE_NOT_ACCEPTED;
336 :     }
337 :    
338 :     if (*mtIn->FormatType() == FORMAT_VideoInfo)
339 :     {
340 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
341 :     hdr = &vih->bmiHeader;
342 : syskin 1307 ar_x = vih->bmiHeader.biXPelsPerMeter*hdr->biWidth;
343 :     ar_y = vih->bmiHeader.biYPelsPerMeter*hdr->biHeight;
344 : suxen_drol 888 }
345 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
346 :     {
347 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
348 :     hdr = &vih2->bmiHeader;
349 : syskin 1307 ar_x = vih2->dwPictAspectRatioX;
350 :     ar_y = vih2->dwPictAspectRatioY;
351 : suxen_drol 888 }
352 :     else
353 :     {
354 :     DPRINTF("Error: Unknown FormatType");
355 :     return VFW_E_TYPE_NOT_ACCEPTED;
356 :     }
357 :    
358 :     if (hdr->biHeight < 0)
359 :     {
360 :     DPRINTF("colorspace: inverted input format not supported");
361 :     }
362 :    
363 :     m_create.width = hdr->biWidth;
364 :     m_create.height = hdr->biHeight;
365 :    
366 :     switch(hdr->biCompression)
367 :     {
368 :     case FOURCC_XVID :
369 :     // case FOURCC_DIVX :
370 :     // case FOURCC_DX50 :
371 :     break;
372 :    
373 :     default :
374 :     DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
375 :     hdr->biCompression,
376 :     (hdr->biCompression)&0xff,
377 :     (hdr->biCompression>>8)&0xff,
378 :     (hdr->biCompression>>16)&0xff,
379 :     (hdr->biCompression>>24)&0xff);
380 :     return VFW_E_TYPE_NOT_ACCEPTED;
381 :     }
382 :    
383 :     return S_OK;
384 :     }
385 :    
386 :    
387 :     /* get list of supported output colorspaces */
388 :    
389 : suxen_drol 1208
390 : suxen_drol 888 HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
391 :     {
392 :     DPRINTF("GetMediaType");
393 :    
394 :     if (m_pInput->IsConnected() == FALSE)
395 :     {
396 :     return E_UNEXPECTED;
397 :     }
398 :    
399 : syskin 1307 VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
400 : suxen_drol 888 if (vih == NULL)
401 :     {
402 :     return E_OUTOFMEMORY;
403 :     }
404 :    
405 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
406 :     vih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
407 :     vih->bmiHeader.biWidth = m_create.width;
408 :     vih->bmiHeader.biHeight = m_create.height;
409 :     vih->bmiHeader.biPlanes = 1;
410 :    
411 :     if (iPosition < 0)
412 :     {
413 :     return E_INVALIDARG;
414 :     }
415 :    
416 :     switch(iPosition)
417 :     {
418 : syskin 1307
419 :     case 0:
420 : Isibaar 1260 if ( USE_YUY2 )
421 :     {
422 : suxen_drol 888 vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1;
423 :     vih->bmiHeader.biBitCount = 16;
424 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
425 :     break;
426 : Isibaar 1260 }
427 : syskin 1307 case 1 :
428 : Isibaar 1260 if ( USE_YVYU )
429 :     {
430 : suxen_drol 888 vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1;
431 :     vih->bmiHeader.biBitCount = 16;
432 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
433 :     break;
434 : Isibaar 1260 }
435 : syskin 1307 case 2 :
436 : Isibaar 1260 if ( USE_UYVY )
437 :     {
438 : suxen_drol 888 vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1;
439 :     vih->bmiHeader.biBitCount = 16;
440 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
441 :     break;
442 : Isibaar 1260 }
443 : syskin 1307 case 3 :
444 :     if ( USE_IYUV )
445 :     {
446 :     vih->bmiHeader.biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
447 :     vih->bmiHeader.biBitCount = 12;
448 :     mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
449 :     break;
450 :     }
451 :     case 4 :
452 :     if ( USE_YV12 )
453 :     {
454 :     vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1;
455 :     vih->bmiHeader.biBitCount = 12;
456 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
457 :     break;
458 :     }
459 : suxen_drol 888 case 5 :
460 : Isibaar 1260 if ( USE_RGB32 )
461 :     {
462 : suxen_drol 888 vih->bmiHeader.biCompression = BI_RGB;
463 :     vih->bmiHeader.biBitCount = 32;
464 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
465 :     break;
466 : Isibaar 1260 }
467 : suxen_drol 888 case 6 :
468 : Isibaar 1260 if ( USE_RGB24 )
469 :     {
470 : suxen_drol 888 vih->bmiHeader.biCompression = BI_RGB;
471 :     vih->bmiHeader.biBitCount = 24;
472 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
473 :     break;
474 : Isibaar 1260 }
475 : suxen_drol 888 case 7 :
476 : Isibaar 1260 if ( USE_RG555 )
477 :     {
478 : suxen_drol 888 vih->bmiHeader.biCompression = BI_RGB;
479 :     vih->bmiHeader.biBitCount = 16;
480 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
481 :     break;
482 : Isibaar 1260 }
483 : suxen_drol 888 case 8 :
484 : Isibaar 1260 if ( USE_RG565 )
485 :     {
486 : suxen_drol 888 vih->bmiHeader.biCompression = BI_RGB;
487 :     vih->bmiHeader.biBitCount = 16;
488 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
489 :     break;
490 : Isibaar 1260 }
491 : suxen_drol 888 default :
492 :     return VFW_S_NO_MORE_ITEMS;
493 :     }
494 :    
495 :     vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader);
496 :    
497 : syskin 1307 if (ar_x != 0 && ar_y != 0) {
498 :     vih->dwPictAspectRatioX = ar_x;
499 :     vih->dwPictAspectRatioY = ar_y;
500 :     } else { // just to be safe
501 :     vih->dwPictAspectRatioX = m_create.width;
502 :     vih->dwPictAspectRatioY = m_create.height;
503 :     }
504 :    
505 : suxen_drol 888 mtOut->SetType(&MEDIATYPE_Video);
506 : syskin 1307 mtOut->SetFormatType(&FORMAT_VideoInfo2);
507 : suxen_drol 888 mtOut->SetTemporalCompression(FALSE);
508 :     mtOut->SetSampleSize(vih->bmiHeader.biSizeImage);
509 :    
510 :     return S_OK;
511 :     }
512 :    
513 :    
514 :     /* (internal function) change colorspace */
515 :    
516 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
517 :     {
518 :     if (formattype == FORMAT_VideoInfo)
519 :     {
520 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
521 :     m_frame.output.stride[0] = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3;
522 :     rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
523 :     }
524 :     else if (formattype == FORMAT_VideoInfo2)
525 :     {
526 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
527 :     m_frame.output.stride[0] = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3;
528 :     rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
529 :     }
530 :     else
531 :     {
532 :     return S_FALSE;
533 :     }
534 :    
535 : suxen_drol 1208 if (subtype == CLSID_MEDIASUBTYPE_IYUV)
536 : suxen_drol 888 {
537 :     DPRINTF("IYUV");
538 :     m_frame.output.csp = XVID_CSP_I420;
539 :     m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */
540 :     }
541 :     else if (subtype == MEDIASUBTYPE_YV12)
542 :     {
543 :     DPRINTF("YV12");
544 :     m_frame.output.csp = XVID_CSP_YV12;
545 :     m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */
546 :     }
547 :     else if (subtype == MEDIASUBTYPE_YUY2)
548 :     {
549 :     DPRINTF("YUY2");
550 :     m_frame.output.csp = XVID_CSP_YUY2;
551 :     }
552 :     else if (subtype == MEDIASUBTYPE_YVYU)
553 :     {
554 :     DPRINTF("YVYU");
555 :     m_frame.output.csp = XVID_CSP_YVYU;
556 :     }
557 :     else if (subtype == MEDIASUBTYPE_UYVY)
558 :     {
559 :     DPRINTF("UYVY");
560 :     m_frame.output.csp = XVID_CSP_UYVY;
561 :     }
562 :     else if (subtype == MEDIASUBTYPE_RGB32)
563 :     {
564 :     DPRINTF("RGB32");
565 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
566 :     }
567 :     else if (subtype == MEDIASUBTYPE_RGB24)
568 :     {
569 :     DPRINTF("RGB24");
570 :     m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
571 :     }
572 :     else if (subtype == MEDIASUBTYPE_RGB555)
573 :     {
574 :     DPRINTF("RGB555");
575 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
576 :     }
577 :     else if (subtype == MEDIASUBTYPE_RGB565)
578 :     {
579 :     DPRINTF("RGB565");
580 :     m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
581 :     }
582 :     else if (subtype == GUID_NULL)
583 :     {
584 :     m_frame.output.csp = XVID_CSP_NULL;
585 :     }
586 :     else
587 :     {
588 :     return S_FALSE;
589 :     }
590 :    
591 :     return S_OK;
592 :     }
593 :    
594 :    
595 :     /* set output colorspace */
596 :    
597 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
598 :     {
599 :     DPRINTF("SetMediaType");
600 :    
601 :     if (direction == PINDIR_OUTPUT)
602 :     {
603 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
604 :     }
605 :    
606 :     return S_OK;
607 :     }
608 :    
609 :    
610 :     /* check input<->output compatiblity */
611 :    
612 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
613 :     {
614 :     DPRINTF("CheckTransform");
615 :     return S_OK;
616 :     }
617 :    
618 :    
619 :     /* alloc output buffer */
620 :    
621 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
622 :     {
623 :     DPRINTF("DecideBufferSize");
624 :     HRESULT result;
625 :     ALLOCATOR_PROPERTIES ppropActual;
626 :    
627 :     if (m_pInput->IsConnected() == FALSE)
628 :     {
629 :     return E_UNEXPECTED;
630 :     }
631 :    
632 :     ppropInputRequest->cBuffers = 1;
633 :     ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
634 :     // cbAlign causes problems with the resize filter */
635 :     // ppropInputRequest->cbAlign = 16;
636 :     ppropInputRequest->cbPrefix = 0;
637 :    
638 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
639 :     if (result != S_OK)
640 :     {
641 :     return result;
642 :     }
643 :    
644 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
645 :     {
646 :     return E_FAIL;
647 :     }
648 :    
649 :     return S_OK;
650 :     }
651 :    
652 :    
653 :     /* decode frame */
654 :    
655 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
656 :     {
657 :     DPRINTF("Transform");
658 :     xvid_dec_stats_t stats;
659 :     int length;
660 :    
661 :     memset(&stats, 0, sizeof(stats));
662 :     stats.version = XVID_VERSION;
663 :    
664 :     if (m_create.handle == NULL)
665 :     {
666 : syskin 1301 if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
667 : suxen_drol 888 {
668 :     DPRINTF("*** XVID_DEC_CREATE error");
669 :     return S_FALSE;
670 :     }
671 :     }
672 :    
673 :     AM_MEDIA_TYPE * mtOut;
674 :     pOut->GetMediaType(&mtOut);
675 :     if (mtOut != NULL)
676 :     {
677 :     HRESULT result;
678 :    
679 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
680 :     DeleteMediaType(mtOut);
681 :    
682 :     if (result != S_OK)
683 :     {
684 :     DPRINTF("*** ChangeColorspace error");
685 :     return result;
686 :     }
687 :     }
688 :    
689 :     m_frame.length = pIn->GetActualDataLength();
690 :     if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
691 :     {
692 :     return S_FALSE;
693 :     }
694 :    
695 :     if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
696 :     {
697 :     return S_FALSE;
698 :     }
699 :    
700 :     m_frame.general = XVID_LOWDELAY;
701 : Isibaar 1260
702 : suxen_drol 888 if (pIn->IsDiscontinuity() == S_OK)
703 :     m_frame.general = XVID_DISCONTINUITY;
704 :    
705 : Isibaar 1260 if (PPSettings.bDeblock_Y)
706 :     m_frame.general |= XVID_DEBLOCKY;
707 :    
708 :     if (PPSettings.bDeblock_UV)
709 :     m_frame.general |= XVID_DEBLOCKUV;
710 : Isibaar 1271 /*
711 :     if (PPSettings.bDering)
712 :     m_frame.general |= XVID_DERING;
713 :     */
714 :     if (PPSettings.bFilmEffect)
715 :     m_frame.general |= XVID_FILMEFFECT;
716 :    
717 : syskin 1307 m_frame.output.csp &= ~XVID_CSP_VFLIP;
718 :     m_frame.output.csp |= rgb_flip^(PPSettings.bFlipVideo ? XVID_CSP_VFLIP : 0);
719 : Isibaar 1260
720 : suxen_drol 888 repeat :
721 :    
722 :     if (pIn->IsPreroll() != S_OK)
723 :     {
724 : syskin 1301 length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
725 : syskin 1250
726 : suxen_drol 888 if (length < 0)
727 :     {
728 :     DPRINTF("*** XVID_DEC_DECODE");
729 :     return S_FALSE;
730 :     }
731 :     }
732 :     else
733 : Isibaar 1300 { /* Preroll frame - won't be displayed */
734 : suxen_drol 888 int tmp = m_frame.output.csp;
735 : Isibaar 1300 int tmp_gen = m_frame.general;
736 :    
737 : suxen_drol 888 m_frame.output.csp = XVID_CSP_NULL;
738 :    
739 : Isibaar 1300 /* Disable postprocessing to speed-up seeking */
740 :     m_frame.general &= ~XVID_DEBLOCKY;
741 :     m_frame.general &= ~XVID_DEBLOCKUV;
742 :     /* m_frame.general &= ~XVID_DERING; */
743 :     m_frame.general &= ~XVID_FILMEFFECT;
744 :    
745 : syskin 1301 length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
746 : suxen_drol 888 if (length < 0)
747 :     {
748 :     DPRINTF("*** XVID_DEC_DECODE");
749 :     return S_FALSE;
750 :     }
751 :    
752 :     m_frame.output.csp = tmp;
753 : Isibaar 1300 m_frame.general = tmp_gen;
754 : suxen_drol 888 }
755 :    
756 : syskin 1250 if (stats.type == XVID_TYPE_NOTHING) {
757 :     DPRINTF("B-Frame decoder lag");
758 :     return S_FALSE;
759 :     }
760 :    
761 :    
762 : suxen_drol 888 if (stats.type == XVID_TYPE_VOL)
763 :     {
764 :     if (stats.data.vol.width != m_create.width ||
765 :     stats.data.vol.height != m_create.height)
766 :     {
767 :     DPRINTF("TODO: auto-resize");
768 :     return S_FALSE;
769 :     }
770 :    
771 : Isibaar 1300 pOut->SetDiscontinuity(TRUE);
772 :     pOut->SetSyncPoint(TRUE);
773 :    
774 : suxen_drol 888 m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
775 :     m_frame.length -= length;
776 :     goto repeat;
777 :     }
778 :    
779 : Isibaar 1300 if (pIn->IsPreroll() == S_OK) {
780 :     return S_FALSE;
781 :     }
782 :    
783 : suxen_drol 888 return S_OK;
784 :     }
785 :    
786 :    
787 :     /* get property page list */
788 :    
789 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
790 :     {
791 :     DPRINTF("GetPages");
792 :    
793 :     pPages->cElems = 1;
794 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
795 :     if (pPages->pElems == NULL)
796 :     {
797 :     return E_OUTOFMEMORY;
798 :     }
799 :     pPages->pElems[0] = CLSID_CABOUT;
800 :    
801 :     return S_OK;
802 :     }
803 :    
804 :    
805 :     /* cleanup pages */
806 :    
807 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
808 :     {
809 :     DPRINTF("FreePages");
810 :     CoTaskMemFree(pPages->pElems);
811 :     return S_OK;
812 :     }

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