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

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

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