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-2011 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 |
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: CXvidDecoder.cpp,v 1.29 2011-03-17 15:11:32 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 |
|
24 |
* |
* |
25 |
****************************************************************************/ |
****************************************************************************/ |
26 |
|
|
36 |
C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug |
C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug |
37 |
*/ |
*/ |
38 |
|
|
39 |
|
/* |
40 |
#define XVID_USE_MFT |
#define XVID_USE_MFT |
41 |
#define XVID_USE_TRAYICON |
#define XVID_USE_TRAYICON |
42 |
|
*/ |
43 |
|
|
44 |
#include <windows.h> |
#include <windows.h> |
45 |
|
|
89 |
{ &MEDIATYPE_Video, &CLSID_DIVX_UC }, |
{ &MEDIATYPE_Video, &CLSID_DIVX_UC }, |
90 |
{ &MEDIATYPE_Video, &CLSID_DX50 }, |
{ &MEDIATYPE_Video, &CLSID_DX50 }, |
91 |
{ &MEDIATYPE_Video, &CLSID_DX50_UC }, |
{ &MEDIATYPE_Video, &CLSID_DX50_UC }, |
92 |
|
{ &MEDIATYPE_Video, &CLSID_3IVX }, |
93 |
|
{ &MEDIATYPE_Video, &CLSID_3IVX_UC }, |
94 |
|
{ &MEDIATYPE_Video, &CLSID_3IV0 }, |
95 |
|
{ &MEDIATYPE_Video, &CLSID_3IV0_UC }, |
96 |
|
{ &MEDIATYPE_Video, &CLSID_3IV1 }, |
97 |
|
{ &MEDIATYPE_Video, &CLSID_3IV1_UC }, |
98 |
|
{ &MEDIATYPE_Video, &CLSID_3IV2 }, |
99 |
|
{ &MEDIATYPE_Video, &CLSID_3IV2_UC }, |
100 |
|
{ &MEDIATYPE_Video, &CLSID_LMP4 }, |
101 |
|
{ &MEDIATYPE_Video, &CLSID_LMP4_UC }, |
102 |
|
{ &MEDIATYPE_Video, &CLSID_RMP4 }, |
103 |
|
{ &MEDIATYPE_Video, &CLSID_RMP4_UC }, |
104 |
|
{ &MEDIATYPE_Video, &CLSID_SMP4 }, |
105 |
|
{ &MEDIATYPE_Video, &CLSID_SMP4_UC }, |
106 |
|
{ &MEDIATYPE_Video, &CLSID_HDX4 }, |
107 |
|
{ &MEDIATYPE_Video, &CLSID_HDX4_UC }, |
108 |
{ &MEDIATYPE_Video, &CLSID_MP4V }, |
{ &MEDIATYPE_Video, &CLSID_MP4V }, |
109 |
{ &MEDIATYPE_Video, &CLSID_MP4V_UC }, |
{ &MEDIATYPE_Video, &CLSID_MP4V_UC }, |
110 |
}; |
}; |
146 |
{ |
{ |
147 |
&CLSID_XVID, // Filter CLSID |
&CLSID_XVID, // Filter CLSID |
148 |
XVID_NAME_L, // Filter name |
XVID_NAME_L, // Filter name |
149 |
MERIT_PREFERRED, // Its merit |
MERIT_PREFERRED+2, // Its merit |
150 |
sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins |
sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins |
151 |
psudPins // Pin details |
psudPins // Pin details |
152 |
}; |
}; |
312 |
|
|
313 |
/* constructor */ |
/* constructor */ |
314 |
|
|
|
#define XVID_DLL_NAME "xvidcore.dll" |
|
|
|
|
315 |
CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : |
CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : |
316 |
CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL) |
CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL) |
317 |
{ |
{ |
346 |
xvid_gbl_init_t init; |
xvid_gbl_init_t init; |
347 |
memset(&init, 0, sizeof(init)); |
memset(&init, 0, sizeof(init)); |
348 |
init.version = XVID_VERSION; |
init.version = XVID_VERSION; |
349 |
|
init.cpu_flags = g_config.cpu; |
350 |
|
|
351 |
|
xvid_gbl_info_t info; |
352 |
|
memset(&info, 0, sizeof(info)); |
353 |
|
info.version = XVID_VERSION; |
354 |
|
|
355 |
m_hdll = LoadLibrary(XVID_DLL_NAME); |
m_hdll = LoadLibrary(XVID_DLL_NAME); |
356 |
if (m_hdll == NULL) { |
if (m_hdll == NULL) { |
386 |
return E_FAIL; |
return E_FAIL; |
387 |
} |
} |
388 |
|
|
389 |
|
if (xvid_global_func(0, XVID_GBL_INFO, &info, NULL) < 0) |
390 |
|
{ |
391 |
|
xvid_global_func = NULL; |
392 |
|
xvid_decore_func = NULL; |
393 |
|
FreeLibrary(m_hdll); |
394 |
|
m_hdll = NULL; |
395 |
|
MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); |
396 |
|
return E_FAIL; |
397 |
|
} |
398 |
|
|
399 |
memset(&m_create, 0, sizeof(m_create)); |
memset(&m_create, 0, sizeof(m_create)); |
400 |
m_create.version = XVID_VERSION; |
m_create.version = XVID_VERSION; |
401 |
m_create.handle = NULL; |
m_create.handle = NULL; |
402 |
|
/* Decoder threads */ |
403 |
|
if (g_config.cpu & XVID_CPU_FORCE) { |
404 |
|
m_create.num_threads = g_config.num_threads; |
405 |
|
} |
406 |
|
else { |
407 |
|
m_create.num_threads = info.num_threads; /* Autodetect */ |
408 |
|
g_config.num_threads = info.num_threads; |
409 |
|
} |
410 |
|
|
411 |
memset(&m_frame, 0, sizeof(m_frame)); |
memset(&m_frame, 0, sizeof(m_frame)); |
412 |
m_frame.version = XVID_VERSION; |
m_frame.version = XVID_VERSION; |
619 |
{ |
{ |
620 |
case FOURCC_mp4v: |
case FOURCC_mp4v: |
621 |
case FOURCC_MP4V: |
case FOURCC_MP4V: |
622 |
|
case FOURCC_lmp4 : |
623 |
|
case FOURCC_LMP4 : |
624 |
|
case FOURCC_rmp4 : |
625 |
|
case FOURCC_RMP4 : |
626 |
|
case FOURCC_smp4 : |
627 |
|
case FOURCC_SMP4 : |
628 |
|
case FOURCC_hdx4 : |
629 |
|
case FOURCC_HDX4 : |
630 |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
631 |
CloseLib(); |
CloseLib(); |
632 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
633 |
} |
} |
634 |
break; |
break; |
635 |
|
case FOURCC_divx : |
636 |
case FOURCC_DIVX : |
case FOURCC_DIVX : |
637 |
|
case FOURCC_dx50 : |
638 |
|
case FOURCC_DX50 : |
639 |
if (!(g_config.supported_4cc & SUPPORT_DIVX)) { |
if (!(g_config.supported_4cc & SUPPORT_DIVX)) { |
640 |
CloseLib(); |
CloseLib(); |
641 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
642 |
} |
} |
643 |
break; |
break; |
644 |
case FOURCC_DX50 : |
case FOURCC_3ivx : |
645 |
if (!(g_config.supported_4cc & SUPPORT_DX50)) { |
case FOURCC_3IVX : |
646 |
|
case FOURCC_3iv0 : |
647 |
|
case FOURCC_3IV0 : |
648 |
|
case FOURCC_3iv1 : |
649 |
|
case FOURCC_3IV1 : |
650 |
|
case FOURCC_3iv2 : |
651 |
|
case FOURCC_3IV2 : |
652 |
|
if (!(g_config.supported_4cc & SUPPORT_3IVX)) { |
653 |
CloseLib(); |
CloseLib(); |
654 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
655 |
} |
} |
656 |
|
case FOURCC_xvid : |
657 |
case FOURCC_XVID : |
case FOURCC_XVID : |
658 |
break; |
break; |
659 |
|
|
814 |
/* (internal function) change colorspace */ |
/* (internal function) change colorspace */ |
815 |
#define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) |
#define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) |
816 |
|
|
817 |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format, int noflip) |
818 |
{ |
{ |
819 |
DWORD biWidth; |
DWORD biWidth; |
820 |
|
|
837 |
return S_FALSE; |
return S_FALSE; |
838 |
} |
} |
839 |
|
|
840 |
|
if (noflip) rgb_flip = 0; |
841 |
|
|
842 |
if (subtype == CLSID_MEDIASUBTYPE_IYUV) |
if (subtype == CLSID_MEDIASUBTYPE_IYUV) |
843 |
{ |
{ |
844 |
DPRINTF("IYUV"); |
DPRINTF("IYUV"); |
912 |
|
|
913 |
if (direction == PINDIR_OUTPUT) |
if (direction == PINDIR_OUTPUT) |
914 |
{ |
{ |
915 |
return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format()); |
return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format(), 0); |
916 |
} |
} |
917 |
|
|
918 |
return S_OK; |
return S_OK; |
1049 |
{ |
{ |
1050 |
HRESULT result; |
HRESULT result; |
1051 |
|
|
1052 |
result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat); |
result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat, 0); |
1053 |
DeleteMediaType(mtOut); |
DeleteMediaType(mtOut); |
1054 |
|
|
1055 |
if (result != S_OK) |
if (result != S_OK) |
1370 |
bs_guid_table[i++] = (GUID *)&CLSID_XVID; |
bs_guid_table[i++] = (GUID *)&CLSID_XVID; |
1371 |
bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC; |
bs_guid_table[i++] = (GUID *)&CLSID_XVID_UC; |
1372 |
|
|
1373 |
if (g_config.supported_4cc & SUPPORT_DX50) { |
if (g_config.supported_4cc & SUPPORT_3IVX) { |
1374 |
bs_guid_table[i++] = (GUID *)&CLSID_DX50; |
bs_guid_table[i++] = (GUID *)&CLSID_3IVX; |
1375 |
bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC; |
bs_guid_table[i++] = (GUID *)&CLSID_3IVX_UC; |
1376 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV0; |
1377 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV0_UC; |
1378 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV1; |
1379 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV1_UC; |
1380 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV2; |
1381 |
|
bs_guid_table[i++] = (GUID *)&CLSID_3IV2_UC; |
1382 |
} |
} |
1383 |
if (g_config.supported_4cc & SUPPORT_DIVX) { |
if (g_config.supported_4cc & SUPPORT_DIVX) { |
1384 |
bs_guid_table[i++] = (GUID *)&CLSID_DIVX; |
bs_guid_table[i++] = (GUID *)&CLSID_DIVX; |
1385 |
bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC; |
bs_guid_table[i++] = (GUID *)&CLSID_DIVX_UC; |
1386 |
|
bs_guid_table[i++] = (GUID *)&CLSID_DX50; |
1387 |
|
bs_guid_table[i++] = (GUID *)&CLSID_DX50_UC; |
1388 |
} |
} |
1389 |
if (g_config.supported_4cc & SUPPORT_MP4V) { |
if (g_config.supported_4cc & SUPPORT_MP4V) { |
1390 |
bs_guid_table[i++] = (GUID *)&CLSID_MP4V; |
bs_guid_table[i++] = (GUID *)&CLSID_MP4V; |
1391 |
bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC; |
bs_guid_table[i++] = (GUID *)&CLSID_MP4V_UC; |
1392 |
|
bs_guid_table[i++] = (GUID *)&CLSID_LMP4; |
1393 |
|
bs_guid_table[i++] = (GUID *)&CLSID_LMP4_UC; |
1394 |
|
bs_guid_table[i++] = (GUID *)&CLSID_RMP4; |
1395 |
|
bs_guid_table[i++] = (GUID *)&CLSID_RMP4_UC; |
1396 |
|
bs_guid_table[i++] = (GUID *)&CLSID_SMP4; |
1397 |
|
bs_guid_table[i++] = (GUID *)&CLSID_SMP4_UC; |
1398 |
|
bs_guid_table[i++] = (GUID *)&CLSID_HDX4; |
1399 |
|
bs_guid_table[i++] = (GUID *)&CLSID_HDX4_UC; |
1400 |
} |
} |
1401 |
|
|
1402 |
const GUID *subtype; |
const GUID *subtype; |
1630 |
hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am); |
hr = MFCreateAMMediaTypeFromMFMediaType(pType, GUID_NULL, &am); |
1631 |
|
|
1632 |
if (SUCCEEDED(hr)) { |
if (SUCCEEDED(hr)) { |
1633 |
if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat))) { |
if (FAILED(ChangeColorspace(am->subtype, am->formattype, am->pbFormat, 1))) { |
1634 |
DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)"); |
DPRINTF("(MFT)InternalCheckOutputType (MF_E_INVALIDTYPE)"); |
1635 |
return MF_E_INVALIDTYPE; |
return MF_E_INVALIDTYPE; |
1636 |
} |
} |
1646 |
hr = OnSetOutputType(pType); |
hr = OnSetOutputType(pType); |
1647 |
} |
} |
1648 |
} |
} |
|
|
|
1649 |
#ifdef XVID_USE_TRAYICON |
#ifdef XVID_USE_TRAYICON |
1650 |
if (SUCCEEDED(hr) && Tray_Icon == 0) /* Create message passing window */ |
if (SUCCEEDED(hr) && Tray_Icon == 0) /* Create message passing window */ |
1651 |
{ |
{ |
2016 |
if (FAILED(pSample->GetSampleDuration(&m_timelength))) { |
if (FAILED(pSample->GetSampleDuration(&m_timelength))) { |
2017 |
m_timelength = INVALID_TIME; |
m_timelength = INVALID_TIME; |
2018 |
} |
} |
2019 |
|
if (m_timestamp != INVALID_TIME && stats.type == XVID_TYPE_IVOP) { |
2020 |
|
m_rtFrame = m_timestamp; |
2021 |
|
} |
2022 |
} |
} |
2023 |
|
|
2024 |
LeaveCriticalSection(&m_mft_lock); |
LeaveCriticalSection(&m_mft_lock); |
2196 |
hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype); |
hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype); |
2197 |
} |
} |
2198 |
|
|
2199 |
if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC) { |
if (subtype == CLSID_MP4V || subtype == CLSID_MP4V_UC || |
2200 |
|
subtype == CLSID_LMP4 || subtype == CLSID_LMP4_UC || |
2201 |
|
subtype == CLSID_RMP4 || subtype == CLSID_RMP4_UC || |
2202 |
|
subtype == CLSID_SMP4 || subtype == CLSID_SMP4_UC || |
2203 |
|
subtype == CLSID_HDX4 || subtype == CLSID_HDX4_UC) { |
2204 |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
2205 |
CloseLib(); |
CloseLib(); |
2206 |
hr = MF_E_INVALIDTYPE; |
hr = MF_E_INVALIDTYPE; |
2215 |
else m_create.fourcc = FOURCC_DIVX; |
else m_create.fourcc = FOURCC_DIVX; |
2216 |
} |
} |
2217 |
else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) { |
else if (subtype == CLSID_DX50 || subtype == CLSID_DX50_UC) { |
2218 |
if (!(g_config.supported_4cc & SUPPORT_DX50)) { |
if (!(g_config.supported_4cc & SUPPORT_DIVX)) { |
2219 |
CloseLib(); |
CloseLib(); |
2220 |
hr = MF_E_INVALIDTYPE; |
hr = MF_E_INVALIDTYPE; |
2221 |
} |
} |
2222 |
else m_create.fourcc = FOURCC_DX50; |
else m_create.fourcc = FOURCC_DX50; |
2223 |
} |
} |
2224 |
|
else if (subtype == CLSID_3IVX || subtype == CLSID_3IVX_UC || |
2225 |
|
subtype == CLSID_3IV0 || subtype == CLSID_3IV0_UC || |
2226 |
|
subtype == CLSID_3IV1 || subtype == CLSID_3IV1_UC || |
2227 |
|
subtype == CLSID_3IV2 || subtype == CLSID_3IV2_UC) { |
2228 |
|
if (!(g_config.supported_4cc & SUPPORT_3IVX)) { |
2229 |
|
CloseLib(); |
2230 |
|
hr = MF_E_INVALIDTYPE; |
2231 |
|
} |
2232 |
|
else m_create.fourcc = FOURCC_3IVX; |
2233 |
|
} |
2234 |
else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) { |
else if (subtype == CLSID_XVID || subtype == CLSID_XVID_UC) { |
2235 |
m_create.fourcc = FOURCC_XVID; |
m_create.fourcc = FOURCC_XVID; |
2236 |
} |
} |