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 >
Wrap
Text File
|
1996-10-10
|
11KB
|
367 lines
// TwoCardDemo.cp
//-------------------------------------------------------------------------
// Copyright (c) 1995
// INTELLIGENT RESOURCES INTEGRATED SYSTEMS INC.
// All Rights Reserved.
//
// This is unpublished work and is the proprietary source code of
// INTELLIGENT RESOURCES INTEGRATED SYSTEMS INC.
// and should be treated as confidential
//-------------------------------------------------------------------------
//
// This demonstrates sending video from a second card over VideoBahn.
//
// This demo is simplified to show the use of VideoBahn components.
// However a future library should provide a higher level interface
// for VideoBahn routing with automatic timing equalization.
//
// Note: Due to a bug in the Gyro 3.3.6 release, timing is not
// automatically equalized, but for a two card configuration, this
// can be done by setting the hsync value to -7 in the timing tool.
//
// Author Reviewed By Date Description
// ------ ----------- ---- -----------
// JDZ 10-Oct-96 Started today.
//
//-------------------------------------------------------------------------
#ifndef __FONTS__
#include <Fonts.h>
#endif
#ifndef __WINDOWS__
#include <Windows.h>
#endif
#ifndef __MENUS__
#include <Menus.h>
#endif
#ifndef __TEXTEDIT__
#include <TextEdit.h>
#endif
#ifndef __DIALOGS__
#include <Dialogs.h>
#endif
#ifndef __EVENTS__
#include <events.h>
#endif
#ifndef VXServices_h
#include "VXServices.h"
#endif
#ifndef VideoDeviceKernel_h
#include "VideoDeviceKernel.h"
#endif
#ifndef VXMediaComponents_h
#include "VXMediaComponents.h"
#endif
#ifndef VBPort_h
#include "VBPort.h"
#endif
#ifndef VBComponent_h
#include "VBComponent.h"
#endif
#ifndef VXDevice_h
#include "VXDevice.h"
#endif
//-------------------------------------------------------------------------
// Local prototypes
//-------------------------------------------------------------------------
static void TwoCardTest(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
static void LoadFrameBuffers(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
static void RouteTwoCards(TVXVideoDevice* VX1, TVXVideoDevice* VX2);
static void DisableAllVBOutputs();
static void DelayTillVBL(TVXVideoDevice* VX, int numDelays);
static void SysInit();
//-------------------------------------------------------------------------
// Constants
//-------------------------------------------------------------------------
const int kPict1ID = 128;
const int kPict2ID = 129;
//-------------------------------------------------------------------------
//------------------------------------------------------------
// VBPortAccessor
//
// This is a temporary work around until the VBCluster class
// is available. This is *not* multiport aware, and must be
// used with caution. Never drive two connected VideoBahn
// outputs at the same time.
//
// Use the function DisableAllVBOutputs before enabling
// specific VideoBahnPorts for output
//------------------------------------------------------------
class VBPortAccessor
{
public:
VBPortAccessor(VBPort* port);
void EnableForOutput(bool enable);
private:
VBPort* fPort;
};
inline VBPortAccessor::VBPortAccessor(VBPort* port) : fPort(port) { }
inline void VBPortAccessor::EnableForOutput(bool enable) { fPort->EnableForOutput(enable); }
//-------------------------------------------------------------------------
int main()
{
SysInit(); // Do MacOS initialization
VXServicesInit(); // Do initialization for VX Services
TVXVideoDevice* VX1 = NULL; // Video Explorer objects
TVXVideoDevice* VX2 = NULL;
GetFirstVideoDevice(VX1); // Get the first Video Explorer
if (VX1 != NULL)
GetNextVideoDevice(VX1, VX2); // Get the second Video Explorer
if (VX1 != NULL && VX2 != NULL)
{
TwoCardTest(VX1, VX2); // Test two card functionality
}
return 0;
}
//------------------------------------------------------------
// TwoCardTest
//
// This is a limited sample which only works with a system
// with two Video Explorer cards, and assumes the VideoBahn
// topology provided by a VideoBahn-2 connector.
//------------------------------------------------------------
static void TwoCardTest(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
{
if (VX1 && VX2)
{
// Get media components we will work with
// These are the basic building blocks to piece together effects
// and set up various video configurations.
FrameBufferComponent_VX* frameBuffer1 = VX1->GetFrameBufferComponent(); // The frame buffer
VideoBahnComponent_VX* videoBahn1 = VX1->GetVideoBahnComponent(); // VideoBahn component
BlenderComponent_VX* blender1 = VX1->GetBlenderComponent(); // A video mixer
BackgroundComponent_VX* background1 = VX1->GetBackgroundComponent(); // The background (default display source)
// Get media components for second card
VideoBahnComponent_VX* videoBahn2 = VX2->GetVideoBahnComponent(); // VideoBahn component
FrameBufferComponent_VX* frameBuffer2 = VX2->GetFrameBufferComponent(); // The frame buffer
// Do all the VideoBahn routing
RouteTwoCards(VX1, VX2);
// Load both frame buffers with PICTs
LoadFrameBuffers(VX1, VX2);
//------------ Display the frame buffer of our card.
*background1->GetInput() << frameBuffer1->GetOutput(); // Display from frame buffer
//------------ Do a cut to the other frame buffer.
*videoBahn2->GetInput() << frameBuffer2->GetOutput(); // Output second card's frame buffer
DelayTillVBL(VX1, 100); // Wait 100 VBLs
*background1->GetInput() << videoBahn1->GetOutput(); // Display from VideoBahn input
//------------ Do a blend of the two frame buffers.
*blender1->GetInput(0) << frameBuffer1->GetOutput(); // Source 1 is our frame buffer
*blender1->GetInput(1) << videoBahn1->GetOutput(); // Source 2 is from the other card
blender1->SetICFs(0.5, 0.5); // Set the Image Contribution Factors for a 50-50 blend
DelayTillVBL(VX1, 100); // Wait 100 VBLs
*background1->GetInput() << blender1->GetOutput(); // Display output of the blender
//------------ Go back to frame buffer on our card
DelayTillVBL(VX1, 100); // Wait 100 VBLs
*background1->GetInput() << frameBuffer1->GetOutput(); // Display from frame buffer
}
}
//------------------------------------------------------------
// LoadFrameBuffers
//
// This disables all Digital Video Port outputs on VideoBahn.
//------------------------------------------------------------
static void LoadFrameBuffers(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
{
// Load both frame buffers with a PICT
SetCurrentVideoExplorer(VX2);
ResPictToBuffer(kPict2ID, kDrawCentered);
SetCurrentVideoExplorer(VX1);
ResPictToBuffer(kPict1ID, kDrawCentered);
}
//------------------------------------------------------------
// RouteTwoCards
//
// Make DVP1 on card 2 send to DVP1 on card 1. This should be
// done differently with the new VBCluster code when that is
// available!!
//------------------------------------------------------------
static void RouteTwoCards(TVXVideoDevice* VX1, TVXVideoDevice* VX2)
{
// Ideally we should use the new tology code to check for connections
// instead of hard coding how digital video ports are wired together
// over VideoBahn. Also we should use the higher level routing API
// for setting the route. But that code isn't ready yet. Thus we will
// do it manually.
//
// Here is some important information on VideoBahn topologies:
//
// Card1 Card2
// ==============
// DVP1-----DVP1
// DVP2-----DVP2
//
//
// Card1 Card2 Card3
// =======================
// DVP1-----DVP1 DVP1--+
// +--DVP2 DVP2-----DVP2 |
// | |
// +--------------------------+
//
//
// Card1 Card2 Card3 Card4
// ================================
// DVP1-----DVP1 DVP1-----DVP1
// +--DVP2 DVP2-----DVP2 DVP2--+
// | |
// +-----------------------------------+
VBPort::EDVPNumber Card1InputDVP = VBPort::kDVP1;
VBPort::EDVPNumber Card2OutputDVP = VBPort::kDVP1;
// First disable all ports for output.
// Never drive two outputs connected to each other.
DisableAllVBOutputs();
// Enable the second card's DVP output on VideoBahn
VBPort* port1 = VX1->GetVBPort(Card1InputDVP); // Get ports
VBPort* port2 = VX2->GetVBPort(Card2OutputDVP);
VBPortAccessor portAccessorCard1(port1); // Create port accessors
VBPortAccessor portAccessorCard2(port2); // In the future this will be evil!
portAccessorCard1.EnableForOutput(false); // The other card will output. Disable this one.
portAccessorCard2.EnableForOutput(true); // Output to the connected DVP(s)
// There are two Digital Video Ports connected to VideoBahn,
// but there is only one input the Video Explorer can use at
// any given time. Thus we must select which of the DVPs we
// want to be our input.
VX1->SelectVideoBahnInChannel(TVXVideoDevice::kSelectDVP1);
}
//------------------------------------------------------------
// DisableAllVBOutputs
//
// This disables all Digital Video Port outputs on VideoBahn.
//------------------------------------------------------------
static void DisableAllVBOutputs()
{
TModularVideoDevice* device;
GetFirstVideoDevice(device);
while (device != NULL)
{
VBPort* port1 = device->GetVBPort(VBPort::kDVP1);
VBPort* port2 = device->GetVBPort(VBPort::kDVP2);
if (port1 != NULL)
{
VBPortAccessor portAccessor(port1);
portAccessor.EnableForOutput(false);
}
if (port2 != NULL)
{
VBPortAccessor portAccessor(port2);
portAccessor.EnableForOutput(false);
}
GetNextVideoDevice(device, device);
}
}
//------------------------------------------------------------
// DelayTillVBL
//
// Wait for VBL. This polls!!
//------------------------------------------------------------
static void DelayTillVBL(TVXVideoDevice* VX, int numDelays)
{
FrameBufferComponent_VX* frameBuffer = VX->GetFrameBufferComponent();
int lastLine = frameBuffer->ActiveLines();
for (int i = 0; i < numDelays; i++)
{
CPoint here = VX->GetBeamPosition();
while (here.v > lastLine)
here = VX->GetBeamPosition();
while (here.v <= lastLine)
here = VX->GetBeamPosition();
}
}
//------------------------------------------------------------
// SysInit
//
// Do MacOS Specific initialization
//------------------------------------------------------------
static void SysInit()
{
InitGraf(&qd.thePort); // initialize QuickDraw globals
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
InitCursor();
}