1/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /*#error uncomment this for compiler test!*/ 29//#define ALOG_NDEBUG 0 30#define ALOG_NIDEBUG 0 31#define LOG_TAG "QualcommUsbCamera" 32 33#include <utils/Log.h> 34#include <utils/threads.h> 35#include <fcntl.h> 36#include <sys/mman.h> 37#include <sys/stat.h> 38#include <unistd.h> 39#include <sys/prctl.h> 40#include <sys/resource.h> 41#include <pthread.h> 42#include <linux/uvcvideo.h> 43 44#include "QCameraHAL.h" 45#include "QualcommUsbCamera.h" 46#include "QCameraUsbPriv.h" 47#include "QCameraMjpegDecode.h" 48#include "QCameraUsbParm.h" 49#include <gralloc_priv.h> 50#include <genlock.h> 51 52extern "C" { 53#include <sys/time.h> 54} 55 56camera_device_ops_t usbcam_camera_ops = { 57 set_preview_window: android::usbcam_set_preview_window, 58 set_callbacks: android::usbcam_set_CallBacks, 59 enable_msg_type: android::usbcam_enable_msg_type, 60 disable_msg_type: android::usbcam_disable_msg_type, 61 msg_type_enabled: android::usbcam_msg_type_enabled, 62 63 start_preview: android::usbcam_start_preview, 64 stop_preview: android::usbcam_stop_preview, 65 preview_enabled: android::usbcam_preview_enabled, 66 store_meta_data_in_buffers: android::usbcam_store_meta_data_in_buffers, 67 68 start_recording: android::usbcam_start_recording, 69 stop_recording: android::usbcam_stop_recording, 70 recording_enabled: android::usbcam_recording_enabled, 71 release_recording_frame: android::usbcam_release_recording_frame, 72 73 auto_focus: android::usbcam_auto_focus, 74 cancel_auto_focus: android::usbcam_cancel_auto_focus, 75 76 take_picture: android::usbcam_take_picture, 77 cancel_picture: android::usbcam_cancel_picture, 78 79 set_parameters: android::usbcam_set_parameters, 80 get_parameters: android::usbcam_get_parameters, 81 put_parameters: android::usbcam_put_parameters, 82 send_command: android::usbcam_send_command, 83 84 release: android::usbcam_release, 85 dump: android::usbcam_dump, 86}; 87 88#define CAPTURE 1 89#define DISPLAY 1 90#define CALL_BACK 1 91#define MEMSET 0 92#define FREAD_JPEG_PICTURE 0 93#define JPEG_ON_USB_CAMERA 1 94#define FILE_DUMP_CAMERA 0 95#define FILE_DUMP_B4_DISP 0 96 97namespace android { 98 99static int initUsbCamera( camera_hardware_t *camHal, 100 int width, int height, 101 int pixelFormat); 102static int startUsbCamCapture( camera_hardware_t *camHal); 103static int stopUsbCamCapture( camera_hardware_t *camHal); 104static int initV4L2mmap( camera_hardware_t *camHal); 105static int unInitV4L2mmap( camera_hardware_t *camHal); 106static int launch_preview_thread( camera_hardware_t *camHal); 107static int launchTakePictureThread( camera_hardware_t *camHal); 108static int initDisplayBuffers( camera_hardware_t *camHal); 109static int deInitDisplayBuffers( camera_hardware_t *camHal); 110static int stopPreviewInternal( camera_hardware_t *camHal); 111static int get_buf_from_cam( camera_hardware_t *camHal); 112static int put_buf_to_cam( camera_hardware_t *camHal); 113static int prvwThreadTakePictureInternal(camera_hardware_t *camHal); 114static int get_buf_from_display( camera_hardware_t *camHal, int *buffer_id); 115static int put_buf_to_display( camera_hardware_t *camHal, int buffer_id); 116static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id); 117static void * previewloop(void *); 118static void * takePictureThread(void *); 119static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht); 120static int get_uvc_device(char *devname); 121static int getPreviewCaptureFmt(camera_hardware_t *camHal); 122static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type); 123static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info); 124static int ioctlLoop(int fd, int ioctlCmd, void *args); 125static int readFromFile(char* fileName, char* buffer, int bufferSize); 126static int fileDump(const char* fileName, char* data, int length, int* frm_cnt); 127static int encodeJpeg( camera_hardware_t *camHal); 128void jpegEncodeCb (jpeg_job_status_t status, 129 uint8_t thumbnailDroppedFlag, 130 uint32_t client_hdl, 131 uint32_t jobId, 132 uint8_t* out_data, 133 uint32_t data_size, 134 void *userData); 135 136/* HAL function implementation goes here*/ 137 138/** 139 * The functions need to be provided by the camera HAL. 140 * 141 * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo() 142 * and openCameraHardware() is 0 to N-1. 143 */ 144 145extern "C" int usbcam_get_number_of_cameras() 146{ 147 /* TBR: This is hardcoded currently to 1 USB camera */ 148 int numCameras = 1; 149 ALOGI("%s: E", __func__); 150 ALOGI("%s: X", __func__); 151 152 return numCameras; 153} 154 155extern "C" int usbcam_get_camera_info(int camera_id, struct camera_info *info) 156{ 157 int rc = -1; 158 ALOGI("%s: E", __func__); 159 160 /* TBR: This info is hardcoded currently irrespective of camera_id */ 161 if(info) { 162 struct CameraInfo camInfo; 163 memset(&camInfo, -1, sizeof (struct CameraInfo)); 164 165 info->facing = CAMERA_FACING_FRONT;//CAMERA_FACING_BACK; 166 info->orientation = 0; 167 rc = 0; 168 } 169 ALOGI("%s: X", __func__); 170 return rc; 171} 172 173/* HAL should return NULL handle if it fails to open camera hardware. */ 174extern "C" int usbcam_camera_device_open( 175 const struct hw_module_t* module, const char* id, 176 struct hw_device_t** hw_device) 177{ 178 int rc = -1; 179 camera_device *device = NULL; 180 camera_hardware_t *camHal; 181 char *dev_name; 182 183 ALOGI("%s: E", __func__); 184 185 /* initialize return handle value to NULL */ 186 *hw_device = NULL; 187 188 camHal = new camera_hardware_t(); 189 if(!camHal) { 190 191 ALOGE("%s: end in no mem", __func__); 192 return -1; 193 } 194 195 rc = usbCamInitDefaultParameters(camHal); 196 if(0 != rc) 197 { 198 ALOGE("%s: usbCamInitDefaultParameters error", __func__); 199 return rc; 200 } 201#if CAPTURE 202 203 dev_name = camHal->dev_name; 204 205 rc = get_uvc_device(dev_name); 206 if(rc || *dev_name == '\0'){ 207 ALOGE("%s: No UVC node found \n", __func__); 208 return -1; 209 } 210 211 camHal->fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); 212 213 if (camHal->fd < 0) { 214 ALOGE("%s: Cannot open '%s'", __func__, dev_name); 215 free(camHal); 216 rc = -1; 217 }else{ 218 rc = 0; 219 } 220 221#else /* CAPTURE */ 222 rc = 0; 223#endif /* CAPTURE */ 224 225 device = &camHal->hw_dev; 226 device->common.close = usbcam_close_camera_device; 227 device->ops = &usbcam_camera_ops; 228 device->priv = (void *)camHal; 229 *hw_device = &(device->common); 230 231 ALOGD("%s: camHal: %p", __func__, camHal); 232 ALOGI("%s: X %d", __func__, rc); 233 234 return rc; 235} 236 237extern "C" int usbcam_close_camera_device( hw_device_t *hw_dev) 238{ 239 ALOGI("%s: device =%p E", __func__, hw_dev); 240 int rc = -1; 241 camera_device_t *device = (camera_device_t *)hw_dev; 242 243 if(device) { 244 camera_hardware_t *camHal = (camera_hardware_t *)device->priv; 245 if(camHal) { 246 rc = close(camHal->fd); 247 if(rc < 0) { 248 ALOGE("%s: close failed ", __func__); 249 } 250 camHal->fd = 0; 251 delete camHal; 252 }else{ 253 ALOGE("%s: camHal is NULL pointer ", __func__); 254 } 255 } 256 ALOGI("%s: X device =%p, rc = %d", __func__, hw_dev, rc); 257 return rc; 258} 259 260int usbcam_set_preview_window(struct camera_device * device, 261 struct preview_stream_ops *window) 262{ 263 ALOGI("%s: E", __func__); 264 int rc = 0; 265 camera_hardware_t *camHal; 266 267 VALIDATE_DEVICE_HDL(camHal, device, -1); 268 Mutex::Autolock autoLock(camHal->lock); 269 270 /* if window is already set, then de-init previous buffers */ 271 if(camHal->window){ 272 rc = deInitDisplayBuffers(camHal); 273 if(rc < 0) { 274 ALOGE("%s: deInitDisplayBuffers returned error", __func__); 275 } 276 } 277 camHal->window = window; 278 279 if(camHal->window){ 280 rc = initDisplayBuffers(camHal); 281 if(rc < 0) { 282 ALOGE("%s: initDisplayBuffers returned error", __func__); 283 } 284 } 285 ALOGI("%s: X. rc = %d", __func__, rc); 286 return rc; 287} 288 289void usbcam_set_CallBacks(struct camera_device * device, 290 camera_notify_callback notify_cb, 291 camera_data_callback data_cb, 292 camera_data_timestamp_callback data_cb_timestamp, 293 camera_request_memory get_memory, 294 void *user) 295{ 296 ALOGI("%s: E", __func__); 297 camera_hardware_t *camHal; 298 299 if(device && device->priv){ 300 camHal = (camera_hardware_t *)device->priv; 301 }else{ 302 ALOGE("%s: Null device or device->priv", __func__); 303 return; 304 } 305 306 Mutex::Autolock autoLock(camHal->lock); 307 308 camHal->notify_cb = notify_cb; 309 camHal->data_cb = data_cb; 310 camHal->data_cb_timestamp = data_cb_timestamp; 311 camHal->get_memory = get_memory; 312 camHal->cb_ctxt = user; 313 314 ALOGI("%s: X", __func__); 315} 316 317void usbcam_enable_msg_type(struct camera_device * device, int32_t msg_type) 318{ 319 ALOGI("%s: E", __func__); 320 ALOGI("%s: msg_type: %d", __func__, msg_type); 321 322 camera_hardware_t *camHal; 323 324 if(device && device->priv){ 325 camHal = (camera_hardware_t *)device->priv; 326 }else{ 327 ALOGE("%s: Null device or device->priv", __func__); 328 return; 329 } 330 331 Mutex::Autolock autoLock(camHal->lock); 332 333 camHal->msgEnabledFlag |= msg_type; 334 335 ALOGI("%s: X", __func__); 336} 337 338void usbcam_disable_msg_type(struct camera_device * device, int32_t msg_type) 339{ 340 ALOGI("%s: E", __func__); 341 ALOGI("%s: msg_type: %d", __func__, msg_type); 342 343 camera_hardware_t *camHal; 344 if(device && device->priv){ 345 camHal = (camera_hardware_t *)device->priv; 346 }else{ 347 ALOGE("%s: Null device or device->priv", __func__); 348 return; 349 } 350 351 Mutex::Autolock autoLock(camHal->lock); 352 353 camHal->msgEnabledFlag &= ~msg_type; 354 355 ALOGI("%s: X", __func__); 356} 357 358int usbcam_msg_type_enabled(struct camera_device * device, int32_t msg_type) 359{ 360 ALOGI("%s: E", __func__); 361 362 camera_hardware_t *camHal; 363 if(device && device->priv){ 364 camHal = (camera_hardware_t *)device->priv; 365 }else{ 366 ALOGE("%s: Null device or device->priv", __func__); 367 return -1; 368 } 369 370 Mutex::Autolock autoLock(camHal->lock); 371 372 ALOGI("%s: X", __func__); 373 return (camHal->msgEnabledFlag & msg_type); 374} 375 376int usbcam_start_preview(struct camera_device * device) 377{ 378 ALOGI("%s: E", __func__); 379 380 int rc = -1; 381 camera_hardware_t *camHal = NULL; 382 383 VALIDATE_DEVICE_HDL(camHal, device, -1); 384 Mutex::Autolock autoLock(camHal->lock); 385 386 /* If preivew is already running, nothing to be done */ 387 if(camHal->previewEnabledFlag){ 388 ALOGI("%s: Preview is already running", __func__); 389 return 0; 390 } 391 392#if CAPTURE 393 rc = initUsbCamera(camHal, camHal->prevWidth, 394 camHal->prevHeight, getPreviewCaptureFmt(camHal)); 395 if(rc < 0) { 396 ALOGE("%s: Failed to intialize the device", __func__); 397 }else{ 398 rc = startUsbCamCapture(camHal); 399 if(rc < 0) { 400 ALOGE("%s: Failed to startUsbCamCapture", __func__); 401 }else{ 402 rc = launch_preview_thread(camHal); 403 if(rc < 0) { 404 ALOGE("%s: Failed to launch_preview_thread", __func__); 405 } 406 } 407 } 408#else /* CAPTURE */ 409 rc = launch_preview_thread(camHal); 410 if(rc < 0) { 411 ALOGE("%s: Failed to launch_preview_thread", __func__); 412 } 413#endif /* CAPTURE */ 414 /* if no errors, then set the flag */ 415 if(!rc) 416 camHal->previewEnabledFlag = 1; 417 418 ALOGD("%s: X", __func__); 419 return rc; 420} 421 422void usbcam_stop_preview(struct camera_device * device) 423{ 424 ALOGD("%s: E", __func__); 425 426 int rc = 0; 427 camera_hardware_t *camHal; 428 429 if(device && device->priv){ 430 camHal = (camera_hardware_t *)device->priv; 431 }else{ 432 ALOGE("%s: Null device or device->priv", __func__); 433 return; 434 } 435 436 Mutex::Autolock autoLock(camHal->lock); 437 438 rc = stopPreviewInternal(camHal); 439 if(rc) 440 ALOGE("%s: stopPreviewInternal returned error", __func__); 441 442 ALOGI("%s: X", __func__); 443 return; 444} 445 446/* This function is equivalent to is_preview_enabled */ 447int usbcam_preview_enabled(struct camera_device * device) 448{ 449 ALOGI("%s: E", __func__); 450 camera_hardware_t *camHal; 451 452 if(device && device->priv){ 453 camHal = (camera_hardware_t *)device->priv; 454 }else{ 455 ALOGE("%s: Null device or device->priv", __func__); 456 return -1; 457 } 458 Mutex::Autolock autoLock(camHal->lock); 459 460 ALOGI("%s: X", __func__); 461 return camHal->previewEnabledFlag; 462} 463 464/* TBD */ 465int usbcam_store_meta_data_in_buffers(struct camera_device * device, int enable) 466{ 467 ALOGI("%s: E", __func__); 468 int rc = 0; 469 470 ALOGI("%s: X", __func__); 471 return rc; 472} 473 474/* TBD */ 475int usbcam_start_recording(struct camera_device * device) 476{ 477 int rc = 0; 478 ALOGD("%s: E", __func__); 479 480 ALOGD("%s: X", __func__); 481 482 return rc; 483} 484 485/* TBD */ 486void usbcam_stop_recording(struct camera_device * device) 487{ 488 ALOGD("%s: E", __func__); 489 490 ALOGD("%s: X", __func__); 491} 492 493/* TBD */ 494int usbcam_recording_enabled(struct camera_device * device) 495{ 496 int rc = 0; 497 ALOGD("%s: E", __func__); 498 499 ALOGD("%s: X", __func__); 500 return rc; 501} 502 503/* TBD */ 504void usbcam_release_recording_frame(struct camera_device * device, 505 const void *opaque) 506{ 507 ALOGV("%s: E", __func__); 508 509 ALOGD("%s: X", __func__); 510} 511 512/* TBD */ 513int usbcam_auto_focus(struct camera_device * device) 514{ 515 ALOGD("%s: E", __func__); 516 int rc = 0; 517 518 ALOGD("%s: X", __func__); 519 return rc; 520} 521 522/* TBD */ 523int usbcam_cancel_auto_focus(struct camera_device * device) 524{ 525 int rc = 0; 526 ALOGD("%s: E", __func__); 527 528 ALOGD("%s: X", __func__); 529 return rc; 530} 531 532int usbcam_take_picture(struct camera_device * device) 533{ 534 ALOGI("%s: E", __func__); 535 int rc = 0; 536 camera_hardware_t *camHal; 537 538 VALIDATE_DEVICE_HDL(camHal, device, -1); 539 540 Mutex::Autolock autoLock(camHal->lock); 541 542 /* If take picture is already in progress, nothing t be done */ 543 if(camHal->takePictInProgress){ 544 ALOGI("%s: Take picture already in progress", __func__); 545 return 0; 546 } 547 548 if(camHal->previewEnabledFlag) 549 { 550 rc = stopPreviewInternal(camHal); 551 if(rc){ 552 ALOGE("%s: stopPreviewInternal returned error", __func__); 553 } 554 USB_CAM_CLOSE(camHal); 555 camHal->prvwStoppedForPicture = 1; 556 } 557 /* TBD: Need to handle any dependencies on video recording state */ 558 rc = launchTakePictureThread(camHal); 559 if(rc) 560 ALOGE("%s: launchTakePictureThread error", __func__); 561 562#if 0 563 /* This implementation requests preview thread to take picture */ 564 if(camHal->previewEnabledFlag) 565 { 566 camHal->prvwCmdPending++; 567 camHal->prvwCmd = USB_CAM_PREVIEW_TAKEPIC; 568 ALOGD("%s: Take picture command set ", __func__); 569 }else{ 570 ALOGE("%s: Take picture without preview started!", __func__); 571 rc = -1; 572 } 573#endif 574 575 if(!rc) 576 camHal->takePictInProgress = 1; 577 578 ALOGI("%s: X", __func__); 579 return rc; 580} 581 582/* TBD */ 583int usbcam_cancel_picture(struct camera_device * device) 584 585{ 586 ALOGI("%s: E", __func__); 587 int rc = 0; 588 589 ALOGI("%s: X", __func__); 590 return rc; 591} 592 593int usbcam_set_parameters(struct camera_device * device, const char *params) 594 595{ 596 ALOGI("%s: E", __func__); 597 int rc = 0; 598 camera_hardware_t *camHal; 599 600 VALIDATE_DEVICE_HDL(camHal, device, -1); 601 602 Mutex::Autolock autoLock(camHal->lock); 603 604 rc = usbCamSetParameters(camHal, params); 605 606 ALOGI("%s: X", __func__); 607 return rc; 608} 609 610char* usbcam_get_parameters(struct camera_device * device) 611{ 612 char *parms; 613 ALOGI("%s: E", __func__); 614 615 camera_hardware_t *camHal; 616 VALIDATE_DEVICE_HDL(camHal, device, NULL); 617 618 Mutex::Autolock autoLock(camHal->lock); 619 620 parms = usbCamGetParameters(camHal); 621 622 ALOGI("%s: X", __func__); 623 return parms; 624} 625 626void usbcam_put_parameters(struct camera_device * device, char *parm) 627 628{ 629 ALOGI("%s: E", __func__); 630 631 camera_hardware_t *camHal; 632 633 if(device && device->priv){ 634 camHal = (camera_hardware_t *)device->priv; 635 }else{ 636 ALOGE("%s: Null device or device->priv", __func__); 637 return; 638 } 639 640 usbCamPutParameters(camHal, parm); 641 642 ALOGI("%s: X", __func__); 643 return; 644} 645 646/* TBD */ 647int usbcam_send_command(struct camera_device * device, 648 int32_t cmd, int32_t arg1, int32_t arg2) 649{ 650 int rc = 0; 651 ALOGI("%s: E", __func__); 652 ALOGI("%d", cmd); 653 654 ALOGI("%s: X", __func__); 655 return rc; 656} 657 658/* TBD */ 659void usbcam_release(struct camera_device * device) 660{ 661 ALOGI("%s: E", __func__); 662#if 0 663 Mutex::Autolock l(&mLock); 664 665 switch(mPreviewState) { 666 case QCAMERA_HAL_PREVIEW_STOPPED: 667 break; 668 case QCAMERA_HAL_PREVIEW_START: 669 break; 670 case QCAMERA_HAL_PREVIEW_STARTED: 671 stopPreviewInternal(); 672 break; 673 case QCAMERA_HAL_RECORDING_STARTED: 674 stopRecordingInternal(); 675 stopPreviewInternal(); 676 break; 677 case QCAMERA_HAL_TAKE_PICTURE: 678 cancelPictureInternal(); 679 break; 680 default: 681 break; 682 } 683 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED; 684#endif 685 ALOGI("%s: X", __func__); 686} 687 688/* TBD */ 689int usbcam_dump(struct camera_device * device, int fd) 690{ 691 ALOGI("%s: E", __func__); 692 int rc = 0; 693 694 ALOGI("%s: X", __func__); 695 return rc; 696} 697/***************************************************************************** 698* Static function definitions below 699*****************************************************************************/ 700 701/******************************************************************************/ 702/* No in place conversion supported. Output buffer and input MUST should be */ 703/* different input buffer for a 4x4 pixel video ***/ 704/****** YUYVYUYV 00 01 02 03 04 05 06 07 ************/ 705/****** YUYVYUYV 08 09 10 11 12 13 14 15 ************/ 706/****** YUYVYUYV 16 17 18 19 20 21 22 23 ************/ 707/****** YUYVYUYV 24 25 26 27 28 29 30 31 ************/ 708/******************************************************************************/ 709/* output generated by this function ******************************************/ 710/************************** YYYY 00 02 04 06 ************/ 711/************************** YYYY 08 10 12 14 ************/ 712/************************** YYYY 16 18 20 22 ************/ 713/************************** YYYY 24 26 28 30 ************/ 714/************************** VUVU 03 01 07 05 ************/ 715/************************** VUVU 19 17 23 21 ************/ 716/******************************************************************************/ 717 718static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht) 719{ 720 int rc =0; 721 int row, col, uv_row; 722 723 ALOGD("%s: E", __func__); 724 /* Arrange Y */ 725 for(row = 0; row < ht; row++) 726 for(col = 0; col < wd * 2; col += 2) 727 { 728 out_buf[row * wd + col / 2] = in_buf[row * wd * 2 + col]; 729 } 730 731 /* Arrange UV */ 732 for(row = 0, uv_row = ht; row < ht; row += 2, uv_row++) 733 for(col = 1; col < wd * 2; col += 4) 734 { 735 out_buf[uv_row * wd + col / 2]= in_buf[row * wd * 2 + col + 2]; 736 out_buf[uv_row * wd + col / 2 + 1] = in_buf[row * wd * 2 + col]; 737 } 738 739 ALOGD("%s: X", __func__); 740 return rc; 741} 742 743/****************************************************************************** 744 * Function: initDisplayBuffers 745 * Description: This function initializes the preview buffers 746 * 747 * Input parameters: 748 * camHal - camera HAL handle 749 * 750 * Return values: 751 * 0 Success 752 * -1 Error 753 * Notes: none 754 *****************************************************************************/ 755static int initDisplayBuffers(camera_hardware_t *camHal) 756{ 757 preview_stream_ops *mPreviewWindow; 758 struct ion_fd_data ion_info_fd; 759 int numMinUndequeuedBufs = 0; 760 int rc = 0; 761 int gralloc_usage = 0; 762 int err; 763 int color=30; 764 765 ALOGD("%s: E", __func__); 766 767#if DISPLAY 768 if(camHal == NULL) { 769 ALOGE("%s: camHal = NULL", __func__); 770 return -1; 771 } 772 773 mPreviewWindow = camHal->window; 774 if(!mPreviewWindow) { 775 ALOGE("%s: mPreviewWindow = NULL", __func__); 776 return -1; 777 } 778 779 /************************************************************************/ 780 /* - get_min_undequeued_buffer_count */ 781 /* - set_buffer_count */ 782 /* - set_buffers_geometry */ 783 /* - set_usage */ 784 /* - dequeue all the display buffers */ 785 /* - cancel buffers: release w/o displaying */ 786 /************************************************************************/ 787 788 /************************************************************************/ 789 /* - get_min_undequeued_buffer_count */ 790 /************************************************************************/ 791 if(mPreviewWindow->get_min_undequeued_buffer_count) { 792 rc = mPreviewWindow->get_min_undequeued_buffer_count( 793 mPreviewWindow, &numMinUndequeuedBufs); 794 if (0 != rc) { 795 ALOGE("%s: get_min_undequeued_buffer_count returned error", __func__); 796 } 797 else 798 ALOGD("%s: get_min_undequeued_buffer_count returned: %d ", 799 __func__, numMinUndequeuedBufs); 800 } 801 else 802 ALOGE("%s: get_min_undequeued_buffer_count is NULL pointer", __func__); 803 804 /************************************************************************/ 805 /* - set_buffer_count */ 806 /************************************************************************/ 807 if(mPreviewWindow->set_buffer_count) { 808 camHal->previewMem.buffer_count = numMinUndequeuedBufs 809 + PRVW_DISP_BUF_CNT; 810 rc = mPreviewWindow->set_buffer_count( 811 mPreviewWindow, 812 camHal->previewMem.buffer_count); 813 if (rc != 0) { 814 ALOGE("%s: set_buffer_count returned error", __func__); 815 }else 816 ALOGD("%s: set_buffer_count returned success", __func__); 817 }else 818 ALOGE("%s: set_buffer_count is NULL pointer", __func__); 819 820 /************************************************************************/ 821 /* - set_buffers_geometry */ 822 /************************************************************************/ 823 if(mPreviewWindow->set_buffers_geometry) { 824 rc = mPreviewWindow->set_buffers_geometry(mPreviewWindow, 825 camHal->dispWidth, 826 camHal->dispHeight, 827 camHal->dispFormat); 828 if (rc != 0) { 829 ALOGE("%s: set_buffers_geometry returned error. %s (%d)", 830 __func__, strerror(-rc), -rc); 831 }else 832 ALOGD("%s: set_buffers_geometry returned success", __func__); 833 }else 834 ALOGE("%s: set_buffers_geometry is NULL pointer", __func__); 835 836 /************************************************************************/ 837 /* - set_usage */ 838 /************************************************************************/ 839 gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID | 840 GRALLOC_USAGE_PRIVATE_UNCACHED; 841 842 if(mPreviewWindow->set_usage) { 843 rc = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage); 844 if (rc != 0) { 845 ALOGE("%s: set_usage returned error", __func__); 846 }else 847 ALOGD("%s: set_usage returned success", __func__); 848 } 849 else 850 ALOGE("%s: set_usage is NULL pointer", __func__); 851 852 /************************************************************************/ 853 /* - dequeue all the display buffers */ 854 /************************************************************************/ 855 for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) { 856 int stride; 857 err = mPreviewWindow->dequeue_buffer( 858 mPreviewWindow, 859 &camHal->previewMem.buffer_handle[cnt], 860 &camHal->previewMem.stride[cnt]); 861 if(!err) { 862 ALOGD("%s: dequeue buf: %p\n", 863 __func__, camHal->previewMem.buffer_handle[cnt]); 864 865 if(mPreviewWindow->lock_buffer) { 866 err = mPreviewWindow->lock_buffer( 867 mPreviewWindow, 868 camHal->previewMem.buffer_handle[cnt]); 869 ALOGD("%s: mPreviewWindow->lock_buffer success", 870 __func__); 871 } 872 873 // lock the buffer using genlock 874 ALOGD("%s: camera call genlock_lock, hdl=%p", 875 __func__, (*camHal->previewMem.buffer_handle[cnt])); 876 877 if (GENLOCK_NO_ERROR != 878 genlock_lock_buffer( 879 (native_handle_t *) (*camHal->previewMem.buffer_handle[cnt]), 880 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) 881 { 882 ALOGE("%s: genlock_lock_buffer(WRITE) failed", 883 __func__); 884 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED; 885 }else { 886 ALOGD("%s: genlock_lock_buffer hdl =%p", 887 __func__, *camHal->previewMem.buffer_handle[cnt]); 888 camHal->previewMem.local_flag[cnt] = BUFFER_LOCKED; 889 } 890 891 /* Store this buffer details in the context */ 892 camHal->previewMem.private_buffer_handle[cnt] = 893 (struct private_handle_t *) (*camHal->previewMem.buffer_handle[cnt]); 894 895 ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__, 896 cnt, camHal->previewMem.private_buffer_handle[cnt]->fd, 897 camHal->previewMem.private_buffer_handle[cnt]->size, 898 camHal->previewMem.private_buffer_handle[cnt]->offset); 899 900 camHal->previewMem.camera_memory[cnt] = 901 camHal->get_memory( 902 camHal->previewMem.private_buffer_handle[cnt]->fd, 903 camHal->previewMem.private_buffer_handle[cnt]->size, 904 1, camHal->cb_ctxt); 905 906 ALOGD("%s: data = %p, size = %d, handle = %p", __func__, 907 camHal->previewMem.camera_memory[cnt]->data, 908 camHal->previewMem.camera_memory[cnt]->size, 909 camHal->previewMem.camera_memory[cnt]->handle); 910 911#ifdef USE_ION 912 /* In case of ION usage, open ION fd */ 913 camHal->previewMem.mem_info[cnt].main_ion_fd = 914 open("/dev/ion", O_RDONLY); 915 if (camHal->previewMem.mem_info[cnt].main_ion_fd < 0) { 916 ALOGE("%s: failed: could not open ion device\n", __func__); 917 }else{ 918 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 919 ion_info_fd.fd = 920 camHal->previewMem.private_buffer_handle[cnt]->fd; 921 if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd, 922 ION_IOC_IMPORT, &ion_info_fd) < 0) { 923 ALOGE("ION import failed\n"); 924 } 925 } 926 camHal->previewMem.mem_info[cnt].fd = 927 camHal->previewMem.private_buffer_handle[cnt]->fd; 928 camHal->previewMem.mem_info[cnt].size = 929 camHal->previewMem.private_buffer_handle[cnt]->size; 930 camHal->previewMem.mem_info[cnt].handle = ion_info_fd.handle; 931 932#endif 933 } 934 else 935 ALOGE("%s: dequeue buf %d failed \n", __func__, cnt); 936 } 937 /************************************************************************/ 938 /* - cancel buffers: queue w/o displaying */ 939 /************************************************************************/ 940 for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) { 941 if (GENLOCK_FAILURE == genlock_unlock_buffer( 942 (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){ 943 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__, 944 (*(camHal->previewMem.buffer_handle[cnt])) ); 945 } else { 946 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED; 947 ALOGD("%s: genlock_unlock_buffer success: hdl = %p", 948 __func__, (*(camHal->previewMem.buffer_handle[cnt]))); 949 } 950 951 err = mPreviewWindow->cancel_buffer(mPreviewWindow, 952 (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]); 953 if(!err) { 954 ALOGD("%s: cancel_buffer successful: %p\n", 955 __func__, camHal->previewMem.buffer_handle[cnt]); 956 }else 957 ALOGE("%s: cancel_buffer failed: %p\n", __func__, 958 camHal->previewMem.buffer_handle[cnt]); 959 } 960#else 961 rc = 0; 962#endif /* #if DISPLAY */ 963 ALOGD("%s: X", __func__); 964 return rc; 965} 966 967/****************************************************************************** 968 * Function: deInitDisplayBuffers 969 * Description: This function de-initializes all the display buffers allocated 970 * in initDisplayBuffers 971 * 972 * Input parameters: 973 * camHal - camera HAL handle 974 * 975 * Return values: 976 * 0 Success 977 * -1 Error 978 * Notes: none 979 *****************************************************************************/ 980static int deInitDisplayBuffers(camera_hardware_t *camHal) 981{ 982 int rc = 0; 983 preview_stream_ops *previewWindow; 984 985 ALOGD("%s: E", __func__); 986 987 if(!camHal || !camHal->window) { 988 ALOGE("%s: camHal = NULL or window = NULL ", __func__); 989 return -1; 990 } 991 992 previewWindow = camHal->window; 993 994 /************************************************************************/ 995 /* - Release all buffers that were acquired using get_memory */ 996 /* - If using ION memory, free ION related resources */ 997 /* - genUnlock if buffer is genLocked */ 998 /* - Cancel buffers: queue w/o displaying */ 999 /************************************************************************/ 1000 1001#if DISPLAY 1002 for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) { 1003 1004 /* Release all buffers that were acquired using get_memory */ 1005 camHal->previewMem.camera_memory[cnt]->release( 1006 camHal->previewMem.camera_memory[cnt]); 1007 1008#ifdef USE_ION 1009 /* If using ION memory, free ION related resources */ 1010 struct ion_handle_data ion_handle; 1011 memset(&ion_handle, 0, sizeof(ion_handle)); 1012 ion_handle.handle = camHal->previewMem.mem_info[cnt].handle; 1013 if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd, 1014 ION_IOC_FREE, &ion_handle) < 0) { 1015 ALOGE("%s: ion free failed\n", __func__); 1016 } 1017 close(camHal->previewMem.mem_info[cnt].main_ion_fd); 1018#endif 1019 1020 /* genUnlock if buffer is genLocked */ 1021 if(camHal->previewMem.local_flag[cnt] == BUFFER_LOCKED){ 1022 if (GENLOCK_FAILURE == genlock_unlock_buffer( 1023 (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){ 1024 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__, 1025 (*(camHal->previewMem.buffer_handle[cnt])) ); 1026 } else { 1027 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED; 1028 ALOGD("%s: genlock_unlock_buffer success: hdl = %p", 1029 __func__, (*(camHal->previewMem.buffer_handle[cnt]))); 1030 } 1031 } 1032 /* cancel buffers: enqueue w/o displaying */ 1033 rc = previewWindow->cancel_buffer(previewWindow, 1034 (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]); 1035 if(!rc) { 1036 ALOGD("%s: cancel_buffer successful: %p\n", 1037 __func__, camHal->previewMem.buffer_handle[cnt]); 1038 }else 1039 ALOGE("%s: cancel_buffer failed: %p\n", __func__, 1040 camHal->previewMem.buffer_handle[cnt]); 1041 } 1042#endif /* #if DISPLAY */ 1043 memset(&camHal->previewMem, 0, sizeof(camHal->previewMem)); 1044 1045 ALOGD("%s: X", __func__); 1046 return rc; 1047} 1048 1049/****************************************************************************** 1050 * Function: getPreviewCaptureFmt 1051 * Description: This function implements the logic to decide appropriate 1052 * capture format from the USB camera 1053 * 1054 * Input parameters: 1055 * camHal - camera HAL handle 1056 * 1057 * Return values: 1058 * Capture format. Default (V4L2_PIX_FMT_MJPEG) 1059 * 1060 * Notes: none 1061 *****************************************************************************/ 1062static int getPreviewCaptureFmt(camera_hardware_t *camHal) 1063{ 1064 int i = 0, mjpegSupported = 0, h264Supported = 0; 1065 struct v4l2_fmtdesc fmtdesc; 1066 1067 memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc)); 1068 1069 /************************************************************************/ 1070 /* - Query the camera for all supported formats */ 1071 /* - Based on the resolution, pick an apporpriate format */ 1072 /************************************************************************/ 1073 1074 /************************************************************************/ 1075 /* - Query the camera for all supported formats */ 1076 /************************************************************************/ 1077 for(i = 0; ; i++) { 1078 fmtdesc.index = i; 1079 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1080 if (-1 == ioctlLoop(camHal->fd, VIDIOC_ENUM_FMT, &fmtdesc)) { 1081 if (EINVAL == errno) { 1082 ALOGI("%s: Queried all formats till index %d\n", __func__, i); 1083 break; 1084 } else { 1085 ALOGE("%s: VIDIOC_ENUM_FMT failed", __func__); 1086 } 1087 } 1088 if(V4L2_PIX_FMT_MJPEG == fmtdesc.pixelformat){ 1089 mjpegSupported = 1; 1090 ALOGI("%s: V4L2_PIX_FMT_MJPEG is supported", __func__ ); 1091 } 1092 if(V4L2_PIX_FMT_H264 == fmtdesc.pixelformat){ 1093 h264Supported = 1; 1094 ALOGI("%s: V4L2_PIX_FMT_H264 is supported", __func__ ); 1095 } 1096 1097 } 1098 1099 /************************************************************************/ 1100 /* - Based on the resolution, pick an apporpriate format */ 1101 /************************************************************************/ 1102 //V4L2_PIX_FMT_MJPEG; V4L2_PIX_FMT_YUYV; V4L2_PIX_FMT_H264 = 0x34363248; 1103 camHal->captureFormat = V4L2_PIX_FMT_YUYV; 1104 if(camHal->prevWidth > 640){ 1105 if(1 == mjpegSupported) 1106 camHal->captureFormat = V4L2_PIX_FMT_MJPEG; 1107 else if(1 == h264Supported) 1108 camHal->captureFormat = V4L2_PIX_FMT_H264; 1109 } 1110 ALOGI("%s: Capture format chosen: 0x%x. 0x%x:YUYV. 0x%x:MJPEG. 0x%x: H264", 1111 __func__, camHal->captureFormat, V4L2_PIX_FMT_YUYV, 1112 V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_H264); 1113 1114 return camHal->captureFormat; 1115} 1116 1117/****************************************************************************** 1118 * Function: getMjpegdOutputFormat 1119 * Description: This function maps display pixel format enum to JPEG output 1120 * format enum 1121 * 1122 * Input parameters: 1123 * dispFormat - Display pixel format 1124 * 1125 * Return values: 1126 * (int)mjpegOutputFormat 1127 * 1128 * Notes: none 1129 *****************************************************************************/ 1130static int getMjpegdOutputFormat(int dispFormat) 1131{ 1132 int mjpegOutputFormat = YCRCBLP_H2V2; 1133 1134 if(HAL_PIXEL_FORMAT_YCrCb_420_SP == dispFormat) 1135 mjpegOutputFormat = YCRCBLP_H2V2; 1136 1137 return mjpegOutputFormat; 1138} 1139 1140/****************************************************************************** 1141 * Function: ioctlLoop 1142 * Description: This function is a blocking call around ioctl 1143 * 1144 * Input parameters: 1145 * fd - IOCTL fd 1146 * ioctlCmd - IOCTL command 1147 * args - IOCTL arguments 1148 * 1149 * Return values: 1150 * (int)mjpegOutputFormat 1151 * 1152 * Notes: none 1153 *****************************************************************************/ 1154static int ioctlLoop(int fd, int ioctlCmd, void *args) 1155{ 1156 int rc = -1; 1157 1158 while(1) 1159 { 1160 rc = ioctl(fd, ioctlCmd, args); 1161 if(!((-1 == rc) && (EINTR == errno))) 1162 break; 1163 } 1164 return rc; 1165} 1166 1167/****************************************************************************** 1168 * Function: initV4L2mmap 1169 * Description: This function requests for V4L2 driver allocated buffers 1170 * 1171 * Input parameters: 1172 * camHal - camera HAL handle 1173 * 1174 * Return values: 1175 * 0 No error 1176 * -1 Error 1177 * 1178 * Notes: none 1179 *****************************************************************************/ 1180static int initV4L2mmap(camera_hardware_t *camHal) 1181{ 1182 int rc = -1; 1183 struct v4l2_requestbuffers reqBufs; 1184 struct v4l2_buffer tempBuf; 1185 1186 ALOGD("%s: E", __func__); 1187 memset(&reqBufs, 0, sizeof(v4l2_requestbuffers)); 1188 reqBufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1189 reqBufs.memory = V4L2_MEMORY_MMAP; 1190 reqBufs.count = PRVW_CAP_BUF_CNT; 1191 1192 if (-1 == ioctlLoop(camHal->fd, VIDIOC_REQBUFS, &reqBufs)) { 1193 if (EINVAL == errno) { 1194 ALOGE("%s: does not support memory mapping\n", __func__); 1195 } else { 1196 ALOGE("%s: VIDIOC_REQBUFS failed", __func__); 1197 } 1198 } 1199 ALOGD("%s: VIDIOC_REQBUFS success", __func__); 1200 1201 if (reqBufs.count < PRVW_CAP_BUF_CNT) { 1202 ALOGE("%s: Insufficient buffer memory on\n", __func__); 1203 } 1204 1205 camHal->buffers = 1206 ( bufObj* ) calloc(reqBufs.count, sizeof(bufObj)); 1207 1208 if (!camHal->buffers) { 1209 ALOGE("%s: Out of memory\n", __func__); 1210 } 1211 1212 /* Store the indexes in the context. Useful during releasing */ 1213 for (camHal->n_buffers = 0; 1214 camHal->n_buffers < reqBufs.count; 1215 camHal->n_buffers++) { 1216 1217 memset(&tempBuf, 0, sizeof(tempBuf)); 1218 1219 tempBuf.index = camHal->n_buffers; 1220 tempBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1221 tempBuf.memory = V4L2_MEMORY_MMAP; 1222 1223 if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYBUF, &tempBuf)) 1224 ALOGE("%s: VIDIOC_QUERYBUF failed", __func__); 1225 1226 ALOGD("%s: VIDIOC_QUERYBUF success", __func__); 1227 1228 camHal->buffers[camHal->n_buffers].len = tempBuf.length; 1229 camHal->buffers[camHal->n_buffers].data = 1230 mmap(NULL /* start anywhere */, 1231 tempBuf.length, 1232 PROT_READ | PROT_WRITE, 1233 MAP_SHARED, 1234 camHal->fd, tempBuf.m.offset); 1235 1236 if (MAP_FAILED == camHal->buffers[camHal->n_buffers].data) 1237 ALOGE("%s: mmap failed", __func__); 1238 } 1239 ALOGD("%s: X", __func__); 1240 return 0; 1241} 1242 1243/****************************************************************************** 1244 * Function: unInitV4L2mmap 1245 * Description: This function unmaps the V4L2 driver buffers 1246 * 1247 * Input parameters: 1248 * camHal - camera HAL handle 1249 * 1250 * Return values: 1251 * 0 No error 1252 * -1 Error 1253 * 1254 * Notes: none 1255 *****************************************************************************/ 1256static int unInitV4L2mmap(camera_hardware_t *camHal) 1257{ 1258 int i, rc = 0; 1259 ALOGD("%s: E", __func__); 1260 1261 for (i = 0; i < camHal->n_buffers; i++) 1262 if (-1 == munmap(camHal->buffers[i].data, camHal->buffers[i].len)){ 1263 ALOGE("%s: munmap failed for buffer: %d", __func__, i); 1264 rc = -1; 1265 } 1266 1267 ALOGD("%s: X", __func__); 1268 return rc; 1269} 1270 1271/****************************************************************************** 1272 * Function: initUsbCamera 1273 * Description: This function sets the resolution and pixel format of the 1274 * USB camera 1275 * 1276 * Input parameters: 1277 * camHal - camera HAL handle 1278 * width - picture width in pixels 1279 * height - picture height in pixels 1280 * pixelFormat - capture format for the camera 1281 * 1282 * Return values: 1283 * 0 No error 1284 * -1 Error 1285 * 1286 * Notes: none 1287 *****************************************************************************/ 1288static int initUsbCamera(camera_hardware_t *camHal, int width, int height, 1289 int pixelFormat) 1290{ 1291 int rc = -1; 1292 struct v4l2_capability cap; 1293 struct v4l2_cropcap cropcap; 1294 struct v4l2_crop crop; 1295 struct v4l2_format v4l2format; 1296 unsigned int min; 1297 1298 ALOGI("%s: E", __func__); 1299 1300 if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYCAP, &cap)) { 1301 if (EINVAL == errno) { 1302 ALOGE( "%s: This is not V4L2 device\n", __func__); 1303 return -1; 1304 } else { 1305 ALOGE("%s: VIDIOC_QUERYCAP errno: %d", __func__, errno); 1306 } 1307 } 1308 ALOGD("%s: VIDIOC_QUERYCAP success", __func__); 1309 1310 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { 1311 ALOGE("%s: This is not video capture device\n", __func__); 1312 return -1; 1313 } 1314 1315 if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 1316 ALOGE("%s: This does not support streaming i/o\n", __func__); 1317 return -1; 1318 } 1319 1320 /* Select video input, video standard and tune here. */ 1321 memset(&cropcap, 0, sizeof(cropcap)); 1322 1323 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1324 1325 if (0 == ioctlLoop(camHal->fd, VIDIOC_CROPCAP, &cropcap)) { 1326 1327 /* reset to default */ 1328 crop.c = cropcap.defrect; 1329 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1330 1331 ALOGD("%s: VIDIOC_CROPCAP success", __func__); 1332 if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_CROP, &crop)) { 1333 switch (errno) { 1334 case EINVAL: 1335 /* Cropping not supported. */ 1336 break; 1337 default: 1338 /* Errors ignored. */ 1339 break; 1340 } 1341 } 1342 ALOGD("%s: VIDIOC_S_CROP success", __func__); 1343 1344 } else { 1345 /* Errors ignored. */ 1346 ALOGE("%s: VIDIOC_S_CROP failed", __func__); 1347 } 1348 1349 1350 memset(&v4l2format, 0, sizeof(v4l2format)); 1351 1352 v4l2format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1353 { 1354 v4l2format.fmt.pix.field = V4L2_FIELD_NONE; 1355 v4l2format.fmt.pix.pixelformat = pixelFormat; 1356 v4l2format.fmt.pix.width = width; 1357 v4l2format.fmt.pix.height = height; 1358 1359 if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_FMT, &v4l2format)) 1360 { 1361 ALOGE("%s: VIDIOC_S_FMT failed", __func__); 1362 return -1; 1363 } 1364 ALOGD("%s: VIDIOC_S_FMT success", __func__); 1365 1366 /* Note VIDIOC_S_FMT may change width and height. */ 1367 } 1368 1369 /* TBR: In case of user pointer buffers, v4l2format.fmt.pix.sizeimage */ 1370 /* might have to be calculated as per V4L2 sample application due to */ 1371 /* open source driver bug */ 1372 1373 rc = initV4L2mmap(camHal); 1374 ALOGI("%s: X", __func__); 1375 return rc; 1376} 1377 1378/****************************************************************************** 1379 * Function: startUsbCamCapture 1380 * Description: This function queues buffer objects to the driver and sends 1381 * STREAM ON command to the USB camera driver 1382 * 1383 * Input parameters: 1384 * camHal - camera HAL handle 1385 * 1386 * Return values: 1387 * 0 No error 1388 * -1 Error 1389 * 1390 * Notes: none 1391 *****************************************************************************/ 1392static int startUsbCamCapture(camera_hardware_t *camHal) 1393{ 1394 int rc = -1; 1395 unsigned int i; 1396 enum v4l2_buf_type v4l2BufType; 1397 ALOGD("%s: E", __func__); 1398 1399 for (i = 0; i < camHal->n_buffers; ++i) { 1400 struct v4l2_buffer tempBuf; 1401 1402 memset(&tempBuf, 0, sizeof(tempBuf)); 1403 tempBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1404 tempBuf.memory = V4L2_MEMORY_MMAP; 1405 tempBuf.index = i; 1406 1407 if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &tempBuf)) 1408 ALOGE("%s: VIDIOC_QBUF for %d buffer failed", __func__, i); 1409 else 1410 ALOGD("%s: VIDIOC_QBUF for %d buffer success", __func__, i); 1411 } 1412 1413 v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1414 if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMON, &v4l2BufType)) 1415 ALOGE("%s: VIDIOC_STREAMON failed", __func__); 1416 else 1417 { 1418 ALOGD("%s: VIDIOC_STREAMON success", __func__); 1419 rc = 0; 1420 } 1421 1422 ALOGD("%s: X", __func__); 1423 return rc; 1424} 1425 1426/****************************************************************************** 1427 * Function: stopUsbCamCapture 1428 * Description: This function sends STREAM OFF command to the USB camera driver 1429 * 1430 * Input parameters: 1431 * camHal - camera HAL handle 1432 * 1433 * Return values: 1434 * 0 No error 1435 * -1 Error 1436 * 1437 * Notes: none 1438 *****************************************************************************/ 1439static int stopUsbCamCapture(camera_hardware_t *camHal) 1440{ 1441 int rc = -1; 1442 unsigned int i; 1443 enum v4l2_buf_type v4l2BufType; 1444 ALOGD("%s: E", __func__); 1445 1446 if(!camHal->fd){ 1447 ALOGE("%s: camHal->fd = NULL ", __func__); 1448 return -1; 1449 } 1450 v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1451 if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMOFF, &v4l2BufType)){ 1452 ALOGE("%s: VIDIOC_STREAMOFF failed", __func__); 1453 rc = -1; 1454 }else{ 1455 ALOGD("%s: VIDIOC_STREAMOFF success", __func__); 1456 rc = 0; 1457 } 1458 1459 ALOGD("%s: X", __func__); 1460 return rc; 1461} 1462 1463/****************************************************************************** 1464 * Function: stopPreviewInternal 1465 * Description: This function sends EXIT command to prview loop thread, 1466 * stops usb camera capture and uninitializes MMAP. This function 1467 * assumes that calling function has locked camHal->lock 1468 * 1469 * Input parameters: 1470 * camHal - camera HAL handle 1471 * 1472 * Return values: 1473 * 0 No error 1474 * -1 Error 1475 * 1476 * Notes: none 1477 *****************************************************************************/ 1478static int stopPreviewInternal(camera_hardware_t *camHal) 1479{ 1480 int rc = 0; 1481 ALOGD("%s: E", __func__); 1482 1483 if(camHal->previewEnabledFlag) 1484 { 1485 camHal->prvwCmdPending++; 1486 camHal->prvwCmd = USB_CAM_PREVIEW_EXIT; 1487 1488 /* yield lock while waiting for the preview thread to exit */ 1489 camHal->lock.unlock(); 1490 if(pthread_join(camHal->previewThread, NULL)){ 1491 ALOGE("%s: Error in pthread_join preview thread", __func__); 1492 } 1493 camHal->lock.lock(); 1494 1495 if(stopUsbCamCapture(camHal)){ 1496 ALOGE("%s: Error in stopUsbCamCapture", __func__); 1497 rc = -1; 1498 } 1499 if(unInitV4L2mmap(camHal)){ 1500 ALOGE("%s: Error in stopUsbCamCapture", __func__); 1501 rc = -1; 1502 } 1503 camHal->previewEnabledFlag = 0; 1504 } 1505 1506 ALOGD("%s: X, rc: %d", __func__, rc); 1507 return rc; 1508} 1509#if 1 1510/****************************************************************************** 1511 * Function: prvwThreadTakePictureInternal 1512 * Description: This function processes one camera frame to get JPEG encoded 1513 * picture. 1514 * 1515 * Input parameters: 1516 * camHal - camera HAL handle 1517 * 1518 * Return values: 1519 * 0 No error 1520 * -1 Error 1521 * 1522 * Notes: none 1523 *****************************************************************************/ 1524static int prvwThreadTakePictureInternal(camera_hardware_t *camHal) 1525{ 1526 int rc = 0; 1527 QCameraHalMemInfo_t *mem_info; 1528 ALOGD("%s: E", __func__); 1529 1530 /************************************************************************/ 1531 /* - If requested for shutter notfication, callback */ 1532 /* - Dequeue capture buffer from USB camera */ 1533 /* - Send capture buffer to JPEG encoder for JPEG compression */ 1534 /* - If jpeg frames callback is requested, callback with jpeg buffers */ 1535 /* - Enqueue capture buffer back to USB camera */ 1536 /************************************************************************/ 1537 1538 /************************************************************************/ 1539 /* - If requested for shutter notfication, callback */ 1540 /************************************************************************/ 1541 if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){ 1542 camHal->lock.unlock(); 1543 camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt); 1544 camHal->lock.lock(); 1545 } 1546 1547#if CAPTURE 1548 /************************************************************************/ 1549 /* - Dequeue capture buffer from USB camera */ 1550 /************************************************************************/ 1551 if (0 == get_buf_from_cam(camHal)) 1552 ALOGD("%s: get_buf_from_cam success", __func__); 1553 else 1554 ALOGE("%s: get_buf_from_cam error", __func__); 1555#endif 1556 1557 /************************************************************************/ 1558 /* - Send capture buffer to JPEG encoder for JPEG compression */ 1559 /************************************************************************/ 1560 /* Optimization: If camera capture is JPEG format, need not compress! */ 1561 /* instead, just data copy from capture buffer to picture buffer */ 1562 if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat){ 1563 /* allocate heap memory for JPEG output */ 1564 mem_info = &camHal->pictMem.mem_info[0]; 1565 mem_info->size = camHal->curCaptureBuf.bytesused; 1566 /* TBD: allocate_ion_memory 1567 rc = QCameraHardwareInterface::allocate_ion_memory(mem_info, 1568 ((0x1 << CAMERA_ZSL_ION_HEAP_ID) | 1569 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID))); 1570 */ 1571 if(rc) 1572 ALOGE("%s: ION memory allocation failed", __func__); 1573 1574 camHal->pictMem.camera_memory[0] = camHal->get_memory( 1575 mem_info->fd, mem_info->size, 1, camHal->cb_ctxt); 1576 if(!camHal->pictMem.camera_memory[0]) 1577 ALOGE("%s: get_mem failed", __func__); 1578 1579 memcpy( camHal->pictMem.camera_memory[0]->data, 1580 (char *)camHal->buffers[camHal->curCaptureBuf.index].data, 1581 camHal->curCaptureBuf.bytesused); 1582 } 1583 1584 /************************************************************************/ 1585 /* - If jpeg frames callback is requested, callback with jpeg buffers */ 1586 /************************************************************************/ 1587 if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) && 1588 (camHal->data_cb)){ 1589 camHal->lock.unlock(); 1590 camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE, 1591 camHal->pictMem.camera_memory[0], 1592 0, NULL, camHal->cb_ctxt); 1593 camHal->lock.lock(); 1594 } 1595 /* release heap memory after the call back */ 1596 if(camHal->pictMem.camera_memory[0]) 1597 camHal->pictMem.camera_memory[0]->release( 1598 camHal->pictMem.camera_memory[0]); 1599 1600 /* TBD: deallocate_ion_memory */ 1601 //rc = QCameraHardwareInterface::deallocate_ion_memory(mem_info); 1602 if(rc) 1603 ALOGE("%s: ION memory de-allocation failed", __func__); 1604 1605#if CAPTURE 1606 /************************************************************************/ 1607 /* - Enqueue capture buffer back to USB camera */ 1608 /************************************************************************/ 1609 if(0 == put_buf_to_cam(camHal)) { 1610 ALOGD("%s: put_buf_to_cam success", __func__); 1611 } 1612 else 1613 ALOGE("%s: put_buf_to_cam error", __func__); 1614#endif 1615 1616 ALOGD("%s: X, rc: %d", __func__, rc); 1617 return rc; 1618} 1619#endif //#if 0 1620/****************************************************************************** 1621 * Function: cache_ops 1622 * Description: This function calls ION ioctl for cache related operations 1623 * 1624 * Input parameters: 1625 * mem_info - QCameraHalMemInfo_t structure with ION info 1626 * buf_ptr - Buffer pointer that needs to be cache operated 1627 * cmd - Cache command - clean/invalidate 1628 * 1629 * Return values: 1630 * MM_CAMERA_OK No error 1631 * -1 Error 1632 * 1633 * Notes: none 1634 *****************************************************************************/ 1635int cache_ops(QCameraHalMemInfo_t *mem_info, 1636 void *buf_ptr, 1637 unsigned int cmd) 1638{ 1639 struct ion_flush_data cache_inv_data; 1640 struct ion_custom_data custom_data; 1641 int ret = MM_CAMERA_OK; 1642 1643#ifdef USE_ION 1644 if (NULL == mem_info) { 1645 ALOGE("%s: mem_info is NULL, return here", __func__); 1646 return -1; 1647 } 1648 1649 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 1650 memset(&custom_data, 0, sizeof(custom_data)); 1651 cache_inv_data.vaddr = buf_ptr; 1652 cache_inv_data.fd = mem_info->fd; 1653 cache_inv_data.handle = mem_info->handle; 1654 cache_inv_data.length = mem_info->size; 1655 custom_data.cmd = cmd; 1656 custom_data.arg = (unsigned long)&cache_inv_data; 1657 1658 ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d", 1659 __func__, cache_inv_data.vaddr, cache_inv_data.fd, 1660 cache_inv_data.handle, cache_inv_data.length, 1661 mem_info->main_ion_fd); 1662 if(mem_info->main_ion_fd > 0) { 1663 if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) { 1664 ALOGE("%s: Cache Invalidate failed\n", __func__); 1665 ret = -1; 1666 } 1667 } 1668#endif 1669 1670 return ret; 1671} 1672 1673/****************************************************************************** 1674 * Function: get_buf_from_cam 1675 * Description: This funtions gets/acquires 1 capture buffer from the camera 1676 * driver. The fetched buffer is stored in curCaptureBuf 1677 * 1678 * Input parameters: 1679 * camHal - camera HAL handle 1680 * 1681 * Return values: 1682 * 0 No error 1683 * -1 Error 1684 * 1685 * Notes: none 1686 *****************************************************************************/ 1687static int get_buf_from_cam(camera_hardware_t *camHal) 1688{ 1689 int rc = -1; 1690 1691 ALOGD("%s: E", __func__); 1692 { 1693 memset(&camHal->curCaptureBuf, 0, sizeof(camHal->curCaptureBuf)); 1694 1695 camHal->curCaptureBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1696 camHal->curCaptureBuf.memory = V4L2_MEMORY_MMAP; 1697 1698 if (-1 == ioctlLoop(camHal->fd, VIDIOC_DQBUF, &camHal->curCaptureBuf)){ 1699 switch (errno) { 1700 case EAGAIN: 1701 ALOGE("%s: EAGAIN error", __func__); 1702 return 1; 1703 1704 case EIO: 1705 /* Could ignore EIO, see spec. */ 1706 1707 /* fall through */ 1708 1709 default: 1710 ALOGE("%s: VIDIOC_DQBUF error", __func__); 1711 } 1712 } 1713 else 1714 { 1715 rc = 0; 1716 ALOGD("%s: VIDIOC_DQBUF: %d successful, %d bytes", 1717 __func__, camHal->curCaptureBuf.index, 1718 camHal->curCaptureBuf.bytesused); 1719 } 1720 } 1721 ALOGD("%s: X", __func__); 1722 return rc; 1723} 1724 1725/****************************************************************************** 1726 * Function: put_buf_to_cam 1727 * Description: This funtion puts/releases 1 capture buffer back to the camera 1728 * driver 1729 * 1730 * Input parameters: 1731 * camHal - camera HAL handle 1732 * 1733 * Return values: 1734 * 0 No error 1735 * -1 Error 1736 * 1737 * Notes: none 1738 *****************************************************************************/ 1739static int put_buf_to_cam(camera_hardware_t *camHal) 1740{ 1741 ALOGD("%s: E", __func__); 1742 1743 camHal->curCaptureBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1744 camHal->curCaptureBuf.memory = V4L2_MEMORY_MMAP; 1745 1746 1747 if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &camHal->curCaptureBuf)) 1748 { 1749 ALOGE("%s: VIDIOC_QBUF failed ", __func__); 1750 return 1; 1751 } 1752 ALOGD("%s: X", __func__); 1753 return 0; 1754} 1755 1756/****************************************************************************** 1757 * Function: put_buf_to_cam 1758 * Description: This funtion gets/acquires 1 display buffer from the display 1759 * window 1760 * 1761 * Input parameters: 1762 * camHal - camera HAL handle 1763 * buffer_id - Buffer id pointer. The id of buffer obtained 1764 * by this function is returned in this arg 1765 * 1766 * Return values: 1767 * 0 No error 1768 * -1 Error 1769 * 1770 * Notes: none 1771 *****************************************************************************/ 1772static int get_buf_from_display(camera_hardware_t *camHal, int *buffer_id) 1773{ 1774 int err = 0; 1775 preview_stream_ops *mPreviewWindow = NULL; 1776 int stride = 0, cnt = 0; 1777 buffer_handle_t *buffer_handle = NULL; 1778 struct private_handle_t *private_buffer_handle = NULL; 1779 1780 ALOGD("%s: E", __func__); 1781 1782 if (camHal == NULL) { 1783 ALOGE("%s: camHal = NULL", __func__); 1784 return -1; 1785 } 1786 1787 mPreviewWindow = camHal->window; 1788 if( mPreviewWindow == NULL) { 1789 ALOGE("%s: mPreviewWindow = NULL", __func__); 1790 return -1; 1791 } 1792 err = mPreviewWindow->dequeue_buffer(mPreviewWindow, 1793 &buffer_handle, 1794 &stride); 1795 if(!err) { 1796 ALOGD("%s: dequeue buf buffer_handle: %p\n", __func__, buffer_handle); 1797 1798 ALOGD("%s: mPreviewWindow->lock_buffer: %p", 1799 __func__, mPreviewWindow->lock_buffer); 1800 if(mPreviewWindow->lock_buffer) { 1801 err = mPreviewWindow->lock_buffer(mPreviewWindow, buffer_handle); 1802 ALOGD("%s: mPreviewWindow->lock_buffer success", __func__); 1803 } 1804 ALOGD("%s: camera call genlock_lock, hdl=%p", 1805 __func__, (*buffer_handle)); 1806 1807 if (GENLOCK_NO_ERROR != 1808 genlock_lock_buffer((native_handle_t *)(*buffer_handle), 1809 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 1810 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__); 1811 } else { 1812 ALOGD("%s: genlock_lock_buffer hdl =%p", __func__, *buffer_handle); 1813 } 1814 1815 private_buffer_handle = (struct private_handle_t *)(*buffer_handle); 1816 1817 ALOGD("%s: fd = %d, size = %d, offset = %d, stride = %d", 1818 __func__, private_buffer_handle->fd, 1819 private_buffer_handle->size, private_buffer_handle->offset, stride); 1820 1821 for(cnt = 0; cnt < camHal->previewMem.buffer_count + 2; cnt++) { 1822 if(private_buffer_handle->fd == 1823 camHal->previewMem.private_buffer_handle[cnt]->fd) { 1824 *buffer_id = cnt; 1825 ALOGD("%s: deQueued fd = %d, index: %d", 1826 __func__, private_buffer_handle->fd, cnt); 1827 break; 1828 } 1829 } 1830 } 1831 else 1832 ALOGE("%s: dequeue buf failed \n", __func__); 1833 1834 ALOGD("%s: X", __func__); 1835 1836 return err; 1837} 1838 1839/****************************************************************************** 1840 * Function: put_buf_to_display 1841 * Description: This funtion puts/enqueues 1 buffer back to the display window 1842 * 1843 * Input parameters: 1844 * camHal - camera HAL handle 1845 * buffer_id - id of the buffer that needs to be enqueued 1846 * 1847 * Return values: 1848 * 0 No error 1849 * -1 Error 1850 * 1851 * Notes: none 1852 *****************************************************************************/ 1853static int put_buf_to_display(camera_hardware_t *camHal, int buffer_id) 1854{ 1855 int err = 0; 1856 preview_stream_ops *mPreviewWindow; 1857 1858 ALOGD("%s: E", __func__); 1859 1860 if (camHal == NULL) { 1861 ALOGE("%s: camHal = NULL", __func__); 1862 return -1; 1863 } 1864 1865 mPreviewWindow = camHal->window; 1866 if( mPreviewWindow == NULL) { 1867 ALOGE("%s: mPreviewWindow = NULL", __func__); 1868 return -1; 1869 } 1870 1871 if (GENLOCK_FAILURE == 1872 genlock_unlock_buffer( 1873 (native_handle_t *) 1874 (*(camHal->previewMem.buffer_handle[buffer_id])))) { 1875 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", 1876 __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) ); 1877 } else { 1878 ALOGD("%s: genlock_unlock_buffer success: hdl =%p", 1879 __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) ); 1880 } 1881 1882 /* Cache clean the output buffer so that cache is written back */ 1883 cache_ops(&camHal->previewMem.mem_info[buffer_id], 1884 (void *)camHal->previewMem.camera_memory[buffer_id]->data, 1885 ION_IOC_CLEAN_CACHES); 1886 /* 1887 cache_ops(&camHal->previewMem.mem_info[buffer_id], 1888 (void *)camHal->previewMem.camera_memory[buffer_id]->data, 1889 ION_IOC_CLEAN_INV_CACHES); 1890*/ 1891 err = mPreviewWindow->enqueue_buffer(mPreviewWindow, 1892 (buffer_handle_t *)camHal->previewMem.buffer_handle[buffer_id]); 1893 if(!err) { 1894 ALOGD("%s: enqueue buf successful: %p\n", 1895 __func__, camHal->previewMem.buffer_handle[buffer_id]); 1896 }else 1897 ALOGE("%s: enqueue buf failed: %p\n", 1898 __func__, camHal->previewMem.buffer_handle[buffer_id]); 1899 1900 ALOGD("%s: X", __func__); 1901 1902 return err; 1903} 1904 1905/****************************************************************************** 1906 * Function: put_buf_to_display 1907 * Description: This funtion transfers the content from capture buffer to 1908 * preiew display buffer after appropriate conversion 1909 * 1910 * Input parameters: 1911 * camHal - camera HAL handle 1912 * buffer_id - id of the buffer that needs to be enqueued 1913 * 1914 * Return values: 1915 * 0 No error 1916 * -1 Error 1917 * 1918 * Notes: none 1919 *****************************************************************************/ 1920static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id) 1921{ 1922 int rc = -1; 1923 1924 if(!camHal) { 1925 ALOGE("%s: camHal is NULL", __func__); 1926 return -1; 1927 } 1928 /* If input and output are raw formats, but different color format, */ 1929 /* call color conversion routine */ 1930 if( (V4L2_PIX_FMT_YUYV == camHal->captureFormat) && 1931 (HAL_PIXEL_FORMAT_YCrCb_420_SP == camHal->dispFormat)) 1932 { 1933 convert_YUYV_to_420_NV12( 1934 (char *)camHal->buffers[camHal->curCaptureBuf.index].data, 1935 (char *)camHal->previewMem.camera_memory[buffer_id]->data, 1936 camHal->prevWidth, 1937 camHal->prevHeight); 1938 ALOGD("%s: Copied %d bytes from camera buffer %d to display buffer: %d", 1939 __func__, camHal->curCaptureBuf.bytesused, 1940 camHal->curCaptureBuf.index, buffer_id); 1941 rc = 0; 1942 } 1943 1944 /* If camera buffer is MJPEG encoded, call mjpeg decode call */ 1945 if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat) 1946 { 1947 if(NULL == camHal->mjpegd) 1948 { 1949 rc = mjpegDecoderInit(&camHal->mjpegd); 1950 if(rc < 0) 1951 ALOGE("%s: mjpegDecoderInit Error: %d", __func__, rc); 1952 } 1953 if(camHal->mjpegd) 1954 { 1955 rc = mjpegDecode( 1956 (void*)camHal->mjpegd, 1957 (char *)camHal->buffers[camHal->curCaptureBuf.index].data, 1958 camHal->curCaptureBuf.bytesused, 1959 (char *)camHal->previewMem.camera_memory[buffer_id]->data, 1960 (char *)camHal->previewMem.camera_memory[buffer_id]->data + 1961 camHal->prevWidth * camHal->prevHeight, 1962 getMjpegdOutputFormat(camHal->dispFormat)); 1963 if(rc < 0) 1964 ALOGE("%s: mjpegDecode Error: %d", __func__, rc); 1965 } 1966 } 1967 return rc; 1968} 1969 1970/****************************************************************************** 1971 * Function: launch_preview_thread 1972 * Description: This is a wrapper function to start preview thread 1973 * 1974 * Input parameters: 1975 * camHal - camera HAL handle 1976 * 1977 * Return values: 1978 * 0 No error 1979 * -1 Error 1980 * 1981 * Notes: none 1982 *****************************************************************************/ 1983static int launch_preview_thread(camera_hardware_t *camHal) 1984{ 1985 ALOGD("%s: E", __func__); 1986 int rc = 0; 1987 1988 if(!camHal) { 1989 ALOGE("%s: camHal is NULL", __func__); 1990 return -1; 1991 } 1992 1993 pthread_attr_t attr; 1994 pthread_attr_init(&attr); 1995 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1996 pthread_create(&camHal->previewThread, &attr, previewloop, camHal); 1997 1998 ALOGD("%s: X", __func__); 1999 return rc; 2000} 2001 2002/****************************************************************************** 2003 * Function: launch_preview_thread 2004 * Description: This is thread funtion for preivew loop 2005 * 2006 * Input parameters: 2007 * hcamHal - camera HAL handle 2008 * 2009 * Return values: 2010 * 0 No error 2011 * -1 Error 2012 * 2013 * Notes: none 2014 *****************************************************************************/ 2015static void * previewloop(void *hcamHal) 2016{ 2017 int rc; 2018 int buffer_id = 0; 2019 pid_t tid = 0; 2020 camera_hardware_t *camHal = NULL; 2021 int msgType = 0; 2022 camera_memory_t *data = NULL; 2023 camera_frame_metadata_t *metadata= NULL; 2024 camera_memory_t *previewMem = NULL; 2025 2026 camHal = (camera_hardware_t *)hcamHal; 2027 ALOGD("%s: E", __func__); 2028 2029 if(!camHal) { 2030 ALOGE("%s: camHal is NULL", __func__); 2031 return NULL ; 2032 } 2033 2034 tid = gettid(); 2035 /* TBR: Set appropriate thread priority */ 2036 androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL); 2037 prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0); 2038 2039 /************************************************************************/ 2040 /* - Time wait (select) on camera fd for input read buffer */ 2041 /* - Check if any preview thread commands are set. If set, process */ 2042 /* - Dequeue display buffer from surface */ 2043 /* - Dequeue capture buffer from USB camera */ 2044 /* - Convert capture format to display format */ 2045 /* - If preview frames callback is requested, callback with prvw buffers*/ 2046 /* - Enqueue display buffer back to surface */ 2047 /* - Enqueue capture buffer back to USB camera */ 2048 /************************************************************************/ 2049 while(1) { 2050 fd_set fds; 2051 struct timeval tv; 2052 int r = 0; 2053 2054 FD_ZERO(&fds); 2055#if CAPTURE 2056 FD_SET(camHal->fd, &fds); 2057#endif /* CAPTURE */ 2058 2059 /************************************************************************/ 2060 /* - Time wait (select) on camera fd for input read buffer */ 2061 /************************************************************************/ 2062 tv.tv_sec = 0; 2063 tv.tv_usec = 500000; 2064 2065 ALOGD("%s: b4 select on camHal->fd + 1,fd: %d", __func__, camHal->fd); 2066#if CAPTURE 2067 r = select(camHal->fd + 1, &fds, NULL, NULL, &tv); 2068#else 2069 r = select(1, NULL, NULL, NULL, &tv); 2070#endif /* CAPTURE */ 2071 ALOGD("%s: after select : %d", __func__, camHal->fd); 2072 2073 if (-1 == r) { 2074 if (EINTR == errno) 2075 continue; 2076 ALOGE("%s: FDSelect error: %d", __func__, errno); 2077 } 2078 2079 if (0 == r) { 2080 ALOGD("%s: select timeout\n", __func__); 2081 } 2082 2083 /* Protect the context for one iteration of preview loop */ 2084 /* this gets unlocked at the end of the while */ 2085 Mutex::Autolock autoLock(camHal->lock); 2086 2087 /************************************************************************/ 2088 /* - Check if any preview thread commands are set. If set, process */ 2089 /************************************************************************/ 2090 if(camHal->prvwCmdPending) 2091 { 2092 /* command is serviced. Hence command pending = 0 */ 2093 camHal->prvwCmdPending--; 2094 //sempost(ack) 2095 if(USB_CAM_PREVIEW_EXIT == camHal->prvwCmd){ 2096 /* unlock before exiting the thread */ 2097 camHal->lock.unlock(); 2098 ALOGI("%s: Exiting coz USB_CAM_PREVIEW_EXIT", __func__); 2099 return (void *)0; 2100 }else if(USB_CAM_PREVIEW_TAKEPIC == camHal->prvwCmd){ 2101 rc = prvwThreadTakePictureInternal(camHal); 2102 if(rc) 2103 ALOGE("%s: prvwThreadTakePictureInternal returned error", 2104 __func__); 2105 } 2106 } 2107 2108 /* Null check on preview window. If null, sleep */ 2109 if(!camHal->window) { 2110 ALOGD("%s: sleeping coz camHal->window = NULL",__func__); 2111 camHal->lock.unlock(); 2112 sleep(2); 2113 continue; 2114 } 2115#if DISPLAY 2116 /************************************************************************/ 2117 /* - Dequeue display buffer from surface */ 2118 /************************************************************************/ 2119 if(0 == get_buf_from_display(camHal, &buffer_id)) { 2120 ALOGD("%s: get_buf_from_display success: %d", 2121 __func__, buffer_id); 2122 }else{ 2123 ALOGE("%s: get_buf_from_display failed. Skipping the loop", 2124 __func__); 2125 continue; 2126 } 2127#endif 2128 2129#if CAPTURE 2130 /************************************************************************/ 2131 /* - Dequeue capture buffer from USB camera */ 2132 /************************************************************************/ 2133 if (0 == get_buf_from_cam(camHal)) 2134 ALOGD("%s: get_buf_from_cam success", __func__); 2135 else 2136 ALOGE("%s: get_buf_from_cam error", __func__); 2137#endif 2138 2139#if FILE_DUMP_CAMERA 2140 /* Debug code to dump frames from camera */ 2141 { 2142 static int frame_cnt = 0; 2143 /* currently hardcoded for Bytes-Per-Pixel = 1.5 */ 2144 fileDump("/data/USBcam.yuv", 2145 (char*)camHal->buffers[camHal->curCaptureBuf.index].data, 2146 camHal->prevWidth * camHal->prevHeight * 1.5, 2147 &frame_cnt); 2148 } 2149#endif 2150 2151#if MEMSET 2152 static int color = 30; 2153 color += 50; 2154 if(color > 200) { 2155 color = 30; 2156 } 2157 ALOGE("%s: Setting to the color: %d\n", __func__, color); 2158 /* currently hardcoded for format of type Bytes-Per-Pixel = 1.5 */ 2159 memset(camHal->previewMem.camera_memory[buffer_id]->data, 2160 color, camHal->dispWidth * camHal->dispHeight * 1.5 + 2 * 1024); 2161#else 2162 convert_data_frm_cam_to_disp(camHal, buffer_id); 2163 ALOGD("%s: Copied data to buffer_id: %d", __func__, buffer_id); 2164#endif 2165 2166#if FILE_DUMP_B4_DISP 2167 /* Debug code to dump display buffers */ 2168 { 2169 static int frame_cnt = 0; 2170 /* currently hardcoded for Bytes-Per-Pixel = 1.5 */ 2171 fileDump("/data/display.yuv", 2172 (char*) camHal->previewMem.camera_memory[buffer_id]->data, 2173 camHal->dispWidth * camHal->dispHeight * 1.5, 2174 &frame_cnt); 2175 ALOGD("%s: Written buf_index: %d ", __func__, buffer_id); 2176 } 2177#endif 2178 2179#if DISPLAY 2180 /************************************************************************/ 2181 /* - Enqueue display buffer back to surface */ 2182 /************************************************************************/ 2183 if(0 == put_buf_to_display(camHal, buffer_id)) { 2184 ALOGD("%s: put_buf_to_display success: %d", __func__, buffer_id); 2185 } 2186 else 2187 ALOGE("%s: put_buf_to_display error", __func__); 2188#endif 2189 2190#if CAPTURE 2191 /************************************************************************/ 2192 /* - Enqueue capture buffer back to USB camera */ 2193 /************************************************************************/ 2194 if(0 == put_buf_to_cam(camHal)) { 2195 ALOGD("%s: put_buf_to_cam success", __func__); 2196 } 2197 else 2198 ALOGE("%s: put_buf_to_cam error", __func__); 2199#endif 2200 2201#if CALL_BACK 2202 /************************************************************************/ 2203 /* - If preview frames callback is requested, callback with prvw buffers*/ 2204 /************************************************************************/ 2205 /* TBD: change the 1.5 hardcoding to Bytes Per Pixel */ 2206 int previewBufSize = camHal->prevWidth * camHal->prevHeight * 1.5; 2207 2208 msgType |= CAMERA_MSG_PREVIEW_FRAME; 2209 2210 if(previewBufSize != 2211 camHal->previewMem.private_buffer_handle[buffer_id]->size) { 2212 2213 previewMem = camHal->get_memory( 2214 camHal->previewMem.private_buffer_handle[buffer_id]->fd, 2215 previewBufSize, 2216 1, 2217 camHal->cb_ctxt); 2218 2219 if (!previewMem || !previewMem->data) { 2220 ALOGE("%s: get_memory failed.\n", __func__); 2221 } 2222 else { 2223 data = previewMem; 2224 ALOGD("%s: GetMemory successful. data = %p", 2225 __func__, data); 2226 ALOGD("%s: previewBufSize = %d, priv_buf_size: %d", 2227 __func__, previewBufSize, 2228 camHal->previewMem.private_buffer_handle[buffer_id]->size); 2229 } 2230 } 2231 else{ 2232 data = camHal->previewMem.camera_memory[buffer_id]; 2233 ALOGD("%s: No GetMemory, no invalid fmt. data = %p, idx=%d", 2234 __func__, data, buffer_id); 2235 } 2236 /* Unlock and lock around the callback. */ 2237 /* Sometimes 'disable_msg' is issued in the callback context, */ 2238 /* leading to deadlock */ 2239 camHal->lock.unlock(); 2240 if((camHal->msgEnabledFlag & CAMERA_MSG_PREVIEW_FRAME) && 2241 camHal->data_cb){ 2242 ALOGD("%s: before data callback", __func__); 2243 camHal->data_cb(msgType, data, 0,metadata, camHal->cb_ctxt); 2244 ALOGD("%s: after data callback: %p", __func__, camHal->data_cb); 2245 } 2246 camHal->lock.lock(); 2247 if (previewMem) 2248 previewMem->release(previewMem); 2249#endif 2250 2251 }//while(1) 2252 ALOGD("%s: X", __func__); 2253 return (void *)0; 2254} 2255 2256/****************************************************************************** 2257 * Function: get_uvc_device 2258 * Description: This function loops through /dev/video entries and probes with 2259 * UVCIOC query. If the device responds to the query, then it is 2260 * detected as UVC webcam 2261 * Input parameters: 2262 * devname - String pointer. The function return dev entry 2263 * name in this string 2264 * Return values: 2265 * 0 Success 2266 * -1 Error 2267 * Notes: none 2268 *****************************************************************************/ 2269static int get_uvc_device(char *devname) 2270{ 2271 char temp_devname[FILENAME_LENGTH]; 2272 FILE *fp = NULL; 2273 int i = 0, ret = 0, fd; 2274 2275 ALOGD("%s: E", __func__); 2276#if 1 2277 strncpy(devname, "/dev/video1", FILENAME_LENGTH); 2278 2279/* 2280 struct stat st; 2281 2282 strncpy(dev_name, "/dev/video1", FILENAME_LENGTH); 2283 if (-1 == stat(dev_name, &st)) { 2284 ALOGE("%s: Cannot identify '%s': %d, %s\n", 2285 __func__, dev_name, errno, strerror(errno)); 2286 } 2287 2288 if (!S_ISCHR(st.st_mode)) { 2289 ALOGE("%s: %s is no device\n", __func__, dev_name); 2290 rc = -1; 2291 } 2292*/ 2293 2294#else 2295 2296 *devname = '\0'; 2297 /************************************************************************/ 2298 /* - List all /dev/video* entries to a file */ 2299 /* - Open the video list file and loop through the list */ 2300 /* - Send UVC specific control query and check the response */ 2301 /* - If device responds to the query as success, device is UVC webcam */ 2302 /************************************************************************/ 2303 2304 /************************************************************************/ 2305 /* - List all /dev/video* entries to a file */ 2306 /************************************************************************/ 2307 /* Temporarily commented out. This logic doesnt seem to be working */ 2308 //system("ls > /data/video_dev_list"); 2309 2310 /************************************************************************/ 2311 /* - Open the video list file and loop through the list */ 2312 /************************************************************************/ 2313 2314 /* Temporarily commented out. This logic doesnt seem to be working */ 2315 /* 2316 fp = fopen("/data/video_dev_list", "rb"); 2317 if(!fp) { 2318 ALOGE("%s: Error in opening /data/video_dev_list ", __func__); 2319 return -1; 2320 } 2321 */ 2322 2323 /* Temporarily commented out. Looping logic changed due to issue in */ 2324 /* executing system("ls > /data/video_dev_list") */ 2325 //while(EOF != fscanf(fp, "%s", devname)){ 2326 while(1){ 2327 uvc_xu_control_query xqry; 2328 2329 sprintf(temp_devname, "/dev/video%d", i); 2330 ALOGD("%s: Probing %s \n", __func__, temp_devname); 2331 2332 fd = open(temp_devname, O_RDWR /* required */ | O_NONBLOCK, 0); 2333 if(-1 != fd){ 2334 memset(&xqry, 0, sizeof(uvc_xu_control_query)); 2335 ret = ioctl(fd, UVCIOC_CTRL_QUERY, &xqry); 2336 ALOGD("%s: UVCIOC ret: %d, errno: %d", __func__, ret, errno); 2337 /****************************************************************/ 2338 /* if UVCIOC is executed successfully, ret = 0 */ 2339 /* if UVCIOC is executed but Control Unit = 0 does not exist, */ 2340 /* ret = -1 and errno = ENOENT */ 2341 /* if UVCIOC doesnot execute, ret = -1 and errno = EINVAL */ 2342 /****************************************************************/ 2343 if((0 == ret) || (ret && (ENOENT == errno))){ 2344 ALOGD("%s: Found UVC node: %s\n", __func__, temp_devname); 2345 strncpy(devname, temp_devname, FILENAME_LENGTH); 2346 /* Exit the loop at the first UVC node detection */ 2347 break; 2348 } 2349 close(fd); 2350 } 2351 /* Temporarily logic to probe video0 to video10 nodes */ 2352 if(i++ > 10) 2353 { 2354 if(fp) 2355 fclose(fp); 2356 break; 2357 } 2358 } 2359#endif /* #if 0 */ 2360 ALOGD("%s: X", __func__); 2361 return 0; 2362} /* get_uvc_device */ 2363 2364/****************************************************************************** 2365 * Function: fileDump 2366 * Description: This is a utility function to dump buffers into a file 2367 * 2368 * Input parameters: 2369 * fn - File name string 2370 * data - pointer to character buffer that needs to be dumped 2371 * length - Length of the buffer to be dumped 2372 * frm_cnt - Pointer to frame count. This count is incremented by this 2373 * function on successful file write 2374 * Return values: 2375 * 0 Success 2376 * -1 Error 2377 * Notes: none 2378 *****************************************************************************/ 2379static int fileDump(const char* fn, char* data, int length, int* frm_cnt) 2380{ 2381 2382 FILE *fp = NULL; 2383 if (0 == *frm_cnt) { 2384 fp = fopen(fn, "wb"); 2385 if (NULL == fp) { 2386 ALOGE("%s: Error in opening %s", __func__, fn); 2387 } 2388 fclose(fp); 2389 } 2390 fp = fopen(fn, "ab"); 2391 if (NULL == fp) { 2392 ALOGE("%s: Error in opening %s", __func__, fn); 2393 } 2394 fwrite(data, 1, length, fp); 2395 fclose(fp); 2396 (*frm_cnt)++; 2397 ALOGD("%s: Written %d bytes for frame:%d, in %s", 2398 __func__, length, *frm_cnt, fn); 2399 2400 return 0; 2401} 2402 2403/****************************************************************************** 2404 * Function: launchTakePictureThread 2405 * Description: This is a wrapper function to start take picture thread 2406 * 2407 * Input parameters: 2408 * camHal - camera HAL handle 2409 * 2410 * Return values: 2411 * 0 No error 2412 * -1 Error 2413 * 2414 * Notes: none 2415 *****************************************************************************/ 2416static int launchTakePictureThread(camera_hardware_t *camHal) 2417{ 2418 ALOGD("%s: E", __func__); 2419 int rc = 0; 2420 2421 if(!camHal) { 2422 ALOGE("%s: camHal is NULL", __func__); 2423 return -1; 2424 } 2425 2426 pthread_attr_t attr; 2427 pthread_attr_init(&attr); 2428 /* create the thread in detatched state, when the thread exits all */ 2429 /* memory resources are freed up */ 2430 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 2431 pthread_create(&camHal->takePictureThread, &attr, takePictureThread, camHal); 2432 2433 ALOGD("%s: X", __func__); 2434 return rc; 2435} 2436 2437/****************************************************************************** 2438 * Function: takePictureThread 2439 * Description: This function is associated with take picture thread 2440 * 2441 * Input parameters: 2442 * camHal - camera HAL handle 2443 * 2444 * Return values: 2445 * 0 No error 2446 * -1 Error 2447 * 2448 * Notes: none 2449 *****************************************************************************/ 2450static void * takePictureThread(void *hcamHal) 2451{ 2452 int rc = 0; 2453 int buffer_id = 0; 2454 pid_t tid = 0; 2455 camera_hardware_t *camHal = NULL; 2456 int msgType = 0; 2457 int jpegLength = 0; 2458 QCameraHalMemInfo_t *mem_info = NULL; 2459 2460 camHal = (camera_hardware_t *)hcamHal; 2461 ALOGI("%s: E", __func__); 2462 2463 if(!camHal) { 2464 ALOGE("%s: camHal is NULL", __func__); 2465 return NULL ; 2466 } 2467 2468 tid = gettid(); 2469 /* TBR: Set appropriate thread priority */ 2470 androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL); 2471 prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0); 2472 2473 /************************************************************************/ 2474 /* - If requested for shutter notfication, notify */ 2475 /* - Initialize USB camera with snapshot parameters */ 2476 /* - Time wait (select) on camera fd for camera frame availability */ 2477 /* - Dequeue capture buffer from USB camera */ 2478 /* - Send capture buffer to JPEG encoder for JPEG compression */ 2479 /* - If jpeg frames callback is requested, callback with jpeg buffers */ 2480 /* - Enqueue capture buffer back to USB camera */ 2481 /* - Free USB camera resources and close camera */ 2482 /* - If preview was stopped for taking picture, restart the preview */ 2483 /************************************************************************/ 2484 2485 Mutex::Autolock autoLock(camHal->lock); 2486 /************************************************************************/ 2487 /* - If requested for shutter notfication, notify */ 2488 /************************************************************************/ 2489#if 0 /* TBD: Temporarily commented out due to an issue. Sometimes it takes */ 2490 /* long time to get back the lock once unlocked and notify callback */ 2491 if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){ 2492 camHal->lock.unlock(); 2493 camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt); 2494 camHal->lock.lock(); 2495 } 2496#endif 2497 /************************************************************************/ 2498 /* - Initialize USB camera with snapshot parameters */ 2499 /************************************************************************/ 2500 USB_CAM_OPEN(camHal); 2501 2502#if JPEG_ON_USB_CAMERA 2503 rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight, 2504 V4L2_PIX_FMT_MJPEG); 2505#else 2506 rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight, 2507 V4L2_PIX_FMT_YUYV); 2508#endif 2509 ERROR_CHECK_EXIT_THREAD(rc, "initUsbCamera"); 2510 2511 rc = startUsbCamCapture(camHal); 2512 ERROR_CHECK_EXIT_THREAD(rc, "startUsbCamCapture"); 2513 2514 /************************************************************************/ 2515 /* - Time wait (select) on camera fd for camera frame availability */ 2516 /************************************************************************/ 2517 { 2518 fd_set fds; 2519 struct timeval tv; 2520 int r = 0; 2521 2522 FD_ZERO(&fds); 2523 FD_SET(camHal->fd, &fds); 2524 2525 tv.tv_sec = 1; 2526 tv.tv_usec = 0; 2527 2528 do{ 2529 ALOGD("%s: b4 select on camHal->fd : %d", __func__, camHal->fd); 2530 r = select(camHal->fd + 1, &fds, NULL, NULL, &tv); 2531 ALOGD("%s: after select", __func__); 2532 }while((0 == r) || ((-1 == r) && (EINTR == errno))); 2533 2534 if ((-1 == r) && (EINTR != errno)){ 2535 ALOGE("%s: FDSelect ret = %d error: %d", __func__, r, errno); 2536 return (void *)-1; 2537 } 2538 2539 } 2540 /************************************************************************/ 2541 /* - Dequeue capture buffer from USB camera */ 2542 /************************************************************************/ 2543 if (0 == get_buf_from_cam(camHal)) 2544 ALOGD("%s: get_buf_from_cam success", __func__); 2545 else 2546 ALOGE("%s: get_buf_from_cam error", __func__); 2547 2548 /************************************************************************/ 2549 /* - Send capture buffer to JPEG encoder for JPEG compression */ 2550 /************************************************************************/ 2551 mem_info = &camHal->pictMem.mem_info[0]; 2552 mem_info->size = MAX_JPEG_BUFFER_SIZE; 2553 2554 rc = allocate_ion_memory(mem_info, 2555 ((0x1 << CAMERA_ZSL_ION_HEAP_ID) | 2556 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID))); 2557 if(rc) 2558 ALOGE("%s: ION memory allocation failed", __func__); 2559 2560 camHal->pictMem.camera_memory[0] = camHal->get_memory( 2561 mem_info->fd, mem_info->size, 1, camHal->cb_ctxt); 2562 if(!camHal->pictMem.camera_memory[0]) 2563 ALOGE("%s: get_mem failed", __func__); 2564 2565#if FREAD_JPEG_PICTURE 2566 jpegLength = readFromFile("/data/tempVGA.jpeg", 2567 (char*)camHal->pictMem.camera_memory[0]->data, 2568 camHal->pictMem.camera_memory[0]->size); 2569 camHal->pictMem.camera_memory[0]->size = jpegLength; 2570 2571#elif JPEG_ON_USB_CAMERA 2572 memcpy((char*)camHal->pictMem.camera_memory[0]->data, 2573 (char *)camHal->buffers[camHal->curCaptureBuf.index].data, 2574 camHal->curCaptureBuf.bytesused); 2575 camHal->pictMem.camera_memory[0]->size = camHal->curCaptureBuf.bytesused; 2576 jpegLength = camHal->curCaptureBuf.bytesused; 2577 2578#else 2579 rc = encodeJpeg(camHal); 2580 ERROR_CHECK_EXIT_THREAD(rc, "jpeg_encode"); 2581#endif 2582 if(jpegLength <= 0) 2583 ALOGI("%s: jpegLength : %d", __func__, jpegLength); 2584 2585 ALOGD("%s: jpegLength : %d", __func__, jpegLength); 2586 /************************************************************************/ 2587 /* - If jpeg frames callback is requested, callback with jpeg buffers */ 2588 /************************************************************************/ 2589 /* TBD: CAMERA_MSG_RAW_IMAGE data call back */ 2590 2591 if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) && 2592 (camHal->data_cb)){ 2593 /* Unlock temporarily, callback might call HAL api in turn */ 2594 camHal->lock.unlock(); 2595 2596 camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE, 2597 camHal->pictMem.camera_memory[0], 2598 0, NULL, camHal->cb_ctxt); 2599 camHal->lock.lock(); 2600 } 2601 2602 /* release heap memory after the call back */ 2603 if(camHal->pictMem.camera_memory[0]) 2604 camHal->pictMem.camera_memory[0]->release( 2605 camHal->pictMem.camera_memory[0]); 2606 2607 rc = deallocate_ion_memory(mem_info); 2608 if(rc) 2609 ALOGE("%s: ION memory de-allocation failed", __func__); 2610 2611 /************************************************************************/ 2612 /* - Enqueue capture buffer back to USB camera */ 2613 /************************************************************************/ 2614 if(0 == put_buf_to_cam(camHal)) { 2615 ALOGD("%s: put_buf_to_cam success", __func__); 2616 } 2617 else 2618 ALOGE("%s: put_buf_to_cam error", __func__); 2619 2620 /************************************************************************/ 2621 /* - Free USB camera resources and close camera */ 2622 /************************************************************************/ 2623 rc = stopUsbCamCapture(camHal); 2624 ERROR_CHECK_EXIT_THREAD(rc, "stopUsbCamCapture"); 2625 2626 rc = unInitV4L2mmap(camHal); 2627 ERROR_CHECK_EXIT_THREAD(rc, "unInitV4L2mmap"); 2628 2629 USB_CAM_CLOSE(camHal); 2630 /************************************************************************/ 2631 /* - If preview was stopped for taking picture, restart the preview */ 2632 /************************************************************************/ 2633 if(camHal->prvwStoppedForPicture) 2634 { 2635 struct camera_device device; 2636 device.priv = (void *)camHal; 2637 2638 USB_CAM_OPEN(camHal); 2639 /* Unlock temporarily coz usbcam_start_preview has a lock */ 2640 camHal->lock.unlock(); 2641 rc = usbcam_start_preview(&device); 2642 if(rc) 2643 ALOGE("%s: start_preview error after take picture", __func__); 2644 camHal->lock.lock(); 2645 camHal->prvwStoppedForPicture = 0; 2646 } 2647 2648 /* take picture activity is done */ 2649 camHal->takePictInProgress = 0; 2650 2651 ALOGI("%s: X", __func__); 2652 return (void *)0; 2653} 2654 2655/****************************************************************************** 2656 * Function: allocate_ion_memory 2657 * Description: This function is allocates ION memory 2658 * 2659 * Input parameters: 2660 * camHal - camera HAL handle 2661 * 2662 * Return values: 2663 * 0 No error 2664 * -1 Error 2665 * 2666 * Notes: none 2667 *****************************************************************************/ 2668static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type) 2669{ 2670 int rc = 0; 2671 struct ion_handle_data handle_data; 2672 struct ion_allocation_data alloc; 2673 struct ion_fd_data ion_info_fd; 2674 int main_ion_fd = 0; 2675 2676 main_ion_fd = open("/dev/ion", O_RDONLY); 2677 if (main_ion_fd <= 0) { 2678 ALOGE("Ion dev open failed %s\n", strerror(errno)); 2679 goto ION_OPEN_FAILED; 2680 } 2681 2682 memset(&alloc, 0, sizeof(alloc)); 2683 alloc.len = mem_info->size; 2684 /* to make it page size aligned */ 2685 alloc.len = (alloc.len + 4095) & (~4095); 2686 alloc.align = 4096; 2687 alloc.flags = ION_FLAG_CACHED; 2688 alloc.heap_id_mask = ion_type; 2689 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 2690 if (rc < 0) { 2691 ALOGE("ION allocation failed\n"); 2692 goto ION_ALLOC_FAILED; 2693 } 2694 2695 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 2696 ion_info_fd.handle = alloc.handle; 2697 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 2698 if (rc < 0) { 2699 ALOGE("ION map failed %s\n", strerror(errno)); 2700 goto ION_MAP_FAILED; 2701 } 2702 2703 mem_info->main_ion_fd = main_ion_fd; 2704 mem_info->fd = ion_info_fd.fd; 2705 mem_info->handle = ion_info_fd.handle; 2706 mem_info->size = alloc.len; 2707 return 0; 2708 2709ION_MAP_FAILED: 2710 memset(&handle_data, 0, sizeof(handle_data)); 2711 handle_data.handle = ion_info_fd.handle; 2712 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 2713ION_ALLOC_FAILED: 2714 close(main_ion_fd); 2715ION_OPEN_FAILED: 2716 return -1; 2717} 2718 2719/****************************************************************************** 2720 * Function: deallocate_ion_memory 2721 * Description: This function de allocates ION memory 2722 * 2723 * Input parameters: 2724 * camHal - camera HAL handle 2725 * 2726 * Return values: 2727 * 0 No error 2728 * -1 Error 2729 * 2730 * Notes: none 2731 *****************************************************************************/ 2732static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info) 2733{ 2734 struct ion_handle_data handle_data; 2735 int rc = 0; 2736 2737 if (mem_info->fd > 0) { 2738 close(mem_info->fd); 2739 mem_info->fd = 0; 2740 } 2741 2742 if (mem_info->main_ion_fd > 0) { 2743 memset(&handle_data, 0, sizeof(handle_data)); 2744 handle_data.handle = mem_info->handle; 2745 ioctl(mem_info->main_ion_fd, ION_IOC_FREE, &handle_data); 2746 close(mem_info->main_ion_fd); 2747 mem_info->main_ion_fd = 0; 2748 } 2749 return rc; 2750} 2751 2752/****************************************************************************** 2753 * Function: readFromFile 2754 * Description: This function reads data from the given file into given buffer 2755 * 2756 * Input parameters: 2757 * camHal - camera HAL handle 2758 * 2759 * Return values: 2760 * int bytesRead 2761 * 2762 * Notes: none 2763 *****************************************************************************/ 2764static int readFromFile(char* fileName, char* buffer, int bufferSize) 2765{ 2766 int bytesRead = 0, fileSize = 0; 2767 FILE *fp; 2768 2769 fp = fopen(fileName, "rb"); 2770 if(!fp){ 2771 ALOGE("%s: Error in opening %s ", __func__, fileName); 2772 return bytesRead; 2773 } 2774 2775 /* If file is bigger for given buffer, exit */ 2776 if (fileSize > bufferSize){ 2777 ALOGE("%s: Error %d > %d", __func__, fileSize, bufferSize); 2778 return bytesRead; 2779 } 2780 2781 bytesRead = fread(buffer, 1, bufferSize, fp); 2782 ALOGD(" %s: bytesRead: %d", __func__, bytesRead); 2783 2784 return bytesRead; 2785} 2786 2787/****************************************************************************** 2788 * Function: encodeJpeg 2789 * Description: This function initializes Jpeg encoder and calls jpeg encoder 2790 * call and waits for the encode to complete 2791 * 2792 * Input parameters: 2793 * camHal - camera HAL handle 2794 * 2795 * Return values: 2796 * 0 No Error 2797 * -1 Error 2798 * 2799 * Notes: none 2800 *****************************************************************************/ 2801int encodeJpeg(camera_hardware_t *camHal) 2802{ 2803 int rc = 0; 2804 mm_jpeg_ops_t mmJpegOps; 2805 int jpegEncHdl = 0; 2806 mm_jpeg_job mmJpegJob; 2807 src_image_buffer_info *srcBuf = NULL; 2808 QCameraHalMemInfo_t jpegInMemInfo; 2809 camera_memory_t* jpegInMem; 2810 uint32_t jobId; 2811 2812 ALOGI("%s: E", __func__); 2813 2814 /************************************************************************/ 2815 /* - Allocate Jpeg input buffer from ION memory */ 2816 /************************************************************************/ 2817 jpegInMemInfo.size = camHal->pictWidth * camHal->pictHeight * 2; 2818 rc = allocate_ion_memory(&jpegInMemInfo, 2819 ((0x1 << CAMERA_ZSL_ION_HEAP_ID) | 2820 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID))); 2821 ERROR_CHECK_EXIT(rc, "allocate_ion_memory"); 2822 2823 jpegInMem = camHal->get_memory( 2824 jpegInMemInfo.fd, jpegInMemInfo.size, 1, camHal->cb_ctxt); 2825 if(!jpegInMem){ 2826 ALOGE("%s: get_mem failed", __func__); 2827 return -1; 2828 } 2829 2830 rc = convert_YUYV_to_420_NV12( 2831 (char *)camHal->buffers[camHal->curCaptureBuf.index].data, 2832 (char *)jpegInMem->data, camHal->pictWidth, camHal->pictHeight); 2833 ERROR_CHECK_EXIT(rc, "convert_YUYV_to_420_NV12"); 2834 /************************************************************************/ 2835 /* - Populate JPEG encoding parameters from the camHal context */ 2836 /************************************************************************/ 2837 memset(&mmJpegJob, 0, sizeof(mmJpegJob)); 2838 2839 mmJpegJob.job_type = JPEG_JOB_TYPE_ENCODE; 2840 mmJpegJob.encode_job.jpeg_cb = jpegEncodeCb; 2841 mmJpegJob.encode_job.userdata = (void *)camHal; 2842 /* TBD: Rotation to be set from settings sent from app */ 2843 mmJpegJob.encode_job.encode_parm.rotation = 0; 2844 mmJpegJob.encode_job.encode_parm.exif_numEntries = 0; 2845 mmJpegJob.encode_job.encode_parm.exif_data = NULL; 2846 2847 /* TBD: Add thumbnail support */ 2848 mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img_num = 1; 2849 mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.is_video_frame = 0; 2850 2851 /* Fill main image information */ 2852 srcBuf = &mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img[0]; 2853 srcBuf->type = JPEG_SRC_IMAGE_TYPE_MAIN; 2854 srcBuf->img_fmt = JPEG_SRC_IMAGE_FMT_YUV; 2855 /* TBD: convert from YUYV to CRCBH2V2 */ 2856 srcBuf->color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 2857 srcBuf->num_bufs = 1; 2858 srcBuf->src_image[0].fd = jpegInMemInfo.fd; 2859 srcBuf->src_image[0].buf_vaddr = (uint8_t*)jpegInMem->data; 2860 //srcBuf->src_image[0].offset = 0; 2861 srcBuf->src_dim.width = camHal->pictWidth; 2862 srcBuf->src_dim.height = camHal->pictHeight; 2863 srcBuf->out_dim.width = camHal->pictWidth; 2864 srcBuf->out_dim.height = camHal->pictHeight; 2865 srcBuf->crop.offset_x = 0; 2866 srcBuf->crop.offset_y = 0; 2867 srcBuf->crop.width = srcBuf->src_dim.width; 2868 srcBuf->crop.height = srcBuf->src_dim.height; 2869 srcBuf->quality = camHal->pictJpegQlty; 2870 2871 /* TBD:Fill thumbnail image information */ 2872 2873 /* Fill out buf information */ 2874 mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_vaddr = 2875 (uint8_t*)camHal->pictMem.camera_memory[0]->data; 2876 mmJpegJob.encode_job.encode_parm.buf_info.sink_img.fd = 0; 2877 /* TBD: hard coded for 1.5 bytes per pixel */ 2878 mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_len = 2879 camHal->pictWidth * camHal->pictHeight * 1.5; 2880 2881 /************************************************************************/ 2882 /* - Initialize jpeg encoder and call Jpeg encoder start */ 2883 /************************************************************************/ 2884 memset(&mmJpegOps, 0, sizeof(mm_jpeg_ops_t)); 2885 jpegEncHdl = jpeg_open(&mmJpegOps); 2886 if(!jpegEncHdl){ 2887 ALOGE("%s: Failed to open Jpeg Encoder instance", __func__); 2888 }else 2889 ALOGD("%s: jpegEncHdl = %d", __func__, jpegEncHdl); 2890 2891 camHal->jpegEncInProgress = 1; 2892 rc = mmJpegOps.start_job(jpegEncHdl, &mmJpegJob, &jobId); 2893 2894 /************************************************************************/ 2895 /* - Wait for JPEG encoder to complete encoding */ 2896 /************************************************************************/ 2897 pthread_mutex_init(&camHal->jpegEncMutex, NULL); 2898 pthread_cond_init(&camHal->jpegEncCond, NULL); 2899 2900 pthread_mutex_lock(&camHal->jpegEncMutex); 2901 while(camHal->jpegEncInProgress) 2902 pthread_cond_wait(&camHal->jpegEncCond, &camHal->jpegEncMutex); 2903 pthread_mutex_unlock(&camHal->jpegEncMutex); 2904 2905 /************************************************************************/ 2906 /* - De-allocate Jpeg input buffer from ION memory */ 2907 /************************************************************************/ 2908 if(jpegInMem) 2909 jpegInMem->release(jpegInMem); 2910 2911 rc = deallocate_ion_memory(&jpegInMemInfo); 2912 if(rc) 2913 ALOGE("%s: ION memory de-allocation failed", __func__); 2914 2915 ALOGI("%s: X rc = %d", __func__, rc); 2916 return rc; 2917} 2918 2919/****************************************************************************** 2920 * Function: jpegEncodeCb 2921 * Description: This is a call back function registered with JPEG encoder. 2922 * Jpeg encoder calls this function on completion of encoding 2923 * 2924 * Input parameters: 2925 * camHal - camera HAL handle 2926 * 2927 * Return values: 2928 * 0 No Error 2929 * -1 Error 2930 * 2931 * Notes: none 2932 *****************************************************************************/ 2933void jpegEncodeCb (jpeg_job_status_t status, 2934 uint8_t thumbnailDroppedFlag, 2935 uint32_t client_hdl, 2936 uint32_t jobId, 2937 uint8_t* out_data, 2938 uint32_t data_size, 2939 void *userData) 2940{ 2941 int rc = 0; 2942 camera_hardware_t *camHal = NULL; 2943 2944 ALOGI("%s: E status = %d", __func__, status); 2945 2946 camHal = (camera_hardware_t*) userData; 2947 2948 if(JPEG_JOB_STATUS_DONE == status){ 2949 ALOGD("%s: JPEG encode successful. out_data:%p, size: %d", __func__, 2950 out_data, data_size); 2951 camHal->jpegEncInProgress = 0; 2952 } 2953 2954 pthread_mutex_lock(&camHal->jpegEncMutex); 2955 pthread_cond_signal(&camHal->jpegEncCond); 2956 pthread_mutex_unlock(&camHal->jpegEncMutex); 2957 2958 ALOGI("%s: X", __func__); 2959 return; 2960} 2961 2962/******************************************************************************/ 2963}; // namespace android 2964