home *** CD-ROM | disk | FTP | other *** search
/ More Insanity: Totally Insane 2 / totally_insane_ii.iso / src / video_library_buffering / examples / memtovid_dmbuffer_O2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-29  |  8.1 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 MEMtoVIDPath = 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. 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. 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 (vlDMPoolGetParams(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. get_server_event(VLServer svr, VLPath path, VLNode memnode)
  142. {
  143.     VLEvent ev;
  144.  
  145.     if (vlEventRecv(svr, path, &ev) < 0) {
  146.     if (vlErrno == VLAgain) return 0;
  147.     vlPerror("Unable to receive event on path");
  148.     return -1;
  149.     }
  150.  
  151.     return process_event(&ev);
  152. }
  153.  
  154. int
  155. buffer_ready(VLServer svr, VLPath path, VLNode memnode)
  156. {
  157.     DMbuffer buffer;
  158.     char *dataArea;
  159.  
  160.    /*
  161.     * Allocate a buffer from the pool and get a pointer to the data
  162.     * (image) area.
  163.     */
  164.     if (dmBufferAllocate(pool, &buffer) != DM_SUCCESS) {
  165.     return 0;
  166.     }
  167.  
  168.     dataArea = dmBufferMapData(buffer);
  169.  
  170.     /* Fill in image data here */
  171.  
  172.    /*
  173.     * Send the buffer to the VL then free it. Note dmBufferFree only
  174.     * indicates that this application is done with the buffer, not that
  175.     * the buffer can be immediately reused or that the memory used by the
  176.     * buffer is freed. vlDMBufferPutValid, among other things, adds the VL
  177.     * as a user of the buffer.
  178.     */
  179.     if (vlDMBufferSend(svr, path, buffer) < 0) {
  180.     vlPerror("Unable to send buffer to video out");
  181.     dmBufferFree(buffer);
  182.     return -1;
  183.     }
  184.  
  185.     dmBufferFree(buffer);
  186.  
  187.     printf("Buffer Output\n");
  188.  
  189.     return 0;
  190. }
  191.  
  192. void
  193. main(int argc, char **argv)
  194. {
  195.     int ret;
  196.     VLTransferDescriptor xferDesc;
  197.     int bufferfd, vlfd;
  198.     fd_set readfds, writefds, exceptfds;
  199.     int nfds;
  200.  
  201.    /* 
  202.     * Connect to the video daemon 
  203.     */
  204.     if (!(svr = vlOpenVideo(""))) {
  205.     vlPerror("Couldn't open video");
  206.     cleanupAndExit(1);
  207.     }
  208.  
  209.    /*
  210.     * Create a memory-to-video path
  211.     */
  212.     if (createMemToVidPath(svr, &MEMtoVIDPath, &src, &drn) == -1) {
  213.     vlPerror("Couldn't create path");
  214.     cleanupAndExit(1);
  215.     }
  216.  
  217.    /* 
  218.     * Set up the hardware for and define the usage of the path 
  219.     */
  220.     if (vlSetupPaths(svr, (VLPathList)&MEMtoVIDPath, 1, VL_SHARE, VL_SHARE)<0) {
  221.     vlPerror("Unable to setup path");
  222.     cleanupAndExit(1);
  223.     }
  224.  
  225.    /*
  226.     * Now set the controls on the path indicating how we would like to 
  227.     * output the video
  228.     */
  229.     if (setMemToVidPathControls(svr, MEMtoVIDPath, src, drn) < 0) {
  230.     vlPerror("Couldn't set controls on path");
  231.     cleanupAndExit(1);
  232.     }
  233.  
  234.    /*
  235.     * Create a dmBufferPool. Note that unlike VL Buffers, it is not 
  236.     * necessary to register a buffer on a memory-to-video path. 
  237.     */
  238.     if (createPool(svr, MEMtoVIDPath, src, &pool) < 0) {
  239.     vlPerror("Couldn't create buffer");
  240.     cleanupAndExit(1);
  241.     }
  242.  
  243.    /* 
  244.     * Register for preempted and transfer failed masks 
  245.     */
  246.     vlSelectEvents(svr, MEMtoVIDPath,  
  247.     ( VLStreamPreemptedMask    | VLTransferFailedMask | 
  248.     VLTransferCompleteMask));
  249.  
  250.    /*
  251.     * Create select desriptors so we know when the dmrb is ready for more 
  252.     * data, or when VL sends us an event.
  253.     */
  254.     dmBufferSetPoolSelectSize(pool, 1);
  255.     bufferfd = dmBufferGetPoolFD(pool);
  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, MEMtoVIDPath, 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, &writefds);
  284.     FD_SET(vlfd, &exceptfds);
  285.     FD_SET(bufferfd, &exceptfds);
  286.  
  287.     if (select(nfds+1, &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, &writefds)) {
  296.         ret = buffer_ready(svr, MEMtoVIDPath, src);
  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, MEMtoVIDPath, src);
  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 (MEMtoVIDPath) {
  342.         vlEndTransfer(svr, MEMtoVIDPath);
  343.        /*
  344.         * If we created a buffer, deregister it then destroy it too...
  345.         */
  346.             if (pool) {
  347.         dmBufferDestroyPool(pool);
  348.         }
  349.             vlDestroyPath(svr, MEMtoVIDPath);
  350.     }
  351.         vlCloseVideo(svr);
  352.     }
  353.     
  354.     exit(exit_type);
  355. }
  356.