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