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

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

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