📄 graphcenter.cpp
字号:
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, ¶m1, ¶m2, 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 + -