📄 cxviddecoder.cpp
字号:
/***************************************************************************** * * XVID MPEG-4 VIDEO CODEC * - XviD Decoder part of the DShow Filter - * * Copyright(C) 2002-2004 Peter Ross <pross@xvid.org> * * 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 * the Free Software Foundation ; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY ; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * 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.16 2005/10/08 00:58:02 suxen_drol 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 * ****************************************************************************/ /* this requires the directx sdk place these paths at the top of the Tools|Options|Directories list headers: C:\DX90SDK\Include C:\DX90SDK\Samples\C++\DirectShow\BaseClasses C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Release C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug*/#include <windows.h>#include <streams.h>#include <initguid.h>#include <olectl.h>#if (1100 > _MSC_VER)#include <olectlid.h>#endif#include <dvdmedia.h> // VIDEOINFOHEADER2#include <xvid.h> // XviD API#include "IXvidDecoder.h"#include "CXvidDecoder.h"#include "CAbout.h"#include "config.h"#include "debug.h"static bool USE_IYUV;static bool USE_YV12;static bool USE_YUY2;static bool USE_YVYU;static bool USE_UYVY;static bool USE_RGB32;static bool USE_RGB24;static bool USE_RG555;static bool USE_RG565;const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] ={ { &MEDIATYPE_Video, &CLSID_XVID }, { &MEDIATYPE_Video, &CLSID_XVID_UC }, { &MEDIATYPE_Video, &CLSID_DIVX }, { &MEDIATYPE_Video, &CLSID_DIVX_UC }, { &MEDIATYPE_Video, &CLSID_DX50 }, { &MEDIATYPE_Video, &CLSID_DX50_UC }, { &MEDIATYPE_Video, &CLSID_MP4V }, { &MEDIATYPE_Video, &CLSID_MP4V_UC },};const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] ={ { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }};const AMOVIESETUP_PIN psudPins[] ={ { L"Input", // String pin name FALSE, // Is it rendered FALSE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L"Output", // Connects to pin sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types &sudInputPinTypes[0] // The pin details }, { L"Output", // String pin name FALSE, // Is it rendered TRUE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L"Input", // Connects to pin sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types sudOutputPinTypes // The pin details }};const AMOVIESETUP_FILTER sudXvidDecoder ={ &CLSID_XVID, // Filter CLSID XVID_NAME_L, // Filter name MERIT_PREFERRED, // Its merit sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins psudPins // Pin details};// List of class IDs and creator functions for the class factory. This// provides the link between the OLE entry point in the DLL and an object// being created. The class factory will call the static CreateInstanceCFactoryTemplate g_Templates[] ={ { XVID_NAME_L, &CLSID_XVID, CXvidDecoder::CreateInstance, NULL, &sudXvidDecoder }, { XVID_NAME_L L"About", &CLSID_CABOUT, CAbout::CreateInstance }};/* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate);STDAPI DllRegisterServer(){ return AMovieDllRegisterServer2( TRUE );}STDAPI DllUnregisterServer(){ return AMovieDllRegisterServer2( FALSE );}/* create instance */CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr){ CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr); if (pNewObject == NULL) { *phr = E_OUTOFMEMORY; } return pNewObject;}/* query interfaces */STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv){ CheckPointer(ppv, E_POINTER); if (riid == IID_IXvidDecoder) { return GetInterface((IXvidDecoder *) this, ppv); } if (riid == IID_ISpecifyPropertyPages) { return GetInterface((ISpecifyPropertyPages *) this, ppv); } return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv);}/* constructor */#define XVID_DLL_NAME "xvidcore.dll"CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL){ DPRINTF("Constructor"); xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize... xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here. LoadRegistryInfo(); *phr = OpenLib();}HRESULT CXvidDecoder::OpenLib(){ DPRINTF("OpenLib"); if (m_hdll != NULL) return E_UNEXPECTED; // Seems, that library already opened. xvid_gbl_init_t init; memset(&init, 0, sizeof(init)); init.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); return E_FAIL; } xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global"); if (xvid_global_func == NULL) { FreeLibrary(m_hdll); m_hdll = NULL; MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST); return E_FAIL; } xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore"); if (xvid_decore_func == NULL) { xvid_global_func = NULL; FreeLibrary(m_hdll); m_hdll = NULL; MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST); return E_FAIL; } if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0) { xvid_global_func = NULL; xvid_decore_func = NULL; FreeLibrary(m_hdll); m_hdll = NULL; MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); return E_FAIL; } memset(&m_create, 0, sizeof(m_create)); m_create.version = XVID_VERSION; m_create.handle = NULL; memset(&m_frame, 0, sizeof(m_frame)); m_frame.version = XVID_VERSION; USE_IYUV = false; USE_YV12 = false; USE_YUY2 = false; USE_YVYU = false; USE_UYVY = false; USE_RGB32 = false; USE_RGB24 = false; USE_RG555 = false; USE_RG565 = false; switch ( g_config.nForceColorspace ) { case FORCE_NONE: USE_IYUV = true; USE_YV12 = true; USE_YUY2 = true; USE_YVYU = true; USE_UYVY = true; USE_RGB32 = true; USE_RGB24 = true; USE_RG555 = true; USE_RG565 = true; break; case FORCE_YV12: USE_IYUV = true; USE_YV12 = true; break; case FORCE_YUY2: USE_YUY2 = true; break; case FORCE_RGB24: USE_RGB24 = true; break; case FORCE_RGB32: USE_RGB32 = true; break; } switch (g_config.aspect_ratio) { case 0: case 1: break; case 2: ar_x = 4; ar_y = 3; break; case 3: ar_x = 16; ar_y = 9; break; case 4: ar_x = 47; ar_y = 20; break; } return S_OK;}void CXvidDecoder::CloseLib(){ DPRINTF("CloseLib"); if ((m_create.handle != NULL) && (xvid_decore_func != NULL)) { xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0); m_create.handle = NULL; } if (m_hdll != NULL) { FreeLibrary(m_hdll); m_hdll = NULL; } xvid_decore_func = NULL; xvid_global_func = NULL;}/* destructor */CXvidDecoder::~CXvidDecoder(){ DPRINTF("Destructor"); CloseLib();}/* check input type */HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn){ DPRINTF("CheckInputType"); BITMAPINFOHEADER * hdr; ar_x = ar_y = 0; if (*mtIn->Type() != MEDIATYPE_Video) { DPRINTF("Error: Unknown Type"); CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } if (m_hdll == NULL) { HRESULT hr = OpenLib(); if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks. return VFW_E_TYPE_NOT_ACCEPTED; } if (*mtIn->FormatType() == FORMAT_VideoInfo) { VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); hdr = &vih->bmiHeader; } else if (*mtIn->FormatType() == FORMAT_VideoInfo2) { VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format(); hdr = &vih2->bmiHeader; if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { ar_x = vih2->dwPictAspectRatioX; ar_y = vih2->dwPictAspectRatioY; } DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); } else if (*mtIn->FormatType() == FORMAT_MPEG2Video) { MPEG2VIDEOINFO * mpgvi = (MPEG2VIDEOINFO*)mtIn->Format(); VIDEOINFOHEADER2 * vih2 = &mpgvi->hdr; hdr = &vih2->bmiHeader; if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { ar_x = vih2->dwPictAspectRatioX; ar_y = vih2->dwPictAspectRatioY; } DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); /* haali media splitter reports VOL information in the format header */ if (mpgvi->cbSequenceHeader>0) { xvid_dec_stats_t stats; memset(&stats, 0, sizeof(stats)); stats.version = XVID_VERSION; if (m_create.handle == NULL) { if (xvid_decore_func == NULL) return E_FAIL; if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) { DPRINTF("*** XVID_DEC_CREATE error"); return S_FALSE; } } m_frame.general = 0; m_frame.bitstream = (void*)mpgvi->dwSequenceHeader; m_frame.length = mpgvi->cbSequenceHeader; m_frame.output.csp = XVID_CSP_NULL; if (xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats) >= 0) { /* honour video dimensions reported in VOL header */ if (stats.type == XVID_TYPE_VOL) { hdr->biWidth = stats.data.vol.width; hdr->biHeight = stats.data.vol.height; } } } } else { DPRINTF("Error: Unknown FormatType"); CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } if (hdr->biHeight < 0) { DPRINTF("colorspace: inverted input format not supported"); } m_create.width = hdr->biWidth; m_create.height = hdr->biHeight; switch(hdr->biCompression) { case FOURCC_mp4v: case FOURCC_MP4V: if (!(g_config.supported_4cc & SUPPORT_MP4V)) { CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } break; case FOURCC_DIVX : 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)) { CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } case FOURCC_XVID : break; default : DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)", hdr->biCompression, (hdr->biCompression)&0xff, (hdr->biCompression>>8)&0xff, (hdr->biCompression>>16)&0xff, (hdr->biCompression>>24)&0xff); CloseLib(); return VFW_E_TYPE_NOT_ACCEPTED; } return S_OK;}/* get list of supported output colorspaces */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -