home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_03_03 / 3n03043a < prev    next >
Text File  |  1992-01-28  |  14KB  |  482 lines

  1. // Listing 1 (video.c)
  2.  
  3. #include <windows.h>
  4. #include "avkapi.h"
  5.  
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9.  
  10. //-----------------------------------------------------
  11. // Misc constants
  12. //-----------------------------------------------------
  13. #define   BOARD_NUM         0   // AVK board number
  14. #define   STREAM_XRES     256   // X Resolution of Stream
  15. #define   STREAM_YRES     240   // Y Resolution of Stream
  16. #define   VIEW_XRES       256   // X Resolution of View
  17. #define   VIEW_YRES       240   // Y Resolution of View
  18. #define   STREAM_CT         1   // Number of streams in buffer
  19. #define   STREAM_INDEX      0   // Index of stream in buffer
  20. #define   BUF_SIZE      65536L  // Size of AVK buffer
  21. #define   EMPTY_LEVEL   32768L  // Level which triggers
  22.                                 // buffer empty message
  23.  
  24. // Macro to check AVK error returns and report errors
  25. #define RETURN_IF_AVK_ERROR(ret)      \
  26.     if (ret != AVK_ERR_OK)            \
  27.       {                               \
  28.       ReportAvkError(ret, __LINE__);  \
  29.       return ret;                     \
  30.       }
  31.  
  32. //-----------------------------------------------------
  33. // Function prototypes
  34. //-----------------------------------------------------
  35. long FAR PASCAL WndProc(HWND, WORD, WORD, LONG);
  36. int InitAvk(HWND hwnd);
  37. int CreateView(void);
  38. int CreateGroup(void);
  39. int CreateConnectors(void);
  40. int TurnOnAudio(void);
  41. int FormatVideoStream(void);
  42. int LoadAlgData(void);
  43. void GuiRectToView(RECT *GuiRect, RECT *ViewRect);
  44. void StopAvk(void);
  45. int EnableConnector(HAVK ConnHandle);
  46. int DisableConnector(HAVK ConnHandle);
  47. int MoveConnector(HWND hwnd);
  48. void GetAbsoluteClientRect(HWND hWnd, RECT *pRect);
  49. void ReportAvkError(int Error, int LineNo);
  50. BOX *RectToBox(RECT *pRect, BOX *pBox);
  51.  
  52. //-----------------------------------------------------
  53. // Module global data
  54. //-----------------------------------------------------
  55. HANDLE  hInstance;
  56.  
  57. HAVK    hAvkSess;       // AVK session handle
  58. HAVK    hDev;           // AVK Device handle
  59. HAVK    hView;          // AVK View handle
  60. HAVK    hGrp;           // AVK Group handle
  61. HAVK    hGrpBuf;        // AVK Group Buffer handle
  62. HAVK    hVidStream;     // AVK Video Stream handle
  63.  
  64. HAVK    hDigiToStrmConn;  // AVK Digitizer to Stream
  65.                           // connector handle
  66. HAVK    hStrmToViewConn;  // AVK Stream to View
  67.                           // connector handle
  68.  
  69. int     GuiXRes;        // X Resolution of Windows screen
  70. int     GuiYRes;        // Y Resolution of Windows screen
  71.  
  72. void    *pVideoAlgData;   // Ptr to Video Algorithm data
  73. unsigned int LenVideoAlgData;
  74.  
  75. //-----------------------------------------------------
  76. // WinMain
  77. //-----------------------------------------------------
  78. int PASCAL WinMain(HANDLE hInst, HANDLE hPrevInstance,
  79.   LPSTR lpszCmdParam, int nCmdShow)
  80.   {
  81.   char szAppName[] = "Live Video";
  82.   HWND    hwnd;
  83.   MSG     msg;
  84.   WNDCLASS  wc;
  85.  
  86.   hInstance = hInst;
  87.   if (!hPrevInstance)
  88.     {
  89.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  90.     wc.lpfnWndProc   = WndProc;
  91.     wc.cbClsExtra    = 0;
  92.     wc.cbWndExtra    = 0;
  93.     wc.hInstance     = hInstance;
  94.     wc.hIcon         = NULL;
  95.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  96.     wc.hbrBackground = GetStockObject(BLACK_BRUSH);
  97.     wc.lpszMenuName  = NULL;
  98.     wc.lpszClassName = szAppName;
  99.     RegisterClass(&wc);
  100.     }
  101.   else
  102.     {
  103.     MessageBox(GetFocus(),
  104.       "Live Video is already active", NULL, MB_OK);
  105.     return 0;
  106.     }
  107.  
  108.   GuiXRes = GetSystemMetrics(SM_CXSCREEN);
  109.   GuiYRes = GetSystemMetrics(SM_CYSCREEN);
  110.  
  111.   hwnd = CreateWindow(szAppName, szAppName,
  112.         WS_OVERLAPPEDWINDOW,
  113.         CW_USEDEFAULT,
  114.         CW_USEDEFAULT,
  115.         CW_USEDEFAULT,
  116.         CW_USEDEFAULT,
  117.         NULL,               // No Parent
  118.         NULL,               // No menu
  119.         hInstance,
  120.         NULL);
  121.  
  122.  
  123.   ShowWindow(hwnd, nCmdShow);
  124.   UpdateWindow(hwnd);
  125.  
  126.   while(GetMessage(&msg, NULL, 0, 0))
  127.     {
  128.     TranslateMessage(&msg);
  129.     DispatchMessage(&msg);
  130.     }
  131.   return msg.wParam;
  132.   }
  133.  
  134. //-----------------------------------------------------
  135. long FAR PASCAL WndProc(HWND hwnd, WORD message,
  136.   WORD wParam, LONG lParam)
  137.   {
  138.   PAINTSTRUCT ps;
  139.  
  140.   // If the message is from AVK, ignore it
  141.   if (message >= AVK_MSG_LOW && message <= AVK_MSG_HIGH)
  142.     return(0);
  143.  
  144.   switch(message)
  145.     {
  146.     case WM_CREATE:
  147.       if (InitAvk(hwnd)       != AVK_ERR_OK ||
  148.           CreateView()        != AVK_ERR_OK ||
  149.           CreateGroup()       != AVK_ERR_OK ||
  150.           CreateConnectors()  != AVK_ERR_OK ||
  151.           TurnOnAudio()       != AVK_ERR_OK)
  152.         DestroyWindow(hwnd);
  153.       return 0;
  154.  
  155.     case WM_PAINT:
  156.       BeginPaint(hwnd, &ps);
  157.       EndPaint(hwnd, &ps);
  158.       return 0;
  159.  
  160.     case WM_MOVE:
  161.     case WM_SIZE:
  162.       MoveConnector(hwnd);
  163.       InvalidateRect(hwnd, NULL, 1);
  164.       break;
  165.  
  166.     case WM_SHOWWINDOW:
  167.       EnableConnector(hDigiToStrmConn);
  168.       EnableConnector(hStrmToViewConn);
  169.       break;
  170.  
  171.     case WM_DESTROY:
  172.       // Free algorithm data if allocated.
  173.       if (pVideoAlgData)
  174.         free(pVideoAlgData);
  175.       StopAvk();
  176.       PostQuitMessage(0);
  177.       return 0;
  178.     }
  179.   return DefWindowProc(hwnd, message, wParam, lParam);
  180.   }
  181.  
  182.  
  183. //-----------------------------------------------------
  184. // Open an AVK session and device (board)
  185. //-----------------------------------------------------
  186. int InitAvk(HWND hwnd)
  187.   {
  188.   int rv;
  189.  
  190.   rv = AvkBeginMsg(hwnd, &hAvkSess, AVK_SESSION_DEFAULT);
  191.   RETURN_IF_AVK_ERROR(rv);
  192.   rv = AvkDeviceOpen(hAvkSess, BOARD_NUM,
  193.     AVK_DEV_OPEN_EXCLUSIVE, &hDev);
  194.   RETURN_IF_AVK_ERROR(rv);
  195.   return AVK_ERR_OK;
  196.   }
  197.  
  198. //-----------------------------------------------------
  199. // Create and display an AVK View
  200. //-----------------------------------------------------
  201. int CreateView(void)
  202.   {
  203.   int rv;
  204.  
  205.   rv = AvkViewCreate(hDev, VIEW_XRES, VIEW_YRES, AVK_YUV9,
  206.     AVK_VID_VGA_KEYED, &hView);
  207.   RETURN_IF_AVK_ERROR(rv);
  208.  
  209.   rv = AvkViewDisplay(hDev, hView,
  210.     AVK_TIME_IMMEDIATE, AVK_VIEW_DISPLAY_DEFAULT);
  211.   RETURN_IF_AVK_ERROR(rv);
  212.  
  213.   return AVK_ERR_OK;
  214.   }
  215.  
  216. //-----------------------------------------------------
  217. // Create AVK Group, Buffer, and Stream
  218. //-----------------------------------------------------
  219. int CreateGroup(void)
  220.   {
  221.   int rv;
  222.  
  223.   rv = AvkGrpCreate(hDev, &hGrp);
  224.   RETURN_IF_AVK_ERROR(rv);
  225.  
  226.   rv = AvkGrpBufCreate(hGrp, AVK_BUF_CAPTURE, BUF_SIZE,
  227.     EMPTY_LEVEL, STREAM_CT, &hGrpBuf);
  228.   RETURN_IF_AVK_ERROR(rv);
  229.  
  230.   rv = AvkVidStrmCreate(hGrpBuf, STREAM_INDEX, &hVidStream);
  231.   RETURN_IF_AVK_ERROR(rv);
  232.  
  233.   rv = FormatVideoStream();
  234.   return rv;
  235.   }
  236.  
  237. //-----------------------------------------------------
  238. // Create all required connectors
  239. //-----------------------------------------------------
  240. int CreateConnectors(void)
  241.   {
  242.   int rv;
  243.   BOX Box;
  244.  
  245.   Box.x1 = Box.y1 = 0;
  246.   Box.x2 = STREAM_XRES - 1;
  247.   Box.y2 = STREAM_YRES - 1;
  248.   rv = AvkConnCreate(AVK_CONN_DIGITIZER, NULL, hVidStream,
  249.     NULL, 0, &hDigiToStrmConn);
  250.   RETURN_IF_AVK_ERROR(rv);
  251.  
  252.   rv = AvkConnCreate(hVidStream, NULL, hView, NULL,
  253.     AVK_PRE_MONITOR, &hStrmToViewConn);
  254.   RETURN_IF_AVK_ERROR(rv);
  255.  
  256.   return AVK_ERR_OK;
  257.   }
  258.  
  259. //-----------------------------------------------------
  260. // Turn on Audio monitoring
  261. //-----------------------------------------------------
  262. int TurnOnAudio(void)
  263.   {
  264.   int rv;
  265.  
  266.   rv = AvkDeviceAudioIn(hDev, AVK_CD_LINE, AVK_MONITOR_ON);
  267.   RETURN_IF_AVK_ERROR(rv);
  268.   return AVK_ERR_OK;
  269.   }
  270.  
  271. //-----------------------------------------------------
  272. // Format a video stream
  273. //-----------------------------------------------------
  274. int FormatVideoStream(void)
  275.   {
  276.   int rv;
  277.   AVK_RTV_20_ENCODE_ARGS RtvArgs = AVK_RTV_20_DEFAULT_ARGS;
  278.  
  279.   // Fetch parameter data for video algorithm
  280.   if (!LoadAlgData())
  281.     return -1;
  282.  
  283.   // Build appropriate data structure for algorithm
  284.   // Use the defaults from the initialization for most fields
  285.   RtvArgs.xLen = STREAM_XRES;
  286.   RtvArgs.yLen = STREAM_YRES;
  287.   RtvArgs.Flags = AVK_RTV_20_PREFILTER | AVK_RTV_20_ASPECT_25;
  288.  
  289.   // Format stream
  290.   rv = AvkVidStrmFormat(hVidStream, 6, STREAM_XRES,
  291.     STREAM_YRES, AVK_YUV9, 33367, AVK_RTV_2_0,
  292.     (char far *)&RtvArgs, sizeof(RtvArgs), sizeof(RtvArgs), 
  293.     pVideoAlgData, LenVideoAlgData, 65536L);
  294.   RETURN_IF_AVK_ERROR(rv);
  295.  
  296.   return AVK_ERR_OK;
  297.   }
  298.  
  299. //-----------------------------------------------------
  300. // Read the video algorithm data from disk
  301. //-----------------------------------------------------
  302. int LoadAlgData(void)
  303.   {
  304.   int fh;
  305.   int LoadOK = FALSE;
  306.   char *Filename = "KE080200.VSH";
  307.  
  308.   // Note that the size of the VSH file is guaranteed to
  309.   // be less than 64k bytes.
  310.   fh = _lopen(Filename, OF_READ);
  311.   if (fh != -1)
  312.     {
  313.     unsigned int FileLen = (unsigned int)_llseek(fh, 0, 2);
  314.  
  315.     LenVideoAlgData = FileLen;
  316.     pVideoAlgData = malloc(FileLen);
  317.     if (pVideoAlgData)
  318.       {
  319.       _llseek(fh, 0, 0);
  320.       if (_lread(fh, pVideoAlgData, FileLen) == FileLen)
  321.         LoadOK = TRUE;
  322.       }
  323.     _lclose(fh);
  324.     }
  325.  
  326.   if (!LoadOK)
  327.     {
  328.     char msg[100];
  329.     sprintf(msg,
  330.       "Error loading Algorithm data from file %s", Filename);
  331.     MessageBox(GetFocus(), msg, "Video Alg Data Load Error",
  332.       MB_ICONSTOP | MB_OK);
  333.     }
  334.   return LoadOK;
  335.   }
  336.  
  337. //-----------------------------------------------------
  338. // GuiRectToView - Converts a RECT specified in System
  339. // Display Screen coordinates to VIEW bitmap coordinates.
  340. //-----------------------------------------------------
  341. void GuiRectToView(RECT *GuiRect, RECT *ViewRect)
  342.   {
  343.   // Prevent negative coordinate conversion
  344.   if (GuiRect->top  < 0) GuiRect->top  = 0;
  345.   if (GuiRect->left < 0) GuiRect->left = 0;
  346.   ViewRect->left   = (int)(((long)GuiRect->left   *
  347.                       VIEW_XRES) / GuiXRes);
  348.   ViewRect->right  = (int)(((long)GuiRect->right  *
  349.                       VIEW_XRES) / GuiXRes);
  350.   ViewRect->top    = (int)(((long)GuiRect->top    *
  351.                       VIEW_YRES) / GuiYRes);
  352.   ViewRect->bottom = (int)(((long)GuiRect->bottom *
  353.                       VIEW_YRES) / GuiYRes);
  354.   }
  355.  
  356. //-----------------------------------------------------
  357. // Shutdown all AVK activity
  358. //-----------------------------------------------------
  359. void StopAvk(void)
  360.   {
  361.   DisableConnector(hDigiToStrmConn);
  362.   DisableConnector(hStrmToViewConn);
  363.  
  364.   AvkDeviceClose(hDev);
  365.   AvkEnd(hAvkSess);
  366.   }
  367.  
  368. //-----------------------------------------------------
  369. // Enables a single connector with error checking
  370. //-----------------------------------------------------
  371. int EnableConnector(HAVK hConn)
  372.   {
  373.   int rv;
  374.  
  375.   if (hConn == 0)
  376.     return AVK_ERR_OK;
  377.  
  378.   rv = AvkConnEnable(hConn, AVK_TIME_IMMEDIATE);
  379.   RETURN_IF_AVK_ERROR(rv);
  380.  
  381.   return AVK_ERR_OK;
  382.   }
  383.  
  384. //-----------------------------------------------------
  385. // Disables a single connector with error checking
  386. //-----------------------------------------------------
  387. int DisableConnector(HAVK hConn)
  388.   {
  389.   int rv;
  390.  
  391.   if (hConn == 0)
  392.     return AVK_ERR_OK;
  393.  
  394.   rv = AvkConnHide(hConn, AVK_TIME_IMMEDIATE);
  395.   RETURN_IF_AVK_ERROR(rv);
  396.  
  397.   return AVK_ERR_OK;
  398.   }
  399.  
  400. //-----------------------------------------------------
  401. // Moves a connector in response to WM_MOVE and WM_SIZE
  402. // messages.
  403. //-----------------------------------------------------
  404. int MoveConnector(HWND hwnd)
  405.   {
  406.   RECT RectGui;
  407.   RECT RectDvi;
  408.   BOX BoxDvi;
  409.   int rv;
  410.  
  411.   // Get screen location of client area and convert to DVI
  412.   GetAbsoluteClientRect(hwnd, &RectGui);
  413.   GuiRectToView(&RectGui, &RectDvi);
  414.  
  415.   // Limit connector to resolution of VIEW
  416.   if (RectDvi.top    >= VIEW_YRES)
  417.     RectDvi.top    = VIEW_YRES - 1;
  418.   if (RectDvi.bottom >= VIEW_YRES)
  419.     RectDvi.bottom = VIEW_YRES - 1;
  420.   if (RectDvi.left   >= VIEW_XRES)
  421.     RectDvi.left   = VIEW_XRES - 1;
  422.   if (RectDvi.right  >= VIEW_XRES)
  423.     RectDvi.right  = VIEW_XRES - 1;
  424.  
  425.   RectToBox(&RectDvi, &BoxDvi);
  426.   DisableConnector(hStrmToViewConn);
  427.   rv = AvkConnModSrcDst(hStrmToViewConn, NULL, &BoxDvi,
  428.     AVK_TIME_IMMEDIATE);
  429.   RETURN_IF_AVK_ERROR(rv);
  430.   EnableConnector(hStrmToViewConn);
  431.  
  432.   return AVK_ERR_OK;
  433.   }
  434.  
  435. //-----------------------------------------------------
  436. // Computes the location of the client area of hwnd in
  437. // absolute GUI coordinates and returns in *pRect.
  438. //-----------------------------------------------------
  439. void GetAbsoluteClientRect(HWND hWnd, RECT *pRect)
  440.   {
  441.   POINT Pt;
  442.  
  443.   GetClientRect(hWnd, pRect);
  444.   Pt.x = pRect->left;
  445.   Pt.y = pRect->top;
  446.   ClientToScreen(hWnd, &Pt);
  447.   pRect->left = Pt.x;
  448.   pRect->top = Pt.y;
  449.  
  450.   Pt.x = pRect->right;
  451.   Pt.y = pRect->bottom;
  452.   ClientToScreen(hWnd, &Pt);
  453.   pRect->right = Pt.x;
  454.   pRect->bottom = Pt.y;
  455.   }
  456.  
  457. //-----------------------------------------------------
  458. // Reports an AVK error to  the screen
  459. //-----------------------------------------------------
  460. void ReportAvkError(int Error, int LineNo)
  461.   {
  462.   char msg[250];
  463.   U16 XErrCode;
  464.  
  465.   AvkGetSubSysErrCode(hAvkSess, (U16 far *)&XErrCode);
  466.   sprintf(msg, "AVK function returned error %d at line %d\n"
  467.     "Subsystem error is %4.4x", Error, LineNo, XErrCode);
  468.   MessageBox(GetFocus(), msg, "AVK Error", MB_OK);
  469.   }
  470.  
  471. //-----------------------------------------------------
  472. // Converts a RECT to a BOX
  473. //-----------------------------------------------------
  474. BOX *RectToBox(RECT *pRect, BOX *pBox)
  475.   {
  476.   pBox->x1 = pRect->left;
  477.   pBox->y1 = pRect->top;
  478.   pBox->x2 = pRect->right;
  479.   pBox->y2 = pRect->bottom;
  480.   return(pBox);
  481.   }
  482.