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

📄 main.c

📁 最新版的基于 Windows CE 的视频捕获解决方案
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * main.c
 *
 * USB Camera for Windows CE Project
 *
 * Copyright (c) 2005-2008 for Cyansoft Studio (www.cyansoft.com.cn).
 * All Rights Reserved.
 *
 *
 * Contributor(s): ______________________________________.
 *
 * $Cyansoft$
 */
#include <windows.h>
#include <commdlg.h>
#include <commctrl.h>
#include "resource.h"

#include "../../inc/zc030xlib.h"
#include "../../inc/avilib.h"
#include "../../inc/framebuffer.h"
#include "../../inc/scale.h"

/* library */
#if defined(ARMV4)
#pragma comment(lib, "../../lib/armv4/zc030xlib.lib")
#pragma comment(lib, "../../lib/armv4/avilib.lib")
#pragma comment(lib, "../../lib/armv4/framebuffer.lib")
#pragma comment(lib, "../../lib/armv4/scale.lib")
#elif defined(ARMV4I)
#pragma comment(lib, "../../lib/armv4i/zc030xlib.lib")
#pragma comment(lib, "../../lib/armv4i/avilib.lib")
#pragma comment(lib, "../../lib/armv4i/framebuffer.lib")
#pragma comment(lib, "../../lib/armv4i/scale.lib")
#elif defined(x86)
#pragma comment(lib, "../../lib/x86/zc030xlib.lib")
#pragma comment(lib, "../../lib/x86/avilib.lib")
#elif defined(MIPSII)
#pragma comment(lib, "../../lib/mipsii/zc030xlib.lib")
#pragma comment(lib, "../../lib/mipsii/avilib.lib")
#elif defined(SH4)
#pragma comment(lib, "../../lib/sh4/zc030xlib.lib")
#pragma comment(lib, "../../lib/sh4/avilib.lib")
#endif

#define SAFE_DESTROY(x) if(x){DestroyWindow(x);x=NULL;}
#define SAFE_FREE(x) if(x){free(x);x=NULL;}
#define MAX_JPG_SIZE 40960

/* globals */
static HINSTANCE g_hInst = NULL;
static HWND g_hWnd = NULL;
static HWND g_hMenuBar = NULL;
static UINT g_uIndex = 0; /* first camera */
static UINT g_uScreenWidth = 0, g_uScreenHeight = 0, g_uBitsPixel = 0;
static char g_szCapFile[MAX_PATH] = {0};
static BOOL g_fIsStart = FALSE, g_fIsExit = FALSE;
static BOOL g_fIsFullScreen = FALSE, g_fIsCapture = FALSE;
static UINT g_uVideoWidth = 320, g_uVideoHeight = 240;
static RECT g_rcDisplay = {0};
static HANDLE g_hThread = NULL;
#if defined(ARM)
static LPBYTE g_pFrameBuffer = NULL;
static LPVOID g_pScaler = NULL;
static CRITICAL_SECTION g_csLock = {0};
static BOOL g_fIsPauseDisplay = FALSE;
#endif

BOOL InitInstance(HINSTANCE hInst, int nShowCmd);
VOID DeinitInstance();
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

/* entry point */
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nShowCmd)
{
	MSG msg = {0};

	if(!InitInstance(hInst, nShowCmd))
		goto finish;

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

finish:
	DeinitInstance();

	return 0;
}

HWND CreateMenuBar(HWND hWnd, UINT uBarId, HINSTANCE hInst, UINT uMenuId)
{
	HWND hBar = NULL;
	hBar = CommandBar_Create(hInst, hWnd, uBarId);
	if(hBar)
	{
		CommandBar_InsertMenubar(hBar, hInst, uMenuId, 0);
		CommandBar_AddAdornments (hBar, 0, 0);
		CommandBar_Show(hBar, TRUE);
	}

	return hBar;
}

BOOL AdjustDisplay(HWND hWnd, BOOL isFullScreen)
{
	if(g_fIsExit)
		return FALSE;

	if(isFullScreen)
	{
		g_rcDisplay.left = 0;
		g_rcDisplay.top = 0;
		g_rcDisplay.right = g_uScreenWidth;
		g_rcDisplay.bottom = g_uScreenHeight;
	}
	else
	{
		RECT rc = {0};
		UINT bar_height = CommandBar_Height(g_hMenuBar);

		GetWindowRect(hWnd, &rc);
		
		if(g_uVideoWidth < min(g_uScreenWidth, g_uScreenHeight - bar_height))
		{
			g_rcDisplay.left = (g_uScreenWidth - g_uVideoWidth)/2;
			g_rcDisplay.top = (g_uScreenHeight - g_uVideoHeight)/2;
			g_rcDisplay.right = g_rcDisplay.left + g_uVideoWidth;
			g_rcDisplay.bottom = g_rcDisplay.top + g_uVideoHeight;			
		}
		else
		{
			UINT width = 0, height = 0;
			if(g_uScreenWidth > g_uScreenHeight)
			{
				width = g_uScreenWidth;
				height = g_uVideoHeight * width / g_uVideoWidth;
				if(height > (g_uScreenHeight - bar_height))
				{
					height = g_uScreenHeight - bar_height;
					width = g_uVideoWidth * height / g_uVideoHeight;
				}
			}
			else
			{
				height = g_uScreenHeight - bar_height;
				width = g_uVideoWidth * height / g_uVideoHeight;
				if(width > g_uScreenWidth)
				{
					width = g_uScreenWidth;
					height = g_uVideoHeight * width / g_uVideoWidth;
				}
			}

			g_rcDisplay.left = (g_uScreenWidth - width)/2;
			g_rcDisplay.top = g_uScreenHeight - height;
			g_rcDisplay.right = g_rcDisplay.left + width;
			g_rcDisplay.bottom = g_rcDisplay.top + height;	
		}
	}

#if defined(ARM)
	if(g_pFrameBuffer != NULL)
	{
		/* Framebuffer Mode */
		EnterCriticalSection(&g_csLock);
		if(g_pScaler != NULL)
		{
			scale_deinit(g_pScaler);
			g_pScaler = NULL;
		}
		
		if(isFullScreen)
			g_pScaler = scale_init(g_uVideoWidth, g_uVideoHeight, max(g_uScreenWidth, g_uScreenHeight), min(g_uScreenWidth, g_uScreenHeight), g_uBitsPixel);
		else
			g_pScaler = scale_init(g_uVideoWidth, g_uVideoHeight, g_rcDisplay.right-g_rcDisplay.left, g_rcDisplay.bottom-g_rcDisplay.top, g_uBitsPixel);
		LeaveCriticalSection(&g_csLock);
	}

#endif

	return TRUE;
}


int GetVideoPalette(UINT bitsPixel)
{
	int fmt = -1;
	
	switch(bitsPixel)
	{
	case 16:
		fmt = VIDEO_PALETTE_RGB565;
		break;
	case 32:
		fmt = VIDEO_PALETTE_RGB32;
		break;
	case 24:
		fmt = VIDEO_PALETTE_RGB24;
		break;
	}
	
	return fmt;
}

BOOL InitInstance(HINSTANCE hInst, int nShowCmd)
{
	HDC hdc = NULL;	
	int fmt = -1;
	LPTSTR pszClassName = TEXT("UsbCam Window Class");
	WNDCLASS wc = {0};
	INITCOMMONCONTROLSEX icce = {0};
	
	icce.dwSize = sizeof(icce);
	icce.dwICC = ICC_BAR_CLASSES;
	if(!InitCommonControlsEx(&icce))
	{
		return FALSE;
	}

	/* get camera count */
	if(capInitCamera() <= 0)
		return FALSE;

	/* get screen size and depth */
	hdc = GetDC(NULL);
	if(hdc)
	{
		g_uScreenWidth = GetDeviceCaps(hdc, HORZRES);
		g_uScreenHeight = GetDeviceCaps(hdc, VERTRES);
		g_uBitsPixel = GetDeviceCaps(hdc, BITSPIXEL);
		ReleaseDC(NULL, hdc);
		hdc = NULL;
	}

#if defined(ARM)
	InitializeCriticalSection(&g_csLock);
	/* 
	 * Important note:
	 * 如果程序异常很可能是这里引起的,可以指定 g_pFrameBuffer = NULL,
	 * 这时将采用 GDI 方式进行显示。
	 *
	 */
	g_pFrameBuffer = GetFrameBuffer();
	if(NULL == g_pFrameBuffer)
		g_uBitsPixel = 24;	
#else
	g_uBitsPixel = 24;
#endif

	fmt = GetVideoPalette(g_uBitsPixel);
	if (0 != capSetVideoFormat(g_uIndex, fmt, VIDEO_SIZE_SIF))
	{
		return FALSE;
	}

	/* register class */
	wc.lpszClassName = pszClassName;
	wc.lpfnWndProc = (WNDPROC) MainWindowProc;
	wc.style = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hInstance = hInst;
	
	RegisterClass(&wc);

	/* create main window */
	g_hWnd = CreateWindow(pszClassName, TEXT("UsbCam"), WS_VISIBLE, 
		0, 0, g_uScreenWidth, g_uScreenHeight, NULL, NULL, hInst, NULL);

	if(NULL == g_hWnd)
		return FALSE;

	/* create menu bar */
	g_hMenuBar = CreateMenuBar(g_hWnd, IDC_CMD_BAR, hInst, IDR_MAIN_MENU);

	ShowWindow(g_hWnd, nShowCmd);
	UpdateWindow(g_hWnd);
	SetWindowPos(g_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

	AdjustDisplay(g_hWnd, g_fIsFullScreen);

	return (g_hMenuBar != NULL);
}

VOID DeinitInstance()
{	
	if(g_hThread)
	{
		DWORD dwCode = 0;
		
		Sleep(500);
		if(GetExitCodeThread(g_hThread, &dwCode))
		{
			if (dwCode == STILL_ACTIVE)
			{
				TerminateThread(g_hThread, 0);
			}
			
			CloseHandle(g_hThread);
			g_hThread = NULL;
		}		
	}	

	if(g_hMenuBar)
	{
		CommandBar_Destroy(g_hMenuBar);
		g_hMenuBar = NULL;
	}

	SAFE_DESTROY(g_hWnd);

	capCloseCamera();

#if defined(ARM)	
	scale_deinit(g_pScaler);
	g_pScaler = NULL;
	
	ReleaseFrameBuffer(g_pFrameBuffer);
	g_pFrameBuffer = NULL;

	DeleteCriticalSection(&g_csLock);
#endif
}

BOOL GetFilePath(HWND hwnd, LPTSTR pFilePath)
{
	TCHAR szFilter[] = TEXT("AVI Files\0*.avi\0\0");			
	OPENFILENAME ofn = {0};
	
	memset(&ofn, 0, sizeof (ofn));
	ofn.lStructSize     = sizeof (ofn);
	ofn.hwndOwner       = hwnd;
	ofn.lpstrFilter     = szFilter;
	ofn.nFilterIndex    = 1;
	ofn.lpstrFile       = pFilePath;
	ofn.nMaxFile        = MAX_PATH;
	ofn.lpstrInitialDir = NULL;
	
	return GetSaveFileName(&ofn);
}

#if defined(ARM)
VOID display_frame(char *rgb, int width, int height)
{
	char *ptr, *src;
	int x, y, l, line, w, h, screenW;
	
	screenW = g_uScreenWidth;
	w = width;
	h = height;
	line = screenW * (g_uBitsPixel >> 3);
	l = w * (g_uBitsPixel >> 3);
	x = g_rcDisplay.left;
	y = g_rcDisplay.top;
	
	ptr = (char *)g_pFrameBuffer + y * line + x * (g_uBitsPixel >> 3);
	src = rgb;
	
	do
	{
		memcpy(ptr, src, l);
		ptr += line;
		src += l;
	} while (--h != 0);		
}

VOID display_frame_full(char *rgb, int width, int height)
{
	char *ptr, *src;
	int x, y, l, line, w, h, screenW;
	
	screenW = g_uScreenWidth;
	w = width;
	h = height;
	line = screenW * (g_uBitsPixel >> 3);
	l = w * (g_uBitsPixel >> 3);
	x = 0;
	y = 0;
	
	ptr = (char *)g_pFrameBuffer + y * line + x * (g_uBitsPixel >> 3);
	src = rgb;
	
	do
	{
		memcpy(ptr, src, l);
		ptr += line;
		src += l;
	} while (--h != 0);	
}

VOID DoDrawFrame(char *rgb)
{
	if(g_fIsFullScreen)
	{

⌨️ 快捷键说明

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