Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

l1394_dcccamera.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           dcccamera.cpp  -  description
00003                              -------------------
00004     begin                : Fri Nov 24 2000
00005     copyright            : (C) 2000-2004 by Michael Repplinger
00006     email                : repplinger@cs.uni-sb.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "l1394_dcccamera.h"
00019 #include "l1394_transaction.h"
00020 #include "l1394_card.h"
00021 #include "l1394_session.h"
00022 
00023 
00024 namespace L1394{
00025 using namespace internal;
00026 DccCamera::DccCamera(const u_int32_t node_id, const Card* parent)
00027   : Node(node_id, parent), Camera(this)
00028 {
00029    message->debugStream() << "DccCamera  > create DccCamera " << endl ;
00030 
00031   is_init   = false;
00032   isoctx    = NULL;
00033   setNodeType(_DccNode);
00034 
00035   readGuid();
00036 
00037   rom_info     = new CsrRom(this);
00038   dcc_register = new DccRegister(this);
00039 
00040   //init default values for 320x240 YUV 4:2:2, 15 fps
00041   setFrameSize(320*240*2);
00042   setFrameWidth(320);
00043   setFrameHeight(240);
00044   channel      = 1;
00045   video_mode  = DEVICE_320x240_YUV_422;
00046   frame_rate  = DEVICE_FRAMES_15;
00047   frame_buffer= 3;
00048 
00049    message->debugStream() << "DccCamera  < create DccCamera " << endl ;
00050   addDevice(this);
00051   setName("DccCamera");
00052 }
00053 
00054 DccCamera::~DccCamera()
00055 {
00056   getEventObject()->call(NODE_DESTROY);
00057 
00058   delete rom_info;
00059   delete dcc_register;
00060   delete isoctx;
00061 }
00062 
00063 Frame* DccCamera::getFrame()
00064 {
00065   MutexGuard m(mutex);
00066   if(isoctx)
00067   {
00068      switch(imode)
00069      {
00070       case DEVICE_ISO_RUN :
00071          if (!isSending())
00072          {
00073            message->warningStream() << "DccCamera > Camera not started" << endl;
00074           return NULL;
00075         }
00076         break;
00077 
00078        case DEVICE_ISO_ONESHOT:
00079          shot();
00080          break;
00081 
00082       default:
00083          break;
00084 
00085     }
00086     return  isoctx->getFrame();
00087   }
00088   else
00089     message->warningStream() << "DccCamera > No valid iso ctx" << endl;
00090   return NULL;
00091 }
00092 
00093 int DccCamera::start()
00094 {
00095 
00096    read(DCC_BASE + 0x614,&tmp_quadlet);
00097    tmp_quadlet.setBit(31, 1);
00098 
00099   if (write(DCC_BASE + 0x614, tmp_quadlet) == L1394_SUCCESS);
00100   {
00101     setSending(true);
00102     return L1394_SUCCESS;
00103   }
00104   return L1394_FAILED;
00105 
00106 }
00107 
00108 int DccCamera::stop()
00109 {
00110   setSending(false);
00111   read(DCC_BASE + 0x614, &tmp_quadlet);
00112   tmp_quadlet.setBit(31, 0);
00113   write(DCC_BASE + 0x614, tmp_quadlet);
00114   if (isoctx)
00115     isoctx->flushQueue();
00116   return L1394_SUCCESS;
00117 }
00118 
00119 void DccCamera::shot()
00120 {
00121   read(DCC_BASE + 0x61c,&tmp_quadlet);
00122 
00123   if (tmp_quadlet.getBit(31) == 1)  {
00124     internal::Transaction::delay(200);
00125     shot();
00126   } else  {
00127     tmp_quadlet.setBit(31, 1);
00128     write(DCC_BASE + 0x61c,tmp_quadlet);
00129   }
00130 }
00131 
00132 void DccCamera::multiShot(unsigned int i)
00133 {
00134   read(DCC_BASE + 0x614,&tmp_quadlet);
00135 //  cout << "0x614 :: " << tmp_quadlet<< endl;
00136 
00137   read(DCC_BASE + 0x61c,&tmp_quadlet);
00138 
00139   tmp_quadlet.setBit( 31, 0);
00140   tmp_quadlet.setBit( 30, 1);
00141 
00142   tmp_quadlet.setBitRange(0, 15, i);
00143 //  cout << tmp_quadlet << endl;
00144   write(DCC_BASE + 0x61c,tmp_quadlet);
00145 }
00146 
00147 int DccCamera::setParameter(const int buffercount, const int channel, const Isomode isomode, const Videomode videomode, const Framerate framerate)
00148 {
00149   MutexGuard m(mutex);
00150 /*  if (is_init) {
00151     message->warningStream() << "DccCamera > Camera is already init." << endl;
00152     return L1394_FAILED;
00153   }*/
00154   frame_buffer    = buffercount;
00155   imode            = isomode;
00156   read(DCC_BASE + 0x400, &tmp_quadlet);
00157   switch(imode)
00158   {
00159     case  DEVICE_ISO_ONESHOT :
00160       if (!tmp_quadlet.getBit(12))
00161       {
00162         message->warningStream() << "DccCamera > Camera does not support One-Shot. Reset to iso-run" << endl;
00163         imode = DEVICE_ISO_RUN;
00164       }
00165       break;
00166 
00167     case  DEVICE_ISO_MULTISHOT :
00168       if (!tmp_quadlet.getBit(11))
00169       {
00170         message->warningStream() << "DccCamera > Camera does not support Multi-Shot. Reset to iso-run" << endl;
00171         imode = DEVICE_ISO_RUN;
00172       }
00173       break;
00174   }
00175 
00176   video_mode      = videomode;
00177   frame_rate      = framerate;
00178 
00179   if (channel == FREE_ISO_CHANNEL)
00180     this->channel = 0;
00181 
00182   return L1394_SUCCESS;
00183 }
00184 int DccCamera::init()
00185 {
00186 /*  if (is_init)
00187   {
00188     message->warningStream() << "DccCamera > Camera is already init" << endl;
00189     return L1394_FAILED;
00190   }*/
00191   MutexGuard m(mutex);
00192   Quadlet q;
00193   q.setBit(31,1);           //init
00194   write(DCC_BASE + 0x0, q);
00195 
00196   q.fromInt(0);
00197   write(DCC_BASE + 0x614, q); //stop iso transmission (if running)
00198 
00199   if (!hasVideoFormat(video_mode))
00200   {
00201      message->warningStream() << "DccCamera > Video mode not supported" << endl;
00202     is_init = false;
00203     return L1394_FAILED;
00204   }
00205 
00206   setVideoMode();
00207 
00208   if (!hasFramerate(video_mode, frame_rate))  {
00209      message->warningStream() << "DccCamera > Framerate not supptorted with video_mode" << endl;
00210     is_init = false;
00211     return L1394_FAILED;
00212   }
00213 
00214   setFramerate();
00215 
00216   q.fromInt(0);
00217   q.setBitRange(28, 31, channel); // Set Channel
00218   q.setBitRange(24, 27, 0x2);     // and speed
00219   write(DCC_BASE + 0x60c, q);
00220 
00221   whiteBalance(0)->onePush(true);
00222 
00223   if (isoctx != NULL) {
00224     delete isoctx;
00225     isoctx = 0;
00226   }
00227   if(imode != DEVICE_ISO_NO)
00228   {
00229 
00230     const std::vector<std::string>& iso_dev = SSession::getInstance()->getIsoDevices();
00231 
00232     if (iso_dev.size() < getCardID()) {
00233       message->errorStream() << "DccCamera > not enough video devices" << endl;
00234       return L1394_FAILED;
00235     }
00236 
00237     isoctx = new DccIso(iso_dev[getCardID()].c_str());
00238 
00239     //is_init = true;
00240     if( isoctx->setParameter(frame_buffer, channel, getFrameSize()) == L1394_FAILED)
00241       return L1394_FAILED;
00242     if( isoctx->startIsoListen() == L1394_FAILED )
00243       return L1394_FAILED;
00244   }
00245   is_init = true;
00246   return L1394_SUCCESS;
00247 }
00248 
00249 void DccCamera::setVideoMode()
00250 {
00251 Quadlet q;
00252 
00253 switch(video_mode)   // set video mode
00254 {
00255   case DEVICE_160x120_YUV_444:
00256     q.setBitRange(29, 31, 0);
00257     write(DCC_BASE + 0x604, q);
00258     setFrameWidth(160);
00259     setFrameHeight(120);
00260     setFrameSize(160 * 120 * 3);
00261     break;
00262 
00263   case DEVICE_320x240_YUV_422:
00264     q.setBitRange(29, 31, 1);
00265     write(DCC_BASE + 0x604, q);
00266     setFrameWidth(320);
00267     setFrameHeight(240);
00268     setFrameSize(320 * 240 * 2);
00269     break;
00270 
00271   case DEVICE_640x480_YUV_411:
00272     q.setBitRange(29, 31, 2);
00273     write(DCC_BASE + 0x604, q);
00274     setFrameWidth(640);
00275     setFrameHeight(480);
00276     setFrameSize(640 * 480 + (640*480)/2 );
00277     break;
00278 
00279   case DEVICE_640x480_YUV_422:
00280     q.setBitRange(29, 31, 3);
00281     write(DCC_BASE + 0x604, q);
00282     setFrameWidth(640);
00283     setFrameHeight(480);
00284     setFrameSize(640 * 480 * 2);
00285     break;
00286 
00287 
00288   case DEVICE_640x480_RGB:
00289     q.setBitRange(29,31,4);
00290     write(DCC_BASE + 0x604, q);
00291     setFrameSize(640 * 480 * 3);
00292     setFrameWidth(640);
00293     setFrameHeight(480);
00294     break;
00295 
00296   case DEVICE_640x480_MONO:
00297     q.setBitRange(29,31,5);
00298     write(DCC_BASE + 0x604, q);
00299     setFrameSize(640*480);
00300     setFrameWidth(640);
00301     setFrameHeight(480);
00302     break;
00303 
00304   case DEVICE_800x600_YUV_422:
00305     q.setBitRange(29,31,0);
00306     write(DCC_BASE + 0x604, q);
00307     setFrameSize(800*600*2);
00308     setFrameWidth(800);
00309     setFrameHeight(600);
00310     break;
00311 
00312   case DEVICE_800x600_RGB:
00313     q.setBitRange(29,31,1);
00314     write(DCC_BASE + 0x604, q);
00315     setFrameSize(800*600*3);
00316     setFrameWidth(800);
00317     setFrameHeight(600);
00318     break;
00319 
00320   case DEVICE_800x600_MONO:
00321     q.setBitRange(29,31,2);
00322     write(DCC_BASE + 0x604, q);
00323     setFrameSize(800*600);
00324     setFrameWidth(800);
00325     setFrameHeight(600);
00326     break;
00327 
00328   case DEVICE_1024x768_YUV_422:
00329     q.setBitRange(29,31,3);
00330     write(DCC_BASE + 0x604, q);
00331     setFrameSize(1024*768*2);
00332     setFrameWidth(1024);
00333     setFrameHeight(768);
00334     break;
00335 
00336   case DEVICE_1024x768_RGB:
00337     q.setBitRange(29,31,4);
00338     write(DCC_BASE + 0x604, q);
00339     setFrameSize(1024*768*3);
00340     setFrameWidth(1024);
00341     setFrameHeight(768);
00342     break;
00343 
00344   case DEVICE_1024x768_MONO:
00345     q.setBitRange(29,31,4);
00346     write(DCC_BASE + 0x604, q);
00347     setFrameSize(1024*768);
00348     setFrameWidth(1024);
00349     setFrameHeight(768);
00350     break;
00351 
00352   case DEVICE_1280x960_YUV_422:
00353     q.setBitRange(29,31,0);
00354     write(DCC_BASE + 0x604, q);
00355     setFrameSize(1280*960*2);
00356     setFrameWidth(1280);
00357     setFrameHeight(960);
00358     break;
00359 
00360   case DEVICE_1280x960_RGB:
00361     q.setBitRange(29,31,1);
00362     write(DCC_BASE + 0x604, q);
00363     setFrameSize(1280*960*3);
00364     setFrameWidth(1280);
00365     setFrameHeight(960);
00366     break;
00367 
00368   case DEVICE_1280x960_MONO:
00369     q.setBitRange(29,31,2);
00370     write(DCC_BASE + 0x604, q);
00371     setFrameSize(1280*960);
00372     setFrameWidth(1280);
00373     setFrameHeight(960);
00374     break;
00375 
00376   case DEVICE_1600x1200_YUV_422:
00377     q.setBitRange(29,31,3);
00378     write(DCC_BASE + 0x604, q);
00379     setFrameSize(1600*1200*2);
00380     setFrameWidth(1600);
00381     setFrameHeight(1200);
00382     break;
00383 
00384   case DEVICE_1600x1200_RGB:
00385     q.setBitRange(29,31,4);
00386     write(DCC_BASE + 0x604, q);
00387     setFrameSize(1600*1200*3);
00388     setFrameWidth(1600);
00389     setFrameHeight(1200);
00390     break;
00391 
00392   case DEVICE_1600x1200_MONO:
00393     q.setBitRange(29,31,5);
00394     write(DCC_BASE + 0x604, q);
00395     setFrameSize(1600*1200);
00396     setFrameWidth(1600);
00397     setFrameHeight(1200);
00398     break;
00399 
00400   }
00401   q.fromInt(0);
00402   if (video_mode >= 0 && video_mode<=5 )
00403     write(DCC_BASE + 0x608, q); // set video format
00404   if (video_mode > 5 && video_mode<=11 )
00405   {
00406     q.setBitRange(29,31,1);
00407     write(DCC_BASE + 0x608, q);
00408   }
00409   if (video_mode > 11 && video_mode<=17 )
00410   {
00411     q.setBitRange(29,31,2);
00412     write(DCC_BASE + 0x608, q);
00413   }
00414   if (video_mode > 17)
00415        message->warningStream() << " DccCamera > Invalid video mode" <<endl;
00416 }
00417 
00418 void DccCamera::setFramerate(const Framerate framerate)
00419 {
00420   frame_rate = framerate;
00421   setFramerate();
00422 }
00423 
00424 void DccCamera::setFramerate()
00425 {
00426   Quadlet q;
00427   switch(frame_rate)
00428   {
00429     case DEVICE_FRAMES_3_75:
00430       q.setBitRange(29, 31, 1);
00431       write(DCC_BASE + 0x600, q);
00432       break;
00433 
00434     case DEVICE_FRAMES_7_5:
00435       q.setBitRange(29, 31, 2);
00436       write(DCC_BASE + 0x600, q);
00437       break;
00438 
00439     case DEVICE_FRAMES_15:
00440       q.setBitRange(29, 31, 3);
00441       write(DCC_BASE + 0x600, q);
00442       break;
00443 
00444     case DEVICE_FRAMES_30:
00445       q.setBitRange(29, 31, 4);
00446       write(DCC_BASE + 0x600, q);
00447       break;
00448     default : message->warningStream() <<"DccCamera > Invalid framerate " << endl;
00449     }
00450 
00451 }
00452 
00453 
00454 bool DccCamera::hasVideoFormat(const Videomode videomode)
00455 {
00456   Quadlet tmp_quadlet;
00457   switch(videomode)
00458   {
00459     case DEVICE_160x120_YUV_444:  if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00460     case DEVICE_320x240_YUV_422:  if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00461     case DEVICE_640x480_YUV_411:  if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00462     case DEVICE_640x480_YUV_422:  if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00463     case DEVICE_640x480_RGB:      if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00464     case DEVICE_640x480_MONO:     if (read(DCC_BASE + 0x180, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00465 
00466     case DEVICE_800x600_YUV_422:  if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00467     case DEVICE_800x600_RGB:      if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00468     case DEVICE_800x600_MONO:     if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00469     case DEVICE_1024x768_YUV_422: if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00470     case DEVICE_1024x768_RGB:     if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00471     case DEVICE_1024x768_MONO:    if (read(DCC_BASE + 0x184, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00472 
00473     case DEVICE_1280x960_YUV_422: if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(31); break;
00474     case DEVICE_1280x960_RGB:     if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(30); break;
00475     case DEVICE_1280x960_MONO:    if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(29); break;
00476     case DEVICE_1600x1200_YUV_422:if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(28); break;
00477     case DEVICE_1600x1200_RGB:    if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(27); break;
00478     case DEVICE_1600x1200_MONO:   if (read(DCC_BASE + 0x188, &tmp_quadlet)) return tmp_quadlet.getBit(26); break;
00479     default : return false;
00480   }
00481   return false;
00482 }
00483 bool DccCamera::hasFramerate(const Videomode mode,const Framerate framerate)
00484 {
00485   Quadlet tmp_quadlet;
00486   if (hasVideoFormat(mode)) {
00487     if (read(DCC_BASE + 0x200 + mode*0x04, &tmp_quadlet) == L1394_SUCCESS)
00488       return tmp_quadlet.getBit(31-framerate);
00489     return false;
00490   }
00491   return false;
00492 }
00493 } //end namespace

Generated on Wed Aug 24 00:36:40 2005 for L1394 by doxygen 1.4.2
L1394 library (NMM) grahics.cs.uni-sb.de/~repplix/l1394_home/