00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "AxisSource.h"
00023
00024 AxisSource::AxisSource(char* axis_name, FrameSize frame_size)
00034 {
00035 if(frame_size == 0){
00036 dims[0] = 352;
00037 dims[1] = 288;
00038 }else if(frame_size == 1){
00039 dims[0] = 704;
00040 dims[1] = 576;
00041 }else if(frame_size == 2){
00042 dims[0] = 320;
00043 dims[1] = 240;
00044 }else{
00045 cerr << "Unsupported Frame Size chosen" << endl;
00046 cerr << "Choose HALF (352x288), FULL (704x576), or CIF (320x240) " << endl;
00047 abort();
00048 }
00049
00050
00051 vs = videoSocket(axis_name);
00052
00053
00054 requestStream(vs);
00055
00056
00057 type = Image::COLOUR;
00058 }
00059
00065 AxisSource::AxisSource()
00066 {
00067 vs = videoSocket("iri32");
00068 dims[0] = 352;
00069 dims[1] = 288;
00070 requestStream(vs);
00071 type = Image::COLOUR;
00072 }
00073
00079 AxisSource::~AxisSource()
00080 {
00081
00082 close(vs);
00083 }
00084
00092 ImageSource& AxisSource::operator >> (ImageRGB& img)
00093 {
00094 unsigned char *image;
00095 readNextFrame(vs,image,dims);
00096
00097 PixelRGB *img_ptr = img.data;
00098 int y_cnt;
00099 int x_cnt;
00100 unsigned char* src_ptr = image + 4*dims[0]*dims[1];
00101 src_ptr += 4*dims[0];
00102
00103 for(y_cnt=0 ; y_cnt< dims[1] ; y_cnt++){
00104 src_ptr -= 2*4*dims[0];
00105 for(x_cnt=0 ; x_cnt< dims[0] ; x_cnt++){
00106 PixelRGB pix((int) *(src_ptr++),
00107 (int) *(src_ptr++),
00108 (int) *(src_ptr++));
00109 *(img_ptr++) = pix ;
00110 src_ptr++;
00111 }
00112 }
00113 delete [] image;
00114 return *this;
00115 }
00116
00124 ImageSource& AxisSource::operator >> (ImageGrey& img)
00125 {
00126 unsigned char *image;
00127 readNextFrame(vs,image,dims);
00128
00129 PixelGrey *img_ptr = img.brightness;
00130 int y_cnt;
00131 int x_cnt;
00132 unsigned char* src_ptr = image + 4*dims[0]*dims[1];
00133 src_ptr += 4*dims[0];
00134
00135 for(y_cnt=0 ; y_cnt< dims[1] ; y_cnt++){
00136 src_ptr -= 2*4*dims[0];
00137 for(x_cnt=0 ; x_cnt< dims[0] ; x_cnt++){
00138 *(img_ptr++) = (PixelGrey)( (RED_COEF*(float)(*src_ptr++)) +
00139 (GREEN_COEF*(float)(*src_ptr++)) +
00140 (BLUE_COEF*(float)(*src_ptr++)) );
00141 src_ptr++;
00142 }
00143 }
00144 delete [] image;
00145 return *this;
00146 }
00147
00157 ImageSource& AxisSource::operator >> (Image& img)
00158 {
00159 (type == Image::COLOUR) ? *this >> (ImageRGB&)img
00160 : *this >> (ImageGrey&)img;
00161
00162 return *this;
00163 }
00164
00165
00166 int AxisSource::videoSocket(char *hostname)
00167 {
00168 int sockfd;
00169 hostent *he;
00170 protoent *protoEntry;
00171 sockaddr_in their_addr;
00172
00173
00174 if ((he = gethostbyname(hostname)) == NULL)
00175 {
00176 string msg("\'gethostbyname\' failed for ");
00177 msg += hostname;
00178
00179 throw msg.c_str();
00180 }
00181
00182 protoEntry = getprotobyname("tcp");
00183 short protocol = protoEntry->p_proto;
00184
00185
00186 if ((sockfd = socket(PF_INET, SOCK_STREAM, protocol)) == -1)
00187 {
00188 throw "Failed to open socket";
00189 }
00190
00191 int on=1;
00192 setsockopt(sockfd, protoEntry->p_proto, TCP_NODELAY, &on, sizeof(int));
00193
00194
00195 their_addr.sin_family = AF_INET;
00196 their_addr.sin_port = htons(PORT);
00197 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
00198 memset(&(their_addr.sin_zero), 0, 8);
00199
00200
00201 if (connect(sockfd, (sockaddr *) &their_addr, sizeof(sockaddr)) == -1)
00202 {
00203 throw "Unable to connect to server..\n";
00204 }
00205
00206 return sockfd;
00207 }
00208
00209
00210 void AxisSource::requestStream(int sockfd)
00211 {
00212
00213 char req[1000] ;
00214
00215 sprintf(req,
00216 "GET /cgi-bin/mjpg/video.cgi?showlength=1&resolution=%dx%d "
00217 "HTTP/1.0\n\n",
00218 dims[0],dims[1]) ;
00219
00220 cout << "Request: " << req;
00221
00222
00223 if (send(sockfd, req, strlen(req), 0) == -1)
00224 {
00225 string msg("Unable to send following request to server: \n\n");
00226 msg += req;
00227
00228 throw msg;
00229 }
00230
00231
00232 unsigned char seqHeader[82];
00233
00234 readSocket(sockfd, seqHeader,81);
00235
00236 seqHeader[81]='\0';
00237 cout << "Received sequence header:\n" << seqHeader;
00238 }
00239
00240
00241 void AxisSource::readNextFrame(int sockfd, unsigned char* &image, int imgSize[2])
00242 {
00243 int buffLength;
00244 int readCount=1;
00245 unsigned char *imgBuff;
00246
00247 while (readCount==1)
00248 {
00249 readCount = readFrame(sockfd, imgBuff, buffLength);
00250 if (readCount==1) delete [] imgBuff;
00251 }
00252
00253 decodeFrame(imgBuff, buffLength, image, imgSize);
00254
00255 delete [] imgBuff;
00256 }
00257
00258
00259 int AxisSource::readFrame(int sockfd, unsigned char* &imgBuff, int &buffLength)
00260 {
00261 int readCount;
00262 int imgLength;
00263 unsigned char *recvBuff;
00264 unsigned char imgHeader[128];
00265
00266
00267 readSocket(sockfd, imgHeader, 13);
00268 imgHeader[13]='\0';
00269
00270
00271 readSocket(sockfd, imgHeader, 25);
00272 imgHeader[25]='\0';
00273
00274
00275 readSocket(sockfd, imgHeader, 24);
00276 imgHeader[24]='\0';
00277
00278 imgLength = 0;
00279 char tmpBuff[128];
00280 for (int i = 0; i < 128; i++) tmpBuff[i] = imgHeader[i];
00281 sscanf(tmpBuff, "Content-Length: %d\n", &imgLength);
00282
00283 if (imgLength < 10000)
00284 {
00285 recvBuff = new unsigned char[imgLength];
00286 recvBuff[0] = imgHeader[22];
00287 recvBuff[1] = imgHeader[23];
00288
00289 unsigned char *tmpHolder = &(recvBuff[2]);
00290 readCount = readSocket(sockfd, tmpHolder, imgLength-2);
00291 }
00292 else if(imgLength < 100000)
00293 {
00294 recvBuff = new unsigned char[imgLength];
00295 recvBuff[0] = imgHeader[23];
00296
00297 unsigned char *tmpHolder = &(recvBuff[1]);
00298 readCount = readSocket(sockfd, tmpHolder, imgLength-1);
00299 }
00300 else
00301 {
00302
00303 recvBuff = new unsigned char[imgLength];
00304 readCount = readSocket(sockfd, recvBuff, imgLength);
00305 }
00306
00307 imgBuff = recvBuff;
00308 buffLength = imgLength;
00309
00310
00311 unsigned char tmp[128];
00312 readSocket(sockfd, tmp, 2);
00313
00314 return readCount;
00315 }
00316
00317
00318 int AxisSource::readSocket(int sockfd, unsigned char *buff, int buffLength)
00319 {
00320 int count = 0, bytesRead = 0;
00321
00322 while (count < buffLength)
00323 {
00324 bytesRead = recv(sockfd, buff+count, buffLength-count, MSG_TRUNC);
00325 count += bytesRead;
00326 }
00327
00328 return (bytesRead == count);
00329 }
00330
00331 void AxisSource::decodeFrame(unsigned char* imgBuff, int buffLength,
00332 unsigned char* &image, int imgSize[2])
00333 {
00334 struct jpeg_error_mgr jerr;
00335 jpeg_decompress_struct cinfo;
00336 cinfo.err = jpeg_std_error(&jerr);
00337
00338 jpeg_create_decompress(&cinfo);
00339 jpeg_mem_src(&cinfo, imgBuff, buffLength);
00340 jpeg_read_header(&cinfo, TRUE);
00341
00342 jpeg_start_decompress(&cinfo);
00343
00344 int rowStride = cinfo.output_width * cinfo.num_components;
00345 int total = rowStride*cinfo.output_height;
00346
00347 JSAMPLE *cdata = new JSAMPLE[total];
00348 JSAMPLE *base = cdata;
00349
00350 int numread;
00351 while(cinfo.output_scanline < cinfo.output_height)
00352 {
00353 numread = jpeg_read_scanlines(&cinfo, &cdata, cinfo.rec_outbuf_height);
00354 cdata += numread*rowStride;
00355 }
00356
00357 int ArowStride = cinfo.output_width * (cinfo.num_components+1);
00358 int Atotal = ArowStride*cinfo.output_height;
00359 JSAMPLE *idata = new JSAMPLE[Atotal];
00360
00361
00362
00363 for(int j=Atotal-ArowStride, i=0; j>=0; j-=2*ArowStride)
00364 {
00365 for (int k=0; k<rowStride; k+=3, i+=3, j+=4)
00366 {
00367 idata[j] = base[i];
00368 idata[j+1] = base[i+1];
00369 idata[j+2] = base[i+2];
00370 idata[j+3] = 0;
00371 }
00372 }
00373 delete [] base;
00374 base = idata;
00375
00376
00377 image = base;
00378 imgSize[0] = cinfo.output_width;
00379 imgSize[1] = cinfo.output_height;
00380
00381 jpeg_finish_decompress(&cinfo);
00382 }
00383
00384
00385
00386
00387
00388