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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "Unicap1394Capture.h"
00047
00048 #include "Image/ByteImage.h"
00049
00050 #include <stdio.h>
00051 #include <string.h>
00052 #include <string>
00053
00054
00055
00056
00057
00058
00059 #define UYVY 0x59565955
00060 #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a)
00061
00062
00063
00064
00065
00066
00067
00068 CUnicap1394Capture::CUnicap1394Capture(int nCameras, VideoMode mode) : m_nCameras(nCameras), m_mode(mode)
00069 {
00070 source = 4;
00071 width = 0;
00072 height = 0;
00073 norm = 0;
00074
00075 for (int i = 0; i < UNICAP_MAX_CAMERAS; i++)
00076 handle[i] = 0;
00077 }
00078
00079 CUnicap1394Capture::~CUnicap1394Capture()
00080 {
00081 CloseCamera();
00082 }
00083
00084
00085
00086
00087
00088
00089 bool CUnicap1394Capture::OpenCamera()
00090 {
00091 unicap_property_t property;
00092 unicap_format_t format;
00093 unicap_format_t format_spec;
00094
00095 int nCamerasFound = 0;
00096
00097
00098 for (int i = 0; i < 10; i++)
00099 {
00100 if (SUCCESS(unicap_enumerate_devices(0, &device[i], i)))
00101 {
00102 printf("info: camera found at index %i\n", i);
00103 printf("info: using device for cam: %s\n", device[i].identifier);
00104 nCamerasFound++;
00105 }
00106
00107 if (!SUCCESS(unicap_open(&handle[i], &device[i])))
00108 {
00109 printf("error2\n");
00110 return false;
00111 }
00112
00113 unicap_void_property( &property );
00114 strcpy( property.identifier, "video norm" );
00115 unicap_get_property( handle[i], &property );
00116 strcpy( property.menu_item, property.menu.menu_items[this->norm] );
00117 if(!SUCCESS(unicap_set_property(handle[i], &property)))
00118 {
00119 printf("error3\n");
00120 return false;
00121 }
00122
00123 unicap_void_property( &property );
00124 strcpy( property.identifier, "source" );
00125 unicap_get_property( handle[i], &property );
00126 strcpy( property.menu_item, property.menu.menu_items[this->source] );
00127 if(!SUCCESS(unicap_set_property(handle[i], &property)))
00128 {
00129 printf("error4\n");
00130 return false;
00131 }
00132
00133 if(!SUCCESS(unicap_lock_stream(handle[i])))
00134 {
00135 printf("error5\n");
00136 return false;
00137 }
00138
00139 unicap_status_t status=0;
00140 unicap_void_format( &format_spec );
00141
00142 format_spec.fourcc = FOURCC('U','Y','V','Y');
00143 int num= - 1;
00144 status = unicap_enumerate_formats(handle[i], &format_spec, &format, 0 );
00145 if(!SUCCESS(status))
00146 {
00147 printf("error: failed get video format\n");
00148 return false;
00149 }
00150
00151 for (int j = 0; j < format.size_count; j++)
00152 {
00153 printf("format %i: width/height = %i/%i\n", j, format.sizes[j].width, format.sizes[j].height);
00154
00155 switch (m_mode)
00156 {
00157 case e320x240:
00158 if (format.sizes[j].width == 320 && format.sizes[j].height == 240)
00159 {
00160 num = j;
00161 width = 320;
00162 height = 240;
00163 }
00164 break;
00165
00166 case e640x480:
00167 if (format.sizes[j].width == 640 && format.sizes[j].height == 480)
00168 {
00169 num = j;
00170 width = 640;
00171 height = 480;
00172 }
00173 break;
00174
00175 case e768x576:
00176 if (format.sizes[j].width == 768 && format.sizes[j].height == 576)
00177 {
00178 num = j;
00179 width = 768;
00180 height = 576;
00181 }
00182 break;
00183 }
00184 }
00185
00186 if (num < 0)
00187 {
00188 printf("error: could not found matching mode\n");
00189 return false;
00190 }
00191
00192 printf("info: took format %i with resolution %i/%i\n", num, width, height);
00193
00194 format.size.width = format.sizes[num].width;
00195 format.size.height = format.sizes[num].height;
00196
00197 if(!SUCCESS( unicap_set_format(handle[i], &format ) ) )
00198 {
00199 printf("error: Failed to set video format\n" );
00200 return false;
00201 }
00202 if( !SUCCESS( unicap_get_format(handle[i], &format ) ) )
00203 {
00204 printf("error: Failed to get video format\n" );
00205 return false;
00206 }
00207 memset(&buffer[i], 0x0, sizeof(unicap_data_buffer_t));
00208 buffer[i].format = format;
00209 buffer[i].buffer_size = format.buffer_size;
00210 buffer[i].type = format.buffer_type;
00211
00212 printf("info: %s->Buffer size: %d\n",device[i].identifier,format.buffer_size);
00213
00214 if (buffer[i].type == UNICAP_BUFFER_TYPE_USER)
00215 buffer[i].data = new unsigned char[buffer[i].buffer_size];
00216
00217 status = unicap_start_capture(handle[i]);
00218 if(!SUCCESS(status))
00219 {
00220 printf("error: failed to start capture on device: %s (Error Code : %x)\n", device[i].identifier,status );
00221 return false;
00222 }
00223
00224 printf("\n");
00225
00226 if (nCamerasFound == m_nCameras)
00227 break;
00228 }
00229
00230 if (nCamerasFound < 0 || (m_nCameras != -1 && nCamerasFound != m_nCameras))
00231 return false;
00232
00233 return true;
00234 }
00235
00236 void CUnicap1394Capture::CloseCamera()
00237 {
00238 for (int i = 0; i < UNICAP_MAX_CAMERAS; i++)
00239 {
00240 if (handle[i])
00241 {
00242 if (!unicap_stop_capture(handle[i]))
00243 printf("error: close\n");
00244
00245 unicap_unlock_stream(handle[i]);
00246
00247 if(!SUCCESS(unicap_close(handle[i])))
00248 {
00249 printf("error: destructor\n");
00250 }
00251
00252 handle[i] = 0;
00253 }
00254 }
00255
00256 }
00257
00258 void CUnicap1394Capture::Convert(const unsigned char *input, unsigned char *output)
00259 {
00260 const int nBytes = width * height * 2;
00261
00262 float u,y1,v,y2,r1,g1,b1,r2,g2,b2;
00263
00264 for(unsigned int i = 0,j=0; i<nBytes;i+=4,j+=6)
00265 {
00266 u = input[i];
00267 y1 =input[i+1];
00268 v = input[i+2];
00269 y2 =input[i+3];
00270
00271 u -= 128;
00272 v -= 128;
00273 y1 -= 16;
00274 y2 -= 16;
00275
00276 r1 = 1.164f * y1 + 1.596f * v;
00277 g1 = 1.164f * y1 - 0.392f * u - 0.813f * v;
00278 b1 = 1.164f * y1 + 2.017f * u;
00279
00280 r2 = 1.164f * y2 + 1.596f * v;
00281 g2 = 1.164f * y2 - 0.392f * u - 0.813f * v;
00282 b2 = 1.164f * y2 + 2.017f * u;
00283
00284
00285 if (r1 < 0) r1 = 0;
00286 if (g1 < 0) g1 = 0;
00287 if (b1 < 0) b1 = 0;
00288 if (r1 > 255) r1 = 255;
00289 if (g1 > 255) g1 = 255;
00290 if (b1 > 255) b1 = 255;
00291
00292 if (r2 < 0) r2 = 0;
00293 if (g2 < 0) g2 = 0;
00294 if (b2 < 0) b2 = 0;
00295 if (r2 > 255) r2 = 255;
00296 if (g2 > 255) g2 = 255;
00297 if (b2 > 255) b2 = 255;
00298
00299 output[j] = (unsigned char)r1;
00300 output[j+1]= (unsigned char)g1;
00301 output[j+2]= (unsigned char)b1;
00302 output[j+3]= (unsigned char)r2;
00303 output[j+4]= (unsigned char)g2;
00304 output[j+5]= (unsigned char)b2;
00305 }
00306 }
00307
00308 bool CUnicap1394Capture::CaptureImage(CByteImage **ppImages)
00309 {
00310 unicap_data_buffer_t *returned_buffer[10] = { 0 };
00311 for (int i = 0; i < m_nCameras; i++)
00312 {
00313
00314 unicap_status_t status = unicap_queue_buffer(handle[i], &buffer[i]);
00315 if(!SUCCESS(status))
00316 {
00317 printf("error: failed to queue a buffer on device: %s (Error Code : %x)\n", device[i].identifier,status);
00318 return false;
00319 }
00320
00321 status = unicap_wait_buffer(handle[i], &returned_buffer[i]);
00322
00323 if (!SUCCESS(status))
00324 {
00325 printf("error: %x\n", status);
00326 printf("error: failed to wait for buffer on device: %s (Error Code : %x)\n", device[i].identifier,status );
00327 }
00328
00329 Convert(returned_buffer[i]->data, ppImages[i]->pixels);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 return true;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389