Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CameraSourceOSX.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_CameraSource_h_
00003 #define INCLUDED_CameraSource_h_
00004 
00005 #include "local/DataSource.h"
00006 #include "Shared/plistCollections.h"
00007 #include <iostream>
00008 #include <stdexcept>
00009 #include <map>
00010 #include <cmath>
00011 
00012 #define TARGET_API_MAC_CARBON 1
00013 #include <Carbon/Carbon.h>
00014 #include <QuickTime/QuickTime.h>
00015 
00016 extern bool checkQTThreadInit();
00017 
00018 class CameraSource : public DataSource, public virtual plist::Dictionary {
00019 public:
00020   //! constructor, pass the short name, device name and input index
00021   CameraSource(SeqGrabComponent grabber, const std::string& srcName, const std::string& devName, const std::string& inputName, int inputIdx)
00022     throw(std::pair<OSErr,const char*>)
00023     : DataSource(), layer(0), sg(grabber), sgChan(NULL), gworld(NULL), name(srcName), deviceName(devName), devInputName(inputName), devInputIdx(inputIdx),
00024     frame(0), skipped(0), queuedFrames(0), grabbing(false),
00025     lastTime(0), duration(0), chanTimeScale(), chanTimeBase(), drawSeq(NULL), callbackerr(noErr),
00026     gworldBuf(NULL), imgbuf(NULL), imgbufSize(0), imgbufUsed(0)
00027   {
00028     initCamera();
00029       
00030     // plist dictionary stuff
00031     setLoadSavePolicy(FIXED,SYNC);
00032     addEntry("Layer",layer,"Controls the resolution layer at which the image should be processed.\n"
00033         "0 indicates \"automatic\" mode (picks layer closest to image's resolution), positive numbers indicate the resolution layer directly.\n"
00034         "Negative values are relative to the number of layers marked available by the vision setup, so that typically -1 would correspond to the \"double\" layer, and -2 would correspond to the \"full\" layer.");
00035   }
00036   
00037   //! destructor, free system resources
00038   ~CameraSource();
00039   
00040   //! accessor for the instance name
00041   virtual const std::string& getName() const { return name; }
00042   //! accessor for the device name
00043   virtual const std::string& getDeviceName() const { return deviceName; }
00044   //! accessor for the name of the input from the device
00045   virtual const std::string& getInputName() const { return devInputName; }
00046   
00047   virtual unsigned int nextTimestamp() { return static_cast<unsigned int>(std::ceil(lastTime+duration)); }
00048   virtual const std::string& nextName() { return name; } //!< this is supposed to be the name for the next camera frame, we just reuse our static instance name
00049   
00050   virtual void setDataSourceThread(LoadDataThread* ldt);
00051   virtual void setDataSourceFramerate(float fps);
00052   
00053   virtual unsigned int getData(const char *& payload, unsigned int& payloadSize, unsigned int& timestamp, std::string& name);
00054   
00055   plist::Primitive<int> layer; //!< Controls the resolution layer at which the image should be processed.\n 0 indicates "automatic" mode (picks layer closest to image's resolution), positive numbers indicate the resolution layer directly.\n Negative values are relative to the number of layers marked available by the vision setup, so that typically -1 would correspond to the "double" layer, and -2 would correspond to the "full" layer.
00056   
00057 protected:
00058   void initCamera();
00059   
00060   //! converts from pascal-format string to c-format string
00061   static std::string p2c(unsigned char pascalStr[]) {
00062     unsigned char len = *pascalStr++;
00063     return std::string(reinterpret_cast<char*>(pascalStr),len);
00064   }
00065 
00066   static void dumpLiteral(OSType t);
00067   static ComponentResult setVideoChannelBounds(SGChannel videoChannel, const Rect *scaledVideoBounds);
00068   static pascal ComponentResult compressCompleteBottleProc(SGChannel c, UInt8 *queuedFrameCount, SGCompressInfo *ci, TimeRecord *t, long refCon);
00069   static pascal OSErr grabDataProc(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon);
00070   
00071   //! Resamples a YUV 4:2:2 (aka '2vuy') image to a YUV 4:4:4 form which is expected in getData()'s payload
00072   void imgFrom2vuy(const unsigned char * s, short srcWidth, short srcHeight, short depth, long dataSize);
00073   //! Resamples a YUV 4:2:2 (aka 'yuv2' or 'yuvu') image to YUV 4:4:4 form which is expected in getData()'s payload
00074   void imgFromyuv2(const unsigned char * s, short srcWidth, short srcHeight, short depth, long dataSize);
00075   
00076   SeqGrabComponent  sg; //!< sequence grabber, might need one of these globally instead of one per CameraSource
00077   SGChannel     sgChan; //!< channel within the sequence grabber, I think there will be one channel per camera
00078   GWorldPtr     gworld; //!< graphics buffer to store the decompressed image (RGB, will have to be converted back to YUV)
00079   std::string name; //!< name to use for image frames
00080   const std::string deviceName; //!< name of hardware device the source is connected
00081   const std::string devInputName; //!< name of the input on the device (in case a single device has multiple inputs)
00082   int devInputIdx; //!< index number of the input
00083     
00084   unsigned int frame; //!< current frame number
00085   unsigned int skipped; //!< number of frames skipped since last successful frame
00086   unsigned int queuedFrames; //!< number of frames the system indicates are waiting to be processed
00087   bool grabbing; //!< set to true when setDataSourceThread is called with a non-NULL value, but can be set back to false if an error occurs
00088   TimeValue       lastTime;
00089   UInt32        duration;
00090   TimeScale       chanTimeScale;
00091   TimeBase      chanTimeBase;
00092   ImageSequence     drawSeq;  // unique identifier for our draw sequence
00093   OSErr callbackerr; //!< error value from call back, so we can tell if an error came from SGIdle itself or the callback functions it may trigger
00094   
00095   char * gworldBuf; //!< buffer used for #gworld
00096   
00097   char * imgbuf;  //!< buffer where YUV image will be stored and returned back to getData caller via payload parameter
00098   size_t imgbufSize; //!< size of #imgbuf allocation
00099   size_t imgbufUsed; //!< amount of #imgbuf's allocation which is actually in use with data 
00100   
00101 private:
00102   CameraSource(const CameraSource&); //!< don't call (copy constructor)
00103   CameraSource& operator=(const CameraSource&); //!< don't call (assignment operator)
00104 };
00105 
00106 #endif

Tekkotsu Hardware Abstraction Layer 4.0
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4