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

l1394_dcciso.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           dcciso.cpp  -  description
00003                              -------------------
00004     begin                : Fri May 4 2001
00005     copyright            : (C) 2001-2004 by Michael Repplinger
00006     email                : repplix@studcs.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_dcciso.h"
00019 #include "l1394_message.h"
00020 
00021 
00022 using std::endl;
00023 
00024 namespace L1394{
00025 namespace internal{
00026 
00027 DccIso::DccIso(const char *device)
00028 {
00029   if (mutex_array == 0)  {
00030     mutex_array = new ThreadMutex*[16];
00031     for (int i = 0; i< 16; i++)
00032       mutex_array[i] = 0;
00033   }
00034   init(&video_mmap);
00035   this->device = device;
00036   fd           = -1;
00037   old_buffer   = 0;
00038   new_buffer   = 0;
00039 
00040   mutex        = new ThreadMutex(ThreadMutex::RECURSIVE);
00041 
00042   release_mode = true;
00043   is_init      = false;
00044   map          = 0;
00045 
00046   frame_array  = 0;
00047   unreleased_buffer = 0;
00048 }
00049 
00050 DccIso::~DccIso()
00051 {
00052   makeClean();
00053   delete mutex;
00054 }
00055 
00056 void DccIso::releaseBuffer(int i)
00057 {
00058   if (unreleased_buffer[i%video_mmap.nb_buffers] == 0) {
00059    // SMessage::getInstance()->warningStream() << "DccIso > Buffer already released : " << i%video_mmap.nb_buffers << endl;
00060   }
00061 
00062   video1394_wait _vwait;
00063   _vwait.channel = video_mmap.channel;
00064   _vwait.buffer  = i % video_mmap.nb_buffers;
00065   SMessage::getInstance()->debugStream() << "DccIso > IOCTRCL release Buffer : " << _vwait.buffer << endl;
00066   if (i >= 0)  {
00067      if (ioctl(fd, VIDEO1394_LISTEN_QUEUE_BUFFER, &_vwait) == -1)  {
00068     //  SMessage::getInstance()->warningStream() << "DccIso > Error in VIDEO1394_LISTEN_QUEUE_BUFFER nr: " << _vwait.buffer << endl;
00069      }
00070   }
00071   SMessage::getInstance()->debugStream() << "DccIso < IOCTRCL release Buffer : " << _vwait.buffer << endl;
00072 }
00073 
00074 Frame *DccIso::getFrame()
00075 {
00076   if (!is_init )
00077     return 0;
00078   if (release_mode)  {
00079     releaseFrame(unreleased_buffer[old_buffer]);
00080   }
00081 
00082   mutex->lock();
00083 
00084   SMessage::getInstance()->debugStream() << "DccIso > Get Frame" << endl;
00085 
00086    video1394_wait vwait;
00087   vwait.channel = video_mmap.channel;
00088   vwait.buffer  = 0;
00089   vwait.filltime.tv_sec =1;
00090   vwait.filltime.tv_usec =0;
00091 
00092   new_buffer    = -1;
00093 
00094   //search for free buffer
00095   for (int i = 0; i < video_mmap.nb_buffers; i++)  {
00096     if ( (frame_array[(i+old_buffer+1) % video_mmap.nb_buffers] != 0) && (new_buffer == -1) )    {
00097       new_buffer = (i+old_buffer+1) % video_mmap.nb_buffers;
00098     }
00099   }
00100 
00101   //if no free buffer, return NULL
00102   if (new_buffer == -1)  {
00103     SMessage::getInstance()->debugStream() << "DccIso > No Frame available. Return NULL" << endl;
00104     mutex->unlock();
00105     return NULL;
00106   }
00107 
00108   SMessage::getInstance()->debugStream() << "DccIso > Frame Nr. " << new_buffer << " available" << endl;
00109 
00110   vwait.buffer = new_buffer;
00111 
00112   SMessage::getInstance()->debugStream() << "DccIso > IOCTRCL on buffer " << vwait.buffer << endl;
00113    if (ioctl(fd, VIDEO1394_LISTEN_WAIT_BUFFER, &vwait)<0)  {
00114      SMessage::getInstance()->errorStream() << "VIDEO1394_LISTEN_WAIT_BUFFER failed" << endl;
00115     mutex->unlock();
00116      return 0;
00117   }
00118 
00119   SMessage::getInstance()->debugStream() << "DccIso < IOCTRCL" << endl;
00120   if (vwait.buffer >0)
00121     SMessage::getInstance()->debugStream() << "DccIso > Buffer ready : " << vwait.buffer << endl;
00122 
00123    unreleased_buffer[new_buffer] = frame_array[new_buffer];
00124   frame_array[new_buffer] = 0;
00125 
00126   old_buffer = new_buffer; //merke letzten buffer
00127 
00128   SMessage::getInstance()->debugStream() << "DccIso < Get Frame" << endl;
00129 
00130   mutex->unlock();
00131 
00132   return unreleased_buffer[new_buffer];
00133 }
00134 
00135 void DccIso::releaseFrame(Frame* buffer)
00136 {
00137   if (buffer == 0)  {
00138    SMessage::getInstance()->warningStream() << "DccIso > Releasing Null ptr" << endl;
00139    return;
00140   }
00141 
00142   mutex->lock();
00143 
00144   int i = (unsigned char*)(buffer->getBuffer()) - map;
00145   i = i / video_mmap.buf_size;
00146 
00147   releaseBuffer( i );
00148   frame_array[i] = buffer;
00149   unreleased_buffer[i] = 0;
00150   mutex->unlock();
00151 }
00152 
00153 int DccIso::setParameter(const int buffercount, const int channel, const int buffersize)
00154 {
00155   mutex->lock();
00156   makeClean();
00157   old_buffer        = buffercount-1;
00158   new_buffer        = 0;
00159 
00160   unreleased_buffer = new Frame*[buffercount];
00161   frame_array       = new Frame*[buffercount];
00162 
00163   if ( mutex_array[channel] ) {
00164     SMessage::getInstance()->errorStream() << "Channel " << channel << " already in use " << endl;
00165     mutex->unlock();
00166     return L1394_FAILED;
00167   }
00168   mutex_array[channel] = mutex;
00169 
00170   video1394_wait vwait;
00171 
00172   video_mmap.channel       = channel;
00173   video_mmap.sync_tag     = VIDEO1394_SYNC_FRAMES;
00174 
00175   if (buffercount <1)
00176     video_mmap.nb_buffers = 1;
00177   else
00178     video_mmap.nb_buffers = buffercount;
00179 
00180   video_mmap.buf_size     = buffersize;
00181   video_mmap.flags         = VIDEO1394_SYNC_FRAMES;
00182 
00183 
00184   vwait.buffer            = 0;
00185   vwait.channel           = channel;
00186 
00187   fd = open(device.c_str(), O_RDWR);
00188   if(fd < 0)  {
00189     SMessage::getInstance()->errorStream()<< "DccIso > Could not open device " << device<< endl;
00190     mutex->unlock();
00191     return L1394_FAILED;
00192   }
00193 
00194   if(ioctl(fd, VIDEO1394_LISTEN_CHANNEL, &video_mmap) < 0)  {
00195     SMessage::getInstance()->errorStream()<< "DccIso > Video listen failed.  " << endl;
00196     mutex->unlock();
00197     return L1394_FAILED;
00198   }
00199 
00200   for(int i = 0; i < video_mmap.nb_buffers; i++)  {
00201     vwait.buffer = i;
00202     if(ioctl(fd, VIDEO1394_LISTEN_QUEUE_BUFFER, &vwait) == -1)    {
00203       SMessage::getInstance()->errorStream() << "DccIso > Queueing Buffer failed" << endl;
00204       mutex->unlock();
00205       return L1394_FAILED;
00206     }
00207   }
00208 
00209   if((map = (unsigned char*)mmap(0, video_mmap.nb_buffers * video_mmap.buf_size, PROT_READ, MAP_SHARED, fd, 0)) == (unsigned char*)-1)
00210   {
00211     SMessage::getInstance()->errorStream() << "DccIso > mmap failed " << endl;
00212     mutex->unlock();
00213     return L1394_FAILED;
00214   }
00215 
00216   for (int i = 0; i<video_mmap.nb_buffers; i++)
00217   {
00218     frame_array[i]       = new Frame( (char*) (map + (i*video_mmap.buf_size)) , buffersize);
00219     //frame_array[i]->setBufferSize( video_mmap.buf_size );
00220     unreleased_buffer[i] = 0;
00221   }
00222   is_init = true;
00223   mutex->unlock();
00224   return L1394_SUCCESS;
00225 }
00226 
00227 int DccIso::startIsoListen() {
00228 //  video1394_wait vwait;
00229 //
00230 //  video_mmap.channel      = video_mmap.channel;
00231 //  video_mmap.sync_tag     = VIDEO1394_SYNC_FRAMES;
00232 //
00233 //  mutex->lock();
00234 //  if(ioctl(fd, VIDEO1394_LISTEN_CHANNEL, &video_mmap) < 0)  {
00235 //    SMessage::getInstance()->errorStream()<< "DccIso > Video listen failed.  " << endl;
00236 //    mutex->unlock();
00237 //    return L1394_FAILED;
00238 //  }
00239 //
00240 //  for(int i = 0; i < video_mmap.nb_buffers; i++)  {
00241 //    vwait.buffer = i;
00242 //    if(ioctl(fd, VIDEO1394_LISTEN_QUEUE_BUFFER, &vwait) == -1)    {
00243 //      SMessage::getInstance()->errorStream() << "DccIso > Queueing Buffer failed" << endl;
00244 //      mutex->unlock();
00245 //      return L1394_FAILED;
00246 //    }
00247 //  }
00248 //  mutex->unlock();
00249   return L1394_SUCCESS;
00250 }
00251 
00252 
00253 int DccIso::stopIsoListen()
00254 {
00255   mutex->lock();
00256   if(ioctl(fd, VIDEO1394_UNLISTEN_CHANNEL, &video_mmap.channel) == -1)
00257   {
00258     SMessage::getInstance()->debugStream() << "DccIso > VIDEO1394_UNLISTEN_CHANNEL failed" << endl;
00259     mutex->unlock();
00260     return L1394_FAILED;
00261   }
00262   mutex->unlock();
00263   return L1394_SUCCESS;
00264 }
00265 
00266 
00267 void DccIso::makeClean() {
00268   for (int i = 0; i< video_mmap.nb_buffers; i++)
00269   {
00270     if (unreleased_buffer[i] != 0)
00271       releaseFrame(unreleased_buffer[i]);
00272     delete frame_array[i]; //delete the Frames
00273   }
00274 
00275   if (map != (unsigned char*)-1)
00276     munmap(map, video_mmap.nb_buffers * video_mmap.buf_size);
00277 
00278   mutex->lock();
00279   if(ioctl(fd, VIDEO1394_UNLISTEN_CHANNEL, &video_mmap.channel) == -1)
00280     SMessage::getInstance()->debugStream() << "DccIso > VIDEO1394_UNLISTEN_CHANNEL failed" << endl;
00281   mutex->unlock();
00282 
00283   if (fd > 0)
00284     close(fd);
00285   fd = -1;                     //set fd to an invalid filedescriptor
00286 
00287   delete [] unreleased_buffer; //delete the array
00288   unreleased_buffer = 0;
00289   delete [] frame_array;       //delete the array
00290   frame_array = 0;
00291   for (int i = 0; i<16; i++)
00292     if (mutex_array[i] == mutex)
00293       mutex_array[i] = 0;
00294   is_init = false;
00295 }
00296 void DccIso::init(video1394_mmap* map) {
00297   map->channel   = -1;
00298   map->sync_tag  = 1;
00299   map->nb_buffers= 0;
00300   map->buf_size  = 0;
00301   map->packet_size = 0;
00302   map->fps = 0;
00303   map->flags = 0;
00304   map->syt_offset = 0;
00305 }
00306 
00307 void DccIso::flushQueue() {
00308   mutex->lock();
00309   for ( int i = 0; i< video_mmap.nb_buffers; i++)
00310     if (frame_array[i])
00311       releaseFrame(frame_array[i]);
00312   mutex->unlock();
00313 }
00314 ThreadMutex** DccIso::mutex_array = 0;
00315 } //end namespace internal
00316 } //end namespace L1394

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/