home *** CD-ROM | disk | FTP | other *** search
/ More Insanity: Totally Insane 2 / totally_insane_ii.iso / src / video_library_buffering / examples / vidtomem_dmbuffer_xplatform.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-29  |  7.9 KB  |  356 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #include <vl/vl.h>
  5.  
  6. #define NBUFFERS 15
  7.  
  8. VLServer svr = NULL;
  9. VLPath VIDtoMEMPath = NULL;
  10. VLNode src = 0, drn = 0;
  11. DMbufferpool pool = NULL;
  12. int transferSize = 0;
  13.  
  14. void cleanupAndExit(int exit_type);
  15.  
  16. int 
  17. createVidToMemPath(VLServer svr, VLPath *path, VLNode *src, VLNode *drn)
  18. {
  19.    /* 
  20.     * Create the memory to video path (just grab the first device 
  21.     * that supports it) 
  22.     */
  23.     *src = vlGetNode(svr, VL_SRC, VL_VIDEO, VL_ANY);
  24.     *drn = vlGetNode(svr, VL_DRN, VL_MEM, VL_ANY);
  25.  
  26.     *path = vlCreatePath(svr, VL_ANY, *src, *drn);
  27.     
  28.     if (*path == -1) return -1;
  29.  
  30.     return 0;
  31. }
  32.  
  33. int 
  34. setVidToMemPathControls(VLServer svr, VLPath path, VLNode src, VLNode drn)
  35. {
  36.     VLControlValue val;
  37.  
  38.    /*
  39.     * Set to 8-bit YUV 4:2:2, SMPTE format
  40.     */
  41.     val.intVal = VL_PACKING_YVYU_422_8;
  42.     if (vlSetControl(svr, path, drn, VL_PACKING, &val) < 0) {
  43.     vlPerror("Unable to set packing");
  44.     return -1;
  45.     }
  46.  
  47.     val.intVal = VL_FORMAT_SMPTE_YUV;
  48.     if (vlSetControl(svr, path, drn, VL_FORMAT, &val) < 0) {
  49.     vlPerror("Unable to set format");
  50.     return -1;
  51.     }
  52.  
  53.    /*
  54.     * Capture non-interleaved (field-based) images
  55.     */
  56.     val.intVal = VL_CAPTURE_NONINTERLEAVED;
  57.     if (vlSetControl(svr, path, drn, VL_CAP_TYPE, &val) < 0) {
  58.     vlPerror("Unable to set noninterleaved capture type");
  59.     return -1;
  60.     }
  61.  
  62.     return 0;
  63. }
  64.  
  65. int
  66. createPool(VLServer svr, VLPath path, VLNode memnode, DMbufferpool *pool)
  67. {
  68.     DMparams *poolParams;
  69.  
  70.     transferSize = vlGetTransferSize(svr, path);
  71.  
  72.     if (dmParamsCreate(&poolParams) != DM_SUCCESS) {
  73.     fprintf(stderr, "Unable to create pool parameter list\n");
  74.     return -1;
  75.     }
  76.  
  77.    /*
  78.     * Set the defaults to a non-cached pool. This is the optimal
  79.     * settings if the CPU will never touch the data, and is equivalent
  80.     * to setting a VL Buffer to "No Access."
  81.     */
  82.     if (dmBufferSetPoolDefaults(poolParams, NBUFFERS, transferSize, DM_TRUE,
  83.     DM_TRUE)  != DM_SUCCESS) {
  84.     fprintf(stderr, "Unable to set pool defaults\n");
  85.         dmParamsDestroy(poolParams);
  86.     return -1;
  87.     }
  88.  
  89.    /*
  90.     * Now query the VL for it's requirements on the pool. If another 
  91.     * library, such as dmIC, will use the pool, it's pool requirements
  92.     * function should be called in addition.
  93.     */
  94.     if (vlDMGetParams(svr, path, memnode, poolParams) < 0) {
  95.     vlPerror("Unable to get VL pool requirements");
  96.     dmParamsDestroy(poolParams);
  97.     return -1;
  98.     }
  99.  
  100.    /*
  101.     * Now we can create the pool
  102.     */
  103.     if (dmBufferCreatePool(poolParams, pool) != DM_SUCCESS) {
  104.     fprintf(stderr, "Unable to create pool\n");
  105.     dmParamsDestroy(poolParams);
  106.     return -1;
  107.     }
  108.  
  109.     dmParamsDestroy(poolParams);
  110.  
  111.     return 0;
  112. }
  113.  
  114. int
  115. process_event(VLEvent *ev)
  116. {
  117.     switch (ev->reason)
  118.     {    
  119.     case VLStreamPreempted:
  120.         fprintf(stderr, "Stream Preempted by another Program\n");
  121.         return -1;
  122.         break;
  123.  
  124.     case VLTransferFailed: 
  125.         fprintf(stderr, "Transfer failed\n");
  126.         return -1;
  127.         break;
  128.     
  129.     case VLTransferComplete:
  130.         fprintf(stderr, "Got Transfer Complete\n");
  131.         break;
  132.  
  133.     default:
  134.         break;
  135.     }
  136.  
  137.     return 0;
  138. }
  139.  
  140. int
  141. process_buffer(VLServer svr, VLPath path, VLNode memnode, DMbuffer buffer)
  142. {
  143.     char *dataArea;
  144.  
  145.    /*
  146.     * Get a pointer to the image contents of the buffer. A real application
  147.     * would do something with it.
  148.     */
  149.     dataArea = dmBufferMapData(buffer);
  150.  
  151.     /* Do something with the image data here */
  152.  
  153.     dmBufferFree(buffer);
  154.  
  155.     printf("Buffer Captured\n");
  156.  
  157.     return 0;
  158. }
  159.  
  160. int
  161. get_server_event(VLServer svr, VLPath path, VLNode memnode)
  162. {
  163.     VLEvent ev;
  164.  
  165.     if (vlCheckEvent(svr, VLAllEventsMask, &ev) == -1) {
  166.     return 0;
  167.     }
  168.  
  169.     return process_event(&ev);
  170. }
  171.  
  172. int
  173. buffer_ready(VLServer svr, VLPath path, VLNode memnode)
  174. {
  175.     DMbuffer buffer;
  176.  
  177.    /*
  178.     * Get the buffer from the VL
  179.     */
  180.     if (vlDMBufferGetValid(svr, path, memnode, &buffer) < 0) {
  181.     if (vlErrno == VLAgain) return 0;
  182.     vlPerror("Unable to get buffer from VL");
  183.     return -1;
  184.     }
  185.  
  186.     return process_buffer(svr, path, memnode, buffer);
  187. }
  188.  
  189. void
  190. main(int argc, char **argv)
  191. {
  192.     int ret;
  193.     VLTransferDescriptor xferDesc;
  194.     int bufferfd, vlfd;
  195.     fd_set readfds, writefds, exceptfds;
  196.     int nfds;
  197.  
  198.    /* 
  199.     * Connect to the video daemon 
  200.     */
  201.     if (!(svr = vlOpenVideo(""))) {
  202.     vlPerror("Couldn't open video");
  203.     cleanupAndExit(1);
  204.     }
  205.  
  206.    /*
  207.     * Create a memory-to-video path
  208.     */
  209.     if (createVidToMemPath(svr, &VIDtoMEMPath, &src, &drn) == -1) {
  210.     vlPerror("Couldn't create path");
  211.     cleanupAndExit(1);
  212.     }
  213.  
  214.    /* 
  215.     * Set up the hardware for and define the usage of the path 
  216.     */
  217.     if (vlSetupPaths(svr, (VLPathList)&VIDtoMEMPath, 1, VL_SHARE, VL_SHARE)<0) {
  218.     vlPerror("Unable to setup path");
  219.     cleanupAndExit(1);
  220.     }
  221.  
  222.    /*
  223.     * Now set the controls on the path indicating how we would like to 
  224.     * output the video
  225.     */
  226.     if (setVidToMemPathControls(svr, VIDtoMEMPath, src, drn) < 0) {
  227.     vlPerror("Couldn't set controls on path");
  228.     cleanupAndExit(1);
  229.     }
  230.  
  231.    /*
  232.     * Create a dmBufferPool and register it on the memory node. The memory
  233.     * node will allocate buffers from the pool to capture video.
  234.     */
  235.     if (createPool(svr, VIDtoMEMPath, drn, &pool) < 0) {
  236.     vlPerror("Couldn't create buffer");
  237.     cleanupAndExit(1);
  238.     }
  239.  
  240.     if (vlDMPoolRegister(svr, VIDtoMEMPath, drn, pool) < 0) {
  241.     vlPerror("Unable to register pool");
  242.     cleanupAndExit(1);
  243.     }
  244.  
  245.    /* 
  246.     * Register for preempted and transfer failed masks 
  247.     */
  248.     vlSelectEvents(svr, VIDtoMEMPath,  
  249.     ( VLStreamPreemptedMask    | VLTransferFailedMask | 
  250.     VLTransferCompleteMask));
  251.  
  252.    /*
  253.     * Create select desriptors so we know when a buffer or VL event is ready
  254.     */
  255.     bufferfd = vlNodeGetFd(svr, VIDtoMEMPath, drn);
  256.     vlfd = vlGetFD(svr);
  257.     if (vlfd > bufferfd) nfds = vlfd+1;
  258.     else nfds = bufferfd+1;
  259.  
  260.    /*
  261.     * Set up transfer descriptor for continuous capture mode with "immediate" 
  262.     * start (don't wait for a trigger event)
  263.     */
  264.     xferDesc.delay = 0;
  265.     xferDesc.trigger = VLTriggerImmediate;
  266.     xferDesc.count = 0;
  267.     xferDesc.mode = VL_TRANSFER_MODE_CONTINUOUS;
  268.  
  269.     if (vlBeginTransfer(svr, VIDtoMEMPath, 1, &xferDesc) < 0) {
  270.     vlPerror("vlBeginTransfer");
  271.     cleanupAndExit(1);
  272.     }
  273.  
  274.    /*
  275.     * This is, for all practical purposes, an event loop that exits after
  276.     * all the data has been read in.
  277.     */
  278.     while (1) {
  279.     FD_ZERO(&readfds);
  280.     FD_ZERO(&writefds);
  281.     FD_ZERO(&exceptfds);
  282.     FD_SET(vlfd, &readfds);
  283.     FD_SET(bufferfd, &readfds);
  284.     FD_SET(vlfd, &exceptfds);
  285.     FD_SET(bufferfd, &exceptfds);
  286.  
  287.     if (select(nfds, &readfds, &writefds, &exceptfds, NULL) < 0) {
  288.         perror("Select failed");
  289.         cleanupAndExit(1);
  290.     }
  291.     
  292.        /*
  293.     * Check if a buffer is ready to be filled
  294.     */
  295.     if (FD_ISSET(bufferfd, &readfds)) {
  296.         ret = buffer_ready(svr, VIDtoMEMPath, drn);
  297.         if (ret != 0) cleanupAndExit(1);
  298.     }
  299.  
  300.        /*
  301.     * Now see if we have a VL event
  302.     */
  303.     if (FD_ISSET(vlfd, &readfds)) {
  304.         ret = get_server_event(svr, VIDtoMEMPath, drn);
  305.         if (ret != 0) cleanupAndExit(1);
  306.     }
  307.  
  308.        /*
  309.     * Also check for exception conditions, for example if the
  310.     * connection to VL was broken, or the buffer was marked
  311.     * "done" (i.e. will not accept more input).
  312.     */
  313.     if (FD_ISSET(vlfd, &exceptfds)) {
  314.         fprintf(stderr, "Exceptional condition on VL connection\n");
  315.         cleanupAndExit(1);
  316.     }
  317.  
  318.     if (FD_ISSET(bufferfd, &exceptfds)) {
  319.         fprintf(stderr, "Exception condition on ring buffer\n");
  320.         cleanupAndExit(1);
  321.     }
  322.     }
  323.  
  324.    /* 
  325.     * Cleanup and exit with no error 
  326.     */
  327.     cleanupAndExit(0);
  328. }
  329.  
  330. void cleanupAndExit(int exit_type)
  331. {
  332.    /*
  333.     * If we opened a server connection, then destroy all the objects we
  334.     * allocated before exiting.
  335.     */
  336.     if (svr) {
  337.        /*
  338.     * If we got as far as creating a path, then stop any transfer in
  339.     * progress and destroy the path.
  340.     */
  341.         if (VIDtoMEMPath) {
  342.         vlEndTransfer(svr, VIDtoMEMPath);
  343.        /*
  344.         * If we created a buffer, deregister it then destroy it too...
  345.         */
  346.             if (pool) {
  347.         dmBufferDestroyPool(pool);
  348.         }
  349.             vlDestroyPath(svr, VIDtoMEMPath);
  350.     }
  351.         vlCloseVideo(svr);
  352.     }
  353.     
  354.     exit(exit_type);
  355. }
  356.