[svn] / trunk / dshow / src / CXvidDecoder.cpp Repository:
ViewVC logotype

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

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

revision 615, Mon Oct 28 11:32:50 2002 UTC revision 855, Sun Feb 16 03:12:56 2003 UTC
# Line 1  Line 1 
1    /**************************************************************************
2     *
3     *      XVID DIRECTSHOW FRONTEND -- decoder fitler
4     *      Copyright (c) 2002 Peter Ross <pross@xvid.org>
5     *
6     *      This program is free software; you can redistribute it and/or modify
7     *      it under the terms of the GNU General Public License as published by
8     *      the Free Software Foundation; either version 2 of the License, or
9     *      (at your option) any later version.
10     *
11     *      This program is distributed in the hope that it will be useful,
12     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     *      GNU General Public License for more details.
15     *
16     *      You should have received a copy of the GNU General Public License
17     *      along with this program; if not, write to the Free Software
18     *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     *
20     *************************************************************************/
21    
22  /*  /*
23          this requires the directx sdk          this requires the directx sdk
24          place these paths at the top of the Tools|Options|Directories list          place these paths at the top of the Tools|Options|Directories list
# Line 10  Line 31 
31          C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release          C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release
32  */  */
33    
34    
35    
36  #include <windows.h>  #include <windows.h>
37    
38  #include <streams.h>  #include <streams.h>
# Line 27  Line 50 
50  #include "CAbout.h"  #include "CAbout.h"
51    
52    
   
53  const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =  const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] =
54  {  {
55      { &MEDIATYPE_Video, &CLSID_XVID },      { &MEDIATYPE_Video, &CLSID_XVID },
56          { &MEDIATYPE_Video, &CLSID_XVID_UC },          { &MEDIATYPE_Video, &CLSID_XVID_UC },
57          { &MEDIATYPE_Video, &CLSID_DIVX },          { &MEDIATYPE_Video, &CLSID_DIVX },
58          { &MEDIATYPE_Video, &CLSID_DIVX_UC }          { &MEDIATYPE_Video, &CLSID_DIVX_UC },
59            { &MEDIATYPE_Video, &CLSID_DX50 },
60            { &MEDIATYPE_Video, &CLSID_DX50_UC },
61  };  };
62    
63  const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =  const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] =
# Line 169  Line 193 
193  CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :  CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
194      CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID)      CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID)
195  {  {
196          DEBUG("Constructor");          DPRINTF("Constructor");
   
     ASSERT(phr);  
197    
198          m_xvid_decore = dummy_xvid_decore;          m_xvid_decore = dummy_xvid_decore;
199    
200          m_hdll = LoadLibrary(XVID_DLL_NAME);          m_hdll = LoadLibrary(XVID_DLL_NAME);
201          if (m_hdll == NULL) {          if (m_hdll == NULL) {
202                  DEBUG("dll load failed");                  DPRINTF("dll load failed");
203                  MessageBox(0, XVID_DLL_NAME " not found","Error", 0);                  MessageBox(0, XVID_DLL_NAME " not found","Error", 0);
204                  return;                  return;
205          }          }
# Line 222  Line 244 
244    
245  CXvidDecoder::~CXvidDecoder()  CXvidDecoder::~CXvidDecoder()
246  {  {
247          DEBUG("Destructor");          DPRINTF("Destructor");
248    
249          if (m_param.handle != NULL)          if (m_param.handle != NULL)
250          {          {
# Line 243  Line 265 
265    
266  HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)  HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn)
267  {  {
268          DEBUG("CheckInputType");          DPRINTF("CheckInputType");
269          BITMAPINFOHEADER * hdr;          BITMAPINFOHEADER * hdr;
270    
271          if (*mtIn->Type() != MEDIATYPE_Video)          if (*mtIn->Type() != MEDIATYPE_Video)
272          {          {
273                    DPRINTF("Error: Unknown Type");
274                  return VFW_E_TYPE_NOT_ACCEPTED;                  return VFW_E_TYPE_NOT_ACCEPTED;
275          }          }
276    
# Line 263  Line 286 
286          }          }
287          else          else
288          {          {
289                    DPRINTF("Error: Unknown FormatType");
290                  return VFW_E_TYPE_NOT_ACCEPTED;                  return VFW_E_TYPE_NOT_ACCEPTED;
291          }          }
292    
293          if (hdr->biHeight < 0)          if (hdr->biHeight < 0)
294          {          {
295                  DEBUG("colorspace: inverted input format not supported");                  DPRINTF("colorspace: inverted input format not supported");
296          }          }
297    
298          m_param.width = hdr->biWidth;          m_param.width = hdr->biWidth;
# Line 278  Line 302 
302          {          {
303          case FOURCC_XVID :          case FOURCC_XVID :
304  //      case FOURCC_DIVX :  //      case FOURCC_DIVX :
305    //      case FOURCC_DX50 :
306                  break;                  break;
307    
308          default :          default :
309                    DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)",
310                            hdr->biCompression,
311                            (hdr->biCompression)&0xff,
312                            (hdr->biCompression>>8)&0xff,
313                            (hdr->biCompression>>16)&0xff,
314                            (hdr->biCompression>>24)&0xff);
315                  return VFW_E_TYPE_NOT_ACCEPTED;                  return VFW_E_TYPE_NOT_ACCEPTED;
316          }          }
317    
# Line 288  Line 319 
319  }  }
320    
321    
322    #define USE_IYUV
323    #define USE_YV12
324    #define USE_YUY2
325    #define USE_YVYU
326    #define USE_UYVY
327    #define USE_RGB32
328    #define USE_RGB24
329    #define USE_RG555
330    #define USE_RG565
331    
332  /* get list of supported output colorspaces */  /* get list of supported output colorspaces */
333    
334  HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)  HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut)
335  {  {
336          DEBUG("GetMediaType");          DPRINTF("GetMediaType");
337    
338          if (m_pInput->IsConnected() == FALSE)          if (m_pInput->IsConnected() == FALSE)
339          {          {
# Line 319  Line 360 
360          switch(iPosition)          switch(iPosition)
361          {          {
362          case 0  :          case 0  :
363    #ifdef USE_IYUV
364                  vih->bmiHeader.biCompression = MEDIASUBTYPE_IYUV.Data1;                  vih->bmiHeader.biCompression = MEDIASUBTYPE_IYUV.Data1;
365                  vih->bmiHeader.biBitCount = 12;                  vih->bmiHeader.biBitCount = 12;
366                  mtOut->SetSubtype(&MEDIASUBTYPE_IYUV);                  mtOut->SetSubtype(&MEDIASUBTYPE_IYUV);
367                  break;                  break;
368    #endif
369          case 1  :          case 1  :
370    #ifdef USE_YV12
371                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1;                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1;
372                  vih->bmiHeader.biBitCount = 12;                  vih->bmiHeader.biBitCount = 12;
373                  mtOut->SetSubtype(&MEDIASUBTYPE_YV12);                  mtOut->SetSubtype(&MEDIASUBTYPE_YV12);
374                  break;                  break;
375    #endif
376          case 2:          case 2:
377    #ifdef USE_YUY2
378                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1;                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1;
379                  vih->bmiHeader.biBitCount = 16;                  vih->bmiHeader.biBitCount = 16;
380                  mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);                  mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);
381                  break;                  break;
382    #endif
383          case 3 :          case 3 :
384    #ifdef USE_YVYU
385                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1;                  vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1;
386                  vih->bmiHeader.biBitCount = 16;                  vih->bmiHeader.biBitCount = 16;
387                  mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);                  mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);
388                  break;                  break;
389    #endif
390          case 4 :          case 4 :
391    #ifdef USE_UYVY
392                  vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1;                  vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1;
393                  vih->bmiHeader.biBitCount = 16;                  vih->bmiHeader.biBitCount = 16;
394                  mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);                  mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);
395                  break;                  break;
396    #endif
397          case 5 :          case 5 :
398    #ifdef USE_RGB32
399                  vih->bmiHeader.biCompression = BI_RGB;                  vih->bmiHeader.biCompression = BI_RGB;
400                  vih->bmiHeader.biBitCount = 32;                  vih->bmiHeader.biBitCount = 32;
401                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);
402                  break;                  break;
403    #endif
404          case 6 :          case 6 :
405    #ifdef USE_RGB24
406                  vih->bmiHeader.biCompression = BI_RGB;                  vih->bmiHeader.biCompression = BI_RGB;
407                  vih->bmiHeader.biBitCount = 24;                  vih->bmiHeader.biBitCount = 24;
408                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);
409                  break;                  break;
410    #endif
411          case 7 :          case 7 :
412    #ifdef USE_RG555
413                  vih->bmiHeader.biCompression = BI_RGB;                  vih->bmiHeader.biCompression = BI_RGB;
414                  vih->bmiHeader.biBitCount = 16;                  vih->bmiHeader.biBitCount = 16;
415                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);
416                  break;                  break;
417    #endif
418          case 8 :          case 8 :
419    #ifdef USE_RG565
420                  vih->bmiHeader.biCompression = BI_RGB;                  vih->bmiHeader.biCompression = BI_RGB;
421                  vih->bmiHeader.biBitCount = 16;                  vih->bmiHeader.biBitCount = 16;
422                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);                  mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);
423                  break;                  break;
424    #endif
425          default :          default :
426                  return VFW_S_NO_MORE_ITEMS;                  return VFW_S_NO_MORE_ITEMS;
427          }          }
# Line 391  Line 441 
441    
442  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)
443  {  {
444            int rgb_flip;
445    
446            if (formattype == FORMAT_VideoInfo)
447            {
448                    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
449                    m_frame.stride = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3;
450                    rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
451            }
452            else if (formattype == FORMAT_VideoInfo2)
453            {
454                    VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
455                    m_frame.stride = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3;
456                    rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
457            }
458            else
459            {
460                    return S_FALSE;
461            }
462    
463          if (subtype == MEDIASUBTYPE_IYUV)          if (subtype == MEDIASUBTYPE_IYUV)
464          {          {
465                  DEBUG("IYUV");                  DPRINTF("IYUV");
466                  m_frame.colorspace = XVID_CSP_I420;                  m_frame.colorspace = XVID_CSP_I420;
467                    m_frame.stride = (m_frame.stride * 2) / 3;      /* planar format fix */
468          }          }
469          else if (subtype == MEDIASUBTYPE_YV12)          else if (subtype == MEDIASUBTYPE_YV12)
470          {          {
471                  DEBUG("YV12");                  DPRINTF("YV12");
472                  m_frame.colorspace = XVID_CSP_YV12;                  m_frame.colorspace = XVID_CSP_YV12;
473                    m_frame.stride = (m_frame.stride * 2) / 3;      /* planar format fix */
474          }          }
475          else if (subtype == MEDIASUBTYPE_YUY2)          else if (subtype == MEDIASUBTYPE_YUY2)
476          {          {
477                  DEBUG("YUY2");                  DPRINTF("YUY2");
478                  m_frame.colorspace = XVID_CSP_YUY2;                  m_frame.colorspace = XVID_CSP_YUY2;
479          }          }
480          else if (subtype == MEDIASUBTYPE_YVYU)          else if (subtype == MEDIASUBTYPE_YVYU)
481          {          {
482                  DEBUG("YVYU");                  DPRINTF("YVYU");
483                  m_frame.colorspace = XVID_CSP_YVYU;                  m_frame.colorspace = XVID_CSP_YVYU;
484          }          }
485          else if (subtype == MEDIASUBTYPE_UYVY)          else if (subtype == MEDIASUBTYPE_UYVY)
486          {          {
487                  DEBUG("UYVY");                  DPRINTF("UYVY");
488                  m_frame.colorspace = XVID_CSP_UYVY;                  m_frame.colorspace = XVID_CSP_UYVY;
489          }          }
490          else if (subtype == MEDIASUBTYPE_RGB32)          else if (subtype == MEDIASUBTYPE_RGB32)
491          {          {
492                  DEBUG("RGB32");                  DPRINTF("RGB32");
493                  m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB32;                  m_frame.colorspace = rgb_flip | XVID_CSP_RGB32;
494          }          }
495          else if (subtype == MEDIASUBTYPE_RGB24)          else if (subtype == MEDIASUBTYPE_RGB24)
496          {          {
497                  DEBUG("RGB24");                  DPRINTF("RGB24");
498                  m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB24;                  m_frame.colorspace = rgb_flip | XVID_CSP_RGB24;
499          }          }
500          else if (subtype == MEDIASUBTYPE_RGB555)          else if (subtype == MEDIASUBTYPE_RGB555)
501          {          {
502                  DEBUG("RGB555");                  DPRINTF("RGB555");
503                  m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB555;                  m_frame.colorspace = rgb_flip | XVID_CSP_RGB555;
504          }          }
505          else if (subtype == MEDIASUBTYPE_RGB565)          else if (subtype == MEDIASUBTYPE_RGB565)
506          {          {
507                  DEBUG("RGB565");                  DPRINTF("RGB565");
508                  m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB565;                  m_frame.colorspace = rgb_flip | XVID_CSP_RGB565;
509          }          }
510          else if (subtype == GUID_NULL)          else if (subtype == GUID_NULL)
511          {          {
# Line 445  Line 516 
516                  return S_FALSE;                  return S_FALSE;
517          }          }
518    
   
         if (formattype == FORMAT_VideoInfo)  
         {  
                 VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;  
                 m_frame.stride = vih->bmiHeader.biWidth;  
         }  
         else if (formattype == FORMAT_VideoInfo2)  
         {  
                 VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;  
                 m_frame.stride = vih2->bmiHeader.biWidth;  
         }  
         else  
         {  
                 return S_FALSE;  
         }  
   
519          return S_OK;          return S_OK;
   
520  }  }
521    
522    
# Line 470  Line 524 
524    
525  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
526  {  {
527          DEBUG("SetMediaType");          DPRINTF("SetMediaType");
528    
529          if (direction == PINDIR_OUTPUT)          if (direction == PINDIR_OUTPUT)
530          {          {
# Line 485  Line 539 
539    
540  HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)  HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
541  {  {
542          DEBUG("CheckTransform");          DPRINTF("CheckTransform");
543          return S_OK;          return S_OK;
544  }  }
545    
# Line 494  Line 548 
548    
549  HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)  HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
550  {  {
551          DEBUG("DecideBufferSize");          DPRINTF("DecideBufferSize");
552          HRESULT result;          HRESULT result;
553          ALLOCATOR_PROPERTIES ppropActual;          ALLOCATOR_PROPERTIES ppropActual;
554    
# Line 524  Line 578 
578  }  }
579    
580    
   
581  /* decode frame */  /* decode frame */
582    
583  HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)  HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
584  {  {
585          DEBUG("Transform");          DPRINTF("Transform");
586            XVID_DEC_STATS stats;
587    
588            BYTE * bitstream;
589            int length;
590    
591          if (m_param.handle == NULL)          if (m_param.handle == NULL)
592          {          {
# Line 554  Line 611 
611                  }                  }
612          }          }
613    
614          if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)          length = pIn->GetActualDataLength();
615            if (pIn->GetPointer((BYTE**)&bitstream) != S_OK)
616          {          {
617                  return S_FALSE;                  return S_FALSE;
618          }          }
# Line 564  Line 622 
622                  return S_FALSE;                  return S_FALSE;
623          }          }
624    
625          m_frame.length = pIn->GetSize();  
626            m_frame.general = XVID_DEC_LOWDELAY;
627    
628            if (pIn->IsDiscontinuity() == S_OK)
629                    m_frame.general = XVID_DEC_DISCONTINUITY;
630    
631    repeat :
632            m_frame.bitstream = bitstream;
633            m_frame.length = length;
634    
635          if (pIn->IsPreroll() != S_OK)          if (pIn->IsPreroll() != S_OK)
636          {          {
637                  if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, 0) != XVID_ERR_OK)                  if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, &stats) != XVID_ERR_OK)
638                  {                  {
639                          return S_FALSE;                          return S_FALSE;
640                  }                  }
# Line 578  Line 644 
644                  int tmp = m_frame.colorspace;                  int tmp = m_frame.colorspace;
645                  m_frame.colorspace = XVID_CSP_NULL;                  m_frame.colorspace = XVID_CSP_NULL;
646    
647                  if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, 0) != XVID_ERR_OK)                  if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, &stats) != XVID_ERR_OK)
648                  {                  {
649                          return S_FALSE;                          return S_FALSE;
650                  }                  }
651    
652                  m_frame.colorspace = tmp;                  m_frame.colorspace = tmp;
653            }
654    
655            if (stats.notify == XVID_DEC_VOL)
656            {
657                    if (stats.data.vol.width != m_param.width ||
658                            stats.data.vol.height != m_param.height)
659                    {
660                            DPRINTF("TODO: auto-resize");
661                            return S_FALSE;
662                    }
663    
664                    bitstream += m_frame.length;
665                    length -= m_frame.length;
666                    goto repeat;
667          }          }
668    
669          return S_OK;          /* only render when we decode a vop */
670            return (stats.notify == XVID_DEC_VOP) ? S_OK : S_FALSE;
671  }  }
672    
673    
# Line 595  Line 675 
675    
676  STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)  STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages)
677  {  {
678          DEBUG("GetPages");          DPRINTF("GetPages");
679    
680          pPages->cElems = 1;          pPages->cElems = 1;
681          pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));          pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
# Line 613  Line 693 
693    
694  STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)  STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages)
695  {  {
696          DEBUG("FreePages");          DPRINTF("FreePages");
697          CoTaskMemFree(pPages->pElems);          CoTaskMemFree(pPages->pElems);
698          return S_OK;          return S_OK;
699  }  }

Legend:
Removed from v.615  
changed lines
  Added in v.855

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