[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 1901, Fri Oct 29 14:33:39 2010 UTC revision 2134, Mon Jan 11 17:02:15 2016 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.22 2010-10-29 14:33:39 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    #ifdef ENABLE_MFT
40  #define XVID_USE_MFT  #define XVID_USE_MFT
41  #define XVID_USE_TRAYICON  #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 int Tray_Icon = 0;  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 180  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 196  Line 206 
206                  NOTIFYICONDATA nid;                  NOTIFYICONDATA nid;
207                  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));                  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
208    
209                  nid.cbSize = NOTIFYICONDATA_V1_SIZE;                  nid.cbSize = sizeof(NOTIFYICONDATA);
210                  nid.hWnd = hwnd;                  nid.hWnd = hwnd;
211                  nid.uID = 1456;                  nid.uID = 1456;
   
212                  Shell_NotifyIcon(NIM_DELETE, &nid);                  Shell_NotifyIcon(NIM_DELETE, &nid);
                 Tray_Icon = 0;  
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 233  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 302  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 312  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            m_tray_icon = 0;
321            m_startClock = clock();
322            interlaced = 0;
323    
324  #if defined(XVID_USE_MFT)  #if defined(XVID_USE_MFT)
325          InitializeCriticalSection(&m_mft_lock);          InitializeCriticalSection(&m_mft_lock);
326          m_pInputType = NULL;          m_pInputType = NULL;
327          m_pOutputType = NULL;          m_pOutputType = NULL;
328            m_pOutputTypeBPP = 32;
329          m_rtFrame = 0;          m_rtFrame = 0;
330          m_duration = 0;          m_duration = 0;
331          m_discont = 0;          m_discont = 0;
332          m_frameRate.Denominator = 1;          m_frameRate.Denominator = 1;
333          m_frameRate.Numerator = 1;          m_frameRate.Numerator = 1;
334            m_thread_handle = NULL;
335  #endif  #endif
336    
337      LoadRegistryInfo();      LoadRegistryInfo();
338    
339      *phr = OpenLib();      *phr = OpenLib();
340    
341            {
342                    TCHAR lpFilename[MAX_PATH];
343                    int sLen = GetModuleFileName(NULL, lpFilename, MAX_PATH);
344    #ifdef _UNICODE
345                    if ((sLen >= 11) && (_wcsnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
346    #else
347                    if ((sLen >= 11) && (_strnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) {
348    #endif
349                            if (m_tray_icon == 0) m_tray_icon = -1; // create no tray icon upon thumbnail generation
350                    }
351            }
352    
353  }  }
354    
355  HRESULT CXvidDecoder::OpenLib()  HRESULT CXvidDecoder::OpenLib()
# Line 338  Line 362 
362          xvid_gbl_init_t init;          xvid_gbl_init_t init;
363          memset(&init, 0, sizeof(init));          memset(&init, 0, sizeof(init));
364          init.version = XVID_VERSION;          init.version = XVID_VERSION;
365            init.cpu_flags = g_config.cpu;
366    
367            xvid_gbl_info_t info;
368            memset(&info, 0, sizeof(info));
369            info.version = XVID_VERSION;
370    
371          m_hdll = LoadLibrary(XVID_DLL_NAME);          m_hdll = LoadLibrary(XVID_DLL_NAME);
372          if (m_hdll == NULL) {          if (m_hdll == NULL) {
# Line 373  Line 402 
402                  return E_FAIL;                  return E_FAIL;
403          }          }
404    
405            if (xvid_global_func(0, XVID_GBL_INFO, &info, NULL) < 0)
406            {
407            xvid_global_func = NULL;
408            xvid_decore_func = NULL;
409            FreeLibrary(m_hdll);
410            m_hdll = NULL;
411                    MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST);
412                    return E_FAIL;
413            }
414    
415          memset(&m_create, 0, sizeof(m_create));          memset(&m_create, 0, sizeof(m_create));
416          m_create.version = XVID_VERSION;          m_create.version = XVID_VERSION;
417          m_create.handle = NULL;          m_create.handle = NULL;
418        /* Decoder threads */
419        if (g_config.cpu & XVID_CPU_FORCE) {
420                    m_create.num_threads = g_config.num_threads;
421            }
422            else {
423            m_create.num_threads = info.num_threads; /* Autodetect */
424                    g_config.num_threads = info.num_threads;
425            }
426    
427          memset(&m_frame, 0, sizeof(m_frame));          memset(&m_frame, 0, sizeof(m_frame));
428          m_frame.version = XVID_VERSION;          m_frame.version = XVID_VERSION;
# Line 464  Line 511 
511  {  {
512      DPRINTF("Destructor");      DPRINTF("Destructor");
513    
514  #ifdef XVID_USE_TRAYICON          if ((MSG_hwnd != NULL) && (m_tray_icon == 1)) { /* Destroy tray icon */
515          if (Tray_Icon) { /* Destroy tray icon */                  SendMessage(MSG_hwnd, WM_CLOSE, 0, 0);
                 NOTIFYICONDATA nid;  
                 ZeroMemory(&nid,sizeof(NOTIFYICONDATA));  
   
                 nid.cbSize = NOTIFYICONDATA_V1_SIZE;  
                 nid.hWnd = MSG_hwnd;  
                 nid.uID = 1456;  
   
                 Shell_NotifyIcon(NIM_DELETE, &nid);  
                 Tray_Icon = 0;  
516          }          }
 #endif  
517    
518          /* Close xvidcore library */          /* Close xvidcore library */
519          CloseLib();          CloseLib();
520    
521            clock_t endClock = clock();
522            if (((endClock - m_startClock) / CLOCKS_PER_SEC) > 3) {
523                    SaveRegistryInfo((endClock - m_startClock) / (CLOCKS_PER_SEC / 10));
524            }
525    
526            if ((MSG_hwnd != 0) && (m_tray_icon == 1)) { /* Final clean-up */
527              MSG_hwnd = 0;
528              Sleep(200);
529              m_tray_icon = 0;
530    #if defined(XVID_USE_MFT)
531              if (m_thread_handle) {
532                      TerminateThread(m_thread_handle, 0);
533                      CloseHandle(m_thread_handle);
534                      m_thread_handle = NULL;
535              }
536    #endif
537            }
538    
539  #if defined(XVID_USE_MFT)  #if defined(XVID_USE_MFT)
540          DeleteCriticalSection(&m_mft_lock);          DeleteCriticalSection(&m_mft_lock);
541  #endif  #endif
# Line 588  Line 643 
643    {    {
644    case FOURCC_mp4v:    case FOURCC_mp4v:
645          case FOURCC_MP4V:          case FOURCC_MP4V:
646            case FOURCC_lmp4 :
647            case FOURCC_LMP4 :
648            case FOURCC_rmp4 :
649            case FOURCC_RMP4 :
650            case FOURCC_smp4 :
651            case FOURCC_SMP4 :
652            case FOURCC_hdx4 :
653            case FOURCC_HDX4 :
654                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
655                          CloseLib();                          CloseLib();
656                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
657                  }                  }
658                  break;                  break;
659            case FOURCC_divx :
660          case FOURCC_DIVX :          case FOURCC_DIVX :
661            case FOURCC_dx50 :
662            case FOURCC_DX50 :
663                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
664                          CloseLib();                          CloseLib();
665                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
666                  }                  }
667                  break;                  break;
668          case FOURCC_DX50 :          case FOURCC_3ivx :
669                  if (!(g_config.supported_4cc & SUPPORT_DX50)) {          case FOURCC_3IVX :
670            case FOURCC_3iv0 :
671            case FOURCC_3IV0 :
672            case FOURCC_3iv1 :
673            case FOURCC_3IV1 :
674            case FOURCC_3iv2 :
675            case FOURCC_3IV2 :
676                    if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
677                          CloseLib();                          CloseLib();
678                          return VFW_E_TYPE_NOT_ACCEPTED;                          return VFW_E_TYPE_NOT_ACCEPTED;
679                  }                  }
680            case FOURCC_xvid :
681          case FOURCC_XVID :          case FOURCC_XVID :
682                  break;                  break;
683    
# Line 655  Line 729 
729                          vih->dwPictAspectRatioY = abs(m_create.height);                          vih->dwPictAspectRatioY = abs(m_create.height);
730                          forced_ar = false;                          forced_ar = false;
731                  }                  }
732                    if (interlaced) {
733                            vih->dwInterlaceFlags = AMINTERLACE_IsInterlaced;
734                            if (interlaced > 1) {
735                                    vih->dwInterlaceFlags |= AMINTERLACE_Field1First;
736                            }
737                    }
738                    else {
739                            vih->dwInterlaceFlags = 0;
740                    }
741          } else {          } else {
742    
743                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
# Line 764  Line 847 
847  /* (internal function) change colorspace */  /* (internal function) change colorspace */
848  #define CALC_BI_STRIDE(width,bitcount)  ((((width * bitcount) + 31) & ~31) >> 3)  #define CALC_BI_STRIDE(width,bitcount)  ((((width * bitcount) + 31) & ~31) >> 3)
849    
850  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format)  HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void *format, int *bitdepth, int noflip)
851  {  {
852          DWORD biWidth;          DWORD biWidth;
853            *bitdepth = 32;
854    
855          if (formattype == FORMAT_VideoInfo)          if (formattype == FORMAT_VideoInfo)
856          {          {
857                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;                  VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;
858                  biWidth = vih->bmiHeader.biWidth;                  biWidth = vih->bmiHeader.biWidth;
859                    *bitdepth = vih->bmiHeader.biBitCount;
860                  out_stride = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);                  out_stride = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);
861                  rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);                  rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
862          }          }
# Line 779  Line 864 
864          {          {
865                  VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;                  VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;
866                  biWidth = vih2->bmiHeader.biWidth;                  biWidth = vih2->bmiHeader.biWidth;
867                    *bitdepth = vih2->bmiHeader.biBitCount;
868                  out_stride = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);                  out_stride = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);
869                  rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);                  rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);
870          }          }
# Line 787  Line 873 
873                  return S_FALSE;                  return S_FALSE;
874          }          }
875    
876            if (noflip) rgb_flip = 0;
877    
878          if (subtype == CLSID_MEDIASUBTYPE_IYUV)          if (subtype == CLSID_MEDIASUBTYPE_IYUV)
879          {          {
880                  DPRINTF("IYUV");                  DPRINTF("IYUV");
# Line 856  Line 944 
944    
945  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)  HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt)
946  {  {
947            int bitdepth;
948          DPRINTF("SetMediaType");          DPRINTF("SetMediaType");
949    
950          if (direction == PINDIR_OUTPUT)          if (direction == PINDIR_OUTPUT)
951          {          {
952                  return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());                  return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format(), &bitdepth, 0);
953          }          }
954    
955          return S_OK;          return S_OK;
# Line 882  Line 971 
971  {  {
972          DPRINTF("CompleteConnect");          DPRINTF("CompleteConnect");
973    
974  #ifdef XVID_USE_TRAYICON          if ((direction == PINDIR_OUTPUT) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
         if ((direction == PINDIR_OUTPUT) && (Tray_Icon == 0))  
975          {          {
976                  WNDCLASSEX wc;                  WNDCLASSEX wc;
977    
# Line 908  Line 996 
996                  NOTIFYICONDATA nid;                  NOTIFYICONDATA nid;
997                  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));                  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
998    
999                  nid.cbSize = NOTIFYICONDATA_V1_SIZE;                  nid.cbSize = sizeof(NOTIFYICONDATA);
1000                  nid.hWnd = MSG_hwnd;                  nid.hWnd = MSG_hwnd;
1001                  nid.uID = 1456;                  nid.uID = 1456;
1002                    nid.uVersion = NOTIFYICON_VERSION;
1003                  nid.uCallbackMessage = WM_ICONMESSAGE;                  nid.uCallbackMessage = WM_ICONMESSAGE;
1004                  nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));                  nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
1005                  strcpy_s(nid.szTip, 19, "Xvid Video Decoder");                  strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
1006                  nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;                  nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
1007    
1008                  Shell_NotifyIcon(NIM_ADD, &nid);                  Shell_NotifyIcon(NIM_ADD, &nid);
1009                    Shell_NotifyIcon(NIM_SETVERSION, &nid);
1010    
1011                  DestroyIcon(nid.hIcon);                  DestroyIcon(nid.hIcon);
1012                  Tray_Icon = 1;                  m_tray_icon = 1;
1013          }          }
 #endif  
1014    
1015          return S_OK;          return S_OK;
1016  }  }
# Line 995  Line 1084 
1084          pOut->GetMediaType(&mtOut);          pOut->GetMediaType(&mtOut);
1085          if (mtOut != NULL)          if (mtOut != NULL)
1086          {          {
1087                    int bitdepth;
1088                  HRESULT result;                  HRESULT result;
1089    
1090                  result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);                  result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat, &bitdepth, 0);
1091                  DeleteMediaType(mtOut);                  DeleteMediaType(mtOut);
1092    
1093                  if (result != S_OK)                  if (result != S_OK)
# Line 1061  Line 1151 
1151                  {                  {
1152              DPRINTF("*** XVID_DEC_DECODE");              DPRINTF("*** XVID_DEC_DECODE");
1153                          return S_FALSE;                          return S_FALSE;
1154                  } else                  } else if ((g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) || !!(interlaced)) {
                         if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) {  
1155    
1156        if (stats.type != XVID_TYPE_NOTHING) {  /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */        if (stats.type != XVID_TYPE_NOTHING) {  /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */
1157                          // inspired by minolta! works for VMR 7 + 9                          // inspired by minolta! works for VMR 7 + 9
# Line 1074  Line 1163 
1163                                  CMediaType mtOut2 = m_pOutput->CurrentMediaType();                                  CMediaType mtOut2 = m_pOutput->CurrentMediaType();
1164                                  VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();                                  VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();
1165    
1166                                  if (*mtOut2.FormatType() == FORMAT_VideoInfo2 &&                                          if (*mtOut2.FormatType() == FORMAT_VideoInfo2)
1167                                          vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)                                          {
1168                                                    int need_format_change = 0;
1169    
1170                                                    if (vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)
1171                                  {                                  {
1172                                          vihOut2->dwPictAspectRatioX = ar_x;                                          vihOut2->dwPictAspectRatioX = ar_x;
1173                                          vihOut2->dwPictAspectRatioY = ar_y;                                          vihOut2->dwPictAspectRatioY = ar_y;
1174                                                            int format_change;
1175                                                    }
1176    
1177                                                    if ((interlaced) && !(vihOut2->dwInterlaceFlags & AMINTERLACE_IsInterlaced))
1178                                                    {
1179                                                            vihOut2->dwInterlaceFlags = AMINTERLACE_IsInterlaced;
1180                                                            if (interlaced > 2) {
1181                                                                    vihOut2->dwInterlaceFlags |= AMINTERLACE_Field1First;
1182                                                            }
1183                                                            need_format_change = 1;
1184                                                    }
1185                                                    else if (!interlaced && !!(vihOut2->dwInterlaceFlags & AMINTERLACE_IsInterlaced)){
1186                                                            vihOut2->dwInterlaceFlags = 0;
1187                                                            need_format_change = 1;
1188                                                    }
1189    
1190                                                    if (need_format_change) {
1191                                          pOut2->SetMediaType(&mtOut2);                                          pOut2->SetMediaType(&mtOut2);
1192                                          m_pOutput->SetMediaType(&mtOut2);                                          m_pOutput->SetMediaType(&mtOut2);
1193                                  }                                  }
1194                                            }
1195                                  pOut2->Release();                                  pOut2->Release();
1196                          }                          }
1197        }        }
# Line 1144  Line 1254 
1254                          ar_y = par_y * stats.data.vol.height;                          ar_y = par_y * stats.data.vol.height;
1255                  }                  }
1256    
1257                    if (!!(stats.data.vol.general & XVID_VOL_INTERLACING)) {
1258                            interlaced = (stats.data.vop.general & XVID_VOP_TOPFIELDFIRST) ? 2 : 1;
1259                    }
1260                    else if (interlaced > 0) {
1261                            interlaced = 0;
1262                    }
1263    
1264                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
1265                  m_frame.length -= length;                  m_frame.length -= length;
1266                  goto repeat;                  goto repeat;
# Line 1267  Line 1384 
1384                  pStreamInfo->cbAlignment = 0;                  pStreamInfo->cbAlignment = 0;
1385          }          }
1386          else {          else {
1387                  pStreamInfo->cbSize = m_create.width * abs(m_create.height) * 4; // XXX                  pStreamInfo->cbSize = (m_create.width * abs(m_create.height) * m_pOutputTypeBPP) >> 3;
1388                  pStreamInfo->cbAlignment = 1;                  pStreamInfo->cbAlignment = 1;
1389          }          }
1390    
# Line 1313  Line 1430 
1430                  return MF_E_INVALIDSTREAMNUMBER;                  return MF_E_INVALIDSTREAMNUMBER;
1431    
1432          DWORD i = 0;          DWORD i = 0;
1433          GUID *bs_guid_table[8];          GUID *bs_guid_table[32];
1434    
1435          bs_guid_table[i++] = (GUID *)&CLSID_XVID;          bs_guid_table[i++] = (GUID *)&CLSID_XVID;
1436          bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC;          bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC;
1437    
1438          if (g_config.supported_4cc & SUPPORT_DX50) {          if (g_config.supported_4cc & SUPPORT_3IVX) {
1439                  bs_guid_table[i++] = (GUID *)&CLSID_DX50;                  bs_guid_table[i++] = (GUID *)&CLSID_3IVX;
1440                  bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_3IVX_UC;
1441                    bs_guid_table[i++] = (GUID *)&CLSID_3IV0;
1442                    bs_guid_table[i++] = (GUID *)&CLSID_3IV0_UC;
1443                    bs_guid_table[i++] = (GUID *)&CLSID_3IV1;
1444                    bs_guid_table[i++] = (GUID *)&CLSID_3IV1_UC;
1445                    bs_guid_table[i++] = (GUID *)&CLSID_3IV2;
1446                    bs_guid_table[i++] = (GUID *)&CLSID_3IV2_UC;
1447          }          }
1448          if (g_config.supported_4cc & SUPPORT_DIVX) {          if (g_config.supported_4cc & SUPPORT_DIVX) {
1449                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX;                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX;
1450                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC;
1451                    bs_guid_table[i++] = (GUID *)&CLSID_DX50;
1452                    bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC;
1453          }          }
1454          if (g_config.supported_4cc & SUPPORT_MP4V) {          if (g_config.supported_4cc & SUPPORT_MP4V) {
1455                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V;                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V;
1456                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC;                  bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC;
1457                    bs_guid_table[i++] = (GUID *)&CLSID_LMP4;
1458                    bs_guid_table[i++] = (GUID *)&CLSID_LMP4_UC;
1459                    bs_guid_table[i++] = (GUID *)&CLSID_RMP4;
1460                    bs_guid_table[i++] = (GUID *)&CLSID_RMP4_UC;
1461                    bs_guid_table[i++] = (GUID *)&CLSID_SMP4;
1462                    bs_guid_table[i++] = (GUID *)&CLSID_SMP4_UC;
1463                    bs_guid_table[i++] = (GUID *)&CLSID_HDX4;
1464                    bs_guid_table[i++] = (GUID *)&CLSID_HDX4_UC;
1465          }          }
1466    
1467          const GUID *subtype;          const GUID *subtype;
# Line 1389  Line 1522 
1522                  break;                  break;
1523  }  }
1524          case 1 :          case 1 :
1525    if ( USE_YVYU )
1526    {
1527                csp = MFVideoFormat_YVYU;
1528                bitdepth = 4;
1529                break;
1530    }
1531            case 2 :
1532  if ( USE_UYVY )  if ( USE_UYVY )
1533  {  {
1534                  csp = MFVideoFormat_UYVY;                  csp = MFVideoFormat_UYVY;
1535                  bitdepth = 4;                  bitdepth = 4;
1536                  break;                  break;
1537  }  }
1538          case 2  :          case 3  :
1539                  if ( USE_IYUV )                  if ( USE_IYUV )
1540  {  {
1541                  csp = MFVideoFormat_IYUV;                  csp = MFVideoFormat_IYUV;
1542                  bitdepth = 3;                  bitdepth = 3;
1543                  break;                  break;
1544  }  }
1545          case 3  :          case 4  :
1546  if ( USE_YV12 )  if ( USE_YV12 )
1547  {  {
1548                  csp = MFVideoFormat_YV12;                  csp = MFVideoFormat_YV12;
1549                  bitdepth = 3;                  bitdepth = 3;
1550                  break;                  break;
1551  }  }
1552          case 4 :          case 5 :
1553  if ( USE_RGB32 )  if ( USE_RGB32 )
1554  {  {
1555                  csp = MFVideoFormat_RGB32;                  csp = MFVideoFormat_RGB32;
1556                  bitdepth = 8;                  bitdepth = 8;
1557                  break;                  break;
1558  }  }
1559          case 5 :          case 6 :
1560  if ( USE_RGB24 )  if ( USE_RGB24 )
1561  {  {
1562                  csp = MFVideoFormat_RGB24;                  csp = MFVideoFormat_RGB24;
1563                  bitdepth = 6;                  bitdepth = 6;
1564                  break;                  break;
1565  }  }
1566          case 6 :          case 7 :
1567  if ( USE_RG555 )  if ( USE_RG555 )
1568  {  {
1569                  csp = MFVideoFormat_RGB555;                  csp = MFVideoFormat_RGB555;
1570                  bitdepth = 4;                  bitdepth = 4;
1571                  break;                  break;
1572  }  }
1573          case 7 :          case 8 :
1574  if ( USE_RG565 )  if ( USE_RG565 )
1575  {  {
1576                  csp = MFVideoFormat_RGB565;                  csp = MFVideoFormat_RGB565;
# Line 1468  Line 1608 
1608          }          }
1609    
1610          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1611                  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);
1612          }          }
1613    
1614          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1615                  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));
1616          }          }
1617    
1618          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
# Line 1480  Line 1620 
1620          }          }
1621    
1622          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1623                    if (interlaced > 1) {
1624                            hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedUpperFirst);
1625                    }
1626                    else if (interlaced) {
1627                            hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedLowerFirst);
1628                    }
1629                    else {
1630                  hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);                  hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
1631          }          }
1632            }
1633    
1634          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1635                  hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, ar_x, ar_y);                  hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, ar_x, ar_y);
# Line 1520  Line 1668 
1668                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1669    
1670          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1671          if (pType) { // /* Check the type */          if (pType) { /* Check the type */
1672              hr = OnCheckInputType(pType);              hr = OnCheckInputType(pType);
1673          }          }
1674          }          }
# Line 1535  Line 1683 
1683          return hr;          return hr;
1684  }  }
1685    
1686    DWORD WINAPI CreateTrayIcon(LPVOID lpParameter)
1687    {
1688            WNDCLASSEX wc;
1689    
1690            wc.cbSize = sizeof(WNDCLASSEX);
1691            wc.lpfnWndProc = msg_proc;
1692            wc.style = CS_HREDRAW | CS_VREDRAW;
1693            wc.cbWndExtra = 0;
1694            wc.cbClsExtra = 0;
1695            wc.hInstance = (HINSTANCE)g_xvid_hInst;
1696            wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
1697            wc.lpszMenuName = NULL;
1698            wc.lpszClassName = "XVID_MSG_WINDOW";
1699            wc.hIcon = NULL;
1700            wc.hIconSm = NULL;
1701            wc.hCursor = NULL;
1702            RegisterClassEx(&wc);
1703    
1704            MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,
1705                    CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE)g_xvid_hInst, NULL);
1706    
1707            /* display the tray icon */
1708            NOTIFYICONDATA nid;
1709            ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
1710    
1711            nid.cbSize = sizeof(NOTIFYICONDATA);
1712            nid.hWnd = MSG_hwnd;
1713            nid.uID = 1456;
1714            nid.uVersion = NOTIFYICON_VERSION;
1715            nid.uCallbackMessage = WM_ICONMESSAGE;
1716            nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON));
1717            strcpy_s(nid.szTip, 19, "Xvid Video Decoder");
1718            nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_SHOWTIP;
1719    
1720            Shell_NotifyIcon(NIM_ADD, &nid);
1721            Shell_NotifyIcon(NIM_SETVERSION, &nid);
1722    
1723            DestroyIcon(nid.hIcon);
1724    
1725            MSG msg;
1726            while (MSG_hwnd && GetMessage(&msg, MSG_hwnd, 0, 0)) {
1727                    TranslateMessage(&msg);
1728                    DispatchMessage(&msg);
1729            }
1730    
1731            return 0;
1732    }
1733    
1734  HRESULT CXvidDecoder::MFTSetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)  HRESULT CXvidDecoder::MFTSetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)
1735  {  {
1736          DPRINTF("(MFT)SetOutputType");          DPRINTF("(MFT)SetOutputType");
# Line 1556  Line 1752 
1752          if (HasPendingOutput())          if (HasPendingOutput())
1753                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;                  hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
1754    
1755            int bitdepth;
1756          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1757                  if (pType) { /* Check the type */                  if (pType) { /* Check the type */
1758                          AM_MEDIA_TYPE *am;                          AM_MEDIA_TYPE *am;
1759                          hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am);                          hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am);
1760    
1761                          if (SUCCEEDED(hr)) {                          if (SUCCEEDED(hr)) {
1762                                  if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat))) {                                  if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat, &bitdepth, 1))) {
1763                                          DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)");                                          DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)");
1764                                          return MF_E_INVALIDTYPE;                                          return MF_E_INVALIDTYPE;
1765                                  }                                  }
# Line 1575  Line 1772 
1772    
1773          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
1774                  if (bReallySet) { /* Set the type if needed */                  if (bReallySet) { /* Set the type if needed */
1775                          hr = OnSetOutputType(pType);                          hr = OnSetOutputType(pType, bitdepth);
1776                  }                  }
1777          }          }
1778    
1779  #ifdef XVID_USE_TRAYICON          if (SUCCEEDED(hr) && (MSG_hwnd == 0) && (m_tray_icon == 0) && (g_config.bTrayIcon != 0))
         if (SUCCEEDED(hr) && Tray_Icon == 0) /* Create message passing window */  
1780          {          {
1781                  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);  
   
                 MSG_hwnd = CreateWindowEx(0, "XVID_MSG_WINDOW", NULL, 0, CW_USEDEFAULT,  
                                   CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE) g_xvid_hInst, NULL);  
   
                 /* display the tray icon */  
                 NOTIFYICONDATA nid;  
                 ZeroMemory(&nid,sizeof(NOTIFYICONDATA));  
   
                 nid.cbSize = NOTIFYICONDATA_V1_SIZE;  
                 nid.hWnd = MSG_hwnd;  
                 nid.uID = 1456;  
                 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);  
1782    
1783                  DestroyIcon(nid.hIcon);                  if (m_thread_handle)
1784                  Tray_Icon = 1;                      m_tray_icon = 1;
1785          }          }
 #endif  
1786    
1787          LeaveCriticalSection(&m_mft_lock);          LeaveCriticalSection(&m_mft_lock);
1788    
1789          return hr;          return hr;
1790  }  }
1791    
# Line 1688  Line 1853 
1853    
1854          EnterCriticalSection(&m_mft_lock);          EnterCriticalSection(&m_mft_lock);
1855    
1856          /* If there's pending output sampels we don't accept new          /* If there's pending output samples we don't accept new
1857             input data until ProcessOutput() or Flush() was called */             input data until ProcessOutput() or Flush() was called */
1858          if (!HasPendingOutput()) {          if (!HasPendingOutput()) {
1859                  *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;                  *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
# Line 1841  Line 2006 
2006          HRESULT hr = S_OK;          HRESULT hr = S_OK;
2007          IMFMediaBuffer *pBuffer;          IMFMediaBuffer *pBuffer;
2008    
2009            int need_format_change = 0;
2010    
2011          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
2012                  hr = pSample->ConvertToContiguousBuffer(&pBuffer);                  hr = pSample->ConvertToContiguousBuffer(&pBuffer);
2013          }          }
# Line 1926  Line 2093 
2093    
2094                          ar_x = par_x * stats.data.vol.width;                          ar_x = par_x * stats.data.vol.width;
2095                          ar_y = par_y * stats.data.vol.height;                          ar_y = par_y * stats.data.vol.height;
2096    
2097                            need_format_change = 1;
2098                    }
2099    
2100                    if (!!(stats.data.vol.general & XVID_VOL_INTERLACING)) {
2101                            interlaced = (stats.data.vop.general & XVID_VOP_TOPFIELDFIRST) ? 2 : 1;
2102                            need_format_change = 1;
2103                    }
2104                    else {
2105                            if (interlaced > 0) {
2106                                    interlaced = 0;
2107                                    need_format_change = 1;
2108                            }
2109                  }                  }
2110    
2111                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;                  m_frame.bitstream = (BYTE*)m_frame.bitstream + length;
# Line 1949  Line 2129 
2129                  if (FAILED(pSample->GetSampleDuration(&m_timelength))) {                  if (FAILED(pSample->GetSampleDuration(&m_timelength))) {
2130                          m_timelength = INVALID_TIME;                          m_timelength = INVALID_TIME;
2131                  }                  }
2132                    if (m_timestamp != INVALID_TIME && stats.type == XVID_TYPE_IVOP) {
2133                            m_rtFrame = m_timestamp;
2134                    }
2135            }
2136    
2137            if (need_format_change) {
2138                    IMFMediaType *pOutputType = NULL;
2139                    hr = MFTGetOutputCurrentType(0, &pOutputType);
2140    
2141                    if (SUCCEEDED(hr)) {
2142                            if (interlaced > 1) {
2143                                    hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedUpperFirst);
2144                            }
2145                            else if (interlaced) {
2146                                    hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_FieldInterleavedLowerFirst);
2147                            }
2148                            else {
2149                                    hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
2150                            }
2151                    }
2152    
2153                    if (SUCCEEDED(hr)) {
2154                            hr = MFSetAttributeRatio(pOutputType, MF_MT_PIXEL_ASPECT_RATIO, ar_x, ar_y);
2155                    }
2156    
2157                    if (SUCCEEDED(hr)) {
2158                            MFTSetOutputType(0, pOutputType, 0);
2159                    }
2160    
2161                    if (pOutputType) pOutputType->Release();
2162          }          }
2163    
2164          LeaveCriticalSection(&m_mft_lock);          LeaveCriticalSection(&m_mft_lock);
# Line 1984  Line 2194 
2194    
2195          BYTE *Dst = NULL;          BYTE *Dst = NULL;
2196          DWORD buffer_size;          DWORD buffer_size;
2197            LONG stride = m_create.width;
2198          IMFMediaBuffer *pOutput = NULL;          IMFMediaBuffer *pOutput = NULL;
2199            IMF2DBuffer *pOutput2D = NULL;
2200    
2201          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
2202                  hr = pOutputSamples[0].pSample->GetBufferByIndex(0, &pOutput); /* Get output buffer */                  hr = pOutputSamples[0].pSample->GetBufferByIndex(0, &pOutput); /* Get output buffer */
# Line 1995  Line 2206 
2206                  hr = pOutput->GetMaxLength(&buffer_size);                  hr = pOutput->GetMaxLength(&buffer_size);
2207          }          }
2208    
2209          if (SUCCEEDED(hr))          if (SUCCEEDED(hr)) {
2210                    hr = pOutput->QueryInterface(IID_IMF2DBuffer, (void **)&pOutput2D);
2211            }
2212    
2213            if (SUCCEEDED(hr)) {
2214                    hr = pOutput2D->Lock2D(&Dst, &stride);
2215            }
2216            else {
2217                  hr = pOutput->Lock(&Dst, NULL, NULL);                  hr = pOutput->Lock(&Dst, NULL, NULL);
2218            }
2219    
2220          if (SUCCEEDED(hr)) {          if (SUCCEEDED(hr)) {
2221                  xvid_gbl_convert_t convert;                  xvid_gbl_convert_t convert;
# Line 2014  Line 2233 
2233    
2234                  convert.output.csp = m_frame.output.csp;                  convert.output.csp = m_frame.output.csp;
2235                  convert.output.plane[0] = Dst;                  convert.output.plane[0] = Dst;
2236                  convert.output.stride[0] = out_stride;                  convert.output.stride[0] = stride;
2237    
2238                  convert.width = m_create.width;                  convert.width = m_create.width;
2239                  convert.height = m_create.height;                  convert.height = m_create.height;
2240                  convert.interlacing = 0;                  convert.interlacing = (interlaced > 0) ? 1 : 0;
2241    
2242                  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)
2243                          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 */
2244                                  hr = E_FAIL;                                  hr = E_FAIL;
   
2245                  m_frame.output.plane[1] = NULL;                  m_frame.output.plane[1] = NULL;
2246          }          }
2247    
# Line 2048  Line 2266 
2266                  }                  }
2267    
2268                  if (SUCCEEDED(hr))                  if (SUCCEEDED(hr))
2269                          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);
2270          }          }
2271    
2272          if (pOutput) {          if (pOutput2D) {
2273                    pOutput2D->Unlock2D();
2274                    pOutput2D->Release();
2275                    if (pOutput)
2276                        pOutput->Release();
2277            }
2278            else if (pOutput) {
2279                  pOutput->Unlock();                  pOutput->Unlock();
2280                  pOutput->Release();                  pOutput->Release();
2281          }          }
# Line 2126  Line 2350 
2350                  hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);                  hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);
2351          }          }
2352    
2353          if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC) {          if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC ||
2354                subtype == CLSID_LMP4 || subtype == CLSID_LMP4_UC ||
2355                subtype == CLSID_RMP4 || subtype == CLSID_RMP4_UC ||
2356                subtype == CLSID_SMP4 || subtype == CLSID_SMP4_UC ||
2357                subtype == CLSID_HDX4 || subtype == CLSID_HDX4_UC) {
2358                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {                  if (!(g_config.supported_4cc & SUPPORT_MP4V)) {
2359                          CloseLib();                          CloseLib();
2360                          hr = MF_E_INVALIDTYPE;                          hr = MF_E_INVALIDTYPE;
# Line 2141  Line 2369 
2369                  else m_create.fourcc = FOURCC_DIVX;                  else m_create.fourcc = FOURCC_DIVX;
2370          }          }
2371          else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) {          else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) {
2372                  if (!(g_config.supported_4cc & SUPPORT_DX50)) {                  if (!(g_config.supported_4cc & SUPPORT_DIVX)) {
2373                          CloseLib();                          CloseLib();
2374                          hr = MF_E_INVALIDTYPE;                          hr = MF_E_INVALIDTYPE;
2375                  }                  }
2376                  else m_create.fourcc = FOURCC_DX50;                  else m_create.fourcc = FOURCC_DX50;
2377          }          }
2378            else if (subtype == CLSID_3IVX || subtype == CLSID_3IVX_UC ||
2379                     subtype == CLSID_3IV0 || subtype == CLSID_3IV0_UC ||
2380                     subtype == CLSID_3IV1 || subtype == CLSID_3IV1_UC ||
2381                     subtype == CLSID_3IV2 || subtype == CLSID_3IV2_UC) {
2382                    if (!(g_config.supported_4cc & SUPPORT_3IVX)) {
2383                            CloseLib();
2384                            hr = MF_E_INVALIDTYPE;
2385                    }
2386                    else m_create.fourcc = FOURCC_3IVX;
2387            }
2388          else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) {          else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) {
2389                  m_create.fourcc = FOURCC_XVID;                  m_create.fourcc = FOURCC_XVID;
2390          }          }
# Line 2225  Line 2463 
2463          return hr;          return hr;
2464  }  }
2465    
2466  HRESULT CXvidDecoder::OnSetOutputType(IMFMediaType *pmt)  HRESULT CXvidDecoder::OnSetOutputType(IMFMediaType *pmt, int bitdepth)
2467  {  {
2468          if (m_pOutputType) m_pOutputType->Release();          if (m_pOutputType) m_pOutputType->Release();
2469    
2470          m_pOutputType = pmt;          m_pOutputType = pmt;
2471          m_pOutputType->AddRef();          m_pOutputType->AddRef();
2472            m_pOutputTypeBPP = bitdepth;
2473    
2474          return S_OK;          return S_OK;
2475  }  }

Legend:
Removed from v.1901  
changed lines
  Added in v.2134

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