[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 1890 - (view) (download)

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

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