📄 capture.cpp
字号:
// capture.cpp
// Emmanuel Grolleau (c) 2002
// This file is a part of AviCapTcl
// Describes the class CCapture which uses VFW to implement
// a Tk widget that captures a video or image from a source
// Version 1.0.0.0
// Last modification 01/05/2002
#include "capture.h"
#include <tkwinint.h>
#define CHECK_CX() if (!_connected) {return FALSE;}
LRESULT PASCAL CompressCallback(HWND hWnd, LPVIDEOHDR lpVHdr);
LRESULT PASCAL TclVideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr);
LRESULT CALLBACK TclYieldCallback(HWND hWnd);
LRESULT PASCAL TclFrameCallback(HWND hWnd, LPVIDEOHDR lpVHdr);
LRESULT CALLBACK TclErrorCallback(HWND hWnd,int nID,LPCSTR lpsz);
void CCapture::_selfInit() {
_connected=FALSE;
_preview=FALSE;
_overlay=FALSE;
_compressionstarted=FALSE;
_bmpInfo=NULL;
_VideoStreamCb=NULL;
_WavStreamCb=NULL;
_YieldCb=NULL;
_FrameCb=NULL;
_ErrorCb=NULL;
_avifile=NULL;
_timer=NULL;
_tcl_VideoStreamCb=NULL;
_tcl_WaveStreamCb=NULL;
_tcl_YieldCb=NULL;
_tcl_FrameCb=NULL;
_tcl_ErrorCb=NULL;
memset(&_compvars,0,sizeof(_compvars));
memcpy(&_compvars.fccHandler,"DIB ",4);
}
void CCapture::_clearAllCb() {
if (_VideoStreamCb) {
capSetCallbackOnVideoStream(capHwnd, NULL);
_VideoStreamCb=NULL;
}
if (_WavStreamCb) {
capSetCallbackOnWaveStream(capHwnd, NULL);
_WavStreamCb=NULL;
}
if (_YieldCb) {
capSetCallbackOnYield(capHwnd, NULL);
_YieldCb=NULL;
}
if (_FrameCb) {
capSetCallbackOnFrame(capHwnd, NULL);
_FrameCb=NULL;
}
if (_ErrorCb) {
capSetCallbackOnError(capHwnd, NULL);
_ErrorCb=NULL;
}
}
int CCapture::nb_capwindow=0;
void CCapture::GetDriversList(CStringArray &Names) {
Names.RemoveAll( );
Names.SetSize(0,1);
char tmpName[80];
char tmpVer[80];
for (int j =0; j < MAXCAPDRIVERS; j++) {
if (capGetDriverDescription (j,tmpName, sizeof (tmpName),tmpVer,sizeof (tmpVer))) {
Names.Add((LPCSTR)tmpName);
} else return;
}
}
CCapture::CCapture(const CString name,Tcl_Interp *interp,BOOL &ok,int w,int h) {
nb_capwindow++;
tclname=name;
tclinterp=interp;
void * pthn=(void *)LPCSTR(tclname);
tkwin=Tk_CreateWindowFromPath(tclinterp, Tk_MainWindow(interp),(char *)pthn, NULL);
Tk_GeometryRequest(tkwin, w, h);
Tk_MakeWindowExist(tkwin);
tk_hwnd=Tk_GetHWND(Tk_WindowId(tkwin));
capHwnd=capCreateCaptureWindow("Capture",WS_CHILD|WS_VISIBLE, 0, 0, w, h,tk_hwnd, nb_capwindow);
ASSERT(capHwnd);
ok=capHwnd?TRUE:FALSE;
AddCapture(this);
_selfInit();
}
BOOL CCapture::Connect(int indx) {
BOOL ret=capDriverConnect(capHwnd, indx);
if (!ret) {
Disconnect();
return FALSE;
}
_getBITMAPINFO();
long w=_bmpInfo->bmiHeader.biWidth;
long h=_bmpInfo->bmiHeader.biHeight;
Tk_GeometryRequest(tkwin, w, h);
SetWindowPos(capHwnd,0,0,0,w,h,0);
_connected=TRUE;
return TRUE;
}
BOOL CCapture::Disconnect() {
if (!_connected) return TRUE;
StopCapture();
_connected=FALSE;
_clearAllCb();
if (_bmpInfo) {
delete _bmpInfo;
_bmpInfo=NULL;
}
return capDriverDisconnect(capHwnd);
}
CCapture::~CCapture() {
Disconnect();
RemoveCapture(this);
DestroyWindow(capHwnd);
Tk_DestroyWindow(tkwin);
}
CCapture::cell* CCapture::_allCaptures=0;
LPTOP_LEVEL_EXCEPTION_FILTER CCapture::_pastExceptionHandler=NULL;
CCapture *CCapture::FindCapture(const CString tclname) {
cell *c=_allCaptures;
while (c) {
if (c->cap->tclname==tclname) {
return c->cap;
}
c=c->suiv;
}
return NULL;
}
LONG WINAPI exceptionhandler (LPEXCEPTION_POINTERS arg) {
CCapture::FreeAllDrivers();
return EXCEPTION_CONTINUE_SEARCH;
}
void CCapture::AddCapture(CCapture* cap) {
if (_allCaptures=NULL) {
// Setting the exception handler
_pastExceptionHandler=SetUnhandledExceptionFilter(exceptionhandler);
}
_allCaptures=new cell(cap,_allCaptures);
}
void CCapture::RemoveCapture(const CCapture *cap) {
cell *c=_allCaptures,*p=NULL;
while (c) {
if (c->cap==cap) {
if (p) {
p->suiv=c->suiv;
} else {
_allCaptures=c->suiv;
}
delete c;
return;
}
p=c;
c=c->suiv;
}
if (_allCaptures==NULL) {
// Remove the exception handler
SetUnhandledExceptionFilter(_pastExceptionHandler);
}
}
void CCapture::FreeAllDrivers() {
while (_allCaptures) {
delete _allCaptures;
}
}
BOOL CCapture::Preview(int rate) {
CHECK_CX();
if (rate==0) {
capPreview(capHwnd,FALSE);
_preview=FALSE;
return TRUE;
} else {
BOOL res=capPreviewRate(capHwnd,rate);
if (!_preview && res) {
_preview=TRUE;
return capPreview(capHwnd,TRUE);
}
return res;
}
}
BOOL CCapture::Overlay(BOOL onoff) {
CHECK_CX();
if (onoff!=_overlay) {
if (capOverlay(capHwnd,onoff)) {
_overlay=onoff;
return TRUE;
} else {return FALSE;}
}
return TRUE;
}
BOOL CCapture::CompressDlg(char fccHandler[4]) {
COMPVARS cmpv;
cmpv.cbSize=sizeof(cmpv);
cmpv.fccType=ICTYPE_VIDEO;
cmpv.dwFlags=0;
if (ICCompressorChoose(capHwnd,0,0,0,&cmpv,0)) {
_compvars=cmpv;
memcpy(fccHandler,&_compvars.fccHandler,4);
return TRUE;
}
memcpy(fccHandler,&_compvars.fccHandler,4);
return FALSE;
}
BOOL CCapture::DisplayDlg() {
return capDlgVideoDisplay(capHwnd);
}
BOOL CCapture::FormatDlg() {
return capDlgVideoFormat(capHwnd);
}
BOOL CCapture::VSourceDlg() {
return capDlgVideoSource(capHwnd);
}
BOOL CCapture::GetCaptureStatus(CAPSTATUS *stat) {
return capGetStatus(capHwnd,stat,sizeof(CAPSTATUS));
}
BOOL CCapture::GetCaptureSetup(CAPTUREPARMS *parms) {
return capCaptureGetSetup (capHwnd, parms, sizeof(CAPTUREPARMS));
}
BOOL CCapture::SetCaptureSetup(CAPTUREPARMS *parms) {
return capCaptureSetSetup (capHwnd, parms, sizeof(CAPTUREPARMS));
}
BOOL CCapture::SetCaptureFile(LPSTR pathname) {
return capFileSetCaptureFile(capHwnd,pathname);
}
BOOL CCapture::StartCapture() {
CHECK_CX();
if (IsCompressed()&&_compressionstarted) {
if (!_tcl_VideoStreamCb) {
if (!capSetCallbackOnVideoStream(capHwnd,CompressCallback)) {
return FALSE;
}
_VideoStreamCb=CompressCallback;
}
char sz[512];
capFileGetCaptureFile(capHwnd,sz,512);
_avifile=new CAVIFile(sz,_compvars.lpbiOut);
CAPTUREPARMS parms;
GetCaptureSetup(&parms);
_timer=new AVITimer(parms.dwRequestMicroSecPerFrame);
return capCaptureSequenceNoFile(capHwnd);
} else {
return capCaptureSequence (capHwnd);
}
}
BOOL CCapture::StartSeq() {
CHECK_CX();
CAPTUREPARMS parms;
GetCaptureSetup(&parms);
_timer=new AVITimer(parms.dwRequestMicroSecPerFrame);
return capCaptureSequenceNoFile(capHwnd) ;
}
BOOL CCapture::StopCapture() {
CHECK_CX();
if (_avifile) {
delete _avifile;
_avifile=NULL;
}
if (_timer) {
delete _timer;
_timer=NULL;
}
return capCaptureStop(capHwnd);
}
void CCapture::Debug(char * text) {
CString T;
T.Format("Debug \"%s\"",text);
Tcl_GlobalEval(tclinterp,T.GetBuffer(0));
}
long CCapture::TimeFrame() {
return _timer?_timer->AddFrame():0;
}
LPVOID CCapture::DefaultCompressCallbackAction(LPVIDEOHDR lpVHdr) {
if (_avifile) {
long size=lpVHdr->dwBufferLength;
BOOL isIndex;
LPVOID newdata=Compress(lpVHdr->lpData,&size,&isIndex);
//CString s;
//s.Format("currentFrame=%d",(int)nb);
//cap->Debug(s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -