⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tvsourcefilter.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	//
	return NULL;
}
//
void CTVStreamSource::AddFilterToCache()
{
	m_iSAddFilterToCache = TRUE;
	IGraphConfig* pConfig = GetGCF();
	if(!pConfig)
		return;
	//vp7: {083863F1-70DE-11D0-BD40-00A0C911CE86}\{C204438D-6E1A-4309-B09C-0C0F749863AF}
	GUID rclsid_vp7 = {0xc204438d, 0x6e1a, 0x4309, {0xb0, 0x9c, 0x0c, 0x0f, 0x74, 0x98, 0x63, 0xaf}};
	IBaseFilter* pIBaseFilter = NULL;
	if (S_OK == CoCreateInstance(rclsid_vp7, 
								 NULL,
								 CLSCTX_INPROC_SERVER,
								 IID_IBaseFilter,
								 (void**)&pIBaseFilter))
	{
		pConfig->AddFilterToCache(pIBaseFilter);
		pIBaseFilter->Release();
		pIBaseFilter = NULL;
	}
	else
		assert(0);
	// WMVideo Decoder DMO: {82D353DF-90BD-4382-8BC2-3F6192B76E34}{4A69B442-28BE-4991-969C-B500ADF5D8A8}
	GUID rclsid_wmv = {0x82D353DF, 0x90BD, 0x4382, {0x8B, 0xC2, 0x3F, 0x61, 0x92, 0xB7, 0x6E, 0x34}};
	pIBaseFilter = CreateDMO( rclsid_wmv, DMOCATEGORY_VIDEO_DECODER);
	if (NULL != pIBaseFilter)
	{
		pConfig->AddFilterToCache(pIBaseFilter);
		pIBaseFilter->Release();
		pIBaseFilter = NULL;
	}
	else
		assert(0);
	
	// WMAudio Decoder DMO: {2EEB4ADF-4578-4D10-BCA7-BB955F56320A}{57F2DB8B-E6BB-4513-9D43-DCD2A6593125}
	GUID rclsid_wma = {0x2EEB4ADF, 0x4578, 0x4D10, {0xBC, 0xA7, 0xBB, 0x95, 0x5F, 0x56, 0x32, 0x0A}};
	pIBaseFilter = CreateDMO( rclsid_wma, DMOCATEGORY_AUDIO_DECODER);
	if (NULL != pIBaseFilter)
	{
		pConfig->AddFilterToCache(pIBaseFilter);
		pIBaseFilter->Release();
		pIBaseFilter = NULL;
	}
	else
		assert(0);
	/*
	//gsm{083863F1-70DE-11D0-BD40-00A0C911CE86}\{6A08CF80-0E18-11CF-A24D-0020AFD79767}
	GUID rclsid_gsm = {0x6A08CF80, 0x0E18, 0x11CF, {0xA2, 0x4D, 0x00, 0x20, 0xAF, 0xD7, 0x97, 0x67}};
	//
	pIBaseFilter = NULL;
	if (S_OK == CoCreateInstance(rclsid_gsm, 
								 NULL,
								 CLSCTX_INPROC_SERVER,
								 IID_IBaseFilter,
								 (void**)&pIBaseFilter))
	{
		pConfig->AddFilterToCache(pIBaseFilter);
		pIBaseFilter->Release();
		pIBaseFilter = NULL;
	}
	else
		assert(0);
	*/
	// 直接无法创建,只能从现有的filter中寻找(所以默认的音频必须是GSM,这样才能找到)
	// gsm
	pIBaseFilter = FindFilterFromFriendlyName(CLSID_AudioCompressorCategory, "GSM 6.10");
    if (NULL != pIBaseFilter) 
	{
		pConfig->AddFilterToCache(pIBaseFilter);
		pIBaseFilter->Release();
		pIBaseFilter = NULL;
	}
	else
		assert(0);
	//
	pConfig->Release();
}
//
IFilterGraph* CTVStreamSource::GetFG()
{
	return m_pGraph;
}
//
IGraphConfig* CTVStreamSource::GetGCF()
{
	IGraphConfig* pConfig = NULL;
	GetFG()->QueryInterface(IID_IGraphConfig, (void**)&pConfig);
	//
	return pConfig;
}
//
bool CTVStreamSource::UpdateAndStartLocalServer()
{
	// 1. get module path & system path
	TCHAR lpModulePath[MAX_PATH_EX] = _T("");
	DWORD dwLen = GetModuleFileName((HMODULE)g_hModule, lpModulePath, MAX_PATH_EX);
	if(dwLen == 0)
		return false;
	TCHAR* idx = _tcsrchr(lpModulePath, _T('\\'));
	if(idx == NULL)
		return false;
	*(idx+1) = _T('\0');

	TCHAR lpSystemPath[MAX_PATH_EX] = _T("");
	dwLen = ::GetSystemDirectory(lpSystemPath, MAX_PATH_EX);
	if(dwLen == 0)
		return false;
	_tcscat(lpSystemPath, "\\");
	
	// 2. check existance of "layer1.dll" "localsrv.exe" "vp7dec.ax"
	bool bForceUpdate = false;
	if(!DoesFileExist(lpModulePath, _T("layer1.dll")))
		bForceUpdate = true;
	if(!DoesFileExist(lpModulePath, _T("localsrv.exe")))
		bForceUpdate = true;
	if(!DoesFileExist(lpSystemPath, _T("vp7dec.ax")))
		bForceUpdate = true;

	// 3. 如果需要强制升级,则不能失败,而且要显示升级界面;
	//    如果不需要,则允许升级失败,且不用显示升级界面
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	ZeroMemory( &pi, sizeof(pi) );

	string filename = lpModulePath;
	filename.append(_T("xtvupdater.exe"));
	if( CreateProcess(  // No module name (use command line). 
		filename.data(), 
		bForceUpdate?NULL:_T(" /S "), // 如果不需要强制升级,则使用/S参数避免显示升级界面
		NULL,             // Process handle not inheritable. 
		NULL,             // Thread handle not inheritable. 
		FALSE,            // Set handle inheritance to FALSE. 
		0,                // No creation flags. 
		NULL,             // Use parent's environment block. 
		NULL,             // Use parent's starting directory. 
		&si,              // Pointer to STARTUPINFO structure.
		&pi )             // Pointer to PROCESS_INFORMATION structure.
		) 
	{
		// Wait until child process exits.
		WaitForSingleObject( pi.hProcess, INFINITE );

		// Close process and thread handles. 
		CloseHandle( pi.hProcess );
		CloseHandle( pi.hThread );
	}
	else if(bForceUpdate)	// 强制升级的话,这里可不能失败
		return false;

	// 4. 如果强制升级,那么升级成功了吗?
	if(bForceUpdate)
	{
		if(!DoesFileExist(lpModulePath, _T("layer1.dll")))
			return false;
		if(!DoesFileExist(lpModulePath, _T("localsrv.exe")))
			return false;
		if(!DoesFileExist(lpSystemPath, _T("vp7dec.ax")))
			return false;
	}

	// 5. 启动LocalServer,它会自动保证同时只存在一个实例的
	filename = lpModulePath;
	filename.append(_T("localsrv.exe"));
	// Start the child process. 
	if( !CreateProcess(  // No module name (use command line). 
		filename.data(), 
		NULL,             // Command line. 
		NULL,             // Process handle not inheritable. 
		NULL,             // Thread handle not inheritable. 
		FALSE,            // Set handle inheritance to FALSE. 
		0,                // No creation flags. 
		NULL,             // Use parent's environment block. 
		NULL,             // Use parent's starting directory. 
		&si,              // Pointer to STARTUPINFO structure.
		&pi )             // Pointer to PROCESS_INFORMATION structure.
		) 
	{
		// 启动失败可不行
        //MessageBox(NULL, "启动localsrv失败,也许直接执行它可以解决问题", "错误", MB_OK);
		return false;
	}
	// Close process and thread handles. 
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	return true;
}

bool CTVStreamSource::DoesFileExist(LPCTSTR path, LPCTSTR filename)
{
	if(!path || !filename)
		return false;

	// 查找文件是否存在
	WIN32_FIND_DATA fileData;

	string match = path;
	match.append(filename);
	HANDLE hFind = FindFirstFile(match.data(), &fileData);
	if(hFind == INVALID_HANDLE_VALUE)
		return false;
	return true;
}

CUnknown * WINAPI CTVStreamSource::CreateInstance(LPUNKNOWN pUnk, HRESULT * phr)
{
    CTVStreamSource* pNewFilter = new CTVStreamSource(pUnk, phr);
	//
    if (phr)
	{
		*phr = (NULL==pNewFilter) ? E_OUTOFMEMORY : S_OK;
	}
	//
    return pNewFilter;
}
//
HRESULT CTVStreamSource::_LoadFile(const char* filename)
{
	ASSERT(strlen(filename) > 0);
	//
	SAFE_DELETE(m_pFileReader);
	//
	m_pFileReader = new ZZLFileReader();
	bool ret = m_pFileReader->Init(filename);
	//
	if(!ret) 
	{
		MessageBox(NULL, _T("zzl文件格式错误,无法播放!"), _T("致命错误"), MB_OK|MB_ICONSTOP);
		return VFW_E_CANNOT_RENDER;
	}
	//
	m_pVideoPin->SetMediaTime();
	m_pAudioPin->SetMediaTime();
	//
	return S_OK;

}
//
HRESULT CTVStreamSource::_LoadURL(char* strURL)
{
	//
	m_pComm = new NetworkProxy();
	//
	bool ret = false;
	if (NULL != m_pComm)
	{
		ret = m_pComm->Request(strURL);
	}
	//
	if(!ret) 
	{
		return VFW_E_CANNOT_RENDER;
	}
	//
	m_pVideoPin->SetMediaTime();
	m_pAudioPin->SetMediaTime(); 
	// 
	return S_OK;
}
//
STDMETHODIMP CTVStreamSource::Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt) 
{
	if(!m_bUpdateComplete)
	{
		if(!UpdateAndStartLocalServer())
		{
			// 1. get module path & system path
			TCHAR lpModulePath[MAX_PATH_EX] = _T("");
			DWORD dwLen = GetModuleFileName((HMODULE)g_hModule, lpModulePath, MAX_PATH_EX);
			if(dwLen == 0)
				return false;
			TCHAR* idx = _tcsrchr(lpModulePath, _T('\\'));
			if(idx == NULL)
				return false;
			*(idx+1) = _T('\0');

			TCHAR lpSystemPath[MAX_PATH_EX] = _T("");
			dwLen = ::GetSystemDirectory(lpSystemPath, MAX_PATH_EX);
			if(dwLen == 0)
				return false;
			_tcscat(lpSystemPath, "\\");

			if(!DoesFileExist(lpModulePath, _T("layer1.dll")) || !DoesFileExist(lpSystemPath, _T("vp7dec.ax"))) {
				MessageBox(NULL, _T("自动下载失败!请到www.mysee.com下载并进行安装!"), _T("错误"), MB_OK|MB_ICONSTOP);
				return VFW_E_CANNOT_RENDER;
			}
		}
		m_bUpdateComplete = TRUE;
	}

	TCHAR szFinal[MAX_PATH_EX] = _T(""); 
	//
	if(lpwszFileName) 
	{
		// 将WCHAR转换成TCHAR
		SAFE_ARRAYDELETE(m_pFileName);
		m_pFileName = new WCHAR[MAX_PATH_EX];
		//
		wcscpy(m_pFileName, lpwszFileName);
	}

	if(0 == WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, m_pFileName, -1, szFinal, sizeof(szFinal), NULL, NULL)) 
	{
		MessageBox(NULL, _T("错误的URL,无法播放!"), _T("致命错误"), MB_OK|MB_ICONSTOP);
		return VFW_E_CANNOT_RENDER;
	}

	// gaov protocol
	if(strnicmp(szFinal, "gaov://", 7) == 0)
    {
        return _LoadURL(szFinal);
    }

	//
	char* index = strrchr(szFinal, '.');
	if(index != NULL)
	{
		index++;
		if(strnicmp(index, "gtv", 3) == 0) 
		{
			//ASSERT(FALSE);
			// gtv file
		}else if(strnicmp(index, "zzl", 3) == 0)
		{
			return _LoadFile(szFinal);
		}
		else 
		{
			index = NULL;
		}
	}
	//
	if(index == NULL) 
	{
		MessageBox(NULL, _T("无法识别的URL,后缀名必是gtv或者zzl!"), _T("致命错误"), MB_OK|MB_ICONSTOP);
		return VFW_E_CANNOT_RENDER;
	}
	//
	return _LoadURL(szFinal);
}

STDMETHODIMP CTVStreamSource::GetCurFile(LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt)
{
	CheckPointer(ppszFileName, E_POINTER);
	*ppszFileName = NULL;
	
	if(m_pFileName != NULL) 
	{
		*ppszFileName = (LPOLESTR) CoTaskMemAlloc(MAX_PATH_EX);
		if (*ppszFileName != NULL)
		{
			CopyMemory(*ppszFileName, m_pFileName, MAX_PATH_EX);
		}
	}
	
	if(pmt != NULL) 
	{
		// TODO
		NOTE("GetCurFile TODO");
	}
	return S_OK;
}

STDMETHODIMP CTVStreamSource::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 
{
	CheckPointer(ppv,E_POINTER);

	if (riid == IID_IFileSourceFilter) 
	{
		return GetInterface((IFileSourceFilter *) this, ppv);
	}
	else if(riid == IID_ISettings)
	{
		return GetInterface((ISettings *) this, ppv);
	}
	else
	{
		return CSource::NonDelegatingQueryInterface(riid, ppv);
	}
}
//
STDMETHODIMP_(void) CTVStreamSource::SetPopMsgHWND(HWND pop) 
{
}
//
STDMETHODIMP CTVStreamSource::Stop()   
{
	CAutoLock cObjectLock(m_pLock);
	
	if(m_bDoRealStop) {

		if(NULL != m_pComm)
			m_pComm->Stop();
	}
	//
	HRESULT hr = CSource::Stop();
	//
	return hr;
}
//
/*
STDMETHODIMP CTVStreamSource::Run(REFERENCE_TIME tStart) 
{
	CAutoLock cObjectLock(m_pLock);
	//
	return CSource::Run(tStart);
}

STDMETHODIMP CTVStreamSource::Pause() 
{
	CAutoLock cObjectLock(m_pLock); 
	//SetBaseRef(_I64_MAX);
	//
	return CSource::Pause();
}*/


//
LONGLONG CTVStreamSource::GetBaseRef()
{
	CAutoLock l(&m_critllBase);
	return m_llBaseRef;
}
//
void CTVStreamSource::SetBaseRef( LONGLONG llBaseRef)
{
	CAutoLock l(&m_critllBase);
	m_llBaseRef = llBaseRef;
	
}


LONGLONG CTVStreamSource::GetRawAudioRef()
{
	CAutoLock l(&m_critllBase);
	return m_rawAudiotime;
}

void CTVStreamSource::SetRawAudioRef(LONGLONG llRawRef)
{
	CAutoLock l(&m_critllBase);
	m_rawAudiotime = llRawRef;
}


//
IBaseFilter* CTVStreamSource::FindFilterFromFriendlyName(REFCLSID clsid, string str)
{
	// Create the System Device Enumerator.
	HRESULT hr;
	IBaseFilter *pFilter = NULL;
	ICreateDevEnum* pSysDevEnum = NULL;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
						IID_ICreateDevEnum, (void **)&pSysDevEnum);

	// Obtain a class enumerator for the video compressor category.
	IEnumMoniker* pEnumCat = NULL;
	hr = pSysDevEnum->CreateClassEnumerator(clsid, &pEnumCat, 0);

	if (hr == S_OK) 
	{
		// Enumerate the monikers.
		IMoniker* pMoniker = NULL;
		ULONG cFetched;
		while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
		{
			IPropertyBag* pPropBag = NULL;
			hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
			if(hr != S_OK)
				break;

			// To retrieve the friendly name of the filter, do the following:
			VARIANT varName;
			VariantInit(&varName);
			hr = pPropBag->Read(L"FriendlyName", &varName, 0);
			if(pPropBag)
				pPropBag->Release();
			if (SUCCEEDED(hr))
			{
				// Display the name in your UI somehow.
				USES_CONVERSION;

				//string str = W2CA(varName.bstrVal);
				//const char* pStr = str.data();
				if (stricmp(W2CA(varName.bstrVal), str.data()) == 0)
				{
					//ASSERT(FALSE);
					VariantClear(&varName);
					// To create an instance of the filter, do the following:
					pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
					pFilter->AddRef();

					pMoniker->Release();
					pMoniker = NULL;
					break;
				}
			}
			//
			VariantClear(&varName);
			if(pMoniker) {
				pMoniker->Release();
				pMoniker = NULL;
			}
		}//end while

	}
	if(pSysDevEnum)
		pSysDevEnum->Release();
	if(pEnumCat)
		pEnumCat->Release();

	if(!pFilter)
		ASSERT(FALSE);

	return pFilter;
}
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -