📄 capturevideo.cpp
字号:
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
int index = 0;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
if (index == deviceId)
{ //生成绑定到设备上的filter
pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);//生成绑定到设备上的filter
}
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
index++;
}
m_bCapStatus = true;
return true;
}
HRESULT CCaptureVideo::InitCaptureGraphBuilder()
{
HRESULT hr;
// 创建IGraphBuilder接口
hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB);
// 创建ICaptureGraphBuilder2接口
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
if (FAILED(hr))return hr;
m_pCapture->SetFiltergraph(m_pGB);
hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
if (FAILED(hr))return hr;
hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);
if (FAILED(hr))return hr;
return hr;
}
HRESULT CCaptureVideo::SetupVideoWindow()
{ //设置显示窗体控件的属性
HRESULT hr;
hr = m_pVW->put_Owner((OAHWND)m_hPreviewWnd);
if (FAILED(hr))return hr;
hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if (FAILED(hr))return hr;
ResizeVideoWindow();
hr = m_pVW->put_Visible(OATRUE);
return hr;
}
void CCaptureVideo::ResizeVideoWindow()
{
if (m_pVW)
{
//让图像充满整个窗口
CRect rc;
::GetClientRect(m_hPreviewWnd,&rc);
m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
}
void CCaptureVideo::GrabOneFrame(CStatic* inpShow)
{
HWND hStill;
hStill = inpShow->GetSafeHwnd();
SetCurrentDirectory(m_strBaseDir);
SetCurrentDirectory(m_strCurDir);
//试探是否已存在捕捉文件
char FileBuf[20];
for(int i=0;i<65535;i++)
{
sprintf(FileBuf,"Pic%05d.bmp",i);
if((access(FileBuf,0)) == -1)
break;
}
mCB.m_strBMPFile = FileBuf;
mCB.m_hStill = hStill;
mCB.bOneShot = TRUE;
}
void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0)
{
CoTaskMemFree((PVOID)mt.pbFormat);
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL)
{
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
HRESULT CCaptureVideo::Stop()
{
mCB.m_socket = INVALID_SOCKET;
/*while (mCB.bWorking == TRUE)
{
;
}*/
ClearGraphs();
//m_pMC->Stop();
return NULL;
}
//获取压缩graph
void CCaptureVideo::GetCompFilter(IBaseFilter **pCompFilter)
{
//枚举系统中的压缩filter
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
#ifdef CANUSEFILTER
int iLoopFilter=1;
#endif
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pSysDevEnum);
if (FAILED(hr))
{
AfxMessageBox("枚举不到视频压缩Filter");
return;
}
//开始枚举压缩filter
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnum, 0); //枚举压缩filter
if (hr == S_OK) // S_FALSE表示没有枚举到这个类型的filter
{
while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
VARIANT var;
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if (SUCCEEDED(hr))
{
//得到一个可以用的压缩filter
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)pCompFilter);
if (SUCCEEDED(hr))
{
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;
// 枚举filter上的 pin,寻找支持 IAMVideoCompression 的pin.
(*pCompFilter)->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress);
pPin->Release();
if (SUCCEEDED(hr)) // 找到这个接口
{
break;
}
}
if (SUCCEEDED(hr))
{
long lCap; // 性能标记
long lKeyFrame, lPFrame; // 真实值
double m_Quality;
long lKeyFrameDef, lPFrameDef; // 默认值
double QualityDef;
// 获取默认值
CString strFilterName=var.bstrVal;
if (strFilterName=="Microsoft MPEG-4 Video Codec V3")
{
hr = pCompress->GetInfo(0, 0, 0, 0, &lKeyFrameDef, &lPFrameDef,
&QualityDef, &lCap);
if (SUCCEEDED(hr))
{
// 获取真实值
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
lKeyFrame = lKeyFrameDef;
}
if (lCap & CompressionCaps_CanBFrame)
{
hr = pCompress->get_PFramesPerKeyFrame(&lPFrame);
if (FAILED(hr) || lPFrame < 0)
lPFrame = lPFrameDef;
}
if (lCap & CompressionCaps_CanQuality)
{
hr = pCompress->get_Quality(&m_Quality);
if (FAILED(hr) || m_Quality < 0)
m_Quality = QualityDef;
}
#ifdef CANUSEFILTER
strFilterName=var.bstrVal;
if (strFilterName=="Microsoft MPEG-4 Video Codec V3")
{
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
break;
}
iLoopFilter++;
#else
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
break;
#endif
}
}
}
//
}
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
}
pSysDevEnum->Release();
pEnum->Release();
}
//清除整个捕捉Graph
bool CCaptureVideo::ClearGraphs()
{
if( m_pGB )
{
if( m_pMC )
m_pMC->Stop();
if( m_pVW )
{
m_pVW->put_Visible( OAFALSE );
m_pVW->put_Owner( NULL );
}
m_pGB->Release();
}
return true;
}
BOOL CCaptureVideo::SetFileDir(CString inDir)
{
//定位在当前目录
LPCSTR lpszPath = m_strBaseDir;
SetCurrentDirectory(lpszPath);
//创建存储目录
lpszPath = inDir;
BOOL pass = CreateDirectory(lpszPath,NULL);
if (pass == FALSE)
{
return pass;
}
//进入新建目录
pass = SetCurrentDirectory(lpszPath);
m_strCurDir = lpszPath;
return pass;
}
BOOL CCaptureVideo::ConnectTo(char *inpIP, int inDesPort)
{
mCB.m_socket = socket(AF_INET,SOCK_STREAM,0);
if (mCB.m_socket == INVALID_SOCKET)
return FALSE;
struct sockaddr_in serversocketaddr;
serversocketaddr.sin_family = AF_INET;
serversocketaddr.sin_addr.S_un.S_addr = inet_addr(inpIP);
serversocketaddr.sin_port = htons(inDesPort);
//连接服务器
if (connect(mCB.m_socket,(struct sockaddr *)&serversocketaddr,sizeof(serversocketaddr)) == SOCKET_ERROR)
return FALSE;
return TRUE;
}
void CCaptureVideo::SetCmd(CVoyCmd *inpCmd)
{
if (mCB.m_pCmd!=NULL && NULL == inpCmd)
{
mCB.m_pCmd->m_pCap = NULL;
mCB.m_pCmd = NULL;
return;
}
mCB.m_pCmd = inpCmd;
inpCmd->m_pCap = this;
}
void CCaptureVideo::SetPosID(UINT inPosID)
{
mCB.m_nPosID = inPosID;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -