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

📄 cameracode.cpp

📁 WEB CAM代码第二版,对CAM驱动有兴趣的朋友参考.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			return 0;
		}
		else
			return GetLastError();
	}
	return 0;
}
//----------------------------------------------------------------------
// Stops the video streaming
//
int StopStreaming ()
{
	fCont = FALSE;
	if (WaitForSingleObject (hThread, 5000) == WAIT_TIMEOUT)
	{
		DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Can't shutdown ReadFrameThread\r\n")));
	}
	CloseHandle (hThread);
	hThread = 0;
	return 0;
}

//======================================================================
// ReadFrameThread - Reads each frame of MJPEG video from the driver,
// and displays it in a device context.  This thread is started
// by the StartStreaming function.
//
DWORD WINAPI ReadFrameThread (PVOID pArg)
{
	int rc = 0;
	BOOL f;
	DWORD dwBytes;
	THREADSTRUCT Thd;
	FORMATPROPS fmtData;
	int nFrameCnt = 0;
	DWORD dwTick = 0;
	DWORD dwErr = 0;

	DEBUGMSG (1, (TEXT ("ReadFrameThread++\r\n")));

	if (!pArg)
		return -1;

	// Copy over params
	Thd = *(PTHREADSTRUCT)pArg;
	LocalFree (pArg);
	
	// Get information about the format
	rc = GetFormatInformation (Thd.wFormat, Thd.wFrame, &fmtData);

	if (rc) 
	{
		printf ("Failure to get format data rc = %d\r\n", rc);
		return rc;
	}
	printf ("Format       %d\r\n", fmtData.wFormatType);
	printf ("dwWidth      %d\r\n", fmtData.dwWidth);
	printf ("dwHeight     %d\r\n", fmtData.dwHeight);
	printf ("dwMaxBuff    %d\r\n", fmtData.dwMaxBuff);
	printf ("nNumInterval %d\r\n", fmtData.nNumInterval);


	// Initialize the conversion library
	rc = InitDisplayFrame (NULL);

	RECT rect;
	// See if the caller wants to just specify position and not size
	if ((Thd.rect.right == 0) && (Thd.rect.bottom == 0))
	{
// If debugging, make room for framerate
#ifdef DEBUG
		SetRect (&rect, Thd.rect.left, Thd.rect.top + 30, 
		         Thd.rect.left + fmtData.dwWidth, Thd.rect.top + 30 + fmtData.dwHeight);
#else
		SetRect (&rect, Thd.rect.left, Thd.rect.top, 
		         Thd.rect.left + fmtData.dwWidth, Thd.rect.top + fmtData.dwHeight);
#endif
	}
	else
		rect = Thd.rect;

	// Parameters needed to start a stream
	STARTVIDSTRUCT svStruct;
	dwBytes = 0;
	svStruct.cbSize = sizeof (STARTVIDSTRUCT);
	svStruct.wFormat = Thd.wFormat;
	svStruct.wFrame = Thd.wFrame;
	svStruct.dwInterval = Thd.dwInterval;
	svStruct.dwNumBuffs = NUMBUFFS;
	svStruct.dwPreBuffSize = PREBUFFSIZE;
	svStruct.dwPostBuffSize = 0;
	//
	// Start the video stream
	//
	f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_STARTVIDEOSTREAM, 
				         (LPVOID)&svStruct, sizeof (STARTVIDSTRUCT), 
						 0, 0, &dwBytes, NULL);

	printf ("deviceioctl IOCTL_CAMERA_DEVICE_STARTVIDEOSTREAM returned %d.  dwBytes:%d\r\n", f, dwBytes);
	if (f)
	{
		// Call the driver for a frame
		GETFRAMESTRUCT gfsIn;
		GETFRAMESTRUCTOUT gfsOut;

		memset (&gfsIn, 0, sizeof (GETFRAMESTRUCT));
		gfsIn.cbSize = sizeof (GETFRAMESTRUCT);
		gfsIn.dwFlags = GETFRAMEFLAG_GET_LATESTFRAME;
		gfsIn.dwFlags |= GETFRAMEFLAG_TIMEOUT_VALID;
		gfsIn.dwTimeout = 10000;
		
		memset (&gfsOut, 0, sizeof (GETFRAMESTRUCTOUT));
		gfsOut.cbSize = sizeof (GETFRAMESTRUCTOUT);

		// Get the next frame of video
		f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME, 
					         &gfsIn, sizeof (GETFRAMESTRUCT), 
							 &gfsOut, sizeof(GETFRAMESTRUCTOUT), &dwBytes, NULL);
		printf ("deviceioctl IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME returned %d.  dwBytes:%d\r\n", f, dwBytes);
		fCont = f;
		while (fCont)
		{
			nFrameCnt++;
			if (fDraw)
			{
				// Draw frame in HDC
				rc = DisplayFrame (gfsOut.pFrameData, PREBUFFSIZE, gfsOut.dwFrameSize, Thd.hdc, &rect);
				if (rc) dwErr++;
				DEBUGMSG (ZONE_TIMING, (TEXT ("DisplayFrame-- %d mS to draw\r\n"), GetTickCount() - dwTick));
			}
#ifdef DEBUG
			{
				TCHAR sz[128];
				DWORD dwElapsed = GetTickCount() - dwTick;
				if (dwElapsed == 0) dwElapsed++;
				wsprintf (sz, TEXT("%3d x %3d  Frame rate  %4d fps   Missed Frames %2d  Errors %3d%%                "), 
				          fmtData.dwWidth, fmtData.dwHeight, 1000/dwElapsed, gfsOut.dwMissedFrames-1, 
						  (dwErr*100)/nFrameCnt);

				ExtTextOut (Thd.hdc, Thd.rect.left+5, Thd.rect.top + 2, ETO_OPAQUE, NULL, sz, lstrlen (sz), 0);
			}
#endif
			dwTick = GetTickCount();

			gfsIn.dwFlags = GETFRAMEFLAG_GET_LATESTFRAME | GETFRAMEFLAG_FREEBUFF_VALID;
			gfsIn.pFrameDataRet = gfsOut.pFrameData;
			gfsIn.dwFlags |= GETFRAMEFLAG_TIMEOUT_VALID;
			gfsIn.dwTimeout = 10000;

			// Call the driver
			f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME, 
						         &gfsIn, sizeof (GETFRAMESTRUCT), 
								 &gfsOut, sizeof(GETFRAMESTRUCTOUT), &dwBytes, NULL);
			if (!f)
			{
				printf ("deviceioctl IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME returned %d.  dwBytes:%d\r\n", f, dwBytes);
				fCont = FALSE;
			}
		}
		//
		// Stop the stream
		//
		f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_STOPVIDEOSTREAM, 
					         0, 0, 0, 0, &dwBytes, NULL);
	}
	else
	{
		printf ("failure calling IOCTL_CAMERA_DEVICE_STARTVIDEOSTREAM rc %d\r\n", GetLastError());
		fCont = FALSE;
	}
	// Clean up translation code
	ReleaseDisplayFrame ();

	DEBUGMSG (1, (TEXT ("ReadFrameThread--\r\n")));
	return 0;
}

//----------------------------------------------------------------------
// GetStillImage - Returns a still from the driver
//
int GetStillImage (WORD wFormat, WORD wFrame, PFORMATPROPS pFmt, PBYTE *ppData, DWORD *pdwSize)
{
	int rc = 0;

	VIDFORMATSTRUCT vf;
	DWORD dwBytes, dwBuff;
	BOOL f;

	memset (&vf, 0, sizeof (vf));
	vf.cbSize = sizeof (VIDFORMATSTRUCT);
	vf.wFormat = wFormat;
	vf.wFrame = wFrame;

	*pdwSize = 0;

	// See if we should allocate the buffer
	if (*ppData == 0)
	{
		// Call to get the size of the buffer
		f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_GETSTILLIMAGE, 
							 &vf, sizeof (VIDFORMATSTRUCT), 0, 0, &dwBytes, NULL);
		if (!f)
		{
			rc = GetLastError();
			printf ("failure calling IOCTL_CAMERA_DEVICE_GETSTILLIMAGE rc %d\r\n", rc);
			return rc;
		}

		// Allocate the buffer
		*ppData = (PBYTE) LocalAlloc (LPTR, dwBytes);
		if (*ppData == 0)
			return ERROR_NOT_ENOUGH_MEMORY;
		dwBuff = dwBytes;

	}
	// Call to get the image
	f = DeviceIoControl (hCam, IOCTL_CAMERA_DEVICE_GETSTILLIMAGE, 
						 &vf, sizeof (VIDFORMATSTRUCT), *ppData, dwBuff, &dwBytes, NULL);
	if (!f)
	{
		rc = GetLastError();
		printf ("failure calling IOCTL_CAMERA_DEVICE_GETSTILLIMAGE rc %d\r\n", rc);
	} else
		*pdwSize = dwBytes;


	printf ("deviceioctl IOCTL_CAMERA_DEVICE_GETNEXTVIDEOFRAME returned %d.  dwBytes:%d\r\n", f, dwBytes);
	return rc;
}
//----------------------------------------------------------------------
//
//
int AllocMMObject (int nSize, PMMOBJSTRUCT obj)
{
	if ((obj == 0) || (nSize == 0))
		return ERROR_INVALID_PARAMETER;

	obj->h = CreateFileMapping ((HANDLE)-1, NULL, PAGE_READWRITE | SEC_COMMIT,
	                            0, nSize, NULL);
	if (obj->h == 0)
		return GetLastError();
	obj->p = (PBYTE)MapViewOfFile (obj->h, FILE_MAP_WRITE, 0, 0, 0);
	if (obj->h == 0)
	{
		CloseHandle (obj->h);
		return GetLastError();
	}
	return 0;
}
//----------------------------------------------------------------------
//
//
int FreeMMObject (PMMOBJSTRUCT obj)
{
	if (obj == 0)
		return ERROR_INVALID_PARAMETER;

	UnmapViewOfFile (obj->p);
	CloseHandle (obj->h);
	return 0;
}
//-------------------------------------------------------------------------
// Writes a MJPEG frame as a JPEG file
//
int WriteJPEG (LPTSTR lpszName, PBYTE pData, int nSize)
{
	BYTE MJPGDHTSeg[0x1A4] = {
	 /* JPEG DHT Segment for YCrCb omitted from MJPG data */
	0xFF,0xC4,0x01,0xA2,
	0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,
	0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
	0x08,0x09,0x0A,0x0B,0x10,0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,
	0x00,0x01,0x7D,0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,
	0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
	0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,0x2A,0x34,
	0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
	0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
	0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
	0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
	0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
	0xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
	0xF8,0xF9,0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
	0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
	0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,0x15,0x62,
	0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,0x27,0x28,0x29,0x2A,
	0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
	0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
	0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
	0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,
	0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
	0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
	0xF9,0xFA
	};
	int rc = 0;
	DWORD dwBytes;

	HANDLE hFile = CreateFile (lpszName, GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		BYTE bHdr[] = 
		{
					  0xff,0xd8,				// SOI
					  0xff,0xe0,				// APP0
					  0x00,0x10,				// APP0 Hdr size
					  0x4a,0x46,0x49,0x46,0x00, // ID string
					  0x01,0x01,				// Version
					  0x00,						// Bits per type
					  0x00, 0x00,				// X density
					  0x00, 0x00,				// Y density
					  0x00,						// X Thumbnail size
					  0x00,						// Y Thumbnail size
		};
		WriteFile (hFile, bHdr, sizeof (bHdr), &dwBytes, NULL);

		// Write DHT color segment needed for stand-alone file
		WriteFile (hFile, MJPGDHTSeg, sizeof (MJPGDHTSeg), &dwBytes, NULL);
		
		// try removing AVI header from image
#if 1
		int n = *(pData+4);
		n = n << 8;
		n += *(pData+5)+4;
		PBYTE p2 = pData + n;
		WriteFile (hFile, p2, nSize-n, &dwBytes, NULL);
#else
		WriteFile (hFile, pData, nSize, &dwBytes, NULL);
#endif
		DEBUGMSG (1, (TEXT("Write %d bytes to image file.\r\n"), dwBytes));

		CloseHandle (hFile);
	} else
		rc = GetLastError();
	return rc;
}

⌨️ 快捷键说明

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