/* * (C) 2003-2006 Gabest * (C) 2006-2013 see Authors.txt * * This file is part of MPC-HC. * * MPC-HC 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 3 of the License, or * (at your option) any later version. * * MPC-HC 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, see . * */ #pragma once #include #include "NullRenderers.h" #include "HdmvClipInfo.h" #include "H264Nalu.h" #include "MediaTypeEx.h" #include "vd.h" #include "text.h" #define LCID_NOSUBTITLES -1 extern void DumpStreamConfig(TCHAR* fn, IAMStreamConfig* pAMVSCCap); extern int CountPins(IBaseFilter* pBF, int& nIn, int& nOut, int& nInC, int& nOutC); extern bool IsSplitter(IBaseFilter* pBF, bool fCountConnectedOnly = false); extern bool IsMultiplexer(IBaseFilter* pBF, bool fCountConnectedOnly = false); extern bool IsStreamStart(IBaseFilter* pBF); extern bool IsStreamEnd(IBaseFilter* pBF); extern bool IsVideoRenderer(IBaseFilter* pBF); extern bool IsAudioWaveRenderer(IBaseFilter* pBF); extern IBaseFilter* GetUpStreamFilter(IBaseFilter* pBF, IPin* pInputPin = NULL); extern IPin* GetUpStreamPin(IBaseFilter* pBF, IPin* pInputPin = NULL); extern IPin* GetFirstPin(IBaseFilter* pBF, PIN_DIRECTION dir = PINDIR_INPUT); extern IPin* GetFirstDisconnectedPin(IBaseFilter* pBF, PIN_DIRECTION dir); extern void NukeDownstream(IBaseFilter* pBF, IFilterGraph* pFG); extern void NukeDownstream(IPin* pPin, IFilterGraph* pFG); extern IBaseFilter* FindFilter(LPCWSTR clsid, IFilterGraph* pFG); extern IBaseFilter* FindFilter(const CLSID& clsid, IFilterGraph* pFG); extern IPin* FindPin(IBaseFilter* pBF, PIN_DIRECTION direction, const AM_MEDIA_TYPE* pRequestedMT); extern CStringW GetFilterName(IBaseFilter* pBF); extern CStringW GetPinName(IPin* pPin); extern IFilterGraph* GetGraphFromFilter(IBaseFilter* pBF); extern IBaseFilter* GetFilterFromPin(IPin* pPin); extern IPin* AppendFilter(IPin* pPin, CString DisplayName, IGraphBuilder* pGB); extern IPin* InsertFilter(IPin* pPin, CString DisplayName, IGraphBuilder* pGB); extern void ExtractMediaTypes(IPin* pPin, CAtlArray& types); extern void ExtractMediaTypes(IPin* pPin, CAtlList& mts); extern void ShowPPage(CString DisplayName, HWND hParentWnd); extern void ShowPPage(IUnknown* pUnknown, HWND hParentWnd); extern CLSID GetCLSID(IBaseFilter* pBF); extern CLSID GetCLSID(IPin* pPin); extern bool IsCLSIDRegistered(LPCTSTR clsid); extern bool IsCLSIDRegistered(const CLSID& clsid); extern void CStringToBin(CString str, CAtlArray& data); extern CString BinToCString(const BYTE* ptr, size_t len); typedef enum { CDROM_NotFound, CDROM_Audio, CDROM_VideoCD, CDROM_DVDVideo, CDROM_Unknown } cdrom_t; extern cdrom_t GetCDROMType(TCHAR drive, CAtlList& files); extern CString GetDriveLabel(TCHAR drive); extern bool GetKeyFrames(CString fn, CUIntArray& kfs); extern DVD_HMSF_TIMECODE RT2HMSF(REFERENCE_TIME rt, double fps = 0); // used to remember the current position extern DVD_HMSF_TIMECODE RT2HMS_r(REFERENCE_TIME rt); // used only for information (for display on the screen) extern REFERENCE_TIME HMSF2RT(DVD_HMSF_TIMECODE hmsf, double fps = 0); extern void memsetd(void* dst, unsigned int c, size_t nbytes); extern void memsetw(void* dst, unsigned short c, size_t nbytes); extern bool ExtractBIH(const AM_MEDIA_TYPE* pmt, BITMAPINFOHEADER* bih); extern bool ExtractBIH(IMediaSample* pMS, BITMAPINFOHEADER* bih); extern bool ExtractAvgTimePerFrame(const AM_MEDIA_TYPE* pmt, REFERENCE_TIME& rtAvgTimePerFrame); extern bool ExtractDim(const AM_MEDIA_TYPE* pmt, int& w, int& h, int& arx, int& ary); extern bool MakeMPEG2MediaType(CMediaType& mt, BYTE* seqhdr, DWORD len, int w, int h); extern bool CreateFilter(CStringW DisplayName, IBaseFilter** ppBF, CStringW& FriendlyName); extern IBaseFilter* AppendFilter(IPin* pPin, IMoniker* pMoniker, IGraphBuilder* pGB); extern CStringW GetFriendlyName(CStringW DisplayName); extern HRESULT LoadExternalObject(LPCTSTR path, REFCLSID clsid, REFIID iid, void** ppv); extern HRESULT LoadExternalFilter(LPCTSTR path, REFCLSID clsid, IBaseFilter** ppBF); extern HRESULT LoadExternalPropertyPage(IPersist* pP, REFCLSID clsid, IPropertyPage** ppPP); extern void UnloadExternalObjects(); extern CString MakeFullPath(LPCTSTR path); extern CString GetMediaTypeName(const GUID& guid); extern GUID GUIDFromCString(CString str); extern HRESULT GUIDFromCString(CString str, GUID& guid); extern CString CStringFromGUID(const GUID& guid); extern CStringW UTF8To16(LPCSTR utf8); extern CStringA UTF16To8(LPCWSTR utf16); extern CStringW UTF8ToStringW(const char* S); extern CStringW LocalToStringW(const char* S); extern CString ISO6391ToLanguage(LPCSTR code); extern CString ISO6392ToLanguage(LPCSTR code); extern LCID ISO6391ToLcid(LPCSTR code); extern LCID ISO6392ToLcid(LPCSTR code); extern CString ISO6391To6392(LPCSTR code); extern CString ISO6392To6391(LPCSTR code); extern CString LanguageToISO6392(LPCTSTR lang); extern int MakeAACInitData(BYTE* pData, int profile, int freq, int channels); extern BOOL CFileGetStatus(LPCTSTR lpszFileName, CFileStatus& status); extern bool DeleteRegKey(LPCTSTR pszKey, LPCTSTR pszSubkey); extern bool SetRegKeyValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValueName, LPCTSTR pszValue); extern bool SetRegKeyValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValue); extern void RegisterSourceFilter(const CLSID& clsid, const GUID& subtype2, LPCTSTR chkbytes, LPCTSTR ext = NULL, ...); extern void RegisterSourceFilter(const CLSID& clsid, const GUID& subtype2, const CAtlList& chkbytes, LPCTSTR ext = NULL, ...); extern void UnRegisterSourceFilter(const GUID& subtype); extern LPCTSTR GetDXVAMode(const GUID* guidDecoder); extern void DumpBuffer(BYTE* pBuffer, int nSize); extern CString ReftimeToString(const REFERENCE_TIME& rtVal); extern CString ReftimeToString2(const REFERENCE_TIME& rtVal); extern CString DVDtimeToString(const DVD_HMSF_TIMECODE& rtVal, bool bAlwaysShowHours = false); extern REFERENCE_TIME StringToReftime(LPCTSTR strVal); extern COLORREF YCrCbToRGB_Rec601(BYTE Y, BYTE Cr, BYTE Cb); extern COLORREF YCrCbToRGB_Rec709(BYTE Y, BYTE Cr, BYTE Cb); extern DWORD YCrCbToRGB_Rec601(BYTE A, BYTE Y, BYTE Cr, BYTE Cb); extern DWORD YCrCbToRGB_Rec709(BYTE A, BYTE Y, BYTE Cr, BYTE Cb); extern void TraceFilterInfo(IBaseFilter* pBF); extern void TracePinInfo(IPin* pPin); extern void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName); extern void HexDump(CString fName, BYTE* buf, int size); extern void CorrectComboListWidth(CComboBox& m_pComboBox); extern void getExtraData(const BYTE* format, const GUID* formattype, const size_t formatlen, BYTE* extra, unsigned int* extralen); extern void audioFormatTypeHandler(const BYTE* format, const GUID* formattype, DWORD* pnSamples, WORD* pnChannels, WORD* pnBitsPerSample, WORD* pnBlockAlign, DWORD* pnBytesPerSec); typedef enum { PICT_NONE, PICT_TOP_FIELD, PICT_BOTTOM_FIELD, PICT_FRAME } FF_FIELD_TYPE; class CPinInfo : public PIN_INFO { public: CPinInfo() { pFilter = NULL; } ~CPinInfo() { if (pFilter) { pFilter->Release(); } } }; class CFilterInfo : public FILTER_INFO { public: CFilterInfo() { pGraph = NULL; } ~CFilterInfo() { if (pGraph) { pGraph->Release(); } } }; #define BeginEnumFilters(pFilterGraph, pEnumFilters, pBaseFilter) \ { \ CComPtr pEnumFilters; \ if (pFilterGraph && SUCCEEDED(pFilterGraph->EnumFilters(&pEnumFilters))) \ { \ for (CComPtr pBaseFilter; S_OK == pEnumFilters->Next(1, &pBaseFilter, 0); pBaseFilter = NULL) \ { #define EndEnumFilters }}} #define BeginEnumCachedFilters(pGraphConfig, pEnumFilters, pBaseFilter) \ { \ CComPtr pEnumFilters; \ if (pGraphConfig && SUCCEEDED(pGraphConfig->EnumCacheFilter(&pEnumFilters))) \ { \ for (CComPtr pBaseFilter; S_OK == pEnumFilters->Next(1, &pBaseFilter, 0); pBaseFilter = NULL) \ { #define EndEnumCachedFilters }}} #define BeginEnumPins(pBaseFilter, pEnumPins, pPin) \ { \ CComPtr pEnumPins; \ if (pBaseFilter && SUCCEEDED(pBaseFilter->EnumPins(&pEnumPins))) \ { \ for (CComPtr pPin; S_OK == pEnumPins->Next(1, &pPin, 0); pPin = NULL) \ { #define EndEnumPins }}} #define BeginEnumMediaTypes(pPin, pEnumMediaTypes, pMediaType) \ { \ CComPtr pEnumMediaTypes; \ if (pPin && SUCCEEDED(pPin->EnumMediaTypes(&pEnumMediaTypes))) \ { \ AM_MEDIA_TYPE* pMediaType = NULL; \ for (; S_OK == pEnumMediaTypes->Next(1, &pMediaType, NULL); DeleteMediaType(pMediaType), pMediaType = NULL) \ { #define EndEnumMediaTypes(pMediaType) \ } \ if (pMediaType) \ DeleteMediaType(pMediaType); \ } \ } #define BeginEnumSysDev(clsid, pMoniker) \ { \ CComPtr pDevEnum4$##clsid; \ pDevEnum4$##clsid.CoCreateInstance(CLSID_SystemDeviceEnum); \ CComPtr pClassEnum4$##clsid; \ if (SUCCEEDED(pDevEnum4$##clsid->CreateClassEnumerator(clsid, &pClassEnum4$##clsid, 0)) \ && pClassEnum4$##clsid) \ { \ for (CComPtr pMoniker; pClassEnum4$##clsid->Next(1, &pMoniker, 0) == S_OK; pMoniker = NULL) \ { #define EndEnumSysDev }}} #define PauseGraph \ CComQIPtr _pMC(m_pGraph); \ OAFilterState _fs = -1; \ if (_pMC) \ _pMC->GetState(1000, &_fs); \ if (_fs == State_Running) \ _pMC->Pause(); \ \ HRESULT _hr = E_FAIL; \ CComQIPtr _pMS((IUnknown*)(INonDelegatingUnknown*)m_pGraph); \ REFERENCE_TIME _rtNow = 0; \ if (_pMS) \ _hr = _pMS->GetCurrentPosition(&_rtNow); #define ResumeGraph \ if (SUCCEEDED(_hr) && _pMS && _fs != State_Stopped) \ _hr = _pMS->SetPositions(&_rtNow, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); \ \ if (_fs == State_Running && _pMS) \ _pMC->Run(); #define CallQueue(call) \ if (!m_pOutputQueue) \ return NOERROR; \ m_pOutputQueue->##call; \ return NOERROR; #define QI(i) (riid == __uuidof(i)) ? GetInterface((i*)this, ppv) : #define QI2(i) (riid == IID_##i) ? GetInterface((i*)this, ppv) : #define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } } #define SAFE_DELETE_ARRAY(p) { if (p) { delete [] (p); (p) = NULL; } } #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } } #define ResStr(id) CString(MAKEINTRESOURCE(id)) template __inline void INITDDSTRUCT(T& dd) { ZeroMemory(&dd, sizeof(dd)); dd.dwSize = sizeof(dd); } template static CUnknown* WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT* phr) { *phr = S_OK; CUnknown* punk = DEBUG_NEW T(lpunk, phr); if (punk == NULL) { *phr = E_OUTOFMEMORY; } return punk; } inline int GCD(int a, int b) { if (a == 0 || b == 0) { return 1; } while (a != b) { if (a < b) { b -= a; } else if (a > b) { a -= b; } } return a; }