📄 ccapture.cpp
字号:
//CCapture.cpp
#include "stdafx.h"
//#include <vfw.h>
#include "CCapture.h"
int CCapture::m_nDriverID=0;
LRESULT CALLBACK MyCallBackProc(HWND hWnd,LPVIDEOHDR lpHdr)
{
CCapture* pCapture=(CCapture*)capGetUserData(hWnd);
if(!pCapture)return NULL;
if(!(pCapture->pbyFrame))return NULL;
if(!(pCapture->m_pCapCallBackFunc))return NULL;
pCapture->FormatImage(lpHdr->lpData,pCapture->pbyFrame,pCapture->m_nWidth,pCapture->m_nHeight);
(*(pCapture->m_pCapCallBackFunc))(pCapture->pbyFrame,lpHdr->dwBufferLength,pCapture->m_lpUserInstance);
return TRUE;
}
void CCapture::FormatImage(BYTE * pBuffer,BYTE* pFrame,int nWidth,int nHeight)
{
int nLineLength, nTwoLineLength, nYTwoLineLength, nUVTwoLineLength;
BYTE* pYTwoLine;
BYTE* pUTwoLine;
BYTE* pVTwoLine;
BYTE* pLine1;
BYTE* pLine2;
int j=0;
switch(m_byImageFormat)
{
case 1://yu420p,bt848
nLineLength=nWidth+nWidth/2;
nTwoLineLength=nWidth+nWidth+nWidth;
nYTwoLineLength=nWidth+nWidth;
nUVTwoLineLength=nWidth/2;
pYTwoLine=pFrame;
pUTwoLine=pFrame+nWidth*nHeight;
pVTwoLine=pFrame+nWidth*nHeight+nWidth*nHeight/4;
pLine1=pBuffer+(nHeight-1)*nLineLength;
pLine2=pBuffer+(nHeight-2)*nLineLength;
for(j=nHeight;j>0;j-=2)
{
FormatTwoLine(pLine1,pLine2,pYTwoLine,pUTwoLine,pVTwoLine,nLineLength);
pYTwoLine+=nYTwoLineLength;
pUTwoLine+=nUVTwoLineLength;
pVTwoLine+=nUVTwoLineLength;
pLine1-=nTwoLineLength;
pLine2-=nTwoLineLength;
}
break;
case 2://yuv2,philips
nLineLength=nWidth+nWidth;
nTwoLineLength=nWidth+nWidth+nWidth+nWidth;
nYTwoLineLength=nWidth+nWidth;
nUVTwoLineLength=nWidth/2;
pYTwoLine=pFrame;
pUTwoLine=pFrame+nWidth*nHeight;
pVTwoLine=pFrame+nWidth*nHeight+nWidth*nHeight/4;
pLine1=pBuffer+(nHeight-1)*nLineLength;
pLine2=pBuffer+(nHeight-2)*nLineLength;
for(j=nHeight;j>0;j-=2)
{
FormatTwoLine(pLine1,pLine2,pYTwoLine,pUTwoLine,pVTwoLine,nLineLength);
pYTwoLine+=nYTwoLineLength;
pUTwoLine+=nUVTwoLineLength;
pVTwoLine+=nUVTwoLineLength;
pLine1-=nTwoLineLength;
pLine2-=nTwoLineLength;
}
break;
}
}
CCapture::CCapture(PCapCallBackFunc pCapCallBackFunc)
{
m_hWndCap=NULL;
m_hParentWnd=NULL;
m_bInitialize=FALSE;
m_nWidth=128;
m_nHeight=96;
m_nFrameRate=30;
m_pCapCallBackFunc=pCapCallBackFunc;
m_bPreviewOrOverlay=FALSE;
m_bVisible=TRUE;
ZeroMemory(&m_bitMapInfo,sizeof(m_bitMapInfo));
m_bitMapInfo.bmiHeader.biSize=sizeof(m_bitMapInfo.bmiHeader);
m_bitMapInfo.bmiHeader.biWidth=(LONG)m_nWidth;
m_bitMapInfo.bmiHeader.biHeight=(LONG)m_nHeight;
m_bitMapInfo.bmiHeader.biPlanes=1;
switch(m_byImageFormat)
{
case 1://yu420p
m_bitMapInfo.bmiHeader.biBitCount=12;
m_bitMapInfo.bmiHeader.biCompression=1345401945;
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*3/2;
break;
case 2://yuv2
m_bitMapInfo.bmiHeader.biBitCount=16;
m_bitMapInfo.bmiHeader.biCompression=844715353;
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*2;
break;
}
m_bitMapInfo.bmiHeader.biXPelsPerMeter=0;
m_bitMapInfo.bmiHeader.biYPelsPerMeter=0;
m_bitMapInfo.bmiHeader.biClrUsed=0;
m_bitMapInfo.bmiHeader.biClrImportant=0;
pbyFrame=new BYTE[m_bitMapInfo.bmiHeader.biSizeImage];
}
CCapture::~CCapture()
{
if(pbyFrame)delete pbyFrame;
if(m_bInitialize)
{
if(m_nDriverID>0)
m_nDriverID--;
EndCap();
}
}
BOOL CCapture::InitCap(HWND hParentWnd,LPVOID lpUserInstance)
{
HMENU hSysMenu=NULL;
if(m_bInitialize)return FALSE;
m_hParentWnd=hParentWnd;
m_lpUserInstance=lpUserInstance;
int x,y;
int w,h;
RECT rec;
if(m_hParentWnd)
{
x=0;
y=0;
GetWindowRect(m_hParentWnd,&rec);
//w=rec.right-rec.left;
//h=rec.bottom-rec.top;
w=m_nWidth;
h=m_nHeight;
}
else
{
x=(GetSystemMetrics(SM_CXSCREEN)-m_nWidth)/2;
y=(GetSystemMetrics(SM_CYSCREEN)-m_nHeight)/2;
}
if(m_bVisible)
m_hWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",
WS_CHILD|WS_VISIBLE,
x,y,
w,//m_nWidth+2*GetSystemMetrics(SM_CXSIZEFRAME),
h,//m_nHeight+2*GetSystemMetrics(SM_CYSIZEFRAME),
m_hParentWnd,(int)0
);
else
m_hWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",
WS_CHILD,
x,y,
m_nWidth+2*GetSystemMetrics(SM_CXSIZEFRAME),
m_nHeight+2*GetSystemMetrics(SM_CYSIZEFRAME ),
m_hParentWnd,(int)0
);
if(!m_hWndCap)return FALSE;
if(!capSetCallbackOnVideoStream(m_hWndCap,MyCallBackProc))
goto ABORT;
if(m_nDriverID>9)goto ABORT;
if(!capDriverConnect(m_hWndCap,m_nDriverID))
goto ABORT;
m_nDriverID++;
hSysMenu=GetSystemMenu(m_hWndCap,FALSE);
EnableMenuItem(hSysMenu,SC_CLOSE,MF_GRAYED);
if(!capDriverGetCaps(m_hWndCap,&m_CapDriverCaps,sizeof(CAPDRIVERCAPS)))
goto ABORT;
if(!capSetUserData(m_hWndCap,this))
goto ABORT;
if(!capSetVideoFormat(m_hWndCap,&m_bitMapInfo,sizeof(m_bitMapInfo)))
goto ABORT;
if(!m_bVisible)
{
m_bInitialize=TRUE;
return TRUE;
}
if(m_CapDriverCaps.fHasOverlay)
if(capOverlay(m_hWndCap,TRUE))
{
m_bInitialize=TRUE;
m_bPreviewOrOverlay=FALSE;
return TRUE;
}
if(!capPreviewRate(m_hWndCap,15))goto ABORT;
if(!capPreviewScale(m_hWndCap,TRUE))goto ABORT;
if(capPreview(m_hWndCap,TRUE))
{
m_bInitialize=TRUE;
m_bPreviewOrOverlay=TRUE;
return TRUE;
}
ABORT:
capDriverDisconnect(m_hWndCap);
::AfxMessageBox("CCaptue's initilize video for windows FAIL!");
PostMessage(m_hWndCap,WM_CLOSE,0,0);
m_hWndCap=NULL;
return FALSE;
}
void CCapture::DisableVisible(BOOL bInvisible)
{
if(!m_bInitialize)
{
m_bVisible=!bInvisible;
return;
}
//if(m_bVisible!=bInvisible)return;
m_bVisible=!bInvisible;
if(m_bVisible)
ShowWindow(m_hWndCap,SW_SHOW);
else
ShowWindow(m_hWndCap,SW_HIDE);
}
BOOL CCapture::SetCapSize(int nWidth,int nHeight)
{
if(!m_bInitialize)
{
m_nWidth=nWidth;
m_nHeight=nHeight;
m_bitMapInfo.bmiHeader.biWidth=(LONG)m_nWidth;
m_bitMapInfo.bmiHeader.biHeight=(LONG)m_nHeight;
switch(m_byImageFormat)
{
case 1:
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*3/2;
break;
case 2:
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*2;
break;
}
if(pbyFrame)delete pbyFrame;
pbyFrame=new BYTE[m_bitMapInfo.bmiHeader.biSizeImage];
return TRUE;
}
if(m_nWidth==nWidth&&m_nHeight==nHeight)
return TRUE;
if(!capGetVideoFormat(m_hWndCap,&m_bitMapInfo,sizeof(m_bitMapInfo)))
return FALSE;
m_bitMapInfo.bmiHeader.biWidth=(LONG)m_nWidth;
m_bitMapInfo.bmiHeader.biHeight=(LONG)m_nHeight;
switch(m_byImageFormat)
{
case 1:
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*3/2;
break;
case 2:
m_bitMapInfo.bmiHeader.biSizeImage=m_nWidth*m_nHeight*2;
break;
}
if(pbyFrame)delete pbyFrame;
pbyFrame=new BYTE[m_bitMapInfo.bmiHeader.biSizeImage];
return capSetVideoFormat(m_hWndCap,&m_bitMapInfo,sizeof(m_bitMapInfo));
}
BOOL CCapture::SetFrameRate(int nFrameRate)
{
if(!m_bInitialize)
{
m_nFrameRate=nFrameRate;
return TRUE;
}
if(m_nFrameRate==nFrameRate)return TRUE;
if(!capCaptureGetSetup(m_hWndCap,&m_captureParms,sizeof(CAPTUREPARMS)))
return FALSE;
m_captureParms.dwRequestMicroSecPerFrame=(int)((1/(float)nFrameRate)*1000000);
return capCaptureSetSetup(m_hWndCap, &m_captureParms, sizeof(CAPTUREPARMS));
}
BOOL CCapture::StartCap()
{
if(!m_bInitialize)
return FALSE;
if(!SetCapSize(m_nWidth,m_nHeight))
return FALSE;
if(!capCaptureGetSetup(m_hWndCap,&m_captureParms,sizeof(CAPTUREPARMS)))
return FALSE;
m_captureParms.fYield=TRUE;
m_captureParms.fAbortRightMouse=FALSE;
m_captureParms.fAbortLeftMouse=FALSE;
m_captureParms.fCaptureAudio=FALSE;
m_captureParms.dwRequestMicroSecPerFrame=(int)((1/(float)m_nFrameRate)*1000000);
if(!capCaptureSetSetup(m_hWndCap, &m_captureParms, sizeof(CAPTUREPARMS)))
return FALSE;
return capCaptureSequenceNoFile(m_hWndCap);
}
void CCapture::EndCap()
{
if(!m_bInitialize)return;
if(m_nDriverID>0)
m_nDriverID--;
m_pCapCallBackFunc=NULL;
m_bInitialize=FALSE;
capDriverDisconnect(m_hWndCap);
SendMessage(m_hWndCap,WM_CLOSE,0,0);
}
BOOL CCapture::SetDisplaySize(int nWidth,int nHeight)
{
//SetWindowPos();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -