- 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
689 lines
19 KiB
C++
689 lines
19 KiB
C++
/*
|
|
* videoDarwin.cpp
|
|
* gem_darwin
|
|
*
|
|
* Created by James Tittle on Fri Jul 12 2002.
|
|
* Copyright (c) 2002-2005 James Tittle & Chris Clepper
|
|
* Copyright (c) 2010-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
|
|
*
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#if defined __APPLE__ && defined __x86_64
|
|
#warning unconditionally disabling QuickTime/Carbon on OSX/64bit
|
|
// with OSX10.6, apple has removed loads of Carbon functionality (in 64bit mode)
|
|
// LATER make this a real check in configure
|
|
# undef HAVE_QUICKTIME
|
|
# undef HAVE_CARBON
|
|
#endif
|
|
|
|
#if defined HAVE_CARBON && defined HAVE_QUICKTIME
|
|
# define HAVE_VIDEODARWIN
|
|
#endif
|
|
|
|
#ifdef HAVE_VIDEODARWIN
|
|
#include "videoDarwin.h"
|
|
#include "Gem/RTE.h"
|
|
#include "plugins/PluginFactory.h"
|
|
|
|
using namespace gem::plugins;
|
|
|
|
#include <unistd.h> // needed for Unix file open() type functions
|
|
#include <stdio.h>
|
|
#include <fcntl.h> /* JMZ thinks that _this_ is needed for open() */
|
|
|
|
#define DEFAULT_WIDTH 320
|
|
#define DEFAULT_HEIGHT 240
|
|
|
|
static std::string pascal2str(const Str255 pstr) {
|
|
const unsigned char*cstr=static_cast<const unsigned char*>(pstr);
|
|
const char*str=(const char*)(cstr+1);
|
|
const size_t length=cstr[0];
|
|
return std::string(str, length);
|
|
}
|
|
|
|
|
|
|
|
REGISTER_VIDEOFACTORY("Darwin", videoDarwin);
|
|
|
|
videoDarwin :: videoDarwin()
|
|
: videoBase("darwin", 0),
|
|
m_newFrame(false),
|
|
m_srcGWorld(NULL),
|
|
m_quality(channelPlayNormal),
|
|
m_colorspace(GL_YCBCR_422_GEM),
|
|
m_inputDevice(0) //set to the first input device
|
|
{
|
|
m_width= DEFAULT_WIDTH;
|
|
m_height=DEFAULT_HEIGHT;
|
|
|
|
m_image.image.xsize = 800;
|
|
m_image.image.ysize = 600;
|
|
m_image.image.setCsizeByFormat(GL_BGRA_EXT);
|
|
m_image.image.allocate();
|
|
|
|
//initSeqGrabber();
|
|
provide("dv");
|
|
provide("iidc");
|
|
provide("analog");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// Destructor
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
videoDarwin :: ~videoDarwin()
|
|
{
|
|
close();
|
|
if (m_vc) {
|
|
if (::SGDisposeChannel(m_sg, m_vc)) {
|
|
error ("Unable to dispose a video channel");
|
|
}
|
|
m_vc = NULL;
|
|
}
|
|
if (m_sg) {
|
|
if (::CloseComponent(m_sg)) {
|
|
error("Unable to dispose a sequence grabber component");
|
|
}
|
|
m_sg = NULL;
|
|
if (m_srcGWorld) {
|
|
::DisposeGWorld(m_srcGWorld);
|
|
m_srcGWorld = NULL;
|
|
}
|
|
}
|
|
}
|
|
bool videoDarwin :: openDevice(gem::Properties&props) {
|
|
applyProperties(props);
|
|
bool success=initSeqGrabber();
|
|
if(NULL==m_sg)success=false;
|
|
if(success)
|
|
applyProperties(props);
|
|
else
|
|
destroySeqGrabber();
|
|
|
|
return success;
|
|
}
|
|
void videoDarwin :: closeDevice(void) {
|
|
destroySeqGrabber();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// render
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
bool videoDarwin :: grabFrame()
|
|
{
|
|
OSErr err;
|
|
|
|
err = SGIdle(m_sg);
|
|
|
|
if (err != noErr){
|
|
error("SGIdle failed with error %d",err);
|
|
m_haveVideo = 0;
|
|
// return false;
|
|
} else {
|
|
//this doesn't do anything so far
|
|
//VDCompressDone(m_vdig,frameCount,data,size,similar,time);
|
|
//err = SGGrabFrameComplete(m_vc,frameCount,done);
|
|
//if (err != noErr) error("SGGrabCompressComplete failed with error %d",err);
|
|
//post("SGGrabFramecomplete done %d framecount = %d",done[0],frameCount);
|
|
|
|
m_haveVideo = 1;
|
|
m_newFrame = true;
|
|
}
|
|
if (!m_haveVideo)
|
|
{
|
|
post("no video yet");
|
|
return true;
|
|
}
|
|
m_image.newimage = m_newFrame;
|
|
m_newFrame = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// startTransfer
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
bool videoDarwin :: startTransfer()
|
|
{
|
|
OSErr err = noErr;
|
|
|
|
SGStartPreview(m_sg);
|
|
m_haveVideo = true;
|
|
m_image.newimage = true;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// stopTransfer
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
bool videoDarwin :: stopTransfer()
|
|
{
|
|
OSErr err = noErr;
|
|
|
|
//might need SGPause or SGStop here
|
|
err = SGStop(m_sg);
|
|
if (err != noErr)error("SGStop failed with error %d",err);
|
|
return true;
|
|
}
|
|
|
|
bool videoDarwin :: initSeqGrabber()
|
|
{
|
|
OSErr anErr;
|
|
Rect srcRect = {0,0, m_height, m_width};
|
|
SGDeviceList devices;
|
|
short deviceCount = 0;
|
|
|
|
m_sg = OpenDefaultComponent(SeqGrabComponentType, 0);
|
|
if(m_sg==NULL){
|
|
error("could not open default component");
|
|
return false;
|
|
}
|
|
anErr = SGInitialize(m_sg);
|
|
if(anErr!=noErr){
|
|
error("could not initialize SG error %d",anErr);
|
|
return false;
|
|
}
|
|
|
|
anErr = SGSetDataRef(m_sg, 0, 0, seqGrabDontMakeMovie);
|
|
if (anErr != noErr){
|
|
error("dataref failed with error %d",anErr);
|
|
}
|
|
|
|
anErr = SGNewChannel(m_sg, VideoMediaType, &m_vc);
|
|
if(anErr!=noErr){
|
|
error("could not make new SG channnel error %d",anErr);
|
|
return false;
|
|
}
|
|
|
|
enumerate();
|
|
anErr = SGGetChannelDeviceList(m_vc, sgDeviceListIncludeInputs, &devices);
|
|
if(anErr!=noErr){
|
|
error("could not get SG channnel Device List");
|
|
}else{
|
|
deviceCount = (*devices)->count;
|
|
m_inputDevice = (*devices)->selectedIndex;
|
|
}
|
|
|
|
/* device selection */
|
|
if(m_devicenum>=0)
|
|
m_inputDevice=m_devicenum;
|
|
else if (!m_devicename.empty()) {
|
|
int i;
|
|
const int maxcount=(deviceCount<m_devices.size()?deviceCount:m_devices.size());
|
|
for(i=0; i<maxcount; i++) {
|
|
if(m_devicename==m_devices[i]) {
|
|
m_inputDevice=i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//this call sets the input device
|
|
if (m_inputDevice >= 0 && m_inputDevice < deviceCount) {//check that the device is not out of bounds
|
|
std::string devname=pascal2str((*devices)->entry[m_inputDevice].name);
|
|
post("SGSetChannelDevice trying[%d] %s", m_inputDevice, devname.c_str());
|
|
}
|
|
anErr = SGSetChannelDevice(m_vc, (*devices)->entry[m_inputDevice].name);
|
|
if(anErr!=noErr) error("SGSetChannelDevice returned error %d",anErr);
|
|
|
|
anErr = SGSetChannelDeviceInput(m_vc,m_inputDeviceChannel);
|
|
if(anErr!=noErr) error("SGSetChannelDeviceInput returned error %d",anErr);
|
|
|
|
//grab the VDIG info from the SGChannel
|
|
m_vdig = SGGetVideoDigitizerComponent(m_vc);
|
|
VideoDigitizerError vdigErr = VDGetDigitizerInfo(m_vdig,&m_vdigInfo); //not sure if this is useful
|
|
|
|
Str255 vdigName;
|
|
memset(vdigName,0,255);
|
|
vdigErr = VDGetInputName(m_vdig,m_inputDevice,vdigName);
|
|
post("vdigName is %s",pascal2str(vdigName).c_str());
|
|
|
|
Rect vdRect;
|
|
vdigErr = VDGetDigitizerRect(m_vdig,&vdRect);
|
|
post("digitizer rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right);
|
|
|
|
vdigErr = VDGetActiveSrcRect(m_vdig,0,&vdRect);
|
|
post("active src rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right);
|
|
|
|
anErr = SGSetChannelBounds(m_vc, &srcRect);
|
|
if(anErr!=noErr){
|
|
error("could not set SG ChannelBounds ");
|
|
}
|
|
|
|
anErr = SGSetVideoRect(m_vc, &srcRect);
|
|
if(anErr!=noErr){
|
|
error("could not set SG Rect ");
|
|
}
|
|
|
|
anErr = SGSetChannelUsage(m_vc, seqGrabPreview);
|
|
if(anErr!=noErr){
|
|
error("could not set SG ChannelUsage ");
|
|
}
|
|
SGSetChannelPlayFlags(m_vc, m_quality);
|
|
OSType pixelFormat=0;
|
|
m_image.image.xsize = m_width;
|
|
m_image.image.ysize = m_height;
|
|
|
|
if (m_colorspace==GL_BGRA_EXT){
|
|
m_image.image.setCsizeByFormat(GL_RGBA_GEM);
|
|
m_rowBytes = m_width*4;
|
|
pixelFormat=k32ARGBPixelFormat;
|
|
post ("using RGB");
|
|
} else {
|
|
m_image.image.setCsizeByFormat(GL_YCBCR_422_APPLE);
|
|
m_rowBytes = m_width*2;
|
|
pixelFormat=k422YpCbCr8PixelFormat;
|
|
post ("using YUV");
|
|
}
|
|
m_image.image.reallocate();
|
|
anErr = QTNewGWorldFromPtr (&m_srcGWorld,
|
|
pixelFormat,
|
|
&srcRect,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
m_image.image.data,
|
|
m_rowBytes);
|
|
|
|
if (anErr!= noErr) {
|
|
error("%d error at QTNewGWorldFromPtr", anErr);
|
|
return false;
|
|
}
|
|
if (NULL == m_srcGWorld) {
|
|
error("could not allocate off screen");
|
|
return false;
|
|
}
|
|
SGSetGWorld(m_sg,(CGrafPtr)m_srcGWorld, NULL);
|
|
SGStartPreview(m_sg); //moved to starttransfer?
|
|
m_haveVideo = true;
|
|
return true;
|
|
}
|
|
|
|
void videoDarwin :: setupCapture()
|
|
{
|
|
if(stop()) {
|
|
SGSetChannelUsage(m_vc, 0);
|
|
SGSetChannelUsage(m_vc, seqGrabPreview);
|
|
SGUpdate(m_sg,0);
|
|
start();
|
|
}
|
|
}
|
|
|
|
void videoDarwin :: destroySeqGrabber()
|
|
{
|
|
if (m_vc) {
|
|
if (::SGDisposeChannel(m_sg, m_vc)) {
|
|
error ("Unable to dispose a video channel");
|
|
}
|
|
m_vc = NULL;
|
|
}
|
|
if (m_sg) {
|
|
if (::CloseComponent(m_sg)) {
|
|
error("Unable to dispose a sequence grabber component");
|
|
}
|
|
m_sg = NULL;
|
|
if (m_srcGWorld) {
|
|
::DisposeGWorld(m_srcGWorld);
|
|
m_srcGWorld = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void videoDarwin :: resetSeqGrabber()
|
|
{
|
|
OSErr anErr;
|
|
post ("starting reset");
|
|
|
|
destroySeqGrabber();
|
|
initSeqGrabber();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// colorspaceMess
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
bool videoDarwin :: setColor(int format)
|
|
{
|
|
m_colorspace = format;
|
|
if(stop()) {
|
|
resetSeqGrabber();
|
|
start();
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// dialog
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
bool videoDarwin :: dialog(std::vector<std::string>dlg)
|
|
{
|
|
Rect newActiveVideoRect;
|
|
Rect curBounds, curVideoRect, newVideoRect;
|
|
ComponentResult err;
|
|
|
|
// Get our current state - do i need this???
|
|
err = SGGetChannelBounds (m_vc, &curBounds);
|
|
err = SGGetVideoRect (m_vc, &curVideoRect);
|
|
|
|
// Pause
|
|
err = SGPause (m_sg, true);
|
|
|
|
// Do the dialog thang
|
|
err = SGSettingsDialog( m_sg, m_vc, 0, nil, 0, nil, 0);
|
|
|
|
// What happened?
|
|
err = SGGetVideoRect (m_vc, &newVideoRect);
|
|
err = SGGetSrcVideoBounds (m_vc, &newActiveVideoRect);
|
|
|
|
err = SGPause (m_sg, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
std::vector<std::string>videoDarwin :: dialogs(void) {
|
|
std::vector<std::string>result;
|
|
return result;
|
|
}
|
|
|
|
bool videoDarwin::enumProperties(gem::Properties&readable,
|
|
gem::Properties&writeable) {
|
|
bool iidc=false;
|
|
gem::any typ;
|
|
|
|
readable.clear();
|
|
writeable.clear();
|
|
|
|
typ=1.;
|
|
if(m_vdig) {
|
|
ComponentDescription desc;
|
|
GetComponentInfo((Component)m_vdig, &desc, NULL, NULL, NULL);
|
|
|
|
iidc=vdSubtypeIIDC == desc.componentSubType;
|
|
}
|
|
#define SETPROP(key, value) typ=value; readable.set(key, typ); writeable.set(key, typ)
|
|
#define SETRPROP(key, value) typ=value; readable.set(key, typ)
|
|
#define SETWPROP(key, value) typ=value; writeable.set(key, typ)
|
|
SETPROP("Hue", 1);
|
|
SETPROP("Sharpness", 1);
|
|
SETPROP("Saturation", 1);
|
|
SETPROP("Brightness", 1);
|
|
if(!iidc) {
|
|
SETPROP("Contrast", 1);
|
|
SETPROP("KeyColor", 1);
|
|
//SETPROP("ClipState", 1);
|
|
//SETPROP("ClipRng", 1);
|
|
//SETPROP("PLLFilterType", 1);
|
|
SETWPROP("MasterBlendLevel", 1);
|
|
//SETPROP("PlayThroughOnOff", 1);
|
|
//SETPROP("FieldPreference", 1);
|
|
SETPROP("BlackLevelValue", 1);
|
|
SETPROP("WhiteLevelValue", 1);
|
|
//SETPROP("Input", 1);
|
|
//SETPROP("InputStandard", 1);
|
|
} else {
|
|
SETWPROP("Gain", 1);
|
|
SETWPROP("Iris", 1);
|
|
SETWPROP("Shutter", 1);
|
|
SETWPROP("Exposure", 1);
|
|
SETWPROP("WhiteBalanceU", 1);
|
|
SETWPROP("WhiteBalanceV", 1);
|
|
SETWPROP("Gamma", 1);
|
|
SETWPROP("Temperature", 1);
|
|
SETWPROP("Zoom", 1);
|
|
SETWPROP("Focus", 1);
|
|
SETWPROP("Pan", 1);
|
|
SETWPROP("Tilt", 1);
|
|
SETWPROP("OpticalFilter", 1);
|
|
SETWPROP("EdgeEnhancement", 1);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool videoDarwin::setIIDCProperty(OSType specifier, double value) {
|
|
QTAtomContainer atomContainer;
|
|
QTAtom featureAtom;
|
|
VDIIDCFeatureSettings settings;
|
|
ComponentDescription desc;
|
|
ComponentResult result = paramErr;
|
|
|
|
//IIDC stuff
|
|
result = VDIIDCGetFeaturesForSpecifier(m_vdig, specifier, &atomContainer);
|
|
if (noErr != result) {
|
|
return false;
|
|
}
|
|
|
|
featureAtom = QTFindChildByIndex(atomContainer, kParentAtomIsContainer,
|
|
vdIIDCAtomTypeFeature, 1, NULL);
|
|
if (0 == featureAtom) return false;//error("featureAtom vdIIDCFeatureSaturation not found");
|
|
|
|
result = QTCopyAtomDataToPtr(atomContainer,
|
|
QTFindChildByID(atomContainer, featureAtom,
|
|
vdIIDCAtomTypeFeatureSettings,
|
|
vdIIDCAtomIDFeatureSettings, NULL),
|
|
true, sizeof(settings), &settings, NULL);
|
|
|
|
settings.state.flags = (vdIIDCFeatureFlagOn |
|
|
vdIIDCFeatureFlagManual |
|
|
vdIIDCFeatureFlagRawControl);
|
|
|
|
settings.state.value = value;
|
|
|
|
result = QTSetAtomData(atomContainer,
|
|
QTFindChildByID(atomContainer, featureAtom,
|
|
vdIIDCAtomTypeFeatureSettings,
|
|
vdIIDCAtomIDFeatureSettings, NULL),
|
|
sizeof(settings), &settings);
|
|
|
|
result = VDIIDCSetFeatures(m_vdig, atomContainer);
|
|
|
|
return true;
|
|
}
|
|
inline unsigned short d2us(double x)
|
|
{ return (unsigned short)(65535.*((x > 1.f) ? 1.f : ( (x < 0.f) ? 0.f : x))); }
|
|
inline double us2d(unsigned short x)
|
|
{ static double factor=1./65535.; return (x*factor); }
|
|
|
|
bool videoDarwin::applyProperties(gem::Properties&props) {
|
|
bool restart=false;
|
|
|
|
bool iidc=false;
|
|
if(m_vdig) {
|
|
ComponentDescription desc;
|
|
GetComponentInfo((Component)m_vdig, &desc, NULL, NULL, NULL);
|
|
iidc=(vdSubtypeIIDC == desc.componentSubType);
|
|
}
|
|
|
|
std::vector<std::string>keys=props.keys();
|
|
int i=0;
|
|
for(i=0; i<keys.size(); i++) {
|
|
double value_d=0.;
|
|
unsigned short value_us=0;
|
|
std::string key=keys[i];
|
|
if("width"==key) {
|
|
if(props.get(key, value_d)) {
|
|
unsigned int width=value_d;
|
|
if(m_width!=width)
|
|
restart=true;
|
|
m_width=width;
|
|
}
|
|
} else if("height"==key) {
|
|
if(props.get(key, value_d)) {
|
|
unsigned int height=value_d;
|
|
if(m_height!=height)
|
|
restart=true;
|
|
m_height=height;
|
|
}
|
|
} else if("channel"==key) {
|
|
if(props.get("channel", value_d)) {
|
|
unsigned int channel=value_d;
|
|
if(channel!=m_inputDeviceChannel)
|
|
restart=true;
|
|
m_inputDeviceChannel=channel;
|
|
}
|
|
} else if("quality"==key) {
|
|
if(props.get(key, value_d)) {
|
|
unsigned int quality=value_d;
|
|
bool doit=false;
|
|
switch (quality){
|
|
case 0:
|
|
m_quality=channelPlayNormal;
|
|
doit=true;
|
|
break;
|
|
case 1:
|
|
m_quality=channelPlayHighQuality;
|
|
doit=true;
|
|
break;
|
|
case 2:
|
|
m_quality=channelPlayFast;
|
|
doit=true;
|
|
break;
|
|
case 3:
|
|
m_quality=channelPlayAllData;
|
|
doit=true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if(doit&&m_vc)
|
|
SGSetChannelPlayFlags(m_vc, m_quality);
|
|
}
|
|
#define PROPSET_IIDC_VD(NAME) \
|
|
} else if (#NAME == key && props.get(key, value_d) && m_vdig) { \
|
|
if(iidc){setIIDCProperty(vdIIDCFeature ## NAME, value_d);} \
|
|
else {value_us = d2us(value_d); \
|
|
VDSet ## NAME (m_vdig,&value_us); } value_d=0
|
|
#define PROPSET_VD(NAME) \
|
|
} else if (#NAME == key && props.get(key, value_d) && m_vdig) { \
|
|
if(!iidc) {value_us = d2us(value_d); \
|
|
VDSet ## NAME (m_vdig,&value_us); } value_d=0
|
|
#define PROPSET_IIDC(NAME) \
|
|
} else if (#NAME == key && props.get(key, value_d) && iidc) { \
|
|
setIIDCProperty(vdIIDCFeature ## NAME, value_d); value_d=0
|
|
|
|
PROPSET_IIDC_VD(Hue);
|
|
PROPSET_IIDC_VD(Sharpness);
|
|
PROPSET_VD(Contrast);
|
|
//PROPSET_VD(KeyColor);
|
|
//PROPSET_VD(ClipState);
|
|
//PROPSET_VD(ClipRng);
|
|
//PROPSET_VD(PLLFilterType);
|
|
PROPSET_VD(MasterBlendLevel);
|
|
//PROPSET_VD(PlayThroughOnOff);
|
|
//PROPSET_VD(FieldPreference);
|
|
PROPSET_VD(BlackLevelValue);
|
|
PROPSET_VD(WhiteLevelValue);
|
|
//PROPSET_VD(Input);
|
|
//PROPSET_VD(InputStandard);
|
|
PROPSET_IIDC_VD(Saturation);
|
|
PROPSET_IIDC_VD(Brightness);
|
|
PROPSET_IIDC(Gain);
|
|
PROPSET_IIDC(Iris);
|
|
PROPSET_IIDC(Shutter);
|
|
PROPSET_IIDC(Exposure);
|
|
PROPSET_IIDC(WhiteBalanceU);
|
|
PROPSET_IIDC(WhiteBalanceV);
|
|
PROPSET_IIDC(Gamma);
|
|
PROPSET_IIDC(Temperature);
|
|
PROPSET_IIDC(Zoom);
|
|
PROPSET_IIDC(Focus);
|
|
PROPSET_IIDC(Pan);
|
|
PROPSET_IIDC(Tilt);
|
|
PROPSET_IIDC(OpticalFilter);
|
|
PROPSET_IIDC(EdgeEnhancement);
|
|
}
|
|
}
|
|
return restart;
|
|
}
|
|
void videoDarwin::setProperties(gem::Properties&props) {
|
|
bool restart=applyProperties(props);
|
|
if(restart) {
|
|
if(stop()) {
|
|
resetSeqGrabber();
|
|
start();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void videoDarwin::getProperties(gem::Properties&props) {
|
|
std::vector<std::string>keys=props.keys();
|
|
bool iidc=false;
|
|
if(m_vdig) {
|
|
ComponentDescription desc;
|
|
GetComponentInfo((Component)m_vdig, &desc, NULL, NULL, NULL);
|
|
iidc=(vdSubtypeIIDC == desc.componentSubType);
|
|
}
|
|
|
|
int i=0;
|
|
for(i=0; i<keys.size(); i++) {
|
|
std::string key=keys[i];
|
|
double value_d=0.;
|
|
unsigned short value_us=0;
|
|
if(0) {
|
|
#define PROPGET_VD(NAME) \
|
|
} else if (#NAME == key && m_vdig && !iidc) { \
|
|
if(0==VDGet ## NAME (m_vdig,&value_us)) {props.set(key, us2d(value_us)); } value_d=0
|
|
PROPGET_VD(Hue);
|
|
PROPGET_VD(Sharpness);
|
|
PROPGET_VD(Saturation);
|
|
PROPGET_VD(Brightness);
|
|
PROPGET_VD(Contrast);
|
|
//PROPGET_VD(KeyColor);
|
|
//PROPGET_VD(ClipState);
|
|
//PROPGET_VD(ClipRng);
|
|
//PROPGET_VD(PLLFilterType);
|
|
//PROPGET_VD(PlayThroughOnOff);
|
|
//PROPGET_VD(FieldPreference);
|
|
PROPGET_VD(BlackLevelValue);
|
|
PROPGET_VD(WhiteLevelValue);
|
|
//PROPGET_VD(Input);
|
|
//PROPGET_VD(InputStandard);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> videoDarwin::enumerate() {
|
|
std::vector<std::string> result;
|
|
OSErr anErr;
|
|
SGDeviceList devices;
|
|
|
|
anErr = SGGetChannelDeviceList(m_vc, sgDeviceListIncludeInputs, &devices);
|
|
if(anErr!=noErr){
|
|
error("could not get SG channnel Device List");
|
|
}else{
|
|
short deviceCount = (*devices)->count;
|
|
short deviceIndex = (*devices)->selectedIndex;
|
|
short inputIndex;
|
|
post("SG channnel Device List count %d index %d",deviceCount,deviceIndex);
|
|
int i;
|
|
m_devices.clear();
|
|
for (i = 0; i < deviceCount; i++){
|
|
m_devices.push_back(pascal2str((*devices)->entry[i].name));
|
|
post("SG channnel Device List[%d] %s", i, m_devices[i].c_str());
|
|
}
|
|
SGGetChannelDeviceAndInputNames(m_vc, NULL, NULL, &inputIndex);
|
|
|
|
bool showInputsAsDevices = ((*devices)->entry[deviceIndex].flags) & sgDeviceNameFlagShowInputsAsDevices;
|
|
|
|
SGDeviceInputList theSGInputList = ((SGDeviceName *)(&((*devices)->entry[deviceIndex])))->inputs; //fugly
|
|
|
|
//we should have device names in big ass undocumented structs
|
|
//walk through the list
|
|
for (i = 0; i < inputIndex; i++){
|
|
std::string input=pascal2str((*theSGInputList)->entry[i].name);
|
|
post("SG channnel Input Device List %d %s",
|
|
i, input.c_str());
|
|
}
|
|
}
|
|
|
|
result=m_devices;
|
|
return result;
|
|
}
|
|
#endif // HAVE_VIDEODARWIN
|