home *** CD-ROM | disk | FTP | other *** search
/ More Insanity: Totally Insane 2 / totally_insane_ii.iso / src / video_library_buffering / examples / memtovid_vlbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-29  |  7.1 KB  |  316 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 MEMtoVIDPath = NULL;
  10. VLNode src = 0, drn = 0;
  11. VLBuffer buf = NULL;
  12. int transferSize = 0;
  13.  
  14. void cleanupAndExit(int exit_type);
  15.  
  16. int 
  17. createMemToVidPath(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_MEM, VL_ANY);
  24.     *drn = vlGetNode(svr, VL_DRN, VL_VIDEO, 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. setMemToVidPathControls(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, src, 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, src, 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, src, 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. createBuffer(VLServer svr, VLPath path, VLNode memnode, VLBuffer *buffer)
  67. {
  68.    /* 
  69.     * Create a VL ring buffer for the data transfers.  
  70.     */
  71.     *buffer = vlCreateBuffer(svr, path, memnode, NBUFFERS);
  72.     if (!*buffer) {
  73.     vlPerror("Unable to create buffer");
  74.     return -1;
  75.     }
  76.  
  77.    /* 
  78.     * If the CPU will never touch the data in the buffer, then there is a
  79.     * potential performance gain to marking the buffer "No Access." This is
  80.     * the case, for example, if the buffer is read from disk using direct
  81.     * I/O then sent immediately to VL. (Marking the buffer "No Access" 
  82.     * marks the buffer non-cacheable. There will be a substantial penalty
  83.     * for accessing the buffer with the CPU.)
  84.     */
  85.     vlBufferAdvise(buf, VL_BUFFER_ADVISE_NOACCESS);
  86.  
  87.     transferSize = vlGetTransferSize(svr, path);
  88.  
  89.     return 0;
  90. }
  91.  
  92. int
  93. process_event(VLEvent *ev)
  94. {
  95.     switch (ev->reason)
  96.     {    
  97.     case VLStreamPreempted:
  98.         fprintf(stderr, "Stream Preempted by another Program\n");
  99.         return -1;
  100.         break;
  101.  
  102.     case VLTransferFailed: 
  103.         fprintf(stderr, "Transfer failed\n");
  104.         return -1;
  105.         break;
  106.  
  107.     case VLTransferComplete:
  108.         fprintf(stderr, "Got Transfer Complete\n");
  109.         break;
  110.     
  111.     default:
  112.         break;
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118. int
  119. get_server_event(VLServer svr, VLPath path, VLNode memnode)
  120. {
  121.     VLEvent ev;
  122.  
  123.     if (vlCheckEvent(svr, VLAllEventsMask, &ev) == -1) {
  124.     return 0;
  125.     }
  126.  
  127.     return process_event(&ev);
  128. }
  129.  
  130. int
  131. buffer_ready(VLServer svr, VLPath path, VLNode memnode)
  132. {
  133.     VLInfoPtr info;
  134.     char *dataArea;
  135.  
  136.     info = vlGetNextFree(svr, buf, transferSize);
  137.     dataArea = vlGetActiveRegion(svr, buf, info);
  138.  
  139.     /* Fill in image data here */
  140.  
  141.     vlPutValid(svr, buf);
  142.  
  143.     printf("Output Buffer\n");
  144.     return 0;
  145. }
  146.  
  147. void
  148. main(int argc, char **argv)
  149. {
  150.     int ret;
  151.     VLTransferDescriptor xferDesc;
  152.     int bufferfd, vlfd;
  153.     fd_set readfds, writefds, exceptfds;
  154.     int nfds;
  155.  
  156.    /* 
  157.     * Connect to the video daemon 
  158.     */
  159.     if (!(svr = vlOpenVideo(""))) {
  160.     vlPerror("Couldn't open video");
  161.     cleanupAndExit(1);
  162.     }
  163.  
  164.    /*
  165.     * Create a memory-to-video path
  166.     */
  167.     if (createMemToVidPath(svr, &MEMtoVIDPath, &src, &drn) == -1) {
  168.     vlPerror("Couldn't create path");
  169.     cleanupAndExit(1);
  170.     }
  171.  
  172.    /* 
  173.     * Set up the hardware for and define the usage of the path 
  174.     */
  175.     if (vlSetupPaths(svr, (VLPathList)&MEMtoVIDPath, 1, VL_SHARE, VL_SHARE)<0) {
  176.     vlPerror("Unable to setup path");
  177.     cleanupAndExit(1);
  178.     }
  179.  
  180.    /*
  181.     * Now set the controls on the path indicating how we would like to 
  182.     * output the video
  183.     */
  184.     if (setMemToVidPathControls(svr, MEMtoVIDPath, src, drn) < 0) {
  185.     vlPerror("Couldn't set controls on path");
  186.     cleanupAndExit(1);
  187.     }
  188.  
  189.    /*
  190.     * Create a VL buffer and associate it with the memory node
  191.     */
  192.     if (createBuffer(svr, MEMtoVIDPath, src, &buf) < 0) {
  193.     vlPerror("Couldn't create buffer");
  194.     cleanupAndExit(1);
  195.     }
  196.  
  197.     if (vlRegisterBuffer(svr, MEMtoVIDPath, src, buf)) {
  198.     vlPerror(argv[0]);
  199.     vlDestroyBuffer(svr, buf);
  200.     cleanupAndExit(1);
  201.     }
  202.          
  203.    /* 
  204.     * Register for preempted and transfer failed masks 
  205.     */
  206.     vlSelectEvents(svr, MEMtoVIDPath,  
  207.     ( VLStreamPreemptedMask    | VLTransferFailedMask | 
  208.     VLTransferCompleteMask));
  209.  
  210.    /*
  211.     * Create select desriptors so we know when the dmrb is ready for more 
  212.     * data, or when VL sends us an event.
  213.     */
  214.     bufferfd = vlBufferGetFd(buf);
  215.     vlfd = vlGetFD(svr);
  216.     if (vlfd > bufferfd) nfds = vlfd+1;
  217.     else nfds = bufferfd+1;
  218.  
  219.    /*
  220.     * Set up transfer descriptor for continuous capture mode with "immediate" 
  221.     * start (don't wait for a trigger event)
  222.     */
  223.     xferDesc.delay = 0;
  224.     xferDesc.trigger = VLTriggerImmediate;
  225.     xferDesc.count = 0;
  226.     xferDesc.mode = VL_TRANSFER_MODE_CONTINUOUS;
  227.  
  228.     if (vlBeginTransfer(svr, MEMtoVIDPath, 1, &xferDesc) < 0) {
  229.     vlPerror("vlBeginTransfer");
  230.     cleanupAndExit(1);
  231.     }
  232.  
  233.    /*
  234.     * This is, for all practical purposes, an event loop that exits after
  235.     * all the data has been read in.
  236.     */
  237.     while (1) {
  238.     FD_ZERO(&readfds);
  239.     FD_ZERO(&writefds);
  240.     FD_ZERO(&exceptfds);
  241.     FD_SET(vlfd, &readfds);
  242.     FD_SET(bufferfd, &writefds);
  243.     FD_SET(vlfd, &exceptfds);
  244.     FD_SET(bufferfd, &exceptfds);
  245.  
  246.     if (select(nfds, &readfds, &writefds, &exceptfds, NULL) < 0) {
  247.         perror("Select failed");
  248.         cleanupAndExit(1);
  249.     }
  250.     
  251.        /*
  252.     * Check if a buffer is ready to be filled
  253.     */
  254.     if (FD_ISSET(bufferfd, &writefds)) {
  255.         ret = buffer_ready(svr, MEMtoVIDPath, src);
  256.         if (ret != 0) cleanupAndExit(1);
  257.     }
  258.  
  259.        /*
  260.     * Now see if we have a VL event
  261.     */
  262.     if (FD_ISSET(vlfd, &readfds)) {
  263.         ret = get_server_event(svr, MEMtoVIDPath, src);
  264.         if (ret != 0) cleanupAndExit(1);
  265.     }
  266.  
  267.        /*
  268.     * Also check for exception conditions, for example if the
  269.     * connection to VL was broken, or the buffer was marked
  270.     * "done" (i.e. will not accept more input).
  271.     */
  272.     if (FD_ISSET(vlfd, &exceptfds)) {
  273.         fprintf(stderr, "Exceptional condition on VL connection\n");
  274.         cleanupAndExit(1);
  275.     }
  276.  
  277.     if (FD_ISSET(bufferfd, &exceptfds)) {
  278.         fprintf(stderr, "Exception condition on ring buffer\n");
  279.         cleanupAndExit(1);
  280.     }
  281.     }
  282.  
  283.    /* 
  284.     * Cleanup and exit with no error 
  285.     */
  286.     cleanupAndExit(0);
  287. }
  288.  
  289. void cleanupAndExit(int exit_type)
  290. {
  291.    /*
  292.     * If we opened a server connection, then destroy all the objects we
  293.     * allocated before exiting.
  294.     */
  295.     if (svr) {
  296.        /*
  297.     * If we got as far as creating a path, then stop any transfer in
  298.     * progress and destroy the path.
  299.     */
  300.         if (MEMtoVIDPath) {
  301.         vlEndTransfer(svr, MEMtoVIDPath);
  302.        /*
  303.         * If we created a buffer, deregister it then destroy it too...
  304.         */
  305.             if (buf) {
  306.         vlDeregisterBuffer(svr, MEMtoVIDPath, src, buf);
  307.         vlDestroyBuffer(svr, buf);
  308.         }
  309.             vlDestroyPath(svr, MEMtoVIDPath);
  310.     }
  311.         vlCloseVideo(svr);
  312.     }
  313.     
  314.     exit(exit_type);
  315. }
  316.