/* ======================================================================== *\ ! ! * ! * 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), fNumFrame(0), fChannel(nch) { fVideo = new MVideo; fVideo->Open(nch); RunThread(); } Camera::~Camera() { // Shut down the thread CancelThread(); // Now delete (close) the device delete fVideo; } void Camera::ProcessFrame(unsigned 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 unsigned 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; yIsOpen()) { gLog << err << "Camera::Thread: ERROR - Device not open." << endl; return kFALSE; } gLog << dbg << "Start Camera::Thread at frame " << fNumFrame%fVideo->GetNumBuffers() << endl; for (int f=0; fGetNumBuffers(); f++) if (!fVideo->CaptureStart(f)) return kFALSE; Int_t timeouts = 0; while (1) { // Switch channel if necessary switch (fVideo->SetChannel(fChannel)) { case kFALSE: // Error swucthing channel return kFALSE; case kSKIP: // No channel switching necessary break; case kTRUE: // Channel switched (skip filled buffers) for (int f=0; fGetNumBuffers(); f++) if (!fVideo->CaptureWait(fNumFrame+f)) return kFALSE; fNumFrame=0; for (int f=0; fGetNumBuffers(); f++) if (!fVideo->CaptureStart(f)) return kFALSE; break; } // Check and wait until capture into the next buffer is finshed unsigned char *img = 0; switch (fVideo->CaptureWait(fNumFrame++, &img)) { case kTRUE: // Process frame // If cacellation is requested cancel here TThread::CancelPoint(); ProcessFrame(img); // If cacellation is requested cancel here TThread::CancelPoint(); // Start to capture into the buffer which has just been processed if (!fVideo->CaptureStart(fNumFrame-1)) break; 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(); }