00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "LIN_DVCam.hpp"
00027
00028
00029
00030
00031 #include <cstdio>
00032 #include <sys/poll.h>
00033 #include <signal.h>
00034 #include <cstring>
00035 #include <cstdlib>
00036 #include <boost/bind.hpp>
00037 #include <errno.h>
00038
00039
00040
00041
00042 namespace kn{
00043
00044 int DVCam::callbackReadFrame( unsigned char *data,
00045 int length,
00046 int complete,
00047 void *callback_data)
00048 {
00049 if(complete && length > 0){
00050 DVCam * self = static_cast<DVCam *>( callback_data );
00051 return self->ReadFrame(data);
00052 }
00053 usleep(500);
00054 return 0;
00055 }
00056
00057 int DVCam::ReadFrame(unsigned char *data)
00058 {
00059 if( dv_parse_header(td, data) < 0 ){ std::cerr << " DVCam::Handler : Error in header of data" << std::endl; return -1;}
00060 boost::mutex::scoped_lock lock(dvmutex);
00061 unsigned int tmpindice = (currentframe+1)%maxframe;
00062
00063 dv_decode_full_frame(td, data, e_dv_color_rgb, pixels[tmpindice], pitches);
00064 currentframe = tmpindice;
00065 usleep(200);
00066 return 0;
00067 }
00068
00069 void DVCam::ResetHandler( void )
00070 {
00071 }
00072
00073 int DVCam::ResetHandlerProxy( raw1394handle_t handle, unsigned int generation )
00074 {
00075 iec61883_dv_t dv = static_cast< iec61883_dv_t >( raw1394_get_userdata( handle ) );
00076 iec61883_dv_fb_t dvfb = static_cast< iec61883_dv_fb_t >( iec61883_dv_get_callback_data( dv ) );
00077 DVCam *self = static_cast< DVCam* >( iec61883_dv_fb_get_callback_data( dvfb ) );
00078 raw1394_update_generation( handle, generation );
00079 if ( self )
00080 self->ResetHandler();
00081 return 0;
00082 }
00083
00084
00085 void DVCam::openDevice(const DVCamParams& params)
00086 {
00087
00088 this->camwidth = 720;
00089 this->camheight = 576;
00090
00091 if(isenable)
00092 closeDevice();
00093
00094 if(params.port < 0)
00095 throw ControllerException("Channel is not valid","DVCam::openDevice");
00096
00097
00098 handle = raw1394_new_handle_on_port(params.port);
00099 if(!handle)
00100 throw ControllerException("Failed to get handle","DVCam::openDevice");
00101
00102
00103 td = dv_decoder_new(FALSE,FALSE,FALSE);
00104 td->quality=DV_QUALITY_BEST;
00105
00106 raw1394_set_bus_reset_handler( handle, this->ResetHandlerProxy );
00107
00108
00109
00110 frame = iec61883_dv_fb_init(handle,DVCam::callbackReadFrame, this);
00111
00112 if(!frame)
00113 throw ControllerException("Failed to init DV","DVCam::openDevice");
00114
00115 isenable=true;
00116
00117 }
00118
00119 void DVCam::closeDevice(void)
00120 {
00121 stop();
00122 if(handle) raw1394_destroy_handle(handle);
00123 handle = 0;
00124 isenable=false;
00125 isgrabbing=false;
00126 td=0;
00127 isenable = false;
00128 frame = 0;
00129
00130 }
00131
00132 void DVCam::start(void)
00133 {
00134
00135 if (frame){
00136 if(!isgrabbing){
00137 isgrabbing = true;
00138 if(iec61883_dv_fb_start (frame, 63)<0)
00139 throw ControllerException("start error","DVCam::start");
00140 thrd = new boost::thread(boost::bind(&DVCam::Handler, this));
00141 }
00142 }else{
00143 throw ControllerException("DVCam not opened","DVCam::start");
00144 }
00145
00146
00147 usleep(120000);
00148 }
00149
00150 void DVCam::stop(void)
00151 {
00152 if(isgrabbing){
00153 isgrabbing = false;
00154 thrd->join();
00155 delete thrd;
00156 thrd = 0;
00157 iec61883_dv_fb_close(frame);
00158 frame = 0;
00159 }
00160 }
00161
00162
00163 unsigned char* DVCam::getImage(void)
00164 {
00165 if(!isgrabbing){start();}
00166 boost::mutex::scoped_lock lock(dvmutex);
00167 return pixels[currentframe][0];
00168 }
00169
00170 void DVCam::Handler(void)
00171 {
00172 struct pollfd raw1394_poll;
00173 raw1394_poll.fd = raw1394_get_fd( handle );
00174 raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;
00175
00176 int result = 0;
00177 while ( isgrabbing ){
00178 while ( ( result = poll( &raw1394_poll, 1, 300 ) ) < 0 )
00179 {
00180 if ( !( errno == EAGAIN || errno == EINTR ) )
00181 {
00182 perror( "error: raw1394 poll" );
00183 break;
00184 }
00185 }
00186 if ( result > 0 && ( ( raw1394_poll.revents & POLLIN )
00187 || ( raw1394_poll.revents & POLLPRI ) ) ){
00188 result = raw1394_loop_iterate( handle );
00189 }
00190 usleep(10);
00191 }
00192
00193 }
00194 }