Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CameraSourceQTSG.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_CameraSourceQTSG_h_
00003 #define INCLUDED_CameraSourceQTSG_h_
00004 
00005 #include "local/DataSource.h"
00006 #include "Shared/plistCollections.h"
00007 #include "IPC/CallbackThread.h"
00008 #include <iostream>
00009 #include <stdexcept>
00010 #include <map>
00011 #include <cmath>
00012 
00013 #define TARGET_API_MAC_CARBON 1
00014 #include <Carbon/Carbon.h>
00015 #include <QuickTime/QuickTime.h>
00016 
00017 extern bool checkQTThreadInit();
00018 
00019 //! This interfaces with a specific camera through QuickTime and the Sequence Grabber, which is deprecated.  See the alternative CameraSourceQTKit implementation.
00020 /*! This camera source is used on pre-10.6 systems, supporting 32 bit only */
00021 class CameraSourceQTSG : public DataSource, public virtual plist::Dictionary {
00022 public:
00023   //! constructor, pass the short name, device name and input index
00024   CameraSourceQTSG(SeqGrabComponent grabber, const std::string& srcName, const std::string& devName, const std::string& inputName, int inputIdx)
00025     throw(std::pair<OSErr,const char*>)
00026     : DataSource(), layer(0), poller(&CameraSourceQTSG::poll,*this,TimeET(0L),TimeET(1.f/(*sensorFramerate)),true,CallbackPollThread::STOP_FALSE),
00027     sg(grabber), sgChan(NULL), gworld(NULL), name(srcName), deviceName(devName), devInputName(inputName), devInputIdx(inputIdx),
00028     frame(0), skipped(0), queuedFrames(0), grabbing(false),
00029     lastTime(0), duration(0), chanTimeScale(), chanTimeBase(), drawSeq(0), callbackerr(noErr),
00030     gworldBuf(NULL), burnIn(false)
00031   {
00032     initCamera();
00033       
00034     // plist dictionary stuff
00035     setLoadSavePolicy(FIXED,SYNC);
00036     addEntry("Layer",layer,"Controls the resolution layer at which the image should be processed.\n"
00037         "0 indicates \"automatic\" mode (picks layer closest to image's resolution), positive numbers indicate the resolution layer directly.\n"
00038         "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.");
00039   }
00040   
00041   //! destructor, free system resources
00042   ~CameraSourceQTSG();
00043   
00044   //! accessor for the instance name
00045   virtual const std::string& getName() const { return name; }
00046   //! accessor for the device name
00047   virtual const std::string& getDeviceName() const { return deviceName; }
00048   //! accessor for the name of the input from the device
00049   virtual const std::string& getInputName() const { return devInputName; }
00050   
00051   virtual unsigned int nextTimestamp() { return static_cast<unsigned int>(std::ceil(lastTime+duration*1000)); }
00052   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
00053   
00054   virtual void registerSource();
00055   virtual void deregisterSource();
00056   virtual bool advance();
00057   
00058   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.
00059   
00060 protected:
00061   void initCamera();
00062   
00063   void doFreeze();
00064   void doUnfreeze();
00065 
00066   
00067   //! converts from pascal-format string to c-format string
00068   static std::string p2c(unsigned char pascalStr[]) {
00069     unsigned char len = *pascalStr++;
00070     return std::string(reinterpret_cast<char*>(pascalStr),len);
00071   }
00072 
00073   static void dumpLiteral(OSType t);
00074   static ComponentResult setVideoChannelBounds(SGChannel videoChannel, const Rect *scaledVideoBounds);
00075   static pascal ComponentResult compressCompleteBottleProc(SGChannel c, UInt8 *queuedFrameCount, SGCompressInfo *ci, TimeRecord *t, long refCon);
00076   static pascal OSErr grabDataProc(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon);
00077   
00078   //! Resamples a YUV 4:2:2 (aka '2vuy') image to a YUV 4:4:4 form which is expected in getData()'s payload
00079   RCRegion * imgFrom2vuy(const unsigned char * s, short srcWidth, short srcHeight, short depth, long dataSize);
00080   //! Resamples a YUV 4:2:2 (aka 'yuv2' or 'yuvu') image to YUV 4:4:4 form which is expected in getData()'s payload
00081   RCRegion * imgFromyuv2(const unsigned char * s, short srcWidth, short srcHeight, short depth, long dataSize);
00082   
00083   bool poll() { Thread::NoCancelScope nc; advance(); return grabbing; }
00084   CallbackPollThread poller;
00085   
00086   SeqGrabComponent  sg; //!< sequence grabber, might need one of these globally instead of one per CameraSourceQTSG
00087   SGChannel     sgChan; //!< channel within the sequence grabber, I think there will be one channel per camera
00088   GWorldPtr     gworld; //!< graphics buffer to store the decompressed image (RGB, will have to be converted back to YUV)
00089   std::string name; //!< name to use for image frames
00090   const std::string deviceName; //!< name of hardware device the source is connected
00091   const std::string devInputName; //!< name of the input on the device (in case a single device has multiple inputs)
00092   int devInputIdx; //!< index number of the input
00093     
00094   unsigned int frame; //!< current frame number
00095   unsigned int skipped; //!< number of frames skipped since last successful frame
00096   unsigned int queuedFrames; //!< number of frames the system indicates are waiting to be processed
00097   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
00098   TimeValue       lastTime;
00099   float duration;
00100   TimeScale       chanTimeScale;
00101   TimeBase      chanTimeBase;
00102   ImageSequence     drawSeq;  // unique identifier for our draw sequence
00103   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
00104   
00105   char * gworldBuf; //!< buffer used for #gworld
00106   bool burnIn; //!< set to true if the image should be skipped (e.g. clearing out a backlog of images when advancing while frozen
00107     
00108 private:
00109   CameraSourceQTSG(const CameraSourceQTSG&); //!< don't call (copy constructor)
00110   CameraSourceQTSG& operator=(const CameraSourceQTSG&); //!< don't call (assignment operator)
00111 };
00112 
00113 /*! @file
00114  * @brief Describes CameraSourceQTSG, which interfaces with a specific camera through QuickTime and the Sequence Grabber, which is deprecated.  See the alternative CameraSourceQTKit implementation.
00115  * @author Ethan Tira-Thompson (ejt) (Creator)
00116  */
00117 
00118 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:38 2016 by Doxygen 1.6.3