00001
00002
00003
00004
00005
00006 #include "opt_nm33_camera.h"
00007
00008 #include <opencv/cv.h>
00009 #include <opencv/highgui.h>
00010
00011
00012 #include <fcntl.h>
00013 #include <sys/mman.h>
00014 #include <unistd.h>
00015 #define CLEAR(x) memset (&(x), 0, sizeof (x))
00016
00017
00018 static bool
00019 mjpeg_to_rgb24 (int width, int height,
00020 unsigned char *src, int length,
00021 unsigned char *dst)
00022 {
00023 cv::Mat temp=cv::imdecode(cv::Mat(std::vector<uchar>(src, src + length)), 1);
00024 if( !temp.data || temp.cols != width || temp.rows != height )
00025 return false;
00026 memcpy(dst, temp.data, width*height*3);
00027 return true;
00028 }
00029
00030 void OptNM3xCamera::device_open(int camera_index)
00031 {
00032
00033 char dev_name[128];
00034 sprintf(dev_name, "/dev/video%1d", camera_index);
00035 fprintf(stderr, "Opening device '%s'\n", dev_name);
00036
00037 width = 640;
00038 height = 480;
00039
00040 try_again:
00041 fd = open(dev_name, O_RDWR, 0);
00042
00043 if (fd == -1) {
00044 fprintf(stderr, "Cannot open '%s': %d, %s\n",
00045 dev_name, errno, strerror(errno));
00046 exit(EXIT_FAILURE);
00047 }
00048
00049
00050 struct v4l2_capability cap;
00051 struct v4l2_format fmt;
00052
00053 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
00054 if (EINVAL == errno) {
00055 fprintf(stderr, "%s is no V4L2 device\n", dev_name);
00056 }
00057 perror("VIDIOC_QUERYCAP");
00058 exit(EXIT_FAILURE);
00059 }
00060
00061 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00062 fprintf(stderr, "%s is no video capture device\n", dev_name);
00063 exit(EXIT_FAILURE);
00064 }
00065
00066 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
00067 fprintf(stderr, "%s does not support streaming i/o\n", dev_name);
00068 exit(EXIT_FAILURE);
00069 }
00070
00071 CLEAR(fmt);
00072
00073 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00074 fmt.fmt.pix.width = width;
00075 fmt.fmt.pix.height = height;
00076 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
00077 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00078
00079 if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
00080 perror("VIDIOC_S_FMT");
00081 exit(EXIT_FAILURE);
00082 }
00083
00084
00085 struct v4l2_requestbuffers req;
00086
00087 CLEAR(req);
00088
00089 req.count = 4;
00090 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00091 req.memory = V4L2_MEMORY_MMAP;
00092
00093 if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
00094 perror("VIDIOC_REQBUFS");
00095 exit(EXIT_FAILURE);
00096 }
00097
00098 if (req.count < 2) {
00099 fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name);
00100 exit(EXIT_FAILURE);
00101 }
00102
00103 buffers = (buffer *)calloc(req.count, sizeof(*buffers));
00104
00105 if (!buffers) {
00106 fprintf(stderr, "Out of memory\n");
00107 exit(EXIT_FAILURE);
00108 }
00109
00110 for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
00111 struct v4l2_buffer buf;
00112
00113 CLEAR(buf);
00114
00115 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00116 buf.memory = V4L2_MEMORY_MMAP;
00117 buf.index = n_buffers;
00118
00119 if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
00120 perror("VIDIOC_QUERYBUF");
00121 exit(EXIT_FAILURE);
00122 }
00123
00124 buffers[n_buffers].length = buf.length;
00125 buffers[n_buffers].start = mmap(NULL ,
00126 buf.length, PROT_READ | PROT_WRITE
00127 ,
00128 MAP_SHARED ,
00129 fd, buf.m.offset);
00130
00131 if (buffers[n_buffers].start == MAP_FAILED) {
00132 perror("mmap");
00133 exit(EXIT_FAILURE);
00134 }
00135 }
00136
00137
00138 unsigned int i;
00139 enum v4l2_buf_type type;
00140
00141 for (i = 0; i < n_buffers; ++i) {
00142 struct v4l2_buffer buf;
00143
00144 CLEAR(buf);
00145
00146 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00147 buf.memory = V4L2_MEMORY_MMAP;
00148 buf.index = i;
00149
00150 if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00151 if ( width == 640 && height == 480 ) {
00152 device_close();
00153 width = 320; height = 240;
00154 goto try_again;
00155 }
00156 perror("VIDIOC_QBUF");
00157 exit(EXIT_FAILURE);
00158 }
00159 }
00160
00161 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00162
00163 if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
00164 if ( width == 640 && height == 480 ) {
00165 device_close();
00166 width = 320; height = 240;
00167 goto try_again;
00168 }
00169 perror("VIDIOC_STREAMON");
00170 exit(EXIT_FAILURE);
00171 }
00172
00173 fprintf(stderr, "video capabilities\n");
00174 fprintf(stderr, "cap.driver = %s\n", cap.driver);
00175 fprintf(stderr, "cap.card = %s\n", cap.card);
00176 fprintf(stderr, "cap.buf_info = %s\n", cap.bus_info);
00177 fprintf(stderr, "cap.version = %d\n", cap.version);
00178 fprintf(stderr, "cap.capabilities = 0x%08x ", cap.capabilities);
00179 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
00180 fprintf(stderr, " VIDEO_CAPTURE");
00181 if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
00182 fprintf(stderr, " VIDEO_OUTPUT");
00183 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
00184 fprintf(stderr, " VIDEO_OVERLAY");
00185 if (cap.capabilities & V4L2_CAP_VBI_CAPTURE)
00186 fprintf(stderr, " VBI_CAPTURE");
00187 if (cap.capabilities & V4L2_CAP_VBI_OUTPUT)
00188 fprintf(stderr, " VBI_OUTPUT");
00189 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
00190 if (cap.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
00191 fprintf(stderr, " SLICED_VBI_CAPTURE");
00192 #endif
00193 #ifdef V4L2_CAP_SLICED_VBI_OUTPUT
00194 if (cap.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
00195 fprintf(stderr, " VBI_SLICED_OUTPUT");
00196 #endif
00197 if (cap.capabilities & V4L2_CAP_RDS_CAPTURE)
00198 fprintf(stderr, " RDS_CAPTURE");
00199 #if V4L2_CAP_VIDEO_OUTPUT_OVERLAY
00200 if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
00201 fprintf(stderr, " VIDEO_OUTPUT_OVERLAY");
00202 #endif
00203 if (cap.capabilities & V4L2_CAP_TUNER)
00204 fprintf(stderr, " TUNER");
00205 if (cap.capabilities & V4L2_CAP_AUDIO)
00206 fprintf(stderr, " AUDIO");
00207 if (cap.capabilities & V4L2_CAP_RADIO)
00208 fprintf(stderr, " RADIO");
00209 if (cap.capabilities & V4L2_CAP_READWRITE)
00210 fprintf(stderr, " READWRITE");
00211 if (cap.capabilities & V4L2_CAP_ASYNCIO)
00212 fprintf(stderr, " ASYNCIO");
00213 if (cap.capabilities & V4L2_CAP_STREAMING)
00214 fprintf(stderr, " STREAMING");
00215 fprintf(stderr, "\n");
00216 fprintf(stderr, "cap.width = %d\n", width);
00217 fprintf(stderr, "cap.height = %d\n", height);
00218
00219
00220 frame = (IplImage *)malloc(sizeof(IplImage));
00221 cvInitImageHeader( frame,
00222 cvSize( width, height ),
00223 IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 );
00224
00225 frame->imageData = (char *)cvAlloc(frame->imageSize);
00226 }
00227
00228 void OptNM3xCamera::device_close()
00229 {
00230
00231 enum v4l2_buf_type type;
00232
00233 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00234
00235 if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
00236 perror("VIDIOC_STREAMOFF");
00237 exit(EXIT_FAILURE);
00238 }
00239
00240
00241 unsigned int i;
00242
00243 for (i = 0; i < n_buffers; ++i) {
00244 if (munmap(buffers[i].start, buffers[i].length) == -1) {
00245 perror("munmap");
00246 exit(EXIT_FAILURE);
00247 }
00248 }
00249
00250
00251 free(buffers);
00252
00253
00254 if (close(fd) == -1) {
00255 perror("close");
00256 exit(EXIT_FAILURE);
00257 }
00258 fd = -1;
00259 }
00260
00261 IplImage *OptNM3xCamera::read_frame ()
00262 {
00263
00264 struct v4l2_buffer buf;
00265
00266 CLEAR(buf);
00267
00268 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00269 buf.memory = V4L2_MEMORY_MMAP;
00270
00271 if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
00272 perror("VIDIOC_DQBUF");
00273 return NULL;
00274 }
00275 assert(buf.index < n_buffers);
00276
00277
00278 if (!mjpeg_to_rgb24(width, height,
00279 (unsigned char*)(buffers[buf.index].start),
00280 buffers[buf.index].length,
00281 (unsigned char*)frame->imageData)) {
00282 perror("mjpeg_to_rgb24");
00283 return NULL;
00284 }
00285
00286 if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
00287 perror("VIDIOC_QBUF");
00288 return NULL;
00289 }
00290
00291 return frame;
00292 }
00293
00294 OptNM3xCamera::OptNM3xCamera(int camera_index)
00295 {
00296 device_open(camera_index);
00297
00298 setMode(4);
00299 if ( strcmp(getFirmwareVersion().c_str(), "") == 0 ) {
00300 fprintf(stderr, "ERROR : try sudo -E ./bin/init_xu_register\n");
00301 exit(1);
00302 }
00303 fprintf(stderr, "firmwareVersion -> %s\n", getFirmwareVersion().c_str());
00304 fprintf(stderr, "serialId -> %s\n", getSerialID().c_str());
00305
00306 frame_omni = frame_wide = frame_middle = frame_narrow = NULL;
00307 }
00308
00309 OptNM3xCamera::~OptNM3xCamera()
00310 {
00311 device_close();
00312 }
00313
00314
00315 IplImage *OptNM3xCamera::queryFrame ()
00316 {
00317 if ( read_frame()==NULL ) {
00318 fprintf(stderr, "ERROR : read_frame returns NULL\n");
00319 return NULL;
00320 }
00321
00322
00323 int height = frame->height, width = frame->width;
00324 if ( ! ( frame_omni && (frame_omni->width == height/2 &&
00325 frame_omni->height == height/2 ) ) )
00326 frame_omni = cvCreateImage(cvSize(height/2, height/2), frame->depth, frame->nChannels);
00327 if ( ! ( frame_wide && (frame_wide->width == (width-height/2) &&
00328 frame_wide->height == height/2 ) ) )
00329 frame_wide = cvCreateImage(cvSize(width-height/2, height/2), frame->depth, frame->nChannels);
00330 if ( ! ( frame_middle && (frame_middle->width == width/2 &&
00331 frame_middle->height == height/2 ) ) )
00332 frame_middle = cvCreateImage(cvSize(width/2, height/2), frame->depth, frame->nChannels);
00333 if ( ! ( frame_narrow && (frame_narrow->width == width/2 &&
00334 frame_narrow->height == height/2 ) ) )
00335 frame_narrow = cvCreateImage(cvSize(width/2, height/2), frame->depth, frame->nChannels);
00336 return frame;
00337 }
00338
00339 void OptNM3xCamera::getOmniImage (IplImage *frame, CvMat &subframe) {
00340 int height = frame->height;
00341 cvGetSubRect(frame, &subframe, cvRect(0, 0, height/2, height/2));
00342 }
00343
00344 void OptNM3xCamera::getWideImage (IplImage *frame, CvMat &subframe) {
00345 int width = frame->width, height = frame->height;
00346 cvGetSubRect(frame, &subframe, cvRect(height/2, 0, width-height/2, height/2));
00347 }
00348
00349 void OptNM3xCamera::getMiddleImage (IplImage *frame, CvMat &subframe) {
00350 int width = frame->width, height = frame->height;
00351 cvGetSubRect(frame, &subframe, cvRect(0, height/2, width/2, height/2));
00352 }
00353
00354 void OptNM3xCamera::getNarrowImage (IplImage *frame, CvMat &subframe) {
00355 int width = frame->width, height = frame->height;
00356 cvGetSubRect(frame, &subframe, cvRect(width/2, height/2, width/2, height/2));
00357 }
00358
00359
00360 IplImage *OptNM3xCamera::queryOmniFrame () {
00361 int height = frame->height;
00362 cvSetImageROI(frame, cvRect(0, 0, height/2, height/2));
00363 cvCopy(frame, frame_omni);
00364 cvResetImageROI(frame);
00365 return frame_omni;
00366 }
00367
00368 IplImage *OptNM3xCamera::queryWideFrame () {
00369 int width = frame->width, height = frame->height;
00370 cvSetImageROI(frame, cvRect(height/2, 0, width-height/2, height/2));
00371 cvCopy(frame, frame_wide);
00372 cvResetImageROI(frame);
00373 return frame_wide;
00374 }
00375
00376 IplImage *OptNM3xCamera::queryMiddleFrame () {
00377 int width = frame->width, height = frame->height;
00378 cvSetImageROI(frame, cvRect(0, height/2, width/2, height/2));
00379 cvCopy(frame, frame_middle);
00380 cvResetImageROI(frame);
00381 return frame_middle;
00382 }
00383
00384 IplImage *OptNM3xCamera::queryNarrowFrame () {
00385 int width = frame->width, height = frame->height;
00386 cvSetImageROI(frame, cvRect(width/2, height/2, width/2, height/2));
00387 cvCopy(frame, frame_narrow);
00388 cvResetImageROI(frame);
00389 return frame_narrow;
00390 }
00391
00392
00393 bool OptNM3xCamera::setMode (int mode) {
00394 return (ioctl(fd, VIDIOC_S_INPUT, &mode)==0);
00395 }
00396
00397
00398 bool OptNM3xCamera::setAutoExposure(bool mode) {
00399 v4l2_set_ioctl(V4L2_CID_EXPOSURE_AUTO, mode?1:2);
00400 return true;
00401 }
00402 bool OptNM3xCamera::setExposure (int value) {
00403 v4l2_set_ioctl(V4L2_CID_EXPOSURE_ABSOLUTE, value);
00404 return true;
00405 }
00406 bool OptNM3xCamera::setIris(int value) {
00407 v4l2_set_ioctl(V4L2_CID_IRIS_ABSOLUTE, value);
00408 return true;
00409 }
00410 bool OptNM3xCamera::setBrightness(int value) {
00411 v4l2_set_ioctl(V4L2_CID_BRIGHTNESS, value);
00412 return true;
00413 }
00414 bool OptNM3xCamera::setSharpness(int value) {
00415 v4l2_set_ioctl(V4L2_CID_SHARPNESS, value);
00416 return true;
00417 }
00418 bool OptNM3xCamera::setWhitebalance(int value) {
00419 v4l2_set_ioctl(V4L2_CID_WHITE_BALANCE_TEMPERATURE, value);
00420 return true;
00421 }
00422 bool OptNM3xCamera::setAutoWhitebalance(bool mode) {
00423 v4l2_set_ioctl(V4L2_CID_AUTO_WHITE_BALANCE, mode?1:0);
00424 return true;
00425 }
00426 bool OptNM3xCamera::setPanAbsolute(double value) {
00427 return v4l2_set_ioctl(V4L2_CID_PAN_ABSOLUTE, (int)(value*3600));
00428 }
00429 bool OptNM3xCamera::setTiltAbsolute(double value) {
00430 return v4l2_set_ioctl(V4L2_CID_TILT_ABSOLUTE, (int)(value*3600));
00431 }
00432 bool OptNM3xCamera::setRollAbsolute(double value) {
00433 return v4l2_set_ioctl(V4L2_CID_ROLL_ABSOLUTE, (int)(value*1));
00434 }
00435 bool OptNM3xCamera::setZoomAbsolute(double value) {
00436 return v4l2_set_ioctl(V4L2_CID_ZOOM_ABSOLUTE, (int)value);
00437 }
00438 bool OptNM3xCamera::setPanAbsolute(int value) {
00439 return v4l2_set_ioctl(V4L2_CID_PAN_ABSOLUTE, value);
00440 }
00441 bool OptNM3xCamera::setTiltAbsolute(int value) {
00442 return v4l2_set_ioctl(V4L2_CID_TILT_ABSOLUTE, value);
00443 }
00444 bool OptNM3xCamera::setRollAbsolute(int value) {
00445 return v4l2_set_ioctl(V4L2_CID_ROLL_ABSOLUTE, value);
00446 }
00447 bool OptNM3xCamera::setZoomAbsolute(int value) {
00448 return v4l2_set_ioctl(V4L2_CID_ZOOM_ABSOLUTE, value);
00449 }
00450
00451 bool OptNM3xCamera::v4l2_set_ioctl(int selector, int value) {
00452 v4l2_queryctrl q;
00453 q.id = selector;
00454 if ( ioctl(fd, VIDIOC_QUERYCTRL, &q) < 0 )
00455 {
00456 perror("unable to query control");
00457 return false;
00458 }
00459
00460 v4l2_control c;
00461 c.id = selector;
00462 c.value = value;
00463 fprintf(stderr, "VIDIOC_S_CTRL: sel = 0x%08x, data =0x%08x\n",
00464 selector, value);
00465 if (ioctl(fd, VIDIOC_S_CTRL, &c) < 0)
00466 {
00467 perror("unable to set control");
00468 return false;
00469 }
00470 return true;
00471 }
00472
00473 int OptNM3xCamera::v4l2_get_ioctl(int selector) {
00474 v4l2_control c;
00475 c.id = selector;
00476 fprintf(stderr, "VIDIOC_S_CTRL: sel = 0x%02x\n", selector);
00477 if (ioctl(fd, VIDIOC_G_CTRL, &c) == 0)
00478 {
00479 perror("unable to get control");
00480 return -1;
00481 }
00482 return c.value;
00483 }
00484
00485
00486 std::string OptNM3xCamera::getFirmwareVersion() {
00487 #ifdef NON_STD_UVC
00488 std::string str(255,0);
00489 #else
00490 std::string str(32,0);
00491 #endif
00492 getXuValue(XU_FIRMWARE_VERSION_CONTROL, str.c_str());
00493 return str.substr(0,str.find_first_of('\0'));
00494 }
00495 bool OptNM3xCamera::setFlipScreen(char value) {
00496 return setXuValue(XU_FLIP_SCREEN_CONTROL,value);
00497 }
00498 bool OptNM3xCamera::setSmallHemisphere(char value) {
00499 return setXuValue(XU_SMALL_HEMISPHERE_CONTROL,value);
00500 }
00501 bool OptNM3xCamera::setMedianFilter(bool mode) {
00502 return setXuValue(XU_MEDIAN_FILTER_CONTROL, (char)(mode?1:0));
00503 }
00504 bool OptNM3xCamera::setJpegQuality(char value) {
00505 return setXuValue(XU_JPEG_QUALITY_CONTROL,value);
00506 }
00507 std::string OptNM3xCamera::getSerialID() {
00508 std::string str(16,0);
00509 getXuValue(XU_SERIAL_ID_CONTROL, str.c_str());
00510 return str.substr(0,str.find_first_of('\0'));
00511 }
00512 bool OptNM3xCamera::setInfoDisplay(bool mode) {
00513 return setXuValue(XU_INFO_DISPLAY_CONTROL, mode?1:0);
00514 }
00515 bool OptNM3xCamera::setCaptureFPS(short value) {
00516 return setXuValue(XU_CAPTURE_FPS_CONTROL,value);
00517 }
00518 short OptNM3xCamera::getActualFPS() {
00519 short value;
00520 getXuValue(XU_CAPTURE_FPS_CONTROL, &value);
00521 return value;
00522 }
00523 bool OptNM3xCamera::setLensType(char value) {
00524 return setXuValue(XU_LENS_TYPE_CONTROL,value);
00525 }
00526 bool OptNM3xCamera::setPanAbsolute(int no, int value) {
00527 return setXuValue(XU_PAN_ABSOLUTE_CONTROL, no, value);
00528 }
00529 bool OptNM3xCamera::setTiltAbsolute(int no, int value) {
00530 return setXuValue(XU_TILT_ABSOLUTE_CONTROL, no, value);
00531 }
00532 bool OptNM3xCamera::setRollAbsolute(int no, int value) {
00533 return setXuValue(XU_ROLL_ABSOLUTE_CONTROL, no, value);
00534 }
00535 bool OptNM3xCamera::setZoomAbsolute(int no, int value) {
00536 return setXuValue(XU_ZOOM_ABSOLUTE_CONTROL, no, value);
00537 }
00538 bool OptNM3xCamera::setLocationAbsolute(int no, int pan, int tilt, int roll, int zoom) {
00539 return setXuValue(XU_LOCATION_ABSOLUTE_CONTROL, no, pan, tilt, roll, zoom);
00540 }
00541
00542 bool OptNM3xCamera::getXuValue(int selector, const char *str) {
00543 return xu_ioctl(selector, UVC_GET_CUR, (void *)str);
00544 }
00545 bool OptNM3xCamera::getXuValue(int selector, short *value) {
00546 return xu_ioctl(selector, UVC_GET_CUR, (void *)value);
00547 }
00548 bool OptNM3xCamera::setXuValue(int selector, char value) {
00549 return xu_ioctl(selector, UVC_SET_CUR, (void *)&value);
00550 }
00551 bool OptNM3xCamera::setXuValue(int selector, short v1, short v2) {
00552 struct { short v1, v2;} value;
00553 value.v1 = v1;
00554 value.v2 = v2;
00555 return xu_ioctl(selector, UVC_SET_CUR, (void *)&value);
00556 }
00557 bool OptNM3xCamera::setXuValue(int selector, short v1, short v2, short v3, short v4, short v5) {
00558 struct { short v1, v2, v3, v4, v5;} value;
00559 value.v1 = v1; value.v2 = v2; value.v3 = v3; value.v4 = v4; value.v5 = v5;
00560 return xu_ioctl(selector, UVC_SET_CUR, (void *)&value);
00561 }
00562
00563 bool OptNM3xCamera::xu_ioctl(int selector, int ctrl, void* value) {
00564 for (int i = 0; i < uvc_xu_tbl_cnt; i++) {
00565 if (xu_control_tbl[i].selector == selector) {
00566 struct uvc_xu_control_query xctrl;
00567 xctrl.unit = 0x60;
00568 xctrl.selector = xu_control_tbl[i].selector;
00569 xctrl.size = xu_control_tbl[i].size;
00570 xctrl.data = (__u8*)value;
00571 xctrl.query = ctrl;
00572 fprintf(stderr, "%s: name = %s, sel = 0x%02x, size = %d, data =",
00573 (ctrl == UVC_SET_CUR) ? "UVC_SET_CUR" : "UVC_GET_CUR",
00574 xu_control_tbl[i].name,
00575 xctrl.selector,
00576 xctrl.size);
00577 if (ioctl(fd, UVCIOC_CTRL_QUERY, &xctrl) != 0) {
00578 xctrl.data[0] = 0;
00579 fprintf(stderr, "\nioctl error %s\n", strerror(errno));
00580 return false;
00581 } else {
00582 for (int j = 0; j < xctrl.size; j++)
00583 fprintf(stderr, " 0x%02x", *(xctrl.data + j));
00584 fprintf(stderr, "\n");
00585 if (xu_control_tbl[i].size == 255) xctrl.data[xctrl.size] = 0;
00586 return true;
00587 }
00588 }
00589 }
00590 return false;
00591 }