www.pudn.com > myseelite_2007_06_28.zip > GraphCenter.cpp
/* * Openmysee * * 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 * */ #include "stdafx.h" #include "GraphCenter.h" #include#include "../captureserver/TVSourceConfig.h" #include "../captureserver/uuids.h" #include #define SAFE_RELEASE(p) { if(p) p->Release(); p = NULL; } //构造析构函数 CGraphCenter::CGraphCenter() :mpAsfReader( NULL) { m_pTVStreamSink = NULL; m_pSourceFile = NULL; m_pAviSplitter = NULL; m_pGB = NULL; m_pMC = NULL; m_pEvent = NULL; InitializeCriticalSection(&moCriticalSection); //保护停止标志位。 EnterCriticalSection(&moCriticalSection); m_iIsStop = 1; //0为运行,1为停止。-1为发生意外错误停止 LeaveCriticalSection(&moCriticalSection); CreateDebugInfo(); } CGraphCenter::~CGraphCenter() { Uninitialize(); EnterCriticalSection(&moCriticalSection); m_iIsStop = 1; //0为运行,1为停止。-1为发生意外错误停止 LeaveCriticalSection(&moCriticalSection); DeleteCriticalSection(&moCriticalSection); //保护停止标志位。 } //将Filter添加到图中去 STDMETHODIMP CGraphCenter::AddFilter(CLSID clsidFilter, IBaseFilter** ppIFilter, LPCTSTR pstrFilterName) { HRESULT hr; assert(m_pGB); assert(ppIFilter); (*ppIFilter) = NULL; // try to instantiate the filter hr = CoCreateInstance(clsidFilter, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID*)(ppIFilter)); if(FAILED(hr)) { //DbgLog((LOG_TRACE, 5, TEXT("Could not instantiate filter"))); //TRACE("Could not instantiate filter"); return hr; } // Check for unicode or not #ifndef _UNICODE if(pstrFilterName) { // not unicode, we need to unicodify the string WCHAR wstrFilterName[256]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, pstrFilterName, -1, wstrFilterName, sizeof(wstrFilterName) / sizeof(WCHAR)); // try to add it to the filter graph hr = m_pGB->AddFilter(*ppIFilter, wstrFilterName); } else { // No filter name specified, cannot convert // try to add it to the filter graph hr = m_pGB->AddFilter(*ppIFilter, NULL); } #else // already unicode, no need to change anything // try to add it to the filter graph hr = m_pGB->AddFilter(*ppIFilter, pstrFilterName); #endif // check the result of the operation if(FAILED(hr)) { //TRACE("Could not add filter to filter graph\n"); // free the filter definitely (*ppIFilter)->Release(); (*ppIFilter) = NULL; return hr; } // that's it return hr; } //pin的连接 STDMETHODIMP CGraphCenter::ConnectPins(IBaseFilter* pIFilterOutput, LPCTSTR pstrPinNameOutput, IBaseFilter* pIFilterInput, LPCTSTR pstrPinNameInput, AM_MEDIA_TYPE* pmt) { HRESULT hr; assert(m_pGB); // Parameters... if((!pIFilterOutput) || (!pIFilterInput)) { assert(pIFilterOutput && pIFilterInput); //TRACE("ConnectPins called with NULL parameter\n"); return E_INVALIDARG; } // Find the first pin IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput, pstrPinNameOutput, PINDIR_OUTPUT); if(!pIPinOutput) { assert(pIPinOutput); return E_FAIL; } // Find the second pin IPin* pIPinInput = FindPinOnFilter(pIFilterInput, pstrPinNameInput, PINDIR_INPUT); if(!pIPinInput) { assert(pIPinInput); // release the other pin pIPinOutput->Release(); return E_FAIL; } if(FAILED(pIPinOutput->Disconnect())) { assert(FALSE); return E_FAIL; } if(FAILED(pIPinInput->Disconnect())) { assert(FALSE); return E_FAIL; } // Now just connect the two pins hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt); // assert(SUCCEEDED(hr)); if(FAILED(hr)) { TraceLog1("Could not direct connect pins!, try intelligent connect"); hr = m_pGB->Connect(pIPinOutput, pIPinInput); } // Release the two pins and return the result pIPinOutput->Release(); pIPinInput->Release(); return hr; } //自动连接Filter STDMETHODIMP CGraphCenter::ConnectAutoPins(IBaseFilter* pIFilterOutput, LPCTSTR pstrPinNameOutput, IBaseFilter* pIFilterInput, LPCTSTR pstrPinNameInput) { HRESULT hr; assert(m_pGB); // Parameters... if((!pIFilterOutput) || (!pIFilterInput)) { assert(pIFilterOutput && pIFilterInput); //TRACE("ConnectPins called with NULL parameter\n"); return E_INVALIDARG; } // Find the first pin IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput, pstrPinNameOutput, PINDIR_OUTPUT); if(!pIPinOutput) { assert(pIPinOutput); return E_FAIL; } // Find the second pin IPin* pIPinInput = FindPinOnFilter(pIFilterInput, pstrPinNameInput, PINDIR_INPUT); if(!pIPinInput) { assert(pIPinInput); // release the other pin pIPinOutput->Release(); return E_FAIL; } if(FAILED(pIPinOutput->Disconnect())) { assert(FALSE); return E_FAIL; } if(FAILED(pIPinInput->Disconnect())) { assert(FALSE); return E_FAIL; } // Now just connect the two pins hr = m_pGB->Connect(pIPinOutput, pIPinInput); assert(SUCCEEDED(hr)); if(FAILED(hr)) //TRACE("Could not connect pins!"); // Release the two pins and return the result pIPinOutput->Release(); pIPinInput->Release(); return hr; } //查找filter上的pin STDMETHODIMP_(IPin*) CGraphCenter::FindPinOnFilter(IBaseFilter* pIFilter, LPCTSTR pstrPinName, PIN_DIRECTION dir) { HRESULT hr; IEnumPins* pIEnumPins; IPin* pIPin; PIN_INFO pi; assert(m_pGB); // Parameters... if(!pIFilter) return NULL; // Enumerate pins on the filter hr = pIFilter->EnumPins(&pIEnumPins); if(FAILED(hr)) // pin was not found! return NULL; // Loop till we find no more pins IPin* pIPinFound = NULL; while( (!pIPinFound) && (pIEnumPins->Next(1, &pIPin, NULL)==S_OK) ) { // Is this the pin? hr = pIPin->QueryPinInfo(&pi); if(!FAILED(hr)) { // check if it is the right direction if(pi.dir == dir) { // Let the graph builder find the right filter TCHAR strFoundPinName[256]; #ifndef _UNICODE // not unicode, we need to de-unicodify the returned pin name WideCharToMultiByte(CP_ACP, NULL, pi.achName, -1, strFoundPinName, sizeof(strFoundPinName), NULL, NULL); #else // just make a copy of the string lstrcpyn(strFoundPinName, pi.achName, sizeof(strFoundPinName)); #endif // check if there is a pin name specified if(!pstrPinName) { // no name specified, take the first pin found pIPinFound = pIPin; pIPinFound->AddRef(); } // check if we have the right pin name else if(lstrcmp(strFoundPinName, pstrPinName)==0) { // yes we have! pIPinFound = pIPin; pIPinFound->AddRef(); } } // release the PIN_INFO data pi.pFilter->Release(); } // release the IPin pointer pIPin->Release(); } // Finished with the enumerator, let it go (be free) pIEnumPins->Release(); // Return whatever we have found return pIPinFound; } //pin的连接 STDMETHODIMP CGraphCenter::ConnectPinsEX(IBaseFilter* pIFilterOutput, Pin_type atype, IBaseFilter* pIFilterInput, LPCTSTR pstrPinNameInput, BOOL bisAuto,AM_MEDIA_TYPE* pmt) { HRESULT hr; assert(m_pGB); // Parameters... if((!pIFilterOutput) || (!pIFilterInput)) { assert(pIFilterOutput && pIFilterInput); //TRACE("ConnectPins called with NULL parameter\n"); return E_INVALIDARG; } // Find the first pin IPin* pIPinOutput = FindPinOnFilterbyType(pIFilterOutput, atype, PINDIR_OUTPUT); if(!pIPinOutput) { assert(pIPinOutput); return E_FAIL; } // Find the second pin IPin* pIPinInput = FindPinOnFilter(pIFilterInput, pstrPinNameInput, PINDIR_INPUT); if(!pIPinInput) { assert(pIPinInput); // release the other pin pIPinOutput->Release(); return E_FAIL; } if(FAILED(pIPinOutput->Disconnect())) { assert(FALSE); return E_FAIL; } if(FAILED(pIPinInput->Disconnect())) { assert(FALSE); return E_FAIL; } if (FALSE == bisAuto) { hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt); } else { hr = m_pGB->Connect(pIPinOutput, pIPinInput); } // Now just connect the two pins // assert(SUCCEEDED(hr)); if(FAILED(hr)) { TraceLog1("Could not direct connect pins!, try intelligent connect"); hr = m_pGB->Connect(pIPinOutput, pIPinInput); } // Release the two pins and return the result pIPinOutput->Release(); pIPinInput->Release(); return hr; } //查找filter上满足一定条件的的媒体类型 STDMETHODIMP_(IPin*) CGraphCenter::FindPinOnFilterbyType(IBaseFilter* pIFilter, Pin_type aType, PIN_DIRECTION dir) { HRESULT hr; IEnumPins* enum_pin; IPin* findpin = NULL; IPin* pin = NULL; IEnumMediaTypes* enum_media_type; AM_MEDIA_TYPE* media_type = NULL; AM_MEDIA_TYPE* tempmedia_type = NULL; PIN_DIRECTION temp_dir; assert(m_pGB); hr = pIFilter->EnumPins(&enum_pin); if (FAILED(hr)) { return NULL; } enum_pin->Reset(); GUID formattype = (aType == VIDEO)? FORMAT_VideoInfo:FORMAT_WaveFormatEx; ULONG liCount = 0; hr = enum_pin->Next(1,&pin,&liCount); while (!findpin && SUCCEEDED(hr)) { //Is this the pin? 不计数 hr = pin->QueryDirection(&temp_dir); if (FAILED(hr)) { break;//return NULL; } if (temp_dir != dir) { continue; } //枚举媒体类型 hr = pin->EnumMediaTypes(&enum_media_type); if (FAILED(hr)) { break; } /* enum_media_type->AddRef(); iii = enum_media_type->Release();计数:1 */ enum_media_type->Reset(); media_type = NULL; hr = enum_media_type->Next(1,&media_type,&liCount); while (NULL == tempmedia_type && SUCCEEDED(hr)) { if((*media_type).formattype == formattype || (*media_type).formattype == FORMAT_MPEGVideo) { tempmedia_type = media_type; findpin = pin; findpin->AddRef(); break; } hr = enum_media_type->Next(1,&media_type,&liCount); if (0 == liCount) { break; } } hr = enum_pin->Next(1,&pin,&liCount); enum_media_type->Release(); if (0 == liCount) { break; } } enum_pin->Release(); return findpin; } STDMETHODIMP CGraphCenter::RemoveFilter(IBaseFilter* pIFilter) { HRESULT hr; // Parameters... if(!pIFilter) // DON'T return an error, this is expected return NOERROR; assert(m_pGB); // Just remove it from the graph hr = m_pGB->RemoveFilter(pIFilter); return hr; } ////////////////////////////////////////////////////////////////////////// //以下为处理接口函数 ////////////////////////////////////////////////////////////////////////// //初始化库 STDMETHODIMP CGraphCenter::Initialize() { HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { //TRACE0("ERROR - Could not initialize COM library"); return hr; } // Create the filter graph manager and query for interfaces. 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; }