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

📄 graphcenter.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	hr = CoCreateInstance(CLSID_FilterGraph, 
		NULL, 
		CLSCTX_INPROC_SERVER, 
		IID_IGraphBuilder, 
		(void **)&m_pGB);
	if (FAILED(hr))
	{
		//TRACE0("ERROR - Could not create the Filter Graph Manager.");
		return hr;
	}

	hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
	if (FAILED(hr))
	{
		//TRACE0("ERROR - Could not Get IMediaControl");
		return hr;
	}

	hr = m_pGB->QueryInterface(IID_IMediaEvent, (void **)&m_pEvent);
	if (FAILED(hr))
	{
		//TRACE0("ERROR - Could not Get IMediaEvent");
		return hr;
	}
	
	#ifdef _DEBUG
	AddGraphToRot(m_pGB, &g_dwRegister);
	#endif //_DEBUG
/*
	// for DEBUG
#ifdef _DEBUG
	AddGraphToRot(m_pGB, &g_dwRegister);
#endif //_DEBUG
*/
	return S_OK;
}

STDMETHODIMP CGraphCenter::Uninitialize()
{
	// first unDEBUG
#ifdef _DEBUG
	RemoveGraphFromRot(g_dwRegister);
#endif //_DEBUG

	DisassembleGraph();

	CoUninitialize();
	return S_OK;	
}

//构建图
STDMETHODIMP CGraphCenter::BuildGraph(LPCTSTR astrFileName, LPCTSTR astrZZLDirectory, LPCTSTR astrZZLFile)
{
	HRESULT hr;
	
	if (NULL == astrZZLDirectory)
	{
		MessageBox(NULL, "输入的将要生成的ZZL文件路径","错误", MB_OK|MB_ICONSTOP);
		return E_FAIL;
	}

    char temp[512] = {0};
    if(astrFileName && strlen(astrFileName) > 4)
        strcpy(temp, astrFileName+strlen(astrFileName)-4); // 只留下后缀名
    strlwr(temp); // 忽略大小写
    if(strcmp(temp, ".wmv") != 0 && strcmp(temp, ".wma") != 0 && strcmp(temp, ".avi") != 0 && strcmp(temp, ".wav") != 0 && strcmp(temp, ".asf") != 0)
	{
		MessageBox(NULL, "文件错误或者不是avi,wav,wmv,wma,asf文件,", "错误", MB_OK|MB_ICONSTOP);
		return E_FAIL;
	}

	//添加TV Sink Filter
	hr = AddFilter(CLSID_TVStreamSink, &m_pTVStreamSink);
	if (FAILED(hr))
	{
        TraceLog1("未能加载CaptureServer的filter\r\n");
		return hr;
	}	
	
	ITVSourceConfig* lpTVSourceConfig = NULL;

	hr = m_pTVStreamSink->QueryInterface(IID_ITVSouceConfig, (void**)&lpTVSourceConfig);
	if (FAILED(hr))
	{
        TraceLog1("从Capture filter中得不到相应界面\r\n");
		return hr;
	}


	//在连接之前,一定要将ZZL目录和ZZL文件名设置好。
	lpTVSourceConfig->SetProgramStorePath(astrZZLDirectory);

	lpTVSourceConfig->SetChannelName(astrZZLFile);

	

	WCHAR lwszFileName[256];
	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_USEGLYPHCHARS,
		astrFileName, -1, 
		lwszFileName, sizeof(lwszFileName) / sizeof(WCHAR));
    wcslwr(lwszFileName); // 忽略大小写,后面的比较才能顺利进行

	 
	ULONG iii;
	//处理wmv文件
	if (NULL != wcsstr(lwszFileName, L".wmv") || NULL != wcsstr(lwszFileName, L".asf"))
	{		
		hr = AddFilter(CLSID_WMAsfReader , &mpAsfReader);
		if (FAILED(hr))
		{
            TraceLog1("加入wmv的filter失败\r\n");
			lpTVSourceConfig->Release();
			return hr;
		}
		
		IFileSourceFilter* lpFileSource = NULL;
		hr = mpAsfReader->QueryInterface(IID_IFileSourceFilter, (void**)&lpFileSource);
		lpFileSource->Load(lwszFileName,NULL);
		
		/*
		//连接
		hr = ConnectPins(mpAsfReader, "Raw Video 0", m_pTVStreamSink, "Video");
		if (FAILED(hr))
            TraceLog1("和wmv视频接口连接时发生错误:0x%X\r\n", hr);
		hr = ConnectPins(mpAsfReader, "Raw Audio 1", m_pTVStreamSink, "Audio");
		if (FAILED(hr))
            TraceLog1("和wmv音频接口连接时发生错误:0x%X\r\n", hr);
		*/

		//连接
			
		hr = ConnectPinsEX(mpAsfReader, AUDIO, m_pTVStreamSink, "Audio");
		if (FAILED(hr))
			TraceLog1("和wmv音频接口连接时发生错误:0x%X\r\n", hr);

		hr = ConnectPinsEX(mpAsfReader,VIDEO,m_pTVStreamSink,"Video");
		if (FAILED(hr))
		{
			TraceLog1("和wmv视频接口连接时发生错误:0x%X\r\n", hr);
		}	
		iii = lpFileSource->Release();
		lpTVSourceConfig->Release();
		return hr;			
	}

	//处理wma文件
	if (NULL != wcsstr(lwszFileName, L".wma"))
	{		
		hr = AddFilter(CLSID_WMAsfReader , &mpAsfReader);
		if (FAILED(hr))
		{
            TraceLog1("加入wma的filter失败\r\n");
			lpTVSourceConfig->Release();
			return hr;
		}

		IFileSourceFilter* lpFileSource = NULL;
		hr = mpAsfReader->QueryInterface(IID_IFileSourceFilter, (void**)&lpFileSource);
		lpFileSource->Load(lwszFileName,NULL);

		//必须在连接之前将之设为单音频,否则,惨惨惨
		lpTVSourceConfig->SetAudioOrVideoOnly(TRUE);
		//连接		
		hr = ConnectPins(mpAsfReader, "Raw Audio 0", m_pTVStreamSink, "Audio");
        if (FAILED(hr))
            TraceLog1("和wma视频接口连接时发生错误:0x%X\r\n", hr);

		lpFileSource->Release();	
		lpTVSourceConfig->Release();
		return hr;			
	}


	hr = m_pGB->AddSourceFilter(lwszFileName, NULL, &m_pSourceFile);
	if (FAILED(hr))
	{
        TraceLog1("加入source filter的filter失败\r\n");
		lpTVSourceConfig->Release();
		return hr;
	}

	//处理wav文件
	if (NULL != wcsstr(lwszFileName, L".wav"))
	{
		lpTVSourceConfig->SetAudioOrVideoOnly(TRUE);
		hr = ConnectAutoPins(m_pSourceFile, NULL, m_pTVStreamSink, "Audio");
        if (FAILED(hr))
            TraceLog1("和wav音频接口连接时发生错误:0x%X\r\n", hr);
		lpTVSourceConfig->Release();
		return hr;		
	}
	lpTVSourceConfig->Release();

	hr = AddFilter(CLSID_AviSplitter, &m_pAviSplitter);
	if (FAILED(hr))
	{
        TraceLog1("加入avi splitter的filter失败\r\n");
		return hr;
	}

	hr = ConnectPins(m_pSourceFile, NULL, m_pAviSplitter, NULL);
	if (FAILED(hr))
	{
        TraceLog1("source filter 和 avi splitter 音频接口连接时发生错误:0x%X\r\n", hr);
		return hr;
	}	
	
	hr = ConnectPins(m_pAviSplitter, "Stream 00", m_pTVStreamSink, "Video");
	if (FAILED(hr))
	{
        //此时可能是Stream 00 为音频频,而Stream01为视频
		hr = ConnectPins(m_pAviSplitter, "Stream 00", m_pTVStreamSink, "Audio");
		if (FAILED(hr))
		{
			TraceLog1("和 avi splitter 视频接口连接时发生错误:0x%X\r\n", hr);
			DisassembleGraph();
			return hr;
		}
		hr = ConnectPins(m_pAviSplitter, "Stream 01", m_pTVStreamSink, "Video");
		if (FAILED(hr))
		{
			TraceLog1("和 avi splitter 视频接口连接时发生错误:0x%X\r\n", hr);
			DisassembleGraph();
			return hr;
		}
		return hr;
		
	}


	hr = ConnectPins(m_pAviSplitter, "Stream 01", m_pTVStreamSink, "Audio");
	if (FAILED(hr))
	{
        TraceLog1("和 avi splitter 音频接口连接时发生错误:0x%X\r\n", hr);
		DisassembleGraph();
		return hr;
	}

	return hr;
}

STDMETHODIMP CGraphCenter::DisassembleGraph()
{
	HRESULT hr;
	hr = RemoveFilter(m_pSourceFile);
	hr = RemoveFilter(m_pAviSplitter);
	hr = RemoveFilter(m_pTVStreamSink);
	hr = RemoveFilter(mpAsfReader);

	ULONG iii;

	if (m_pTVStreamSink)
	{
		iii = m_pTVStreamSink->Release();
		m_pTVStreamSink = NULL;
	}
	if (mpAsfReader)
	{
		iii = mpAsfReader->Release();
		mpAsfReader = NULL;
	}

	if (m_pSourceFile)
	{
		iii = m_pSourceFile->Release();
		m_pSourceFile = NULL;
	}

	if (m_pAviSplitter)
	{
		iii = m_pAviSplitter->Release();
		m_pAviSplitter = NULL;
	}



	/*
	SAFE_RELEASE(m_pSourceFile)
	SAFE_RELEASE(m_pAviSplitter)
	SAFE_RELEASE(m_pAviSplitter)
	SAFE_RELEASE(mpAsfReader)
	*/
	return hr;
}

STDMETHODIMP CGraphCenter::Run()
{
	HRESULT hr;
	HANDLE lhhandle = NULL;	

		
	hr = m_pMC->Run();
	if (FAILED(hr))
	{
		return hr;
	}
	
	DWORD ldwThreadID;
	lhhandle = CreateThread(0,0,(LPTHREAD_START_ROUTINE)WaitForEnd,this,0,&ldwThreadID);
	if (NULL != lhhandle)
	{
		CloseHandle(lhhandle);		
	}
	else
	{
		MessageBox(NULL,"错误","错误",MB_OK);
		return E_FAIL;
	}
	
	/*
	if (SUCCEEDED(hr))
	{
		// Wait for completion.
		long evCode;
		hr = m_pEvent->WaitForCompletion(INFINITE, &evCode);

		int i = 0;
		// Note: Do not use INFINITE in a real application, because it
		// can block indefinitely.
	}
	*/
	
	
	return hr;
}

STDMETHODIMP CGraphCenter::Stop()
{
	HRESULT hr;
	hr = m_pMC->Stop();
	TRACE1("CGraphCenter::Stop停止\n");
	//hr = DisassembleGraph();
	return hr;
}

void WINAPI CGraphCenter::WaitForEnd(void * apParameter)
{
	/*
	CGraphCenter* lpGraphCenter = (CGraphCenter*) apParameter;
	HANDLE  hEvent; 
	long    evCode, param1, param2;
	BOOLEAN bDone = FALSE;
	HRESULT hr = S_OK;
	hr = lpGraphCenter->m_pEvent->GetEventHandle((OAEVENT*)&hEvent);
	if (FAILED(hr))
	{
		
	}
	while(!bDone) 
	{
		if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 100))
		{ 
			while (hr = lpGraphCenter->m_pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr)) 
			{
				printf("Event code: %#04x\n Params: %d, %d\n", evCode, param1, param2);
				lpGraphCenter->m_pEvent->FreeEventParams(evCode, param1, param2);
				bDone = (EC_COMPLETE == evCode);
			}
		}
	} 
	*/
	
	

	CGraphCenter* lpGraphCenter = (CGraphCenter*) apParameter;
	
	HRESULT hr;	
	if (NULL == lpGraphCenter->mpGetZZLStateProc)
	{
		return;
	}

	ITVSourceConfig* lpTVSourceConfig;
	int liState = 0;//0为运行,1为停止。-1为发生意外错误停止
	EnterCriticalSection(&lpGraphCenter->moCriticalSection);
	hr = lpGraphCenter->m_pTVStreamSink->QueryInterface(IID_ITVSouceConfig, (void**)&lpTVSourceConfig);
	LeaveCriticalSection(&lpGraphCenter->moCriticalSection);

    int bytethesamecounter = 0;
    LONGLONG prevsize = 0;
	while ( 0 == liState)
	{
		lpTVSourceConfig->GetZZLState(&liState);
        if(lpTVSourceConfig->EndOfStream())
		{
            TRACE1("因为EndOfStream非正常退出\n");
			break;
		}
        LONGLONG size = lpTVSourceConfig->GetTotalBytes();
		
        if(size == prevsize)
            bytethesamecounter++;
        else
            prevsize = size;

        TraceLog1("handle file: %d bytes\r\n",size);
        Sleep(500);

        if(bytethesamecounter > 10)
		{
			TRACE1("因为bytethesamecounter非正常退出\n");
			break;
		}
           
	}
	TRACE1("end123mistate:%d\n",liState );
	ULONG iii = lpTVSourceConfig->Release();
	lpTVSourceConfig = NULL;
	
	EnterCriticalSection(&lpGraphCenter->moCriticalSection);
	lpGraphCenter->m_iIsStop = 1;
	hr = lpGraphCenter->Stop();	
	lpGraphCenter->DisassembleGraph();
	LeaveCriticalSection(&lpGraphCenter->moCriticalSection);

	lpGraphCenter->mpGetZZLStateProc(lpGraphCenter->mpGetZZLUserPara, 1);
	

	/*
	hr = lpGraphCenter->m_pEvent->WaitForCompletion(INFINITE, &lpEvCode);
	if (FAILED(hr))
	{
		lpGraphCenter->mpGetZZLStateProc(lpGraphCenter->mpGetZZLUserPara, -1);
		EnterCriticalSection(&lpGraphCenter->moCriticalSection);
		lpGraphCenter->m_iIsStop  = -1;		
		LeaveCriticalSection(&lpGraphCenter->moCriticalSection);
		return ;
	}
	if (EC_COMPLETE != lpEvCode && EC_USERABORT != lpEvCode)
	{
		lpGraphCenter->mpGetZZLStateProc(lpGraphCenter->mpGetZZLUserPara, -1);
		EnterCriticalSection(&lpGraphCenter->moCriticalSection);
		lpGraphCenter->m_iIsStop = -1;		
		LeaveCriticalSection(&lpGraphCenter->moCriticalSection);
		return;
	}
	lpGraphCenter->mpGetZZLStateProc(lpGraphCenter->mpGetZZLUserPara, 1);
	EnterCriticalSection(&lpGraphCenter->moCriticalSection);
	lpGraphCenter->m_iIsStop = 1;
	LeaveCriticalSection(&lpGraphCenter->moCriticalSection);

	hr = lpGraphCenter->Stop();	
	lpGraphCenter->DisassembleGraph();
	
	Sleep(100);
	*/
}

float CGraphCenter::GetCompressedSpeed()
{
	HRESULT hr;
	float lfSpeed;
	if (0 != GetState())
	{
		return 0;
	}
	assert(m_pTVStreamSink);

	ITVSourceConfig* lpTVSourceConfig = NULL;
	hr = m_pTVStreamSink->QueryInterface(IID_ITVSouceConfig, (void**)&lpTVSourceConfig);
	if (FAILED(hr))
	{
		MessageBox(NULL, "获取速度失败", "错误", MB_OK|MB_ICONSTOP);
		return 0;
	}
	lfSpeed = lpTVSourceConfig->GetCompressedSpeed();
	lpTVSourceConfig->Release();
	return lfSpeed;
}

//设置状态回调函数
void CGraphCenter::SetStateProc(GetZZLState* apStateproc, void* apUserPara)
{
	assert(apStateproc);
	mpGetZZLStateProc = apStateproc;
	mpGetZZLUserPara = apUserPara;
}

//创建调试信息日志
bool CGraphCenter::CreateDebugInfo()
{
    char strPath[255];
	char strLogFileName[255];
	
	//首先设置日志打印选项
	CDebugTrace::SetTraceLevel(6);
	
	CDebugTrace::SetTraceOptions(CDebugTrace::GetTraceOptions() \
		| CDebugTrace::Timestamp & ~CDebugTrace::LogLevel \
		& ~CDebugTrace::FileAndLine | CDebugTrace::AppendToFile\
		& ~CDebugTrace::PrintToConsole);
	
	if (!GetModuleFileName(NULL,strPath, 255))
	{
		TRACE1("CMediaCenter::CreateDebugInfo:GetModuleFileName()函数返回失败!\n");
		return false;
	}
	
	//从strPath中去掉文件名,从而取得可执行文件的路径;
	int nPosition = 0;
	nPosition = (int)(strrchr(strPath,'\\') - strPath);
	strPath[nPosition+1] = '\0';
	
	//生成日志目录
	strcat(strPath, "日志文件\\");	
	if(TRUE != CreateDirectory(strPath, NULL))
	{
		int i = GetLastError();
		if (ERROR_ACCESS_DENIED != i && ERROR_ALREADY_EXISTS != i)
		{
			MessageBox(NULL, "创建文件夹失败", "错误", MB_OK|MB_ICONSTOP);
		}
	}

	//生成TRACE文件名
	SYSTEMTIME loSystemTime;
	GetLocalTime(&loSystemTime);
	
	sprintf(strLogFileName, "%sGetZZLDisplay%4d%02d%02d%s", strPath,loSystemTime.wYear,\
		loSystemTime.wMonth,loSystemTime.wDay,".log");
	//sprintf(strLogFileName, "%sUTMedia%4d%02d%02d%s", strPath,loSystemTime.wYear,\
//		loSystemTime.wMonth,loSystemTime.wDay,".log");
	//strcat(strPath, "GetZZLDisplay.log");
	CDebugTrace::SetLogFileName(strLogFileName);	    
	return true;
}

⌨️ 快捷键说明

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