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

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

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

revision 1898, Sun Oct 17 18:31:52 2010 UTC revision 2113, Sun Jun 14 19:17:57 2015 UTC
# Line 3  Line 3 
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - Xvid Decoder part of the DShow Filter  -   *  - Xvid Decoder part of the DShow Filter  -
5   *   *
6   *  Copyright(C) 2002-2010 Peter Ross <pross@xvid.org>   *  Copyright(C) 2002-2011 Peter Ross <pross@xvid.org>
7   *               2003-2010 Michael Militzer <michael@xvid.org>   *               2003-2012 Michael Militzer <michael@xvid.org>
8   *   *
9   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
10   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20   *  along with this program ; if not, write to the Free Software   *  along with this program ; if not, write to the Free Software
21   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   *   *
23   * $Id: CXvidDecoder.cpp,v 1.20 2010-10-17 18:31:46 Isibaar Exp $   * $Id$
  *  
  ****************************************************************************/  
   
 /****************************************************************************  
  *  
  * 2003/12/11 - added some additional options, mainly to make the deblocking  
  *              code from xvidcore available. Most of the new code is taken  
  *              from Nic's dshow filter, (C) Nic, http://nic.dnsalias.com  
24   *   *
25   ****************************************************************************/   ****************************************************************************/
26    
# Line 44  Line 36 
36          C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug          C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug
37  */  */
38    
39  //#define XVID_USE_MFT  #ifdef ENABLE_MFT
40  //#define XVID_USE_TRAYICON  #define XVID_USE_MFT
41    #endif
42    
43  #include <windows.h>  #include <windows.h>
44    
# Line 95  Line 88 
88          { &MEDIATYPE_Video, &CLSID_DIVX_UC },          { &MEDIATYPE_Video, &CLSID_DIVX_UC },
89          { &MEDIATYPE_Video, &CLSID_DX50 },          { &MEDIATYPE_Video, &CLSID_DX50 },
90          { &MEDIATYPE_Video, &CLSID_DX50_UC },          { &MEDIATYPE_Video, &CLSID_DX50_UC },
91            { &MEDIATYPE_Video, &CLSID_3IVX },
92            { &MEDIATYPE_Video, &CLSID_3IVX_UC },
93            { &MEDIATYPE_Video, &CLSID_3IV0 },
94            { &MEDIATYPE_Video, &CLSID_3IV0_UC },
95            { &MEDIATYPE_Video, &CLSID_3IV1 },
96            { &MEDIATYPE_Video, &CLSID_3IV1_UC },
97            { &MEDIATYPE_Video, &CLSID_3IV2 },
98            { &MEDIATYPE_Video, &CLSID_3IV2_UC },
99            { &MEDIATYPE_Video, &CLSID_LMP4 },
100            { &MEDIATYPE_Video, &CLSID_LMP4_UC },
101            { &MEDIATYPE_Video, &CLSID_RMP4 },
102            { &MEDIATYPE_Video, &CLSID_RMP4_UC },
103            { &MEDIATYPE_Video, &CLSID_SMP4 },
104            { &MEDIATYPE_Video, &CLSID_SMP4_UC },
105            { &MEDIATYPE_Video, &CLSID_HDX4 },
106            { &MEDIATYPE_Video, &CLSID_HDX4_UC },
107          { &MEDIATYPE_Video, &CLSID_MP4V },          { &MEDIATYPE_Video, &CLSID_MP4V },
108    { &MEDIATYPE_Video, &CLSID_MP4V_UC },    { &MEDIATYPE_Video, &CLSID_MP4V_UC },
109  };  };
# Line 136  Line 145 
145  {  {
146          &CLSID_XVID,                    // Filter CLSID          &CLSID_XVID,                    // Filter CLSID
147          XVID_NAME_L,                    // Filter name          XVID_NAME_L,                    // Filter name
148          MERIT_PREFERRED,                // Its merit          MERIT_PREFERRED+2,              // Its merit
149          sizeof(psudPins) / sizeof(AMOVIESETUP_PIN),     // Number of pins          sizeof(psudPins) / sizeof(AMOVIESETUP_PIN),     // Number of pins
150          psudPins                                // Pin details          psudPins                                // Pin details
151  };  };
# Line 166  Line 175 
175  /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */  /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */
176  int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);  int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);
177    
 #ifdef XVID_USE_TRAYICON  
178  extern HINSTANCE g_xvid_hInst;  extern HINSTANCE g_xvid_hInst;
179    
180  static int GUI_Page = 0;  static int GUI_Page = 0;
181    static HWND MSG_hwnd = NULL; /* message handler window */
182    
183  extern "C" void CALLBACK Configure(HWND hWndParent, HINSTANCE hInstParent, LPSTR lpCmdLine, int nCmdShow );  extern "C" void CALLBACK Configure(HWND hWndParent, HINSTANCE hInstParent, LPSTR lpCmdLine, int nCmdShow );
184    
185  LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
# Line 179  Line 189 
189          case WM_ICONMESSAGE:          case WM_ICONMESSAGE:
190                  switch(lParam)                  switch(lParam)
191                  {                  {
192                    case WM_LBUTTONUP:
193                  case WM_LBUTTONDBLCLK:                  case WM_LBUTTONDBLCLK:
194                          if (!GUI_Page) {                          if (!GUI_Page) {
195                                  GUI_Page = 1;                                  GUI_Page = 1;
# Line 191  Line 202 
202                  };                  };
203                  break;                  break;
204    
205            case WM_DESTROY:
206                    NOTIFYICONDATA nid;
207                    ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
208    
209                    nid.cbSize = sizeof(NOTIFYICONDATA);
210                    nid.hWnd = hwnd;
211                    nid.uID = 1456;
212                    Shell_NotifyIcon(NIM_DELETE, &nid);
213          default:          default:
214                  return DefWindowProc(hwnd, uMsg, wParam, lParam);                  return DefWindowProc(hwnd, uMsg, wParam, lParam);
215          }          }
216    
217          return TRUE; /* ok */          return TRUE; /* ok */
218  }  }
 #endif  
219    
220  STDAPI DllRegisterServer()  STDAPI DllRegisterServer()
221  {  {
# Line 222  Line 240 
240          /* Register the MFT decoder */          /* Register the MFT decoder */
241          MFTRegister(CLSID_XVID,                          // CLSID          MFTRegister(CLSID_XVID,                          // CLSID
242                          MFT_CATEGORY_VIDEO_DECODER,          // Category                          MFT_CATEGORY_VIDEO_DECODER,          // Category
243                          const_cast<LPWSTR>(XVID_NAME_L),     // Friendly name                                  const_cast<LPWSTR>(XVID_NAME_MFT_L), // Friendly name
244                          0,                                   // Flags                          0,                                   // Flags
245                          inputs_num,                          // Number of input types                          inputs_num,                          // Number of input types
246                          mft_bs,                              // Input types                          mft_bs,                              // Input types
# Line 291  Line 309 
309    
310  /* constructor */  /* constructor */
311    
 #define XVID_DLL_NAME "xvidcore.dll"  
   
312  CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :  CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) :
313      CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL)      CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL)
314  {  {
# Line 301  Line 317 
317      xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize...      xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize...
318      xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here.      xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here.
319    
320  #ifdef XVID_USE_TRAYICON          m_tray_icon = 0;
321          MSG_hwnd = NULL;          m_startClock = clock();
 #endif  
322    
323  #if defined(XVID_USE_MFT)  #if defined(XVID_USE_MFT)
324          InitializeCriticalSection(&m_mft_lock);          InitializeCriticalSection(&m_mft_lock);
325          m_pInputType = NULL;          m_pInputType = NULL;
326          m_pOutputType = NULL;          m_pOutputType = NULL;
327            m_pOutputTypeBPP = 32;
328          m_rtFrame = 0;          m_rtFrame = 0;
329          m_duration = 0;          m_duration = 0;
330          m_discont = 0;          m_discont = 0;
331          m_frameRate.Denominator = 1;          m_frameRate.Denominator = 1;
332          m_frameRate.Numerator = 1;          m_frameRate.Numerator = 1;
333            m_thread_handle = NULL;
334  #endif  #endif
335    
336      LoadRegistryInfo();      LoadRegistryInfo();
337    
338      *phr = OpenLib();      *phr = OpenLib();
339    
340            {
341                    TCHAR lpFilename[MAX_PATH];
342                    int sLen = GetModuleFileName(NULL, lpFilename, MAX_PATH);
343    #ifdef _UNICODE
344                    if ((sLen >= 11) && (_wcsnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
345    #else
346                    if ((sLen >= 11) && (_strnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
347    #endif
348                            if (m_tray_icon == 0) m_tray_icon = -1; // create no tray icon upon thumbnail generation
349                    }
350            }
351    
352  }  }
353    
354  HRESULT CXvidDecoder::OpenLib()  HRESULT CXvidDecoder::OpenLib()
# Line 331  Line 361 
361          xvid_gbl_init_t init;          xvid_gbl_init_t init;
362          memset(&init, 0, sizeof(init));          memset(&init, 0, sizeof(init));
363          init.version = XVID_VERSION;          init.version = XVID_VERSION;
364            init.cpu_flags = g_config.cpu;
365    
366            xvid_gbl_info_t info;
367            memset(&info, 0, sizeof(info));
368            info.version = XVID_VERSION;
369    
370          m_hdll = LoadLibrary(XVID_DLL_NAME);          m_hdll = LoadLibrary(XVID_DLL_NAME);
371          if (m_hdll == NULL) {          if (m_hdll == NULL) {
# Line 366  Line 401 
401                  return E_FAIL;                  return E_FAIL;
402          }          }
403    
404            if (xvid_global_func(0, XVID_GBL_INFO, &info, NULL) < 0)
405            {
406            xvid_global_func = NULL;
407            xvid_decore_func = NULL;
408            FreeLibrary(m_hdll);
409            m_hdll = NULL;
410                    MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
411                    return E_FAIL;
412            }
413    
414          memset(&m_create, 0, sizeof(m_create));          memset(&m_create, 0, sizeof(m_create));
415          m_create.version = XVID_VERSION;          m_create.version = XVID_VERSION;
416          m_create.handle = NULL;          m_create.handle = NULL;
417        /* Decoder threads */
418        if (g_config.cpu & XVID_CPU_FORCE) {
419                    m_create.num_threads = g_config.num_threads;
420            }
421            else {
422            m_create.num_threads = info.num_threads; /* Autodetect */
423                    g_config.num_threads = info.num_threads;
424            }
425    
426          memset(&m_frame, 0, sizeof(m_frame));          memset(&m_frame, 0, sizeof(m_frame));
427          m_frame.version = XVID_VERSION;          m_frame.version = XVID_VERSION;
# Line 456  Line 509 
509  CXvidDecoder::~CXvidDecoder()  CXvidDecoder::~CXvidDecoder()
510  {  {
511      DPRINTF("Destructor");      DPRINTF("Destructor");
         CloseLib();  
512    
513  #ifdef XVID_USE_TRAYICON          if ((MSG_hwnd != NULL) && (m_tray_icon == 1)) { /* Destroy tray icon */
514          if (MSG_hwnd != NULL) {                  SendMessage(MSG_hwnd, WM_CLOSE, 0, 0);
515                  NOTIFYICONDATA nid;          }
                 nid.cbSize = sizeof(NOTIFYICONDATA);  
                 nid.hWnd = MSG_hwnd;  
                 nid.uID = 100;  
516    
517                  Shell_NotifyIcon(NIM_DELETE, &nid);          /* Close xvidcore library */
518            CloseLib();
519    
520                  DestroyWindow(MSG_hwnd);          clock_t endClock = clock();
521                  MSG_hwnd = NULL;          if (((endClock - m_startClock) / CLOCKS_PER_SEC) > 3) {
522                    SaveRegistryInfo((endClock - m_startClock) / (CLOCKS_PER_SEC / 10));
523            }
524    
525            if ((MSG_hwnd != 0) && (m_tray_icon == 1)) { /* Final clean-up */
526              MSG_hwnd = 0;
527              Sleep(200);
528              m_tray_icon = 0;
529    #if defined(XVID_USE_MFT)
530              if (m_thread_handle) {
531                      TerminateThread(m_thread_handle, 0);
532                      CloseHandle(m_thread_handle);
533                      m_thread_handle = NULL;
534          }          }
535  #endif  #endif
536            }
537    
538  #if defined(XVID_USE_MFT)  #if defined(XVID_USE_MFT)
539          DeleteCriticalSection(&m_mft_lock);          DeleteCriticalSection(&m_mft_lock);
# Line 579  Line 642 
642    {    {
643    case FOURCC_mp4v:    case FOURCC_mp4v:
644          case FOURCC_MP4V:          case FOURCC_MP4V:
645            case FOURCC_lmp4 :
646            case FOURCC_LMP4 :
647            case FOURCC_rmp4 :
648            case FOURCC_RMP4 :
649            case FOURCC_smp4 :
650            case FOURCC_SMP4 :
651            case FOURCC_hdx4 :
652            case FOURCC_HDX4 :
653                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
654                          CloseLib();                          CloseLib();
655                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
656                  }                  }
657                  break;                  break;
658            case FOURCC_divx :
659          case FOURCC_DIVX :          case FOURCC_DIVX :
660            case FOURCC_dx50 :
661            case FOURCC_DX50 :
662                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
663                          CloseLib();                          CloseLib();
664                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
665                  }                  }
666                  break;                  break;
667          case FOURCC_DX50 :          case FOURCC_3ivx :
668                  if (!(g_config.supported_4cc & SUPPORT_DX50)) {          case FOURCC_3IVX :
669            case FOURCC_3iv0 :
670            case FOURCC_3IV0 :
671            case FOURCC_3iv1 :
672            case FOURCC_3IV1 :
673            case FOURCC_3iv2 :
674            case FOURCC_3IV2 :
675                    if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
676                          CloseLib();                          CloseLib();
677                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
678                  }                  }
679            case FOURCC_xvid :
680          case FOURCC_XVID :          case FOURCC_XVID :
681                  break;                  break;
682    
# Line 755  Line 837 
837  /* (internal function) change colorspace */  /* (internal function) change colorspace */
838  #define CALC_BI_STRIDE(width,bitcount)  ((((width * bitcount) + 31) & ~31) >> 3)  #define CALC_BI_STRIDE(width,bitcount)  ((((width * bitcount) + 31) & ~31) >> 3)
839    
840  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void *format, int *bitdepth, int noflip)
841  {  {
842          DWORD biWidth;          DWORD biWidth;
843            *bitdepth = 32;
844    
845          if (formattype == FORMAT_VideoInfo)          if (formattype == FORMAT_VideoInfo)
846          {          {
847                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
848                  biWidth = vih->bmiHeader.biWidth;                  biWidth = vih->bmiHeader.biWidth;
849                    *bitdepth = vih->bmiHeader.biBitCount;
850                  out_stride = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);                  out_stride = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);
851                  rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);                  rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
852          }          }
# Line 770  Line 854 
854          {          {
855                  VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;                  VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
856                  biWidth = vih2->bmiHeader.biWidth;                  biWidth = vih2->bmiHeader.biWidth;
857                    *bitdepth = vih2->bmiHeader.biBitCount;
858                  out_stride = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);                  out_stride = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);
859                  rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);                  rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
860          }          }
# Line 778  Line 863 
863                  return S_FALSE;                  return S_FALSE;
864          }          }
865    
866            if (noflip) rgb_flip = 0;
867    
868          if (subtype == CLSID_MEDIASUBTYPE_IYUV)          if (subtype == CLSID_MEDIASUBTYPE_IYUV)
869          {          {
870                  DPRINTF("IYUV");                  DPRINTF("IYUV");
# Line 847  Line 934 
934    
935  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
936  {  {
937            int bitdepth;
938          DPRINTF("SetMediaType");          DPRINTF("SetMediaType");
939    
940          if (direction == PINDIR_OUTPUT)          if (direction == PINDIR_OUTPUT)
941          {          {
942                  return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());                  return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format(), &bitdepth, 0);
943          }          }
944    
945          return S_OK;          return S_OK;
# Line 873  Line 961 
961  {  {
962          DPRINTF("CompleteConnect");          DPRINTF("CompleteConnect");
963    
964  #ifdef XVID_USE_TRAYICON          if ((direction == PINDIR_OUTPUT) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
         if ((direction == PINDIR_OUTPUT) && (MSG_hwnd == NULL))  
965          {          {
966                  WNDCLASSEX wc;                  WNDCLASSEX wc;
967    
# Line 897  Line 984 
984    
985                  /* display the tray icon */                  /* display the tray icon */
986                  NOTIFYICONDATA nid;                  NOTIFYICONDATA nid;
987                    ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
988    
989                  nid.cbSize = sizeof(NOTIFYICONDATA);                  nid.cbSize = sizeof(NOTIFYICONDATA);
990                  nid.hWnd = MSG_hwnd;                  nid.hWnd = MSG_hwnd;
991                  nid.uID = 100;                  nid.uID = 1456;
992                  nid.uVersion = NOTIFYICON_VERSION;                  nid.uVersion = NOTIFYICON_VERSION;
993                  nid.uCallbackMessage = WM_ICONMESSAGE;                  nid.uCallbackMessage = WM_ICONMESSAGE;
994                  nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));                  nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
995                  strcpy_s(nid.szTip, 19, "Xvid Video Decoder");                  strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
996                  nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;                  nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
997    
998                  Shell_NotifyIcon(NIM_ADD, &nid);                  Shell_NotifyIcon(NIM_ADD, &nid);
999                    Shell_NotifyIcon(NIM_SETVERSION, &nid);
1000    
1001                    DestroyIcon(nid.hIcon);
1002                    m_tray_icon = 1;
1003          }          }
 #endif  
1004    
1005          return S_OK;          return S_OK;
1006  }  }
# Line 919  Line 1010 
1010  {  {
1011          DPRINTF("BreakConnect");          DPRINTF("BreakConnect");
1012    
 #ifdef XVID_USE_TRAYICON  
         if ((direction == PINDIR_OUTPUT) && (MSG_hwnd != NULL)) {  
                 NOTIFYICONDATA nid;  
   
                 nid.cbSize = sizeof(NOTIFYICONDATA);  
                 nid.hWnd = MSG_hwnd;  
                 nid.uID = 100;  
                 nid.uVersion = NOTIFYICON_VERSION;  
   
                 if(Shell_NotifyIcon(NIM_DELETE, &nid) == TRUE) {  
                         DestroyWindow(MSG_hwnd);  
                         MSG_hwnd = NULL;  
                 }  
         }  
 #endif  
   
1013          return S_OK;          return S_OK;
1014  }  }
1015    
# Line 999  Line 1074 
1074          pOut->GetMediaType(&mtOut);          pOut->GetMediaType(&mtOut);
1075          if (mtOut != NULL)          if (mtOut != NULL)
1076          {          {
1077                    int bitdepth;
1078                  HRESULT result;                  HRESULT result;
1079    
1080                  result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);                  result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat, &bitdepth, 0);
1081                  DeleteMediaType(mtOut);                  DeleteMediaType(mtOut);
1082    
1083                  if (result != S_OK)                  if (result != S_OK)
# Line 1271  Line 1347 
1347                  pStreamInfo->cbAlignment = 0;                  pStreamInfo->cbAlignment = 0;
1348          }          }
1349          else {          else {
1350                  pStreamInfo->cbSize = m_create.width * abs(m_create.height) * 4; // XXX                  pStreamInfo->cbSize = (m_create.width * abs(m_create.height) * m_pOutputTypeBPP) >> 3;
1351                  pStreamInfo->cbAlignment = 1;                  pStreamInfo->cbAlignment = 1;
1352          }          }
1353    
# Line 1322  Line 1398 
1398          bs_guid_table[i++] = (GUID *)&CLSID_XVID;          bs_guid_table[i++] = (GUID *)&CLSID_XVID;
1399          bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC;          bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC;
1400    
1401          if (g_config.supported_4cc & SUPPORT_DX50) {          if (g_config.supported_4cc & SUPPORT_3IVX) {
1402                  bs_guid_table[i++] = (GUID *)&CLSID_DX50;                  bs_guid_table[i++] = (GUID *)&CLSID_3IVX;
1403                  bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_3IVX_UC;
1404                    bs_guid_table[i++] = (GUID *)&CLSID_3IV0;
1405                    bs_guid_table[i++] = (GUID *)&CLSID_3IV0_UC;
1406                    bs_guid_table[i++] = (GUID *)&CLSID_3IV1;
1407                    bs_guid_table[i++] = (GUID *)&CLSID_3IV1_UC;
1408                    bs_guid_table[i++] = (GUID *)&CLSID_3IV2;
1409                    bs_guid_table[i++] = (GUID *)&CLSID_3IV2_UC;
1410          }          }
1411          if (g_config.supported_4cc & SUPPORT_DIVX) {          if (g_config.supported_4cc & SUPPORT_DIVX) {
1412                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX;                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX;
1413                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC;
1414                    bs_guid_table[i++] = (GUID *)&CLSID_DX50;
1415                    bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC;
1416          }          }
1417          if (g_config.supported_4cc & SUPPORT_MP4V) {          if (g_config.supported_4cc & SUPPORT_MP4V) {
1418                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V;                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V;
1419                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC;
1420                    bs_guid_table[i++] = (GUID *)&CLSID_LMP4;
1421                    bs_guid_table[i++] = (GUID *)&CLSID_LMP4_UC;
1422                    bs_guid_table[i++] = (GUID *)&CLSID_RMP4;
1423                    bs_guid_table[i++] = (GUID *)&CLSID_RMP4_UC;
1424                    bs_guid_table[i++] = (GUID *)&CLSID_SMP4;
1425                    bs_guid_table[i++] = (GUID *)&CLSID_SMP4_UC;
1426                    bs_guid_table[i++] = (GUID *)&CLSID_HDX4;
1427                    bs_guid_table[i++] = (GUID *)&CLSID_HDX4_UC;
1428          }          }
1429    
1430          const GUID *subtype;          const GUID *subtype;
# Line 1393  Line 1485 
1485                  break;                  break;
1486  }  }
1487          case 1 :          case 1 :
1488    if ( USE_YVYU )
1489    {
1490                csp = MFVideoFormat_YVYU;
1491                bitdepth = 4;
1492                break;
1493    }
1494            case 2 :
1495  if ( USE_UYVY )  if ( USE_UYVY )
1496  {  {
1497                  csp = MFVideoFormat_UYVY;                  csp = MFVideoFormat_UYVY;
1498                  bitdepth = 4;                  bitdepth = 4;
1499                  break;                  break;
1500  }  }
1501          case 2  :          case 3  :
1502                  if ( USE_IYUV )                  if ( USE_IYUV )
1503  {  {
1504                  csp = MFVideoFormat_IYUV;                  csp = MFVideoFormat_IYUV;
1505                  bitdepth = 3;                  bitdepth = 3;
1506                  break;                  break;
1507  }  }
1508          case 3  :          case 4  :
1509  if ( USE_YV12 )  if ( USE_YV12 )
1510  {  {
1511                  csp = MFVideoFormat_YV12;                  csp = MFVideoFormat_YV12;
1512                  bitdepth = 3;                  bitdepth = 3;
1513                  break;                  break;
1514  }  }
1515          case 4 :          case 5 :
1516  if ( USE_RGB32 )  if ( USE_RGB32 )
1517  {  {
1518                  csp = MFVideoFormat_RGB32;                  csp = MFVideoFormat_RGB32;
1519                  bitdepth = 8;                  bitdepth = 8;
1520                  break;                  break;
1521  }  }
1522          case 5 :          case 6 :
1523  if ( USE_RGB24 )  if ( USE_RGB24 )
1524  {  {
1525                  csp = MFVideoFormat_RGB24;                  csp = MFVideoFormat_RGB24;
1526                  bitdepth = 6;                  bitdepth = 6;
1527                  break;                  break;
1528  }  }
1529          case 6 :          case 7 :
1530  if ( USE_RG555 )  if ( USE_RG555 )
1531  {  {
1532                  csp = MFVideoFormat_RGB555;                  csp = MFVideoFormat_RGB555;
1533                  bitdepth = 4;                  bitdepth = 4;
1534                  break;                  break;
1535  }  }
1536          case 7 :          case 8 :
1537  if ( USE_RG565 )  if ( USE_RG565 )
1538  {  {
1539                  csp = MFVideoFormat_RGB565;                  csp = MFVideoFormat_RGB565;
# Line 1472  Line 1571 
1571          }          }
1572    
1573          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1574                  hr = pOutputType->SetUINT32(MF_MT_SAMPLE_SIZE, (m_create.height * m_create.width * bitdepth)>>1);                  hr = pOutputType->SetUINT32(MF_MT_SAMPLE_SIZE, (abs(m_create.height) * m_create.width * bitdepth) >> 1);
1575          }          }
1576    
1577          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1578                  hr = MFSetAttributeSize(pOutputType, MF_MT_FRAME_SIZE, m_create.width, m_create.height);                  hr = MFSetAttributeSize(pOutputType, MF_MT_FRAME_SIZE, m_create.width, abs(m_create.height));
1579          }          }
1580    
1581          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
# Line 1524  Line 1623 
1623                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1624    
1625          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1626          if (pType) { // /* Check the type */          if (pType) { /* Check the type */
1627              hr = OnCheckInputType(pType);              hr = OnCheckInputType(pType);
1628          }          }
1629          }          }
# Line 1539  Line 1638 
1638          return hr;          return hr;
1639  }  }
1640    
1641    DWORD WINAPI CreateTrayIcon(LPVOID lpParameter)
1642    {
1643            WNDCLASSEX wc;
1644    
1645            wc.cbSize = sizeof(WNDCLASSEX);
1646            wc.lpfnWndProc = msg_proc;
1647            wc.style = CS_HREDRAW | CS_VREDRAW;
1648            wc.cbWndExtra = 0;
1649            wc.cbClsExtra = 0;
1650            wc.hInstance = (HINSTANCE)g_xvid_hInst;
1651            wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
1652            wc.lpszMenuName = NULL;
1653            wc.lpszClassName = "XVID_MSG_WINDOW";
1654            wc.hIcon = NULL;
1655            wc.hIconSm = NULL;
1656            wc.hCursor = NULL;
1657            RegisterClassEx(&wc);
1658    
1659            MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,
1660                    CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE)g_xvid_hInst, NULL);
1661    
1662            /* display the tray icon */
1663            NOTIFYICONDATA nid;
1664            ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
1665    
1666            nid.cbSize = sizeof(NOTIFYICONDATA);
1667            nid.hWnd = MSG_hwnd;
1668            nid.uID = 1456;
1669            nid.uVersion = NOTIFYICON_VERSION;
1670            nid.uCallbackMessage = WM_ICONMESSAGE;
1671            nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
1672            strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
1673            nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
1674    
1675            Shell_NotifyIcon(NIM_ADD, &nid);
1676            Shell_NotifyIcon(NIM_SETVERSION, &nid);
1677    
1678            DestroyIcon(nid.hIcon);
1679    
1680            MSG msg;
1681            while (MSG_hwnd && GetMessage(&msg, MSG_hwnd, 0, 0)) {
1682                    TranslateMessage(&msg);
1683                    DispatchMessage(&msg);
1684            }
1685    
1686            return 0;
1687    }
1688    
1689  HRESULT CXvidDecoder::MFTSetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)  HRESULT CXvidDecoder::MFTSetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)
1690  {  {
1691          DPRINTF("(MFT)SetOutputType");          DPRINTF("(MFT)SetOutputType");
# Line 1553  Line 1700 
1700    
1701          EnterCriticalSection(&m_mft_lock);          EnterCriticalSection(&m_mft_lock);
1702    
1703          /* Actually set the type or just test it?          /* Actually set the type or just test it? */
1704          BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);          BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
1705    
1706          /* If we have samples pending the type can't be changed right now */          /* If we have samples pending the type can't be changed right now */
1707          if (HasPendingOutput())          if (HasPendingOutput())
1708                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1709    
1710            int bitdepth;
1711          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1712                  if (pType) { /* Check the type */                  if (pType) { /* Check the type */
1713                          AM_MEDIA_TYPE *am;                          AM_MEDIA_TYPE *am;
1714                          hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am);                          hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am);
1715    
1716                          if (SUCCEEDED(hr)) {                          if (SUCCEEDED(hr)) {
1717                                  if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat))) {                                  if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat, &bitdepth, 1))) {
1718                                          DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)");                                          DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)");
1719                                          return MF_E_INVALIDTYPE;                                          return MF_E_INVALIDTYPE;
1720                                  }                                  }
# Line 1579  Line 1727 
1727    
1728          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1729                  if (bReallySet) { /* Set the type if needed */                  if (bReallySet) { /* Set the type if needed */
1730                          hr = OnSetOutputType(pType);                          hr = OnSetOutputType(pType, bitdepth);
1731                  }                  }
1732          }          }
1733    
1734  #ifdef XVID_USE_TRAYICON          if (SUCCEEDED(hr) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
         if (SUCCEEDED(hr) && MSG_hwnd == NULL) /* Create message passing window */  
1735          {          {
1736                  WNDCLASSEX wc;                  m_thread_handle = CreateThread(NULL, 0, CreateTrayIcon, NULL, 0, NULL);  /* Create message passing window */
   
                 wc.cbSize = sizeof(WNDCLASSEX);  
                 wc.lpfnWndProc = msg_proc;  
                 wc.style = CS_HREDRAW | CS_VREDRAW;  
                 wc.cbWndExtra = 0;  
                 wc.cbClsExtra = 0;  
                 wc.hInstance = (HINSTANCE) g_xvid_hInst;  
                 wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH);  
                 wc.lpszMenuName = NULL;  
                 wc.lpszClassName = "XVID_MSG_WINDOW";  
                 wc.hIcon = NULL;  
                 wc.hIconSm = NULL;  
                 wc.hCursor = NULL;  
                 RegisterClassEx(&wc);  
1737    
1738                  MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,                  if (m_thread_handle)
1739                                    CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE) g_xvid_hInst, NULL);                      m_tray_icon = 1;
   
                 /* display the tray icon */  
                 NOTIFYICONDATA nid;  
   
                 nid.cbSize = sizeof(NOTIFYICONDATA);  
                 nid.hWnd = MSG_hwnd;  
                 nid.uID = 100;  
                 nid.uVersion = NOTIFYICON_VERSION;  
                 nid.uCallbackMessage = WM_ICONMESSAGE;  
                 nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));  
                 strcpy_s(nid.szTip, 19, "Xvid Video Decoder");  
                 nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;  
   
                 Shell_NotifyIcon(NIM_ADD, &nid);  
1740          }          }
 #endif  
1741    
1742          LeaveCriticalSection(&m_mft_lock);          LeaveCriticalSection(&m_mft_lock);
1743    
1744          return hr;          return hr;
1745  }  }
1746    
# Line 1689  Line 1808 
1808    
1809          EnterCriticalSection(&m_mft_lock);          EnterCriticalSection(&m_mft_lock);
1810    
1811          /* If there's pending output sampels we don't accept new          /* If there's pending output samples we don't accept new
1812             input data until ProcessOutput() or Flush() was called */             input data until ProcessOutput() or Flush() was called */
1813          if (!HasPendingOutput()) {          if (!HasPendingOutput()) {
1814                  *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;                  *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
# Line 1926  Line 2045 
2045                          }                          }
2046    
2047                          ar_x = par_x * stats.data.vol.width;                          ar_x = par_x * stats.data.vol.width;
2048                          ar_y = par_y * stats.data.vol.height;                          ar_y = par_y * stats.data.vol.height; /* TODO: Actually set the newly determined AR on the output sample type
2049                                                                                                               or it'll have no effect at all... */
2050                  }                  }
2051    
2052                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
# Line 1950  Line 2070 
2070                  if (FAILED(pSample->GetSampleDuration(&m_timelength))) {                  if (FAILED(pSample->GetSampleDuration(&m_timelength))) {
2071                          m_timelength = INVALID_TIME;                          m_timelength = INVALID_TIME;
2072                  }                  }
2073                    if (m_timestamp != INVALID_TIME && stats.type == XVID_TYPE_IVOP) {
2074                            m_rtFrame = m_timestamp;
2075                    }
2076          }          }
2077    
2078          LeaveCriticalSection(&m_mft_lock);          LeaveCriticalSection(&m_mft_lock);
# Line 1985  Line 2108 
2108    
2109          BYTE *Dst = NULL;          BYTE *Dst = NULL;
2110          DWORD buffer_size;          DWORD buffer_size;
2111            LONG stride = m_create.width;
2112          IMFMediaBuffer *pOutput = NULL;          IMFMediaBuffer *pOutput = NULL;
2113            IMF2DBuffer *pOutput2D = NULL;
2114    
2115          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
2116                  hr = pOutputSamples[0].pSample->GetBufferByIndex(0, &pOutput); /* Get output buffer */                  hr = pOutputSamples[0].pSample->GetBufferByIndex(0, &pOutput); /* Get output buffer */
# Line 1996  Line 2120 
2120                  hr = pOutput->GetMaxLength(&buffer_size);                  hr = pOutput->GetMaxLength(&buffer_size);
2121          }          }
2122    
2123          if (SUCCEEDED(hr))          if (SUCCEEDED(hr)) {
2124                    hr = pOutput->QueryInterface(IID_IMF2DBuffer, (void **)&pOutput2D);
2125            }
2126    
2127            if (SUCCEEDED(hr)) {
2128                    hr = pOutput2D->Lock2D(&Dst, &stride);
2129            }
2130            else {
2131                  hr = pOutput->Lock(&Dst, NULL, NULL);                  hr = pOutput->Lock(&Dst, NULL, NULL);
2132            }
2133    
2134          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
2135                  xvid_gbl_convert_t convert;                  xvid_gbl_convert_t convert;
# Line 2015  Line 2147 
2147    
2148                  convert.output.csp = m_frame.output.csp;                  convert.output.csp = m_frame.output.csp;
2149                  convert.output.plane[0] = Dst;                  convert.output.plane[0] = Dst;
2150                  convert.output.stride[0] = out_stride;                  convert.output.stride[0] = stride;
2151    
2152                  convert.width = m_create.width;                  convert.width = m_create.width;
2153                  convert.height = m_create.height;                  convert.height = m_create.height;
# Line 2024  Line 2156 
2156                  if (m_frame.output.plane[1] != NULL && Dst != NULL && xvid_global_func != NULL)                  if (m_frame.output.plane[1] != NULL && Dst != NULL && xvid_global_func != NULL)
2157                          if (xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0) /* CSP convert into output buffer */                          if (xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0) /* CSP convert into output buffer */
2158                                  hr = E_FAIL;                                  hr = E_FAIL;
   
2159                  m_frame.output.plane[1] = NULL;                  m_frame.output.plane[1] = NULL;
2160          }          }
2161    
# Line 2049  Line 2180 
2180                  }                  }
2181    
2182                  if (SUCCEEDED(hr))                  if (SUCCEEDED(hr))
2183                          hr = pOutput->SetCurrentLength(m_create.width * abs(m_create.height) * 4); // XXX                          hr = pOutput->SetCurrentLength((m_create.width * abs(m_create.height) * m_pOutputTypeBPP) >> 3);
2184          }          }
2185    
2186          if (pOutput) {          if (pOutput2D) {
2187                    pOutput2D->Unlock2D();
2188                    pOutput2D->Release();
2189                    if (pOutput)
2190                        pOutput->Release();
2191            }
2192            else if (pOutput) {
2193                  pOutput->Unlock();                  pOutput->Unlock();
2194                  pOutput->Release();                  pOutput->Release();
2195          }          }
# Line 2127  Line 2264 
2264                  hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);                  hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);
2265          }          }
2266    
2267          if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC) {          if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC ||
2268                subtype == CLSID_LMP4 || subtype == CLSID_LMP4_UC ||
2269                subtype == CLSID_RMP4 || subtype == CLSID_RMP4_UC ||
2270                subtype == CLSID_SMP4 || subtype == CLSID_SMP4_UC ||
2271                subtype == CLSID_HDX4 || subtype == CLSID_HDX4_UC) {
2272                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
2273                          CloseLib();                          CloseLib();
2274                          hr = MF_E_INVALIDTYPE;                          hr = MF_E_INVALIDTYPE;
# Line 2142  Line 2283 
2283                  else m_create.fourcc = FOURCC_DIVX;                  else m_create.fourcc = FOURCC_DIVX;
2284          }          }
2285          else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) {          else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) {
2286                  if (!(g_config.supported_4cc & SUPPORT_DX50)) {                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
2287                          CloseLib();                          CloseLib();
2288                          hr = MF_E_INVALIDTYPE;                          hr = MF_E_INVALIDTYPE;
2289                  }                  }
2290                  else m_create.fourcc = FOURCC_DX50;                  else m_create.fourcc = FOURCC_DX50;
2291          }          }
2292            else if (subtype == CLSID_3IVX || subtype == CLSID_3IVX_UC ||
2293                     subtype == CLSID_3IV0 || subtype == CLSID_3IV0_UC ||
2294                     subtype == CLSID_3IV1 || subtype == CLSID_3IV1_UC ||
2295                     subtype == CLSID_3IV2 || subtype == CLSID_3IV2_UC) {
2296                    if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
2297                            CloseLib();
2298                            hr = MF_E_INVALIDTYPE;
2299                    }
2300                    else m_create.fourcc = FOURCC_3IVX;
2301            }
2302          else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) {          else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) {
2303                  m_create.fourcc = FOURCC_XVID;                  m_create.fourcc = FOURCC_XVID;
2304          }          }
# Line 2226  Line 2377 
2377          return hr;          return hr;
2378  }  }
2379    
2380  HRESULT CXvidDecoder::OnSetOutputType(IMFMediaType *pmt)  HRESULT CXvidDecoder::OnSetOutputType(IMFMediaType *pmt, int bitdepth)
2381  {  {
2382          if (m_pOutputType) m_pOutputType->Release();          if (m_pOutputType) m_pOutputType->Release();
2383    
2384          m_pOutputType = pmt;          m_pOutputType = pmt;
2385          m_pOutputType->AddRef();          m_pOutputType->AddRef();
2386            m_pOutputTypeBPP = bitdepth;
2387    
2388          return S_OK;          return S_OK;
2389  }  }

Legend:
Removed from v.1898  
changed lines
  Added in v.2113

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