[cvs] / xvidcore / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

Diff of /xvidcore/dshow/src/CXvidDecoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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