[svn] / trunk / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Annotation of /trunk/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 855 - (view) (download)

1 : suxen_drol 855 /**************************************************************************
2 :     *
3 :     * XVID DIRECTSHOW FRONTEND -- decoder fitler
4 :     * Copyright (c) 2002 Peter Ross <pross@xvid.org>
5 :     *
6 :     * This program is free software; you can redistribute it and/or modify
7 :     * it under the terms of the GNU General Public License as published by
8 :     * the Free Software Foundation; either version 2 of the License, or
9 :     * (at your option) any later version.
10 :     *
11 :     * This program is distributed in the hope that it will be useful,
12 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     * GNU General Public License for more details.
15 :     *
16 :     * You should have received a copy of the GNU General Public License
17 :     * along with this program; if not, write to the Free Software
18 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 :     *
20 :     *************************************************************************/
21 :    
22 :     /*
23 : Isibaar 6 this requires the directx sdk
24 :     place these paths at the top of the Tools|Options|Directories list
25 :    
26 :     headers:
27 :     C:\DXVCSDK\include
28 :     C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses
29 :    
30 :     libraries (optional):
31 :     C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release
32 :     */
33 :    
34 : suxen_drol 855
35 :    
36 : Isibaar 6 #include <windows.h>
37 :    
38 :     #include <streams.h>
39 :     #include <initguid.h>
40 :     #include <olectl.h>
41 :     #if (1100 > _MSC_VER)
42 :     #include <olectlid.h>
43 :     #endif
44 :     #include <dvdmedia.h> // VIDEOINFOHEADER2
45 :    
46 : Isibaar 380 #include <xvid.h> // XviD API
47 :    
48 : Isibaar 6 #include "IXvidDecoder.h"
49 :     #include "CXvidDecoder.h"
50 :     #include "CAbout.h"
51 :    
52 :    
53 :     const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
54 :     {
55 :     { &MEDIATYPE_Video, &CLSID_XVID },
56 :     { &MEDIATYPE_Video, &CLSID_XVID_UC },
57 :     { &MEDIATYPE_Video, &CLSID_DIVX },
58 : suxen_drol 855 { &MEDIATYPE_Video, &CLSID_DIVX_UC },
59 :     { &MEDIATYPE_Video, &CLSID_DX50 },
60 :     { &MEDIATYPE_Video, &CLSID_DX50_UC },
61 : Isibaar 6 };
62 :    
63 :     const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
64 :     {
65 :     { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }
66 :     };
67 :    
68 :    
69 :     const AMOVIESETUP_PIN psudPins[] =
70 :     {
71 :     {
72 :     L"Input", // String pin name
73 :     FALSE, // Is it rendered
74 :     FALSE, // Is it an output
75 :     FALSE, // Allowed none
76 :     FALSE, // Allowed many
77 :     &CLSID_NULL, // Connects to filter
78 :     L"Output", // Connects to pin
79 :     sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
80 :     &sudInputPinTypes[0] // The pin details
81 :     },
82 :     {
83 :     L"Output", // String pin name
84 :     FALSE, // Is it rendered
85 :     TRUE, // Is it an output
86 :     FALSE, // Allowed none
87 :     FALSE, // Allowed many
88 :     &CLSID_NULL, // Connects to filter
89 :     L"Input", // Connects to pin
90 :     sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types
91 :     sudOutputPinTypes // The pin details
92 :     }
93 :     };
94 :    
95 :    
96 :     const AMOVIESETUP_FILTER sudXvidDecoder =
97 :     {
98 :     &CLSID_XVID, // Filter CLSID
99 :     XVID_NAME_L, // Filter name
100 :     MERIT_PREFERRED, // Its merit
101 :     sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins
102 :     psudPins // Pin details
103 :     };
104 :    
105 :    
106 :     // List of class IDs and creator functions for the class factory. This
107 :     // provides the link between the OLE entry point in the DLL and an object
108 :     // being created. The class factory will call the static CreateInstance
109 :    
110 :     CFactoryTemplate g_Templates[] =
111 :     {
112 :     {
113 :     XVID_NAME_L,
114 :     &CLSID_XVID,
115 :     CXvidDecoder::CreateInstance,
116 :     NULL,
117 :     &sudXvidDecoder
118 :     },
119 :     {
120 :     XVID_NAME_L L"About",
121 :     &CLSID_CABOUT,
122 :     CAbout::CreateInstance
123 :     }
124 :    
125 :     };
126 :    
127 :     int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);
128 :    
129 :    
130 :    
131 :    
132 :     STDAPI DllRegisterServer()
133 :     {
134 :     return AMovieDllRegisterServer2( TRUE );
135 :     }
136 :    
137 :    
138 :     STDAPI DllUnregisterServer()
139 :     {
140 :     return AMovieDllRegisterServer2( FALSE );
141 :     }
142 :    
143 :    
144 :     /* create instance */
145 :    
146 :     CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
147 :     {
148 :     CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr);
149 :     if (pNewObject == NULL)
150 :     {
151 :     *phr = E_OUTOFMEMORY;
152 :     }
153 :     return pNewObject;
154 :     }
155 :    
156 :    
157 :     /* query interfaces */
158 :    
159 :     STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv)
160 :     {
161 :     CheckPointer(ppv, E_POINTER);
162 :    
163 :     if (riid == IID_IXvidDecoder)
164 :     {
165 :     return GetInterface((IXvidDecoder *) this, ppv);
166 :     }
167 :    
168 :     if (riid == IID_ISpecifyPropertyPages)
169 :     {
170 :     return GetInterface((ISpecifyPropertyPages *) this, ppv);
171 :     }
172 :    
173 :     return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv);
174 :     }
175 :    
176 :    
177 :    
178 :     /* dummy decore() */
179 :    
180 :     static int dummy_xvid_decore(void * handle, int opt, void * param1, void * param2)
181 :     {
182 :     return XVID_ERR_FAIL;
183 :     }
184 :    
185 :    
186 :    
187 :     /* constructor */
188 :    
189 :     #define XVID_DLL_NAME "xvid.dll"
190 :     #define XVID_INIT_NAME "xvid_init"
191 :     #define XVID_DECORE_NAME "xvid_decore"
192 :    
193 :     CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
194 :     CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID)
195 :     {
196 : suxen_drol 855 DPRINTF("Constructor");
197 : Isibaar 6
198 :     m_xvid_decore = dummy_xvid_decore;
199 :    
200 :     m_hdll = LoadLibrary(XVID_DLL_NAME);
201 :     if (m_hdll == NULL) {
202 : suxen_drol 855 DPRINTF("dll load failed");
203 : Isibaar 6 MessageBox(0, XVID_DLL_NAME " not found","Error", 0);
204 :     return;
205 :     }
206 :    
207 :     m_xvid_init = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, XVID_INIT_NAME);
208 :     if (m_xvid_init == NULL) {
209 :     MessageBox(0, XVID_INIT_NAME "() not found", "Error", 0);
210 :     return;
211 :     }
212 :    
213 :     m_xvid_decore = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, XVID_DECORE_NAME);
214 :     if (m_xvid_decore == NULL) {
215 :     MessageBox(0, XVID_DECORE_NAME "() not found", "Error", 0);
216 :     return;
217 :     }
218 :    
219 :     XVID_INIT_PARAM init;
220 :    
221 :     init.cpu_flags = 0;
222 :     if (m_xvid_init(0, 0, &init, 0) != XVID_ERR_OK)
223 :     {
224 :     MessageBox(0, XVID_INIT_NAME "() failed", "Error", 0);
225 :     return;
226 :     }
227 :    
228 :     if (init.api_version < API_VERSION)
229 :     {
230 :     MessageBox(0, XVID_DLL_NAME " implements an older api version; update your " XVID_DLL_NAME, "Warning", 0);
231 :     }
232 :     else if (init.api_version > API_VERSION)
233 :     {
234 :     MessageBox(0, XVID_DLL_NAME " implements a newer api version; update your directshow filter", "Error", 0);
235 :     return;
236 :     }
237 :    
238 :     m_param.handle = NULL;
239 :     }
240 :    
241 :    
242 :    
243 :     /* destructor */
244 :    
245 :     CXvidDecoder::~CXvidDecoder()
246 :     {
247 : suxen_drol 855 DPRINTF("Destructor");
248 : Isibaar 6
249 :     if (m_param.handle != NULL)
250 :     {
251 :     m_xvid_decore(m_param.handle, XVID_DEC_DESTROY, 0, 0);
252 :     m_param.handle = NULL;
253 :     }
254 :    
255 :     if (m_hdll != NULL)
256 :     {
257 :     FreeLibrary(m_hdll);
258 :     m_hdll = NULL;
259 :     }
260 :     }
261 :    
262 :    
263 :    
264 :     /* check input type */
265 :    
266 :     HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
267 :     {
268 : suxen_drol 855 DPRINTF("CheckInputType");
269 : Isibaar 6 BITMAPINFOHEADER * hdr;
270 : suxen_drol 855
271 : Isibaar 6 if (*mtIn->Type() != MEDIATYPE_Video)
272 :     {
273 : suxen_drol 855 DPRINTF("Error: Unknown Type");
274 : Isibaar 6 return VFW_E_TYPE_NOT_ACCEPTED;
275 :     }
276 :    
277 :     if (*mtIn->FormatType() == FORMAT_VideoInfo)
278 :     {
279 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
280 :     hdr = &vih->bmiHeader;
281 :     }
282 :     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
283 :     {
284 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
285 :     hdr = &vih2->bmiHeader;
286 :     }
287 :     else
288 :     {
289 : suxen_drol 855 DPRINTF("Error: Unknown FormatType");
290 : Isibaar 6 return VFW_E_TYPE_NOT_ACCEPTED;
291 :     }
292 :    
293 :     if (hdr->biHeight < 0)
294 :     {
295 : suxen_drol 855 DPRINTF("colorspace: inverted input format not supported");
296 : Isibaar 6 }
297 :    
298 :     m_param.width = hdr->biWidth;
299 :     m_param.height = hdr->biHeight;
300 :    
301 :     switch(hdr->biCompression)
302 :     {
303 :     case FOURCC_XVID :
304 :     // case FOURCC_DIVX :
305 : suxen_drol 855 // case FOURCC_DX50 :
306 : Isibaar 6 break;
307 :    
308 :     default :
309 : suxen_drol 855 DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
310 :     hdr->biCompression,
311 :     (hdr->biCompression)&0xff,
312 :     (hdr->biCompression>>8)&0xff,
313 :     (hdr->biCompression>>16)&0xff,
314 :     (hdr->biCompression>>24)&0xff);
315 : Isibaar 6 return VFW_E_TYPE_NOT_ACCEPTED;
316 :     }
317 :    
318 :     return S_OK;
319 :     }
320 :    
321 :    
322 : suxen_drol 855 #define USE_IYUV
323 :     #define USE_YV12
324 :     #define USE_YUY2
325 :     #define USE_YVYU
326 :     #define USE_UYVY
327 :     #define USE_RGB32
328 :     #define USE_RGB24
329 :     #define USE_RG555
330 :     #define USE_RG565
331 :    
332 : Isibaar 6 /* get list of supported output colorspaces */
333 :    
334 :     HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
335 :     {
336 : suxen_drol 855 DPRINTF("GetMediaType");
337 : Isibaar 6
338 :     if (m_pInput->IsConnected() == FALSE)
339 :     {
340 :     return E_UNEXPECTED;
341 :     }
342 :    
343 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
344 :     if (vih == NULL)
345 :     {
346 :     return E_OUTOFMEMORY;
347 :     }
348 :    
349 :     ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
350 :     vih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
351 :     vih->bmiHeader.biWidth = m_param.width;
352 :     vih->bmiHeader.biHeight = m_param.height;
353 :     vih->bmiHeader.biPlanes = 1;
354 :    
355 :     if (iPosition < 0)
356 :     {
357 :     return E_INVALIDARG;
358 :     }
359 :    
360 :     switch(iPosition)
361 :     {
362 :     case 0 :
363 : suxen_drol 855 #ifdef USE_IYUV
364 : suxen_drol 615 vih->bmiHeader.biCompression = MEDIASUBTYPE_IYUV.Data1;
365 :     vih->bmiHeader.biBitCount = 12;
366 :     mtOut->SetSubtype(&MEDIASUBTYPE_IYUV);
367 :     break;
368 : suxen_drol 855 #endif
369 : suxen_drol 615 case 1 :
370 : suxen_drol 855 #ifdef USE_YV12
371 : Isibaar 6 vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1;
372 :     vih->bmiHeader.biBitCount = 12;
373 :     mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
374 :     break;
375 : suxen_drol 855 #endif
376 : suxen_drol 615 case 2:
377 : suxen_drol 855 #ifdef USE_YUY2
378 : Isibaar 6 vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1;
379 :     vih->bmiHeader.biBitCount = 16;
380 :     mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
381 :     break;
382 : suxen_drol 855 #endif
383 : suxen_drol 615 case 3 :
384 : suxen_drol 855 #ifdef USE_YVYU
385 : Isibaar 6 vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1;
386 :     vih->bmiHeader.biBitCount = 16;
387 :     mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
388 :     break;
389 : suxen_drol 855 #endif
390 : suxen_drol 615 case 4 :
391 : suxen_drol 855 #ifdef USE_UYVY
392 : Isibaar 6 vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1;
393 :     vih->bmiHeader.biBitCount = 16;
394 :     mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
395 :     break;
396 : suxen_drol 855 #endif
397 : suxen_drol 615 case 5 :
398 : suxen_drol 855 #ifdef USE_RGB32
399 : Isibaar 6 vih->bmiHeader.biCompression = BI_RGB;
400 :     vih->bmiHeader.biBitCount = 32;
401 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
402 :     break;
403 : suxen_drol 855 #endif
404 : suxen_drol 615 case 6 :
405 : suxen_drol 855 #ifdef USE_RGB24
406 : Isibaar 6 vih->bmiHeader.biCompression = BI_RGB;
407 :     vih->bmiHeader.biBitCount = 24;
408 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
409 :     break;
410 : suxen_drol 855 #endif
411 : suxen_drol 615 case 7 :
412 : suxen_drol 855 #ifdef USE_RG555
413 : Isibaar 6 vih->bmiHeader.biCompression = BI_RGB;
414 :     vih->bmiHeader.biBitCount = 16;
415 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
416 :     break;
417 : suxen_drol 855 #endif
418 : suxen_drol 615 case 8 :
419 : suxen_drol 855 #ifdef USE_RG565
420 : Isibaar 6 vih->bmiHeader.biCompression = BI_RGB;
421 :     vih->bmiHeader.biBitCount = 16;
422 :     mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
423 :     break;
424 : suxen_drol 855 #endif
425 : Isibaar 6 default :
426 :     return VFW_S_NO_MORE_ITEMS;
427 :     }
428 :    
429 :     vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader);
430 :    
431 :     mtOut->SetType(&MEDIATYPE_Video);
432 :     mtOut->SetFormatType(&FORMAT_VideoInfo);
433 :     mtOut->SetTemporalCompression(FALSE);
434 :     mtOut->SetSampleSize(vih->bmiHeader.biSizeImage);
435 :    
436 :     return S_OK;
437 :     }
438 :    
439 :    
440 :     /* (internal function) change colorspace */
441 :    
442 :     HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
443 :     {
444 : suxen_drol 855 int rgb_flip;
445 :    
446 :     if (formattype == FORMAT_VideoInfo)
447 :     {
448 :     VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
449 :     m_frame.stride = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3;
450 :     rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
451 :     }
452 :     else if (formattype == FORMAT_VideoInfo2)
453 :     {
454 :     VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
455 :     m_frame.stride = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3;
456 :     rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
457 :     }
458 :     else
459 :     {
460 :     return S_FALSE;
461 :     }
462 :    
463 : suxen_drol 615 if (subtype == MEDIASUBTYPE_IYUV)
464 : Isibaar 6 {
465 : suxen_drol 855 DPRINTF("IYUV");
466 : suxen_drol 615 m_frame.colorspace = XVID_CSP_I420;
467 : suxen_drol 855 m_frame.stride = (m_frame.stride * 2) / 3; /* planar format fix */
468 : suxen_drol 615 }
469 :     else if (subtype == MEDIASUBTYPE_YV12)
470 :     {
471 : suxen_drol 855 DPRINTF("YV12");
472 : Isibaar 6 m_frame.colorspace = XVID_CSP_YV12;
473 : suxen_drol 855 m_frame.stride = (m_frame.stride * 2) / 3; /* planar format fix */
474 : Isibaar 6 }
475 :     else if (subtype == MEDIASUBTYPE_YUY2)
476 :     {
477 : suxen_drol 855 DPRINTF("YUY2");
478 : Isibaar 6 m_frame.colorspace = XVID_CSP_YUY2;
479 :     }
480 :     else if (subtype == MEDIASUBTYPE_YVYU)
481 :     {
482 : suxen_drol 855 DPRINTF("YVYU");
483 : Isibaar 6 m_frame.colorspace = XVID_CSP_YVYU;
484 :     }
485 :     else if (subtype == MEDIASUBTYPE_UYVY)
486 :     {
487 : suxen_drol 855 DPRINTF("UYVY");
488 : Isibaar 6 m_frame.colorspace = XVID_CSP_UYVY;
489 :     }
490 :     else if (subtype == MEDIASUBTYPE_RGB32)
491 :     {
492 : suxen_drol 855 DPRINTF("RGB32");
493 :     m_frame.colorspace = rgb_flip | XVID_CSP_RGB32;
494 : Isibaar 6 }
495 :     else if (subtype == MEDIASUBTYPE_RGB24)
496 :     {
497 : suxen_drol 855 DPRINTF("RGB24");
498 :     m_frame.colorspace = rgb_flip | XVID_CSP_RGB24;
499 : Isibaar 6 }
500 :     else if (subtype == MEDIASUBTYPE_RGB555)
501 :     {
502 : suxen_drol 855 DPRINTF("RGB555");
503 :     m_frame.colorspace = rgb_flip | XVID_CSP_RGB555;
504 : Isibaar 6 }
505 :     else if (subtype == MEDIASUBTYPE_RGB565)
506 :     {
507 : suxen_drol 855 DPRINTF("RGB565");
508 :     m_frame.colorspace = rgb_flip | XVID_CSP_RGB565;
509 : Isibaar 6 }
510 :     else if (subtype == GUID_NULL)
511 :     {
512 :     m_frame.colorspace = XVID_CSP_NULL;
513 :     }
514 :     else
515 :     {
516 :     return S_FALSE;
517 :     }
518 :    
519 :     return S_OK;
520 :     }
521 :    
522 :    
523 :     /* set output colorspace */
524 :    
525 :     HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
526 :     {
527 : suxen_drol 855 DPRINTF("SetMediaType");
528 : Isibaar 6
529 :     if (direction == PINDIR_OUTPUT)
530 :     {
531 :     return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
532 :     }
533 :    
534 :     return S_OK;
535 :     }
536 :    
537 :    
538 :     /* check input<->output compatiblity */
539 :    
540 :     HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
541 :     {
542 : suxen_drol 855 DPRINTF("CheckTransform");
543 : Isibaar 6 return S_OK;
544 :     }
545 :    
546 :    
547 :     /* alloc output buffer */
548 :    
549 :     HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
550 :     {
551 : suxen_drol 855 DPRINTF("DecideBufferSize");
552 : Isibaar 6 HRESULT result;
553 :     ALLOCATOR_PROPERTIES ppropActual;
554 :    
555 :     if (m_pInput->IsConnected() == FALSE)
556 :     {
557 :     return E_UNEXPECTED;
558 :     }
559 :    
560 :     ppropInputRequest->cBuffers = 1;
561 :     ppropInputRequest->cbBuffer = m_param.width * m_param.height * 4;
562 :     // cbAlign causes problems with the resize filter */
563 :     // ppropInputRequest->cbAlign = 16;
564 :     ppropInputRequest->cbPrefix = 0;
565 :    
566 :     result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
567 :     if (result != S_OK)
568 :     {
569 :     return result;
570 :     }
571 :    
572 :     if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
573 :     {
574 :     return E_FAIL;
575 :     }
576 :    
577 :     return S_OK;
578 :     }
579 :    
580 :    
581 :     /* decode frame */
582 :    
583 :     HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
584 :     {
585 : suxen_drol 855 DPRINTF("Transform");
586 :     XVID_DEC_STATS stats;
587 : Isibaar 6
588 : suxen_drol 855 BYTE * bitstream;
589 :     int length;
590 :    
591 : Isibaar 6 if (m_param.handle == NULL)
592 :     {
593 :     if (m_xvid_decore(0, XVID_DEC_CREATE, &m_param, 0) != XVID_ERR_OK)
594 :     {
595 :     return S_FALSE;
596 :     }
597 :     }
598 :    
599 :     AM_MEDIA_TYPE * mtOut;
600 :     pOut->GetMediaType(&mtOut);
601 :     if (mtOut != NULL)
602 :     {
603 :     HRESULT result;
604 :    
605 :     result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
606 :     DeleteMediaType(mtOut);
607 :    
608 :     if (result != S_OK)
609 :     {
610 :     return result;
611 :     }
612 :     }
613 :    
614 : suxen_drol 855 length = pIn->GetActualDataLength();
615 :     if (pIn->GetPointer((BYTE**)&bitstream) != S_OK)
616 : Isibaar 6 {
617 :     return S_FALSE;
618 :     }
619 :    
620 :     if (pOut->GetPointer((BYTE**)&m_frame.image) != S_OK)
621 :     {
622 :     return S_FALSE;
623 :     }
624 :    
625 :    
626 : suxen_drol 855 m_frame.general = XVID_DEC_LOWDELAY;
627 :    
628 :     if (pIn->IsDiscontinuity() == S_OK)
629 :     m_frame.general = XVID_DEC_DISCONTINUITY;
630 :    
631 :     repeat :
632 :     m_frame.bitstream = bitstream;
633 :     m_frame.length = length;
634 :    
635 : Isibaar 6 if (pIn->IsPreroll() != S_OK)
636 :     {
637 : suxen_drol 855 if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, &stats) != XVID_ERR_OK)
638 : Isibaar 6 {
639 :     return S_FALSE;
640 :     }
641 :     }
642 :     else
643 :     {
644 :     int tmp = m_frame.colorspace;
645 :     m_frame.colorspace = XVID_CSP_NULL;
646 :    
647 : suxen_drol 855 if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, &stats) != XVID_ERR_OK)
648 : Isibaar 6 {
649 :     return S_FALSE;
650 :     }
651 :    
652 :     m_frame.colorspace = tmp;
653 : suxen_drol 855 }
654 : Isibaar 6
655 : suxen_drol 855 if (stats.notify == XVID_DEC_VOL)
656 :     {
657 :     if (stats.data.vol.width != m_param.width ||
658 :     stats.data.vol.height != m_param.height)
659 :     {
660 :     DPRINTF("TODO: auto-resize");
661 :     return S_FALSE;
662 :     }
663 :    
664 :     bitstream += m_frame.length;
665 :     length -= m_frame.length;
666 :     goto repeat;
667 : Isibaar 6 }
668 :    
669 : suxen_drol 855 /* only render when we decode a vop */
670 :     return (stats.notify == XVID_DEC_VOP) ? S_OK : S_FALSE;
671 : Isibaar 6 }
672 :    
673 :    
674 :     /* get property page list */
675 :    
676 :     STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
677 :     {
678 : suxen_drol 855 DPRINTF("GetPages");
679 : Isibaar 6
680 :     pPages->cElems = 1;
681 :     pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
682 :     if (pPages->pElems == NULL)
683 :     {
684 :     return E_OUTOFMEMORY;
685 :     }
686 :     pPages->pElems[0] = CLSID_CABOUT;
687 :    
688 :     return S_OK;
689 :     }
690 :    
691 :    
692 :     /* cleanup pages */
693 :    
694 :     STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
695 :     {
696 : suxen_drol 855 DPRINTF("FreePages");
697 : Isibaar 6 CoTaskMemFree(pPages->pElems);
698 :     return S_OK;
699 :     }

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