📄 vfwimageprocessor.cpp
字号:
/*******************************************************************************
Title............... Video For Windows Class Interface
Programmer.......... Ken Varn
Date Created........ 9/20/2000
Operating System.... Windows NT 4
Compiler............ Microsoft Visual C++ 6
File Type........... C++ Source
Description:
Class interface to Video For Windows.
Before using any functions in this class, the Initialize() member
function must be called on the instantiated object.
When finished using this class, the Destroy() member function should
be used.
Revision History:
Revision Date.... xx-xx-xx
Programmer....... xxx
Comments......... xxx
*******************************************************************************/
#include "stdafx.h"
#include "VFWImageProcessor.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma comment(lib,"vfw32")
UINT CVFWImageProcessor::m_ValidDriverIndex[MAX_VFW_DEVICES];
USHORT CVFWImageProcessor::m_TotalVideoDrivers = 0;
#define UM_VID_SOURCE (WM_USER+1)
#define UM_VID_FORMAT (WM_USER+2)
#define UM_VID_DISPLAY (WM_USER+3)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVFWImageProcessor::CVFWImageProcessor()
{
m_TransferBitmapInfo = NULL;
m_TransferBitmapInfoSize = 0;
m_hWndVideo = NULL;
m_CaptureThread = NULL;
m_DriverIndex = -1;
memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
}
CVFWImageProcessor::~CVFWImageProcessor()
{
Destroy();
}
/*******************************************************************************
Function : Initialize
Arguments : DriverIndex (input) - Index of VFW driver.
Return : TRUE Success, FALSE Failure
Description: Inititlizes the object for using VFW interface to capture
device.
*******************************************************************************/
BOOL CVFWImageProcessor::Initialize(SHORT DriverIndex)
{
BOOL Ret = FALSE;
SHORT Index;
Destroy();
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
// This semaphore will temporarily be used to determine when the
// capture thread is ready.
m_ImageReady.ResetEvent();
// Create message pump for window messages.
m_CaptureThread = AfxBeginThread(CaptureThreadFunc,(void *) this);
m_CaptureThread->m_bAutoDelete = FALSE;
// Wait for event to determine when capture thread is ready.
::WaitForSingleObject(m_ImageReady, INFINITE);
if (m_hWndVideo)
{
capSetUserData(m_hWndVideo,this);
capSetCallbackOnError(m_hWndVideo,ErrorCallbackProc);
capSetCallbackOnCapControl(m_hWndVideo,ControlCallbackProc);
capSetCallbackOnStatus(m_hWndVideo,StatusCallbackProc);
capSetCallbackOnFrame(m_hWndVideo, FrameCallbackProc);
capSetCallbackOnVideoStream(m_hWndVideo, StreamCallbackProc);
// Construct list of valid video drivers.
// This creates a contiguous virtual driver table.
if (!m_TotalVideoDrivers)
{
char szDeviceName[80];
char szDeviceVersion[80];
for (Index = 0; Index < MAX_VFW_DEVICES; Index++)
{
if (capGetDriverDescription(Index,
szDeviceName,
sizeof(szDeviceName),
szDeviceVersion,
sizeof(szDeviceVersion)))
{
try
{
if (capDriverConnect(m_hWndVideo, Index))
{
m_ValidDriverIndex[m_TotalVideoDrivers] = Index;
m_TotalVideoDrivers++;
capDriverDisconnect(m_hWndVideo);
}
}
catch(CException *Ex)
{
Ex->Delete();
}
catch(...)
{
}
}
}
}
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
Ret = SetDriver(DriverIndex);
}
if (!Ret)
{
if (m_ErrorID == 0)
m_ErrorID = DV_ERR_NONSPECIFIC;
Destroy();
}
return Ret;
}
/*******************************************************************************
Function : GetCapWindow
Arguments : none
Return : HWND of VFW window.
Description: Used to retrieve the handle used for VFW image processing.
*******************************************************************************/
HWND CVFWImageProcessor::GetCapWindow()
{
return m_hWndVideo;
}
//
// Copy Constructor
//
CVFWImageProcessor::CVFWImageProcessor(const CVFWImageProcessor &CopyFrom)
{
m_TransferBitmapInfo = NULL;
m_TransferBitmapInfoSize = 0;
m_hWndVideo = NULL;
m_CaptureThread = NULL;
m_DriverIndex = -1;
memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
Copy(CopyFrom);
}
//
// Copy class using operator=
//
CVFWImageProcessor &CVFWImageProcessor::operator =(const CVFWImageProcessor &CopyFrom)
{
return Copy(CopyFrom);
}
/*******************************************************************************
Function : Destroy
Arguments : none
Return : none
Description: Closes up the interface for VFW of capture device.
*******************************************************************************/
VOID CVFWImageProcessor::Destroy()
{
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
if (m_hWndVideo)
{
DisablePreviewVideo();
capCaptureAbort(m_hWndVideo);
capSetCallbackOnError(m_hWndVideo,NULL);
capSetCallbackOnCapControl(m_hWndVideo,NULL);
capSetCallbackOnStatus(m_hWndVideo,NULL);
capSetCallbackOnFrame(m_hWndVideo,NULL);
capSetCallbackOnVideoStream(m_hWndVideo, NULL);
capSetUserData(m_hWndVideo,NULL);
capDriverDisconnect(m_hWndVideo);
}
if (m_CaptureThread)
{
DWORD ExitCode;
INT Timeout = 50; // Tenths of a Second
// Terminate the message queue thread and wait for it to end.
m_CaptureThread->PostThreadMessage(WM_QUIT,0,0);
while(Timeout)
{
GetExitCodeThread(m_CaptureThread->m_hThread, &ExitCode);
if (ExitCode != STILL_ACTIVE)
{
// Thread has ended.
break;
}
else
{
Sleep(100);
}
--Timeout;
}
delete m_CaptureThread;
m_hWndVideo = NULL;
}
m_TransferBitmapInfo = NULL;
m_TransferBitmapInfoSize = 0;
m_hWndVideo = NULL;
m_CaptureThread = NULL;
m_DriverIndex = -1;
memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
}
/*******************************************************************************
Function : CaptureDIB
Arguments : Bitmap (output) - Pointer to bitmap to receive image.
If *Bitmap = NULL, then allocation will
be performed automatically.
BitmapLength (input) - Size of Bitmap if *Bitmap is not NULL.
RetBitmapLength (output) - Actual size of image.
Return : TRUE Success, FALSE Failed.
Description: Captures a DIB image from video capture device.
*******************************************************************************/
BOOL CVFWImageProcessor::CaptureDIB(PBITMAPINFO *Bitmap,
ULONG BitmapLength,
ULONG *RetBitmapLength)
{
BOOL Ret = FALSE;
CSingleLock ImageLockObj(&m_ImageProtect);
DWORD Size = 0;
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
if (*Bitmap == NULL)
{
AllocDIBImage(Bitmap,&Size);
BitmapLength = Size;
}
else
{
AllocDIBImage(NULL,&Size);
}
if (*Bitmap && Size > 0)
{
if (RetBitmapLength)
{
*RetBitmapLength = Size;
}
// Must assign pointer to class member variable so that the
// callback function can get to it.
ImageLockObj.Lock();
m_TransferBitmapInfo = *Bitmap;
m_TransferBitmapInfoSize = BitmapLength;
ImageLockObj.Unlock();
// Reset event semaphore so we know when an image is ready.
m_ImageReady.ResetEvent();
// Start capturing now. Callback function will capture and signal us when done.
TRACE("Before Capture Start Call\n");
Ret = capGrabFrame(m_hWndVideo);
TRACE("After Capture Start Call\n");
if (Ret)
{
Ret = FALSE;
// Wait for capture to complete.
if (::WaitForSingleObject(m_ImageReady,2000) == WAIT_OBJECT_0)
{
TRACE("Image Ready\n");
Ret = TRUE; // Success
}
}
ImageLockObj.Lock();
m_TransferBitmapInfo = NULL;
m_TransferBitmapInfoSize = 0;
ImageLockObj.Unlock();
if (!Ret)
{
if (RetBitmapLength)
{
*RetBitmapLength = (ULONG) 0;
}
}
}
if (!Ret && m_ErrorID == 0)
{
m_ErrorID = DV_ERR_NONSPECIFIC;
}
return Ret;
}
/*******************************************************************************
Function : CaptureAVI
Arguments : Filename (input) - Name of file to capture AVI
FramesPerSec (input) - Frames Per second of AVI.
Duration (input) - How long to run it in seconds.
Quality (input unused)
Return : TRUE Success, FALSE Failed.
Description: Captures AVI to file from current video capture device.
*******************************************************************************/
BOOL CVFWImageProcessor::CaptureAVI(LPCTSTR Filename,
FLOAT FramesPerSec,
ULONG Duration,
UINT Quality)
{
BOOL Ret = FALSE;
CAPTUREPARMS OrigCapParms;
CAPTUREPARMS CapParms;
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
m_CancelCapture.ResetEvent();
capCaptureGetSetup(m_hWndVideo,&OrigCapParms,sizeof(OrigCapParms));
CapParms = OrigCapParms;
CapParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 / FramesPerSec);
CapParms.fLimitEnabled = TRUE;
CapParms.wTimeLimit = Duration;
CapParms.fYield = FALSE;
CapParms.wPercentDropForError = 100; //Quality;
capCaptureSetSetup(m_hWndVideo, &CapParms, sizeof(CapParms));
Ret = capCaptureSequence(m_hWndVideo);
if (Ret)
{
Ret = capFileSaveAs(m_hWndVideo, Filename);
}
capCaptureSetSetup(m_hWndVideo, &OrigCapParms, sizeof (OrigCapParms));
if (!Ret && m_ErrorID == 0)
{
m_ErrorID = DV_ERR_NONSPECIFIC;
}
return Ret;
}
//
// Private function used to copy objects.
//
CVFWImageProcessor &CVFWImageProcessor::Copy(const CVFWImageProcessor &CopyFrom)
{
INT DeviceIdx;
if (&CopyFrom != this)
{
Destroy();
if (CopyFrom.m_hWndVideo)
{
CAPDRIVERCAPS DriverCaps;
capDriverGetCaps(CopyFrom.m_hWndVideo,&DriverCaps,sizeof(DriverCaps));
// Find the device id in the virtual device list.
for (DeviceIdx=0;DeviceIdx<MAX_VFW_DEVICES;++DeviceIdx)
{
if (m_ValidDriverIndex[DeviceIdx] == DriverCaps.wDeviceIndex)
{
Initialize(DeviceIdx);
break;
}
}
}
}
return *this;
}
/*******************************************************************************
Function : SetDriver
Arguments : DriverIndex (input) - Driver to set
Return : TRUE Success, FALSE Failed.
Description: Sets curretn capture driver.
*******************************************************************************/
BOOL CVFWImageProcessor::SetDriver(SHORT DriverIndex)
{
BOOL Ret = TRUE;
CAPTUREPARMS CapParms = {0};
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);
if (DriverIndex >= m_TotalVideoDrivers)
{
Ret = FALSE;
m_ErrorID = DV_ERR_BADDEVICEID;
}
if (m_hWndVideo && m_DriverIndex != DriverIndex && Ret)
{
if (GetParent(m_hWndVideo) != NULL)
capPreview(m_hWndVideo,FALSE);
DisablePreviewVideo();
capCaptureAbort(m_hWndVideo);
Ret = capDriverConnect(m_hWndVideo, m_ValidDriverIndex[DriverIndex]);
if (Ret)
{
capGetVideoFormat(m_hWndVideo,(PBITMAPINFO) &m_BitmapInfoHeader,sizeof(m_BitmapInfoHeader));
capCaptureGetSetup(m_hWndVideo,&CapParms,sizeof(CapParms));
CapParms.fAbortLeftMouse = FALSE;
CapParms.fAbortRightMouse = FALSE;
CapParms.fYield = TRUE;
CapParms.fCaptureAudio = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -