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

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