1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /*! 18 * \file exynos_v4l2.c 19 * \brief source file for libv4l2 20 * \author Jinsung Yang (jsgood.yang (at) samsung.com) 21 * \author Sangwoo Park (sw5771.park (at) samsung.com) 22 * \date 2012/01/17 23 * 24 * <b>Revision History: </b> 25 * - 2012/01/17: Jinsung Yang (jsgood.yang (at) samsung.com) \n 26 * Initial version 27 * 28 */ 29 30 #include <stdio.h> 31 #include <errno.h> 32 #include <stdarg.h> 33 #include <fcntl.h> 34 #include <string.h> 35 #include <sys/types.h> 36 #include <sys/ioctl.h> 37 #include <sys/stat.h> 38 39 #include "exynos_v4l2.h" 40 41 //#define LOG_NDEBUG 0 42 #define LOG_TAG "libexynosv4l2" 43 #include <utils/Log.h> 44 #include "Exynos_log.h" 45 46 #define VIDEODEV_MINOR_MAX 63 47 48 //#define EXYNOS_V4L2_TRACE 0 49 #ifdef EXYNOS_V4L2_TRACE 50 #define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) 51 #define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) 52 #else 53 #define Exynos_v4l2_In() ((void *)0) 54 #define Exynos_v4l2_Out() ((void *)0) 55 #endif 56 57 static bool __v4l2_check_buf_type(enum v4l2_buf_type type) 58 { 59 bool supported; 60 61 switch (type) { 62 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 63 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 64 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 65 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 66 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 67 supported = true; 68 break; 69 70 default: 71 supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false; 72 break; 73 } 74 75 return supported; 76 } 77 78 static int __v4l2_open(const char *filename, int oflag, va_list ap) 79 { 80 mode_t mode = 0; 81 int fd; 82 83 if (oflag & O_CREAT) 84 mode = va_arg(ap, int); 85 86 fd = open(filename, oflag, mode); 87 88 return fd; 89 } 90 91 int exynos_v4l2_open(const char *filename, int oflag, ...) 92 { 93 va_list ap; 94 int fd; 95 96 Exynos_v4l2_In(); 97 98 va_start(ap, oflag); 99 fd = __v4l2_open(filename, oflag, ap); 100 va_end(ap); 101 102 Exynos_v4l2_Out(); 103 104 return fd; 105 } 106 107 int exynos_v4l2_open_devname(const char *devname, int oflag, ...) 108 { 109 bool found = false; 110 int fd = -1; 111 struct stat s; 112 va_list ap; 113 FILE *stream_fd; 114 char filename[64], name[64]; 115 int minor, size, i = 0; 116 117 Exynos_v4l2_In(); 118 119 do { 120 if (i > VIDEODEV_MINOR_MAX) 121 break; 122 123 /* video device node */ 124 sprintf(filename, "/dev/video%d", i++); 125 126 /* if the node is video device */ 127 if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) && 128 ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) { 129 minor = (int)((unsigned short)(s.st_rdev & 0x3f)); 130 ALOGD("try node: %s, minor: %d", filename, minor); 131 /* open sysfs entry */ 132 sprintf(filename, "/sys/class/video4linux/video%d/name", minor); 133 stream_fd = fopen(filename, "r"); 134 if (stream_fd == NULL) { 135 ALOGE("failed to open sysfs entry for videodev"); 136 continue; /* try next */ 137 } 138 139 /* read sysfs entry for device name */ 140 size = (int)fgets(name, sizeof(name), stream_fd); 141 fclose(stream_fd); 142 143 /* check read size */ 144 if (size == 0) { 145 ALOGE("failed to read sysfs entry for videodev"); 146 } else { 147 /* matched */ 148 if (strncmp(name, devname, strlen(devname)) == 0) { 149 ALOGI("node found for device %s: /dev/video%d", devname, minor); 150 found = true; 151 } 152 } 153 } 154 } while (found == false); 155 156 if (found) { 157 sprintf(filename, "/dev/video%d", minor); 158 va_start(ap, oflag); 159 fd = __v4l2_open(filename, oflag, ap); 160 va_end(ap); 161 162 if (fd > 0) 163 ALOGI("open video device %s", filename); 164 else 165 ALOGE("failed to open video device %s", filename); 166 } else { 167 ALOGE("no video device found"); 168 } 169 170 Exynos_v4l2_Out(); 171 172 return fd; 173 } 174 175 int exynos_v4l2_close(int fd) 176 { 177 int ret = -1; 178 179 Exynos_v4l2_In(); 180 181 if (fd < 0) 182 ALOGE("%s: invalid fd: %d", __func__, fd); 183 else 184 ret = close(fd); 185 186 Exynos_v4l2_Out(); 187 188 return ret; 189 } 190 191 bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf) 192 { 193 int ret = -1; 194 struct v4l2_input input; 195 196 Exynos_v4l2_In(); 197 198 if (fd < 0) { 199 ALOGE("%s: invalid fd: %d", __func__, fd); 200 return NULL; 201 } 202 203 input.index = index; 204 ret = ioctl(fd, VIDIOC_ENUMINPUT, &input); 205 if (ret) { 206 ALOGE("%s: no matching index founds", __func__); 207 return false; 208 } 209 210 ALOGI("Name of input channel[%d] is %s", input.index, input.name); 211 212 strcpy(input_name_buf, (const char *)input.name); 213 214 Exynos_v4l2_Out(); 215 216 return true; 217 } 218 219 int exynos_v4l2_s_input(int fd, int index) 220 { 221 int ret = -1; 222 struct v4l2_input input; 223 224 Exynos_v4l2_In(); 225 226 if (fd < 0) { 227 ALOGE("%s: invalid fd: %d", __func__, fd); 228 return ret; 229 } 230 231 input.index = index; 232 233 ret = ioctl(fd, VIDIOC_S_INPUT, &input); 234 if (ret){ 235 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno)); 236 return ret; 237 } 238 239 Exynos_v4l2_Out(); 240 241 return ret; 242 } 243 244 bool exynos_v4l2_querycap(int fd, unsigned int need_caps) 245 { 246 struct v4l2_capability cap; 247 int ret; 248 249 Exynos_v4l2_In(); 250 251 if (fd < 0) { 252 ALOGE("%s: invalid fd: %d", __func__, fd); 253 return false; 254 } 255 256 if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) && 257 !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) && 258 !(need_caps & V4L2_CAP_VIDEO_OUTPUT) && 259 !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) && 260 !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) { 261 ALOGE("%s: unsupported capabilities", __func__); 262 return false; 263 } 264 265 memset(&cap, 0, sizeof(cap)); 266 267 ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); 268 if (ret) { 269 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno)); 270 return false; 271 } 272 273 if ((need_caps & cap.capabilities) != need_caps) { 274 ALOGE("%s: unsupported capabilities", __func__); 275 return false; 276 } 277 278 Exynos_v4l2_Out(); 279 280 return true; 281 } 282 283 bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt) 284 { 285 struct v4l2_fmtdesc fmtdesc; 286 int found = 0; 287 288 Exynos_v4l2_In(); 289 290 fmtdesc.type = type; 291 fmtdesc.index = 0; 292 293 while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { 294 if (fmtdesc.pixelformat == fmt) { 295 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description); 296 found = 1; 297 break; 298 } 299 300 fmtdesc.index++; 301 } 302 303 if (!found) { 304 ALOGE("%s: unsupported pixel format", __func__); 305 return false; 306 } 307 308 Exynos_v4l2_Out(); 309 310 return true; 311 } 312 313 int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt) 314 { 315 int ret = -1; 316 317 Exynos_v4l2_In(); 318 319 if (fd < 0) { 320 ALOGE("%s: invalid fd: %d", __func__, fd); 321 return ret; 322 } 323 324 if (!fmt) { 325 ALOGE("%s: fmt is NULL", __func__); 326 return ret; 327 } 328 329 if (__v4l2_check_buf_type(fmt->type) == false) { 330 ALOGE("%s: unsupported buffer type", __func__); 331 return ret; 332 } 333 334 ret = ioctl(fd, VIDIOC_G_FMT, fmt); 335 if (ret) { 336 ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno)); 337 return ret; 338 } 339 340 Exynos_v4l2_Out(); 341 342 return ret; 343 } 344 345 static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt) 346 { 347 int ret = -1; 348 349 Exynos_v4l2_In(); 350 351 if (fd < 0) { 352 ALOGE("%s: invalid fd: %d", __func__, fd); 353 return ret; 354 } 355 356 if (!fmt) { 357 ALOGE("%s: fmt is NULL", __func__); 358 return ret; 359 } 360 361 if (__v4l2_check_buf_type(fmt->type) == false) { 362 ALOGE("%s: unsupported buffer type", __func__); 363 return ret; 364 } else { 365 ret = ioctl(fd, request, fmt); 366 if (ret) { 367 if (request == VIDIOC_TRY_FMT) 368 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno)); 369 else 370 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno)); 371 372 return ret; 373 } 374 } 375 376 Exynos_v4l2_Out(); 377 378 return ret; 379 } 380 381 int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt) 382 { 383 return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt); 384 } 385 386 int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt) 387 { 388 return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt); 389 } 390 391 int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req) 392 { 393 int ret = -1; 394 unsigned int count; 395 396 Exynos_v4l2_In(); 397 398 if (fd < 0) { 399 ALOGE("%s: invalid fd: %d", __func__, fd); 400 return ret; 401 } 402 403 if (!req) { 404 ALOGE("%s: req is NULL", __func__); 405 return ret; 406 } 407 408 if ((req->memory != V4L2_MEMORY_MMAP) && 409 (req->memory != V4L2_MEMORY_USERPTR) && 410 (req->memory != V4L2_MEMORY_DMABUF)) { 411 ALOGE("%s: unsupported memory type", __func__); 412 return ret; 413 } 414 415 if (__v4l2_check_buf_type(req->type) == false) { 416 ALOGE("%s: unsupported buffer type", __func__); 417 return ret; 418 } 419 420 count = req->count; 421 422 ret = ioctl(fd, VIDIOC_REQBUFS, req); 423 if (ret) { 424 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno)); 425 return ret; 426 } 427 428 if (count != req->count) { 429 ALOGW("number of buffers had been changed: %d => %d", count, req->count); 430 } 431 432 Exynos_v4l2_Out(); 433 434 return ret; 435 } 436 437 int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf) 438 { 439 int ret = -1; 440 441 Exynos_v4l2_In(); 442 443 if (fd < 0) { 444 ALOGE("%s: invalid fd: %d", __func__, fd); 445 return ret; 446 } 447 448 if (!buf) { 449 ALOGE("%s: buf is NULL", __func__); 450 return ret; 451 } 452 453 if ((buf->memory != V4L2_MEMORY_MMAP) && 454 (buf->memory != V4L2_MEMORY_DMABUF)) { 455 ALOGE("%s: unsupported memory type", __func__); 456 return ret; 457 } 458 459 if (__v4l2_check_buf_type(buf->type) == false) { 460 ALOGE("%s: unsupported buffer type", __func__); 461 return ret; 462 } 463 464 ret = ioctl(fd, VIDIOC_QUERYBUF, buf); 465 if (ret) { 466 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno)); 467 return ret; 468 } 469 470 Exynos_v4l2_Out(); 471 472 return ret; 473 } 474 475 int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf) 476 { 477 int ret = -1; 478 479 Exynos_v4l2_In(); 480 481 if (fd < 0) { 482 ALOGE("%s: invalid fd: %d", __func__, fd); 483 return ret; 484 } 485 486 if (!buf) { 487 ALOGE("%s: buf is NULL", __func__); 488 return ret; 489 } 490 491 if ((buf->memory != V4L2_MEMORY_MMAP) && 492 (buf->memory != V4L2_MEMORY_USERPTR) && 493 (buf->memory != V4L2_MEMORY_DMABUF)) { 494 ALOGE("%s: unsupported memory type", __func__); 495 return ret; 496 } 497 498 if (__v4l2_check_buf_type(buf->type) == false) { 499 ALOGE("%s: unsupported buffer type", __func__); 500 return ret; 501 } 502 503 ret = ioctl(fd, VIDIOC_QBUF, buf); 504 if (ret) { 505 ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno, strerror(errno)); 506 return ret; 507 } 508 509 Exynos_v4l2_Out(); 510 511 return ret; 512 } 513 514 int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf) 515 { 516 int ret = -1; 517 518 Exynos_v4l2_In(); 519 520 if (fd < 0) { 521 ALOGE("%s: invalid fd: %d", __func__, fd); 522 return ret; 523 } 524 525 if (!buf) { 526 ALOGE("%s: buf is NULL", __func__); 527 return ret; 528 } 529 530 if ((buf->memory != V4L2_MEMORY_MMAP) && 531 (buf->memory != V4L2_MEMORY_USERPTR) && 532 (buf->memory != V4L2_MEMORY_DMABUF)) { 533 ALOGE("%s: unsupported memory type", __func__); 534 return ret; 535 } 536 537 if (__v4l2_check_buf_type(buf->type) == false) { 538 ALOGE("%s: unsupported buffer type", __func__); 539 return ret; 540 } 541 542 ret = ioctl(fd, VIDIOC_DQBUF, buf); 543 if (ret) { 544 ALOGE("failed to ioctl: VIDIOC_DQBUF (%d - %s)", errno, strerror(errno)); 545 return ret; 546 } 547 548 Exynos_v4l2_Out(); 549 550 return ret; 551 } 552 553 int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type) 554 { 555 int ret = -1; 556 557 Exynos_v4l2_In(); 558 559 if (fd < 0) { 560 ALOGE("%s: invalid fd: %d", __func__, fd); 561 return ret; 562 } 563 564 if (__v4l2_check_buf_type(type) == false) { 565 ALOGE("%s: unsupported buffer type", __func__); 566 return ret; 567 } 568 569 ret = ioctl(fd, VIDIOC_STREAMON, &type); 570 if (ret) { 571 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno)); 572 return ret; 573 } 574 575 Exynos_v4l2_Out(); 576 577 return ret; 578 } 579 580 int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type) 581 { 582 int ret = -1; 583 584 Exynos_v4l2_In(); 585 586 if (fd < 0) { 587 ALOGE("%s: invalid fd: %d", __func__, fd); 588 return ret; 589 } 590 591 if (__v4l2_check_buf_type(type) == false) { 592 ALOGE("%s: unsupported buffer type", __func__); 593 return ret; 594 } 595 596 ret = ioctl(fd, VIDIOC_STREAMOFF, &type); 597 if (ret) { 598 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno)); 599 return ret; 600 } 601 602 Exynos_v4l2_Out(); 603 604 return ret; 605 } 606 607 int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop) 608 { 609 int ret = -1; 610 611 Exynos_v4l2_In(); 612 613 if (fd < 0) { 614 ALOGE("%s: invalid fd: %d", __func__, fd); 615 return ret; 616 } 617 618 if (!crop) { 619 ALOGE("%s: crop is NULL", __func__); 620 return ret; 621 } 622 623 if (__v4l2_check_buf_type(crop->type) == false) { 624 ALOGE("%s: unsupported buffer type", __func__); 625 return ret; 626 } 627 628 ret = ioctl(fd, VIDIOC_CROPCAP, crop); 629 if (ret) { 630 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno)); 631 return ret; 632 } 633 634 Exynos_v4l2_Out(); 635 636 return ret; 637 } 638 639 int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop) 640 { 641 int ret = -1; 642 643 Exynos_v4l2_In(); 644 645 if (fd < 0) { 646 ALOGE("%s: invalid fd: %d", __func__, fd); 647 return ret; 648 } 649 650 if (!crop) { 651 ALOGE("%s: crop is NULL", __func__); 652 return ret; 653 } 654 655 if (__v4l2_check_buf_type(crop->type) == false) { 656 ALOGE("%s: unsupported buffer type", __func__); 657 return ret; 658 } 659 660 ret = ioctl(fd, VIDIOC_G_CROP, crop); 661 if (ret) { 662 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno)); 663 return ret; 664 } 665 666 Exynos_v4l2_Out(); 667 668 return ret; 669 } 670 671 int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop) 672 { 673 int ret = -1; 674 675 Exynos_v4l2_In(); 676 677 if (fd < 0) { 678 ALOGE("%s: invalid fd: %d", __func__, fd); 679 return ret; 680 } 681 682 if (!crop) { 683 ALOGE("%s: crop is NULL", __func__); 684 return ret; 685 } 686 687 if (__v4l2_check_buf_type(crop->type) == false) { 688 ALOGE("%s: unsupported buffer type", __func__); 689 return ret; 690 } 691 692 ret = ioctl(fd, VIDIOC_S_CROP, crop); 693 if (ret) { 694 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno)); 695 return ret; 696 } 697 698 Exynos_v4l2_Out(); 699 700 return ret; 701 } 702 703 int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value) 704 { 705 int ret = -1; 706 struct v4l2_control ctrl; 707 708 Exynos_v4l2_In(); 709 710 ctrl.id = id; 711 712 if (fd < 0) { 713 ALOGE("%s: invalid fd: %d", __func__, fd); 714 return ret; 715 } 716 717 ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); 718 if (ret) { 719 ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d - %s)", errno, strerror(errno)); 720 return ret; 721 } 722 723 *value = ctrl.value; 724 725 Exynos_v4l2_Out(); 726 727 return ret; 728 } 729 730 int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value) 731 { 732 int ret = -1; 733 struct v4l2_control ctrl; 734 735 Exynos_v4l2_In(); 736 737 ctrl.id = id; 738 ctrl.value = value; 739 740 if (fd < 0) { 741 ALOGE("%s: invalid fd: %d", __func__, fd); 742 return ret; 743 } 744 745 ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); 746 if (ret) { 747 ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", errno); 748 return ret; 749 } 750 751 Exynos_v4l2_Out(); 752 753 return ret; 754 } 755 756 int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm) 757 { 758 int ret = -1; 759 760 Exynos_v4l2_In(); 761 762 if (fd < 0) { 763 ALOGE("%s: invalid fd: %d", __func__, fd); 764 return ret; 765 } 766 767 if (__v4l2_check_buf_type(streamparm->type) == false) { 768 ALOGE("%s: unsupported buffer type", __func__); 769 return ret; 770 } 771 772 ret = ioctl(fd, VIDIOC_G_PARM, streamparm); 773 if (ret) { 774 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno)); 775 return ret; 776 } 777 778 Exynos_v4l2_Out(); 779 780 return ret; 781 } 782 783 int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm) 784 { 785 int ret = -1; 786 787 Exynos_v4l2_In(); 788 789 if (fd < 0) { 790 ALOGE("%s: invalid fd: %d", __func__, fd); 791 return ret; 792 } 793 794 if (__v4l2_check_buf_type(streamparm->type) == false) { 795 ALOGE("%s: unsupported buffer type", __func__); 796 return ret; 797 } 798 799 ret = ioctl(fd, VIDIOC_S_PARM, streamparm); 800 if (ret) { 801 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno)); 802 return ret; 803 } 804 805 Exynos_v4l2_Out(); 806 807 return ret; 808 } 809 810 int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) 811 { 812 int ret = -1; 813 814 Exynos_v4l2_In(); 815 816 if (fd < 0) { 817 ALOGE("%s: invalid fd: %d", __func__, fd); 818 return ret; 819 } 820 821 if (ctrl == NULL) { 822 ALOGE("%s: ctrl is NULL", __func__); 823 return ret; 824 } 825 826 ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl); 827 if (ret) 828 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno)); 829 830 Exynos_v4l2_Out(); 831 832 return ret; 833 } 834 835 int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) 836 { 837 int ret = -1; 838 839 Exynos_v4l2_In(); 840 841 if (fd < 0) { 842 ALOGE("%s: invalid fd: %d", __func__, fd); 843 return ret; 844 } 845 846 if (ctrl == NULL) { 847 ALOGE("%s: ctrl is NULL", __func__); 848 return ret; 849 } 850 851 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl); 852 if (ret) 853 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno)); 854 855 Exynos_v4l2_Out(); 856 857 return ret; 858 } 859