⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 captureframe.cpp

📁 matlab的视频接口程序
💻 CPP
字号:
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// CaptureFrame.cpp:
//	implementation of the CCaptureFrame class.
//	Copyright 
//		(c) 1998 School of Information Systems, UEA
//	Author
//		Farzad Pezeshkpour
//	Revision
//		1998/12/03
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

#include "stdafx.h"
#include "utility.h"
#include "CaptureFrame.h"
#include "resource.h"
#include "menuitem.h"
#include <sstream>


#undef AVICapSM

//#pragma warning (disable : 4005)
#define AVICapSM(hwnd,m,w,l) ( (::IsWindow(hwnd)) ? ::SendMessage(hwnd,m,w,l) : 0)
//#pragma warning (default : 4005)
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Static Declarations
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CCaptureFrame *CCaptureFrame::m_pFrame = NULL;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCaptureFrame::CCaptureFrame()
: CWindowImpl <CCaptureFrame> (),
  m_hVfwWnd(NULL),
  m_bPreview(false),
  m_bStretch(false),
  m_bProportional(false),
  m_pFormat(NULL),
  m_hIC(NULL),
  m_dwFrames(0)
{
	
	m_vcaps.wDeviceIndex = 99;
}





CCaptureFrame::~CCaptureFrame()
{
	ReleaseIC ();
	if (m_hVfwWnd != NULL) {
		::SetParent (m_hVfwWnd, GetDesktopWindow());
		SetFrameCallback (false);
		capDriverDisconnect(m_hVfwWnd);
		m_hVfwWnd = NULL;
	}
	DestroyWindow();
}




CWndClassInfo& CCaptureFrame::GetWndClassInfo ()
{
	static CWndClassInfo wc =
	{
		{ sizeof(WNDCLASSEX), CS_NOCLOSE|CS_HREDRAW|CS_VREDRAW, StartWindowProc,
		  0, 0, 0, LoadIcon (_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_ICON2)), 0, (HBRUSH)(COLOR_WINDOW+1), MAKEINTRESOURCE(IDR_MENU1), "MatlabVfwFrame", 0 },

		NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
	}; 
	return wc;
}



LRESULT CCaptureFrame::OnInitMenuPopup(WPARAM wParam, LPARAM lParam)
{
	// We don't process the system menu (yet)
	if (((BOOL)HIWORD(lParam))) {
		return 1;
	}

	LRESULT result;
	CMenuItem mi;
	mi.m_hMenu = (HMENU) wParam;
	UINT uiPos = (UINT) LOWORD (lParam);

	// Hack - this functionality should be provided by an overridable
	// baseclass member

	if (uiPos == 0) {
		UpdateDeviceMenu (mi.m_hMenu);
		return 0;
	}

	UINT count = (UINT)::GetMenuItemCount (mi.m_hMenu);
	for (UINT i = 0; i < count; i++) {
		mi.m_nIndex = i;
		mi.m_nId = ::GetMenuItemID (mi.m_hMenu, mi.m_nIndex);
		wParam = MAKEWPARAM (mi.m_nId, CN_COMMAND_UI);
		ProcessWindowMessage (m_hWnd, WM_COMMAND, wParam, ((LPARAM) &mi), result, 0);
	}
	return 0;
}


void	CCaptureFrame::OnUpdatePreview (CMenuItem *pItem)
{
	pItem->SetCheck(m_bPreview);
}

void	CCaptureFrame::OnPreview		()
{
	SetPreview (!m_bPreview);
}

HWND CCaptureFrame::Create(HWND hWndParent, RECT & rcPos, LPCTSTR sszWindowName, DWORD dwStyle, DWORD dwExStyle, UINT nID)
{
	HWND hWnd = CWindowImpl<CCaptureFrame>::Create(hWndParent, rcPos, sszWindowName, dwStyle, dwExStyle, nID);
	m_hVfwWnd = capCreateCaptureWindow ("VfwCapture", WS_CHILD|WS_VISIBLE, 0, 0, 320, 240, hWnd, 4456);
	ConnectDevice (0);
	return hWnd;
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// EmptyDeviceList
// Ensures that the list of devices is empty
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void CCaptureFrame::EmptyDeviceList()
{
	for (WORD wIndex = 0; wIndex < 10; wIndex++)
		m_sDevices[wIndex] = "";

}

std::string *CCaptureFrame::GetDriverList ()
{
	BuildDeviceList();
	return m_sDevices;
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// BuildDeviceList
// Clears the current device list and re-reads the system
// video devices
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void CCaptureFrame::BuildDeviceList()
{
	EmptyDeviceList ();
	char szDeviceName[80];
	char szDeviceVersion[80];
	

	for (WORD wIndex = 0; wIndex < 10; wIndex++) 
	{
	    if (capGetDriverDescription (wIndex, szDeviceName, 
			sizeof (szDeviceName), szDeviceVersion, 
			sizeof (szDeviceVersion)))
		{
			m_sDevices[wIndex] = szDeviceName;
		}
	}
}



//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// UpdateDeviceMenu
// Called by the framework to rebuild the device menu
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void CCaptureFrame::UpdateDeviceMenu(HMENU hMenu)
{
	BuildDeviceList ();

	int count = GetMenuItemCount (hMenu);
	while (count-- > 0) {
		::RemoveMenu (hMenu, 0, MF_BYPOSITION);
		DrawMenuBar();
	}

	UINT iDriver = 99; // default value indicating no match
	UINT iNext = 0;
	MENUITEMINFO mi;
	

	mi.cbSize = sizeof(mi);
	mi.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE;
	mi.fType = MFT_STRING;
	mi.wID = ID_DEVICEMENU_0;
	mi.dwTypeData = "";

	for (WORD wIndex = 0; wIndex < 10; wIndex++) {
		if (!m_sDevices[wIndex].empty()) {
			mi.wID = ID_DEVICEMENU_0 + wIndex;
			mi.dwTypeData = (char*)m_sDevices[wIndex].c_str();

			if (::InsertMenuItem (hMenu, iNext, TRUE, &mi)) {
				if (m_vcaps.wDeviceIndex == wIndex)
						iDriver = iNext;
				DrawMenuBar ();
				++iNext;
			}
		}
	}

	// set the check button
	if (iDriver < 10) 
		::CheckMenuRadioItem (hMenu, 0, iNext-1, iDriver, MF_BYPOSITION);
	
}


void CCaptureFrame::OnSelectDriver	(DWORD dwId)
{
	dwId -= ID_DEVICEMENU_0;
	SetDriver(dwId);
}

bool CCaptureFrame::SetDriver (DWORD dwId) 
{
	if (dwId > 9) return false;
	if (m_sDevices[dwId].empty ()) return false;
	capDriverDisconnect(m_hVfwWnd);
	m_vcaps.wDeviceIndex = 99;
	ConnectDevice((WORD)dwId);
	return true;
}

bool CCaptureFrame::ConnectDevice(WORD index)
{
	bool ok = true;
	if (index > 9 || m_hVfwWnd == NULL) ok = false;

	ok = ok && capDriverConnect(m_hVfwWnd, index);
	ok = ok && capDriverGetCaps(m_hVfwWnd, &m_vcaps, sizeof(m_vcaps));
	ok = ok && capPreviewRate(m_hVfwWnd, 20);     // rate, in milliseconds
	if (ok) {
		ReleaseIC();
		RetrieveFormat();
		ResetSize();
	}
	return ok;
}



bool CCaptureFrame::SetPreview (bool bPreview)
{
	bool ok = true;
	if (m_hVfwWnd == NULL) ok = false;
	ok = ok && capPreview(m_hVfwWnd, bPreview);
	if (ok) 
		m_bPreview = bPreview;
	return ok;
}



LRESULT CCaptureFrame::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	SetSize ();
	return 0;
}




//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// OnUpdateStretch
// Called before the Stretch Item in the Window menu is updated
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void	CCaptureFrame::OnUpdateStretch (CMenuItem *pItem)
{
	pItem->SetCheck(m_bStretch);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// OnStretch
// Called when the Stretch item in the Window menu is activated
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void	CCaptureFrame::OnStretch		()
{
	SetStretch (!m_bStretch);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// SetStretch
// Called to (un)set the stretching of the preview window
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
bool	CCaptureFrame::SetStretch (bool bStretch)
{
	bool ok = (m_hVfwWnd != NULL);
	ok = ok && capPreviewScale (m_hVfwWnd, bStretch);
	if (ok) {
		m_bStretch = bStretch;
		SetSize();
		RedrawWindow ();
	}
	return ok;
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// DeleteFormat
// Delete an existing video format
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void CCaptureFrame::DeleteFormat ()
{
	if (m_pFormat) {
		delete ((LPBYTE)m_pFormat);
		m_pFormat = NULL;
	}
}

void CCaptureFrame::RetrieveFormat ()
{
	DeleteFormat();
	DWORD dwSize;
	dwSize = capGetVideoFormatSize(m_hVfwWnd);
	m_pFormat = (LPBITMAPINFO)new BYTE [dwSize];
	capGetVideoFormat(m_hVfwWnd, m_pFormat, dwSize); 
}


void CCaptureFrame::ResetSize ()
{
	if (m_hVfwWnd == NULL || m_pFormat == NULL) return;
	RECT cr;
	RECT wr;
	RECT pos;
	GetClientRect (&cr);
	GetWindowRect (&wr);
	pos = wr;
	wr.right -= wr.left;
	wr.bottom -= wr.top;
	wr.left = wr.top = 0;

	// calculate the size of the frame
	cr.right = wr.right - cr.right;
	cr.bottom = wr.bottom - cr.bottom;

	pos.right = m_pFormat->bmiHeader.biWidth + cr.right;
	pos.bottom = m_pFormat->bmiHeader.biHeight + cr.bottom;

	MoveWindow (pos.left, pos.top, pos.right, pos.bottom);
}



void CCaptureFrame::SetFrameCallback (bool bSet) {
	if (m_hVfwWnd == NULL) return;
	if (bSet) {
		m_pFrame = this;
		capSetCallbackOnFrame (m_hVfwWnd, FrameCallback);
	} else {
		m_pFrame = NULL;
		capSetCallbackOnFrame (m_hVfwWnd, NULL);
	}
}

LRESULT PASCAL CCaptureFrame::FrameCallback (HWND hWnd, LPVIDEOHDR lpVHdr)
{
	if (m_pFrame != NULL)
		m_pFrame->m_queue.AppendFrame (m_pFrame->m_pFormat, lpVHdr->lpData);
	return (LRESULT) TRUE ;
}



void CCaptureFrame::Grab(WORD wCount)
{
	if (m_hVfwWnd == NULL) {
		std::string *pStr = new std::string("capture window not created yet.");
		throw pStr;
	}
	m_dwFrames = wCount;
	m_queue.SetSize (wCount);
	m_queue.ClearBuffer();

	SetFrameCallback (true);
	//capCaptureSequenceNoFile (m_hVfwWnd);
	for (WORD i = 0; i < wCount; i++)
		capGrabFrameNoStop (m_hVfwWnd);

	SetFrameCallback (false);
}


void CCaptureFrame::ReleaseIC()
{
	if (m_hIC != NULL) {
		ICClose (m_hIC);
		m_hIC = NULL;
	}
}



void CCaptureFrame::GetMatlabArrays (int lower, int upper, 
					  mxArray *plhs[], int nlhs)
{
	m_queue.GetMatlabArrays (lower, upper, plhs, nlhs, m_hIC);
}



//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// OnUpdateFormatDlg
//	Called before the "Format Dlg" item in the Configure menu is 
//	updated
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void	CCaptureFrame::OnUpdateFormatDlg (CMenuItem *pItem)
{
	pItem->Enable(m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoFormat);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// OnUpdateSourceDlg
//	Called before the "Source Dlg" item in the Configure menu is 
//	updated
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void	CCaptureFrame::OnUpdateSourceDlg (CMenuItem *pItem)
{
	pItem->Enable(m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoSource);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// OnUpdateDisplayDlg
//	Called before the "Display Dlg" item in the Configure menu is 
//	updated
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
void	CCaptureFrame::OnUpdateDisplayDlg (CMenuItem *pItem)
{
	pItem->Enable(m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoDisplay);
}



bool CCaptureFrame::ConfigureSource ()
{
	if (m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoSource) {
		capDlgVideoSource (m_hVfwWnd);
		ReleaseIC();
		RetrieveFormat();
		if (!m_bStretch)
			ResetSize();
		return true;
	} else 
		return false;
}

bool CCaptureFrame::ConfigureFormat()
{
	if (m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoFormat) {
		capDlgVideoFormat (m_hVfwWnd);
		ReleaseIC();
		RetrieveFormat();
		if (!m_bStretch)
			ResetSize();
		return true;
	} else
		return false;
}

bool CCaptureFrame::ConfigureDisplay ()
{
	if (m_hVfwWnd != NULL && m_vcaps.fHasDlgVideoDisplay) {
		capDlgVideoDisplay (m_hVfwWnd);
		ReleaseIC();
		RetrieveFormat();
		if (!m_bStretch)
			ResetSize();
		return true;
	} else
		return false;
}


void CCaptureFrame::OnHide ()
{
	ShowWindow (SW_HIDE);
}

void CCaptureFrame::OnShow ()
{
	ShowWindow (SW_SHOWDEFAULT);
}

void CCaptureFrame::OnShow (bool bShow)
{
	ShowWindow (bShow ? SW_SHOWDEFAULT : SW_HIDE);
}

void CCaptureFrame::SetSize()
{
	RECT r;
	GetClientRect (&r);
	
	WORD height = r.bottom;
	WORD width = r.right;

	WORD imwidth = 0;
	WORD imheight = 0;

	if (m_pFormat != NULL) {
		imwidth = (WORD) m_pFormat->bmiHeader.biWidth;
		imheight = (WORD) m_pFormat->bmiHeader.biHeight;
	}

	WORD x = (width - imwidth) / 2;
	WORD y = (height - imheight) / 2;

	if (m_bStretch) {
		::MoveWindow (m_hVfwWnd, 0, 0, width, height, FALSE);
	} else {
		::MoveWindow (m_hVfwWnd, x, y, imwidth, imheight, FALSE);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -