[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.13, Thu Jan 29 07:06:04 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-2003 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    
64    // Externs defined here
65    PostProcessing_Settings PPSettings;
66    
67    int rgb_flip;
68    
69    bool USE_IYUV;
70    bool USE_YV12;
71    bool USE_YUY2;
72    bool USE_YVYU;
73    bool USE_UYVY;
74    bool USE_RGB32;
75    bool USE_RGB24;
76    bool USE_RG555;
77    bool USE_RG565;
78    
79    const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
80    {
81        { &MEDIATYPE_Video, &CLSID_XVID },
82            { &MEDIATYPE_Video, &CLSID_XVID_UC },
83            { &MEDIATYPE_Video, &CLSID_DIVX },
84            { &MEDIATYPE_Video, &CLSID_DIVX_UC },
85            { &MEDIATYPE_Video, &CLSID_DX50 },
86            { &MEDIATYPE_Video, &CLSID_DX50_UC },
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    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            HKEY hKey;
250            DWORD size;
251            RegOpenKeyEx(XVID_REG_KEY, XVID_REG_SUBKEY, 0, KEY_READ, &hKey);
252    
253            // Set the default post-processing settings
254            REG_GET_N("Brightness", PPSettings.nBrightness, 25)
255            REG_GET_N("Deblock_Y",  PPSettings.nDeblock_Y, 0)
256            REG_GET_N("Deblock_UV", PPSettings.nDeblock_UV, 0)
257            REG_GET_N("Dering",  PPSettings.nDering, 0)
258            REG_GET_N("FilmEffect", PPSettings.nFilmEffect, 0)
259            REG_GET_N("ForceColorspace", PPSettings.nForceColorspace, 0)
260            REG_GET_N("FlipVideo",  PPSettings.nFlipVideo, 0)
261    
262            RegCloseKey(hKey);
263    
264            USE_IYUV = false;
265            USE_YV12 = false;
266            USE_YUY2 = false;
267            USE_YVYU = false;
268            USE_UYVY = false;
269            USE_RGB32 = false;
270            USE_RGB24 = false;
271            USE_RG555 = false;
272            USE_RG565 = false;
273    
274            switch ( PPSettings.nForceColorspace )
275            {
276            case FORCE_NONE:
277                    USE_IYUV = true;
278                    USE_YV12 = true;
279                    USE_YUY2 = true;
280                    USE_YVYU = true;
281                    USE_UYVY = true;
282                    USE_RGB32 = true;
283                    USE_RGB24 = true;
284                    USE_RG555 = true;
285                    USE_RG565 = true;
286                    break;
287            case FORCE_YV12:
288                    USE_IYUV = true;
289                    USE_YV12 = true;
290                    break;
291            case FORCE_YUY2:
292                    USE_YUY2 = true;
293                    break;
294            case FORCE_RGB24:
295                    USE_RGB24 = true;
296                    break;
297            case FORCE_RGB32:
298                    USE_RGB32 = true;
299                    break;
300            }
301    }
302    
303    
304    
305    /* destructor */
306    
307    CXvidDecoder::~CXvidDecoder()
308    {
309            DPRINTF("Destructor");
310    
311            if (m_create.handle != NULL)
312            {
313                    xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0);
314                    m_create.handle = NULL;
315            }
316    
317            if (m_hdll != NULL)
318            {
319                    FreeLibrary(m_hdll);
320                    m_hdll = NULL;
321            }
322    }
323    
324    
325    
326    /* check input type */
327    
328    HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
329    {
330            DPRINTF("CheckInputType");
331            BITMAPINFOHEADER * hdr;
332    
333            if (*mtIn->Type() != MEDIATYPE_Video)
334            {
335                    DPRINTF("Error: Unknown Type");
336                    return VFW_E_TYPE_NOT_ACCEPTED;
337            }
338    
339            if (*mtIn->FormatType() == FORMAT_VideoInfo)
340            {
341                    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format();
342                    hdr = &vih->bmiHeader;
343                    /* PAR (x:y) is (1/ppm_X):(1/ppm_Y) where ppm is pixels-per-meter
344                       which is equal to ppm_Y:ppm_X */
345                    ar_x = vih->bmiHeader.biYPelsPerMeter*hdr->biWidth;
346                    ar_y = vih->bmiHeader.biXPelsPerMeter*hdr->biHeight;
347            }
348            else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
349            {
350                    VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format();
351                    hdr = &vih2->bmiHeader;
352                    ar_x = vih2->dwPictAspectRatioX;
353                    ar_y = vih2->dwPictAspectRatioY;
354            }
355            else
356            {
357                    DPRINTF("Error: Unknown FormatType");
358                    return VFW_E_TYPE_NOT_ACCEPTED;
359            }
360    
361            if (hdr->biHeight < 0)
362            {
363                    DPRINTF("colorspace: inverted input format not supported");
364            }
365    
366            m_create.width = hdr->biWidth;
367            m_create.height = hdr->biHeight;
368    
369            switch(hdr->biCompression)
370            {
371            case FOURCC_XVID :
372    //      case FOURCC_DIVX :
373    //      case FOURCC_DX50 :
374                    break;
375    
376            default :
377                    DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
378                            hdr->biCompression,
379                            (hdr->biCompression)&0xff,
380                            (hdr->biCompression>>8)&0xff,
381                            (hdr->biCompression>>16)&0xff,
382                            (hdr->biCompression>>24)&0xff);
383                    return VFW_E_TYPE_NOT_ACCEPTED;
384            }
385    
386            return S_OK;
387    }
388    
389    
390    /* get list of supported output colorspaces */
391    
392    
393    HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
394    {
395            DPRINTF("GetMediaType");
396    
397            if (m_pInput->IsConnected() == FALSE)
398            {
399                    return E_UNEXPECTED;
400            }
401    
402            VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
403            if (vih == NULL)
404            {
405                    return E_OUTOFMEMORY;
406            }
407    
408            ZeroMemory(vih, sizeof (VIDEOINFOHEADER));
409            vih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
410            vih->bmiHeader.biWidth  = m_create.width;
411            vih->bmiHeader.biHeight = m_create.height;
412            vih->bmiHeader.biPlanes = 1;
413    
414            if (iPosition < 0)
415            {
416                    return E_INVALIDARG;
417            }
418    
419            switch(iPosition)
420            {
421    
422            case 0:
423    if ( USE_YUY2 )
424    {
425                    vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1;
426                    vih->bmiHeader.biBitCount = 16;
427                    mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
428                    break;
429    }
430            case 1 :
431    if ( USE_YVYU )
432    {
433                    vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1;
434                    vih->bmiHeader.biBitCount = 16;
435                    mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
436                    break;
437    }
438            case 2 :
439    if ( USE_UYVY )
440    {
441                    vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1;
442                    vih->bmiHeader.biBitCount = 16;
443                    mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
444                    break;
445    }
446            case 3  :
447                    if ( USE_IYUV )
448    {
449                    vih->bmiHeader.biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;
450                    vih->bmiHeader.biBitCount = 12;
451                    mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);
452                    break;
453    }
454            case 4  :
455    if ( USE_YV12 )
456    {
457                    vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1;
458                    vih->bmiHeader.biBitCount = 12;
459                    mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
460                    break;
461    }
462            case 5 :
463    if ( USE_RGB32 )
464    {
465                    vih->bmiHeader.biCompression = BI_RGB;
466                    vih->bmiHeader.biBitCount = 32;
467                    mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
468                    break;
469    }
470            case 6 :
471    if ( USE_RGB24 )
472    {
473                    vih->bmiHeader.biCompression = BI_RGB;
474                    vih->bmiHeader.biBitCount = 24;
475                    mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
476                    break;
477    }
478            case 7 :
479    if ( USE_RG555 )
480    {
481                    vih->bmiHeader.biCompression = BI_RGB;
482                    vih->bmiHeader.biBitCount = 16;
483                    mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
484                    break;
485    }
486            case 8 :
487    if ( USE_RG565 )
488    {
489                    vih->bmiHeader.biCompression = BI_RGB;
490                    vih->bmiHeader.biBitCount = 16;
491                    mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
492                    break;
493    }
494            default :
495                    return VFW_S_NO_MORE_ITEMS;
496            }
497    
498            vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader);
499    
500            if (ar_x != 0 && ar_y != 0) {
501                    vih->dwPictAspectRatioX = ar_x;
502                    vih->dwPictAspectRatioY = ar_y;
503            } else { // just to be safe
504                    vih->dwPictAspectRatioX = m_create.width;
505                    vih->dwPictAspectRatioY = m_create.height;
506            }
507    
508            mtOut->SetType(&MEDIATYPE_Video);
509            mtOut->SetFormatType(&FORMAT_VideoInfo2);
510            mtOut->SetTemporalCompression(FALSE);
511            mtOut->SetSampleSize(vih->bmiHeader.biSizeImage);
512    
513            return S_OK;
514    }
515    
516    
517    /* (internal function) change colorspace */
518    
519    HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
520    {
521            if (formattype == FORMAT_VideoInfo)
522            {
523                    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
524                    m_frame.output.stride[0] = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3;
525                    rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
526            }
527            else if (formattype == FORMAT_VideoInfo2)
528            {
529                    VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
530                    m_frame.output.stride[0] = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3;
531                    rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
532            }
533            else
534            {
535                    return S_FALSE;
536            }
537    
538            if (subtype == CLSID_MEDIASUBTYPE_IYUV)
539            {
540                    DPRINTF("IYUV");
541                    rgb_flip = 0;
542                    m_frame.output.csp = XVID_CSP_I420;
543                    m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3;  /* planar format fix */
544            }
545            else if (subtype == MEDIASUBTYPE_YV12)
546            {
547                    DPRINTF("YV12");
548                    rgb_flip = 0;
549                    m_frame.output.csp = XVID_CSP_YV12;
550                    m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3;  /* planar format fix */
551            }
552            else if (subtype == MEDIASUBTYPE_YUY2)
553            {
554                    DPRINTF("YUY2");
555                    rgb_flip = 0;
556                    m_frame.output.csp = XVID_CSP_YUY2;
557            }
558            else if (subtype == MEDIASUBTYPE_YVYU)
559            {
560                    DPRINTF("YVYU");
561                    rgb_flip = 0;
562                    m_frame.output.csp = XVID_CSP_YVYU;
563            }
564            else if (subtype == MEDIASUBTYPE_UYVY)
565            {
566                    DPRINTF("UYVY");
567                    rgb_flip = 0;
568                    m_frame.output.csp = XVID_CSP_UYVY;
569            }
570            else if (subtype == MEDIASUBTYPE_RGB32)
571            {
572                    DPRINTF("RGB32");
573                    m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;
574            }
575            else if (subtype == MEDIASUBTYPE_RGB24)
576            {
577                    DPRINTF("RGB24");
578                    m_frame.output.csp = rgb_flip | XVID_CSP_BGR;
579            }
580            else if (subtype == MEDIASUBTYPE_RGB555)
581            {
582                    DPRINTF("RGB555");
583                    m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;
584            }
585            else if (subtype == MEDIASUBTYPE_RGB565)
586            {
587                    DPRINTF("RGB565");
588                    m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;
589            }
590            else if (subtype == GUID_NULL)
591            {
592                    m_frame.output.csp = XVID_CSP_NULL;
593            }
594            else
595            {
596                    return S_FALSE;
597            }
598    
599            return S_OK;
600    }
601    
602    
603    /* set output colorspace */
604    
605    HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
606    {
607            DPRINTF("SetMediaType");
608    
609            if (direction == PINDIR_OUTPUT)
610            {
611                    return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());
612            }
613    
614            return S_OK;
615    }
616    
617    
618    /* check input<->output compatiblity */
619    
620    HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
621    {
622            DPRINTF("CheckTransform");
623            return S_OK;
624    }
625    
626    
627    /* alloc output buffer */
628    
629    HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
630    {
631            DPRINTF("DecideBufferSize");
632            HRESULT result;
633            ALLOCATOR_PROPERTIES ppropActual;
634    
635            if (m_pInput->IsConnected() == FALSE)
636            {
637                    return E_UNEXPECTED;
638            }
639    
640            ppropInputRequest->cBuffers = 1;
641            ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;
642            // cbAlign causes problems with the resize filter */
643            // ppropInputRequest->cbAlign = 16;
644            ppropInputRequest->cbPrefix = 0;
645    
646            result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);
647            if (result != S_OK)
648            {
649                    return result;
650            }
651    
652            if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)
653            {
654                    return E_FAIL;
655            }
656    
657            return S_OK;
658    }
659    
660    
661    /* decode frame */
662    
663    HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
664    {
665            DPRINTF("Transform");
666            xvid_dec_stats_t stats;
667        int length;
668    
669            memset(&stats, 0, sizeof(stats));
670            stats.version = XVID_VERSION;
671    
672            if (m_create.handle == NULL)
673            {
674                    if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
675                    {
676                DPRINTF("*** XVID_DEC_CREATE error");
677                            return S_FALSE;
678                    }
679            }
680    
681            AM_MEDIA_TYPE * mtOut;
682            pOut->GetMediaType(&mtOut);
683            if (mtOut != NULL)
684            {
685                    HRESULT result;
686    
687                    result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
688                    DeleteMediaType(mtOut);
689    
690                    if (result != S_OK)
691                    {
692                DPRINTF("*** ChangeColorspace error");
693                            return result;
694                    }
695            }
696    
697            m_frame.length = pIn->GetActualDataLength();
698            if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
699            {
700                    return S_FALSE;
701            }
702    
703            if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
704            {
705                    return S_FALSE;
706            }
707    
708            m_frame.general = XVID_LOWDELAY;
709    
710            if (pIn->IsDiscontinuity() == S_OK)
711                    m_frame.general = XVID_DISCONTINUITY;
712    
713            if (PPSettings.nDeblock_Y)
714                    m_frame.general |= XVID_DEBLOCKY;
715    
716            if (PPSettings.nDeblock_UV)
717                    m_frame.general |= XVID_DEBLOCKUV;
718    /*
719            if (PPSettings.nDering)
720                    m_frame.general |= XVID_DERING;
721    */
722            if (PPSettings.nFilmEffect)
723                    m_frame.general |= XVID_FILMEFFECT;
724    
725            m_frame.output.csp &= ~XVID_CSP_VFLIP;
726            m_frame.output.csp |= rgb_flip^(PPSettings.nFlipVideo ? XVID_CSP_VFLIP : 0);
727    
728    repeat :
729    
730            if (pIn->IsPreroll() != S_OK)
731            {
732                    length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
733    
734                    if (length < 0)
735                    {
736                DPRINTF("*** XVID_DEC_DECODE");
737                            return S_FALSE;
738                    }
739            }
740            else
741            {       /* Preroll frame - won't be displayed */
742                    int tmp = m_frame.output.csp;
743                    int tmp_gen = m_frame.general;
744    
745                    m_frame.output.csp = XVID_CSP_NULL;
746    
747                    /* Disable postprocessing to speed-up seeking */
748                    m_frame.general &= ~XVID_DEBLOCKY;
749                    m_frame.general &= ~XVID_DEBLOCKUV;
750    /*              m_frame.general &= ~XVID_DERING; */
751                    m_frame.general &= ~XVID_FILMEFFECT;
752    
753                    length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
754                    if (length < 0)
755                    {
756                DPRINTF("*** XVID_DEC_DECODE");
757                            return S_FALSE;
758                    }
759    
760                    m_frame.output.csp = tmp;
761                    m_frame.general = tmp_gen;
762            }
763    
764            if (stats.type == XVID_TYPE_NOTHING) {
765                    DPRINTF("B-Frame decoder lag");
766                    return S_FALSE;
767            }
768    
769    
770            if (stats.type == XVID_TYPE_VOL)
771            {
772                    if (stats.data.vol.width != m_create.width ||
773                            stats.data.vol.height != m_create.height)
774                    {
775                            DPRINTF("TODO: auto-resize");
776                            return S_FALSE;
777                    }
778    
779                    pOut->SetDiscontinuity(TRUE);
780                    pOut->SetSyncPoint(TRUE);
781    
782                    m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
783                    m_frame.length -= length;
784                    goto repeat;
785            }
786    
787            if (pIn->IsPreroll() == S_OK) {
788                    return S_FALSE;
789            }
790    
791            return S_OK;
792    }
793    
794    
795    /* get property page list */
796    
797    STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
798    {
799            DPRINTF("GetPages");
800    
801            pPages->cElems = 1;
802            pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
803            if (pPages->pElems == NULL)
804            {
805                    return E_OUTOFMEMORY;
806            }
807            pPages->pElems[0] = CLSID_CABOUT;
808    
809            return S_OK;
810    }
811    
812    
813    /* cleanup pages */
814    
815    STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
816    {
817            DPRINTF("FreePages");
818            CoTaskMemFree(pPages->pElems);
819            return S_OK;
820    }

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

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