QuicktimeCapture.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  QuicktimeCapture.cpp
00037 // Author:    Pedram Azad
00038 // Date:      2005
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include "QuicktimeCapture.h"
00047 #include "Image/ByteImage.h"
00048 
00049 #include <QuickTime/QuickTimeStreaming.h>
00050 
00051 
00052 
00053 // ****************************************************************************
00054 // Constructor / Destructor
00055 // ****************************************************************************
00056 
00057 CQuicktimeCapture::CQuicktimeCapture(VideoMode mode, const char *pComponentName) : m_mode(mode)
00058 {
00059         grabber = 0;
00060         videoChannel = 0;
00061         gWorld = 0;
00062         m_pBuffer = 0;
00063         imgDesc = 0;
00064         
00065         width = -1;
00066         height = -1;
00067         
00068         m_sComponentName = "";
00069         
00070         if (pComponentName)
00071                 m_sComponentName += pComponentName;
00072         
00073         m_bImagePending = false;
00074 }
00075 
00076 CQuicktimeCapture::~CQuicktimeCapture()
00077 {
00078         CloseCamera();
00079 }
00080 
00081 
00082 // ****************************************************************************
00083 // Methods
00084 // ****************************************************************************
00085 
00086 bool CQuicktimeCapture::OpenCamera()
00087 {
00088         CloseCamera();
00089         
00090         switch (m_mode)
00091         {
00092                 case e320x240:
00093                         width = 320;
00094                         height = 240;
00095                 break;
00096                 
00097                 case e640x480:
00098                         width = 640;
00099                         height = 480;
00100                 break;
00101                 
00102                 default:
00103                         return false;
00104         }
00105         
00106         srcRect.left = 0;
00107         srcRect.right = width - 1;
00108         srcRect.top = 0;
00109         srcRect.bottom = height - 1;
00110         
00111         Component comp = 0;
00112         Handle grabberName = NewHandle(0);
00113         Handle info = NewHandle(0);
00114         ComponentDescription desc;
00115   
00116         desc.componentType = SeqGrabComponentType;
00117         desc.componentSubType = 0;
00118         desc.componentManufacturer = 0;
00119         desc.componentFlags = 0;
00120         desc.componentFlagsMask = 0;  
00121 
00122         // find a sequence grabber that matches the given component name
00123         bool bFound = false;
00124         while (comp = FindNextComponent(comp, &desc))
00125         {
00126                 if (GetComponentInfo(comp, &desc, grabberName, info, 0) != noErr)
00127                 {
00128                         printf("error: could not get info on component id = %i\n", comp);
00129                         return false;
00130                 }
00131                 
00132                 printf("grabber: '%s'\n", *grabberName + 1);
00133 
00134                 if (m_sComponentName.length() == 0 || strcmp(m_sComponentName.c_str(), *grabberName + 1) == 0)
00135                 {
00136                         bFound = true;
00137                         break;
00138                 }
00139     }
00140  
00141         if (!bFound)
00142         {
00143                 printf("error: could not find a sequence grabber named '%s'\n", m_sComponentName.c_str());
00144                 return false;
00145         }
00146         
00147         // found grabber, open and initialize it
00148         grabber = OpenComponent(comp);
00149         
00150         if (!grabber)
00151         {
00152                 printf("error: could not open sequence grabber\n");
00153                 return false;
00154         }
00155         
00156         if (SGInitialize(grabber) != noErr)
00157         {
00158                 printf("errror: could not initialize the sequence grabber\n");
00159                 return false;
00160         }
00161 
00162         if (SGSetDataRef(grabber, 0, 0, seqGrabDontMakeMovie) != noErr)
00163         {
00164                 printf("error: could not set data reference on sequence grabber\n");
00165                 return false;
00166         }
00167 
00168         if (QTNewGWorld(&gWorld, k24RGBPixelFormat, &srcRect, 0, 0, 0) != noErr)
00169         {
00170                 printf("error: could not create new gworld\n");
00171                 return false;
00172         }
00173 
00174         if (!LockPixels(GetPortPixMap(gWorld)))
00175         {
00176                 printf("error: could not lock pixels in new gworld\n");
00177                 return false;
00178         }
00179 
00180         if (SGSetGWorld(grabber, gWorld, 0) != noErr)
00181         {
00182                 printf("error: could not set gworld\n");
00183                 return false;
00184         }
00185   
00186         // create video channel
00187         if (SGNewChannel(grabber, VideoMediaType, &videoChannel) != noErr || !videoChannel)
00188         {
00189                 printf("error: could not open video channel\n");
00190                 return false;
00191         }
00192 
00193         if (SGSetChannelUsage(videoChannel, seqGrabRecord) != noErr)
00194         {
00195                 printf("error: could not set channel usage to 'record'\n");
00196                 return false;
00197         }
00198                              
00199         if (SGSetChannelBounds(videoChannel, &srcRect) != noErr)
00200         {
00201                 printf("error: could not set channel bounds to %ix%i\n", width, height);
00202                 return false;
00203         }
00204 
00205         if (SGSetDataProc(grabber, NewSGDataUPP(sDataProc), (long)this) != noErr)
00206         {
00207                 printf("error: could not set data proc\n");
00208                 return false;
00209         }
00210         
00211         SGStartRecord(grabber);
00212         
00213         return true;
00214 }
00215 
00216 void CQuicktimeCapture::CloseCamera()
00217 {
00218         if (grabber)
00219         {
00220                 SGStop(grabber);
00221         
00222                 if (videoChannel)
00223                 {
00224                         SGDisposeChannel(grabber, videoChannel);
00225                         videoChannel = 0;
00226                 }
00227 
00228                 if (gWorld)
00229                 {
00230                         DisposeGWorld(gWorld);
00231                         gWorld = 0;
00232                 }
00233                 
00234                 grabber = 0;
00235         }
00236         
00237         m_bImagePending = false;
00238 }
00239 
00240 bool CQuicktimeCapture::CaptureImage(CByteImage **ppImages)
00241 {
00242         if (!videoChannel)
00243                 return false;
00244                 
00245         CByteImage *pImage = ppImages[0];
00246         if (pImage->width != width || pImage->height != height || pImage->type != CByteImage::eRGB24)
00247                 return false;
00248         
00249         while (!m_bImagePending)
00250                 SGIdle(grabber);
00251                 
00252         ImageSequence image_sequence;
00253 
00254         if (DecompressSequenceBegin(&image_sequence, imgDesc, gWorld, 0, &srcRect, 0, srcCopy, 0, 0, codecNormalQuality, bestSpeedCodec) != noErr)
00255         {
00256                 printf("error: could not begin decompression\n");
00257                 return false;
00258         }
00259 
00260         CodecFlags ignore;
00261   
00262         DecompressSequenceFrameS(image_sequence, m_pBuffer, m_lImageLength, 0, &ignore, NULL);
00263 
00264         const int nBytes = 3 * pImage->width * pImage->height;
00265         const unsigned char *input = (unsigned char *) GetPixBaseAddr(GetGWorldPixMap(gWorld));
00266         unsigned char *output = pImage->pixels;
00267         for (int i = 0, offset = 0; i < nBytes; i += 3, offset += 4)
00268         {
00269                 output[i] = input[offset + 1];
00270                 output[i + 1] = input[offset + 2];
00271                 output[i + 2] = input[offset + 3];
00272         }
00273         
00274         CDSequenceEnd(image_sequence);
00275         
00276         m_bImagePending = false;
00277         
00278         return true;
00279 }
00280 
00281 pascal OSErr CQuicktimeCapture::sDataProc(SGChannel channel, Ptr p, long length, long *offset, long chRefCon, TimeValue time, short writeType, long refcon)
00282 {
00283         return ((CQuicktimeCapture *) refcon)->dataProc(channel, p, length);
00284 }
00285 
00286 OSErr CQuicktimeCapture::dataProc(SGChannel channel, Ptr p, long length)
00287 {
00288         if (!imgDesc)
00289         {
00290                 imgDesc = (ImageDescriptionHandle) NewHandle(0);
00291                 SGGetChannelSampleDescription(videoChannel, (Handle) imgDesc);
00292         }
00293         
00294         m_pBuffer = p;
00295         m_lImageLength = length;
00296         m_bImagePending = true;
00297 
00298         return noErr;
00299 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:58