lms-video/Gem/plugins/videoSGI/videoSGI.cpp
Santi Noreña e85d191b46 - Reestructuración de ficheros y directorios general
- merge v0.01 --> Añadido fileselector
- Añadidas fuentes de Gem y Pure Data
- pix2jpg incluído en Gem. Archivos de construcción de Gem modificados.
- Añadido fichero ompiling.txt con instrucciones de compilación
2013-02-04 18:00:17 +01:00

401 lines
9.6 KiB
C++

////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// zmoelnig@iem.kug.ac.at
//
// Implementation file
//
// Copyright (c) 1997-1998 Mark Danks.
// Copyright (c) Günther Geiger.
// Copyright (c) 2001-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
//
/////////////////////////////////////////////////////////
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "videoSGI.h"
#include "plugins/PluginFactory.h"
using namespace gem::plugins;
#include "Gem/RTE.h"
#ifdef HAVE_VL_VL_H
# include <unistd.h>
# include <dmedia/vl_vino.h>
REGISTER_VIDEOFACTORY("sgi", videoSGI);
/*
from pix_indycam:
"zoom" -> zoomMess
"bright" -> brightMess
"contrast" -> contrastMess
"hue" -> hueMess
"sat" -> satMess
*/
/////////////////////////////////////////////////////////
//
// video
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
videoSGI :: videoSGI()
: videoBase("sgi", 0),
m_haveVideo(0), m_swap(1), m_colorSwap(0),
m_svr(NULL), m_drn(NULL), m_src(NULL), m_path(NULL)
{
provide("indy");
provide("analog");
}
////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
videoSGI :: ~videoSGI()
{
stopTransfer();
close();
cleanPixBlock();
}
bool videoSGI :: openDevice()
{
// Connect to the daemon
if ( !(m_svr = vlOpenVideo("")) )
{
error("GEM: videoSGI: Unable to open video");
goto cleanup;
}
// Set up a drain node in memory
m_drn = vlGetNode(m_svr, VL_DRN, VL_MEM, VL_ANY);
// Set up a source node on any video source
m_src = vlGetNode(m_svr, VL_SRC, VL_VIDEO, VL_ANY);
// Create a path using the first device that will support it
m_path = vlCreatePath(m_svr, VL_ANY, m_src, m_drn);
// Set up the hardware for and define the usage of the path
if ( (vlSetupPaths(m_svr, (VLPathList)&m_path, 1, VL_SHARE, VL_SHARE)) < 0 )
{
error("GEM: videoSGI: Unable to setup video path");
goto cleanup;
}
// Set the packing to RGBA
VLControlValue val;
// first try to see if it can handle RGBA format
// according to vl.h, this is really RGBA (OpenGL format)
val.intVal = VL_PACKING_ABGR_8;
if ( vlSetControl(m_svr, m_path, m_drn, VL_PACKING, &val) )
{
// nope, so try ABGR, and set the color swapping
// according to vl.h, this is really ABGR (IrisGL format)
val.intVal = VL_PACKING_RGBA_8;
if ( vlSetControl(m_svr, m_path, m_drn, VL_PACKING, &val) )
{
post("GEM: videoSGI: Unable to set the video packing");
goto cleanup;
}
post("GEM: videoSGI: Video has to color swap (ABGR to RGBA)");
m_colorSwap = 1;
}
// Get the video size
VLControlValue value;
if(m_width>0) {
value.xyVal.x = m_width;
value.xyVal.y = m_height;
if ( vlSetControl(m_svr, m_path, m_drn, VL_SIZE, &value) ) {
vlGetControl(m_svr, m_path, m_drn, VL_SIZE, &value);
post("GEM: videoSGI: dimen error: wanted %dx%d got %dx%d", m_width, m_height, value.xyVal.x, value.xyVal.y);
m_width =value.xyVal.x;
m_height=value.xyVal.y;
}
}
vlGetControl(m_svr, m_path, m_drn, VL_SIZE, &value);
m_width =value.xyVal.x;
m_height=value.xyVal.y;
m_pixBlock.image.xsize = m_width;
m_pixBlock.image.ysize = m_height;
m_pixBlock.image.reallocate();
return true;
cleanup:
closeDevice();
return false;
}
void videoSGI :: closeDevice() {
m_src=NULL;
m_drn=NULL;
if(m_svr) {
if(m_path)
vlDestroyPath(m_svr, m_path);
vlCloseVideo(m_svr);
}
m_path=NULL;
m_svr=NULL;
}
////////////////////////////////////////////////////////
// render
//
/////////////////////////////////////////////////////////
pixBlock *videoSGI::getFrame(void) {
{
if(!(m_haveVideo && m_capturing))return NULL;
VLInfoPtr info = vlGetLatestValid(m_svr, m_buffer);
while (!info)
{
sginap(1);
info = vlGetLatestValid(m_svr, m_buffer);
}
// Get a pointer to the frame
unsigned char *dataPtr = (unsigned char *)(vlGetActiveRegion(m_svr, m_buffer, info));
m_pixBlock.image.fromABGR(dataPtr);
// free the frame
vlPutFree(m_svr, m_buffer);
m_pixBlock.newimage = 1;
return &m_pixBlock;
}
////////////////////////////////////////////////////////
// startTransfer
//
/////////////////////////////////////////////////////////
bool videoSGI :: startTransfer()
{
if(NULL=m_svr || NULL=m_path || NULL==m_drn || NULL=m_src)return false;
// Create and register a buffer for 1 frame
m_buffer = vlCreateBuffer(m_svr, m_path, m_drn, 1);
if ( !m_buffer )
{
error("GEM: videoSGI: Unable to allocate buffer");
return false;
}
vlRegisterBuffer(m_svr, m_path, m_drn, m_buffer);
// Begin the data transfer
if ( vlBeginTransfer(m_svr, m_path, 0, NULL) )
{
error("GEM: videoSGI: Unable to start video transfer");
vlDeregisterBuffer(m_svr, m_path, m_drn, m_buffer);
vlDestroyBuffer(m_svr, m_buffer);
return false;
}
return true;
}
////////////////////////////////////////////////////////
// stopTransfer
//
/////////////////////////////////////////////////////////
bool videoSGI :: stopTransfer()
{
if ( !m_capturing ) return false;
if(NULL=m_svr || NULL=m_path || NULL==m_drn || NULL=m_src)return false;
// Clean up the buffer
vlEndTransfer(m_svr, m_path);
vlDeregisterBuffer(m_svr, m_path, m_drn, m_buffer);
vlDestroyBuffer(m_svr, m_buffer);
m_buffer=NULL;
return true;
}
#if 0
////////////////////////////////////////////////////////
// offsetMess
//
/////////////////////////////////////////////////////////
void videoSGI :: offsetMess(int x, int y)
{
if (!m_haveVideo)
{
post("GEM: videoSGI: Connect to video first");
return;
}
// stop the transfer and destroy the buffer
if ( !stopTransfer() )
{
post("GEM: videoSGI: error stopping transfer");
return;
}
VLControlValue value;
value.xyVal.x = x;
value.xyVal.y = y;
if ( vlSetControl(m_svr, m_path, m_drn, VL_OFFSET, &value) )
{
post("GEM: videoSGI: offset error");
startTransfer();
return;
}
// start the transfer and rebuild the buffer
if ( !startTransfer() )
{
post("GEM: videoSGI: error starting transfer");
return;
}
}
/////////////////////////////////////////////////////////
// zoomMess
//
/////////////////////////////////////////////////////////
void videoINDY :: zoomMess(int num, int denom)
{
if (!m_haveVideo)
{
error("Connect to video first");
return;
}
VLControlValue value;
value.fractVal.numerator = num;
value.fractVal.denominator = denom;
if ( vlSetControl(m_svr, m_path, m_drn, VL_ZOOM, &value) )
error("zoom error");
}
/////////////////////////////////////////////////////////
// brightMess
//
/////////////////////////////////////////////////////////
void videoINDY :: brightMess(int val)
{
if (!m_haveVideo)
{
error("Connect to video first");
return;
}
VLControlValue value;
value.intVal = val;
if ( vlSetControl(m_svr, m_path, m_drn, VL_BRIGHTNESS, &value) )
error("problem setting brightness");
}
/////////////////////////////////////////////////////////
// contrastMess
//
/////////////////////////////////////////////////////////
void videoINDY :: contrastMess(int val)
{
if (!m_haveVideo)
{
error("Connect to video first");
return;
}
VLControlValue value;
value.intVal = val;
if ( vlSetControl(m_svr, m_path, m_drn, VL_CONTRAST, &value) )
error("problem setting contrast");
}
/////////////////////////////////////////////////////////
// hueMess
//
/////////////////////////////////////////////////////////
void videoINDY :: hueMess(int val)
{
if (!m_haveVideo)
{
error("Connect to video first");
return;
}
VLControlValue value;
value.intVal = val;
if ( vlSetControl(m_svr, m_path, m_drn, VL_HUE, &value) )
error("problem setting hue");
}
/////////////////////////////////////////////////////////
// satMess
//
/////////////////////////////////////////////////////////
void videoINDY :: satMess(int val)
{
if (!m_haveVideo)
{
error("Connect to video first");
return;
}
VLControlValue value;
value.intVal = val;
if ( vlSetControl(m_svr, m_path, m_src, VL_VINO_INDYCAM_SATURATION, &value) )
error("problem setting saturation");
}
#endif
///////////////////////////////////////////////////////
// dimenMess
//
////////////////////////////////////////////////////////
bool videoSGI :: setDimen(int x, int y, int leftmargin, int rightmargin, int topmargin, int bottommargin){
{
bool result=true;
m_width=x;
m_height=y
if(NULL=m_svr || NULL=m_path || NULL==m_drn || NULL=m_src)return false;
if(!m_capturing)return false;
stopTransfer();
VLControlValue value;
value.xyVal.x = m_width;
value.xyVal.y = m_height;
if ( vlSetControl(m_svr, m_path, m_drn, VL_SIZE, &value) ) {
vlGetControl(m_svr, m_path, m_drn, VL_SIZE, &value);
post("GEM: videoSGI: dimen error: wanted %dx%d got %dx%d", m_width, m_height, value.xyVal.x, value.xyVal.y);
m_width =value.xyVal.x;
m_height=value.xyVal.y;
result=false;
}
m_pixBlock.image.xsize = m_width;
m_pixBlock.image.ysize = m_height;
m_pixBlock.image.reallocate();
start();
return result;
}
#else /* !HAVE_VL_VL_H */
videoSGI :: videoSGI() : videoBase("") { }
videoSGI :: ~videoSGI() { }
#endif /* !HAVE_VL_VL_H */