/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 1/2008 ! ! Copyright: MAGIC Software Development, 2000-2008 ! ! \* ======================================================================== */ #include "Camera.h" #include "MLog.h" #include "MLogManip.h" #include "MVideo.h" #include "PixClient.h" //ClassImp(Camera); using namespace std; Camera::Camera(PixClient &client, Int_t nch) : MThread("Camera"), fClient(client), fVideo(0) { fVideo = new MVideo; fVideo->Open(nch); RunThread(); } Camera::~Camera() { // Shut down the thread CancelThread(); // Now delete (close) the device delete fVideo; } void Camera::ProcessFrame(char *img) { gettimeofday(&fTime, NULL); const Int_t W = fVideo->GetWidth(); const Int_t H = fVideo->GetHeight(); const Bool_t crop = W!=768 || H!=576; // FIXME: This only works for one RGB24 if (!crop) { // FIXME: Grey scale assumed! const char *end = img + 768*576*depth; char *beg = fImg; while (img < end) { *beg++ = *img; img += depth; } } else { const Int_t w = TMath::Min(W, 768); const Int_t h = TMath::Min(H, 576); memset(fImg, 0, 768*576); for (int y=0; yGetWidth())*3+1]+(UInt_t)(UChar_t)img[(x+y*fVideo->GetWidth())*3+2])/3; } fClient.ProcessFrame(fNumFrame-1, (byte*)fImg, &fTime); } Int_t Camera::Thread() { fNumSkipped = 0; fNumFrame = 0; if (!fVideo->IsOpen()) { gLog << err << "Camera::Thread: ERROR - Device not open." << endl; return kFALSE; } //Print(); for (int f=1; fGetNumBuffers(); f++) if (!fVideo->CaptureStart(f)) return kFALSE; Int_t timeouts = 0; while (1) { // If cacellation is requested cancel here TThread::CancelPoint(); // Start to capture into the buffer which has just been processed if (!fVideo->CaptureStart(fNumFrame)) break; // If cacellation is requested cancel here TThread::CancelPoint(); // Check and wait until capture into the next buffer is finshed char *img = 0; switch (fVideo->CaptureWait(++fNumFrame, &img)) { case kTRUE: // Process frame ProcessFrame(img); timeouts = 0; continue; case kFALSE: // Waiting failed break; case kSKIP: // Skip frame fNumFrame--; fNumSkipped++; if (timeouts++<5) continue; cout << "ERROR - At least five captured images timed out." << endl; break; } break; } // Is this necessary?!? //for (int i=0; iSetChannel(chan); RunThread(); }