- 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
		
			
				
	
	
		
			299 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			299 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// GEM - Graphics Environment for Multimedia
 | 
						|
//
 | 
						|
// zmoelnig@iem.kug.ac.at
 | 
						|
//
 | 
						|
// Implementation file 
 | 
						|
//
 | 
						|
//    Copyright (c) 1997-1999 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
 | 
						|
 | 
						|
#ifdef HAVE_LIBVFW32
 | 
						|
# ifndef HAVE_VFW_H
 | 
						|
#  define HAVE_VFW_H
 | 
						|
# endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef HAVE_VFW_H
 | 
						|
#include "videoVFW.h"
 | 
						|
#include "plugins/PluginFactory.h"
 | 
						|
using namespace gem::plugins;
 | 
						|
#include "Gem/RTE.h"
 | 
						|
 | 
						|
 | 
						|
/* MinGW headers seem to be incomplete */
 | 
						|
#ifndef AVSTREAMMASTER_NONE
 | 
						|
#define AVSTREAMMASTER_NONE 1
 | 
						|
#endif
 | 
						|
 | 
						|
REGISTER_VIDEOFACTORY("VFW", videoVFW);
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// videoVFW
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// Constructor
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
videoVFW :: videoVFW(void)
 | 
						|
  : videoBase("vfw", 0), 
 | 
						|
    m_hWndC(NULL)
 | 
						|
{
 | 
						|
  provide("dv");
 | 
						|
  provide("iidc");
 | 
						|
  provide("analog");
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// Destructor
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
videoVFW :: ~videoVFW(void)
 | 
						|
{
 | 
						|
  close();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// openDevice
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
bool videoVFW :: openDevice(gem::Properties&props)
 | 
						|
{
 | 
						|
  char driverName[256];
 | 
						|
  char driverDesc[256];
 | 
						|
  if (capGetDriverDescription(0, driverName, 256, driverDesc, 256))
 | 
						|
    post("videoVFW: driver '%s'", driverName);
 | 
						|
 | 
						|
 | 
						|
  double d;
 | 
						|
  if (props.get("width", d))
 | 
						|
    m_width=d;
 | 
						|
 | 
						|
  if (props.get("height", d))
 | 
						|
    m_height=d;
 | 
						|
 | 
						|
  if(m_hWndC)closeDevice();
 | 
						|
  
 | 
						|
  // Connect to the daemon
 | 
						|
  m_hWndC = capCreateCaptureWindow ((LPSTR) "GEM video",	// window name if pop-up 
 | 
						|
				    0,				// window style (not visible)
 | 
						|
				    0, 0, m_width, m_height,// window position and dimensions
 | 
						|
				    GetDesktopWindow(), 0);
 | 
						|
  if (!m_hWndC) {
 | 
						|
    error("Unable to create capture window");
 | 
						|
    return false;
 | 
						|
  } 
 | 
						|
 | 
						|
  if (!capDriverConnect(m_hWndC, 0)) {
 | 
						|
    error("Unable to connect to video driver");
 | 
						|
    closeDevice();
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  CAPTUREPARMS params;
 | 
						|
  if (!capCaptureGetSetup(m_hWndC, ¶ms, sizeof(CAPTUREPARMS))) {
 | 
						|
    error("Unable to get capture parameters");
 | 
						|
    closeDevice();
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  params.fYield = TRUE;
 | 
						|
  params.fCaptureAudio = FALSE;
 | 
						|
  params.wPercentDropForError = 100;
 | 
						|
  params.fLimitEnabled = FALSE;
 | 
						|
  params.AVStreamMaster = AVSTREAMMASTER_NONE;
 | 
						|
  params.fStepCaptureAt2x = FALSE;
 | 
						|
  params.fAbortLeftMouse = FALSE;
 | 
						|
  params.fAbortRightMouse = FALSE;
 | 
						|
  if (!capCaptureSetSetup(m_hWndC, ¶ms, sizeof(CAPTUREPARMS)))
 | 
						|
    {
 | 
						|
      error("Unable to set capture parameters");
 | 
						|
      closeDevice();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!capSetCallbackOnVideoStream(m_hWndC, videoVFW::videoFrameCallback))
 | 
						|
    {
 | 
						|
      error("Unable to set frame callback");
 | 
						|
      closeDevice();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  if (!capSetUserData(m_hWndC, this))
 | 
						|
    {
 | 
						|
      error("Unable to set user data");
 | 
						|
      closeDevice();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  DWORD formSize = capGetVideoFormat(m_hWndC, NULL, 0);
 | 
						|
  BITMAPINFO *videoFormat = (BITMAPINFO *)(new char[formSize]);
 | 
						|
  if (!capGetVideoFormat(m_hWndC, videoFormat, formSize))
 | 
						|
    {
 | 
						|
      error("Unable to get video format");
 | 
						|
      closeDevice();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
  videoFormat->bmiHeader.biWidth = m_width;
 | 
						|
  videoFormat->bmiHeader.biHeight = m_height;
 | 
						|
  videoFormat->bmiHeader.biBitCount = 24;
 | 
						|
  videoFormat->bmiHeader.biCompression = BI_RGB;
 | 
						|
  videoFormat->bmiHeader.biClrUsed = 0;
 | 
						|
  videoFormat->bmiHeader.biClrImportant = 0;
 | 
						|
  videoFormat->bmiHeader.biSizeImage = 0;
 | 
						|
  if (!capSetVideoFormat(m_hWndC, videoFormat, formSize)) {
 | 
						|
      error("Unable to set video format");
 | 
						|
      delete videoFormat;
 | 
						|
      closeDevice();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  if (!capGetVideoFormat(m_hWndC, videoFormat, formSize)) {
 | 
						|
    error("Unable to get video format");
 | 
						|
  }
 | 
						|
  m_width=static_cast<int>(videoFormat->bmiHeader.biWidth);
 | 
						|
  m_height=static_cast<int>(videoFormat->bmiHeader.biHeight);
 | 
						|
 | 
						|
  verbose(1, "Connected with %dx%d @ %d",
 | 
						|
          m_width, m_height,
 | 
						|
          static_cast<int>(videoFormat->bmiHeader.biBitCount));
 | 
						|
 | 
						|
  delete videoFormat;
 | 
						|
 | 
						|
  m_image.image.xsize = m_width;
 | 
						|
  m_image.image.ysize = m_height;
 | 
						|
  m_image.image.setCsizeByFormat(GL_RGBA);
 | 
						|
 | 
						|
  m_image.image.reallocate();
 | 
						|
  m_image.image.setBlack();
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// closeDevice
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
void videoVFW :: closeDevice(void)
 | 
						|
{
 | 
						|
  if (m_hWndC) {
 | 
						|
    capDriverDisconnect(m_hWndC);
 | 
						|
    DestroyWindow(m_hWndC);
 | 
						|
  }
 | 
						|
  m_hWndC=NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// videoFrame callback
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
void videoVFW :: videoFrame(LPVIDEOHDR lpVHdr)
 | 
						|
{
 | 
						|
  int count = lpVHdr->dwBytesUsed;
 | 
						|
  // notice that it is times 3 for the color!
 | 
						|
  // incoming data is BGR
 | 
						|
  const int dataSize = m_image.image.xsize * m_image.image.ysize * 3;
 | 
						|
 | 
						|
  if (count < dataSize)
 | 
						|
    {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  lock();
 | 
						|
  m_image.image.fromBGR(lpVHdr->lpData);
 | 
						|
  m_image.newimage = true;
 | 
						|
  unlock();
 | 
						|
}
 | 
						|
void videoVFW :: videoFrameCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
 | 
						|
{
 | 
						|
  videoVFW*ptr = reinterpret_cast<videoVFW*>(capGetUserData(hWnd));
 | 
						|
  ptr->videoFrame(lpVHdr);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// render
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
bool videoVFW :: grabFrame(void)
 | 
						|
{
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// startTransfer
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
bool videoVFW :: startTransfer(void)
 | 
						|
{
 | 
						|
  bool result= capCaptureSequenceNoFile(m_hWndC);
 | 
						|
  m_image.newfilm=result;
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// stopTransfer
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
bool videoVFW :: stopTransfer(void)
 | 
						|
{
 | 
						|
  capCaptureStop(m_hWndC);
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
// csMess
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////
 | 
						|
bool videoVFW :: setColor(int format)
 | 
						|
{
 | 
						|
  if(format)m_image.image.setCsizeByFormat(format);
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
bool videoVFW :: enumProperties(gem::Properties&readable, gem::Properties&writeable) {
 | 
						|
  readable.clear();
 | 
						|
  writeable.clear();
 | 
						|
 | 
						|
  gem::any type=0;
 | 
						|
 | 
						|
  writeable.set("width", type);
 | 
						|
  writeable.set("height", type);
 | 
						|
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void videoVFW :: setProperties(gem::Properties&props) {
 | 
						|
  double d;
 | 
						|
  bool dorestart=false;
 | 
						|
 | 
						|
  if (props.get("width", d)) {
 | 
						|
    m_width=d;
 | 
						|
    dorestart=true;
 | 
						|
  }
 | 
						|
 | 
						|
  if (props.get("height", d)) {
 | 
						|
    m_height=d;
 | 
						|
    dorestart=true;
 | 
						|
  }
 | 
						|
 | 
						|
  if(dorestart && m_hWndC)
 | 
						|
    reset();
 | 
						|
}
 | 
						|
void videoVFW :: getProperties(gem::Properties&props) {
 | 
						|
}
 | 
						|
 | 
						|
#endif /* HAVE_VFW */
 |