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

l1394_dviso.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           dviso.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_dviso.h"
00019 #include "l1394_node.h"
00020 #include "l1394_message.h"
00021 #include "l1394_resource.h"
00022 
00023 namespace L1394{
00024 namespace internal{
00025 
00026 DvIso::DvIso(const Node* parent, raw1394handle_t handler)
00027 {
00028   frame_mode = false;
00029 
00030   iso_handler = handler;
00031 
00032   if (dv_iso_array == 0) //create the DvIso Array
00033   {
00034     dv_iso_array = new DvIso*[64];
00035     for (int i = 0; i< 64; i++)
00036       dv_iso_array[i] = 0;
00037   }
00038 
00039   this->parent  = parent;
00040 
00041   iso_listen = false;
00042 
00043 }
00044 
00045 int DvIso::setParameter(const int buffercount, const int channel, const int buffersize)
00046 {
00047   if(iso_listen)
00048   {
00049     SMessage::getInstance()->errorStream() << "DvIso > Parameter could not changed while isolistening" << endl;
00050     return L1394_FAILED;
00051   }
00052 
00053   if (channel > 63)
00054   {
00055     this->channel = 63;
00056     SMessage::getInstance()->errorStream() << "Invalid channel number " << channel<< endl;
00057   }
00058   else
00059     this->channel = channel;
00060   if ( (dv_iso_array[this->channel] != NULL) && (dv_iso_array[this->channel] != this) )
00061   {
00062     SMessage::getInstance()->errorStream() << "Channel " << this->channel <<" already in use" << endl;
00063     return L1394_FAILED;
00064   }
00065   else
00066     dv_iso_array[this->channel] = this;
00067 
00068   for (int i = 0; i< buffercount; i++)
00069     frame_queue.insert(frame_queue.begin(), new Frame(buffersize));//1440000
00070 
00071   current_frame = frame_queue.front();
00072   frame_queue.pop_front();
00073   return L1394_SUCCESS;
00074 }
00075 
00076 DvIso::~DvIso(){
00077 
00078   dv_iso_array[channel] = 0;
00079 
00080   for (int i = 0; i< 64; i++)
00081     if ( dv_iso_array[i] == 0)
00082       return ;
00083 
00084   delete [] dv_iso_array;
00085 }
00086 
00087 
00088 /* from Arne Schirmacher's DvGrab */
00089 int DvIso::L1394IsoHandle(raw1394handle_t , int channel, size_t length,  quadlet_t *data)
00090 {
00091    //cout << "Node > receiving iso data on channel "<< channel << " of size " << length << endl;
00092    DvIso* dv_iso = dv_iso_array[channel];
00093    if (dv_iso == 0)
00094      return 0;
00095 
00096     if (length > 16)
00097     {
00098       unsigned char *p = (unsigned char*) & data[3];
00099       int section_type = p[0] >> 5;           /* section type is in bits 5 - 7 */
00100       int dif_sequence = p[1] >> 4;           /* dif sequence number is in bits 4 - 7 */
00101       int dif_block = p[2];
00102       if (section_type == 0 && dif_sequence == 0)
00103       {
00104         dv_iso->ready_frames.push_back(dv_iso->current_frame);
00105         if (dv_iso->frame_queue.size() > 0)
00106         {
00107           dv_iso->mutex.lock();
00108           dv_iso->current_frame = dv_iso->frame_queue.front();
00109           dv_iso->frame_queue.pop_front();
00110           dv_iso->current_frame->setBufferSize(0); //reset the used buffersize to 0
00111           dv_iso->mutex.unlock();
00112         }
00113         else
00114           dv_iso->current_frame = 0;
00115 
00116         cout << "start new frame" << endl;
00117       }
00118 
00119       else
00120       {
00121         if (dv_iso->current_frame != NULL)
00122         {
00123           switch (section_type)
00124           {
00125             case 0:           // 1 Header block
00126               memcpy(dv_iso->current_frame->getBuffer() + dif_sequence * 150 * 80, p, 480);
00127               break;
00128 
00129             case 1:           // 2 Subcode blocks
00130               memcpy(dv_iso->current_frame->getBuffer() + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p, 480);
00131               break;
00132 
00133             case 2:           // 3 VAUX blocks
00134               memcpy(dv_iso->current_frame->getBuffer() + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p, 480);
00135               break;
00136 
00137             case 3:           // 9 Audio blocks interleaved with video
00138               memcpy(dv_iso->current_frame->getBuffer() + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p, 480);
00139               break;
00140 
00141             case 4:           // 135 Video blocks interleaved with audio
00142               memcpy(dv_iso->current_frame->getBuffer()  + dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, p, 480);
00143               break;
00144 
00145             default:           // we can't handle any other data
00146               break;
00147           }
00148         dv_iso->current_frame->setBufferSize(480+dv_iso->current_frame->getBufferSize());
00149         }
00150       }
00151     }
00152     else
00153     cout << "receive small buffer" << endl;
00154   return L1394_SUCCESS;
00155 }
00156 
00157 int DvIso::startIsoListen()
00158 {
00159   raw1394_set_iso_handler(iso_handler, channel, L1394IsoHandle);
00160 
00161   if (raw1394_start_iso_rcv(iso_handler, channel) < 0)
00162   {
00163     SMessage::getInstance()->errorStream() <<"raw1394 - couldn't start iso receive" << endl;
00164  //   cout <<"raw1394 - couldn't start iso receive" << endl;
00165     return L1394_FAILED;
00166   }
00167 
00168   pthread_create(&thread, 0, run_static, (void *)this);
00169 
00170   return L1394_SUCCESS;
00171 }
00172 
00173 void DvIso::isoRun()
00174 {
00175   iso_listen = true;
00176   while(iso_listen)
00177       raw1394_loop_iterate(iso_handler);
00178 }
00179 
00180 int DvIso::stopIsoListen()
00181 {
00182   iso_listen = false;
00183   dv_iso_array[channel] = 0;
00184   //releaseIsoChannel(iso_channel);
00185   return L1394_SUCCESS;
00186 }
00187 
00188 Frame* DvIso::getFrame()
00189 {
00190   if (ready_frames.size() > 0)
00191   {
00192     mutex.lock();
00193     Frame* frame = ready_frames.front();
00194     ready_frames.pop_front();
00195     mutex.unlock();
00196     //unreleased_frames.insert(unreleased_frames.begin(), frame);
00197     return frame;
00198   }
00199 
00200   return 0;
00201 }
00202 
00203 
00204 void DvIso::releaseFrame(Frame* frame)
00205 {
00206   mutex.lock();
00207   frame_queue.push_back(frame);
00208   mutex.unlock();
00209 }
00210 
00211 void* DvIso::run_static(void *me) {(static_cast<DvIso*>(me))->isoRun(); return 0; }
00212 
00213 DvIso** DvIso::dv_iso_array = 0;
00214 
00215 } //namespace internal
00216 } //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/