--- trunk/xvidcore/dshow/src/CXvidDecoder.cpp 2010/10/29 16:39:07 1902 +++ trunk/xvidcore/dshow/src/CXvidDecoder.cpp 2015/06/08 19:18:52 2103 @@ -3,8 +3,8 @@ * XVID MPEG-4 VIDEO CODEC * - Xvid Decoder part of the DShow Filter - * - * Copyright(C) 2002-2010 Peter Ross - * 2003-2010 Michael Militzer + * Copyright(C) 2002-2011 Peter Ross + * 2003-2011 Michael Militzer * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: CXvidDecoder.cpp,v 1.23 2010-10-29 16:39:07 Isibaar Exp $ - * - ****************************************************************************/ - -/**************************************************************************** - * - * 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 + * $Id$ * ****************************************************************************/ @@ -44,8 +36,9 @@ C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug */ -// #define XVID_USE_MFT -// #define XVID_USE_TRAYICON +#ifdef ENABLE_MFT +#define XVID_USE_MFT +#endif #include @@ -95,6 +88,22 @@ { &MEDIATYPE_Video, &CLSID_DIVX_UC }, { &MEDIATYPE_Video, &CLSID_DX50 }, { &MEDIATYPE_Video, &CLSID_DX50_UC }, + { &MEDIATYPE_Video, &CLSID_3IVX }, + { &MEDIATYPE_Video, &CLSID_3IVX_UC }, + { &MEDIATYPE_Video, &CLSID_3IV0 }, + { &MEDIATYPE_Video, &CLSID_3IV0_UC }, + { &MEDIATYPE_Video, &CLSID_3IV1 }, + { &MEDIATYPE_Video, &CLSID_3IV1_UC }, + { &MEDIATYPE_Video, &CLSID_3IV2 }, + { &MEDIATYPE_Video, &CLSID_3IV2_UC }, + { &MEDIATYPE_Video, &CLSID_LMP4 }, + { &MEDIATYPE_Video, &CLSID_LMP4_UC }, + { &MEDIATYPE_Video, &CLSID_RMP4 }, + { &MEDIATYPE_Video, &CLSID_RMP4_UC }, + { &MEDIATYPE_Video, &CLSID_SMP4 }, + { &MEDIATYPE_Video, &CLSID_SMP4_UC }, + { &MEDIATYPE_Video, &CLSID_HDX4 }, + { &MEDIATYPE_Video, &CLSID_HDX4_UC }, { &MEDIATYPE_Video, &CLSID_MP4V }, { &MEDIATYPE_Video, &CLSID_MP4V_UC }, }; @@ -136,7 +145,7 @@ { &CLSID_XVID, // Filter CLSID XVID_NAME_L, // Filter name - MERIT_PREFERRED, // Its merit + MERIT_PREFERRED+2, // Its merit sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins psudPins // Pin details }; @@ -166,7 +175,6 @@ /* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */ int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate); -#ifdef XVID_USE_TRAYICON extern HINSTANCE g_xvid_hInst; static int GUI_Page = 0; @@ -208,7 +216,6 @@ return TRUE; /* ok */ } -#endif STDAPI DllRegisterServer() { @@ -233,7 +240,7 @@ /* Register the MFT decoder */ MFTRegister(CLSID_XVID, // CLSID MFT_CATEGORY_VIDEO_DECODER, // Category - const_cast(XVID_NAME_L), // Friendly name + const_cast(XVID_NAME_MFT_L), // Friendly name 0, // Flags inputs_num, // Number of input types mft_bs, // Input types @@ -302,10 +309,8 @@ /* constructor */ -#define XVID_DLL_NAME "xvidcore.dll" - CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : - CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL) + CVideoTransformFilter(TEXT("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL) { DPRINTF("Constructor"); @@ -326,6 +331,21 @@ LoadRegistryInfo(); *phr = OpenLib(); + + { + TCHAR lpFilename[MAX_PATH]; + int sLen = GetModuleFileName(NULL, lpFilename, MAX_PATH); +#ifdef _UNICODE + if ((sLen >= 11) && (_wcsnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) { +#else + if ((sLen >= 11) && (_strnicmp(&(lpFilename[sLen - 11]), TEXT("dllhost.exe"), 11) == 0)) { +#endif + if (Tray_Icon == 0) Tray_Icon = -1; // create no tray icon upon thumbnail generation + } + else + if (Tray_Icon == -1) Tray_Icon = 0; // can show tray icon + } + } HRESULT CXvidDecoder::OpenLib() @@ -338,11 +358,16 @@ xvid_gbl_init_t init; memset(&init, 0, sizeof(init)); init.version = XVID_VERSION; + init.cpu_flags = g_config.cpu; + + xvid_gbl_info_t info; + memset(&info, 0, sizeof(info)); + info.version = XVID_VERSION; m_hdll = LoadLibrary(XVID_DLL_NAME); if (m_hdll == NULL) { DPRINTF("dll load failed"); - MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST); + MessageBox(0, XVID_DLL_NAME TEXT(" not found"), TEXT("Error"), MB_TOPMOST); return E_FAIL; } @@ -350,7 +375,7 @@ if (xvid_global_func == NULL) { FreeLibrary(m_hdll); m_hdll = NULL; - MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST); + MessageBox(0, TEXT("xvid_global() not found"), TEXT("Error"), MB_TOPMOST); return E_FAIL; } @@ -359,7 +384,7 @@ xvid_global_func = NULL; FreeLibrary(m_hdll); m_hdll = NULL; - MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST); + MessageBox(0, TEXT("xvid_decore() not found"), TEXT("Error"), MB_TOPMOST); return E_FAIL; } @@ -369,13 +394,31 @@ xvid_decore_func = NULL; FreeLibrary(m_hdll); m_hdll = NULL; - MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); + MessageBox(0, TEXT("xvid_global() failed"), TEXT("Error"), MB_TOPMOST); + return E_FAIL; + } + + if (xvid_global_func(0, XVID_GBL_INFO, &info, NULL) < 0) + { + xvid_global_func = NULL; + xvid_decore_func = NULL; + FreeLibrary(m_hdll); + m_hdll = NULL; + MessageBox(0, TEXT("xvid_global() failed"), TEXT("Error"), MB_TOPMOST); return E_FAIL; } memset(&m_create, 0, sizeof(m_create)); m_create.version = XVID_VERSION; m_create.handle = NULL; + /* Decoder threads */ + if (g_config.cpu & XVID_CPU_FORCE) { + m_create.num_threads = g_config.num_threads; + } + else { + m_create.num_threads = info.num_threads; /* Autodetect */ + g_config.num_threads = info.num_threads; + } memset(&m_frame, 0, sizeof(m_frame)); m_frame.version = XVID_VERSION; @@ -464,8 +507,7 @@ { DPRINTF("Destructor"); -#ifdef XVID_USE_TRAYICON - if (Tray_Icon) { /* Destroy tray icon */ + if (Tray_Icon > 0) { /* Destroy tray icon */ NOTIFYICONDATA nid; ZeroMemory(&nid,sizeof(NOTIFYICONDATA)); @@ -476,7 +518,6 @@ Shell_NotifyIcon(NIM_DELETE, &nid); Tray_Icon = 0; } -#endif /* Close xvidcore library */ CloseLib(); @@ -586,24 +627,43 @@ switch(hdr->biCompression) { - case FOURCC_mp4v: - case FOURCC_MP4V: + case FOURCC_mp4v : + case FOURCC_MP4V : + case FOURCC_lmp4 : + case FOURCC_LMP4 : + case FOURCC_rmp4 : + case FOURCC_RMP4 : + case FOURCC_smp4 : + case FOURCC_SMP4 : + case FOURCC_hdx4 : + case FOURCC_HDX4 : if (!(g_config.supported_4cc & SUPPORT_MP4V)) { CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } break; + case FOURCC_divx : case FOURCC_DIVX : + case FOURCC_dx50 : + case FOURCC_DX50 : if (!(g_config.supported_4cc & SUPPORT_DIVX)) { CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } break; - case FOURCC_DX50 : - if (!(g_config.supported_4cc & SUPPORT_DX50)) { + case FOURCC_3ivx : + case FOURCC_3IVX : + case FOURCC_3iv0 : + case FOURCC_3IV0 : + case FOURCC_3iv1 : + case FOURCC_3IV1 : + case FOURCC_3iv2 : + case FOURCC_3IV2 : + if (!(g_config.supported_4cc & SUPPORT_3IVX)) { CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } + case FOURCC_xvid : case FOURCC_XVID : break; @@ -764,7 +824,7 @@ /* (internal function) change colorspace */ #define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) -HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) +HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format, int noflip) { DWORD biWidth; @@ -787,6 +847,8 @@ return S_FALSE; } + if (noflip) rgb_flip = 0; + if (subtype == CLSID_MEDIASUBTYPE_IYUV) { DPRINTF("IYUV"); @@ -860,7 +922,7 @@ if (direction == PINDIR_OUTPUT) { - return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format()); + return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format(), 0); } return S_OK; @@ -882,8 +944,7 @@ { DPRINTF("CompleteConnect"); -#ifdef XVID_USE_TRAYICON - if ((direction == PINDIR_OUTPUT) && (Tray_Icon == 0)) + if ((direction == PINDIR_OUTPUT) && (Tray_Icon == 0) && (g_config.bTrayIcon != 0)) { WNDCLASSEX wc; @@ -895,14 +956,14 @@ wc.hInstance = (HINSTANCE) g_xvid_hInst; wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = "XVID_MSG_WINDOW"; + wc.lpszClassName = TEXT("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); + MSG_hwnd = CreateWindowEx(0, TEXT("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; @@ -913,7 +974,7 @@ nid.uID = 1456; nid.uCallbackMessage = WM_ICONMESSAGE; nid.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON)); - strcpy_s(nid.szTip, 19, "Xvid Video Decoder"); + lstrcpy(nid.szTip, TEXT("Xvid Video Decoder")); nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; Shell_NotifyIcon(NIM_ADD, &nid); @@ -921,7 +982,6 @@ DestroyIcon(nid.hIcon); Tray_Icon = 1; } -#endif return S_OK; } @@ -997,7 +1057,7 @@ { HRESULT result; - result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat); + result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat, 0); DeleteMediaType(mtOut); if (result != S_OK) @@ -1318,17 +1378,33 @@ bs_guid_table[i++] = (GUID *)&CLSID_XVID; bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC; - if (g_config.supported_4cc & SUPPORT_DX50) { - bs_guid_table[i++] = (GUID *)&CLSID_DX50; - bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC; + if (g_config.supported_4cc & SUPPORT_3IVX) { + bs_guid_table[i++] = (GUID *)&CLSID_3IVX; + bs_guid_table[i++] = (GUID *)&CLSID_3IVX_UC; + bs_guid_table[i++] = (GUID *)&CLSID_3IV0; + bs_guid_table[i++] = (GUID *)&CLSID_3IV0_UC; + bs_guid_table[i++] = (GUID *)&CLSID_3IV1; + bs_guid_table[i++] = (GUID *)&CLSID_3IV1_UC; + bs_guid_table[i++] = (GUID *)&CLSID_3IV2; + bs_guid_table[i++] = (GUID *)&CLSID_3IV2_UC; } if (g_config.supported_4cc & SUPPORT_DIVX) { bs_guid_table[i++] = (GUID *)&CLSID_DIVX; bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC; + bs_guid_table[i++] = (GUID *)&CLSID_DX50; + bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC; } if (g_config.supported_4cc & SUPPORT_MP4V) { bs_guid_table[i++] = (GUID *)&CLSID_MP4V; bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC; + bs_guid_table[i++] = (GUID *)&CLSID_LMP4; + bs_guid_table[i++] = (GUID *)&CLSID_LMP4_UC; + bs_guid_table[i++] = (GUID *)&CLSID_RMP4; + bs_guid_table[i++] = (GUID *)&CLSID_RMP4_UC; + bs_guid_table[i++] = (GUID *)&CLSID_SMP4; + bs_guid_table[i++] = (GUID *)&CLSID_SMP4_UC; + bs_guid_table[i++] = (GUID *)&CLSID_HDX4; + bs_guid_table[i++] = (GUID *)&CLSID_HDX4_UC; } const GUID *subtype; @@ -1562,7 +1638,7 @@ hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am); if (SUCCEEDED(hr)) { - if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat))) { + if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat, 1))) { DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)"); return MF_E_INVALIDTYPE; } @@ -1578,9 +1654,8 @@ hr = OnSetOutputType(pType); } } - -#ifdef XVID_USE_TRAYICON - if (SUCCEEDED(hr) && Tray_Icon == 0) /* Create message passing window */ + + if (SUCCEEDED(hr) && (Tray_Icon == 0) && (g_config.bTrayIcon != 0)) /* Create message passing window */ { WNDCLASSEX wc; @@ -1592,13 +1667,13 @@ wc.hInstance = (HINSTANCE) g_xvid_hInst; wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = "XVID_MSG_WINDOW"; + wc.lpszClassName = TEXT("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, + MSG_hwnd = CreateWindowEx(0, TEXT("XVID_MSG_WINDOW"), NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, (HINSTANCE) g_xvid_hInst, NULL); /* display the tray icon */ @@ -1609,16 +1684,15 @@ 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.hIcon = LoadIcon(g_xvid_hInst, MAKEINTRESOURCE(IDI_ICON)); + lstrcpy(nid.szTip, TEXT("Xvid Video Decoder")); nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - + Shell_NotifyIcon(NIM_ADD, &nid); DestroyIcon(nid.hIcon); Tray_Icon = 1; } -#endif LeaveCriticalSection(&m_mft_lock); return hr; @@ -1839,7 +1913,7 @@ EnterCriticalSection(&m_mft_lock); HRESULT hr = S_OK; - IMFMediaBuffer *pBuffer; + IMFMediaBuffer *pBuffer = NULL; if (SUCCEEDED(hr)) { hr = pSample->ConvertToContiguousBuffer(&pBuffer); @@ -1949,6 +2023,9 @@ if (FAILED(pSample->GetSampleDuration(&m_timelength))) { m_timelength = INVALID_TIME; } + if (m_timestamp != INVALID_TIME && stats.type == XVID_TYPE_IVOP) { + m_rtFrame = m_timestamp; + } } LeaveCriticalSection(&m_mft_lock); @@ -2090,9 +2167,9 @@ } if (m_hdll == NULL) { - HRESULT hr = OpenLib(); + HRESULT hr2 = OpenLib(); - if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks. + if (FAILED(hr2) || (m_hdll == NULL)) // Paranoid checks. hr = MF_E_INVALIDTYPE; } @@ -2126,7 +2203,11 @@ hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype); } - if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC) { + if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC || + subtype == CLSID_LMP4 || subtype == CLSID_LMP4_UC || + subtype == CLSID_RMP4 || subtype == CLSID_RMP4_UC || + subtype == CLSID_SMP4 || subtype == CLSID_SMP4_UC || + subtype == CLSID_HDX4 || subtype == CLSID_HDX4_UC) { if (!(g_config.supported_4cc & SUPPORT_MP4V)) { CloseLib(); hr = MF_E_INVALIDTYPE; @@ -2141,12 +2222,22 @@ else m_create.fourcc = FOURCC_DIVX; } else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) { - if (!(g_config.supported_4cc & SUPPORT_DX50)) { + if (!(g_config.supported_4cc & SUPPORT_DIVX)) { CloseLib(); hr = MF_E_INVALIDTYPE; } else m_create.fourcc = FOURCC_DX50; } + else if (subtype == CLSID_3IVX || subtype == CLSID_3IVX_UC || + subtype == CLSID_3IV0 || subtype == CLSID_3IV0_UC || + subtype == CLSID_3IV1 || subtype == CLSID_3IV1_UC || + subtype == CLSID_3IV2 || subtype == CLSID_3IV2_UC) { + if (!(g_config.supported_4cc & SUPPORT_3IVX)) { + CloseLib(); + hr = MF_E_INVALIDTYPE; + } + else m_create.fourcc = FOURCC_3IVX; + } else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) { m_create.fourcc = FOURCC_XVID; }