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

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