home *** CD-ROM | disk | FTP | other *** search
/ More Insanity: Totally Insane 2 / totally_insane_ii.iso / src / video_library_buffering / examples / vidtomem_vlbuffer.c < prev   
Encoding:
C/C++ Source or Header  |  1997-05-29  |  7.1 KB  |  318 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. VLBuffer buf = 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. 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 = vlGetNextValid(svr, buf);
  137.     if (info == NULL) return 0;
  138.  
  139.     dataArea = vlGetActiveRegion(svr, buf, info);
  140.  
  141.     /* Fill in image data here */
  142.  
  143.     vlPutFree(svr, buf);
  144.  
  145.     printf("Got Buffer\n");
  146.     return 0;
  147. }
  148.  
  149. void
  150. main(int argc, char **argv)
  151. {
  152.     int ret;
  153.     VLTransferDescriptor xferDesc;
  154.     int bufferfd, vlfd;
  155.     fd_set readfds, writefds, exceptfds;
  156.     int nfds;
  157.  
  158.    /* 
  159.     * Connect to the video daemon 
  160.     */
  161.     if (!(svr = vlOpenVideo(""))) {
  162.     vlPerror("Couldn't open video");
  163.     cleanupAndExit(1);
  164.     }
  165.  
  166.    /*
  167.     * Create a video-to-memory path
  168.     */
  169.     if (createVidToMemPath(svr, &VIDtoMEMPath, &src, &drn) == -1) {
  170.     vlPerror("Couldn't create path");
  171.     cleanupAndExit(1);
  172.     }
  173.  
  174.    /* 
  175.     * Set up the hardware for and define the usage of the path 
  176.     */
  177.     if (vlSetupPaths(svr, (VLPathList)&VIDtoMEMPath, 1, VL_SHARE, VL_SHARE)<0) {
  178.     vlPerror("Unable to setup path");
  179.     cleanupAndExit(1);
  180.     }
  181.  
  182.    /*
  183.     * Now set the controls on the path indicating how we would like to 
  184.     * output the video
  185.     */
  186.     if (setVidToMemPathControls(svr, VIDtoMEMPath, src, drn) < 0) {
  187.     vlPerror("Couldn't set controls on path");
  188.     cleanupAndExit(1);
  189.     }
  190.  
  191.    /*
  192.     * Create a VL buffer and associate it with the memory node
  193.     */
  194.     if (createBuffer(svr, VIDtoMEMPath, drn, &buf) < 0) {
  195.     vlPerror("Couldn't create buffer");
  196.     cleanupAndExit(1);
  197.     }
  198.  
  199.     if (vlRegisterBuffer(svr, VIDtoMEMPath, drn, buf)) {
  200.     vlPerror(argv[0]);
  201.     vlDestroyBuffer(svr, buf);
  202.     cleanupAndExit(1);
  203.     }
  204.          
  205.    /* 
  206.     * Register for preempted and transfer failed masks 
  207.     */
  208.     vlSelectEvents(svr, VIDtoMEMPath,  
  209.     ( VLStreamPreemptedMask    | VLTransferFailedMask |
  210.     VLTransferCompleteMask));
  211.  
  212.    /*
  213.     * Create select desriptors so we know when the dmrb has more 
  214.     * data, or when VL sends us an event.
  215.     */
  216.     bufferfd = vlBufferGetFd(buf);
  217.     vlfd = vlGetFD(svr);
  218.     if (vlfd > bufferfd) nfds = vlfd+1;
  219.     else nfds = bufferfd+1;
  220.  
  221.    /*
  222.     * Set up transfer descriptor for continuous capture mode with "immediate" 
  223.     * start (don't wait for a trigger event)
  224.     */
  225.     xferDesc.delay = 0;
  226.     xferDesc.trigger = VLTriggerImmediate;
  227.     xferDesc.count = 0;
  228.     xferDesc.mode = VL_TRANSFER_MODE_CONTINUOUS;
  229.  
  230.     if (vlBeginTransfer(svr, VIDtoMEMPath, 1, &xferDesc) < 0) {
  231.     vlPerror("vlBeginTransfer");
  232.     cleanupAndExit(1);
  233.     }
  234.  
  235.    /*
  236.     * This is, for all practical purposes, an event loop that exits after
  237.     * all the data has been read in.
  238.     */
  239.     while (1) {
  240.     FD_ZERO(&readfds);
  241.     FD_ZERO(&writefds);
  242.     FD_ZERO(&exceptfds);
  243.     FD_SET(vlfd, &readfds);
  244.     FD_SET(bufferfd, &readfds);
  245.     FD_SET(vlfd, &exceptfds);
  246.     FD_SET(bufferfd, &exceptfds);
  247.  
  248.     if (select(nfds, &readfds, &writefds, &exceptfds, NULL) < 0) {
  249.         perror("Select failed");
  250.         cleanupAndExit(1);
  251.     }
  252.     
  253.        /*
  254.     * Check if a buffer is ready to be filled
  255.     */
  256.     if (FD_ISSET(bufferfd, &readfds)) {
  257.         ret = buffer_ready(svr, VIDtoMEMPath, drn);
  258.         if (ret != 0) cleanupAndExit(1);
  259.     }
  260.  
  261.        /*
  262.     * Now see if we have a VL event
  263.     */
  264.     if (FD_ISSET(vlfd, &readfds)) {
  265.         ret = get_server_event(svr, VIDtoMEMPath, drn);
  266.         if (ret != 0) cleanupAndExit(1);
  267.     }
  268.  
  269.        /*
  270.     * Also check for exception conditions, for example if the
  271.     * connection to VL was broken, or the buffer was marked
  272.     * "done" (i.e. will not accept more input).
  273.     */
  274.     if (FD_ISSET(vlfd, &exceptfds)) {
  275.         fprintf(stderr, "Exceptional condition on VL connection\n");
  276.         cleanupAndExit(1);
  277.     }
  278.  
  279.     if (FD_ISSET(bufferfd, &exceptfds)) {
  280.         fprintf(stderr, "Exception condition on ring buffer\n");
  281.         cleanupAndExit(1);
  282.     }
  283.     }
  284.  
  285.    /* 
  286.     * Cleanup and exit with no error 
  287.     */
  288.     cleanupAndExit(0);
  289. }
  290.  
  291. void cleanupAndExit(int exit_type)
  292. {
  293.    /*
  294.     * If we opened a server connection, then destroy all the objects we
  295.     * allocated before exiting.
  296.     */
  297.     if (svr) {
  298.        /*
  299.     * If we got as far as creating a path, then stop any transfer in
  300.     * progress and destroy the path.
  301.     */
  302.         if (VIDtoMEMPath) {
  303.         vlEndTransfer(svr, VIDtoMEMPath);
  304.        /*
  305.         * If we created a buffer, deregister it then destroy it too...
  306.         */
  307.             if (buf) {
  308.         vlDeregisterBuffer(svr, VIDtoMEMPath, drn, buf);
  309.         vlDestroyBuffer(svr, buf);
  310.         }
  311.             vlDestroyPath(svr, VIDtoMEMPath);
  312.     }
  313.         vlCloseVideo(svr);
  314.     }
  315.     
  316.     exit(exit_type);
  317. }
  318.