home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / video / simpleVideo / lib / svUtil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  20.3 KB  |  849 lines

  1. /*
  2.  * Copyright (c) 1994, Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that the name of Silicon Graphics may not be used in any advertising or
  7.  * publicity relating to the software without the specific, prior written
  8.  * permission of Silicon Graphics.
  9.  *
  10.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  11.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  12.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  13.  *
  14.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  15.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  16.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  17.  * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
  18.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19.  */
  20. /* $Id: svUtil.c,v 1.5 1994/07/18 22:26:08 dpb Exp $ */
  21.  
  22. #include <string.h>
  23. #include <bstring.h>
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26. #include <assert.h>
  27. /* #include <dmedia/rb.h> */
  28. #include <vl/vl.h>
  29. #include "vlUtil.h"
  30. #include "sv.h"
  31. #include "svPriv.h"
  32.  
  33. #define numof(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
  34.  
  35.  
  36. /*
  37.  * forward static function definitions;
  38.  */
  39.  
  40. static void
  41. _shutdownVL(void);
  42.  
  43.  
  44. /*
  45.  * undocumented entry points;
  46.  */
  47.  
  48. VLInfoPtr dmRBLockWritable(VLBuffer, int space, int count,
  49.                   int *realCount, int block);
  50.  
  51. VLInfoPtr dmRBLockReadable(VLBuffer, int frameCount,
  52.                int *actualCount, int block);
  53.  
  54. /*
  55.  * Possible Galileo video connections;
  56.  */
  57.  
  58. #define svINPUT_MEMORY    0
  59. #define svOUTPUT_MEMORY    0
  60.  
  61. typedef struct {
  62.     int id;
  63.     char *device;
  64.     char *name;
  65.     int type;
  66.     int kind;
  67.     int number;
  68.     int muxValue;
  69. } SvConnection;
  70.  
  71. /* XXX - we're gonna have to whack this a bit because the
  72.  *       control value associated with a particular muxswitch
  73.  *       label is not constant! i.e, "Composite 2" is "4" for
  74.  *       Galileo and "5" for Indy Video.
  75.  */
  76.  
  77. static SvConnection inputConnections[] = {
  78.     { svINPUT_MEMORY,      "",     "memory",       VL_SRC, VL_MEM,   0, -1 },
  79.     { vnINPUT_INDYCAM,     "vino", "IndyCam",      VL_SRC, VL_VIDEO, 0, -1 }, 
  80.     { vnINPUT_COMPOSITE,   "vino", "Composite",    VL_SRC, VL_VIDEO, 1,  1 },
  81.     { vnINPUT_SVIDEO,      "vino", "SVideo",       VL_SRC, VL_VIDEO, 1,  2 },
  82.     { gvINPUT_COMPOSITE_1, "ev1",  "Composite 1",  VL_SRC, VL_VIDEO, 0,  3 },
  83.     { gvINPUT_SVIDEO,      "ev1",  "Y/C (svideo)", VL_SRC, VL_VIDEO, 0,  1 },
  84.     { gvINPUT_COMPOSITE_2, "ev1",  "Composite 2",  VL_SRC, VL_VIDEO, 0,  5 },
  85.     { gvINPUT_DIGITAL_1,   "ev1",  "Digital 1",    VL_SRC, VL_VIDEO, 1, -1 },
  86.     { gvINPUT_DIGITAL_2,   "ev1",  "Digital 2",    VL_SRC, VL_VIDEO, 2, -1 },
  87. };
  88.  
  89. static int numInputConnections = numof(inputConnections);
  90.  
  91. static SvConnection outputConnections[] = {
  92.     { svOUTPUT_MEMORY,  "",    "memory",      VL_DRN, VL_MEM,   0, -1 },
  93.     { gvOUTPUT_ANALOG,  "ev1", "Analog  Out", VL_DRN, VL_VIDEO, 0, -1 },
  94.     { gvOUTPUT_DIGITAL, "ev1", "Digital Out", VL_DRN, VL_VIDEO, 0, -1 },
  95. };
  96.  
  97. static int numOutputConnections = numof(outputConnections);
  98.  
  99. /**********************************************************************
  100.  * Simple Video context management -
  101.  **********************************************************************
  102.  */
  103.  
  104. typedef struct {
  105.     int pid;
  106.     ConnectionState *sv;
  107. } SvContext;
  108.  
  109. typedef struct {
  110.     int pid;
  111.     int contextNum;
  112. } SvPidTable;
  113.  
  114. #define TABLE_SIZE 256
  115. static SvContext _svContextTable[TABLE_SIZE];
  116. static SvPidTable _svPidEntry[TABLE_SIZE];
  117.  
  118.  
  119. static int
  120. _allocContextEntry(void)
  121. {
  122.     int pid;
  123.     int i;
  124.     ConnectionState *sv;
  125.  
  126.     pid = (int) getpid();
  127.  
  128.     for (i=0; i<TABLE_SIZE; i++)
  129.     if (_svContextTable[i].pid == 0)
  130.         break;
  131.  
  132.     /* xxx table overflow ? */
  133.  
  134.     sv = (ConnectionState *) malloc(sizeof(ConnectionState));
  135.     _svContextTable[i].pid = pid;
  136.     _svContextTable[i].sv = sv;
  137.  
  138.     sv->vlInitialized = FALSE;
  139.     sv->svr = NULL;
  140.     sv->dev = NULL;
  141.     sv->input = -1;
  142.     sv->output = -1;
  143.     sv->pathUsageMode = VL_SHARE;
  144.     sv->controlUsageMode = VL_SHARE;
  145.     sv->frameCount = 1;
  146.     sv->packing = VL_PACKING_RGB_8;
  147.     sv->saveImagesCompressed = FALSE;
  148.     sv->transferMode = svTRANSFER_DISCRETE;
  149.     sv->transferCountRemaining = 0;
  150.     sv->freeFrameNextXfer = FALSE;
  151.     sv->recoverFromPreemption = FALSE;
  152.     sv->deviceWidthFactor = 1;
  153.     sv->deviceHeightFactor = 1;
  154.     sv->saved_src = -1;
  155.     sv->saved_drn = -1;
  156.     sv->saved_buffer_node = NULL;
  157.     sv->saved_path = -1;
  158.     sv->saved_buffer = NULL;
  159.     sv->transferSize = 0; 
  160.     sv->transferring = FALSE;
  161.  
  162.     sv->setupPathCallback = NULL;
  163.  
  164.     return(i);
  165. }
  166.  
  167. static int
  168. _allocPidEntry(int pid)
  169. {
  170.     int i;
  171.  
  172.     for (i=0; i<TABLE_SIZE; i++)
  173.     if (_svPidEntry[i].pid == 0)
  174.         break;
  175.  
  176.     /* xxx handle table overflow? */
  177.  
  178.     _svPidEntry[i].pid = pid;
  179.     _svPidEntry[i].contextNum = 0;
  180.  
  181.     return i;
  182. }
  183.  
  184. static int
  185. _findPidEntry(int alloc)
  186. {
  187.     int pid;
  188.     int i, j;
  189.  
  190.     pid = (int) getpid();
  191.  
  192.     for (i=0; i<TABLE_SIZE; i++)
  193.     if (_svPidEntry[i].pid == pid)
  194.         return(i);
  195.  
  196.     i = _allocPidEntry(pid);
  197.     if (alloc) {
  198.     j = _allocContextEntry();
  199.     _svPidEntry[i].contextNum = j;
  200.     }    
  201.  
  202.     return i;
  203. }
  204.  
  205. ConnectionState *
  206. _findContext(void)
  207. {
  208.     int pidEntry, contextEntry;
  209.  
  210.     pidEntry = _findPidEntry(TRUE);
  211.     contextEntry = _svPidEntry[pidEntry].contextNum;
  212.  
  213.     return _svContextTable[contextEntry].sv;
  214. }
  215.  
  216. svContext
  217. svNewContext(void)
  218. {
  219.     int pidEntry;
  220.     int newContextEntry;
  221.  
  222.     newContextEntry = _allocContextEntry();
  223.     pidEntry = _findPidEntry(TRUE);
  224.     _svPidEntry[pidEntry].contextNum = newContextEntry;
  225.  
  226.     return(newContextEntry);
  227. }
  228.  
  229. void
  230. svSetContext(svContext contextNum)
  231. {
  232.     int pidEntry;
  233.  
  234.     pidEntry = _findPidEntry(FALSE);
  235.     _svPidEntry[pidEntry].contextNum = contextNum;
  236. }
  237.  
  238. svContext
  239. svCurrentContext(void)
  240. {
  241.     int pidEntry;
  242.  
  243.     pidEntry = _findPidEntry(TRUE);
  244.     return _svPidEntry[pidEntry].contextNum;
  245. }
  246.  
  247. void
  248. svFreeContext(svContext contextNum)
  249. {
  250.     /* xxx write */
  251.     assert(0);
  252. }
  253.  
  254. void
  255. svSetupPathCallback(SVSetupPathCallback callbackFunction)
  256. {
  257.     ConnectionState *sv;
  258.  
  259.     sv = _findContext();
  260.     sv->setupPathCallback = callbackFunction;
  261. }
  262.  
  263. /***********************************************************************
  264.  * Internal support functions;
  265.  ***********************************************************************
  266.  */
  267.  
  268. /**********************************************************************
  269.  * _initializeVL -
  270.  *
  271.  * establish our connection to the video daemon and find the device
  272.  * number of the galileo device.
  273.  **********************************************************************
  274.  */
  275.  
  276. static VLServer svr;
  277.  
  278. static int
  279. _initializeVL(ConnectionState *sv,
  280.           SvConnection *srcConn,
  281.           SvConnection *drnConn) {
  282.     int i;
  283.  
  284.     char *devName;
  285.     VLDevList devlist;
  286.  
  287.     /* Find a connection record with a device name in it */
  288.     if (strcmp(srcConn->device, "") != 0)
  289.     devName = srcConn->device;
  290.     else
  291.     devName = drnConn->device;
  292.  
  293.     if (!svr)
  294.     svr = vlOpenVideo("");
  295.  
  296.     sv->svr = svr;
  297.     if (!svr)
  298.     return svInitFailed;
  299.  
  300.  
  301.     /* Find the desired device */
  302.     
  303.     vlGetDeviceList(sv->svr, &devlist);
  304.     for (i=0; i<devlist.numDevices; i++)
  305.     if (strcmp(devlist.devices[i].name, devName) == 0)
  306.         break;
  307.  
  308.     /* it wasn't there */
  309.     if (i == devlist.numDevices)
  310.     return svDeviceNotFound;
  311.  
  312.     /* we found it, now save it for future use */
  313.     sv->dev = devlist.devices[i].dev;
  314.  
  315.     /* galileo hack */
  316.     if (strcmp(devName, "ev1") == 0)
  317.     sv->deviceWidthFactor = 2;
  318.  
  319.     /* vino hack */
  320.     if (strcmp(devName, "vino") == 0)
  321.     sv->deviceHeightFactor = 2;
  322.  
  323.     atexit(_shutdownVL);
  324.     return svSuccess;
  325. }
  326.  
  327. /**********************************************************************
  328.  * _shutdownVL -
  329.  *
  330.  * cleanup VL before exiting.
  331.  **********************************************************************
  332.  */
  333.  
  334. static void
  335. _shutdownVL(void)
  336. {
  337.     ConnectionState *sv;
  338.  
  339.     sv = _findContext();
  340.  
  341.     if (sv->transferring)
  342.     vlEndTransfer(sv->svr, sv->saved_path);
  343.  
  344.     if (sv->saved_buffer) {
  345.     vlDeregisterBuffer(sv->svr, sv->saved_path,
  346.                sv->saved_buffer_node, sv->saved_buffer);
  347.     vlDestroyBuffer(sv->svr, sv->saved_buffer);
  348.     }
  349.  
  350.     if (sv->saved_path)
  351.     vlDestroyPath(sv->svr, sv->saved_path);
  352.  
  353.     vlCloseVideo(sv->svr);
  354. }
  355.  
  356. /**********************************************************************
  357.  * _configurePath -
  358.  *
  359.  * make sure we have a path from the input specified in
  360.  * svSelectedInputConnection to the output specified in
  361.  * svSelectedOutputConnection.
  362.  **********************************************************************
  363.  */
  364.  
  365. static int
  366. _configurePath(int src, int drn, ConnectionState *sv)
  367. {
  368.     int i;
  369.     int status;
  370.     SvConnection *srcConn, *drnConn;
  371.     VLNode srcNode, drnNode;
  372.     VLPath path;
  373.  
  374.  
  375.     if (src == sv->saved_src && drn == sv->saved_drn)
  376.     return svSuccess;
  377.  
  378.     /* We're not trying to use the same path, so tear down
  379.      * the old path if it exists and build the new one up
  380.      * from scratch;
  381.      */
  382.  
  383.     if (sv->saved_path != -1) {
  384.     if (sv->saved_buffer) {
  385.         vlDeregisterBuffer(sv->svr, sv->saved_path,
  386.                    sv->saved_buffer_node, sv->saved_buffer);
  387.         vlDestroyBuffer(sv->svr, sv->saved_buffer);
  388.     }
  389.         
  390.     vlDestroyPath(sv->svr, sv->saved_path);
  391.     sv->saved_path = -1;
  392.     sv->saved_src = -1;
  393.     sv->saved_drn = -1;
  394.     sv->saved_buffer_node = NULL;
  395.     sv->saved_buffer = NULL;
  396.  
  397.     sv->transferCountRemaining = 0;
  398.     sv->freeFrameNextXfer    = FALSE;
  399.     sv->transferring         = FALSE;
  400.     }
  401.  
  402.     /* Find the connection record for the selected source and
  403.      * selected drain connection;
  404.      */
  405.  
  406.     for (i=0; i<numInputConnections; i++)
  407.     if (inputConnections[i].id == src)
  408.         break;
  409.  
  410.     if (i == numInputConnections)
  411.     return svBadInputConnection;
  412.  
  413.     srcConn = &inputConnections[i];
  414.  
  415.     for (i=0; i<numOutputConnections; i++)
  416.     if (outputConnections[i].id == drn)
  417.         break;
  418.  
  419.     if (i == numOutputConnections)
  420.     return svBadOutputConnection;
  421.  
  422.     drnConn = &outputConnections[i];
  423.  
  424.     /* We've got our two node records, now call initializeVL to
  425.      * open the VL connection and pick the device we'll be using;
  426.      */
  427.     
  428.     if (!sv->vlInitialized++)
  429.     if ((status = _initializeVL(sv, srcConn, drnConn)) != svSuccess)
  430.         return status;
  431.  
  432.     /* Now that we know what kind of nodes we should be using,
  433.      * create them;
  434.      */
  435.  
  436.     srcNode = vlGetNode(sv->svr, srcConn->type, srcConn->kind, srcConn->number);
  437.     drnNode = vlGetNode(sv->svr, drnConn->type, drnConn->kind, drnConn->number);
  438.  
  439.     if (srcNode == -1)
  440.     return svBadInputNode;
  441.  
  442.     if (drnNode == -1)
  443.     return svBadOutputNode;
  444.  
  445.     path = vlCreatePath(sv->svr, sv->dev, srcNode, drnNode);
  446.     if (path == -1)
  447.     return svBadPath;
  448.  
  449.     /*
  450.      * If we make it this far, find out if we can now setup the path;
  451.      */
  452.        
  453.     if (vlSetupPaths(sv->svr, &path, 1, sv->pathUsageMode, sv->controlUsageMode) < 0)
  454.     return svBadPathSetup;
  455.  
  456.     if (sv->setupPathCallback)
  457.     (sv->setupPathCallback)(sv->svr, path, srcNode, drnNode);
  458.  
  459.     /*
  460.      * Still going?  Then all we need to do is see if we
  461.      * need to pound on the muxswitch control to access the
  462.      * correct connection;
  463.      */
  464.  
  465.     if (srcConn->muxValue >= 0)
  466.     vlSetMuxSwitch(sv->svr, path, srcNode, srcConn->muxValue);
  467.  
  468.     if (drnConn->muxValue >= 0)
  469.     vlSetMuxSwitch(sv->svr, path, drnNode, drnConn->muxValue);
  470.  
  471.     /*
  472.      * Now, before we can *really* do anything, we have to be able
  473.      * to create and register a buffer to use in the frame transfer;
  474.      */
  475.  
  476.     {
  477.     VLNode node = NULL;
  478.     VLBuffer buffer;
  479.     
  480.     if (srcConn->kind == VL_MEM)
  481.         node = srcNode;
  482.     if (drnConn->kind == VL_MEM)
  483.         node = drnNode;
  484.  
  485.     if (node) {
  486.         vlSetPacking(sv->svr, path, node, sv->packing);
  487.         vlSetCapType(sv->svr, path, node, VL_CAPTURE_INTERLEAVED);
  488.  
  489.         buffer = vlCreateBuffer(sv->svr, path, node, sv->frameCount);
  490.         if (buffer == NULL)
  491.         return svBufferAllocFailed;
  492.  
  493.         if (vlRegisterBuffer(sv->svr, path, node, buffer) != VLSuccess) {
  494.         vlDestroyBuffer(sv->svr, buffer);
  495.         return svBufferRegisterFailed;
  496.         }
  497.  
  498.         sv->saved_buffer_node = node;
  499.         sv->saved_buffer = buffer;
  500.     }
  501.     }
  502.  
  503.     /*
  504.      * Everything worked, so record the src connection,
  505.      * the drain connection, and the path we just created
  506.      * for future reference;
  507.      */
  508.  
  509.     sv->saved_src  = src;
  510.     sv->saved_drn  = drn;
  511.     sv->saved_path = path;
  512.     sv->transferSize = vlGetTransferSize(sv->svr, sv->saved_path);
  513.  
  514.     return svSuccess;
  515. }
  516.  
  517. /**********************************************************************
  518.  * BeginTransfer - 
  519.  *
  520.  * initiate a transfer if necessary;
  521.  **********************************************************************
  522.  */
  523.  
  524. /* XXX add triggering??? */
  525.  
  526. static int
  527. _beginTransfer(ConnectionState *sv)
  528. {
  529.     int ret;
  530.     VLTransferDescriptor xferDesc;
  531.  
  532.     if (sv->freeFrameNextXfer) {
  533.     vlPutFree(sv->svr, sv->saved_buffer);
  534.     sv->freeFrameNextXfer = FALSE;
  535.     }
  536.  
  537.     if (sv->transferCountRemaining == 0) {
  538.     if (sv->transferring) {
  539.         if (vlEndTransfer(sv->svr, sv->saved_path) < 0)  {
  540.         /*** If we were only preempted,
  541.          *** try to re-setup our path;
  542.          ***/
  543.         if (sv->recoverFromPreemption &&  vlErrno == VLBadAccess) { 
  544.             ret = vlSetupPaths(sv->svr, &(sv->saved_path), 1,
  545.                        sv->pathUsageMode, sv->controlUsageMode);
  546.             if (ret)
  547.             return svEndTransferFixupFailed;
  548.  
  549.             if (sv->setupPathCallback)
  550.             (sv->setupPathCallback)(sv->svr, sv->saved_path,
  551.                         sv->saved_src, sv->saved_drn);
  552.         }
  553.         else
  554.             return svEndTransferFailed;
  555.         }
  556.  
  557.         sv->transferring = FALSE;
  558.         if (vlBufferReset(sv->svr, sv->saved_buffer) < 0)
  559.         return svBufferResetFailed;
  560.     }
  561.  
  562.     if (sv->transferMode == svTRANSFER_DISCRETE) {
  563.         xferDesc.mode    = VL_TRANSFER_MODE_DISCRETE;
  564.         xferDesc.count   = (short) sv->frameCount;
  565.         xferDesc.delay   = 0;
  566.         xferDesc.trigger = VLTriggerImmediate;
  567.     }
  568.     
  569.     if (sv->transferMode == svTRANSFER_CONTINUOUS) {
  570.         xferDesc.mode = VL_TRANSFER_MODE_CONTINUOUS;
  571.         xferDesc.trigger = VLTriggerImmediate;
  572.     }
  573.  
  574.     if (vlBeginTransfer(sv->svr, sv->saved_path, 1, &xferDesc))
  575.         return svBeginTransferFailed;
  576.     
  577.     sv->transferring = TRUE;
  578.     sv->transferCountRemaining = sv->frameCount;
  579.     }
  580.     
  581.     return svSuccess;
  582. }
  583.  
  584. /***********************************************************************
  585.  * Public Utility routines for settting transfer parameters;
  586.  ***********************************************************************
  587.  */
  588.  
  589. /**********************************************************************
  590.  *
  591.  * svSelectInput -
  592.  *
  593.  * Select the input connection you wish to use.
  594.  **********************************************************************
  595.  */
  596.  
  597. void
  598. svSelectInput(int input)
  599. {
  600.     ConnectionState *sv;
  601.  
  602.     sv = _findContext();
  603.     sv->input = input;
  604. }
  605.  
  606. /**********************************************************************
  607.  *
  608.  * svSelectOutput -
  609.  *
  610.  * Select the output connection you wish to use.
  611.  **********************************************************************
  612.  */
  613.  
  614. void
  615. svSelectOutput(int output)
  616. {
  617.     ConnectionState *sv;
  618.  
  619.     sv = _findContext();
  620.     sv->output = output;
  621. }
  622.  
  623. /**********************************************************************
  624.  *
  625.  * svNodeAccessMode -
  626.  *
  627.  * Set the locking mode for nodes.
  628.  **********************************************************************
  629.  */
  630.  
  631. void
  632. svNodeAccessMode(VLUsageType mode)
  633. {
  634.     ConnectionState *sv;
  635.  
  636.     sv = _findContext();
  637.     sv->pathUsageMode = mode;
  638. }
  639.  
  640. /**********************************************************************
  641.  *
  642.  * svControlAccessMode -
  643.  *
  644.  * Set the locking mode for controls.
  645.  **********************************************************************
  646.  */
  647.  
  648. void
  649. svControlAccessMode(VLUsageType mode)
  650. {
  651.     ConnectionState *sv;
  652.  
  653.     sv = _findContext();
  654.     sv->controlUsageMode = mode;
  655. }
  656.  
  657. /**********************************************************************
  658.  *
  659.  * svSetFrameCount -
  660.  *
  661.  * Set the number of frames in the ring buffer.
  662.  **********************************************************************
  663.  */
  664.  
  665. void
  666. svSetFrameCount(int count)
  667. {
  668.     ConnectionState *sv;
  669.  
  670.     sv = _findContext();
  671.     sv->frameCount = count;
  672. }
  673.  
  674. /**********************************************************************
  675.  *
  676.  * svSetImagePacking -
  677.  *
  678.  * Set the image packing for a particular context.
  679.  **********************************************************************
  680.  */
  681.  
  682. void
  683. svSetImagePacking(int packing)
  684. {
  685.     ConnectionState *sv;
  686.  
  687.     sv = _findContext();
  688.     sv->packing = packing;
  689. }
  690.  
  691. /**********************************************************************
  692.  *
  693.  * svSetTransferMode -
  694.  *
  695.  * Set the transferMode.
  696.  **********************************************************************
  697.  */
  698.  
  699. void
  700. svSetTransferMode(int mode)
  701. {
  702.     ConnectionState *sv;
  703.  
  704.     sv = _findContext();
  705.     sv->transferMode = mode;
  706. }
  707.  
  708. /**********************************************************************
  709.  *
  710.  * svCompressedImages -
  711.  *
  712.  * Set the transferMode.
  713.  **********************************************************************
  714.  */
  715.  
  716. void
  717. svCompressedImages(int saveCompressed)
  718. {
  719.     ConnectionState *sv;
  720.  
  721.     sv = _findContext();
  722.     sv->saveImagesCompressed = saveCompressed;
  723. }
  724.  
  725. /**********************************************************************
  726.  *
  727.  * svRecoverFromPreemption -
  728.  *
  729.  * Attempt to recover from a preemption when our path was
  730.  * setup in VL_SHARE mode;
  731.  **********************************************************************
  732.  */
  733.  
  734. void
  735. svRecoverFromPreemption(void)
  736. {
  737.     ConnectionState *sv;
  738.  
  739.     sv = _findContext();
  740.     sv->recoverFromPreemption = TRUE;
  741. }
  742.  
  743. /***********************************************************************
  744.  * Routines for grabbing, putting frames;
  745.  ***********************************************************************
  746.  */
  747.  
  748. /**********************************************************************
  749.  * svGetFrame -
  750.  *
  751.  * Grab a frame from the selected input.
  752.  **********************************************************************
  753.  */
  754.  
  755. int
  756. svGetFrame(svImage *frame)
  757. {
  758.     int status;
  759.  
  760.  
  761.     VLInfoPtr info;
  762.     DMImageInfo *imageInfo;
  763.     ConnectionState *sv;
  764.  
  765.     sv = _findContext();
  766.  
  767.     if ((status = _configurePath(sv->input, svOUTPUT_MEMORY, sv)) != svSuccess)
  768.     return status;
  769.  
  770.     if ((status = _beginTransfer(sv)) != svSuccess)
  771.     return status;
  772.  
  773.     info = dmRBLockReadable(sv->saved_buffer, 1, NULL, 1 /* block */);
  774.     if (sv->transferMode == svTRANSFER_DISCRETE)
  775.     sv->transferCountRemaining--;
  776.     sv->freeFrameNextXfer = TRUE;
  777.  
  778.     /* XXX note that in the ev1_dma.c , imageInfo->width is set
  779.      *     to wds_per_line; should almost certainly convert this
  780.      *     to the number of bytes wide the line is, check to see
  781.      *     if the dm struct is documented that way or not;
  782.      */
  783.  
  784.     /*
  785.      * XXX we turned on interleave mode for vino; It seems to work,
  786.      *     but the imageInfo->height doesn't seem to take this
  787.      *     info account, so we need a special vino whack also.
  788.      */
  789.  
  790.     /*
  791.      * XXX the values coming back from the vino driver in imageInfo->packing
  792.      *     don't match what we asked for;
  793.      *     set to 2, we get back frames with packing = 0;
  794.      *     set to 5, we get back frames with packing = 2;
  795.      *
  796.      *     So, blow off value passed back, just use the value we originally
  797.      *     requested that is stored in sv->packing;
  798.      */
  799.  
  800.     imageInfo = vlGetImageInfo(sv->svr, sv->saved_buffer, info);
  801.  
  802.     frame->width   = imageInfo->width  * sv->deviceWidthFactor;
  803.     frame->height  = imageInfo->height * sv->deviceHeightFactor;
  804.     /* XXX frame->packing = imageInfo->packing; */
  805.     frame->packing = sv->packing;
  806.     frame->data    = vlGetActiveRegion(sv->svr, sv->saved_buffer, info);
  807.     frame->dataSize = sv->transferSize;
  808.  
  809.     return svSuccess;
  810. }
  811.  
  812. /**********************************************************************
  813.  * svPutFrame -
  814.  *
  815.  * Use an image as a frame of video output;
  816.  **********************************************************************
  817.  */
  818.  
  819. int
  820. svPutFrame(svImage *frame)
  821. {
  822.     int status;
  823.      VLInfoPtr info;
  824.     char *dataPtr;
  825.     ConnectionState *sv;
  826.  
  827.     sv = _findContext();
  828.  
  829.     if ((status = _configurePath(svINPUT_MEMORY, sv->output, sv)) != svSuccess)
  830.     return status;
  831.  
  832.     if ((status = _beginTransfer(sv)) != svSuccess)
  833.     return status;
  834.  
  835.     /* xxx we should check for size mismatches */
  836.  
  837.     info = dmRBLockWritable(sv->saved_buffer, sv->transferSize, 1,
  838.                 NULL, 1 /* block */);
  839.     dataPtr = vlGetActiveRegion(sv->svr, sv->saved_buffer, info);
  840.     bcopy(frame->data, dataPtr, frame->dataSize);
  841.  
  842.     vlPutValid(sv->svr, sv->saved_buffer);
  843.     if (sv->transferMode == svTRANSFER_DISCRETE)
  844.     sv->transferCountRemaining--; 
  845.  
  846.     return svSuccess;
  847. }
  848.  
  849.