////////////////////////////////////////////////////////////////
// File - WebCamII.C
//
// This is a diagnostics application for accessing the WebCamII
// USB Camera.
// It accesses the hardware via WinDriver functions.
//
// Copyrights (c) Jungo Ltd. 2000
// Written by Nir Borenshtein
////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <time.h>
#include "cpia.h"
#include "screen_lib.h"
#include "usb_diag_lib.h"
// Input of command from user
static char line [4096];
DWORD g_unique_id;
typedef BOOL (*GRAB_FRAME_FUNC)(PVOID pBuffer, FRAME_INFO frameInfo, BOOL first_time, BOOL last_time);
typedef BOOL (*CONVERT_YUV2RGB_FUNC)(PVOID pYCrCb_Buffer, BYTE *pBGR_Buffer, FRAME_INFO frameInfo);
typedef BOOL (*DRAW_PIC_FUNC)(PVOID pBuffer, FRAME_INFO frameInfo, BOOL first_time, BOOL last_time);
typedef struct
{
GRAB_FRAME_FUNC grab_frame_func;
CONVERT_YUV2RGB_FUNC convert_yuv2rgb_func;
DRAW_PIC_FUNC draw_pic_func;
FRAME_INFO frameInfo;
BOOL fStopped;
HANDLE hThread;
} THREAD_DATA;
// Thread functions
void DrawPicturesOnScreen(THREAD_DATA *pContGrab);
DWORD WINAPI DrawPicturesHandler(void *pParam);
void StopDrawing(THREAD_DATA *pContGrab);
int main(int argc, char *argv[])
{
UINT cmd;
PVOID pYCrCb_Buffer = NULL;
BYTE *pBGR_Buffer = NULL;
FRAME_INFO frameInfo;
DWORD data_type;
char path[255];
do
{
printf ("\n");
printf ("WebCamII Main Menu\n");
printf ("------------------\n");
printf ("1. Scan for USB Devices.\n");
printf ("2. Grab Frame.\n");
printf ("3. Store Frame Data on disk.\n");
printf ("4. Continues Grabing.\n");
printf ("99. Exit.\n");
printf ("Enter option: ");
cmd = 0;
gets(line);
sscanf (line, "%d", &cmd);
switch (cmd)
{
case 1:
USB_Print_device_info(0,0);
break;
case 2:
printf ("Please enter type of frame you want to grab - QCIF/CIF (0/1): ");
gets(line);
sscanf (line, "%x", &frameInfo.frameType);
printf ("\n");
if ((frameInfo.frameType > 1) || (frameInfo.frameType < 0))
{
printf("Invalid Frame Type\n");
break;
}
if (!g_unique_id)
{
printf ("Please enter the uniqueId of the camera: ");
gets(line);
sscanf (line, "%d", &g_unique_id);
printf ("\n");
}
frameInfo.uniqueId = g_unique_id;
// Free locked memory
if (pYCrCb_Buffer)
free(pYCrCb_Buffer);
pYCrCb_Buffer = NULL;
if (pBGR_Buffer)
free(pBGR_Buffer);
pBGR_Buffer = NULL;
if (frameInfo.frameType == QCIF)
{
frameInfo.frameType = QCIF;
frameInfo.dwBuffSize = QCIF_BUFFER_SIZE;
frameInfo.dwBytesInLine = QCIF_BYTES_IN_LINE;
frameInfo.frameRowNum = QCIF_ROW_NUM;
frameInfo.frameColNum = QCIF_COL_NUM;
if(!(pYCrCb_Buffer = malloc(QCIF_BUFFER_SIZE)))
{
printf("Failed allocating QCIF buffer\n");
break;
}
}
else
{
frameInfo.frameType = CIF;
frameInfo.dwBuffSize = CIF_BUFFER_SIZE;
frameInfo.dwBytesInLine = CIF_BYTES_IN_LINE;
frameInfo.frameRowNum = CIF_ROW_NUM;
frameInfo.frameColNum = CIF_COL_NUM;
if(!(pYCrCb_Buffer = malloc(CIF_BUFFER_SIZE)))
{
printf("Failed allocating CIF buffer\n");
break;
}
}
frameInfo.subSample = SS_422;
printf("Grabbing frame, please wait ...\n");
if (!GrabFrame(pYCrCb_Buffer, frameInfo, TRUE, TRUE))
{
printf("Could not grab a frame!\n");
if (!pYCrCb_Buffer)
free(pYCrCb_Buffer);
pYCrCb_Buffer = NULL;
g_unique_id = 0;
break;
}
printf("Operation ended succesfuly.\n");
printf("Converting data, please wait ...\n");
pBGR_Buffer = (BYTE *)malloc(sizeof(DWORD) * frameInfo.frameRowNum * frameInfo.frameColNum);
if (!pBGR_Buffer)
{
printf("Failed allocating BGR buffer\n");
free(pYCrCb_Buffer);
pYCrCb_Buffer = NULL;
break;
}
if (!ConvertYUV2RGB(pYCrCb_Buffer, pBGR_Buffer, frameInfo))
{
printf("Error was detected while conversion\n");
if (pBGR_Buffer)
free(pBGR_Buffer);
pBGR_Buffer = NULL;
if (pYCrCb_Buffer)
free(pYCrCb_Buffer);
pYCrCb_Buffer = NULL;
break;
}
printf("Operation ended succesfuly.\n");
printf("Printing data, please wait ...\n");
DrawPicture(pBGR_Buffer, frameInfo, TRUE, TRUE);
printf("Operation ended succesfuly.\n");
break;
case 3:
BZERO(path);
printf ("Which kind of data do you want to store - YCrCb/RGB (0/1): ");
gets(line);
sscanf (line, "%x", &data_type);
printf ("\n");
if ((data_type < 0) || (data_type > 1))
{
printf("Invalid data type\n");
break;
}
printf ("Please enter path with file name: ");
gets(line);
sscanf (line, "%s", &path);
printf ("\n");
if (path)
{
if (data_type == 0)
{
if (pYCrCb_Buffer)
StoreFrameOnFile(pYCrCb_Buffer, frameInfo.dwBuffSize, path);
else
printf("buffer is empty\n");
}
else
{
if (pBGR_Buffer)
StoreFrameOnFile(pBGR_Buffer, frameInfo.dwBuffSize, path);
else
printf("buffer is empty\n");
}
}
break;
case 4:
{
THREAD_DATA contGrab;
BYTE c;
BZERO(contGrab);
if (!g_unique_id)
{
printf ("Please enter the uniqueId of the camera: ");
gets(line);
sscanf (line, "%d", &g_unique_id);
printf ("\n");
}
contGrab.frameInfo.uniqueId = g_unique_id;
contGrab.frameInfo.frameType = QCIF;
contGrab.frameInfo.dwBuffSize = QCIF_BUFFER_SIZE;
contGrab.frameInfo.dwBytesInLine = QCIF_BYTES_IN_LINE;
contGrab.frameInfo.frameRowNum = QCIF_ROW_NUM;
contGrab.frameInfo.frameColNum = QCIF_COL_NUM;
contGrab.frameInfo.subSample = SS_422;
contGrab.grab_frame_func = GrabFrame;
contGrab.convert_yuv2rgb_func = ConvertYUV2RGB;
contGrab.draw_pic_func = DrawPicture;
printf ("Press <Enter> to start drawing. While drawing, press <Enter> to stop\n\n");
getchar();
DrawPicturesOnScreen(&contGrab);
while ((c=getchar()) != 10) {} // ESC code
StopDrawing(&contGrab);
break;
}
break;
}
} while (cmd!=99);
if (pYCrCb_Buffer)
free(pYCrCb_Buffer);
if (pBGR_Buffer)
free(pBGR_Buffer);
return 0;
}
void StopDrawing(THREAD_DATA *pContGrab)
{
WD_USB_TRANSFER transfer;
BZERO(transfer);
if (!pContGrab->hThread)
return;
printf("Stop drawing pictures\n");
pContGrab->fStopped = TRUE;
WaitForSingleObject(pContGrab->hThread, INFINITE);
CloseHandle(pContGrab->hThread);
pContGrab->hThread = NULL;
}
DWORD WINAPI DrawPicturesHandler(void *pParam)
{
THREAD_DATA *pContGrab = (THREAD_DATA*) pParam;
PVOID pYCrCb_Buffer = NULL;
BYTE *pBGR_Buffer = NULL;
DWORD rc;
BOOL first = TRUE;
BOOL last = FALSE;
DWORD count = 0;
time_t start_time, end_time;
DWORD secs;
if(!(pYCrCb_Buffer = malloc(pContGrab->frameInfo.dwBuffSize)))
{
printf("Failed allocating YUV buffer\n");
rc = 1;
goto Exit;
}
pBGR_Buffer = (BYTE *)malloc(sizeof(DWORD) * pContGrab->frameInfo.frameRowNum * pContGrab->frameInfo.frameColNum);
if (!pBGR_Buffer)
{
printf("Failed allocating BGR buffer\n");
rc = 1;
goto Exit;
}
time(&start_time);
for (;!last;)
{
count++;
if(pContGrab->fStopped)
last = TRUE;
if (!pContGrab->grab_frame_func(pYCrCb_Buffer, pContGrab->frameInfo, first, last))
{
printf("Could not grab a frame!\n");
g_unique_id = 0;
goto Exit;
break;
}
if (!pContGrab->convert_yuv2rgb_func(pYCrCb_Buffer, pBGR_Buffer, pContGrab->frameInfo))
{
printf("Error was detected while conversion\n");
goto Exit;
break;
}
pContGrab->draw_pic_func(pBGR_Buffer, pContGrab->frameInfo, first, last);
first = FALSE;
}
time(&end_time);
secs = end_time - start_time;
printf("worked %d seconds, showed %d pictures. %d.%02d pics/seconds\n",
secs, count, count/secs, ((count*100)/secs % 100));
rc = 0;
Exit:
if (pYCrCb_Buffer)
free(pYCrCb_Buffer);
if (pBGR_Buffer)
free(pBGR_Buffer);
return rc;
}
void DrawPicturesOnScreen(THREAD_DATA *pContGrab)
{
// Start the running thread
DWORD threadId;
pContGrab->fStopped = FALSE;
printf("Start drawing pictures\n");
pContGrab->hThread = CreateThread (0, 0x1000, DrawPicturesHandler,
(PVOID)pContGrab, 0, &threadId);
}