home *** CD-ROM | disk | FTP | other *** search
/ jayz.best.vwh.net / 2015-02-07.jayz.best.vwh.net.tar / jayz.best.vwh.net / TwoCardDemo.cp.hqx / TwoCardDemo.cp next >
Text File  |  1996-10-10  |  11KB  |  367 lines

  1. // TwoCardDemo.cp
  2. //-------------------------------------------------------------------------
  3. //                          Copyright (c) 1995
  4. //             INTELLIGENT RESOURCES INTEGRATED SYSTEMS INC.
  5. //                          All Rights Reserved.
  6. //
  7. //     This is unpublished work and is the proprietary source code of
  8. //             INTELLIGENT RESOURCES INTEGRATED SYSTEMS INC.
  9. //                 and should be treated as confidential
  10. //-------------------------------------------------------------------------
  11. //
  12. // This demonstrates sending video from a second card over VideoBahn.
  13. //
  14. // This demo is simplified to show the use of VideoBahn components.
  15. // However a future library should provide a higher level interface
  16. // for VideoBahn routing with automatic timing equalization.
  17. //
  18. // Note: Due to a bug in the Gyro 3.3.6 release, timing is not
  19. // automatically equalized, but for a two card configuration, this
  20. // can be done by setting the hsync value to -7 in the timing tool.
  21. //
  22. // Author        Reviewed By        Date            Description
  23. // ------        -----------        ----            -----------
  24. // JDZ                            10-Oct-96        Started today.
  25. //
  26. //-------------------------------------------------------------------------
  27.  
  28. #ifndef __FONTS__
  29. #include <Fonts.h>
  30. #endif
  31.  
  32. #ifndef __WINDOWS__
  33. #include <Windows.h>
  34. #endif
  35.  
  36. #ifndef __MENUS__
  37. #include <Menus.h>
  38. #endif
  39.  
  40. #ifndef __TEXTEDIT__
  41. #include <TextEdit.h>
  42. #endif
  43.  
  44. #ifndef __DIALOGS__
  45. #include <Dialogs.h>
  46. #endif
  47.  
  48. #ifndef __EVENTS__
  49. #include <events.h>
  50. #endif
  51.  
  52. #ifndef   VXServices_h
  53. #include "VXServices.h"
  54. #endif
  55.  
  56. #ifndef   VideoDeviceKernel_h
  57. #include "VideoDeviceKernel.h"
  58. #endif
  59.  
  60. #ifndef   VXMediaComponents_h
  61. #include "VXMediaComponents.h"
  62. #endif
  63.  
  64. #ifndef   VBPort_h
  65. #include "VBPort.h"
  66. #endif
  67.  
  68. #ifndef   VBComponent_h
  69. #include "VBComponent.h"
  70. #endif
  71.  
  72. #ifndef   VXDevice_h
  73. #include "VXDevice.h"
  74. #endif
  75.  
  76. //-------------------------------------------------------------------------
  77. // Local prototypes
  78. //-------------------------------------------------------------------------
  79.  
  80. static void TwoCardTest(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
  81.  
  82. static void LoadFrameBuffers(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
  83. static void RouteTwoCards(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
  84. static void DisableAllVBOutputs();
  85. static void DelayTillVBL(TVXVideoDevice* VX, int numDelays);
  86.  
  87. static void SysInit();
  88.  
  89. //-------------------------------------------------------------------------
  90. // Constants
  91. //-------------------------------------------------------------------------
  92.  
  93. const int kPict1ID = 128;
  94. const int kPict2ID = 129;
  95.  
  96.  
  97. //-------------------------------------------------------------------------
  98.  
  99. //------------------------------------------------------------
  100. // VBPortAccessor
  101. //
  102. //    This is a temporary work around until the VBCluster class
  103. //    is available. This is *not* multiport aware, and must be
  104. //    used with caution. Never drive two connected VideoBahn
  105. //    outputs at the same time.
  106. //
  107. //    Use the function DisableAllVBOutputs before enabling
  108. //    specific VideoBahnPorts for output
  109. //------------------------------------------------------------
  110.  
  111. class VBPortAccessor
  112.     {
  113.     public:
  114.         VBPortAccessor(VBPort* port);
  115.  
  116.         void EnableForOutput(bool enable);
  117.  
  118.     private:
  119.         VBPort* fPort;
  120.     };
  121.  
  122. inline VBPortAccessor::VBPortAccessor(VBPort* port)                : fPort(port)    { }
  123. inline void VBPortAccessor::EnableForOutput(bool enable)        { fPort->EnableForOutput(enable); }
  124.  
  125.  
  126. //-------------------------------------------------------------------------
  127. int main()
  128.     {
  129.     SysInit();                    // Do MacOS initialization
  130.     VXServicesInit();            // Do initialization for VX Services
  131.  
  132.     TVXVideoDevice* VX1 = NULL;            // Video Explorer objects
  133.     TVXVideoDevice* VX2 = NULL;
  134.  
  135.     GetFirstVideoDevice(VX1);            // Get the first Video Explorer
  136.     if (VX1 != NULL)
  137.         GetNextVideoDevice(VX1, VX2);    // Get the second Video Explorer
  138.  
  139.     if (VX1 != NULL && VX2 != NULL)
  140.         {
  141.         TwoCardTest(VX1, VX2);            // Test two card functionality
  142.         }
  143.     return 0;
  144.     }
  145.  
  146.  
  147. //------------------------------------------------------------
  148. // TwoCardTest
  149. //
  150. //    This is a limited sample which only works with a system
  151. //    with two Video Explorer cards, and assumes the VideoBahn
  152. //    topology provided by a VideoBahn-2 connector.
  153. //------------------------------------------------------------
  154.  
  155. static void TwoCardTest(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
  156.     {
  157.     if (VX1 && VX2)
  158.         {
  159.         // Get media components we will work with
  160.         // These are the basic building blocks to piece together effects
  161.         // and set up various video configurations.
  162.     
  163.         FrameBufferComponent_VX*    frameBuffer1 = VX1->GetFrameBufferComponent();    // The frame buffer
  164.         VideoBahnComponent_VX*        videoBahn1     = VX1->GetVideoBahnComponent();    // VideoBahn component
  165.         BlenderComponent_VX*        blender1     = VX1->GetBlenderComponent();        // A video mixer
  166.         BackgroundComponent_VX*        background1     = VX1->GetBackgroundComponent();    // The background (default display source)
  167.  
  168.         // Get media components for second card
  169.  
  170.         VideoBahnComponent_VX*        videoBahn2     = VX2->GetVideoBahnComponent();    // VideoBahn component
  171.         FrameBufferComponent_VX*    frameBuffer2 = VX2->GetFrameBufferComponent();    // The frame buffer
  172.  
  173.         // Do all the VideoBahn routing
  174.  
  175.         RouteTwoCards(VX1, VX2);
  176.  
  177.         // Load both frame buffers with PICTs
  178.  
  179.         LoadFrameBuffers(VX1, VX2);
  180.  
  181.         //------------ Display the frame buffer of our card.
  182.  
  183.         *background1->GetInput()  <<  frameBuffer1->GetOutput();    // Display from frame buffer
  184.  
  185.         //------------ Do a cut to the other frame buffer.
  186.  
  187.         *videoBahn2->GetInput()  <<  frameBuffer2->GetOutput();        // Output second card's frame buffer
  188.  
  189.         DelayTillVBL(VX1, 100);                                        // Wait 100 VBLs
  190.         *background1->GetInput() <<  videoBahn1->GetOutput();        // Display from VideoBahn input
  191.  
  192.         //------------ Do a blend of the two frame buffers.
  193.  
  194.         *blender1->GetInput(0)  <<  frameBuffer1->GetOutput();        // Source 1 is our frame buffer
  195.         *blender1->GetInput(1)  <<  videoBahn1->GetOutput();        // Source 2 is from the other card
  196.         blender1->SetICFs(0.5, 0.5);                                // Set the Image Contribution Factors for a 50-50 blend
  197.  
  198.         DelayTillVBL(VX1, 100);                                        // Wait 100 VBLs
  199.         *background1->GetInput() <<  blender1->GetOutput();            // Display output of the blender
  200.  
  201.         //------------ Go back to frame buffer on our card
  202.     
  203.         DelayTillVBL(VX1, 100);                                        // Wait 100 VBLs
  204.         *background1->GetInput()  <<  frameBuffer1->GetOutput();    // Display from frame buffer
  205.         }
  206.     }
  207.  
  208.  
  209. //------------------------------------------------------------
  210. // LoadFrameBuffers
  211. //
  212. //    This disables all Digital Video Port outputs on VideoBahn.
  213. //------------------------------------------------------------
  214.  
  215. static void LoadFrameBuffers(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
  216.     {
  217.     // Load both frame buffers with a PICT
  218.  
  219.     SetCurrentVideoExplorer(VX2);
  220.     ResPictToBuffer(kPict2ID, kDrawCentered);
  221.  
  222.     SetCurrentVideoExplorer(VX1);
  223.     ResPictToBuffer(kPict1ID, kDrawCentered);
  224.     }
  225.  
  226.  
  227. //------------------------------------------------------------
  228. // RouteTwoCards
  229. //
  230. //    Make DVP1 on card 2 send to DVP1 on card 1. This should be
  231. //    done differently with the new VBCluster code when that is
  232. //    available!!
  233. //------------------------------------------------------------
  234.  
  235. static void RouteTwoCards(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
  236.     {
  237.     // Ideally we should use the new tology code to check for connections
  238.     // instead of hard coding how digital video ports are wired together
  239.     // over VideoBahn. Also we should use the higher level routing API
  240.     // for setting the route. But that code isn't ready yet. Thus we will
  241.     // do it manually.
  242.     //
  243.     // Here is some important information on VideoBahn topologies:
  244.     //
  245.     //    Card1    Card2
  246.     //    ==============
  247.     //    DVP1-----DVP1
  248.     //    DVP2-----DVP2
  249.     //
  250.     //
  251.     //    Card1    Card2    Card3
  252.     //    =======================
  253.     //    DVP1-----DVP1     DVP1--+
  254.     // +--DVP2     DVP2-----DVP2  |
  255.     // |                          |
  256.     // +--------------------------+
  257.     //
  258.     //
  259.     //    Card1    Card2    Card3    Card4
  260.     //    ================================
  261.     //    DVP1-----DVP1     DVP1-----DVP1
  262.     // +--DVP2     DVP2-----DVP2     DVP2--+
  263.     // |                                   |
  264.     // +-----------------------------------+
  265.  
  266.     VBPort::EDVPNumber Card1InputDVP  = VBPort::kDVP1;
  267.     VBPort::EDVPNumber Card2OutputDVP = VBPort::kDVP1;
  268.  
  269.     // First disable all ports for output.
  270.     // Never drive two outputs connected to each other.
  271.  
  272.     DisableAllVBOutputs();
  273.  
  274.     // Enable the second card's DVP output on VideoBahn
  275.  
  276.     VBPort* port1 = VX1->GetVBPort(Card1InputDVP);    // Get ports
  277.     VBPort* port2 = VX2->GetVBPort(Card2OutputDVP);
  278.  
  279.     VBPortAccessor portAccessorCard1(port1);        // Create port accessors
  280.     VBPortAccessor portAccessorCard2(port2);        // In the future this will be evil!
  281.  
  282.     portAccessorCard1.EnableForOutput(false);        // The other card will output. Disable this one.
  283.     portAccessorCard2.EnableForOutput(true);        // Output to the connected DVP(s)
  284.  
  285.     // There are two Digital Video Ports connected to VideoBahn,
  286.     // but there is only one input the Video Explorer can use at
  287.     // any given time. Thus we must select which of the DVPs we
  288.     // want to be our input.
  289.  
  290.     VX1->SelectVideoBahnInChannel(TVXVideoDevice::kSelectDVP1);
  291.     }
  292.  
  293. //------------------------------------------------------------
  294. // DisableAllVBOutputs
  295. //
  296. //    This disables all Digital Video Port outputs on VideoBahn.
  297. //------------------------------------------------------------
  298.  
  299. static void DisableAllVBOutputs()
  300.     {
  301.     TModularVideoDevice* device;
  302.  
  303.     GetFirstVideoDevice(device);
  304.     while (device != NULL)
  305.         {
  306.         VBPort* port1 = device->GetVBPort(VBPort::kDVP1);
  307.         VBPort* port2 = device->GetVBPort(VBPort::kDVP2);
  308.  
  309.         if (port1 != NULL)
  310.             {
  311.             VBPortAccessor portAccessor(port1);
  312.             portAccessor.EnableForOutput(false);
  313.             }
  314.  
  315.         if (port2 != NULL)
  316.             {
  317.             VBPortAccessor portAccessor(port2);
  318.             portAccessor.EnableForOutput(false);
  319.             }
  320.  
  321.         GetNextVideoDevice(device, device);
  322.         }
  323.     }
  324.  
  325.  
  326. //------------------------------------------------------------
  327. // DelayTillVBL
  328. //
  329. //    Wait for VBL. This polls!!
  330. //------------------------------------------------------------
  331.  
  332. static void DelayTillVBL(TVXVideoDevice* VX, int numDelays)
  333.     {
  334.     FrameBufferComponent_VX* frameBuffer = VX->GetFrameBufferComponent();
  335.     int lastLine = frameBuffer->ActiveLines();
  336.  
  337.     for (int i = 0; i < numDelays; i++)
  338.         {
  339.         CPoint here = VX->GetBeamPosition();
  340.         while (here.v > lastLine)
  341.             here = VX->GetBeamPosition();
  342.         while (here.v <= lastLine)
  343.             here = VX->GetBeamPosition();
  344.         }
  345.     }
  346.  
  347.  
  348. //------------------------------------------------------------
  349. // SysInit
  350. //
  351. //    Do MacOS Specific initialization
  352. //------------------------------------------------------------
  353.  
  354. static void SysInit()
  355.     {
  356.     InitGraf(&qd.thePort);    // initialize QuickDraw globals
  357.  
  358.     InitFonts();
  359.     InitWindows();
  360.     InitMenus();
  361.     TEInit();
  362.     InitDialogs(nil);
  363.     InitCursor();
  364.     }
  365.  
  366.  
  367.