1 2 /* 3 ** Copyright 2008, Google Inc. 4 ** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. 5 ** 6 ** Licensed under the Apache License, Version 2.0 (the "License"); 7 ** you may not use this file except in compliance with the License. 8 ** You may obtain a copy of the License at 9 ** 10 ** http://www.apache.org/licenses/LICENSE-2.0 11 ** 12 ** Unless required by applicable law or agreed to in writing, software 13 ** distributed under the License is distributed on an "AS IS" BASIS, 14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 ** See the License for the specific language governing permissions and 16 ** limitations under the License. 17 */ 18 19 #define ALOG_NDEBUG 0 20 #define ALOG_NIDEBUG 0 21 #define LOG_TAG "QualcommCameraHardware" 22 #include <utils/Log.h> 23 #include "QualcommCameraHardware.h" 24 25 #include <utils/Errors.h> 26 #include <utils/threads.h> 27 28 #include <binder/MemoryHeapPmem.h> 29 #if 0 30 #include <binder/MemoryHeapIon.h> 31 #endif 32 #include <camera/Camera.h> 33 #include <hardware/camera.h> 34 #include <utils/String16.h> 35 #include <sys/types.h> 36 #include <sys/stat.h> 37 #include <unistd.h> 38 #include <fcntl.h> 39 #include <cutils/properties.h> 40 #include <math.h> 41 #if HAVE_ANDROID_OS 42 #include <linux/android_pmem.h> 43 #endif 44 #include <linux/ioctl.h> 45 #include "QCameraParameters.h" 46 #include <media/mediarecorder.h> 47 #include <gralloc_priv.h> 48 #include <genlock.h> 49 50 #include "linux/msm_mdp.h" 51 #include <linux/fb.h> 52 #define LIKELY(exp) __builtin_expect(!!(exp), 1) 53 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0) 54 #define CAMERA_HAL_UNUSED(expr) do { (void)(expr); } while (0) 55 56 extern "C" { 57 #include <fcntl.h> 58 #include <time.h> 59 #include <pthread.h> 60 #include <stdio.h> 61 #include <string.h> 62 #include <unistd.h> 63 #include <termios.h> 64 #include <assert.h> 65 #include <stdlib.h> 66 #include <ctype.h> 67 #include <signal.h> 68 #include <errno.h> 69 #include <sys/mman.h> 70 #include <sys/system_properties.h> 71 #include <sys/time.h> 72 #include <stdlib.h> 73 74 75 #include <camera.h> 76 #include <cam_fifo.h> 77 #include <liveshot.h> 78 #include <jpege.h> 79 #include <jpeg_encoder.h> 80 81 #define DUMP_LIVESHOT_JPEG_FILE 0 82 83 #define DEFAULT_PICTURE_WIDTH 640 84 #define DEFAULT_PICTURE_HEIGHT 480 85 #define DEFAULT_PICTURE_WIDTH_3D 1920 86 #define DEFAULT_PICTURE_HEIGHT_3D 1080 87 #define INITIAL_PREVIEW_HEIGHT 144 88 #define INITIAL_PREVIEW_WIDTH 176 89 90 #define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2) 91 #define MAX_ZOOM_LEVEL 5 92 #define NOT_FOUND -1 93 // Number of video buffers held by kernal (initially 1,2 &3) 94 #define ACTIVE_VIDEO_BUFFERS 3 95 #define ACTIVE_PREVIEW_BUFFERS 3 96 #define ACTIVE_ZSL_BUFFERS 3 97 #define APP_ORIENTATION 90 98 #define HDR_HAL_FRAME 2 99 100 #define FLASH_AUTO 24 101 #define FLASH_SNAP 32 102 103 #define DUMMY_CAMERA_STARTED 1; 104 #define DUMMY_CAMERA_STOPPED 0; 105 #define FLOOR16(X) ((X) & 0xFFF0) 106 #if DLOPEN_LIBMMCAMERA 107 #include <dlfcn.h> 108 109 110 // Conversion routines from YV420sp to YV12 format 111 int (*LINK_yuv_convert_ycrcb420sp_to_yv12_inplace) (yuv_image_type* yuvStructPtr); 112 int (*LINK_yuv_convert_ycrcb420sp_to_yv12) (yuv_image_type* yuvStructPtrin, yuv_image_type* yuvStructPtrout); 113 #define NUM_YV12_FRAMES 1 114 #define FOCUS_AREA_INIT "(-1000,-1000,1000,1000,1000)" 115 116 void *libmmcamera; 117 void* (*LINK_cam_conf)(void *data); 118 void* (*LINK_cam_frame)(void *data); 119 void* (*LINK_wait_cam_frame_thread_ready)(void); 120 void* (*LINK_cam_frame_set_exit_flag)(int flag); 121 bool (*LINK_jpeg_encoder_init)(); 122 void (*LINK_jpeg_encoder_join)(); 123 bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen, 124 const uint8_t *thumbnailbuf, int thumbnailfd, 125 const uint8_t *snapshotbuf, int snapshotfd, 126 common_crop_t *scaling_parms, exif_tags_info_t *exif_data, 127 int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset,int zsl_enable); 128 void (*LINK_camframe_terminate)(void); 129 //for 720p 130 // Function pointer , called by camframe when a video frame is available. 131 void (**LINK_camframe_video_callback)(struct msm_frame * frame); 132 // Function to add a frame to free Q 133 void (*LINK_camframe_add_frame)(cam_frame_type_t type,struct msm_frame *frame); 134 135 void (*LINK_camframe_release_all_frames)(cam_frame_type_t type); 136 137 int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality); 138 int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality); 139 int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation); 140 int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height, 141 uint32_t* p_y_offset, 142 uint32_t* p_cbcr_offset, 143 uint32_t* p_buf_size); 144 int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location); 145 void (*LINK_jpeg_encoder_set_3D_info)(cam_3d_frame_format_t format); 146 const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len); 147 int (*LINK_launch_cam_conf_thread)(void); 148 int (*LINK_release_cam_conf_thread)(void); 149 mm_camera_status_t (*LINK_mm_camera_init)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*,uint8_t); 150 mm_camera_status_t (*LINK_mm_camera_deinit)(); 151 mm_camera_status_t (*LINK_mm_camera_destroy)(); 152 mm_camera_status_t (*LINK_mm_camera_exec)(); 153 mm_camera_status_t (*LINK_mm_camera_get_camera_info) (qcamera_info_t* p_cam_info, int* p_num_cameras); 154 155 int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height, 156 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf); 157 158 // callbacks 159 void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop); 160 void (**LINK_cancel_liveshot)(void); 161 int8_t (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data, 162 int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size); 163 void (*LINK_set_liveshot_frame)(struct msm_frame *liveshot_frame); 164 #else 165 #define LINK_cam_conf cam_conf 166 #define LINK_cam_frame cam_frame 167 #define LINK_wait_cam_frame_thread_ready wait_cam_frame_thread_ready 168 #define LINK_cam_frame cam_frame_set_exit_flag 169 #define LINK_jpeg_encoder_init jpeg_encoder_init 170 #define LINK_jpeg_encoder_join jpeg_encoder_join 171 #define LINK_jpeg_encoder_encode jpeg_encoder_encode 172 #define LINK_camframe_terminate camframe_terminate 173 #define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality 174 #define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality 175 #define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation 176 #define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset 177 #define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation 178 #define LINK_jpeg_encoder_set_3D_info jpeg_encoder_set_3D_info 179 #define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes 180 #define LINK_launch_cam_conf_thread launch_cam_conf_thread 181 #define LINK_release_cam_conf_thread release_cam_conf_thread 182 #define LINK_zoom_crop_upscale zoom_crop_upscale 183 #define LINK_mm_camera_init mm_camera_config_init 184 #define LINK_mm_camera_deinit mm_camera_config_deinit 185 #define LINK_mm_camera_destroy mm_camera_config_destroy 186 #define LINK_mm_camera_exec mm_camera_exec 187 #define LINK_camframe_add_frame camframe_add_frame 188 #define LINK_camframe_release_all_frames camframe_release_all_frames 189 #define LINK_mm_camera_get_camera_info mm_camera_get_camera_info 190 191 extern void (*mmcamera_camframe_callback)(struct msm_frame *frame); 192 extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo); 193 extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr, 194 uint32_t buff_size); 195 extern void (*mmcamera_jpeg_callback)(jpeg_event_t status); 196 extern void (*mmcamera_shutter_callback)(common_crop_t *crop); 197 extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size); 198 #define LINK_set_liveshot_params set_liveshot_params 199 #define LINK_set_liveshot_frame set_liveshot_frame 200 #endif 201 202 } // extern "C" 203 204 #ifndef HAVE_CAMERA_SIZE_TYPE 205 struct camera_size_type { 206 int width; 207 int height; 208 }; 209 #endif 210 #if 0 211 typedef struct crop_info_struct { 212 int32_t x; 213 int32_t y; 214 int32_t w; 215 int32_t h; 216 } zoom_crop_info; 217 #endif 218 union zoomimage 219 { 220 char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1]; 221 struct mdp_blit_req_list list; 222 } zoomImage; 223 224 //Default to VGA 225 #define DEFAULT_PREVIEW_WIDTH 640 226 #define DEFAULT_PREVIEW_HEIGHT 480 227 #define DEFAULT_PREVIEW_WIDTH_3D 1280 228 #define DEFAULT_PREVIEW_HEIGHT_3D 720 229 230 //Default FPS 231 #define MINIMUM_FPS 5 232 #define MAXIMUM_FPS 31 233 #define DEFAULT_FPS MAXIMUM_FPS 234 #define DEFAULT_FIXED_FPS_VALUE 30 235 /* 236 * Modifying preview size requires modification 237 * in bitmasks for boardproperties 238 */ 239 static uint32_t PREVIEW_SIZE_COUNT; 240 static uint32_t HFR_SIZE_COUNT; 241 242 board_property boardProperties[] = { 243 {TARGET_MSM7625, 0x00000fff, false, false, false}, 244 {TARGET_MSM7625A, 0x00000fff, false, false, false}, 245 {TARGET_MSM7627, 0x000006ff, false, false, false}, 246 {TARGET_MSM7627A, 0x000006ff, false, false, false}, 247 {TARGET_MSM7630, 0x00000fff, true, true, false}, 248 {TARGET_MSM8660, 0x00001fff, true, true, false}, 249 {TARGET_QSD8250, 0x00000fff, false, false, false} 250 }; 251 252 //static const camera_size_type* picture_sizes; 253 //static int PICTURE_SIZE_COUNT; 254 /* TODO 255 * Ideally this should be a populated by lower layers. 256 * But currently this is no API to do that at lower layer. 257 * Hence populating with default sizes for now. This needs 258 * to be changed once the API is supported. 259 */ 260 //sorted on column basis 261 static struct camera_size_type zsl_picture_sizes[] = { 262 { 1024, 768}, // 1MP XGA 263 { 800, 600}, //SVGA 264 { 800, 480}, // WVGA 265 { 640, 480}, // VGA 266 { 352, 288}, //CIF 267 { 320, 240}, // QVGA 268 { 176, 144} // QCIF 269 }; 270 271 static struct camera_size_type for_3D_picture_sizes[] = { 272 { 1920, 1080}, 273 }; 274 275 static int data_counter = 0; 276 static int sensor_rotation = 0; 277 static int record_flag = 0; 278 static camera_size_type* picture_sizes; 279 static camera_size_type* preview_sizes; 280 static camera_size_type* hfr_sizes; 281 static unsigned int PICTURE_SIZE_COUNT; 282 static const camera_size_type * picture_sizes_ptr; 283 static int supportedPictureSizesCount; 284 static liveshotState liveshot_state = LIVESHOT_DONE; 285 286 #ifdef Q12 287 #undef Q12 288 #endif 289 290 #define Q12 4096 291 292 static const target_map targetList [] = { 293 { "msm7625", TARGET_MSM7625 }, 294 { "msm7625a", TARGET_MSM7625A }, 295 { "msm7627", TARGET_MSM7627 }, 296 { "msm7627a", TARGET_MSM7627A }, 297 { "qsd8250", TARGET_QSD8250 }, 298 { "msm7630", TARGET_MSM7630 }, 299 { "msm8660", TARGET_MSM8660 } 300 301 }; 302 static targetType mCurrentTarget = TARGET_MAX; 303 304 typedef struct { 305 uint32_t aspect_ratio; 306 uint32_t width; 307 uint32_t height; 308 } thumbnail_size_type; 309 310 static thumbnail_size_type thumbnail_sizes[] = { 311 { 7281, 512, 288 }, //1.777778 312 { 6826, 480, 288 }, //1.666667 313 { 6808, 256, 154 }, //1.662337 314 { 6144, 432, 288 }, //1.5 315 { 5461, 512, 384 }, //1.333333 316 { 5006, 352, 288 }, //1.222222 317 }; 318 #define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type)) 319 #define DEFAULT_THUMBNAIL_SETTING 4 320 #define THUMBNAIL_WIDTH_STR "512" 321 #define THUMBNAIL_HEIGHT_STR "384" 322 #define THUMBNAIL_SMALL_HEIGHT 144 323 static camera_size_type jpeg_thumbnail_sizes[] = { 324 { 512, 288 }, 325 { 480, 288 }, 326 { 432, 288 }, 327 { 512, 384 }, 328 { 352, 288 }, 329 {0,0} 330 }; 331 //supported preview fps ranges should be added to this array in the form (minFps,maxFps) 332 static android::FPSRange FpsRangesSupported[] = {{MINIMUM_FPS*1000,MAXIMUM_FPS*1000}}; 333 334 #define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0])) 335 336 #define JPEG_THUMBNAIL_SIZE_COUNT (sizeof(jpeg_thumbnail_sizes)/sizeof(camera_size_type)) 337 static int attr_lookup(const str_map arr[], int len, const char *name) 338 { 339 if (name) { 340 for (int i = 0; i < len; i++) { 341 if (!strcmp(arr[i].desc, name)) 342 return arr[i].val; 343 } 344 } 345 return NOT_FOUND; 346 } 347 348 // round to the next power of two 349 static inline unsigned clp2(unsigned x) 350 { 351 x = x - 1; 352 x = x | (x >> 1); 353 x = x | (x >> 2); 354 x = x | (x >> 4); 355 x = x | (x >> 8); 356 x = x | (x >>16); 357 return x + 1; 358 } 359 360 static int exif_table_numEntries = 0; 361 #define MAX_EXIF_TABLE_ENTRIES 14 362 exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES]; 363 //static zoom_crop_info zoomCropInfo; 364 static android_native_rect_t zoomCropInfo; 365 static void *mLastQueuedFrame = NULL; 366 #define RECORD_BUFFERS 9 367 #define RECORD_BUFFERS_8x50 8 368 static int kRecordBufferCount; 369 /* controls whether VPE is avialable for the target 370 * under consideration. 371 * 1: VPE support is available 372 * 0: VPE support is not available (default) 373 */ 374 static bool mVpeEnabled; 375 static cam_frame_start_parms camframeParams; 376 377 static int HAL_numOfCameras; 378 static qcamera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS]; 379 static int HAL_currentCameraId; 380 static int HAL_currentCameraMode; 381 static mm_camera_config mCfgControl; 382 static bool mCameraOpen; 383 384 static int HAL_currentSnapshotMode; 385 static int previewWidthToNativeZoom; 386 static int previewHeightToNativeZoom; 387 #define CAMERA_SNAPSHOT_NONZSL 0x04 388 #define CAMERA_SNAPSHOT_ZSL 0x08 389 390 namespace android { 391 extern void native_send_data_callback(int32_t msgType, 392 camera_memory_t * framebuffer, 393 void* user); 394 395 extern camera_memory_t* get_mem(int fd,size_t buf_size, 396 unsigned int num_bufs, 397 void *user); 398 399 static const int PICTURE_FORMAT_JPEG = 1; 400 static const int PICTURE_FORMAT_RAW = 2; 401 402 // from aeecamera.h 403 static const str_map whitebalance[] = { 404 { QCameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO }, 405 { QCameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT }, 406 { QCameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT }, 407 { QCameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT }, 408 { QCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT } 409 }; 410 411 // from camera_effect_t. This list must match aeecamera.h 412 static const str_map effects[] = { 413 { QCameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF }, 414 { QCameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO }, 415 { QCameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE }, 416 { QCameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE }, 417 { QCameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA }, 418 { QCameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE }, 419 { QCameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD }, 420 { QCameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD }, 421 { QCameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA } 422 }; 423 424 // from qcamera/common/camera.h 425 static const str_map autoexposure[] = { 426 { QCameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE }, 427 { QCameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED }, 428 { QCameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING } 429 }; 430 431 // from qcamera/common/camera.h 432 static const str_map antibanding[] = { 433 { QCameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF }, 434 { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ }, 435 { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ }, 436 { QCameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO } 437 }; 438 439 static const str_map antibanding_3D[] = { 440 { QCameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF }, 441 { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ }, 442 { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ } 443 }; 444 445 /* Mapping from MCC to antibanding type */ 446 struct country_map { 447 uint32_t country_code; 448 camera_antibanding_type type; 449 }; 450 451 #if 0 //not using this function. keeping this as this came from Google. 452 static struct country_map country_numeric[] = { 453 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece 454 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands 455 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium 456 { 208, CAMERA_ANTIBANDING_50HZ }, // France 457 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco 458 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra 459 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain 460 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary 461 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia 462 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia 463 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy 464 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania 465 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland 466 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic 467 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia 468 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria 469 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom 470 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom 471 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark 472 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden 473 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway 474 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland 475 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania 476 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia 477 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia 478 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation 479 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine 480 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus 481 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova 482 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland 483 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany 484 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar 485 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal 486 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg 487 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland 488 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland 489 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania 490 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta 491 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus 492 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia 493 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia 494 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria 495 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey 496 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands 497 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland 498 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia 499 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia 500 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein 501 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro 502 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada 503 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America 504 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America 505 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America 506 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America 507 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America 508 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America 509 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America 510 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico 511 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico 512 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica 513 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique 514 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados 515 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands 516 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda 517 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada 518 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat 519 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles 520 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba 521 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas 522 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla 523 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica 524 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba 525 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic 526 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti 527 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan 528 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan 529 { 404, CAMERA_ANTIBANDING_50HZ }, // India 530 { 405, CAMERA_ANTIBANDING_50HZ }, // India 531 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan 532 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka 533 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar 534 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon 535 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan 536 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria 537 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq 538 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait 539 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia 540 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen 541 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman 542 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates 543 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel 544 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain 545 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar 546 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia 547 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal 548 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates 549 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates 550 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran 551 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan 552 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan 553 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep 554 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan 555 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan 556 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan 557 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam 558 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong 559 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao 560 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia 561 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos 562 { 460, CAMERA_ANTIBANDING_50HZ }, // China 563 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan 564 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh 565 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives 566 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia 567 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia 568 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia 569 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor 570 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines 571 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand 572 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore 573 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand 574 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam 575 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru 576 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea 577 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga 578 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu 579 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji 580 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa 581 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati 582 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia 583 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands 584 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt 585 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria 586 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco 587 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia 588 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya 589 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia 590 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal 591 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania 592 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali 593 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea 594 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso 595 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger 596 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin 597 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius 598 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia 599 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone 600 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana 601 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria 602 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad 603 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic 604 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon 605 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde 606 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea 607 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola 608 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles 609 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan 610 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia 611 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia 612 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti 613 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya 614 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania 615 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda 616 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi 617 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique 618 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia 619 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar 620 { 647, CAMERA_ANTIBANDING_50HZ }, // France 621 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe 622 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia 623 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi 624 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho 625 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana 626 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland 627 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros 628 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa 629 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea 630 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize 631 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala 632 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador 633 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras 634 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua 635 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica 636 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama 637 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina 638 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil 639 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile 640 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia 641 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela 642 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia 643 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana 644 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador 645 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana 646 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay 647 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname 648 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay 649 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands 650 }; 651 #define country_number (sizeof(country_numeric) / sizeof(country_map)) 652 /* Look up pre-sorted antibanding_type table by current MCC. */ 653 static camera_antibanding_type camera_get_location(void) { 654 char value[PROP_VALUE_MAX]; 655 char country_value[PROP_VALUE_MAX]; 656 uint32_t country_code; 657 memset(value, 0x00, sizeof(value)); 658 memset(country_value, 0x00, sizeof(country_value)); 659 if (!__system_property_get("gsm.operator.numeric", value)) { 660 return CAMERA_ANTIBANDING_60HZ; 661 } 662 memcpy(country_value, value, 3); 663 country_code = atoi(country_value); 664 ALOGD("value:%s, country value:%s, country code:%d\n", 665 value, country_value, country_code); 666 int left = 0; 667 int right = country_number - 1; 668 while (left <= right) { 669 int index = (left + right) >> 1; 670 if (country_numeric[index].country_code == country_code) 671 return country_numeric[index].type; 672 else if (country_numeric[index].country_code > country_code) 673 right = index - 1; 674 else 675 left = index + 1; 676 } 677 return CAMERA_ANTIBANDING_60HZ; 678 } 679 #endif 680 681 static const str_map scenemode[] = { 682 { QCameraParameters::SCENE_MODE_AUTO, CAMERA_BESTSHOT_OFF }, 683 { QCameraParameters::SCENE_MODE_ASD, CAMERA_BESTSHOT_AUTO }, 684 { QCameraParameters::SCENE_MODE_ACTION, CAMERA_BESTSHOT_ACTION }, 685 { QCameraParameters::SCENE_MODE_PORTRAIT, CAMERA_BESTSHOT_PORTRAIT }, 686 { QCameraParameters::SCENE_MODE_LANDSCAPE, CAMERA_BESTSHOT_LANDSCAPE }, 687 { QCameraParameters::SCENE_MODE_NIGHT, CAMERA_BESTSHOT_NIGHT }, 688 { QCameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT }, 689 { QCameraParameters::SCENE_MODE_THEATRE, CAMERA_BESTSHOT_THEATRE }, 690 { QCameraParameters::SCENE_MODE_BEACH, CAMERA_BESTSHOT_BEACH }, 691 { QCameraParameters::SCENE_MODE_SNOW, CAMERA_BESTSHOT_SNOW }, 692 { QCameraParameters::SCENE_MODE_SUNSET, CAMERA_BESTSHOT_SUNSET }, 693 { QCameraParameters::SCENE_MODE_STEADYPHOTO, CAMERA_BESTSHOT_ANTISHAKE }, 694 { QCameraParameters::SCENE_MODE_FIREWORKS , CAMERA_BESTSHOT_FIREWORKS }, 695 { QCameraParameters::SCENE_MODE_SPORTS , CAMERA_BESTSHOT_SPORTS }, 696 { QCameraParameters::SCENE_MODE_PARTY, CAMERA_BESTSHOT_PARTY }, 697 { QCameraParameters::SCENE_MODE_CANDLELIGHT, CAMERA_BESTSHOT_CANDLELIGHT }, 698 { QCameraParameters::SCENE_MODE_BACKLIGHT, CAMERA_BESTSHOT_BACKLIGHT }, 699 { QCameraParameters::SCENE_MODE_FLOWERS, CAMERA_BESTSHOT_FLOWERS }, 700 { QCameraParameters::SCENE_MODE_AR, CAMERA_BESTSHOT_AR }, 701 }; 702 703 static const str_map scenedetect[] = { 704 { QCameraParameters::SCENE_DETECT_OFF, FALSE }, 705 { QCameraParameters::SCENE_DETECT_ON, TRUE }, 706 }; 707 708 // from camera.h, led_mode_t 709 static const str_map flash[] = { 710 { QCameraParameters::FLASH_MODE_OFF, LED_MODE_OFF }, 711 { QCameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO }, 712 { QCameraParameters::FLASH_MODE_ON, LED_MODE_ON }, 713 { QCameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH} 714 }; 715 716 // from mm-camera/common/camera.h. 717 static const str_map iso[] = { 718 { QCameraParameters::ISO_AUTO, CAMERA_ISO_AUTO}, 719 { QCameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR}, 720 { QCameraParameters::ISO_100, CAMERA_ISO_100}, 721 { QCameraParameters::ISO_200, CAMERA_ISO_200}, 722 { QCameraParameters::ISO_400, CAMERA_ISO_400}, 723 { QCameraParameters::ISO_800, CAMERA_ISO_800 }, 724 { QCameraParameters::ISO_1600, CAMERA_ISO_1600 } 725 }; 726 727 static const str_map iso_3D[] = { 728 { QCameraParameters::ISO_AUTO, CAMERA_ISO_AUTO}, 729 { QCameraParameters::ISO_100, CAMERA_ISO_100}, 730 { QCameraParameters::ISO_200, CAMERA_ISO_200}, 731 { QCameraParameters::ISO_400, CAMERA_ISO_400}, 732 { QCameraParameters::ISO_800, CAMERA_ISO_800 }, 733 { QCameraParameters::ISO_1600, CAMERA_ISO_1600 } 734 }; 735 736 737 #define DONT_CARE AF_MODE_MAX 738 static const str_map focus_modes[] = { 739 { QCameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO}, 740 { QCameraParameters::FOCUS_MODE_INFINITY, DONT_CARE }, 741 { QCameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL }, 742 { QCameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }, 743 { QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, AF_MODE_CAF }, 744 { QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, DONT_CARE } 745 }; 746 747 static const str_map lensshade[] = { 748 { QCameraParameters::LENSSHADE_ENABLE, TRUE }, 749 { QCameraParameters::LENSSHADE_DISABLE, FALSE } 750 }; 751 752 static const str_map hfr[] = { 753 { QCameraParameters::VIDEO_HFR_OFF, CAMERA_HFR_MODE_OFF }, 754 { QCameraParameters::VIDEO_HFR_2X, CAMERA_HFR_MODE_60FPS }, 755 { QCameraParameters::VIDEO_HFR_3X, CAMERA_HFR_MODE_90FPS }, 756 { QCameraParameters::VIDEO_HFR_4X, CAMERA_HFR_MODE_120FPS }, 757 }; 758 759 static const str_map mce[] = { 760 { QCameraParameters::MCE_ENABLE, TRUE }, 761 { QCameraParameters::MCE_DISABLE, FALSE } 762 }; 763 764 static const str_map hdr[] = { 765 { QCameraParameters::HDR_ENABLE, TRUE }, 766 { QCameraParameters::HDR_DISABLE, FALSE } 767 }; 768 769 static const str_map histogram[] = { 770 { QCameraParameters::HISTOGRAM_ENABLE, TRUE }, 771 { QCameraParameters::HISTOGRAM_DISABLE, FALSE } 772 }; 773 774 static const str_map skinToneEnhancement[] = { 775 { QCameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, TRUE }, 776 { QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, FALSE } 777 }; 778 779 static const str_map denoise[] = { 780 { QCameraParameters::DENOISE_OFF, FALSE }, 781 { QCameraParameters::DENOISE_ON, TRUE } 782 }; 783 784 static const str_map selectable_zone_af[] = { 785 { QCameraParameters::SELECTABLE_ZONE_AF_AUTO, AUTO }, 786 { QCameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT }, 787 { QCameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED }, 788 { QCameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE } 789 }; 790 791 static const str_map facedetection[] = { 792 { QCameraParameters::FACE_DETECTION_OFF, FALSE }, 793 { QCameraParameters::FACE_DETECTION_ON, TRUE } 794 }; 795 796 #define DONT_CARE_COORDINATE -1 797 static const str_map touchafaec[] = { 798 { QCameraParameters::TOUCH_AF_AEC_OFF, FALSE }, 799 { QCameraParameters::TOUCH_AF_AEC_ON, TRUE } 800 }; 801 802 static const str_map redeye_reduction[] = { 803 { QCameraParameters::REDEYE_REDUCTION_ENABLE, TRUE }, 804 { QCameraParameters::REDEYE_REDUCTION_DISABLE, FALSE } 805 }; 806 807 static const str_map zsl_modes[] = { 808 { QCameraParameters::ZSL_OFF, FALSE }, 809 { QCameraParameters::ZSL_ON, TRUE }, 810 }; 811 812 /* 813 * Values based on aec.c 814 */ 815 #define DONT_CARE_COORDINATE -1 816 #define CAMERA_HISTOGRAM_ENABLE 1 817 #define CAMERA_HISTOGRAM_DISABLE 0 818 #define HISTOGRAM_STATS_SIZE 257 819 820 /* 821 * Values based on aec.c 822 */ 823 #define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12 824 #define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12 825 #define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0 826 #define EXPOSURE_COMPENSATION_DENOMINATOR 6 827 #define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR) 828 829 static const str_map picture_formats[] = { 830 {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG}, 831 {QCameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW} 832 }; 833 834 static const str_map recording_Hints[] = { 835 {"false", FALSE}, 836 {"true", TRUE} 837 }; 838 839 static const str_map picture_formats_zsl[] = { 840 {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG} 841 }; 842 843 static const str_map frame_rate_modes[] = { 844 {QCameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO}, 845 {QCameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED} 846 }; 847 848 static int mPreviewFormat; 849 static const str_map preview_formats[] = { 850 {QCameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21}, 851 {QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO}, 852 {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12} 853 }; 854 static const str_map preview_formats1[] = { 855 {QCameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21}, 856 {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12} 857 }; 858 859 static const str_map app_preview_formats[] = { 860 {QCameraParameters::PIXEL_FORMAT_YUV420SP, HAL_PIXEL_FORMAT_YCrCb_420_SP}, //nv21 861 //{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO}, //nv21_adreno 862 {QCameraParameters::PIXEL_FORMAT_YUV420P, HAL_PIXEL_FORMAT_YV12}, //YV12 863 }; 864 865 866 static bool parameter_string_initialized = false; 867 static String8 preview_size_values; 868 static String8 hfr_size_values; 869 static String8 picture_size_values; 870 static String8 fps_ranges_supported_values; 871 static String8 jpeg_thumbnail_size_values; 872 static String8 antibanding_values; 873 static String8 effect_values; 874 static String8 autoexposure_values; 875 static String8 whitebalance_values; 876 static String8 flash_values; 877 static String8 focus_mode_values; 878 static String8 iso_values; 879 static String8 lensshade_values; 880 static String8 mce_values; 881 static String8 hdr_values; 882 static String8 histogram_values; 883 static String8 skinToneEnhancement_values; 884 static String8 touchafaec_values; 885 static String8 picture_format_values; 886 static String8 scenemode_values; 887 static String8 denoise_values; 888 static String8 zoom_ratio_values; 889 static String8 preview_frame_rate_values; 890 static String8 frame_rate_mode_values; 891 static String8 scenedetect_values; 892 static String8 preview_format_values; 893 static String8 selectable_zone_af_values; 894 static String8 facedetection_values; 895 static String8 hfr_values; 896 static String8 redeye_reduction_values; 897 static String8 zsl_values; 898 899 mm_camera_notify mCamNotify; 900 mm_camera_ops mCamOps; 901 static mm_camera_buffer_t mEncodeOutputBuffer[MAX_SNAPSHOT_BUFFERS]; 902 static encode_params_t mImageEncodeParms; 903 static capture_params_t mImageCaptureParms; 904 static raw_capture_params_t mRawCaptureParms; 905 static zsl_capture_params_t mZslCaptureParms; 906 static zsl_params_t mZslParms; 907 static yv12_format_parms_t myv12_params; 908 909 static String8 create_sizes_str(const camera_size_type *sizes, int len) { 910 String8 str; 911 char buffer[32]; 912 913 if (len > 0) { 914 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height); 915 str.append(buffer); 916 } 917 for (int i = 1; i < len; i++) { 918 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height); 919 str.append(buffer); 920 } 921 return str; 922 } 923 924 static String8 create_fps_str(const android:: FPSRange* fps, int len) { 925 String8 str; 926 char buffer[32]; 927 928 if (len > 0) { 929 sprintf(buffer, "(%d,%d)", fps[0].minFPS, fps[0].maxFPS); 930 str.append(buffer); 931 } 932 for (int i = 1; i < len; i++) { 933 sprintf(buffer, ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS); 934 str.append(buffer); 935 } 936 return str; 937 } 938 939 static String8 create_values_str(const str_map *values, int len) { 940 String8 str; 941 942 if (len > 0) { 943 str.append(values[0].desc); 944 } 945 for (int i = 1; i < len; i++) { 946 str.append(","); 947 str.append(values[i].desc); 948 } 949 return str; 950 } 951 952 953 static String8 create_str(int16_t *arr, int length){ 954 String8 str; 955 char buffer[32]; 956 957 if(length > 0){ 958 snprintf(buffer, sizeof(buffer), "%d", arr[0]); 959 str.append(buffer); 960 } 961 962 for (int i =1;i<length;i++){ 963 snprintf(buffer, sizeof(buffer), ",%d",arr[i]); 964 str.append(buffer); 965 } 966 return str; 967 } 968 969 static String8 create_values_range_str(int min, int max){ 970 String8 str; 971 char buffer[32]; 972 973 if(min <= max){ 974 snprintf(buffer, sizeof(buffer), "%d", min); 975 str.append(buffer); 976 977 for (int i = min + 1; i <= max; i++) { 978 snprintf(buffer, sizeof(buffer), ",%d", i); 979 str.append(buffer); 980 } 981 } 982 return str; 983 } 984 985 extern "C" { 986 //------------------------------------------------------------------------ 987 // : 720p busyQ funcitons 988 // -------------------------------------------------------------------- 989 static struct fifo_queue g_busy_frame_queue = 990 {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, (char *)"video_busy_q"}; 991 }; 992 993 static void cam_frame_wait_video (void) 994 { 995 ALOGV("cam_frame_wait_video E "); 996 if ((g_busy_frame_queue.num_of_frames) <=0){ 997 pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut)); 998 } 999 ALOGV("cam_frame_wait_video X"); 1000 return; 1001 } 1002 1003 void cam_frame_flush_video (void) 1004 { 1005 ALOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames); 1006 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 1007 1008 while (g_busy_frame_queue.front) 1009 { 1010 //dequeue from the busy queue 1011 struct fifo_node *node = dequeue (&g_busy_frame_queue); 1012 if(node) 1013 free(node); 1014 1015 ALOGV("cam_frame_flush_video: node \n"); 1016 } 1017 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 1018 ALOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames); 1019 return ; 1020 } 1021 1022 static struct msm_frame * cam_frame_get_video() 1023 { 1024 struct msm_frame *p = NULL; 1025 ALOGV("cam_frame_get_video... in\n"); 1026 ALOGV("cam_frame_get_video... got lock\n"); 1027 if (g_busy_frame_queue.front) 1028 { 1029 //dequeue 1030 struct fifo_node *node = dequeue (&g_busy_frame_queue); 1031 if (node) 1032 { 1033 p = (struct msm_frame *)node->f; 1034 free (node); 1035 } 1036 ALOGV("cam_frame_get_video... out = %x\n", p->buffer); 1037 } 1038 return p; 1039 } 1040 1041 // Parse string like "(1, 2, 3, 4, ..., N)" 1042 // num is pointer to an allocated array of size N 1043 static int parseNDimVector_HAL(const char *str, int *num, int N, char delim = ',') 1044 { 1045 char *start, *end; 1046 if(num == NULL) { 1047 ALOGE("Invalid output array (num == NULL)"); 1048 return -1; 1049 } 1050 //check if string starts and ends with parantheses 1051 if(str[0] != '(' || str[strlen(str)-1] != ')') { 1052 ALOGE("Invalid format of string %s, valid format is (n1, n2, n3, n4 ...)", str); 1053 return -1; 1054 } 1055 start = (char*) str; 1056 start++; 1057 for(int i=0; i<N; i++) { 1058 *(num+i) = (int) strtol(start, &end, 10); 1059 if(*end != delim && i < N-1) { 1060 ALOGE("Cannot find delimeter '%c' in string \"%s\". end = %c", delim, str, *end); 1061 return -1; 1062 } 1063 start = end+1; 1064 } 1065 return 0; 1066 } 1067 static int countChar(const char *str , char ch ) 1068 { 1069 int noOfChar = 0; 1070 1071 for ( int i = 0; str[i] != '\0'; i++) { 1072 if ( str[i] == ch ) 1073 noOfChar = noOfChar + 1; 1074 } 1075 1076 return noOfChar; 1077 } 1078 int checkAreaParameters(const char *str) 1079 { 1080 int areaValues[6]; 1081 int left, right, top, bottom, weight; 1082 1083 if(countChar(str, ',') > 4) { 1084 ALOGE("%s: No of area parameters exceeding the expected number %s", __FUNCTION__, str); 1085 return -1; 1086 } 1087 1088 if(parseNDimVector_HAL(str, areaValues, 5) !=0) { 1089 ALOGE("%s: Failed to parse the input string %s", __FUNCTION__, str); 1090 return -1; 1091 } 1092 1093 ALOGV("%s: Area values are %d,%d,%d,%d,%d", __FUNCTION__, 1094 areaValues[0], areaValues[1], areaValues[2], areaValues[3], areaValues[4]); 1095 1096 left = areaValues[0]; 1097 top = areaValues[1]; 1098 right = areaValues[2]; 1099 bottom = areaValues[3]; 1100 weight = areaValues[4]; 1101 1102 // left should >= -1000 1103 if (!(left >= -1000)) 1104 return -1; 1105 // top should >= -1000 1106 if(!(top >= -1000)) 1107 return -1; 1108 // right should <= 1000 1109 if(!(right <= 1000)) 1110 return -1; 1111 // bottom should <= 1000 1112 if(!(bottom <= 1000)) 1113 return -1; 1114 // weight should >= 1 1115 // weight should <= 1000 1116 if(!((1 <= weight) && (weight <= 1000))) 1117 return -1; 1118 // left should < right 1119 if(!(left < right)) 1120 return -1; 1121 // top should < bottom 1122 if(!(top < bottom)) 1123 return -1; 1124 1125 return 0; 1126 } 1127 1128 static void cam_frame_post_video (struct msm_frame *p) 1129 { 1130 if (!p) 1131 { 1132 ALOGE("post video , buffer is null"); 1133 return; 1134 } 1135 ALOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer)); 1136 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 1137 ALOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames); 1138 //enqueue to busy queue 1139 struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node)); 1140 if (node) 1141 { 1142 ALOGV(" post video , enqueing in busy queue"); 1143 node->f = p; 1144 node->next = NULL; 1145 enqueue (&g_busy_frame_queue, node); 1146 ALOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames); 1147 } 1148 else 1149 { 1150 ALOGE("cam_frame_post_video error... out of memory\n"); 1151 } 1152 1153 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 1154 pthread_cond_signal(&(g_busy_frame_queue.wait)); 1155 1156 ALOGV("cam_frame_post_video... out = %x\n", p->buffer); 1157 1158 return; 1159 } 1160 1161 QualcommCameraHardware::FrameQueue::FrameQueue(){ 1162 mInitialized = false; 1163 } 1164 1165 QualcommCameraHardware::FrameQueue::~FrameQueue(){ 1166 flush(); 1167 } 1168 1169 void QualcommCameraHardware::FrameQueue::init(){ 1170 Mutex::Autolock l(&mQueueLock); 1171 mInitialized = true; 1172 mQueueWait.signal(); 1173 } 1174 1175 void QualcommCameraHardware::FrameQueue::deinit(){ 1176 Mutex::Autolock l(&mQueueLock); 1177 mInitialized = false; 1178 mQueueWait.signal(); 1179 } 1180 1181 bool QualcommCameraHardware::FrameQueue::isInitialized(){ 1182 Mutex::Autolock l(&mQueueLock); 1183 return mInitialized; 1184 } 1185 1186 bool QualcommCameraHardware::FrameQueue::add( 1187 struct msm_frame * element){ 1188 Mutex::Autolock l(&mQueueLock); 1189 if(mInitialized == false) 1190 return false; 1191 1192 mContainer.add(element); 1193 mQueueWait.signal(); 1194 return true; 1195 } 1196 1197 struct msm_frame * QualcommCameraHardware::FrameQueue::get(){ 1198 1199 struct msm_frame *frame; 1200 mQueueLock.lock(); 1201 while(mInitialized && mContainer.isEmpty()){ 1202 mQueueWait.wait(mQueueLock); 1203 } 1204 1205 if(!mInitialized){ 1206 mQueueLock.unlock(); 1207 return NULL; 1208 } 1209 1210 frame = mContainer.itemAt(0); 1211 mContainer.removeAt(0); 1212 mQueueLock.unlock(); 1213 return frame; 1214 } 1215 1216 void QualcommCameraHardware::FrameQueue::flush(){ 1217 Mutex::Autolock l(&mQueueLock); 1218 mContainer.clear(); 1219 1220 } 1221 1222 1223 void QualcommCameraHardware::storeTargetType(void) { 1224 char mDeviceName[PROPERTY_VALUE_MAX]; 1225 property_get("ro.product.device",mDeviceName," "); 1226 mCurrentTarget = TARGET_MAX; 1227 for( int i = 0; i < TARGET_MAX ; i++) { 1228 if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) { 1229 mCurrentTarget = targetList[i].targetEnum; 1230 if(mCurrentTarget == TARGET_MSM7625) { 1231 if(!strncmp(mDeviceName, "msm7625a" , 8)) 1232 mCurrentTarget = TARGET_MSM7625A; 1233 } 1234 if(mCurrentTarget == TARGET_MSM7627) { 1235 if(!strncmp(mDeviceName, "msm7627a" , 8)) 1236 mCurrentTarget = TARGET_MSM7627A; 1237 } 1238 break; 1239 } 1240 } 1241 ALOGV(" Storing the current target type as %d ", mCurrentTarget ); 1242 return; 1243 } 1244 1245 void *openCamera(void *data) { 1246 ALOGV(" openCamera : E"); 1247 mCameraOpen = false; 1248 1249 if (!libmmcamera) { 1250 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror()); 1251 return false; 1252 } 1253 1254 *(void **)&LINK_mm_camera_init = 1255 ::dlsym(libmmcamera, "mm_camera_init"); 1256 1257 *(void **)&LINK_mm_camera_exec = 1258 ::dlsym(libmmcamera, "mm_camera_exec"); 1259 1260 *(void **)&LINK_mm_camera_deinit = 1261 ::dlsym(libmmcamera, "mm_camera_deinit"); 1262 1263 1264 if (MM_CAMERA_SUCCESS != LINK_mm_camera_init(&mCfgControl, &mCamNotify, &mCamOps, 0)) { 1265 ALOGE("startCamera: mm_camera_init failed:"); 1266 return false; 1267 //pthread_exit((void*) ret_val); 1268 } 1269 1270 uint8_t camera_id8 = (uint8_t)HAL_currentCameraId; 1271 if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_CAMERA_ID, &camera_id8)) { 1272 ALOGE("setting camera id failed"); 1273 LINK_mm_camera_deinit(); 1274 return false; 1275 //pthread_exit((void*) ret_val); 1276 } 1277 1278 //camera_mode_t mode = (camera_mode_t)HAL_currentCameraMode; 1279 camera_mode_t mode = CAMERA_MODE_2D; 1280 if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_MODE, &mode)) { 1281 ALOGE("startCamera: CAMERA_PARM_MODE failed:"); 1282 LINK_mm_camera_deinit(); 1283 return false; 1284 //pthread_exit((void*) ret_val); 1285 } 1286 1287 if (MM_CAMERA_SUCCESS != LINK_mm_camera_exec()) { 1288 ALOGE("startCamera: mm_camera_exec failed:"); 1289 return false; 1290 //pthread_exit((void*) ret_val); 1291 } 1292 mCameraOpen = true; 1293 ALOGV(" openCamera : X"); 1294 if (CAMERA_MODE_3D == mode) { 1295 camera_3d_frame_t snapshotFrame; 1296 snapshotFrame.frame_type = CAM_SNAPSHOT_FRAME; 1297 if(MM_CAMERA_SUCCESS != 1298 mCfgControl.mm_camera_get_parm(CAMERA_PARM_3D_FRAME_FORMAT, 1299 (void *)&snapshotFrame)){ 1300 ALOGE("%s: get 3D format failed", __func__); 1301 LINK_mm_camera_deinit(); 1302 return false; 1303 //pthread_exit((void*) ret_val); 1304 } 1305 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 1306 if (obj != 0) { 1307 obj->mSnapshot3DFormat = snapshotFrame.format; 1308 ALOGI("%s: 3d format snapshot %d", __func__, obj->mSnapshot3DFormat); 1309 } 1310 } 1311 1312 ALOGV("openCamera : X"); 1313 // pthread_exit((void*) ret_val); 1314 1315 return NULL; 1316 } 1317 //------------------------------------------------------------------------------------- 1318 static Mutex singleton_lock; 1319 static bool singleton_releasing; 1320 static nsecs_t singleton_releasing_start_time; 1321 static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5); 1322 static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1); 1323 static Condition singleton_wait; 1324 1325 static void receive_camframe_callback(struct msm_frame *frame); 1326 static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size); 1327 static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo); 1328 static void receive_camframe_video_callback(struct msm_frame *frame); // 720p 1329 static int8_t receive_event_callback(mm_camera_event* event); 1330 static void receive_shutter_callback(common_crop_t *crop); 1331 static void receive_camframe_error_callback(camera_error_type err); 1332 static int fb_fd = -1; 1333 static int32_t mMaxZoom = 0; 1334 static bool zoomSupported = false; 1335 static int dstOffset = 0; 1336 1337 static int16_t * zoomRatios; 1338 1339 1340 /* When using MDP zoom, double the preview buffers. The usage of these 1341 * buffers is as follows: 1342 * 1. As all the buffers comes under a single FD, and at initial registration, 1343 * this FD will be passed to surface flinger, surface flinger can have access 1344 * to all the buffers when needed. 1345 * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the 1346 * camera driver to receive preview frames. The remaining buffers (DstSet), 1347 * will be used at HAL and by surface flinger only when crop information 1348 * is present in the frame. 1349 * 3. When there is no crop information, there will be no call to MDP zoom, 1350 * and the buffers in SrcSet will be passed to surface flinger to display. 1351 * 4. With crop information present, MDP zoom will be called, and the final 1352 * data will be placed in a buffer from DstSet, and this buffer will be given 1353 * to surface flinger to display. 1354 */ 1355 #define NUM_MORE_BUFS 2 1356 1357 QualcommCameraHardware::QualcommCameraHardware() 1358 : mParameters(), 1359 mCameraRunning(false), 1360 mPreviewInitialized(false), 1361 mPreviewThreadRunning(false), 1362 mHFRThreadRunning(false), 1363 mFrameThreadRunning(false), 1364 mVideoThreadRunning(false), 1365 mSnapshotThreadRunning(false), 1366 mJpegThreadRunning(false), 1367 mSmoothzoomThreadRunning(false), 1368 mSmoothzoomThreadExit(false), 1369 mInSnapshotMode(false), 1370 mEncodePending(false), 1371 mBuffersInitialized(false), 1372 mSnapshotFormat(0), 1373 mFirstFrame(true), 1374 mReleasedRecordingFrame(false), 1375 mPreviewFrameSize(0), 1376 mRawSize(0), 1377 mCbCrOffsetRaw(0), 1378 mYOffset(0), 1379 mAutoFocusThreadRunning(false), 1380 mInitialized(false), 1381 mBrightness(0), 1382 mSkinToneEnhancement(0), 1383 mHJR(0), 1384 mInPreviewCallback(false), 1385 //mUseOverlay(0), 1386 mIs3DModeOn(0), 1387 //mOverlay(0), 1388 mMsgEnabled(0), 1389 mNotifyCallback(0), 1390 mDataCallback(0), 1391 mDataCallbackTimestamp(0), 1392 mCallbackCookie(0), 1393 mDebugFps(0), 1394 mSnapshotDone(0), 1395 maxSnapshotWidth(0), 1396 maxSnapshotHeight(0), 1397 mHasAutoFocusSupport(0), 1398 mDisEnabled(0), 1399 mRotation(0), 1400 mResetWindowCrop(false), 1401 mThumbnailWidth(0), 1402 mThumbnailHeight(0), 1403 strTexturesOn(false), 1404 mPictureWidth(0), 1405 mPictureHeight(0), 1406 mPostviewWidth(0), 1407 mPostviewHeight(0), 1408 mPreviewWindow(NULL), 1409 mTotalPreviewBufferCount(0), 1410 mZslFlashEnable(false), 1411 mZslPanorama(false), 1412 mSnapshotCancel(false), 1413 mHFRMode(false), 1414 mActualPictWidth(0), 1415 mActualPictHeight(0), 1416 mDenoiseValue(0), 1417 mPreviewStopping(false), 1418 mInHFRThread(false), 1419 mPrevHeapDeallocRunning(false), 1420 mHdrMode(false ), 1421 mExpBracketMode(false), 1422 mZslEnable(false), 1423 mStoreMetaDataInFrame(0), 1424 mRecordingState(0) 1425 { 1426 ALOGI("QualcommCameraHardware constructor E"); 1427 mMMCameraDLRef = MMCameraDL::getInstance(); 1428 libmmcamera = mMMCameraDLRef->pointer(); 1429 char value[PROPERTY_VALUE_MAX]; 1430 mCameraOpen = false; 1431 /*if(HAL_currentSnapshotMode == CAMERA_SNAPSHOT_ZSL) { 1432 ALOGI("%s: this is ZSL mode", __FUNCTION__); 1433 mZslEnable = true; 1434 }*/ 1435 1436 property_get("persist.camera.hal.multitouchaf", value, "0"); 1437 mMultiTouch = atoi(value); 1438 1439 storeTargetType(); 1440 for(int i=0; i< MAX_SNAPSHOT_BUFFERS; i++) { 1441 mRawMapped[i] = NULL; 1442 mJpegMapped[i] = NULL; 1443 mThumbnailMapped[i] = NULL; 1444 } 1445 mRawSnapshotMapped = NULL; 1446 mJpegCopyMapped = NULL; 1447 for(int i=0; i< RECORD_BUFFERS; i++) { 1448 mRecordMapped[i] = NULL; 1449 } 1450 1451 for(int i=0; i<3; i++) 1452 mStatsMapped[i] = NULL; 1453 1454 mJpegLiveSnapMapped = NULL; 1455 if(HAL_currentCameraMode == CAMERA_SUPPORT_MODE_3D){ 1456 mIs3DModeOn = true; 1457 } 1458 /* TODO: Will remove this command line interface at end */ 1459 property_get("persist.camera.hal.3dmode", value, "0"); 1460 int mode = atoi(value); 1461 if( mode == 1) { 1462 mIs3DModeOn = true; 1463 HAL_currentCameraMode = CAMERA_MODE_3D; 1464 } 1465 1466 if( (pthread_create(&mDeviceOpenThread, NULL, openCamera, NULL)) != 0) { 1467 ALOGE(" openCamera thread creation failed "); 1468 } 1469 memset(&mDimension, 0, sizeof(mDimension)); 1470 memset(&mCrop, 0, sizeof(mCrop)); 1471 memset(&zoomCropInfo, 0, sizeof(android_native_rect_t)); 1472 //storeTargetType(); 1473 property_get("persist.debug.sf.showfps", value, "0"); 1474 mDebugFps = atoi(value); 1475 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) { 1476 kPreviewBufferCountActual = kPreviewBufferCount; 1477 kRecordBufferCount = RECORD_BUFFERS; 1478 recordframes = new msm_frame[kRecordBufferCount]; 1479 record_buffers_tracking_flag = new bool[kRecordBufferCount]; 1480 } 1481 else { 1482 kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS; 1483 if( mCurrentTarget == TARGET_QSD8250 ) { 1484 kRecordBufferCount = RECORD_BUFFERS_8x50; 1485 recordframes = new msm_frame[kRecordBufferCount]; 1486 record_buffers_tracking_flag = new bool[kRecordBufferCount]; 1487 } 1488 } 1489 mTotalPreviewBufferCount = kTotalPreviewBufferCount; 1490 if((mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) 1491 && (mCurrentTarget != TARGET_MSM8660)) { 1492 for (int i = 0; i < mTotalPreviewBufferCount; i++) 1493 metadata_memory[i] = NULL; 1494 } 1495 else { 1496 for (int i = 0; i < kRecordBufferCount; i++) 1497 metadata_memory[i] = NULL; 1498 } 1499 switch(mCurrentTarget){ 1500 case TARGET_MSM7627: 1501 case TARGET_MSM7627A: 1502 jpegPadding = 0; // to be checked. 1503 break; 1504 case TARGET_QSD8250: 1505 case TARGET_MSM7630: 1506 case TARGET_MSM8660: 1507 jpegPadding = 0; 1508 break; 1509 default: 1510 jpegPadding = 0; 1511 break; 1512 } 1513 // Initialize with default format values. The format values can be 1514 // overriden when application requests. 1515 mDimension.prev_format = CAMERA_YUV_420_NV21; 1516 mPreviewFormat = CAMERA_YUV_420_NV21; 1517 mDimension.enc_format = CAMERA_YUV_420_NV21; 1518 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) 1519 mDimension.enc_format = CAMERA_YUV_420_NV12; 1520 mDimension.main_img_format = CAMERA_YUV_420_NV21; 1521 mDimension.thumb_format = CAMERA_YUV_420_NV21; 1522 1523 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){ 1524 /* DIS is disabled all the time in VPE support targets. 1525 * No provision for the user to control this. 1526 */ 1527 mDisEnabled = 0; 1528 /* Get the DIS value from properties, to check whether 1529 * DIS is disabled or not. If the property is not found 1530 * default to DIS disabled.*/ 1531 property_get("persist.camera.hal.dis", value, "0"); 1532 mDisEnabled = atoi(value); 1533 mVpeEnabled = 1; 1534 } 1535 if(mIs3DModeOn) { 1536 mDisEnabled = 0; 1537 } 1538 ALOGV("constructor EX"); 1539 } 1540 1541 void QualcommCameraHardware::hasAutoFocusSupport(){ 1542 if( !mCamOps.mm_camera_is_supported(CAMERA_OPS_FOCUS)){ 1543 ALOGI("AutoFocus is not supported"); 1544 mHasAutoFocusSupport = false; 1545 }else { 1546 mHasAutoFocusSupport = true; 1547 } 1548 if(mZslEnable) 1549 mHasAutoFocusSupport = false; 1550 } 1551 1552 //filter Picture sizes based on max width and height 1553 void QualcommCameraHardware::filterPictureSizes(){ 1554 unsigned int i; 1555 if(PICTURE_SIZE_COUNT <= 0) 1556 return; 1557 maxSnapshotWidth = picture_sizes[0].width; 1558 maxSnapshotHeight = picture_sizes[0].height; 1559 // Iterate through all the width and height to find the max value 1560 for(i =0; i<PICTURE_SIZE_COUNT;i++){ 1561 if(((maxSnapshotWidth < picture_sizes[i].width) && 1562 (maxSnapshotHeight <= picture_sizes[i].height))){ 1563 maxSnapshotWidth = picture_sizes[i].width; 1564 maxSnapshotHeight = picture_sizes[i].height; 1565 } 1566 } 1567 if(mZslEnable){ 1568 // due to lack of PMEM we restrict to lower resolution 1569 picture_sizes_ptr = zsl_picture_sizes; 1570 supportedPictureSizesCount = 7; 1571 } 1572 else if(mIs3DModeOn){ 1573 // In 3D mode we only want 1080p picture size 1574 picture_sizes_ptr = for_3D_picture_sizes; 1575 supportedPictureSizesCount = 1; 1576 } 1577 else{ 1578 picture_sizes_ptr = picture_sizes; 1579 supportedPictureSizesCount = PICTURE_SIZE_COUNT; 1580 } 1581 } 1582 1583 bool QualcommCameraHardware::supportsSceneDetection() { 1584 unsigned int prop = 0; 1585 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) { 1586 if((mCurrentTarget == boardProperties[prop].target) 1587 && boardProperties[prop].hasSceneDetect == true) { 1588 return true; 1589 break; 1590 } 1591 } 1592 return false; 1593 } 1594 1595 bool QualcommCameraHardware::supportsSelectableZoneAf() { 1596 unsigned int prop = 0; 1597 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) { 1598 if((mCurrentTarget == boardProperties[prop].target) 1599 && boardProperties[prop].hasSelectableZoneAf == true) { 1600 return true; 1601 break; 1602 } 1603 } 1604 return false; 1605 } 1606 1607 bool QualcommCameraHardware::supportsFaceDetection() { 1608 unsigned int prop = 0; 1609 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) { 1610 if((mCurrentTarget == boardProperties[prop].target) 1611 && boardProperties[prop].hasFaceDetect == true) { 1612 return true; 1613 break; 1614 } 1615 } 1616 return false; 1617 } 1618 1619 void QualcommCameraHardware::initDefaultParameters() 1620 { 1621 ALOGV("initDefaultParameters E"); 1622 mDimension.picture_width = DEFAULT_PICTURE_WIDTH; 1623 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT; 1624 mDimension.ui_thumbnail_width = 1625 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width; 1626 mDimension.ui_thumbnail_height = 1627 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height; 1628 bool ret = native_set_parms(CAMERA_PARM_DIMENSION, 1629 sizeof(cam_ctrl_dimension_t),(void *) &mDimension); 1630 if(ret != true) { 1631 ALOGE("CAMERA_PARM_DIMENSION failed!!!"); 1632 return; 1633 } 1634 hasAutoFocusSupport(); 1635 //Disable DIS for Web Camera 1636 if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_VIDEO_DIS)){ 1637 ALOGI("DISABLE DIS"); 1638 mDisEnabled = 0; 1639 }else { 1640 ALOGI("Enable DIS"); 1641 } 1642 // Initialize constant parameter strings. This will happen only once in the 1643 // lifetime of the mediaserver process. 1644 if (!parameter_string_initialized) { 1645 if(mIs3DModeOn){ 1646 antibanding_values = create_values_str( 1647 antibanding_3D, sizeof(antibanding_3D) / sizeof(str_map)); 1648 } else{ 1649 antibanding_values = create_values_str( 1650 antibanding, sizeof(antibanding) / sizeof(str_map)); 1651 } 1652 effect_values = create_values_str( 1653 effects, sizeof(effects) / sizeof(str_map)); 1654 autoexposure_values = create_values_str( 1655 autoexposure, sizeof(autoexposure) / sizeof(str_map)); 1656 whitebalance_values = create_values_str( 1657 whitebalance, sizeof(whitebalance) / sizeof(str_map)); 1658 //filter picture sizes 1659 filterPictureSizes(); 1660 picture_size_values = create_sizes_str( 1661 picture_sizes_ptr, supportedPictureSizesCount); 1662 preview_size_values = create_sizes_str( 1663 preview_sizes, PREVIEW_SIZE_COUNT); 1664 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, 1665 preview_size_values.string()); 1666 1667 mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_SIZES, 1668 preview_size_values.string()); 1669 1670 mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES, 1671 picture_size_values.string()); 1672 mParameters.set(QCameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, 1673 "true"); 1674 mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES, 1675 QCameraParameters::FOCUS_MODE_INFINITY); 1676 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, 1677 QCameraParameters::FOCUS_MODE_INFINITY); 1678 mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1"); 1679 1680 mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, FOCUS_AREA_INIT); 1681 mParameters.set(QCameraParameters::KEY_METERING_AREAS, FOCUS_AREA_INIT); 1682 1683 if(!mIs3DModeOn){ 1684 hfr_size_values = create_sizes_str( 1685 hfr_sizes, HFR_SIZE_COUNT); 1686 } 1687 fps_ranges_supported_values = create_fps_str( 1688 FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT ); 1689 mParameters.set( 1690 QCameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, 1691 fps_ranges_supported_values); 1692 mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000); 1693 1694 flash_values = create_values_str( 1695 flash, sizeof(flash) / sizeof(str_map)); 1696 if(mHasAutoFocusSupport){ 1697 focus_mode_values = create_values_str( 1698 focus_modes, sizeof(focus_modes) / sizeof(str_map)); 1699 } 1700 if(mIs3DModeOn){ 1701 iso_values = create_values_str( 1702 iso_3D,sizeof(iso_3D)/sizeof(str_map)); 1703 } else{ 1704 iso_values = create_values_str( 1705 iso,sizeof(iso)/sizeof(str_map)); 1706 } 1707 lensshade_values = create_values_str( 1708 lensshade,sizeof(lensshade)/sizeof(str_map)); 1709 mce_values = create_values_str( 1710 mce,sizeof(mce)/sizeof(str_map)); 1711 if(!mIs3DModeOn){ 1712 hfr_values = create_values_str( 1713 hfr,sizeof(hfr)/sizeof(str_map)); 1714 } 1715 if(mCurrentTarget == TARGET_MSM8660) 1716 hdr_values = create_values_str( 1717 hdr,sizeof(hdr)/sizeof(str_map)); 1718 //Currently Enabling Histogram for 8x60 1719 if(mCurrentTarget == TARGET_MSM8660) { 1720 histogram_values = create_values_str( 1721 histogram,sizeof(histogram)/sizeof(str_map)); 1722 } 1723 //Currently Enabling Skin Tone Enhancement for 8x60 and 7630 1724 if((mCurrentTarget == TARGET_MSM8660)||(mCurrentTarget == TARGET_MSM7630)) { 1725 skinToneEnhancement_values = create_values_str( 1726 skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map)); 1727 } 1728 if(mHasAutoFocusSupport){ 1729 touchafaec_values = create_values_str( 1730 touchafaec,sizeof(touchafaec)/sizeof(str_map)); 1731 } 1732 zsl_values = create_values_str( 1733 zsl_modes,sizeof(zsl_modes)/sizeof(str_map)); 1734 1735 if(mZslEnable){ 1736 picture_format_values = create_values_str( 1737 picture_formats_zsl, sizeof(picture_formats_zsl)/sizeof(str_map)); 1738 } else{ 1739 picture_format_values = create_values_str( 1740 picture_formats, sizeof(picture_formats)/sizeof(str_map)); 1741 } 1742 if(mCurrentTarget == TARGET_MSM8660 || 1743 (mCurrentTarget == TARGET_MSM7625A || 1744 mCurrentTarget == TARGET_MSM7627A)) { 1745 denoise_values = create_values_str( 1746 denoise, sizeof(denoise) / sizeof(str_map)); 1747 } 1748 if(mCfgControl.mm_camera_query_parms(CAMERA_PARM_ZOOM_RATIO, 1749 (void **)&zoomRatios, (uint32_t *) &mMaxZoom) == MM_CAMERA_SUCCESS) { 1750 zoomSupported = true; 1751 if( mMaxZoom >0) { 1752 ALOGI("Maximum zoom value is %d", mMaxZoom); 1753 if(zoomRatios != NULL) { 1754 zoom_ratio_values = create_str(zoomRatios, mMaxZoom); 1755 } else { 1756 ALOGE("Failed to get zoomratios .."); 1757 } 1758 } else { 1759 zoomSupported = false; 1760 } 1761 } else { 1762 zoomSupported = false; 1763 ALOGE("Failed to get maximum zoom value...setting max " 1764 "zoom to zero"); 1765 mMaxZoom = 0; 1766 } 1767 preview_frame_rate_values = create_values_range_str( 1768 MINIMUM_FPS, MAXIMUM_FPS); 1769 1770 scenemode_values = create_values_str( 1771 scenemode, sizeof(scenemode) / sizeof(str_map)); 1772 1773 if(supportsSceneDetection()) { 1774 scenedetect_values = create_values_str( 1775 scenedetect, sizeof(scenedetect) / sizeof(str_map)); 1776 } 1777 1778 if(mHasAutoFocusSupport && supportsSelectableZoneAf()){ 1779 selectable_zone_af_values = create_values_str( 1780 selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map)); 1781 } 1782 1783 if(mHasAutoFocusSupport && supportsFaceDetection()) { 1784 facedetection_values = create_values_str( 1785 facedetection, sizeof(facedetection) / sizeof(str_map)); 1786 } 1787 1788 redeye_reduction_values = create_values_str( 1789 redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map)); 1790 1791 parameter_string_initialized = true; 1792 } 1793 //set video size 1794 if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 1795 String8 vSize = create_sizes_str(preview_sizes, 1); 1796 mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, vSize.string()); 1797 } 1798 if(mIs3DModeOn){ 1799 ALOGI("In initDefaultParameters - 3D mode on so set the default preview to 1280 x 720"); 1800 mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH_3D, DEFAULT_PREVIEW_HEIGHT_3D); 1801 mDimension.display_width = DEFAULT_PREVIEW_WIDTH_3D; 1802 mDimension.display_height = DEFAULT_PREVIEW_HEIGHT_3D; 1803 } else{ 1804 mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT); 1805 mDimension.display_width = DEFAULT_PREVIEW_WIDTH; 1806 mDimension.display_height = DEFAULT_PREVIEW_HEIGHT; 1807 } 1808 mParameters.setPreviewFrameRate(DEFAULT_FPS); 1809 if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){ 1810 mParameters.set( 1811 QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, 1812 preview_frame_rate_values.string()); 1813 } else { 1814 mParameters.setPreviewFrameRate(DEFAULT_FIXED_FPS_VALUE); 1815 mParameters.set( 1816 QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, 1817 DEFAULT_FIXED_FPS_VALUE); 1818 } 1819 mParameters.setPreviewFrameRateMode("frame-rate-auto"); 1820 mParameters.setPreviewFormat("yuv420sp"); // informative 1821 mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP); 1822 if(mIs3DModeOn){ 1823 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH_3D, DEFAULT_PICTURE_HEIGHT_3D); 1824 } else{ 1825 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT); 1826 } 1827 mParameters.setPictureFormat("jpeg"); // informative 1828 1829 mParameters.set(QCameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp"); 1830 1831 mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, "85"); // max quality 1832 1833 mParameters.set("power-mode-supported", "false"); 1834 1835 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, 1836 THUMBNAIL_WIDTH_STR); // informative 1837 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, 1838 THUMBNAIL_HEIGHT_STR); // informative 1839 mDimension.ui_thumbnail_width = 1840 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width; 1841 mDimension.ui_thumbnail_height = 1842 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height; 1843 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90"); 1844 1845 String8 valuesStr = create_sizes_str(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_COUNT); 1846 mParameters.set(QCameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, 1847 valuesStr.string()); 1848 1849 // Define CAMERA_SMOOTH_ZOOM in Android.mk file , to enable smoothzoom 1850 #ifdef CAMERA_SMOOTH_ZOOM 1851 mParameters.set(QCameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true"); 1852 #endif 1853 1854 if(zoomSupported){ 1855 mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "true"); 1856 ALOGI("max zoom is %d", mMaxZoom-1); 1857 /* mMaxZoom value that the query interface returns is the size 1858 * of zoom table. So the actual max zoom value will be one 1859 * less than that value. 1860 */ 1861 mParameters.set("max-zoom",mMaxZoom-1); 1862 mParameters.set(QCameraParameters::KEY_ZOOM_RATIOS, 1863 zoom_ratio_values); 1864 } else { 1865 mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "false"); 1866 } 1867 /* Enable zoom support for video application if VPE enabled */ 1868 if(zoomSupported && mVpeEnabled) { 1869 mParameters.set("video-zoom-support", "true"); 1870 } else { 1871 mParameters.set("video-zoom-support", "false"); 1872 } 1873 1874 mParameters.set(QCameraParameters::KEY_CAMERA_MODE,0); 1875 1876 mParameters.set(QCameraParameters::KEY_ANTIBANDING, 1877 QCameraParameters::ANTIBANDING_OFF); 1878 mParameters.set(QCameraParameters::KEY_EFFECT, 1879 QCameraParameters::EFFECT_NONE); 1880 mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE, 1881 QCameraParameters::AUTO_EXPOSURE_FRAME_AVG); 1882 mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, 1883 QCameraParameters::WHITE_BALANCE_AUTO); 1884 if( (mCurrentTarget != TARGET_MSM7630) 1885 && (mCurrentTarget != TARGET_QSD8250) 1886 && (mCurrentTarget != TARGET_MSM8660) 1887 && (mCurrentTarget != TARGET_MSM7627A)) { 1888 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, 1889 "yuv420sp"); 1890 } else if(mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) { 1891 preview_format_values = create_values_str( 1892 preview_formats1, sizeof(preview_formats1) / sizeof(str_map)); 1893 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, 1894 preview_format_values.string()); 1895 } else { 1896 preview_format_values = create_values_str( 1897 preview_formats, sizeof(preview_formats) / sizeof(str_map)); 1898 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, 1899 preview_format_values.string()); 1900 } 1901 1902 frame_rate_mode_values = create_values_str( 1903 frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map)); 1904 if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE)){ 1905 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES, 1906 frame_rate_mode_values.string()); 1907 } 1908 1909 mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, 1910 preview_size_values.string()); 1911 mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES, 1912 picture_size_values.string()); 1913 mParameters.set(QCameraParameters::KEY_SUPPORTED_ANTIBANDING, 1914 antibanding_values); 1915 mParameters.set(QCameraParameters::KEY_SUPPORTED_EFFECTS, effect_values); 1916 mParameters.set(QCameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values); 1917 mParameters.set(QCameraParameters::KEY_SUPPORTED_WHITE_BALANCE, 1918 whitebalance_values); 1919 1920 if(mHasAutoFocusSupport){ 1921 mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES, 1922 focus_mode_values); 1923 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, 1924 QCameraParameters::FOCUS_MODE_AUTO); 1925 } else { 1926 mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES, 1927 QCameraParameters::FOCUS_MODE_INFINITY); 1928 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, 1929 QCameraParameters::FOCUS_MODE_INFINITY); 1930 } 1931 1932 mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, 1933 picture_format_values); 1934 1935 if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) { 1936 mParameters.set(QCameraParameters::KEY_FLASH_MODE, 1937 QCameraParameters::FLASH_MODE_OFF); 1938 mParameters.set(QCameraParameters::KEY_SUPPORTED_FLASH_MODES, 1939 flash_values); 1940 } 1941 1942 mParameters.set(QCameraParameters::KEY_MAX_SHARPNESS, 1943 CAMERA_MAX_SHARPNESS); 1944 mParameters.set(QCameraParameters::KEY_MAX_CONTRAST, 1945 CAMERA_MAX_CONTRAST); 1946 mParameters.set(QCameraParameters::KEY_MAX_SATURATION, 1947 CAMERA_MAX_SATURATION); 1948 1949 mParameters.set( 1950 QCameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, 1951 EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR); 1952 mParameters.set( 1953 QCameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, 1954 EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR); 1955 mParameters.set( 1956 QCameraParameters::KEY_EXPOSURE_COMPENSATION, 1957 EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR); 1958 mParameters.setFloat( 1959 QCameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, 1960 EXPOSURE_COMPENSATION_STEP); 1961 1962 mParameters.set("luma-adaptation", "3"); 1963 mParameters.set("skinToneEnhancement", "0"); 1964 mParameters.set("zoom-supported", "true"); 1965 mParameters.set("zoom", 0); 1966 mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT, 1967 QCameraParameters::PIXEL_FORMAT_JPEG); 1968 1969 mParameters.set(QCameraParameters::KEY_SHARPNESS, 1970 CAMERA_DEF_SHARPNESS); 1971 mParameters.set(QCameraParameters::KEY_CONTRAST, 1972 CAMERA_DEF_CONTRAST); 1973 mParameters.set(QCameraParameters::KEY_SATURATION, 1974 CAMERA_DEF_SATURATION); 1975 1976 mParameters.set(QCameraParameters::KEY_ISO_MODE, 1977 QCameraParameters::ISO_AUTO); 1978 mParameters.set(QCameraParameters::KEY_LENSSHADE, 1979 QCameraParameters::LENSSHADE_ENABLE); 1980 mParameters.set(QCameraParameters::KEY_SUPPORTED_ISO_MODES, 1981 iso_values); 1982 mParameters.set(QCameraParameters::KEY_SUPPORTED_LENSSHADE_MODES, 1983 lensshade_values); 1984 mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT, 1985 QCameraParameters::MCE_ENABLE); 1986 mParameters.set(QCameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES, 1987 mce_values); 1988 if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR) && !(mIs3DModeOn)) { 1989 mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE, 1990 QCameraParameters::VIDEO_HFR_OFF); 1991 mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES, 1992 hfr_size_values.string()); 1993 mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES, 1994 hfr_values); 1995 } else 1996 mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,""); 1997 1998 mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING, 1999 QCameraParameters::MCE_DISABLE); 2000 mParameters.set(QCameraParameters::KEY_SUPPORTED_HDR_IMAGING_MODES, 2001 hdr_values); 2002 mParameters.set(QCameraParameters::KEY_HISTOGRAM, 2003 QCameraParameters::HISTOGRAM_DISABLE); 2004 mParameters.set(QCameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES, 2005 histogram_values); 2006 mParameters.set(QCameraParameters::KEY_SKIN_TONE_ENHANCEMENT, 2007 QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE); 2008 mParameters.set(QCameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES, 2009 skinToneEnhancement_values); 2010 mParameters.set(QCameraParameters::KEY_SCENE_MODE, 2011 QCameraParameters::SCENE_MODE_AUTO); 2012 mParameters.set("strtextures", "OFF"); 2013 2014 mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_MODES, 2015 scenemode_values); 2016 mParameters.set(QCameraParameters::KEY_DENOISE, 2017 QCameraParameters::DENOISE_OFF); 2018 mParameters.set(QCameraParameters::KEY_SUPPORTED_DENOISE, 2019 denoise_values); 2020 2021 //touch af/aec parameters 2022 mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC, 2023 QCameraParameters::TOUCH_AF_AEC_OFF); 2024 mParameters.set(QCameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC, 2025 touchafaec_values); 2026 mParameters.set("touchAfAec-dx","100"); 2027 mParameters.set("touchAfAec-dy","100"); 2028 mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1"); 2029 mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "1"); 2030 2031 mParameters.set(QCameraParameters::KEY_SCENE_DETECT, 2032 QCameraParameters::SCENE_DETECT_OFF); 2033 mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_DETECT, 2034 scenedetect_values); 2035 mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF, 2036 QCameraParameters::SELECTABLE_ZONE_AF_AUTO); 2037 mParameters.set(QCameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF, 2038 selectable_zone_af_values); 2039 mParameters.set(QCameraParameters::KEY_FACE_DETECTION, 2040 QCameraParameters::FACE_DETECTION_OFF); 2041 mParameters.set(QCameraParameters::KEY_SUPPORTED_FACE_DETECTION, 2042 facedetection_values); 2043 mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION, 2044 QCameraParameters::REDEYE_REDUCTION_DISABLE); 2045 mParameters.set(QCameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION, 2046 redeye_reduction_values); 2047 mParameters.set(QCameraParameters::KEY_ZSL, 2048 QCameraParameters::ZSL_OFF); 2049 mParameters.set(QCameraParameters::KEY_SUPPORTED_ZSL_MODES, 2050 zsl_values); 2051 2052 float focalLength = 0.0f; 2053 float horizontalViewAngle = 0.0f; 2054 float verticalViewAngle = 0.0f; 2055 2056 mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCAL_LENGTH, 2057 (void *)&focalLength); 2058 mParameters.setFloat(QCameraParameters::KEY_FOCAL_LENGTH, 2059 focalLength); 2060 mCfgControl.mm_camera_get_parm(CAMERA_PARM_HORIZONTAL_VIEW_ANGLE, 2061 (void *)&horizontalViewAngle); 2062 mParameters.setFloat(QCameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, 2063 horizontalViewAngle); 2064 mCfgControl.mm_camera_get_parm(CAMERA_PARM_VERTICAL_VIEW_ANGLE, 2065 (void *)&verticalViewAngle); 2066 mParameters.setFloat(QCameraParameters::KEY_VERTICAL_VIEW_ANGLE, 2067 verticalViewAngle); 2068 numCapture = 1; 2069 if(mZslEnable) { 2070 int maxSnapshot = MAX_SNAPSHOT_BUFFERS - 2; 2071 char value[5]; 2072 property_get("persist.camera.hal.capture", value, "1"); 2073 numCapture = atoi(value); 2074 if(numCapture > maxSnapshot) 2075 numCapture = maxSnapshot; 2076 else if(numCapture < 1) 2077 numCapture = 1; 2078 mParameters.set("capture-burst-captures-values", maxSnapshot); 2079 mParameters.set("capture-burst-interval-supported", "false"); 2080 } 2081 mParameters.set("num-snaps-per-shutter", numCapture); 2082 ALOGI("%s: setting num-snaps-per-shutter to %d", __FUNCTION__, numCapture); 2083 if(mIs3DModeOn) 2084 mParameters.set("3d-frame-format", "left-right"); 2085 2086 switch(mCurrentTarget){ 2087 case TARGET_MSM7627: 2088 case TARGET_QSD8250: 2089 case TARGET_MSM7630: 2090 mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "800x480"); 2091 break; 2092 case TARGET_MSM7627A: 2093 mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "864x480"); 2094 break; 2095 case TARGET_MSM8660: 2096 mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1920x1088"); 2097 break; 2098 default: 2099 mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "640x480"); 2100 break; 2101 } 2102 if (setParameters(mParameters) != NO_ERROR) { 2103 ALOGE("Failed to set default parameters?!"); 2104 } 2105 2106 /* Initialize the camframe_timeout_flag*/ 2107 Mutex::Autolock l(&mCamframeTimeoutLock); 2108 camframe_timeout_flag = FALSE; 2109 mPostviewHeap = NULL; 2110 mDisplayHeap = NULL; 2111 mLastPreviewFrameHeap = NULL; 2112 mThumbnailHeap = NULL; 2113 2114 mInitialized = true; 2115 strTexturesOn = false; 2116 2117 ALOGV("initDefaultParameters X"); 2118 } 2119 2120 2121 #define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff) 2122 2123 bool QualcommCameraHardware::startCamera() 2124 { 2125 ALOGV("startCamera E"); 2126 if( mCurrentTarget == TARGET_MAX ) { 2127 ALOGE(" Unable to determine the target type. Camera will not work "); 2128 return false; 2129 } 2130 #if DLOPEN_LIBMMCAMERA 2131 2132 ALOGV("loading liboemcamera at %p", libmmcamera); 2133 if (!libmmcamera) { 2134 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror()); 2135 return false; 2136 } 2137 2138 *(void **)&LINK_cam_frame = 2139 ::dlsym(libmmcamera, "cam_frame"); 2140 *(void **)&LINK_wait_cam_frame_thread_ready = 2141 ::dlsym(libmmcamera, "wait_cam_frame_thread_ready"); 2142 *(void **)&LINK_cam_frame_set_exit_flag = 2143 ::dlsym(libmmcamera, "cam_frame_set_exit_flag"); 2144 *(void **)&LINK_camframe_terminate = 2145 ::dlsym(libmmcamera, "camframe_terminate"); 2146 2147 *(void **)&LINK_jpeg_encoder_init = 2148 ::dlsym(libmmcamera, "jpeg_encoder_init"); 2149 2150 *(void **)&LINK_jpeg_encoder_encode = 2151 ::dlsym(libmmcamera, "jpeg_encoder_encode"); 2152 2153 *(void **)&LINK_jpeg_encoder_join = 2154 ::dlsym(libmmcamera, "jpeg_encoder_join"); 2155 2156 mCamNotify.preview_frame_cb = &receive_camframe_callback; 2157 2158 mCamNotify.camstats_cb = &receive_camstats_callback; 2159 2160 mCamNotify.on_event = &receive_event_callback; 2161 2162 mCamNotify.on_error_event = &receive_camframe_error_callback; 2163 2164 // 720 p new recording functions 2165 mCamNotify.video_frame_cb = &receive_camframe_video_callback; 2166 // 720 p new recording functions 2167 2168 *(void **)&LINK_camframe_add_frame = ::dlsym(libmmcamera, "camframe_add_frame"); 2169 2170 *(void **)&LINK_camframe_release_all_frames = ::dlsym(libmmcamera, "camframe_release_all_frames"); 2171 2172 *(void **)&LINK_mmcamera_shutter_callback = 2173 ::dlsym(libmmcamera, "mmcamera_shutter_callback"); 2174 2175 *LINK_mmcamera_shutter_callback = receive_shutter_callback; 2176 2177 *(void**)&LINK_jpeg_encoder_setMainImageQuality = 2178 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality"); 2179 2180 *(void**)&LINK_jpeg_encoder_setThumbnailQuality = 2181 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality"); 2182 2183 *(void**)&LINK_jpeg_encoder_setRotation = 2184 ::dlsym(libmmcamera, "jpeg_encoder_setRotation"); 2185 2186 *(void**)&LINK_jpeg_encoder_get_buffer_offset = 2187 ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset"); 2188 2189 *(void**)&LINK_jpeg_encoder_set_3D_info = 2190 ::dlsym(libmmcamera, "jpeg_encoder_set_3D_info"); 2191 2192 /* Disabling until support is available. 2193 *(void**)&LINK_jpeg_encoder_setLocation = 2194 ::dlsym(libmmcamera, "jpeg_encoder_setLocation"); 2195 */ 2196 *(void **)&LINK_cam_conf = 2197 ::dlsym(libmmcamera, "cam_conf"); 2198 2199 /* Disabling until support is available. 2200 *(void **)&LINK_default_sensor_get_snapshot_sizes = 2201 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes"); 2202 */ 2203 *(void **)&LINK_launch_cam_conf_thread = 2204 ::dlsym(libmmcamera, "launch_cam_conf_thread"); 2205 2206 *(void **)&LINK_release_cam_conf_thread = 2207 ::dlsym(libmmcamera, "release_cam_conf_thread"); 2208 2209 mCamNotify.on_liveshot_event = &receive_liveshot_callback; 2210 2211 *(void **)&LINK_cancel_liveshot = 2212 ::dlsym(libmmcamera, "cancel_liveshot"); 2213 2214 *(void **)&LINK_set_liveshot_params = 2215 ::dlsym(libmmcamera, "set_liveshot_params"); 2216 2217 *(void **)&LINK_set_liveshot_frame = 2218 ::dlsym(libmmcamera, "set_liveshot_frame"); 2219 2220 *(void **)&LINK_mm_camera_destroy = 2221 ::dlsym(libmmcamera, "mm_camera_destroy"); 2222 2223 *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12_inplace = 2224 ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12"); 2225 2226 *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12 = 2227 ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12_ver2"); 2228 2229 /* Disabling until support is available.*/ 2230 *(void **)&LINK_zoom_crop_upscale = 2231 ::dlsym(libmmcamera, "zoom_crop_upscale"); 2232 2233 2234 #else 2235 mCamNotify.preview_frame_cb = &receive_camframe_callback; 2236 mCamNotify.camstats_cb = &receive_camstats_callback; 2237 mCamNotify.on_event = &receive_event_callback; 2238 2239 mmcamera_shutter_callback = receive_shutter_callback; 2240 mCamNotify.on_liveshot_event = &receive_liveshot_callback; 2241 mCamNotify.video_frame_cb = &receive_camframe_video_callback; 2242 2243 #endif // DLOPEN_LIBMMCAMERA 2244 #if 0 //commenting this for now as not getting graphics permission 2245 if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){ 2246 fb_fd = open("/dev/graphics/fb0", O_RDWR); 2247 if (fb_fd < 0) { 2248 ALOGE("startCamera: fb0 open failed: %s!", strerror(errno)); 2249 return FALSE; 2250 } 2251 } 2252 #endif 2253 int ret_val; 2254 if (pthread_join(mDeviceOpenThread, (void**)&ret_val) != 0) { 2255 ALOGE("openCamera thread exit failed"); 2256 return false; 2257 } 2258 2259 if (!mCameraOpen) { 2260 ALOGE("openCamera() failed"); 2261 return false; 2262 } 2263 2264 2265 mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT); 2266 if ((picture_sizes == NULL) || (!PICTURE_SIZE_COUNT)) { 2267 ALOGE("startCamera X: could not get snapshot sizes"); 2268 return false; 2269 } 2270 ALOGI("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT); 2271 mCfgControl.mm_camera_query_parms(CAMERA_PARM_PREVIEW_SIZE, (void **)&preview_sizes, &PREVIEW_SIZE_COUNT); 2272 if ((preview_sizes == NULL) || (!PREVIEW_SIZE_COUNT)) { 2273 ALOGE("startCamera X: could not get preview sizes"); 2274 return false; 2275 } 2276 ALOGI("startCamera preview_sizes %p previewSizeCount %d", preview_sizes, PREVIEW_SIZE_COUNT); 2277 2278 mCfgControl.mm_camera_query_parms(CAMERA_PARM_HFR_SIZE, (void **)&hfr_sizes, &HFR_SIZE_COUNT); 2279 if ((hfr_sizes == NULL) || (!HFR_SIZE_COUNT)) { 2280 ALOGE("startCamera X: could not get hfr sizes"); 2281 return false; 2282 } 2283 ALOGI("startCamera hfr_sizes %p hfrSizeCount %d", hfr_sizes, HFR_SIZE_COUNT); 2284 2285 2286 ALOGV("startCamera X"); 2287 return true; 2288 } 2289 2290 status_t QualcommCameraHardware::dump(int fd, 2291 const Vector<String16>& args) const 2292 { 2293 const size_t SIZE = 256; 2294 char buffer[SIZE]; 2295 String8 result; 2296 #if 0 2297 // Dump internal primitives. 2298 result.append("QualcommCameraHardware::dump"); 2299 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled); 2300 result.append(buffer); 2301 int width, height; 2302 mParameters.getPreviewSize(&width, &height); 2303 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height); 2304 result.append(buffer); 2305 mParameters.getPictureSize(&width, &height); 2306 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height); 2307 result.append(buffer); 2308 snprintf(buffer, 255, 2309 "preview frame size(%d), raw size (%d), jpeg size (%d) " 2310 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize, 2311 mJpegSize, mJpegMaxSize); 2312 result.append(buffer); 2313 write(fd, result.string(), result.size()); 2314 2315 // Dump internal objects. 2316 if (mPreviewHeap[0] != 0) { 2317 mPreviewHeap[0]->dump(fd, args); 2318 } 2319 if (mRawHeap != 0) { 2320 mRawHeap->dump(fd, args); 2321 } 2322 if (mJpegHeap != 0) { 2323 mJpegHeap->dump(fd, args); 2324 } 2325 mParameters.dump(fd, args); 2326 #endif 2327 return NO_ERROR; 2328 } 2329 2330 /* Issue ioctl calls related to starting Camera Operations*/ 2331 bool static native_start_ops(mm_camera_ops_type_t type, void* value) 2332 { 2333 if(mCamOps.mm_camera_start(type, value,NULL) != MM_CAMERA_SUCCESS) { 2334 ALOGE("native_start_ops: type %d error %s", 2335 type,strerror(errno)); 2336 return false; 2337 } 2338 return true; 2339 } 2340 2341 /* Issue ioctl calls related to stopping Camera Operations*/ 2342 bool static native_stop_ops(mm_camera_ops_type_t type, void* value) 2343 { 2344 if(mCamOps.mm_camera_stop(type, value,NULL) != MM_CAMERA_SUCCESS) { 2345 ALOGE("native_stop_ops: type %d error %s", 2346 type,strerror(errno)); 2347 return false; 2348 } 2349 return true; 2350 } 2351 /*==========================================================================*/ 2352 2353 2354 #define GPS_PROCESSING_METHOD_SIZE 101 2355 #define FOCAL_LENGTH_DECIMAL_PRECISON 100 2356 2357 static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; 2358 #define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix)) 2359 2360 static rat_t latitude[3]; 2361 static rat_t longitude[3]; 2362 static char lonref[2]; 2363 static char latref[2]; 2364 static rat_t altitude; 2365 static rat_t gpsTimestamp[3]; 2366 static char gpsDatestamp[20]; 2367 static char dateTime[20]; 2368 static rat_t focalLength; 2369 static uint16_t flashMode; 2370 static int iso_arr[] = {0,1,100,200,400,800,1600}; 2371 static uint16_t isoMode; 2372 static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 2373 static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type, 2374 uint32_t count, uint8_t copy, void *data) { 2375 2376 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) { 2377 ALOGE("Number of entries exceeded limit"); 2378 return; 2379 } 2380 2381 int index = exif_table_numEntries; 2382 exif_data[index].tag_id = tagid; 2383 exif_data[index].tag_entry.type = type; 2384 exif_data[index].tag_entry.count = count; 2385 exif_data[index].tag_entry.copy = copy; 2386 if((type == EXIF_RATIONAL) && (count > 1)) 2387 exif_data[index].tag_entry.data._rats = (rat_t *)data; 2388 if((type == EXIF_RATIONAL) && (count == 1)) 2389 exif_data[index].tag_entry.data._rat = *(rat_t *)data; 2390 else if(type == EXIF_ASCII) 2391 exif_data[index].tag_entry.data._ascii = (char *)data; 2392 else if(type == EXIF_BYTE) 2393 exif_data[index].tag_entry.data._byte = *(uint8_t *)data; 2394 else if((type == EXIF_SHORT) && (count > 1)) 2395 exif_data[index].tag_entry.data._shorts = (uint16_t *)data; 2396 else if((type == EXIF_SHORT) && (count == 1)) 2397 exif_data[index].tag_entry.data._short = *(uint16_t *)data; 2398 // Increase number of entries 2399 exif_table_numEntries++; 2400 } 2401 2402 static void parseLatLong(const char *latlonString, int *pDegrees, 2403 int *pMinutes, int *pSeconds ) { 2404 2405 double value = atof(latlonString); 2406 value = fabs(value); 2407 int degrees = (int) value; 2408 2409 double remainder = value - degrees; 2410 int minutes = (int) (remainder * 60); 2411 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000); 2412 2413 *pDegrees = degrees; 2414 *pMinutes = minutes; 2415 *pSeconds = seconds; 2416 } 2417 2418 static void setLatLon(exif_tag_id_t tag, const char *latlonString) { 2419 2420 int degrees, minutes, seconds; 2421 2422 parseLatLong(latlonString, °rees, &minutes, &seconds); 2423 2424 rat_t value[3] = { {degrees, 1}, 2425 {minutes, 1}, 2426 {seconds, 1000} }; 2427 2428 if(tag == EXIFTAGID_GPS_LATITUDE) { 2429 memcpy(latitude, value, sizeof(latitude)); 2430 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3, 2431 1, (void *)latitude); 2432 } else { 2433 memcpy(longitude, value, sizeof(longitude)); 2434 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3, 2435 1, (void *)longitude); 2436 } 2437 } 2438 2439 void QualcommCameraHardware::setGpsParameters() { 2440 const char *str = NULL; 2441 2442 str = mParameters.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD); 2443 2444 if(str!=NULL ){ 2445 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 2446 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str, 2447 GPS_PROCESSING_METHOD_SIZE - 1); 2448 gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0'; 2449 addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII, 2450 EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1, 2451 1, (void *)gpsProcessingMethod); 2452 } 2453 2454 str = NULL; 2455 2456 //Set Latitude 2457 str = mParameters.get(QCameraParameters::KEY_GPS_LATITUDE); 2458 if(str != NULL) { 2459 setLatLon(EXIFTAGID_GPS_LATITUDE, str); 2460 //set Latitude Ref 2461 float latitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LATITUDE); 2462 latref[0] = 'N'; 2463 if(latitudeValue < 0 ){ 2464 latref[0] = 'S'; 2465 } 2466 latref[1] = '\0'; 2467 mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latref); 2468 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2, 2469 1, (void *)latref); 2470 } 2471 2472 //set Longitude 2473 str = NULL; 2474 str = mParameters.get(QCameraParameters::KEY_GPS_LONGITUDE); 2475 if(str != NULL) { 2476 setLatLon(EXIFTAGID_GPS_LONGITUDE, str); 2477 //set Longitude Ref 2478 float longitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LONGITUDE); 2479 lonref[0] = 'E'; 2480 if(longitudeValue < 0){ 2481 lonref[0] = 'W'; 2482 } 2483 lonref[1] = '\0'; 2484 mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, lonref); 2485 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2, 2486 1, (void *)lonref); 2487 } 2488 2489 //set Altitude 2490 str = NULL; 2491 str = mParameters.get(QCameraParameters::KEY_GPS_ALTITUDE); 2492 if(str != NULL) { 2493 double value = atof(str); 2494 int ref = 0; 2495 if(value < 0){ 2496 ref = 1; 2497 value = -value; 2498 } 2499 uint32_t value_meter = value * 1000; 2500 rat_t alt_value = {value_meter, 1000}; 2501 memcpy(&altitude, &alt_value, sizeof(altitude)); 2502 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1, 2503 1, (void *)&altitude); 2504 //set AltitudeRef 2505 mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, ref); 2506 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1, 2507 1, (void *)&ref); 2508 } 2509 2510 //set Gps TimeStamp 2511 str = NULL; 2512 str = mParameters.get(QCameraParameters::KEY_GPS_TIMESTAMP); 2513 if(str != NULL) { 2514 2515 long value = atol(str); 2516 time_t unixTime; 2517 struct tm *UTCTimestamp; 2518 2519 unixTime = (time_t)value; 2520 UTCTimestamp = gmtime(&unixTime); 2521 2522 strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp); 2523 addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII, 2524 strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp); 2525 2526 rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1}, 2527 {UTCTimestamp->tm_min, 1}, 2528 {UTCTimestamp->tm_sec, 1} }; 2529 2530 2531 memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp)); 2532 addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL, 2533 3, 1, (void *)&gpsTimestamp); 2534 } 2535 2536 } 2537 2538 2539 bool QualcommCameraHardware::initZslParameter(void) 2540 { ALOGV("%s: E", __FUNCTION__); 2541 mParameters.getPictureSize(&mPictureWidth, &mPictureHeight); 2542 ALOGI("initZslParamter E: picture size=%dx%d", mPictureWidth, mPictureHeight); 2543 if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) { 2544 mDimension.picture_width = mPictureWidth; 2545 mDimension.picture_height = mPictureHeight; 2546 } 2547 2548 /* use the default thumbnail sizes */ 2549 mZslParms.picture_width = mPictureWidth; 2550 mZslParms.picture_height = mPictureHeight; 2551 mZslParms.preview_width = mDimension.display_width; 2552 mZslParms.preview_height = mDimension.display_height; 2553 mZslParms.useExternalBuffers = TRUE; 2554 /* fill main image size, thumbnail size, postview size into capture_params_t*/ 2555 memset(&mZslCaptureParms, 0, sizeof(zsl_capture_params_t)); 2556 mZslCaptureParms.thumbnail_height = mPostviewHeight; 2557 mZslCaptureParms.thumbnail_width = mPostviewWidth; 2558 ALOGI("Number of snapshot to capture: %d",numCapture); 2559 mZslCaptureParms.num_captures = numCapture; 2560 2561 return true; 2562 } 2563 2564 2565 bool QualcommCameraHardware::initImageEncodeParameters(int size) 2566 { 2567 ALOGV("%s: E", __FUNCTION__); 2568 memset(&mImageEncodeParms, 0, sizeof(encode_params_t)); 2569 int jpeg_quality = mParameters.getInt("jpeg-quality"); 2570 bool ret; 2571 if (jpeg_quality >= 0) { 2572 ALOGI("initJpegParameters, current jpeg main img quality =%d", 2573 jpeg_quality); 2574 //Application can pass quality of zero 2575 //when there is no back sensor connected. 2576 //as jpeg quality of zero is not accepted at 2577 //camera stack, pass default value. 2578 if(jpeg_quality == 0) jpeg_quality = 85; 2579 mImageEncodeParms.quality = jpeg_quality; 2580 ret = native_set_parms(CAMERA_PARM_JPEG_MAINIMG_QUALITY, sizeof(int), &jpeg_quality); 2581 if(!ret){ 2582 ALOGE("initJpegParametersX: failed to set main image quality"); 2583 return false; 2584 } 2585 } 2586 2587 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality"); 2588 if (thumbnail_quality >= 0) { 2589 //Application can pass quality of zero 2590 //when there is no back sensor connected. 2591 //as quality of zero is not accepted at 2592 //camera stack, pass default value. 2593 if(thumbnail_quality == 0) thumbnail_quality = 85; 2594 ALOGI("initJpegParameters, current jpeg thumbnail quality =%d", 2595 thumbnail_quality); 2596 /* TODO: check with mm-camera? */ 2597 mImageEncodeParms.quality = thumbnail_quality; 2598 ret = native_set_parms(CAMERA_PARM_JPEG_THUMB_QUALITY, sizeof(int), &thumbnail_quality); 2599 if(!ret){ 2600 ALOGE("initJpegParameters X: failed to set thumbnail quality"); 2601 return false; 2602 } 2603 } 2604 2605 int rotation = mParameters.getInt("rotation"); 2606 char mDeviceName[PROPERTY_VALUE_MAX]; 2607 property_get("ro.hw_plat", mDeviceName, ""); 2608 if(!strcmp(mDeviceName,"7x25A")) 2609 rotation = (rotation + 90)%360; 2610 2611 if (mIs3DModeOn) 2612 rotation = 0; 2613 if (rotation >= 0) { 2614 ALOGI("initJpegParameters, rotation = %d", rotation); 2615 mImageEncodeParms.rotation = rotation; 2616 } 2617 2618 jpeg_set_location(); 2619 2620 //set TimeStamp 2621 const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME); 2622 if(str != NULL) { 2623 strncpy(dateTime, str, 19); 2624 dateTime[19] = '\0'; 2625 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 2626 20, 1, (void *)dateTime); 2627 } 2628 2629 int focalLengthValue = (int) (mParameters.getFloat( 2630 QCameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISON); 2631 rat_t focalLengthRational = {focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISON}; 2632 memcpy(&focalLength, &focalLengthRational, sizeof(focalLengthRational)); 2633 addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1, 2634 1, (void *)&focalLength); 2635 //Adding ExifTag for ISOSpeedRating 2636 const char *iso_str = mParameters.get(QCameraParameters::KEY_ISO_MODE); 2637 int iso_value = attr_lookup(iso, sizeof(iso) / sizeof(str_map), iso_str); 2638 isoMode = iso_arr[iso_value]; 2639 addExifTag(EXIFTAGID_ISO_SPEED_RATING,EXIF_SHORT,1,1,(void *)&isoMode); 2640 2641 if (mUseJpegDownScaling) { 2642 ALOGI("initImageEncodeParameters: update main image", __func__); 2643 mImageEncodeParms.output_picture_width = mActualPictWidth; 2644 mImageEncodeParms.output_picture_height = mActualPictHeight; 2645 } 2646 mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw; 2647 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) 2648 mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw; 2649 /* TODO: check this */ 2650 mImageEncodeParms.y_offset = 0; 2651 for(int i = 0; i < size; i++){ 2652 memset(&mEncodeOutputBuffer[i], 0, sizeof(mm_camera_buffer_t)); 2653 mEncodeOutputBuffer[i].ptr = (uint8_t *)mJpegMapped[i]->data; 2654 mEncodeOutputBuffer[i].filled_size = mJpegMaxSize; 2655 mEncodeOutputBuffer[i].size = mJpegMaxSize; 2656 mEncodeOutputBuffer[i].fd = mJpegfd[i]; 2657 mEncodeOutputBuffer[i].offset = 0; 2658 } 2659 mImageEncodeParms.p_output_buffer = mEncodeOutputBuffer; 2660 mImageEncodeParms.exif_data = exif_data; 2661 mImageEncodeParms.exif_numEntries = exif_table_numEntries; 2662 2663 mImageEncodeParms.format3d = mIs3DModeOn; 2664 return true; 2665 } 2666 2667 bool QualcommCameraHardware::native_set_parms( 2668 camera_parm_type_t type, uint16_t length, void *value) 2669 { 2670 if(mCfgControl.mm_camera_set_parm(type,value) != MM_CAMERA_SUCCESS) { 2671 ALOGE("native_set_parms failed: type %d length %d error %s", 2672 type, length, strerror(errno)); 2673 return false; 2674 } 2675 return true; 2676 2677 } 2678 bool QualcommCameraHardware::native_set_parms( 2679 camera_parm_type_t type, uint16_t length, void *value, int *result) 2680 { 2681 mm_camera_status_t status; 2682 status = mCfgControl.mm_camera_set_parm(type,value); 2683 ALOGI("native_set_parms status = %d", status); 2684 if( status == MM_CAMERA_SUCCESS || status == MM_CAMERA_ERR_INVALID_OPERATION){ 2685 *result = status ; 2686 return true; 2687 } 2688 ALOGE("%s: type %d length %d error %s, status %d", __FUNCTION__, 2689 type, length, strerror(errno), status); 2690 *result = status; 2691 return false; 2692 } 2693 2694 void QualcommCameraHardware::jpeg_set_location() 2695 { 2696 bool encode_location = true; 2697 camera_position_type pt; 2698 2699 #define PARSE_LOCATION(what,type,fmt,desc) do { \ 2700 pt.what = 0; \ 2701 const char *what##_str = mParameters.get("gps-"#what); \ 2702 ALOGI("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \ 2703 if (what##_str) { \ 2704 type what = 0; \ 2705 if (sscanf(what##_str, fmt, &what) == 1) \ 2706 pt.what = what; \ 2707 else { \ 2708 ALOGE("GPS " #what " %s could not" \ 2709 " be parsed as a " #desc, what##_str); \ 2710 encode_location = false; \ 2711 } \ 2712 } \ 2713 else { \ 2714 ALOGI("GPS " #what " not specified: " \ 2715 "defaulting to zero in EXIF header."); \ 2716 encode_location = false; \ 2717 } \ 2718 } while(0) 2719 2720 PARSE_LOCATION(timestamp, long, "%ld", "long"); 2721 if (!pt.timestamp) pt.timestamp = time(NULL); 2722 PARSE_LOCATION(altitude, short, "%hd", "short"); 2723 PARSE_LOCATION(latitude, double, "%lf", "double float"); 2724 PARSE_LOCATION(longitude, double, "%lf", "double float"); 2725 2726 #undef PARSE_LOCATION 2727 2728 if (encode_location) { 2729 ALOGI("setting image location ALT %d LAT %lf LON %lf", 2730 pt.altitude, pt.latitude, pt.longitude); 2731 2732 setGpsParameters(); 2733 /* Disabling until support is available. 2734 if (!LINK_jpeg_encoder_setLocation(&pt)) { 2735 ALOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed."); 2736 } 2737 */ 2738 } 2739 else ALOGI("not setting image location"); 2740 } 2741 2742 static bool register_buf(int size, 2743 int frame_size, 2744 int cbcr_offset, 2745 int yoffset, 2746 int pmempreviewfd, 2747 uint32_t offset, 2748 uint8_t *buf, 2749 int pmem_type, 2750 bool vfe_can_write, 2751 bool register_buffer, 2752 bool use_all_chnls) 2753 { 2754 struct msm_pmem_info pmemBuf; 2755 CAMERA_HAL_UNUSED(frame_size); 2756 2757 memset(&pmemBuf, 0, sizeof(struct msm_pmem_info)); 2758 pmemBuf.type = pmem_type; 2759 pmemBuf.fd = pmempreviewfd; 2760 pmemBuf.offset = offset; 2761 pmemBuf.len = size; 2762 pmemBuf.vaddr = buf; 2763 pmemBuf.planar0_off = yoffset; 2764 if(!use_all_chnls) { 2765 ALOGI("use_all_chnls = %d\n", use_all_chnls); 2766 pmemBuf.planar1_off = cbcr_offset; 2767 pmemBuf.planar2_off = yoffset; 2768 } else { 2769 pmemBuf.planar1_off = myv12_params.CbOffset; 2770 pmemBuf.planar2_off = myv12_params.CrOffset; 2771 } 2772 ALOGI("register_buf: CbOff = 0x%x CrOff = 0x%x", 2773 pmemBuf.planar1_off, pmemBuf.planar2_off); 2774 2775 pmemBuf.active = vfe_can_write; 2776 2777 ALOGI("register_buf: reg = %d buffer = %p", 2778 !register_buffer, buf); 2779 if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER : 2780 CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) { 2781 ALOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM error %s", 2782 strerror(errno)); 2783 return false; 2784 } 2785 2786 return true; 2787 2788 } 2789 2790 static bool register_buf(int size, 2791 int frame_size, 2792 int cbcr_offset, 2793 int yoffset, 2794 int pmempreviewfd, 2795 uint32_t offset, 2796 uint8_t *buf, 2797 int pmem_type, 2798 bool vfe_can_write, 2799 bool register_buffer = true, 2800 bool use_all_chnls = false); 2801 2802 void QualcommCameraHardware::runFrameThread(void *data) 2803 { 2804 ALOGV("runFrameThread E"); 2805 int type; 2806 int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 2807 2808 if(libmmcamera) 2809 { 2810 LINK_cam_frame(data); 2811 } 2812 //waiting for preview thread to complete before clearing of the buffers 2813 mPreviewThreadWaitLock.lock(); 2814 while (mPreviewThreadRunning) { 2815 ALOGI("runframethread: waiting for preview thread to complete."); 2816 mPreviewThreadWait.wait(mPreviewThreadWaitLock); 2817 ALOGI("initPreview: old preview thread completed."); 2818 } 2819 mPreviewThreadWaitLock.unlock(); 2820 2821 // Cancelling previewBuffers and returning them to display before stopping preview 2822 // This will ensure that all preview buffers are available for dequeing when 2823 //startPreview is called again with the same ANativeWindow object (snapshot case). If the 2824 //ANativeWindow is a new one(camera-camcorder switch case) because the app passed a new 2825 //surface then buffers will be re-allocated and not returned from the old pool. 2826 relinquishBuffers(); 2827 mPreviewBusyQueue.flush(); 2828 /* Flush the Free Q */ 2829 LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME); 2830 2831 if(mIs3DModeOn != true) { 2832 #if 0 2833 if(mInHFRThread == false) 2834 { 2835 mPmemWaitLock.lock(); 2836 //mPreviewHeap.clear(); 2837 // TODO do properly 2838 mPrevHeapDeallocRunning = true; 2839 mPmemWait.signal(); 2840 mPmemWaitLock.unlock(); 2841 2842 if(( mPreviewFormat == CAMERA_YUV_420_YV12 )&& 2843 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) && 2844 previewWidth%32 != 0 ) 2845 mYV12Heap.clear(); 2846 2847 } 2848 else 2849 #endif 2850 { 2851 int mBufferSize = previewWidth * previewHeight * 3/2; 2852 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 2853 ALOGI("unregistering all preview buffers"); 2854 //unregister preview buffers. we are not deallocating here. 2855 for (int cnt = 0; cnt < mTotalPreviewBufferCount; ++cnt) { 2856 register_buf(mBufferSize, 2857 mBufferSize, 2858 mCbCrOffset, 2859 0, 2860 frames[cnt].fd, 2861 0, 2862 (uint8_t *)frames[cnt].buffer, 2863 MSM_PMEM_PREVIEW, 2864 false, 2865 false, 2866 true); 2867 //mPreviewHeap[cnt].clear(); 2868 // TODO : clean properly 2869 } 2870 } 2871 } 2872 if(!mZslEnable) { 2873 if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)){ 2874 if(mHFRMode != true) { 2875 #if 0 2876 mRecordHeap.clear(); 2877 mRecordHeap = NULL; 2878 #endif 2879 } else { 2880 ALOGI("%s: unregister record buffers with camera driver", __FUNCTION__); 2881 register_record_buffers(false); 2882 } 2883 int CbCrOffset = PAD_TO_2K(mDimension.video_width * mDimension.video_height); 2884 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) { 2885 #if 0 2886 if (mRecordfd[cnt] > 0) { 2887 ALOGE("Unregistering buffer %d with kernel",cnt); 2888 register_buf(mRecordFrameSize, 2889 mRecordFrameSize, CbCrOffset, 0, 2890 mRecordfd[cnt], 2891 0, 2892 (uint8_t *)recordframes[cnt].buffer, 2893 MSM_PMEM_VIDEO, 2894 false, false); 2895 ALOGE("Came back from register call to kernel"); 2896 } 2897 #endif 2898 type = MSM_PMEM_VIDEO; 2899 ALOGI("%s: unregister record buffers[%d] with camera driver", __FUNCTION__, cnt); 2900 if(recordframes) { 2901 register_buf(mRecordFrameSize, 2902 mRecordFrameSize, CbCrOffset, 0, 2903 recordframes[cnt].fd, 2904 0, 2905 (uint8_t *)recordframes[cnt].buffer, 2906 type, 2907 false,false); 2908 if(mRecordMapped[cnt]) { 2909 mRecordMapped[cnt]->release(mRecordMapped[cnt]); 2910 mRecordMapped[cnt] = NULL; 2911 close(mRecordfd[cnt]); 2912 if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){ 2913 struct encoder_media_buffer_type * packet = 2914 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 2915 native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle)); 2916 metadata_memory[cnt]->release(metadata_memory[cnt]); 2917 metadata_memory[cnt] = NULL; 2918 } 2919 #ifdef USE_ION 2920 deallocate_ion_memory(&record_main_ion_fd[cnt], &record_ion_info_fd[cnt]); 2921 #endif 2922 } 2923 } 2924 } 2925 } 2926 } 2927 2928 mFrameThreadWaitLock.lock(); 2929 mFrameThreadRunning = false; 2930 mFrameThreadWait.signal(); 2931 mFrameThreadWaitLock.unlock(); 2932 2933 ALOGV("runFrameThread X"); 2934 } 2935 2936 2937 void QualcommCameraHardware::runPreviewThread(void *data) 2938 { 2939 static int hfr_count = 0; 2940 msm_frame* frame = NULL; 2941 status_t retVal = NO_ERROR; 2942 CAMERA_HAL_UNUSED(data); 2943 android_native_buffer_t *buffer; 2944 buffer_handle_t *handle = NULL; 2945 int bufferIndex = 0; 2946 2947 while((frame = mPreviewBusyQueue.get()) != NULL) { 2948 if (UNLIKELY(mDebugFps)) { 2949 debugShowPreviewFPS(); 2950 } 2951 mCallbackLock.lock(); 2952 int msgEnabled = mMsgEnabled; 2953 camera_data_callback pcb = mDataCallback; 2954 void *pdata = mCallbackCookie; 2955 camera_data_timestamp_callback rcb = mDataCallbackTimestamp; 2956 void *rdata = mCallbackCookie; 2957 camera_data_callback mcb = mDataCallback; 2958 void *mdata = mCallbackCookie; 2959 mCallbackLock.unlock(); 2960 2961 // signal smooth zoom thread , that a new preview frame is available 2962 mSmoothzoomThreadWaitLock.lock(); 2963 if(mSmoothzoomThreadRunning) { 2964 mSmoothzoomThreadWait.signal(); 2965 } 2966 mSmoothzoomThreadWaitLock.unlock(); 2967 2968 // Find the offset within the heap of the current buffer. 2969 ssize_t offset_addr = 0; // TODO , use proper value 2970 // (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base(); 2971 // ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize; 2972 common_crop_t *crop = (common_crop_t *) (frame->cropinfo); 2973 #ifdef DUMP_PREVIEW_FRAMES 2974 static int frameCnt = 0; 2975 int written; 2976 if (frameCnt >= 0 && frameCnt <= 10 ) { 2977 char buf[128]; 2978 snprintf(buffer, sizeof(buf), "/data/%d_preview.yuv", frameCnt); 2979 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2980 ALOGI("dumping preview frame %d", frameCnt); 2981 if (file_fd < 0) { 2982 ALOGE("cannot open file\n"); 2983 } 2984 else 2985 { 2986 ALOGI("dumping data"); 2987 written = write(file_fd, (uint8_t *)frame->buffer, 2988 mPreviewFrameSize ); 2989 if(written < 0) 2990 ALOGE("error in data write"); 2991 } 2992 close(file_fd); 2993 } 2994 frameCnt++; 2995 #endif 2996 mInPreviewCallback = true; 2997 if (crop->in1_w != 0 && crop->in1_h != 0) { 2998 zoomCropInfo.left = (crop->out1_w - crop->in1_w + 1) / 2 - 1; 2999 zoomCropInfo.top = (crop->out1_h - crop->in1_h + 1) / 2 - 1; 3000 /* There can be scenarios where the in1_wXin1_h and 3001 * out1_wXout1_h are same. In those cases, reset the 3002 * x and y to zero instead of negative for proper zooming 3003 */ 3004 if(zoomCropInfo.left < 0) zoomCropInfo.left = 0; 3005 if(zoomCropInfo.top < 0) zoomCropInfo.top = 0; 3006 zoomCropInfo.right = zoomCropInfo.left + crop->in1_w; 3007 zoomCropInfo.bottom = zoomCropInfo.top + crop->in1_h; 3008 mPreviewWindow-> set_crop (mPreviewWindow, 3009 zoomCropInfo.left, 3010 zoomCropInfo.top, 3011 zoomCropInfo.right, 3012 zoomCropInfo.bottom); 3013 /* Set mResetOverlayCrop to true, so that when there is 3014 * no crop information, setCrop will be called 3015 * with zero crop values. 3016 */ 3017 mResetWindowCrop = true; 3018 3019 } else { 3020 // Reset zoomCropInfo variables. This will ensure that 3021 // stale values wont be used for postview 3022 zoomCropInfo.left = 0; 3023 zoomCropInfo.top = 0; 3024 zoomCropInfo.right = crop->in1_w; 3025 zoomCropInfo.bottom = crop->in1_h; 3026 /* This reset is required, if not, overlay driver continues 3027 * to use the old crop information for these preview 3028 * frames which is not the correct behavior. To avoid 3029 * multiple calls, reset once. 3030 */ 3031 if(mResetWindowCrop == true){ 3032 mPreviewWindow-> set_crop (mPreviewWindow, 3033 zoomCropInfo.left, 3034 zoomCropInfo.top, 3035 zoomCropInfo.right, 3036 zoomCropInfo.bottom); 3037 mResetWindowCrop = false; 3038 } 3039 } 3040 /* To overcome a timing case where we could be having the overlay refer to deallocated 3041 mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the 3042 first preview frame is queued to the overlay in 8660. Also adding the condition 3043 to check if snapshot is currently in progress ensures that the resources being 3044 used by the snapshot thread are not incorrectly deallocated by preview thread*/ 3045 if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) { 3046 ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated"); 3047 mThumbnailHeap.clear(); 3048 mDisplayHeap.clear(); 3049 if(!mZslEnable){ 3050 mDisplayHeap.clear(); 3051 mPostviewHeap.clear(); 3052 } 3053 mFirstFrame = false; 3054 } 3055 mLastQueuedFrame = (void *)frame->buffer; 3056 bufferIndex = mapBuffer(frame); 3057 3058 // if 7x27A && yv12 is set as preview format use convert routines to 3059 // convert from YUV420sp to YV12 3060 yuv_image_type in_buf, out_buf; 3061 int conversion_result = 0; 3062 3063 if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) && 3064 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 )){ 3065 // if the width is not multiple of 32, 3066 //we cannot do inplace conversion as sizes of 420sp and YV12 frames differ 3067 if(previewWidth%32){ 3068 #if 0 //TODO : 3069 ALOGE("YV12::Doing not inplace conversion from 420sp to yv12"); 3070 in_buf.imgPtr = (unsigned char*)mPreviewMapped[bufferIndex]->data; 3071 in_buf.dx = out_buf.dx = previewWidth; 3072 in_buf.dy = in_buf.dy = previewHeight; 3073 conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12(&in_buf, &out_buf); 3074 #endif 3075 } else { 3076 ALOGI("Doing inplace conversion from 420sp to yv12"); 3077 in_buf.imgPtr = (unsigned char *)mPreviewMapped[bufferIndex]->data; 3078 in_buf.dx = previewWidth; 3079 in_buf.dy = previewHeight; 3080 conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12_inplace(&in_buf); 3081 } 3082 } 3083 3084 if(bufferIndex >= 0) { 3085 //Need to encapsulate this in IMemory object and send 3086 3087 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME)) { 3088 int previewBufSize; 3089 /* for CTS : Forcing preview memory buffer lenth to be 3090 'previewWidth * previewHeight * 3/2'. Needed when gralloc allocated extra memory.*/ 3091 if( mPreviewFormat == CAMERA_YUV_420_NV21 || mPreviewFormat == CAMERA_YUV_420_YV12) { 3092 previewBufSize = previewWidth * previewHeight * 3/2; 3093 camera_memory_t *previewMem = mGetMemory(frames[bufferIndex].fd, previewBufSize, 3094 1, mCallbackCookie); 3095 if (!previewMem || !previewMem->data) { 3096 ALOGE("%s: mGetMemory failed.\n", __func__); 3097 } else { 3098 pcb(CAMERA_MSG_PREVIEW_FRAME,previewMem,0,NULL,pdata); 3099 previewMem->release(previewMem); 3100 } 3101 } else 3102 pcb(CAMERA_MSG_PREVIEW_FRAME,(camera_memory_t *) mPreviewMapped[bufferIndex],0,NULL,pdata); 3103 } 3104 3105 // TODO : may have to reutn proper frame as pcb 3106 mDisplayLock.lock(); 3107 if( mPreviewWindow != NULL) { 3108 if (BUFFER_LOCKED == frame_buffer[bufferIndex].lockState) { 3109 if (GENLOCK_FAILURE == genlock_unlock_buffer( 3110 (native_handle_t*)(*(frame_buffer[bufferIndex].buffer)))) { 3111 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 3112 mDisplayLock.unlock(); 3113 } else { 3114 frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED; 3115 } 3116 } else { 3117 ALOGI("%s: buffer to be enqueued is unlocked", __FUNCTION__); 3118 mDisplayLock.unlock(); 3119 } 3120 const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 3121 if(str != NULL){ 3122 int is_hfr_off = 0; 3123 hfr_count++; 3124 if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) { 3125 is_hfr_off = 1; 3126 retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow, 3127 frame_buffer[bufferIndex].buffer); 3128 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) { 3129 hfr_count %= 2; 3130 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) { 3131 hfr_count %= 3; 3132 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) { 3133 hfr_count %= 4; 3134 } 3135 if(hfr_count == 0) 3136 retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow, 3137 frame_buffer[bufferIndex].buffer); 3138 else if(!is_hfr_off) 3139 retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 3140 frame_buffer[bufferIndex].buffer); 3141 } else 3142 retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow, 3143 frame_buffer[bufferIndex].buffer); 3144 if( retVal != NO_ERROR) 3145 ALOGE("%s: Failed while queueing buffer %d for display." 3146 " Error = %d", __FUNCTION__, 3147 frames[bufferIndex].fd, retVal); 3148 int stride; 3149 retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow, 3150 &(handle),&(stride)); 3151 private_handle_t *bhandle = (private_handle_t *)(*handle); 3152 if( retVal != NO_ERROR) { 3153 ALOGE("%s: Failed while dequeueing buffer from display." 3154 " Error = %d", __FUNCTION__, retVal); 3155 } else { 3156 retVal = mPreviewWindow->lock_buffer(mPreviewWindow,handle); 3157 //yyan todo use handle to find out buffer 3158 if(retVal != NO_ERROR) 3159 ALOGE("%s: Failed while dequeueing buffer from" 3160 "display. Error = %d", __FUNCTION__, retVal); 3161 } 3162 } 3163 mDisplayLock.unlock(); 3164 } else 3165 ALOGE("Could not find the buffer"); 3166 3167 // If output is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..) 3168 3169 nsecs_t timeStamp = nsecs_t(frame->ts.tv_sec)*1000000000LL + frame->ts.tv_nsec; 3170 3171 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) { 3172 int flagwait = 1; 3173 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) && (record_flag)) { 3174 if(mStoreMetaDataInFrame){ 3175 flagwait = 1; 3176 if(metadata_memory[bufferIndex]!= NULL) 3177 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[bufferIndex],0,rdata); 3178 else flagwait = 0; 3179 } else { 3180 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mPreviewMapped[bufferIndex],0, rdata); 3181 } 3182 if(flagwait){ 3183 Mutex::Autolock rLock(&mRecordFrameLock); 3184 if (mReleasedRecordingFrame != true) { 3185 mRecordWait.wait(mRecordFrameLock); 3186 } 3187 mReleasedRecordingFrame = false; 3188 } 3189 } 3190 } 3191 3192 if ( mCurrentTarget == TARGET_MSM8660 ) { 3193 mMetaDataWaitLock.lock(); 3194 if (mFaceDetectOn == true && mSendMetaData == true) { 3195 mSendMetaData = false; 3196 fd_roi_t *roi = (fd_roi_t *)(frame->roi_info.info); 3197 3198 switch (roi->type) { 3199 case FD_ROI_TYPE_HEADER: 3200 { 3201 mNumFDRcvd = 0; 3202 memset(mFaceArray, -1, sizeof(mFaceArray)); 3203 mFaceArray[0] = 0; //faces_detected * 4; 3204 3205 mFacesDetected = roi->d.hdr.num_face_detected; 3206 if(mFacesDetected > MAX_ROI) 3207 mFacesDetected = MAX_ROI; 3208 } 3209 break; 3210 case FD_ROI_TYPE_DATA: 3211 { 3212 int idx = roi->d.data.idx; 3213 if (idx < mFacesDetected) { 3214 mFaceArray[idx*4+1] = roi->d.data.face.face_boundary.x; 3215 mFaceArray[idx*4+2] = roi->d.data.face.face_boundary.y; 3216 mFaceArray[idx*4+3] = roi->d.data.face.face_boundary.x; 3217 mFaceArray[idx*4+4] = roi->d.data.face.face_boundary.y; 3218 mNumFDRcvd++; 3219 if (mNumFDRcvd == mFacesDetected) { 3220 mFaceArray[0] = mFacesDetected * 4; 3221 if(mMetaDataHeap != NULL){ 3222 ALOGV("runPreviewThread mMetaDataHEap is non-NULL"); 3223 memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)mFaceArray, sizeof(mFaceArray)); 3224 } 3225 } 3226 } 3227 } 3228 break; 3229 } 3230 } 3231 mMetaDataWaitLock.unlock(); 3232 } 3233 bufferIndex = mapFrame(handle); 3234 if(bufferIndex >= 0) { 3235 LINK_camframe_add_frame(CAM_PREVIEW_FRAME, &frames[bufferIndex]); 3236 private_handle_t *bhandle = (private_handle_t *)(*handle); 3237 if (GENLOCK_NO_ERROR != genlock_lock_buffer(bhandle, GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 3238 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 3239 frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED; 3240 } else { 3241 frame_buffer[bufferIndex].lockState = BUFFER_LOCKED; 3242 } 3243 } else { 3244 ALOGE("Could not find the Frame"); 3245 3246 // Special Case: Stoppreview is issued which causes thumbnail buffer 3247 // to be cancelled. Frame thread has still not exited. In preview thread 3248 // dequeue returns incorrect buffer id (previously cancelled thumbnail buffer) 3249 // This will throw error "Could not find frame". We need to cancel the incorrectly 3250 // dequeued buffer here to ensure that all buffers are available for the next 3251 // startPreview call. 3252 3253 mDisplayLock.lock(); 3254 ALOGV(" error Cancelling preview buffers "); 3255 retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 3256 handle); 3257 if(retVal != NO_ERROR) 3258 ALOGE("%s: cancelBuffer failed for buffer", __FUNCTION__); 3259 mDisplayLock.unlock(); 3260 } 3261 } 3262 mPreviewThreadWaitLock.lock(); 3263 mPreviewThreadRunning = false; 3264 mPreviewThreadWait.signal(); 3265 mPreviewThreadWaitLock.unlock(); 3266 } 3267 int QualcommCameraHardware::mapBuffer(struct msm_frame *frame) { 3268 int ret = -1; 3269 for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 3270 if (frame_buffer[cnt].frame->buffer == frame->buffer) { 3271 ret = cnt; 3272 break; 3273 } 3274 } 3275 return ret; 3276 } 3277 int QualcommCameraHardware::mapvideoBuffer(struct msm_frame *frame) 3278 { 3279 int ret = -1; 3280 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) { 3281 if ((unsigned int)mRecordMapped[cnt]->data == (unsigned int)frame->buffer) { 3282 ret = cnt; 3283 ALOGI("found match returning %d", ret); 3284 break; 3285 } 3286 } 3287 return ret; 3288 3289 } 3290 int QualcommCameraHardware::mapRawBuffer(struct msm_frame *frame) 3291 { 3292 int ret = -1; 3293 for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) { 3294 if ((unsigned int)mRawMapped[cnt]->data == (unsigned int)frame->buffer) { 3295 ret = cnt; 3296 ALOGI("found match returning %d", ret); 3297 break; 3298 } 3299 } 3300 return ret; 3301 } 3302 int QualcommCameraHardware::mapThumbnailBuffer(struct msm_frame *frame) 3303 { 3304 int ret = -1; 3305 for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) { 3306 if ((unsigned int)(uint8_t *)mThumbnailMapped[cnt] == (unsigned int)frame->buffer) { 3307 ret = cnt; 3308 ALOGI("found match returning %d", ret); 3309 break; 3310 } 3311 } 3312 if(ret < 0) ALOGE("mapThumbnailBuffer, could not find match"); 3313 return ret; 3314 } 3315 int QualcommCameraHardware::mapJpegBuffer(mm_camera_buffer_t *encode_buffer) 3316 { 3317 int ret = -1; 3318 for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) { 3319 if ((unsigned int)mJpegMapped[cnt]->data == (unsigned int)encode_buffer->ptr) { 3320 ret = cnt; 3321 ALOGI("found match returning %d", ret); 3322 break; 3323 } 3324 } 3325 return ret; 3326 } 3327 int QualcommCameraHardware::mapFrame(buffer_handle_t *buffer) { 3328 int ret = -1; 3329 for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 3330 if (frame_buffer[cnt].buffer == buffer) { 3331 ret = cnt; 3332 break; 3333 } 3334 } 3335 return ret; 3336 } 3337 3338 void *preview_thread(void *user) 3339 { 3340 ALOGV("preview_thread E"); 3341 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 3342 if (obj != 0) { 3343 obj->runPreviewThread(user); 3344 } 3345 else ALOGE("not starting preview thread: the object went away!"); 3346 ALOGV("preview_thread X"); 3347 return NULL; 3348 } 3349 3350 void *hfr_thread(void *user) 3351 { 3352 ALOGV("hfr_thread E"); 3353 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 3354 if (obj != 0) { 3355 obj->runHFRThread(user); 3356 } 3357 else ALOGE("not starting hfr thread: the object went away!"); 3358 ALOGV("hfr_thread X"); 3359 return NULL; 3360 } 3361 3362 void QualcommCameraHardware::runHFRThread(void *data) 3363 { 3364 ALOGV("runHFRThread E"); 3365 mInHFRThread = true; 3366 CAMERA_HAL_UNUSED(data); 3367 ALOGI("%s: stopping Preview", __FUNCTION__); 3368 stopPreviewInternal(); 3369 3370 // Release thumbnail Buffers 3371 if( mPreviewWindow != NULL ) { 3372 private_handle_t *handle; 3373 for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) { 3374 if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) { 3375 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]); 3376 ALOGV("%s: Cancelling postview buffer %d ", __FUNCTION__, handle->fd); 3377 ALOGV("runHfrThread : display lock"); 3378 mDisplayLock.lock(); 3379 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) { 3380 if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) { 3381 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 3382 mDisplayLock.unlock(); 3383 continue; 3384 } else { 3385 mThumbnailLockState[cnt] = BUFFER_UNLOCKED; 3386 } 3387 } 3388 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 3389 mThumbnailBuffer[cnt]); 3390 if(retVal != NO_ERROR) 3391 ALOGE("%s: cancelBuffer failed for postview buffer %d", 3392 __FUNCTION__, handle->fd); 3393 // unregister , unmap and release as well 3394 int mBufferSize = previewWidth * previewHeight * 3/2; 3395 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 3396 if(mThumbnailMapped[cnt] && (mSnapshotFormat == PICTURE_FORMAT_JPEG)) { 3397 ALOGI("%s: Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd); 3398 register_buf(mBufferSize, 3399 mBufferSize, mCbCrOffset, 0, 3400 handle->fd, 3401 0, 3402 (uint8_t *)mThumbnailMapped[cnt], 3403 MSM_PMEM_THUMBNAIL, 3404 false, false); 3405 if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) { 3406 ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index); 3407 } 3408 mThumbnailBuffer[cnt] = NULL; 3409 mThumbnailMapped[cnt] = NULL; 3410 } 3411 ALOGV("runHfrThread : display unlock"); 3412 mDisplayLock.unlock(); 3413 } 3414 } 3415 } 3416 3417 ALOGV("%s: setting parameters", __FUNCTION__); 3418 setParameters(mParameters); 3419 ALOGV("%s: starting Preview", __FUNCTION__); 3420 if( mPreviewWindow == NULL) 3421 { 3422 startPreviewInternal(); 3423 } 3424 else { 3425 getBuffersAndStartPreview(); 3426 } 3427 3428 mHFRMode = false; 3429 mInHFRThread = false; 3430 } 3431 3432 void QualcommCameraHardware::runVideoThread(void *data) 3433 { 3434 ALOGV("runVideoThread E"); 3435 msm_frame* vframe = NULL; 3436 CAMERA_HAL_UNUSED(data); 3437 3438 while(true) { 3439 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 3440 3441 // Exit the thread , in case of stop recording.. 3442 mVideoThreadWaitLock.lock(); 3443 if(mVideoThreadExit){ 3444 ALOGV("Exiting video thread.."); 3445 mVideoThreadWaitLock.unlock(); 3446 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 3447 break; 3448 } 3449 mVideoThreadWaitLock.unlock(); 3450 3451 ALOGV("in video_thread : wait for video frame "); 3452 // check if any frames are available in busyQ and give callback to 3453 // services/video encoder 3454 cam_frame_wait_video(); 3455 ALOGV("video_thread, wait over.."); 3456 3457 // Exit the thread , in case of stop recording.. 3458 mVideoThreadWaitLock.lock(); 3459 if(mVideoThreadExit){ 3460 ALOGV("Exiting video thread.."); 3461 mVideoThreadWaitLock.unlock(); 3462 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 3463 break; 3464 } 3465 mVideoThreadWaitLock.unlock(); 3466 3467 // Get the video frame to be encoded 3468 vframe = cam_frame_get_video (); 3469 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 3470 ALOGI("in video_thread : got video frame %x",vframe); 3471 3472 /*if (UNLIKELY(mDebugFps)) { 3473 debugShowVideoFPS(); 3474 }*/ 3475 3476 if(vframe != NULL) { 3477 // Find the offset within the heap of the current buffer. 3478 //ALOGV("Got video frame : buffer %d base %d ", vframe->buffer, 3479 //(unsigned long int)mRecordHeap->mHeap->base()); 3480 //ssize_t offset = 3481 // (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base(); 3482 //ALOGV("offset = %d , alignsize = %d , new_offset = %d", (int)offset, mRecordHeap->mAlignedBufferSize, 3483 // (int)(offset / mRecordHeap->mAlignedBufferSize)); 3484 3485 //offset /= mRecordHeap->mAlignedBufferSize; 3486 3487 //set the track flag to true for this video buffer 3488 //record_buffers_tracking_flag[offset] = true; 3489 3490 /* Extract the timestamp of this frame */ 3491 nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec; 3492 3493 // dump frames for test purpose 3494 #if 0 3495 static int frameCnt = 0; 3496 if (frameCnt >= 11 && frameCnt <= 13 ) { 3497 char buf[128]; 3498 sprintf(buf, "/data/%d_v.yuv", frameCnt); 3499 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 3500 ALOGV("dumping video frame %d", frameCnt); 3501 if (file_fd < 0) { 3502 ALOGE("cannot open file\n"); 3503 } 3504 else 3505 { 3506 write(file_fd, (const void *)vframe->buffer, 3507 vframe->cbcr_off * 3 / 2); 3508 } 3509 close(file_fd); 3510 } 3511 frameCnt++; 3512 #endif 3513 #if 0 3514 if(mIs3DModeOn ) { 3515 /* VPE will be taking care of zoom, so no need to 3516 * use overlay's setCrop interface for zoom 3517 * functionality. 3518 */ 3519 /* get the offset of current video buffer for rendering */ 3520 ssize_t offset_addr = (ssize_t)vframe->buffer - 3521 (ssize_t)mRecordHeap->mHeap->base(); 3522 /* To overcome a timing case where we could be having the overlay refer to deallocated 3523 mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the 3524 first preview frame is queued to the overlay in 8660 */ 3525 if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) { 3526 ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated"); 3527 mThumbnailHeap.clear(); 3528 mDisplayHeap.clear(); 3529 mFirstFrame = false; 3530 mPostviewHeap.clear(); 3531 } 3532 mLastQueuedFrame = (void *)vframe->buffer; 3533 } 3534 #endif 3535 // Enable IF block to give frames to encoder , ELSE block for just simulation 3536 #if 1 3537 ALOGV("in video_thread : got video frame, before if check giving frame to services/encoder"); 3538 mCallbackLock.lock(); 3539 int msgEnabled = mMsgEnabled; 3540 camera_data_timestamp_callback rcb = mDataCallbackTimestamp; 3541 void *rdata = mCallbackCookie; 3542 mCallbackLock.unlock(); 3543 3544 /* When 3D mode is ON, the video thread will be ON even in preview 3545 * mode. We need to distinguish when recording is started. So, when 3546 * 3D mode is ON, check for the recordingState (which will be set 3547 * with start recording and reset in stop recording), before 3548 * calling rcb. 3549 */ 3550 int index = mapvideoBuffer(vframe); 3551 if(!mIs3DModeOn) { 3552 record_buffers_tracking_flag[index] = true; 3553 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) { 3554 ALOGV("in video_thread : got video frame, giving frame to services/encoder index = %d", index); 3555 if(mStoreMetaDataInFrame){ 3556 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[index],0,rdata); 3557 } else { 3558 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordMapped[index],0,rdata); 3559 } 3560 } 3561 } 3562 #if 0 3563 else { 3564 mCallbackLock.lock(); 3565 msgEnabled = mMsgEnabled; 3566 data_callback pcb = mDataCallback; 3567 void *pdata = mCallbackCookie; 3568 mCallbackLock.unlock(); 3569 if (pcb != NULL) { 3570 ALOGE("pcb is not null"); 3571 static int count = 0; 3572 //if(msgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 3573 if (!count) { 3574 ALOGE("Giving first frame to app"); 3575 pcb(CAMERA_MSG_PREVIEW_FRAME, mRecordHeap->mBuffers[offset], 3576 pdata); 3577 count++; 3578 } 3579 } 3580 if(mRecordingState == 1) { 3581 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) { 3582 ALOGV("in video_thread 3D mode : got video frame, giving frame to services/encoder"); 3583 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata); 3584 } 3585 } else { 3586 /* When in preview mode, put the video buffer back into 3587 * free Q, for next availability. 3588 */ 3589 ALOGV("in video_thread 3D mode : got video frame, putting frame to Free Q"); 3590 record_buffers_tracking_flag[offset] = false; 3591 LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe); 3592 } 3593 } 3594 #endif 3595 #else 3596 // 720p output2 : simulate release frame here: 3597 ALOGI("in video_thread simulation , releasing the video frame"); 3598 LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe); 3599 #endif 3600 3601 } else ALOGE("in video_thread get frame returned null"); 3602 3603 3604 } // end of while loop 3605 3606 mVideoThreadWaitLock.lock(); 3607 mVideoThreadRunning = false; 3608 mVideoThreadWait.signal(); 3609 mVideoThreadWaitLock.unlock(); 3610 3611 ALOGV("runVideoThread X"); 3612 } 3613 3614 void *video_thread(void *user) 3615 { 3616 ALOGV("video_thread E"); 3617 CAMERA_HAL_UNUSED(user); 3618 3619 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 3620 if (obj != 0) { 3621 obj->runVideoThread(user); 3622 } 3623 else ALOGE("not starting video thread: the object went away!"); 3624 ALOGV("video_thread X"); 3625 return NULL; 3626 } 3627 3628 void *frame_thread(void *user) 3629 { 3630 ALOGD("frame_thread E"); 3631 CAMERA_HAL_UNUSED(user); 3632 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 3633 if (obj != 0) { 3634 obj->runFrameThread(user); 3635 } 3636 else ALOGW("not starting frame thread: the object went away!"); 3637 ALOGD("frame_thread X"); 3638 return NULL; 3639 } 3640 3641 static int parse_size(const char *str, int &width, int &height) 3642 { 3643 // Find the width. 3644 char *end; 3645 int w = (int)strtol(str, &end, 10); 3646 // If an 'x' or 'X' does not immediately follow, give up. 3647 if ( (*end != 'x') && (*end != 'X') ) 3648 return -1; 3649 3650 // Find the height, immediately after the 'x'. 3651 int h = (int)strtol(end+1, 0, 10); 3652 3653 width = w; 3654 height = h; 3655 3656 return 0; 3657 } 3658 QualcommCameraHardware* hardware; 3659 3660 int QualcommCameraHardware::allocate_ion_memory(int *main_ion_fd, struct ion_allocation_data* alloc, 3661 struct ion_fd_data* ion_info_fd, int ion_type, int size, int *memfd) 3662 { 3663 int rc = 0; 3664 struct ion_handle_data handle_data; 3665 3666 *main_ion_fd = open("/dev/ion", O_RDONLY | O_SYNC); 3667 if (*main_ion_fd < 0) { 3668 ALOGE("Ion dev open failed\n"); 3669 ALOGE("Error is %s\n", strerror(errno)); 3670 goto ION_OPEN_FAILED; 3671 } 3672 alloc->len = size; 3673 /* to make it page size aligned */ 3674 alloc->len = (alloc->len + 4095) & (~4095); 3675 alloc->align = 4096; 3676 alloc->flags = 0; 3677 alloc->heap_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID); 3678 3679 rc = ioctl(*main_ion_fd, ION_IOC_ALLOC, alloc); 3680 if (rc < 0) { 3681 ALOGE("ION allocation failed\n"); 3682 goto ION_ALLOC_FAILED; 3683 } 3684 3685 ion_info_fd->handle = alloc->handle; 3686 rc = ioctl(*main_ion_fd, ION_IOC_SHARE, ion_info_fd); 3687 if (rc < 0) { 3688 ALOGE("ION map failed %s\n", strerror(errno)); 3689 goto ION_MAP_FAILED; 3690 } 3691 *memfd = ion_info_fd->fd; 3692 return 0; 3693 3694 ION_MAP_FAILED: 3695 handle_data.handle = ion_info_fd->handle; 3696 ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data); 3697 ION_ALLOC_FAILED: 3698 close(*main_ion_fd); 3699 ION_OPEN_FAILED: 3700 return -1; 3701 } 3702 int QualcommCameraHardware::deallocate_ion_memory(int *main_ion_fd, struct ion_fd_data* ion_info_fd) 3703 { 3704 struct ion_handle_data handle_data; 3705 int rc = 0; 3706 3707 handle_data.handle = ion_info_fd->handle; 3708 ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data); 3709 close(*main_ion_fd); 3710 return rc; 3711 } 3712 3713 bool QualcommCameraHardware::initPreview() 3714 { 3715 const char * pmem_region; 3716 int CbCrOffset = 0; 3717 int ion_heap; 3718 mParameters.getPreviewSize(&previewWidth, &previewHeight); 3719 const char *recordSize = NULL; 3720 recordSize = mParameters.get(QCameraParameters::KEY_VIDEO_SIZE); 3721 ALOGI("%s Got preview dimension as %d x %d ", __func__, previewWidth, previewHeight); 3722 if(!recordSize) { 3723 //If application didn't set this parameter string, use the values from 3724 //getPreviewSize() as video dimensions. 3725 ALOGV("No Record Size requested, use the preview dimensions"); 3726 videoWidth = previewWidth; 3727 videoHeight = previewHeight; 3728 } else { 3729 //Extract the record witdh and height that application requested. 3730 if(!parse_size(recordSize, videoWidth, videoHeight)) { 3731 //VFE output1 shouldn't be greater than VFE output2. 3732 if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) { 3733 //Set preview sizes as record sizes. 3734 ALOGI("Preview size %dx%d is greater than record size %dx%d,\ 3735 resetting preview size to record size",previewWidth,\ 3736 previewHeight, videoWidth, videoHeight); 3737 previewWidth = videoWidth; 3738 previewHeight = videoHeight; 3739 mParameters.setPreviewSize(previewWidth, previewHeight); 3740 } 3741 if( (mCurrentTarget != TARGET_MSM7630) 3742 && (mCurrentTarget != TARGET_QSD8250) 3743 && (mCurrentTarget != TARGET_MSM8660) ) { 3744 //For Single VFE output targets, use record dimensions as preview dimensions. 3745 previewWidth = videoWidth; 3746 previewHeight = videoHeight; 3747 mParameters.setPreviewSize(previewWidth, previewHeight); 3748 } 3749 } else { 3750 ALOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize); 3751 return false; 3752 } 3753 } 3754 3755 mDimension.display_width = previewWidth; 3756 mDimension.display_height= previewHeight; 3757 mDimension.ui_thumbnail_width = 3758 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width; 3759 mDimension.ui_thumbnail_height = 3760 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height; 3761 3762 ALOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight ); 3763 3764 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 3765 mDimension.video_width = CEILING16(videoWidth); 3766 /* Backup the video dimensions, as video dimensions in mDimension 3767 * will be modified when DIS is supported. Need the actual values 3768 * to pass ap part of VPE config 3769 */ 3770 videoWidth = mDimension.video_width; 3771 mDimension.video_height = videoHeight; 3772 ALOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, 3773 mDimension.video_width, mDimension.video_height); 3774 } 3775 3776 // See comments in deinitPreview() for why we have to wait for the frame 3777 // thread here, and why we can't use pthread_join(). 3778 mFrameThreadWaitLock.lock(); 3779 while (mFrameThreadRunning) { 3780 ALOGI("initPreview: waiting for old frame thread to complete."); 3781 mFrameThreadWait.wait(mFrameThreadWaitLock); 3782 ALOGI("initPreview: old frame thread completed."); 3783 } 3784 mFrameThreadWaitLock.unlock(); 3785 3786 mInSnapshotModeWaitLock.lock(); 3787 while (mInSnapshotMode) { 3788 ALOGI("initPreview: waiting for snapshot mode to complete."); 3789 mInSnapshotModeWait.wait(mInSnapshotModeWaitLock); 3790 ALOGI("initPreview: snapshot mode completed."); 3791 } 3792 mInSnapshotModeWaitLock.unlock(); 3793 3794 pmem_region = "/dev/pmem_adsp"; 3795 ion_heap = ION_CAMERA_HEAP_ID; 3796 3797 int cnt = 0; 3798 3799 memset(&myv12_params, 0, sizeof(yv12_format_parms_t)); 3800 mPreviewFrameSize = previewWidth * previewHeight * 3/2; 3801 ALOGI("Width = %d Height = %d \n", previewWidth, previewHeight); 3802 if(mPreviewFormat == CAMERA_YUV_420_YV12) { 3803 myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight); 3804 myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4); 3805 mDimension.prev_format = CAMERA_YUV_420_YV12; 3806 ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset); 3807 } else { 3808 CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 3809 } 3810 3811 //Pass the yuv formats, display dimensions, 3812 //so that vfe will be initialized accordingly. 3813 mDimension.display_luma_width = previewWidth; 3814 mDimension.display_luma_height = previewHeight; 3815 mDimension.display_chroma_width = previewWidth; 3816 mDimension.display_chroma_height = previewHeight; 3817 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) { 3818 mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) + 3819 2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2)); 3820 CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)); 3821 mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO; 3822 mDimension.display_luma_width = CEILING32(previewWidth); 3823 mDimension.display_luma_height = CEILING32(previewHeight); 3824 mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2); 3825 //Chroma Height is not needed as of now. Just sending with other dimensions. 3826 mDimension.display_chroma_height = CEILING32(previewHeight/2); 3827 } 3828 ALOGV("mDimension.prev_format = %d", mDimension.prev_format); 3829 ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width); 3830 ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height); 3831 ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width); 3832 ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height); 3833 3834 dstOffset = 0; 3835 //set DIS value to get the updated video width and height to calculate 3836 //the required record buffer size 3837 if(mVpeEnabled) { 3838 bool status = setDIS(); 3839 if(status) { 3840 ALOGE("Failed to set DIS"); 3841 return false; 3842 } 3843 } 3844 3845 //Pass the original video width and height and get the required width 3846 //and height for record buffer allocation 3847 mDimension.orig_video_width = videoWidth; 3848 mDimension.orig_video_height = videoHeight; 3849 if(mZslEnable){ 3850 //Limitation of ZSL where the thumbnail and display dimensions should be the same 3851 mDimension.ui_thumbnail_width = mDimension.display_width; 3852 mDimension.ui_thumbnail_height = mDimension.display_height; 3853 mParameters.getPictureSize(&mPictureWidth, &mPictureHeight); 3854 if (updatePictureDimension(mParameters, mPictureWidth, 3855 mPictureHeight)) { 3856 mDimension.picture_width = mPictureWidth; 3857 mDimension.picture_height = mPictureHeight; 3858 } 3859 } 3860 // mDimension will be filled with thumbnail_width, thumbnail_height, 3861 // orig_picture_dx, and orig_picture_dy after this function call. We need to 3862 // keep it for jpeg_encoder_encode. 3863 bool ret = native_set_parms(CAMERA_PARM_DIMENSION, 3864 sizeof(cam_ctrl_dimension_t), &mDimension); 3865 #if 0 3866 if(mIs3DModeOn != true) { 3867 if(mInHFRThread == false) 3868 { 3869 mPrevHeapDeallocRunning = false; 3870 #ifdef USE_ION 3871 mPreviewHeap = new IonPool(ion_heap, 3872 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 3873 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2, 3874 mPreviewFrameSize, 3875 kPreviewBufferCountActual, 3876 mPreviewFrameSize, 3877 CbCrOffset, 3878 0, 3879 "preview"); 3880 #else 3881 mPreviewHeap = new PmemPool(pmem_region, 3882 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 3883 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2, 3884 mPreviewFrameSize, 3885 kPreviewBufferCountActual, 3886 mPreviewFrameSize, 3887 CbCrOffset, 3888 0, 3889 "preview"); 3890 #endif 3891 if (!mPreviewHeap->initialized()) { 3892 mPreviewHeap.clear(); 3893 ALOGE("initPreview X: could not initialize Camera preview heap."); 3894 return false; 3895 } 3896 } 3897 else 3898 { 3899 for (int cnt = 0; cnt < kPreviewBufferCountActual; ++cnt) { 3900 bool status; 3901 int active = (cnt < ACTIVE_PREVIEW_BUFFERS); 3902 status = register_buf(mPreviewFrameSize, 3903 mPreviewFrameSize, 3904 CbCrOffset, 3905 0, 3906 mPreviewHeap->mHeap->getHeapID(), 3907 mPreviewHeap->mAlignedBufferSize * cnt, 3908 (uint8_t *)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt, 3909 MSM_PMEM_PREVIEW, 3910 active, 3911 true); 3912 if(status == false){ 3913 ALOGE("Registring Preview Buffers failed for HFR mode"); 3914 return false; 3915 } 3916 } 3917 } 3918 // if 7x27A , YV12 format is set as preview format , if width is not 32 3919 // bit aligned , we need seperate buffer to hold YV12 data 3920 yv12framesize = (previewWidth*previewHeight) 3921 + 2* ( CEILING16(previewWidth/2) * (previewHeight/2)) ; 3922 if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) && 3923 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) && 3924 previewWidth%32 != 0 ){ 3925 ALOGE("initpreview : creating YV12 heap as previewwidth %d not 32 aligned", previewWidth); 3926 #ifdef USE_ION 3927 mYV12Heap = new IonPool(ion_heap, 3928 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 3929 MSM_PMEM_PREVIEW, 3930 yv12framesize, 3931 NUM_YV12_FRAMES, 3932 yv12framesize, 3933 CbCrOffset, 3934 0, 3935 "postview"); 3936 #else 3937 mYV12Heap = new PmemPool(pmem_region, 3938 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 3939 MSM_PMEM_PREVIEW, 3940 yv12framesize, 3941 NUM_YV12_FRAMES, 3942 yv12framesize, 3943 CbCrOffset, 3944 0, 3945 "postview"); 3946 #endif 3947 if (!mYV12Heap->initialized()) { 3948 mYV12Heap.clear(); 3949 ALOGE("initPreview X: could not initialize YV12 Camera preview heap."); 3950 return false; 3951 } 3952 } 3953 } 3954 #endif 3955 3956 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 3957 3958 // Allocate video buffers after allocating preview buffers. 3959 bool status = initRecord(); 3960 if(status != true) { 3961 ALOGE("Failed to allocate video bufers"); 3962 return false; 3963 } 3964 } 3965 3966 if (ret) { 3967 if(mIs3DModeOn != true) { 3968 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) { 3969 #if 0 3970 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID(); 3971 frames[cnt].buffer = 3972 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt; 3973 frames[cnt].y_off = 0; 3974 frames[cnt].cbcr_off = CbCrOffset; 3975 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC; 3976 #endif 3977 } 3978 3979 mPreviewBusyQueue.init(); 3980 LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME); 3981 for(int i=ACTIVE_PREVIEW_BUFFERS ;i <kPreviewBufferCount; i++) 3982 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]); 3983 3984 mPreviewThreadWaitLock.lock(); 3985 pthread_attr_t pattr; 3986 pthread_attr_init(&pattr); 3987 pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); 3988 3989 mPreviewThreadRunning = !pthread_create(&mPreviewThread, 3990 &pattr, 3991 preview_thread, 3992 (void*)NULL); 3993 ret = mPreviewThreadRunning; 3994 mPreviewThreadWaitLock.unlock(); 3995 3996 if(ret == false) 3997 return ret; 3998 } 3999 4000 4001 mFrameThreadWaitLock.lock(); 4002 pthread_attr_t attr; 4003 pthread_attr_init(&attr); 4004 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 4005 camframeParams.cammode = CAMERA_MODE_2D; 4006 4007 if (mIs3DModeOn) { 4008 camframeParams.cammode = CAMERA_MODE_3D; 4009 } else { 4010 camframeParams.cammode = CAMERA_MODE_2D; 4011 } 4012 LINK_cam_frame_set_exit_flag(0); 4013 4014 mFrameThreadRunning = !pthread_create(&mFrameThread, 4015 &attr, 4016 frame_thread, 4017 &camframeParams); 4018 ret = mFrameThreadRunning; 4019 mFrameThreadWaitLock.unlock(); 4020 LINK_wait_cam_frame_thread_ready(); 4021 } 4022 mFirstFrame = true; 4023 4024 ALOGV("initPreview X: %d", ret); 4025 return ret; 4026 } 4027 4028 void QualcommCameraHardware::deinitPreview(void) 4029 { 4030 ALOGV("deinitPreview E"); 4031 4032 mPreviewBusyQueue.deinit(); 4033 4034 // When we call deinitPreview(), we signal to the frame thread that it 4035 // needs to exit, but we DO NOT WAIT for it to complete here. The problem 4036 // is that deinitPreview is sometimes called from the frame-thread's 4037 // callback, when the refcount on the Camera client reaches zero. If we 4038 // called pthread_join(), we would deadlock. So, we just call 4039 // LINK_camframe_terminate() in deinitPreview(), which makes sure that 4040 // after the preview callback returns, the camframe thread will exit. We 4041 // could call pthread_join() in initPreview() to join the last frame 4042 // thread. However, we would also have to call pthread_join() in release 4043 // as well, shortly before we destroy the object; this would cause the same 4044 // deadlock, since release(), like deinitPreview(), may also be called from 4045 // the frame-thread's callback. This we have to make the frame thread 4046 // detached, and use a separate mechanism to wait for it to complete. 4047 4048 LINK_camframe_terminate(); 4049 ALOGV("deinitPreview X"); 4050 } 4051 4052 bool QualcommCameraHardware::initRawSnapshot() 4053 { 4054 ALOGV("initRawSnapshot E"); 4055 const char * pmem_region; 4056 4057 //get width and height from Dimension Object 4058 bool ret = native_set_parms(CAMERA_PARM_DIMENSION, 4059 sizeof(cam_ctrl_dimension_t), &mDimension); 4060 4061 4062 if(!ret){ 4063 ALOGE("initRawSnapshot X: failed to set dimension"); 4064 return false; 4065 } 4066 int rawSnapshotSize = mDimension.raw_picture_height * 4067 mDimension.raw_picture_width; 4068 4069 ALOGI("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\ 4070 "raw_picture_width = %d", 4071 rawSnapshotSize, mDimension.raw_picture_height, 4072 mDimension.raw_picture_width); 4073 4074 // Create Memory for Raw Snapshot 4075 if( createSnapshotMemory(numCapture, numCapture, false, PICTURE_FORMAT_RAW) == false ) // TODO : check if the numbers are correct 4076 { 4077 ALOGE("ERROR : initRawSnapshot , createSnapshotMemory failed"); 4078 return false; 4079 } 4080 4081 mRawCaptureParms.num_captures = 1; 4082 mRawCaptureParms.raw_picture_width = mDimension.raw_picture_width; 4083 mRawCaptureParms.raw_picture_height = mDimension.raw_picture_height; 4084 4085 ALOGV("initRawSnapshot X"); 4086 return true; 4087 4088 } 4089 bool QualcommCameraHardware::initZslBuffers(bool initJpegHeap){ 4090 ALOGV("Init ZSL buffers E"); 4091 const char * pmem_region; 4092 int ion_heap = ION_CP_MM_HEAP_ID; 4093 int postViewBufferSize; 4094 4095 mPostviewWidth = mDimension.display_width; 4096 mPostviewHeight = mDimension.display_height; 4097 4098 //postview buffer initialization 4099 postViewBufferSize = mPostviewWidth * mPostviewHeight * 3 / 2; 4100 int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * mPostviewHeight); 4101 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) { 4102 postViewBufferSize = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight)) + 4103 2 * (CEILING32(mPostviewWidth/2) * CEILING32(mPostviewHeight/2)); 4104 int CbCrOffsetPostview = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight)); 4105 } 4106 4107 //Snapshot buffer initialization 4108 mRawSize = mPictureWidth * mPictureHeight * 3 / 2; 4109 mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * mPictureHeight); 4110 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) { 4111 mRawSize = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) + 4112 2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2)); 4113 mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)); 4114 } 4115 4116 //Jpeg buffer initialization 4117 if( mCurrentTarget == TARGET_MSM7627 || 4118 (mCurrentTarget == TARGET_MSM7625A || 4119 mCurrentTarget == TARGET_MSM7627A)) 4120 mJpegMaxSize = CEILING16(mPictureWidth) * CEILING16(mPictureHeight) * 3 / 2; 4121 else { 4122 mJpegMaxSize = mPictureWidth * mPictureHeight * 3 / 2; 4123 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){ 4124 mJpegMaxSize = 4125 PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) + 4126 2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2)); 4127 } 4128 } 4129 4130 cam_buf_info_t buf_info; 4131 int yOffset = 0; 4132 buf_info.resolution.width = mPictureWidth; 4133 buf_info.resolution.height = mPictureHeight; 4134 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) { 4135 mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info); 4136 mRawSize = buf_info.size; 4137 mJpegMaxSize = mRawSize; 4138 mCbCrOffsetRaw = buf_info.cbcr_offset; 4139 yOffset = buf_info.yoffset; 4140 } 4141 4142 ALOGV("initZslBuffer: initializing mRawHeap."); 4143 if(mCurrentTarget == TARGET_MSM8660) { 4144 pmem_region = "/dev/pmem_smipool"; 4145 } else { 4146 pmem_region = "/dev/pmem_adsp"; 4147 } 4148 //Main Raw Image 4149 #if 0 4150 #ifdef USE_ION 4151 mRawHeap = 4152 new IonPool( ion_heap, 4153 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 4154 MSM_PMEM_MAINIMG, 4155 mJpegMaxSize, 4156 MAX_SNAPSHOT_BUFFERS, 4157 mRawSize, 4158 mCbCrOffsetRaw, 4159 yOffset, 4160 "snapshot camera"); 4161 #else 4162 mRawHeap = 4163 new PmemPool(pmem_region, 4164 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 4165 MSM_PMEM_MAINIMG, 4166 mJpegMaxSize, 4167 MAX_SNAPSHOT_BUFFERS, 4168 mRawSize, 4169 mCbCrOffsetRaw, 4170 yOffset, 4171 "snapshot camera"); 4172 #endif 4173 if (!mRawHeap->initialized()) { 4174 ALOGE("initZslBuffer X failed "); 4175 mRawHeap.clear(); 4176 ALOGE("initRaw X: error initializing mRawHeap"); 4177 return false; 4178 } 4179 4180 4181 // Jpeg 4182 if (initJpegHeap) { 4183 ALOGV("initZslRaw: initializing mJpegHeap."); 4184 mJpegHeap = 4185 new AshmemPool(mJpegMaxSize, 4186 (MAX_SNAPSHOT_BUFFERS - 2), // It is the max number of snapshot supported. 4187 0, // we do not know how big the picture will be 4188 "jpeg"); 4189 4190 if (!mJpegHeap->initialized()) { 4191 mJpegHeap.clear(); 4192 mRawHeap.clear(); 4193 ALOGE("initZslRaw X failed: error initializing mJpegHeap."); 4194 return false; 4195 } 4196 } 4197 4198 //PostView 4199 pmem_region = "/dev/pmem_adsp"; 4200 ion_heap = ION_HEAP_ADSP_ID; 4201 #ifdef USE_ION 4202 mPostviewHeap = 4203 new IonPool(ion_heap, 4204 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 4205 MSM_PMEM_THUMBNAIL, 4206 postViewBufferSize, 4207 MAX_SNAPSHOT_BUFFERS, 4208 postViewBufferSize, 4209 CbCrOffsetPostview, 4210 0, 4211 "thumbnail"); 4212 #else 4213 mPostviewHeap = 4214 new PmemPool(pmem_region, 4215 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 4216 MSM_PMEM_THUMBNAIL, 4217 postViewBufferSize, 4218 MAX_SNAPSHOT_BUFFERS, 4219 postViewBufferSize, 4220 CbCrOffsetPostview, 4221 0, 4222 "thumbnail"); 4223 #endif 4224 4225 if (!mPostviewHeap->initialized()) { 4226 mPostviewHeap.clear(); 4227 mJpegHeap.clear(); 4228 mRawHeap.clear(); 4229 ALOGE("initZslBuffer X failed: error initializing mPostviewHeap."); 4230 return false; 4231 } 4232 #endif 4233 if( createSnapshotMemory(MAX_SNAPSHOT_BUFFERS, MAX_SNAPSHOT_BUFFERS, initJpegHeap) == false ) // TODO : check if the numbers are correct 4234 { 4235 ALOGE("ERROR : initZslraw , createSnapshotMemory failed"); 4236 return false; 4237 } 4238 /* frame all the exif and encode information into encode_params_t */ 4239 initImageEncodeParameters(MAX_SNAPSHOT_BUFFERS); 4240 4241 ALOGV("initZslRaw X"); 4242 return true; 4243 } 4244 4245 bool QualcommCameraHardware::deinitZslBuffers() 4246 { 4247 ALOGV("deinitZslBuffers E"); 4248 for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) { 4249 if(NULL != mRawMapped[cnt]) { 4250 ALOGI("Unregister MAIN_IMG"); 4251 register_buf(mJpegMaxSize, 4252 mRawSize,mCbCrOffsetRaw,0, 4253 mRawfd[cnt],0, 4254 (uint8_t *)mRawMapped[cnt]->data, 4255 MSM_PMEM_MAINIMG, 4256 0, 0); 4257 mRawMapped[cnt]->release(mRawMapped[cnt]); 4258 mRawMapped[cnt] = NULL; 4259 close(mRawfd[cnt]); 4260 #ifdef USE_ION 4261 deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]); 4262 #endif 4263 } 4264 } 4265 for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) { 4266 if(mJpegMapped[cnt]) { 4267 mJpegMapped[cnt]->release(mJpegMapped[cnt]); 4268 mJpegMapped[cnt] = NULL; 4269 } 4270 } 4271 ALOGV("deinitZslBuffers X"); 4272 return true; 4273 } 4274 4275 bool QualcommCameraHardware::createSnapshotMemory (int numberOfRawBuffers, int numberOfJpegBuffers, 4276 bool initJpegHeap, int snapshotFormat) 4277 { 4278 char * pmem_region; 4279 int ret; 4280 int ion_heap = ION_CP_MM_HEAP_ID; 4281 if(mCurrentTarget == TARGET_MSM8660) { 4282 pmem_region = "/dev/pmem_smipool"; 4283 } else { 4284 pmem_region = "/dev/pmem_adsp"; 4285 } 4286 if( snapshotFormat == PICTURE_FORMAT_JPEG) { 4287 // Create Raw memory for snapshot 4288 for(int cnt = 0; cnt < numberOfRawBuffers; cnt++) 4289 { 4290 #ifdef USE_ION 4291 if (allocate_ion_memory(&raw_main_ion_fd[cnt], &raw_alloc[cnt], &raw_ion_info_fd[cnt], 4292 ion_heap, mJpegMaxSize, &mRawfd[cnt]) < 0){ 4293 ALOGE("do_mmap: Open device %s failed!\n",pmem_region); 4294 return NULL; 4295 } 4296 #else 4297 mRawfd[cnt] = open(pmem_region, O_RDWR|O_SYNC); 4298 if (mRawfd[cnt] <= 0) { 4299 ALOGE("%s: Open device %s failed!\n",__func__, pmem_region); 4300 return false; 4301 } 4302 #endif 4303 ALOGI("%s Raw memory index: %d , fd is %d ", __func__, cnt, mRawfd[cnt]); 4304 mRawMapped[cnt]=mGetMemory(mRawfd[cnt], mJpegMaxSize,1,mCallbackCookie); 4305 if(mRawMapped[cnt] == NULL) { 4306 ALOGE("Failed to get camera memory for mRawMapped heap index: %d", cnt); 4307 return false; 4308 }else{ 4309 ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p", 4310 mRawMapped[cnt]->data ,mRawMapped[cnt]->handle, mRawMapped[cnt]->size, mRawMapped[cnt]->release); 4311 } 4312 // Register Raw frames 4313 ALOGI("Registering buffer %d with fd :%d with kernel",cnt,mRawfd[cnt]); 4314 int active = (cnt < ACTIVE_ZSL_BUFFERS); // TODO check ? 4315 register_buf(mJpegMaxSize, 4316 mRawSize, 4317 mCbCrOffsetRaw, 4318 mYOffset, 4319 mRawfd[cnt],0, 4320 (uint8_t *)mRawMapped[cnt]->data, 4321 MSM_PMEM_MAINIMG, 4322 active); 4323 } 4324 // Create Jpeg memory for snapshot 4325 if (initJpegHeap) 4326 { 4327 for(int cnt = 0; cnt < numberOfJpegBuffers; cnt++) 4328 { 4329 ALOGI("%s Jpeg memory index: %d , fd is %d ", __func__, cnt, mJpegfd[cnt]); 4330 mJpegMapped[cnt]=mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie); 4331 if(mJpegMapped[cnt] == NULL) { 4332 ALOGE("Failed to get camera memory for mJpegMapped heap index: %d", cnt); 4333 return false; 4334 }else{ 4335 ALOGI("Received following info for jpeg mapped data:%p,handle:%p, size:%d,release:%p", 4336 mJpegMapped[cnt]->data ,mJpegMapped[cnt]->handle, mJpegMapped[cnt]->size, mJpegMapped[cnt]->release); 4337 } 4338 } 4339 } 4340 // Lock Thumbnail buffers, and register them 4341 ALOGI("Locking and registering Thumbnail buffer(s)"); 4342 for(int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) { 4343 // TODO : change , lock all thumbnail buffers 4344 if((mPreviewWindow != NULL) && (mThumbnailBuffer[cnt] != NULL)) { 4345 ALOGI("createsnapshotbuffers : display lock"); 4346 mDisplayLock.lock(); 4347 /* Lock the postview buffer before use */ 4348 ALOGI(" Locking thumbnail/postview buffer %d", cnt); 4349 if( (ret = mPreviewWindow->lock_buffer(mPreviewWindow, 4350 mThumbnailBuffer[cnt])) != NO_ERROR) { 4351 ALOGE(" Error locking postview buffer. Error = %d ", ret); 4352 ALOGE("createsnapshotbuffers : display unlock error"); 4353 mDisplayLock.unlock(); 4354 return false; 4355 } 4356 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t*)(*mThumbnailBuffer[cnt]), 4357 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 4358 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 4359 mDisplayLock.unlock(); 4360 return -EINVAL; 4361 } else { 4362 mThumbnailLockState[cnt] = BUFFER_LOCKED; 4363 } 4364 mDisplayLock.unlock(); 4365 ALOGE("createsnapshotbuffers : display unlock"); 4366 } 4367 4368 private_handle_t *thumbnailHandle; 4369 int mBufferSize = previewWidth * previewHeight * 3/2; 4370 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 4371 4372 if(mThumbnailBuffer[cnt]) { 4373 thumbnailHandle = (private_handle_t *)(*mThumbnailBuffer[cnt]); 4374 ALOGI("fd thumbnailhandle fd %d size %d", thumbnailHandle->fd, thumbnailHandle->size); 4375 mThumbnailMapped [cnt]= (unsigned int) mmap(0, thumbnailHandle->size, PROT_READ|PROT_WRITE, 4376 MAP_SHARED, thumbnailHandle->fd, 0); 4377 if((void *)mThumbnailMapped[cnt] == MAP_FAILED){ 4378 ALOGE(" Couldnt map Thumbnail buffer %d", errno); 4379 return false; 4380 } 4381 register_buf(mBufferSize, 4382 mBufferSize, mCbCrOffset, 0, 4383 thumbnailHandle->fd, 4384 0, 4385 (uint8_t *)mThumbnailMapped[cnt], 4386 MSM_PMEM_THUMBNAIL, 4387 (cnt < ACTIVE_ZSL_BUFFERS)); 4388 } 4389 } // for loop locking and registering thumbnail buffers 4390 } else { // End if Format is Jpeg , start if format is RAW 4391 if(numberOfRawBuffers ==1) { 4392 int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width; 4393 #ifdef USE_ION 4394 if (allocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_alloc, &raw_snapshot_ion_info_fd, 4395 ion_heap, rawSnapshotSize, &mRawSnapshotfd) < 0){ 4396 ALOGE("do_mmap: Open device %s failed!\n",pmem_region); 4397 return false; 4398 } 4399 #else 4400 mRawSnapshotfd = open(pmem_region, O_RDWR|O_SYNC); 4401 if (mRawSnapshotfd <= 0) { 4402 ALOGE("%s: Open device %s failed for rawnspashot!\n",__func__, pmem_region); 4403 return false; 4404 } 4405 #endif 4406 ALOGI("%s Raw snapshot memory , fd is %d ", __func__, mRawSnapshotfd); 4407 mRawSnapshotMapped=mGetMemory(mRawSnapshotfd, 4408 rawSnapshotSize, 4409 1, 4410 mCallbackCookie); 4411 if(mRawSnapshotMapped == NULL) { 4412 ALOGE("Failed to get camera memory for mRawSnapshotMapped "); 4413 return false; 4414 }else{ 4415 ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p", 4416 mRawSnapshotMapped->data ,mRawSnapshotMapped->handle, mRawSnapshotMapped->size, mRawSnapshotMapped->release); 4417 } 4418 // Register Raw frames 4419 ALOGI("Registering RawSnapshot buffer with fd :%d with kernel",mRawSnapshotfd); 4420 int active = 1; // TODO check ? 4421 register_buf( rawSnapshotSize, 4422 rawSnapshotSize, 4423 0, 4424 0, 4425 mRawSnapshotfd, 4426 0, 4427 (uint8_t *)mRawSnapshotMapped->data, 4428 MSM_PMEM_RAW_MAINIMG, 4429 active); 4430 } else { 4431 ALOGE("Multiple raw snapshot capture not supported for now...."); 4432 return false; 4433 } 4434 } // end else , if RAW format 4435 return true; 4436 } 4437 bool QualcommCameraHardware::initRaw(bool initJpegHeap) 4438 { 4439 const char * pmem_region; 4440 int ion_heap; 4441 int postViewBufferSize; 4442 uint32_t pictureAspectRatio; 4443 uint32_t i; 4444 mParameters.getPictureSize(&mPictureWidth, &mPictureHeight); 4445 mActualPictWidth = mPictureWidth; 4446 mActualPictHeight = mPictureHeight; 4447 if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) { 4448 mDimension.picture_width = mPictureWidth; 4449 mDimension.picture_height = mPictureHeight; 4450 } 4451 ALOGV("initRaw E: picture size=%dx%d", mPictureWidth, mPictureHeight); 4452 int w_scale_factor = (mIs3DModeOn && mSnapshot3DFormat == SIDE_BY_SIDE_FULL) ? 2 : 1; 4453 4454 /* use the default thumbnail sizes */ 4455 mThumbnailHeight = thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height; 4456 mThumbnailWidth = (mThumbnailHeight * mPictureWidth)/ mPictureHeight; 4457 /* see if we can get better thumbnail sizes (not mandatory?) */ 4458 pictureAspectRatio = (uint32_t)((mPictureWidth * Q12) / mPictureHeight); 4459 for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ){ 4460 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) 4461 { 4462 mThumbnailWidth = thumbnail_sizes[i].width; 4463 mThumbnailHeight = thumbnail_sizes[i].height; 4464 break; 4465 } 4466 } 4467 /* calculate thumbnail aspect ratio */ 4468 if(mCurrentTarget == TARGET_MSM7627 ) { 4469 int thumbnail_aspect_ratio = 4470 (uint32_t)((mThumbnailWidth * Q12) / mThumbnailHeight); 4471 4472 if (thumbnail_aspect_ratio < pictureAspectRatio) { 4473 4474 /* if thumbnail is narrower than main image, in other words wide mode 4475 * snapshot then we want to adjust the height of the thumbnail to match 4476 * the main image aspect ratio. */ 4477 mThumbnailHeight = 4478 (mThumbnailWidth * Q12) / pictureAspectRatio; 4479 } else if (thumbnail_aspect_ratio != pictureAspectRatio) { 4480 4481 /* if thumbnail is wider than main image we want to adjust width of the 4482 * thumbnail to match main image aspect ratio */ 4483 mThumbnailWidth = 4484 (mThumbnailHeight * pictureAspectRatio) / Q12; 4485 } 4486 /* make the dimensions multiple of 16 - JPEG requirement */ 4487 mThumbnailWidth = FLOOR16(mThumbnailWidth); 4488 mThumbnailHeight = FLOOR16(mThumbnailHeight); 4489 ALOGV("the thumbnail sizes are %dx%d",mThumbnailWidth,mThumbnailHeight); 4490 } 4491 4492 /* calculate postView size */ 4493 mPostviewWidth = mThumbnailWidth; 4494 mPostviewHeight = mThumbnailHeight; 4495 /* Try to keep the postview dimensions near to preview for better 4496 * performance and userexperience. If the postview and preview dimensions 4497 * are same, then we can try to use the same overlay of preview for 4498 * postview also. If not, we need to reset the overlay for postview. 4499 * we will be getting the same dimensions for preview and postview 4500 * in most of the cases. The only exception is for applications 4501 * which won't use optimalPreviewSize based on picture size. 4502 */ 4503 if((mPictureHeight >= previewHeight) && 4504 (mCurrentTarget != TARGET_MSM7627) && !mIs3DModeOn) { 4505 mPostviewHeight = previewHeight; 4506 mPostviewWidth = (previewHeight * mPictureWidth) / mPictureHeight; 4507 }else if(mActualPictHeight < mThumbnailHeight){ 4508 mPostviewHeight = THUMBNAIL_SMALL_HEIGHT; 4509 mPostviewWidth = (THUMBNAIL_SMALL_HEIGHT * mActualPictWidth)/ mActualPictHeight; 4510 mThumbnailWidth = mPostviewWidth; 4511 mThumbnailHeight = mPostviewHeight; 4512 } 4513 4514 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){ 4515 mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO; 4516 mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO; 4517 } 4518 4519 mDimension.ui_thumbnail_width = mPostviewWidth; 4520 mDimension.ui_thumbnail_height = mPostviewHeight; 4521 4522 // mDimension will be filled with thumbnail_width, thumbnail_height, 4523 // orig_picture_dx, and orig_picture_dy after this function call. We need to 4524 // keep it for jpeg_encoder_encode. 4525 bool ret = native_set_parms(CAMERA_PARM_DIMENSION, 4526 sizeof(cam_ctrl_dimension_t), &mDimension); 4527 4528 if(!ret) { 4529 ALOGE("initRaw X: failed to set dimension"); 4530 return false; 4531 } 4532 #if 0 4533 if (mJpegHeap != NULL) { 4534 ALOGV("initRaw: clearing old mJpegHeap."); 4535 mJpegHeap.clear(); 4536 } 4537 #endif 4538 //postview buffer initialization 4539 postViewBufferSize = mPostviewWidth * w_scale_factor * mPostviewHeight * 3 / 2; 4540 int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * w_scale_factor * mPostviewHeight); 4541 4542 //Snapshot buffer initialization 4543 mRawSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2; 4544 mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * w_scale_factor * mPictureHeight); 4545 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) { 4546 mRawSize = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) + 4547 2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2)); 4548 mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)); 4549 } 4550 4551 //Jpeg buffer initialization 4552 if( mCurrentTarget == TARGET_MSM7627 || 4553 (mCurrentTarget == TARGET_MSM7625A || 4554 mCurrentTarget == TARGET_MSM7627A)) 4555 mJpegMaxSize = CEILING16(mPictureWidth * w_scale_factor) * CEILING16(mPictureHeight) * 3 / 2; 4556 else { 4557 mJpegMaxSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2; 4558 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){ 4559 mJpegMaxSize = 4560 PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) + 4561 2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2)); 4562 } 4563 } 4564 4565 int rotation = mParameters.getInt("rotation"); 4566 char mDeviceName[PROPERTY_VALUE_MAX]; 4567 property_get("ro.hw_plat", mDeviceName, ""); 4568 if(!strcmp(mDeviceName,"7x25A")) 4569 rotation = (rotation + 90)%360; 4570 4571 if (mIs3DModeOn) 4572 rotation = 0; 4573 ret = native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation); 4574 if(!ret){ 4575 ALOGE("setting camera id failed"); 4576 return false; 4577 } 4578 cam_buf_info_t buf_info; 4579 if(mIs3DModeOn == false) 4580 { 4581 buf_info.resolution.width = mPictureWidth * w_scale_factor; 4582 buf_info.resolution.height = mPictureHeight; 4583 mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info); 4584 mRawSize = buf_info.size; 4585 mJpegMaxSize = mRawSize; 4586 mCbCrOffsetRaw = buf_info.cbcr_offset; 4587 mYOffset = buf_info.yoffset; 4588 } 4589 int mBufferSize; 4590 int CbCrOffset; 4591 if(mCurrentTarget != TARGET_MSM7627 && mCurrentTarget != TARGET_MSM7627A){ 4592 mParameters.getPreviewSize(&previewWidth, &previewHeight); 4593 mBufferSize = previewWidth * previewHeight * 3/2; 4594 CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 4595 } 4596 else { 4597 mBufferSize = mPostviewWidth * mPostviewHeight * 3/2; 4598 CbCrOffset = PAD_TO_WORD(mPostviewWidth * mPostviewHeight); 4599 } 4600 4601 ALOGV("initRaw: initializing mRawHeap."); 4602 4603 //PostView 4604 pmem_region = "/dev/pmem_adsp"; 4605 ion_heap = ION_CAMERA_HEAP_ID; 4606 // Create memory for Raw YUV frames and Jpeg images 4607 if( createSnapshotMemory(numCapture, numCapture, initJpegHeap) == false ) 4608 { 4609 ALOGE("ERROR : initraw , createSnapshotMemory failed"); 4610 return false; 4611 } 4612 /* frame all the exif and encode information into encode_params_t */ 4613 4614 initImageEncodeParameters(numCapture); 4615 /* fill main image size, thumbnail size, postview size into capture_params_t*/ 4616 memset(&mImageCaptureParms, 0, sizeof(capture_params_t)); 4617 mImageCaptureParms.num_captures = numCapture; 4618 mImageCaptureParms.picture_width = mPictureWidth; 4619 mImageCaptureParms.picture_height = mPictureHeight; 4620 mImageCaptureParms.postview_width = mPostviewWidth; 4621 mImageCaptureParms.postview_height = mPostviewHeight; 4622 4623 int width = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); 4624 int height = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); 4625 if((width != 0) && (height != 0)) { 4626 mImageCaptureParms.thumbnail_width = mThumbnailWidth; 4627 mImageCaptureParms.thumbnail_height = mThumbnailHeight; 4628 } else { 4629 mImageCaptureParms.thumbnail_width = 0; 4630 mImageCaptureParms.thumbnail_height = 0; 4631 } 4632 4633 ALOGI("%s: picture size=%dx%d",__FUNCTION__, 4634 mImageCaptureParms.picture_width, mImageCaptureParms.picture_height); 4635 ALOGI("%s: postview size=%dx%d",__FUNCTION__, 4636 mImageCaptureParms.postview_width, mImageCaptureParms.postview_height); 4637 ALOGI("%s: thumbnail size=%dx%d",__FUNCTION__, 4638 mImageCaptureParms.thumbnail_width, mImageCaptureParms.thumbnail_height); 4639 4640 ALOGV("initRaw X"); 4641 return true; 4642 } 4643 4644 4645 void QualcommCameraHardware::deinitRawSnapshot() 4646 { 4647 ALOGV("deinitRawSnapshot E"); 4648 4649 int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width; 4650 // Unregister and de allocated memory for Raw Snapshot 4651 if(mRawSnapshotMapped) { 4652 register_buf( rawSnapshotSize, 4653 rawSnapshotSize, 4654 0, 4655 0, 4656 mRawSnapshotfd, 4657 0, 4658 (uint8_t *)mRawSnapshotMapped->data, 4659 MSM_PMEM_RAW_MAINIMG, 4660 false, 4661 false); 4662 mRawSnapshotMapped->release(mRawSnapshotMapped); 4663 mRawSnapshotMapped = NULL; 4664 close(mRawSnapshotfd); 4665 #ifdef USE_ION 4666 deallocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_ion_info_fd); 4667 #endif 4668 } 4669 ALOGV("deinitRawSnapshot X"); 4670 } 4671 4672 void QualcommCameraHardware::deinitRaw() 4673 { 4674 ALOGV("deinitRaw E"); 4675 ALOGV("deinitRaw , clearing raw memory and jpeg memory"); 4676 for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) { 4677 if(NULL != mRawMapped[cnt]) { 4678 ALOGI("Unregister MAIN_IMG"); 4679 register_buf(mJpegMaxSize, 4680 mRawSize,mCbCrOffsetRaw,0, 4681 mRawfd[cnt],0, 4682 (uint8_t *)mRawMapped[cnt]->data, 4683 MSM_PMEM_MAINIMG, 4684 0, 0); 4685 mRawMapped[cnt]->release(mRawMapped[cnt]); 4686 mRawMapped[cnt] = NULL; 4687 close(mRawfd[cnt]); 4688 #ifdef USE_ION 4689 deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]); 4690 #endif 4691 } 4692 } 4693 for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) { 4694 if(NULL != mJpegMapped[cnt]) { 4695 mJpegMapped[cnt]->release(mJpegMapped[cnt]); 4696 mJpegMapped[cnt] = NULL; 4697 } 4698 } 4699 if( mPreviewWindow != NULL ) { 4700 ALOGI("deinitRaw , clearing/cancelling thumbnail buffers:"); 4701 private_handle_t *handle; 4702 for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) { 4703 if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) { 4704 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]); 4705 ALOGI("%s: Cancelling postview buffer %d ", __FUNCTION__, handle->fd); 4706 ALOGI("deinitraw : display lock"); 4707 mDisplayLock.lock(); 4708 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) { 4709 if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) { 4710 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 4711 } else { 4712 mThumbnailLockState[cnt] = BUFFER_UNLOCKED; 4713 } 4714 } 4715 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 4716 mThumbnailBuffer[cnt]); 4717 if(retVal != NO_ERROR) 4718 ALOGE("%s: cancelBuffer failed for postview buffer %d", 4719 __FUNCTION__, handle->fd); 4720 if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){ 4721 struct encoder_media_buffer_type * packet = 4722 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 4723 native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle)); 4724 metadata_memory[cnt]->release(metadata_memory[cnt]); 4725 metadata_memory[cnt] = NULL; 4726 } 4727 // unregister , unmap and release as well 4728 4729 int mBufferSize = previewWidth * previewHeight * 3/2; 4730 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 4731 if(mThumbnailMapped[cnt]) { 4732 ALOGI("%s: Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd); 4733 register_buf(mBufferSize, 4734 mBufferSize, mCbCrOffset, 0, 4735 handle->fd, 4736 0, 4737 (uint8_t *)mThumbnailMapped[cnt], 4738 MSM_PMEM_THUMBNAIL, 4739 false, false); 4740 if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) { 4741 ALOGE("deinitraw : Error un-mmapping the thumbnail buffer %d", index); 4742 } 4743 mThumbnailBuffer[cnt] = NULL; 4744 mThumbnailMapped[cnt] = NULL; 4745 } 4746 ALOGI("deinitraw : display unlock"); 4747 mDisplayLock.unlock(); 4748 } 4749 } 4750 } 4751 ALOGV("deinitRaw X"); 4752 } 4753 4754 void QualcommCameraHardware::relinquishBuffers() 4755 { 4756 status_t retVal; 4757 ALOGV("%s: E ", __FUNCTION__); 4758 mDisplayLock.lock(); 4759 if( mPreviewWindow != NULL) { 4760 for(int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 4761 if (BUFFER_LOCKED == frame_buffer[cnt].lockState) { 4762 ALOGI(" Cancelling preview buffers %d ",frames[cnt].fd); 4763 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 4764 (*(frame_buffer[cnt].buffer)))) { 4765 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 4766 } else { 4767 frame_buffer[cnt].lockState = BUFFER_UNLOCKED; 4768 } 4769 } 4770 retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 4771 frame_buffer[cnt].buffer); 4772 mPreviewMapped[cnt]->release(mPreviewMapped[cnt]); 4773 if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){ 4774 struct encoder_media_buffer_type * packet = 4775 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 4776 native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle)); 4777 metadata_memory[cnt]->release(metadata_memory[cnt]); 4778 metadata_memory[cnt] = NULL; 4779 } 4780 ALOGI("release preview buffers"); 4781 if(retVal != NO_ERROR) 4782 ALOGE("%s: cancelBuffer failed for preview buffer %d ", 4783 __FUNCTION__, frames[cnt].fd); 4784 } 4785 } else { 4786 ALOGV(" PreviewWindow is null, will not cancelBuffers "); 4787 } 4788 mDisplayLock.unlock(); 4789 ALOGV("%s: X ", __FUNCTION__); 4790 } 4791 status_t QualcommCameraHardware::set_PreviewWindow(void* param) 4792 { 4793 ALOGV(": set_preview_window"); 4794 preview_stream_ops_t* window = (preview_stream_ops_t*)param; 4795 return setPreviewWindow(window); 4796 } 4797 4798 status_t QualcommCameraHardware::setPreviewWindow(preview_stream_ops_t* window) 4799 { 4800 status_t retVal = NO_ERROR; 4801 ALOGV(" %s: E ", __FUNCTION__); 4802 if( window == NULL) { 4803 ALOGW(" Setting NULL preview window "); 4804 /* Current preview window will be invalidated. 4805 * Release all the buffers back */ 4806 //@TODO: We may need to this to avoid leak 4807 /*if(mPreviewWindow!=NULL) 4808 relinquishBuffers();*/ 4809 } 4810 ALOGI("Set preview window:: "); 4811 mDisplayLock.lock(); 4812 mPreviewWindow = window; 4813 mDisplayLock.unlock(); 4814 4815 if( (mPreviewWindow != NULL) && mCameraRunning) { 4816 /* Initial preview in progress. Stop it and start 4817 * the actual preview */ 4818 stopInitialPreview(); 4819 retVal = getBuffersAndStartPreview(); 4820 } 4821 ALOGV(" %s : X ", __FUNCTION__ ); 4822 return retVal; 4823 } 4824 4825 status_t QualcommCameraHardware::getBuffersAndStartPreview() { 4826 status_t retVal = NO_ERROR; 4827 int stride; 4828 bool all_chnls = false; 4829 ALOGI(" %s : E ", __FUNCTION__); 4830 mFrameThreadWaitLock.lock(); 4831 while (mFrameThreadRunning) { 4832 ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__); 4833 mFrameThreadWait.wait(mFrameThreadWaitLock); 4834 ALOGV("%s: old frame thread completed.",__FUNCTION__); 4835 } 4836 mFrameThreadWaitLock.unlock(); 4837 4838 if( mPreviewWindow!= NULL) { 4839 ALOGV("%s: Calling native_window_set_buffer", __FUNCTION__); 4840 4841 android_native_buffer_t *mPreviewBuffer; 4842 int32_t previewFormat; 4843 const char *str = mParameters.getPreviewFormat(); 4844 int numMinUndequeuedBufs = 0; 4845 4846 int err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, 4847 &numMinUndequeuedBufs); 4848 4849 if (err != 0) { 4850 ALOGW("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 4851 strerror(-err), -err); 4852 return err; 4853 } 4854 mTotalPreviewBufferCount = kPreviewBufferCount + numMinUndequeuedBufs; 4855 4856 previewFormat = attr_lookup(app_preview_formats, 4857 sizeof(app_preview_formats) / sizeof(str_map), str); 4858 if (previewFormat == NOT_FOUND) { 4859 previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; 4860 } 4861 4862 retVal = mPreviewWindow->set_buffer_count(mPreviewWindow, 4863 mTotalPreviewBufferCount + 4864 (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture) ); //1); 4865 4866 if(retVal != NO_ERROR) { 4867 ALOGE("%s: Error while setting buffer count to %d ", __FUNCTION__, kPreviewBufferCount + 1); 4868 return retVal; 4869 } 4870 mParameters.getPreviewSize(&previewWidth, &previewHeight); 4871 4872 retVal = mPreviewWindow->set_buffers_geometry(mPreviewWindow, 4873 previewWidth, previewHeight, previewFormat); 4874 4875 if(retVal != NO_ERROR) { 4876 ALOGE("%s: Error while setting buffer geometry ", __FUNCTION__); 4877 return retVal; 4878 } 4879 4880 #ifdef USE_ION 4881 mPreviewWindow->set_usage (mPreviewWindow, 4882 GRALLOC_USAGE_PRIVATE_CAMERA_HEAP | 4883 GRALLOC_USAGE_PRIVATE_UNCACHED); 4884 #else 4885 mPreviewWindow->set_usage (mPreviewWindow, 4886 GRALLOC_USAGE_PRIVATE_ADSP_HEAP | 4887 GRALLOC_USAGE_PRIVATE_UNCACHED); 4888 #endif 4889 int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 4890 int cnt = 0, active = 1; 4891 int mBufferSize = previewWidth * previewHeight * 3/2; 4892 for (cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 4893 //const native_handle *nh = (native_handle *)malloc (sizeof(native_handle)); 4894 buffer_handle_t *bhandle =NULL;// &nh; ; 4895 //buffer_handle_t *bh_handle=&handle; 4896 retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow, 4897 &(bhandle), 4898 &(stride)); 4899 4900 if((retVal == NO_ERROR)) { 4901 /* Acquire lock on the buffer if it was successfully 4902 * dequeued from gralloc */ 4903 ALOGV(" Locking buffer %d ", cnt); 4904 retVal = mPreviewWindow->lock_buffer(mPreviewWindow, 4905 bhandle); 4906 // lock the buffer using genlock 4907 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*bhandle), 4908 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 4909 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 4910 return -EINVAL; 4911 } 4912 ALOGI(" Locked buffer %d successfully", cnt); 4913 //yyan todo use handle to find out mPreviewBuffer 4914 4915 } else { 4916 ALOGE("%s: dequeueBuffer failed for preview buffer. Error = %d", 4917 __FUNCTION__, retVal); 4918 return retVal; 4919 } 4920 if(retVal == NO_ERROR) { 4921 private_handle_t *handle = (private_handle_t *)(*bhandle);//(private_handle_t *)mPreviewBuffer->handle; 4922 ALOGI("Handle %p, Fd passed:%d, Base:%p, Size %p", 4923 handle,handle->fd,handle->base,handle->size); 4924 4925 if(handle) { 4926 4927 //thumbnailHandle = (private_handle_t *)mThumbnailBuffer->handle; 4928 ALOGV("fd mmap fd %d size %d", handle->fd, handle->size/*thumbnailHandle->size*/); 4929 mPreviewMapped[cnt]= mGetMemory(handle->fd,handle->size,1,mCallbackCookie); 4930 4931 if((void *)mPreviewMapped[cnt] == NULL){ 4932 ALOGE(" Failed to get camera memory for Preview buffer %d ",cnt); 4933 }else{ 4934 ALOGI(" Mapped Preview buffer %d", cnt); 4935 } 4936 ALOGI("Got the following from get_mem data: %p, handle :%d, release : %p, size: %d", 4937 mPreviewMapped[cnt]->data, 4938 mPreviewMapped[cnt]->handle, 4939 mPreviewMapped[cnt]->release, 4940 mPreviewMapped[cnt]->size); 4941 ALOGI(" getbuffersandrestartpreview deQ %d", handle->fd); 4942 frames[cnt].fd = handle->fd; 4943 frames[cnt].buffer = (unsigned int)mPreviewMapped[cnt]->data;//(unsigned int)mPreviewHeap[cnt]->mHeap->base(); 4944 if(((void *)frames[cnt].buffer == MAP_FAILED) 4945 || (frames[cnt].buffer == 0)) { 4946 ALOGE("%s: Couldnt map preview buffers", __FUNCTION__); 4947 return UNKNOWN_ERROR; 4948 } 4949 4950 if(mPreviewFormat == CAMERA_YUV_420_YV12 && mCurrentTarget != TARGET_MSM7627A) { 4951 myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight); 4952 myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4); 4953 ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset); 4954 frames[cnt].planar0_off = 0; 4955 frames[cnt].planar1_off = myv12_params.CbOffset; 4956 frames[cnt].planar2_off = myv12_params.CrOffset; 4957 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC; 4958 all_chnls = true; 4959 }else{ 4960 frames[cnt].planar0_off = 0; 4961 frames[cnt].planar1_off= CbCrOffset; 4962 frames[cnt].planar2_off = 0; 4963 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC; 4964 } 4965 frame_buffer[cnt].frame = &frames[cnt]; 4966 frame_buffer[cnt].buffer = bhandle; 4967 frame_buffer[cnt].size = handle->size; 4968 frame_buffer[cnt].lockState = BUFFER_LOCKED; 4969 active = (cnt < ACTIVE_PREVIEW_BUFFERS); 4970 4971 ALOGI("Registering buffer %d with fd :%d with kernel",cnt,handle->fd); 4972 register_buf(mBufferSize, 4973 mBufferSize, CbCrOffset, 0, 4974 handle->fd, 4975 0, 4976 (uint8_t *)frames[cnt].buffer/*(uint8_t *)mThumbnailMapped*/, 4977 MSM_PMEM_PREVIEW, 4978 active,true,all_chnls); 4979 ALOGI("Came back from register call to kernel"); 4980 } else 4981 ALOGE("%s: setPreviewWindow: Could not get buffer handle", __FUNCTION__); 4982 } else { 4983 ALOGE("%s: lockBuffer failed for preview buffer. Error = %d", 4984 __FUNCTION__, retVal); 4985 return retVal; 4986 } 4987 } 4988 4989 4990 // Dequeue Thumbnail/Postview Buffers here , Consider ZSL/Multishot cases 4991 for (cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) { 4992 4993 retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow, 4994 &mThumbnailBuffer[cnt], &(stride)); 4995 private_handle_t* handle = (private_handle_t *)(*mThumbnailBuffer[cnt]); 4996 ALOGI(" : dequeing thumbnail buffer fd %d", handle->fd); 4997 if(retVal != NO_ERROR) { 4998 ALOGE("%s: dequeueBuffer failed for postview buffer. Error = %d ", 4999 __FUNCTION__, retVal); 5000 return retVal; 5001 } 5002 } 5003 5004 // Cancel minUndequeuedBufs. 5005 for (cnt = kPreviewBufferCount; cnt < mTotalPreviewBufferCount; cnt++) { 5006 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)(*(frame_buffer[cnt].buffer)))) { 5007 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 5008 return -EINVAL; 5009 } 5010 frame_buffer[cnt].lockState = BUFFER_UNLOCKED; 5011 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 5012 frame_buffer[cnt].buffer); 5013 ALOGI(" Cancelling preview buffers %d ",frame_buffer[cnt].frame->fd); 5014 } 5015 } else { 5016 ALOGE("%s: Could not get Buffer from Surface", __FUNCTION__); 5017 return UNKNOWN_ERROR; 5018 } 5019 mPreviewBusyQueue.init(); 5020 LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME); 5021 for(int i=ACTIVE_PREVIEW_BUFFERS ;i < kPreviewBufferCount; i++) 5022 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]); 5023 5024 mBuffersInitialized = true; 5025 5026 //Starting preview now as the preview buffers are allocated 5027 // if(!mPreviewInitialized && !mCameraRunning) { // TODO just for testing 5028 ALOGI("setPreviewWindow: Starting preview after buffer allocation"); 5029 startPreviewInternal(); 5030 // } 5031 ALOGV(" %s : X ",__FUNCTION__); 5032 return NO_ERROR; 5033 } 5034 void QualcommCameraHardware::release() 5035 { 5036 ALOGV("release E"); 5037 Mutex::Autolock l(&mLock); 5038 #if 0 5039 { 5040 Mutex::Autolock checkLock(&singleton_lock); 5041 if(singleton_releasing){ 5042 ALOGE("ERROR: multiple release!"); 5043 return; 5044 } 5045 } 5046 #endif 5047 ALOGI("release: mCameraRunning = %d", mCameraRunning); 5048 if (mCameraRunning) { 5049 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) { 5050 mRecordFrameLock.lock(); 5051 mReleasedRecordingFrame = true; 5052 mRecordWait.signal(); 5053 mRecordFrameLock.unlock(); 5054 } 5055 stopPreviewInternal(); 5056 ALOGI("release: stopPreviewInternal done."); 5057 } 5058 LINK_jpeg_encoder_join(); 5059 mm_camera_ops_type_t current_ops_type = (mSnapshotFormat 5060 == PICTURE_FORMAT_JPEG) ? CAMERA_OPS_CAPTURE_AND_ENCODE 5061 : CAMERA_OPS_RAW_CAPTURE; 5062 mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL); 5063 5064 //Signal the snapshot thread 5065 mJpegThreadWaitLock.lock(); 5066 mJpegThreadRunning = false; 5067 mJpegThreadWait.signal(); 5068 mJpegThreadWaitLock.unlock(); 5069 5070 // Wait for snapshot thread to complete before clearing the 5071 // resources. 5072 mSnapshotThreadWaitLock.lock(); 5073 while (mSnapshotThreadRunning) { 5074 ALOGV("release: waiting for old snapshot thread to complete."); 5075 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock); 5076 ALOGV("release: old snapshot thread completed."); 5077 } 5078 mSnapshotThreadWaitLock.unlock(); 5079 5080 { 5081 Mutex::Autolock l (&mRawPictureHeapLock); 5082 deinitRaw(); 5083 } 5084 5085 deinitRawSnapshot(); 5086 ALOGI("release: clearing resources done."); 5087 if(mCurrentTarget == TARGET_MSM8660) { 5088 ALOGV("release : Clearing the mThumbnailHeap and mDisplayHeap"); 5089 mLastPreviewFrameHeap.clear(); 5090 mLastPreviewFrameHeap = NULL; 5091 mThumbnailHeap.clear(); 5092 mThumbnailHeap = NULL; 5093 mPostviewHeap.clear(); 5094 mPostviewHeap = NULL; 5095 mDisplayHeap.clear(); 5096 mDisplayHeap = NULL; 5097 } 5098 LINK_mm_camera_deinit(); 5099 if(fb_fd >= 0) { 5100 close(fb_fd); 5101 fb_fd = -1; 5102 } 5103 singleton_lock.lock(); 5104 singleton_releasing = true; 5105 singleton_releasing_start_time = systemTime(); 5106 singleton_lock.unlock(); 5107 5108 ALOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning); 5109 ALOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning); 5110 ALOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning); 5111 mFrameThreadWaitLock.lock(); 5112 while (mFrameThreadRunning) { 5113 ALOGV("release: waiting for old frame thread to complete."); 5114 mFrameThreadWait.wait(mFrameThreadWaitLock); 5115 ALOGV("release: old frame thread completed."); 5116 } 5117 mFrameThreadWaitLock.unlock(); 5118 5119 } 5120 5121 QualcommCameraHardware::~QualcommCameraHardware() 5122 { 5123 ALOGI("~QualcommCameraHardware E"); 5124 5125 //singleton_lock.lock(); 5126 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) { 5127 delete [] recordframes; 5128 recordframes = NULL; 5129 delete [] record_buffers_tracking_flag; 5130 } 5131 mMMCameraDLRef.clear(); 5132 //singleton.clear(); 5133 //singleton_releasing = false; 5134 //singleton_releasing_start_time = 0; 5135 //singleton_wait.signal(); 5136 //singleton_lock.unlock(); 5137 ALOGI("~QualcommCameraHardware X"); 5138 } 5139 #if 0 5140 IMemoryHeap* QualcommCameraHardware::getRawHeap() const 5141 { 5142 #if 0 5143 ALOGV("getRawHeap"); 5144 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL; 5145 #endif 5146 } 5147 5148 IMemoryHeap* QualcommCameraHardware::getPreviewHeap() const 5149 { 5150 #if 0 5151 ALOGV("getPreviewHeap"); 5152 return mPreviewHeap[0] != NULL ? mPreviewHeap[0]->mHeap : NULL; 5153 if(mIs3DModeOn != true) { 5154 if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) && 5155 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) && 5156 previewWidth%32 != 0 ) 5157 return mYV12Heap->mHeap; 5158 5159 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL; 5160 } else 5161 return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL; 5162 5163 #endif 5164 } 5165 #endif 5166 #if 0 5167 status_t QualcommCameraHardware::startInitialPreview() { 5168 ALOGV(" %s : E", __FUNCTION__); 5169 const char * pmem_region = "/dev/pmem_smipool"; 5170 int initialPreviewWidth = INITIAL_PREVIEW_WIDTH; 5171 int initialPreviewHeight = INITIAL_PREVIEW_HEIGHT; 5172 int previewFrameSize = initialPreviewWidth * initialPreviewHeight * 3/2; 5173 int CbCrOffset = PAD_TO_WORD(initialPreviewWidth * initialPreviewHeight); 5174 mFrameThreadWaitLock.lock(); 5175 while (mFrameThreadRunning) { 5176 ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__); 5177 mFrameThreadWait.wait(mFrameThreadWaitLock); 5178 ALOGV("%s: old frame thread completed.",__FUNCTION__); 5179 } 5180 mFrameThreadWaitLock.unlock(); 5181 5182 mInitialPreviewHeap = new PmemPool(pmem_region, 5183 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 5184 MSM_PMEM_PREVIEW, 5185 previewFrameSize, 5186 kPreviewBufferCount, 5187 previewFrameSize, 5188 CbCrOffset, 5189 0, 5190 "initial preview"); 5191 5192 mDimension.display_width = initialPreviewWidth; 5193 mDimension.display_height = initialPreviewHeight; 5194 mDimension.video_width = initialPreviewWidth; 5195 mDimension.video_height = initialPreviewHeight; 5196 mDimension.display_luma_width = initialPreviewWidth; 5197 mDimension.display_luma_height = initialPreviewHeight; 5198 mDimension.display_chroma_width = initialPreviewWidth; 5199 mDimension.display_chroma_height = initialPreviewHeight; 5200 mDimension.orig_video_width = initialPreviewWidth; 5201 mDimension.orig_video_height = initialPreviewHeight; 5202 ALOGV("mDimension.prev_format = %d", mDimension.prev_format); 5203 ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width); 5204 ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height); 5205 ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width); 5206 ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height); 5207 5208 native_set_parms(CAMERA_PARM_DIMENSION, 5209 sizeof(cam_ctrl_dimension_t), &mDimension); 5210 ALOGV(" %s : mDimension.video_width = %d mDimension.video_height = %d", __FUNCTION__, 5211 mDimension.video_width, mDimension.video_height); 5212 mRecordFrameSize = previewFrameSize; 5213 ALOGV("mRecordFrameSize = %d", mRecordFrameSize); 5214 5215 mRecordHeap = new PmemPool(pmem_region, 5216 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 5217 MSM_PMEM_VIDEO, 5218 previewFrameSize, 5219 kRecordBufferCount, 5220 previewFrameSize, 5221 CbCrOffset, 5222 0, 5223 "initial record"); 5224 5225 if (!mRecordHeap->initialized()) { 5226 mRecordHeap.clear(); 5227 ALOGE("%s X: could not initialize record heap.", __FUNCTION__); 5228 return false; 5229 } 5230 { 5231 Mutex::Autolock cameraRunningLock(&mCameraRunningLock); 5232 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL); 5233 } 5234 5235 ALOGV(" %s : X", __FUNCTION__); 5236 return NO_ERROR; 5237 } 5238 #endif 5239 status_t QualcommCameraHardware::startPreviewInternal() 5240 { 5241 ALOGV("in startPreviewInternal : E"); 5242 if (!mBuffersInitialized) { 5243 ALOGE("startPreviewInternal: Buffers not allocated. Cannot start preview"); 5244 return NO_ERROR; 5245 } 5246 mPreviewStopping = false; 5247 #if 0 5248 if(mZslEnable && !mZslPanorama){ 5249 ALOGE("start zsl Preview called"); 5250 mCamOps.mm_camera_start(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL); 5251 if (mCurrentTarget == TARGET_MSM8660) { 5252 if(mLastPreviewFrameHeap != NULL) 5253 mLastPreviewFrameHeap.clear(); 5254 } 5255 } 5256 #endif 5257 if(mCameraRunning) { 5258 ALOGV("startPreview X: preview already running."); 5259 return NO_ERROR; 5260 } 5261 if(mZslEnable){ 5262 //call init 5263 ALOGI("ZSL Enable called"); 5264 uint8_t is_zsl = 1; 5265 mm_camera_status_t status; 5266 if(MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE, 5267 (void *)&is_zsl)){ 5268 ALOGE("ZSL Enable failed"); 5269 return UNKNOWN_ERROR; 5270 } 5271 } 5272 5273 if (!mPreviewInitialized) { 5274 mLastQueuedFrame = NULL; 5275 mPreviewInitialized = initPreview(); 5276 if (!mPreviewInitialized) { 5277 ALOGE("startPreview X initPreview failed. Not starting preview."); 5278 mPreviewBusyQueue.deinit(); 5279 return UNKNOWN_ERROR; 5280 } 5281 } 5282 5283 /* For 3D mode, start the video output, as this need to be 5284 * used for display also. 5285 */ 5286 if(mIs3DModeOn) { 5287 startRecordingInternal(); 5288 if(!mVideoThreadRunning) { 5289 ALOGE("startPreview X startRecording failed. Not starting preview."); 5290 return UNKNOWN_ERROR; 5291 } 5292 } 5293 5294 { 5295 Mutex::Autolock cameraRunningLock(&mCameraRunningLock); 5296 if(( mCurrentTarget != TARGET_MSM7630 ) && 5297 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) 5298 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL); 5299 else { 5300 if(!mZslEnable){ 5301 ALOGI("Calling CAMERA_OPS_STREAMING_VIDEO"); 5302 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL); 5303 ALOGI(": Calling CAMERA_OPS_STREAMING_VIDEO %d", mCameraRunning); 5304 }else { 5305 initZslParameter(); 5306 mCameraRunning = false; 5307 if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_init(CAMERA_OPS_STREAMING_ZSL, 5308 (void *)&mZslParms, NULL)) { 5309 //register buffers for ZSL 5310 bool status = initZslBuffers(true); 5311 if(status != true) { 5312 ALOGE("Failed to allocate ZSL buffers"); 5313 return false; 5314 } 5315 if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_start(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){ 5316 mCameraRunning = true; 5317 } 5318 } 5319 if(mCameraRunning == false) 5320 ALOGE("Starting ZSL CAMERA_OPS_STREAMING_ZSL failed!!!"); 5321 } 5322 } 5323 } 5324 5325 if(!mCameraRunning) { 5326 deinitPreview(); 5327 if(mZslEnable){ 5328 //deinit 5329 ALOGI("ZSL DISABLE called"); 5330 uint8_t is_zsl = 0; 5331 mm_camera_status_t status; 5332 if( MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE, 5333 (void *)&is_zsl)){ 5334 ALOGE("ZSL_Disable failed!!"); 5335 return UNKNOWN_ERROR; 5336 } 5337 } 5338 /* Flush the Busy Q */ 5339 cam_frame_flush_video(); 5340 /* Need to flush the free Qs as these are initalized in initPreview.*/ 5341 LINK_camframe_release_all_frames(CAM_VIDEO_FRAME); 5342 LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME); 5343 mPreviewInitialized = false; 5344 mOverlayLock.lock(); 5345 //mOverlay = NULL; 5346 mOverlayLock.unlock(); 5347 ALOGE("startPreview X: native_start_ops: CAMERA_OPS_STREAMING_PREVIEW ioctl failed!"); 5348 return UNKNOWN_ERROR; 5349 } 5350 5351 //Reset the Gps Information 5352 exif_table_numEntries = 0; 5353 previewWidthToNativeZoom = previewWidth; 5354 previewHeightToNativeZoom = previewHeight; 5355 5356 ALOGV("startPreviewInternal X"); 5357 return NO_ERROR; 5358 } 5359 status_t QualcommCameraHardware::startInitialPreview() { 5360 mCameraRunning = DUMMY_CAMERA_STARTED; 5361 return NO_ERROR; 5362 } 5363 status_t QualcommCameraHardware::startPreview() 5364 { 5365 status_t result; 5366 ALOGV("startPreview E"); 5367 Mutex::Autolock l(&mLock); 5368 if( mPreviewWindow == NULL) { 5369 /* startPreview has been called before setting the preview 5370 * window. Start the camera with initial buffers because the 5371 * CameraService expects the preview to be enabled while 5372 * setting a valid preview window */ 5373 ALOGV(" %s : Starting preview with initial buffers ", __FUNCTION__); 5374 result = startInitialPreview(); 5375 } else { 5376 /* startPreview has been issued after a valid preview window 5377 * is set. Get the preview buffers from gralloc and start 5378 * preview normally */ 5379 ALOGV(" %s : Starting normal preview ", __FUNCTION__); 5380 result = getBuffersAndStartPreview(); 5381 } 5382 ALOGV("startPreview X"); 5383 return result; 5384 } 5385 5386 void QualcommCameraHardware::stopInitialPreview() { 5387 mCameraRunning = 0;//!native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL); 5388 #if 0 5389 ALOGV(" %s : E ", __FUNCTION__); 5390 if (mCameraRunning) { 5391 ALOGV(" %s : Camera was running. Stopping ", __FUNCTION__); 5392 { 5393 Mutex::Autolock l(&mCamframeTimeoutLock); 5394 { 5395 Mutex::Autolock cameraRunningLock(&mCameraRunningLock); 5396 if(!camframe_timeout_flag) { 5397 mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL); 5398 } 5399 } 5400 } 5401 mInitialPreviewHeap.clear(); 5402 mRecordHeap.clear(); 5403 } 5404 ALOGV(" %s : X ", __FUNCTION__); 5405 #endif 5406 } 5407 5408 void QualcommCameraHardware::stopPreviewInternal() 5409 { 5410 ALOGV("stopPreviewInternal E: %d", mCameraRunning); 5411 mPreviewStopping = true; 5412 if (mCameraRunning && mPreviewWindow!=NULL) { 5413 /* For 3D mode, we need to exit the video thread.*/ 5414 if(mIs3DModeOn) { 5415 mRecordingState = 0; 5416 mVideoThreadWaitLock.lock(); 5417 ALOGI("%s: 3D mode, exit video thread", __FUNCTION__); 5418 mVideoThreadExit = 1; 5419 mVideoThreadWaitLock.unlock(); 5420 5421 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 5422 pthread_cond_signal(&(g_busy_frame_queue.wait)); 5423 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 5424 } 5425 5426 // Cancel auto focus. 5427 { 5428 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) { 5429 cancelAutoFocusInternal(); 5430 } 5431 } 5432 5433 // make mSmoothzoomThreadExit true 5434 mSmoothzoomThreadLock.lock(); 5435 mSmoothzoomThreadExit = true; 5436 mSmoothzoomThreadLock.unlock(); 5437 // singal smooth zoom thread , so that it can exit gracefully 5438 mSmoothzoomThreadWaitLock.lock(); 5439 if(mSmoothzoomThreadRunning) 5440 mSmoothzoomThreadWait.signal(); 5441 5442 mSmoothzoomThreadWaitLock.unlock(); 5443 5444 Mutex::Autolock l(&mCamframeTimeoutLock); 5445 { 5446 Mutex::Autolock cameraRunningLock(&mCameraRunningLock); 5447 if(!camframe_timeout_flag) { 5448 if (( mCurrentTarget != TARGET_MSM7630 ) && 5449 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) 5450 mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL); 5451 else{ 5452 if(!mZslEnable){ 5453 ALOGI("%s ops_streaming mCameraRunning b= %d",__FUNCTION__, mCameraRunning); 5454 mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL); 5455 ALOGI("%s ops_streaming mCameraRunning = %d",__FUNCTION__, mCameraRunning); 5456 }else { 5457 mCameraRunning = true; 5458 if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_stop(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){ 5459 deinitZslBuffers(); 5460 if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_deinit(CAMERA_OPS_STREAMING_ZSL, 5461 (void *)&mZslParms, NULL)) { 5462 mCameraRunning = false; 5463 } 5464 } 5465 if(mCameraRunning ==true) 5466 ALOGE("Starting ZSL CAMERA_OPS_STREAMING_ZSL failed!!!"); 5467 } 5468 } 5469 } else { 5470 /* This means that the camframetimeout was issued. 5471 * But we did not issue native_stop_preview(), so we 5472 * need to update mCameraRunning to indicate that 5473 * Camera is no longer running. */ 5474 ALOGE("%s, : MAKE MCAMER_RUNNING FALSE!!!",__FUNCTION__); 5475 mCameraRunning = 0; 5476 } 5477 } 5478 } 5479 /* in 3D mode, wait for the video thread before clearing resources.*/ 5480 if(mIs3DModeOn) { 5481 mVideoThreadWaitLock.lock(); 5482 while (mVideoThreadRunning) { 5483 ALOGI("%s: waiting for video thread to complete.", __FUNCTION__); 5484 mVideoThreadWait.wait(mVideoThreadWaitLock); 5485 ALOGI("%s : video thread completed.", __FUNCTION__); 5486 } 5487 mVideoThreadWaitLock.unlock(); 5488 } 5489 ALOGI("%s, J_mCameraRunning = %d", __FUNCTION__, mCameraRunning); 5490 if (!mCameraRunning) { 5491 ALOGI("%s, before calling deinitpre mPreviewInitialized = %d", __FUNCTION__, mPreviewInitialized); 5492 if(mPreviewInitialized) { 5493 ALOGI("before calling deinitpreview"); 5494 deinitPreview(); 5495 if( ( mCurrentTarget == TARGET_MSM7630 ) || 5496 (mCurrentTarget == TARGET_QSD8250) || 5497 (mCurrentTarget == TARGET_MSM8660)) { 5498 mVideoThreadWaitLock.lock(); 5499 ALOGV("in stopPreviewInternal: making mVideoThreadExit 1"); 5500 mVideoThreadExit = 1; 5501 mVideoThreadWaitLock.unlock(); 5502 //720p : signal the video thread , and check in video thread 5503 //if stop is called, if so exit video thread. 5504 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 5505 pthread_cond_signal(&(g_busy_frame_queue.wait)); 5506 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 5507 5508 ALOGI(" flush video and release all frames"); 5509 /* Flush the Busy Q */ 5510 cam_frame_flush_video(); 5511 /* Flush the Free Q */ 5512 LINK_camframe_release_all_frames(CAM_VIDEO_FRAME); 5513 } 5514 mPreviewInitialized = false; 5515 } 5516 } 5517 else ALOGI("stopPreviewInternal: Preview is stopped already"); 5518 5519 ALOGV("stopPreviewInternal X: %d", mCameraRunning); 5520 } 5521 5522 void QualcommCameraHardware::stopPreview() 5523 { 5524 ALOGV("stopPreview: E"); 5525 Mutex::Autolock l(&mLock); 5526 { 5527 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) 5528 return; 5529 } 5530 if( mSnapshotThreadRunning ) { 5531 ALOGV("In stopPreview during snapshot"); 5532 return; 5533 } 5534 if( mPreviewWindow != NULL ) { 5535 private_handle_t *handle; 5536 for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) { 5537 if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) { 5538 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]); 5539 ALOGI("%s: Cancelling postview buffer %d ", __FUNCTION__, handle->fd); 5540 ALOGI("stoppreview : display lock"); 5541 mDisplayLock.lock(); 5542 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) { 5543 if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) { 5544 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 5545 mDisplayLock.unlock(); 5546 continue; 5547 } else { 5548 mThumbnailLockState[cnt] = BUFFER_UNLOCKED; 5549 } 5550 } 5551 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow, 5552 mThumbnailBuffer[cnt]); 5553 ALOGI("stopPreview : after cancelling thumbnail buffer"); 5554 if(retVal != NO_ERROR) 5555 ALOGE("%s: cancelBuffer failed for postview buffer %d", 5556 __FUNCTION__, handle->fd); 5557 // unregister , unmap and release as well 5558 int mBufferSize = previewWidth * previewHeight * 3/2; 5559 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight); 5560 if(mThumbnailMapped[cnt] && (mSnapshotFormat == PICTURE_FORMAT_JPEG) 5561 || mZslEnable) { 5562 ALOGI("%s: Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd); 5563 register_buf(mBufferSize, 5564 mBufferSize, mCbCrOffset, 0, 5565 handle->fd, 5566 0, 5567 (uint8_t *)mThumbnailMapped[cnt], 5568 MSM_PMEM_THUMBNAIL, 5569 false, false); 5570 if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) { 5571 ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index); 5572 } 5573 mThumbnailMapped[cnt] = NULL; 5574 } 5575 mThumbnailBuffer[cnt] = NULL; 5576 ALOGI("stoppreview : display unlock"); 5577 mDisplayLock.unlock(); 5578 } 5579 } 5580 } 5581 stopPreviewInternal(); 5582 ALOGV("stopPreview: X"); 5583 } 5584 5585 void QualcommCameraHardware::runAutoFocus() 5586 { 5587 bool status = true; 5588 void *libhandle = NULL; 5589 isp3a_af_mode_t afMode = AF_MODE_AUTO; 5590 5591 mAutoFocusThreadLock.lock(); 5592 // Skip autofocus if focus mode is infinity. 5593 5594 const char * focusMode = mParameters.get(QCameraParameters::KEY_FOCUS_MODE); 5595 if ((mParameters.get(QCameraParameters::KEY_FOCUS_MODE) == 0) 5596 || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_INFINITY) == 0) 5597 || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0)) { 5598 goto done; 5599 } 5600 5601 if(!libmmcamera){ 5602 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror()); 5603 mAutoFocusThreadRunning = false; 5604 mAutoFocusThreadLock.unlock(); 5605 return; 5606 } 5607 5608 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes, 5609 sizeof(focus_modes) / sizeof(str_map), 5610 mParameters.get(QCameraParameters::KEY_FOCUS_MODE)); 5611 5612 /* This will block until either AF completes or is cancelled. */ 5613 ALOGV("af start (mode %d)", afMode); 5614 status_t err; 5615 err = mAfLock.tryLock(); 5616 if(err == NO_ERROR) { 5617 { 5618 Mutex::Autolock cameraRunningLock(&mCameraRunningLock); 5619 if(mCameraRunning){ 5620 ALOGV("Start AF"); 5621 status = native_start_ops(CAMERA_OPS_FOCUS ,(void *)&afMode); 5622 }else{ 5623 ALOGV("As Camera preview is not running, AF not issued"); 5624 status = false; 5625 } 5626 } 5627 mAfLock.unlock(); 5628 } 5629 else{ 5630 //AF Cancel would have acquired the lock, 5631 //so, no need to perform any AF 5632 ALOGV("As Cancel auto focus is in progress, auto focus request " 5633 "is ignored"); 5634 status = FALSE; 5635 } 5636 { 5637 Mutex::Autolock pl(&mParametersLock); 5638 if(mHasAutoFocusSupport && (updateFocusDistances(focusMode) != NO_ERROR)) { 5639 ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, focusMode); 5640 } 5641 } 5642 5643 ALOGV("af done: %d", (int)status); 5644 5645 done: 5646 mAutoFocusThreadRunning = false; 5647 mAutoFocusThreadLock.unlock(); 5648 5649 mCallbackLock.lock(); 5650 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS); 5651 camera_notify_callback cb = mNotifyCallback; 5652 void *data = mCallbackCookie; 5653 mCallbackLock.unlock(); 5654 if (autoFocusEnabled) 5655 cb(CAMERA_MSG_FOCUS, status, 0, data); 5656 5657 } 5658 5659 status_t QualcommCameraHardware::cancelAutoFocusInternal() 5660 { 5661 ALOGV("cancelAutoFocusInternal E"); 5662 bool afRunning = true; 5663 5664 if(!mHasAutoFocusSupport){ 5665 ALOGV("cancelAutoFocusInternal X"); 5666 return NO_ERROR; 5667 } 5668 5669 status_t rc = NO_ERROR; 5670 status_t err; 5671 5672 do { 5673 err = mAfLock.tryLock(); 5674 if(err == NO_ERROR) { 5675 //Got Lock, means either AF hasn't started or 5676 // AF is done. So no need to cancel it, just change the state 5677 ALOGV("Auto Focus is not in progress, Cancel Auto Focus is ignored"); 5678 mAfLock.unlock(); 5679 5680 mAutoFocusThreadLock.lock(); 5681 afRunning = mAutoFocusThreadRunning; 5682 mAutoFocusThreadLock.unlock(); 5683 if(afRunning) { 5684 usleep( 5000 ); 5685 } 5686 } 5687 } while ( err == NO_ERROR && afRunning ); 5688 if(afRunning) { 5689 //AF is in Progess, So cancel it 5690 ALOGV("Lock busy...cancel AF"); 5691 rc = native_stop_ops(CAMERA_OPS_FOCUS, NULL) ? 5692 NO_ERROR : UNKNOWN_ERROR; 5693 5694 /*now just wait for auto focus thread to be finished*/ 5695 mAutoFocusThreadLock.lock(); 5696 mAutoFocusThreadLock.unlock(); 5697 } 5698 ALOGV("cancelAutoFocusInternal X: %d", rc); 5699 return rc; 5700 } 5701 5702 void *auto_focus_thread(void *user) 5703 { 5704 ALOGV("auto_focus_thread E"); 5705 CAMERA_HAL_UNUSED(user); 5706 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 5707 if (obj != 0) { 5708 obj->runAutoFocus(); 5709 } 5710 else ALOGW("not starting autofocus: the object went away!"); 5711 ALOGV("auto_focus_thread X"); 5712 return NULL; 5713 } 5714 5715 status_t QualcommCameraHardware::autoFocus() 5716 { 5717 ALOGV("autoFocus E"); 5718 Mutex::Autolock l(&mLock); 5719 5720 if(!mHasAutoFocusSupport){ 5721 /* 5722 * If autofocus is not supported HAL defaults 5723 * focus mode to infinity and supported mode to 5724 * infinity also. In this mode and fixed mode app 5725 * should not call auto focus. 5726 */ 5727 ALOGI("Auto Focus not supported"); 5728 ALOGV("autoFocus X"); 5729 return INVALID_OPERATION; 5730 } 5731 { 5732 mAutoFocusThreadLock.lock(); 5733 if (!mAutoFocusThreadRunning) { 5734 5735 // Create a detached thread here so that we don't have to wait 5736 // for it when we cancel AF. 5737 pthread_t thr; 5738 pthread_attr_t attr; 5739 pthread_attr_init(&attr); 5740 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 5741 mAutoFocusThreadRunning = 5742 !pthread_create(&thr, &attr, 5743 auto_focus_thread, NULL); 5744 if (!mAutoFocusThreadRunning) { 5745 ALOGE("failed to start autofocus thread"); 5746 mAutoFocusThreadLock.unlock(); 5747 return UNKNOWN_ERROR; 5748 } 5749 } 5750 mAutoFocusThreadLock.unlock(); 5751 } 5752 5753 ALOGV("autoFocus X"); 5754 return NO_ERROR; 5755 } 5756 5757 status_t QualcommCameraHardware::cancelAutoFocus() 5758 { 5759 ALOGV("cancelAutoFocus E"); 5760 Mutex::Autolock l(&mLock); 5761 5762 int rc = NO_ERROR; 5763 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) { 5764 rc = cancelAutoFocusInternal(); 5765 } 5766 5767 ALOGV("cancelAutoFocus X"); 5768 return rc; 5769 } 5770 5771 void QualcommCameraHardware::runSnapshotThread(void *data) 5772 { 5773 bool ret = true; 5774 CAMERA_HAL_UNUSED(data); 5775 ALOGI("runSnapshotThread E"); 5776 5777 if(!libmmcamera){ 5778 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror()); 5779 } 5780 mSnapshotCancelLock.lock(); 5781 if(mSnapshotCancel == true) { 5782 mSnapshotCancel = false; 5783 mSnapshotCancelLock.unlock(); 5784 ALOGI("%s: cancelpicture has been called..so abort taking snapshot", __FUNCTION__); 5785 deinitRaw(); 5786 mInSnapshotModeWaitLock.lock(); 5787 mInSnapshotMode = false; 5788 mInSnapshotModeWait.signal(); 5789 mInSnapshotModeWaitLock.unlock(); 5790 mSnapshotThreadWaitLock.lock(); 5791 mSnapshotThreadRunning = false; 5792 mSnapshotThreadWait.signal(); 5793 mSnapshotThreadWaitLock.unlock(); 5794 return; 5795 } 5796 mSnapshotCancelLock.unlock(); 5797 5798 mJpegThreadWaitLock.lock(); 5799 mJpegThreadRunning = true; 5800 mJpegThreadWait.signal(); 5801 mJpegThreadWaitLock.unlock(); 5802 mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ? 5803 CAMERA_OPS_CAPTURE_AND_ENCODE : 5804 CAMERA_OPS_RAW_CAPTURE; 5805 if(strTexturesOn == true) { 5806 current_ops_type = CAMERA_OPS_CAPTURE; 5807 mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms, 5808 NULL); 5809 } else if(mSnapshotFormat == PICTURE_FORMAT_JPEG){ 5810 if(!mZslEnable || mZslFlashEnable){ 5811 mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms, 5812 (void *)&mImageEncodeParms); 5813 }else{ 5814 notifyShutter(TRUE); 5815 initZslParameter(); 5816 ALOGI("snapshot mZslCapture.thumbnail %d %d %d",mZslCaptureParms.thumbnail_width, 5817 mZslCaptureParms.thumbnail_height,mZslCaptureParms.num_captures); 5818 mCamOps.mm_camera_start(current_ops_type,(void *)&mZslCaptureParms, 5819 (void *)&mImageEncodeParms); 5820 } 5821 mJpegThreadWaitLock.lock(); 5822 while (mJpegThreadRunning) { 5823 ALOGV("%s: waiting for jpeg callback.", __FUNCTION__); 5824 mJpegThreadWait.wait(mJpegThreadWaitLock); 5825 ALOGV("%s: jpeg callback received.", __FUNCTION__); 5826 } 5827 mJpegThreadWaitLock.unlock(); 5828 5829 //cleanup 5830 if(!mZslEnable || mZslFlashEnable) 5831 deinitRaw(); 5832 }else if(mSnapshotFormat == PICTURE_FORMAT_RAW){ 5833 notifyShutter(TRUE); 5834 mCamOps.mm_camera_start(current_ops_type,(void *)&mRawCaptureParms, 5835 NULL); 5836 // Waiting for callback to come 5837 ALOGV("runSnapshotThread : waiting for callback to come"); 5838 mJpegThreadWaitLock.lock(); 5839 while (mJpegThreadRunning) { 5840 ALOGV("%s: waiting for jpeg callback.", __FUNCTION__); 5841 mJpegThreadWait.wait(mJpegThreadWaitLock); 5842 ALOGV("%s: jpeg callback received.", __FUNCTION__); 5843 } 5844 mJpegThreadWaitLock.unlock(); 5845 ALOGV("runSnapshotThread : calling deinitRawSnapshot"); 5846 deinitRawSnapshot(); 5847 5848 } 5849 5850 if(!mZslEnable || mZslFlashEnable) 5851 mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL); 5852 mZslFlashEnable = false; 5853 mSnapshotThreadWaitLock.lock(); 5854 mSnapshotThreadRunning = false; 5855 mSnapshotThreadWait.signal(); 5856 mSnapshotThreadWaitLock.unlock(); 5857 ALOGV("runSnapshotThread X"); 5858 } 5859 5860 void *snapshot_thread(void *user) 5861 { 5862 ALOGD("snapshot_thread E"); 5863 CAMERA_HAL_UNUSED(user); 5864 QualcommCameraHardware *obj = QualcommCameraHardware::getInstance(); 5865 if (obj != 0) { 5866 obj->runSnapshotThread(user); 5867 } 5868 else ALOGW("not starting snapshot thread: the object went away!"); 5869 ALOGD("snapshot_thread X"); 5870 return NULL; 5871 } 5872 5873 status_t QualcommCameraHardware::takePicture() 5874 { 5875 ALOGE("takePicture(%d)", mMsgEnabled); 5876 Mutex::Autolock l(&mLock); 5877 if(mRecordingState ) { 5878 return takeLiveSnapshotInternal( ); 5879 } 5880 5881 if(strTexturesOn == true){ 5882 mEncodePendingWaitLock.lock(); 5883 while(mEncodePending) { 5884 ALOGI("takePicture: Frame given to application, waiting for encode call"); 5885 mEncodePendingWait.wait(mEncodePendingWaitLock); 5886 ALOGI("takePicture: Encode of the application data is done"); 5887 } 5888 mEncodePendingWaitLock.unlock(); 5889 } 5890 5891 // Wait for old snapshot thread to complete. 5892 mSnapshotThreadWaitLock.lock(); 5893 while (mSnapshotThreadRunning) { 5894 ALOGV("takePicture: waiting for old snapshot thread to complete."); 5895 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock); 5896 ALOGV("takePicture: old snapshot thread completed."); 5897 } 5898 // if flash is enabled then run snapshot as normal mode and not zsl mode. 5899 // App should expect only 1 callback as multi snapshot in normal mode is not supported 5900 mZslFlashEnable = false; 5901 if(mZslEnable){ 5902 int is_flash_needed = 0; 5903 mm_camera_status_t status; 5904 status = mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP, 5905 (void *)&is_flash_needed); 5906 if(is_flash_needed) { 5907 mZslFlashEnable = true; 5908 } 5909 } 5910 //Adding ExifTag for Flash 5911 const char *flash_str = mParameters.get(QCameraParameters::KEY_FLASH_MODE); 5912 if(flash_str){ 5913 int is_flash_fired = 0; 5914 if(mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP, 5915 (void *)&is_flash_fired) != MM_CAMERA_SUCCESS){ 5916 flashMode = FLASH_SNAP ; //for No Flash support,bit 5 will be 1 5917 } else { 5918 if(!strcmp(flash_str,"on")) 5919 flashMode = 1; 5920 5921 if(!strcmp(flash_str,"off")) 5922 flashMode = 0; 5923 5924 if(!strcmp(flash_str,"auto")){ 5925 //for AUTO bits 3 and 4 will be 1 5926 //for flash fired bit 0 will be 1, else 0 5927 flashMode = FLASH_AUTO; 5928 if(is_flash_fired) 5929 flashMode = (is_flash_fired>>1) | flashMode ; 5930 } 5931 } 5932 addExifTag(EXIFTAGID_FLASH,EXIF_SHORT,1,1,(void *)&flashMode); 5933 } 5934 5935 if(mParameters.getPictureFormat() != 0 && 5936 !strcmp(mParameters.getPictureFormat(), 5937 QCameraParameters::PIXEL_FORMAT_RAW)){ 5938 mSnapshotFormat = PICTURE_FORMAT_RAW; 5939 { 5940 // HACK: Raw ZSL capture is not supported yet 5941 mZslFlashEnable = true; 5942 } 5943 } 5944 else 5945 mSnapshotFormat = PICTURE_FORMAT_JPEG; 5946 5947 if(!mZslEnable || mZslFlashEnable){ 5948 if((mSnapshotFormat == PICTURE_FORMAT_JPEG)){ 5949 if(!native_start_ops(CAMERA_OPS_PREPARE_SNAPSHOT, NULL)) { 5950 mSnapshotThreadWaitLock.unlock(); 5951 ALOGE("PREPARE SNAPSHOT: CAMERA_OPS_PREPARE_SNAPSHOT ioctl Failed"); 5952 return UNKNOWN_ERROR; 5953 } 5954 } 5955 } 5956 else { 5957 int rotation = mParameters.getInt("rotation"); 5958 native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation); 5959 } 5960 #if 0 // TODO for ICS 5961 if(mCurrentTarget == TARGET_MSM8660) { 5962 /* Store the last frame queued for preview. This 5963 * shall be used as postview */ 5964 if (!(storePreviewFrameForPostview())) 5965 return UNKNOWN_ERROR; 5966 } 5967 #endif 5968 if(!mZslEnable || mZslFlashEnable) 5969 stopPreviewInternal(); 5970 #if 0 5971 else if(mZslEnable && !mZslPanorama) { 5972 /* Dont stop preview if ZSL Panorama is enabled for 5973 * Continuous viewfinder support*/ 5974 ALOGE("Calling stop preview"); 5975 mCamOps.mm_camera_stop(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL); 5976 } 5977 #endif 5978 5979 5980 mFrameThreadWaitLock.unlock(); 5981 5982 mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ? 5983 CAMERA_OPS_CAPTURE_AND_ENCODE : 5984 CAMERA_OPS_RAW_CAPTURE; 5985 if(strTexturesOn == true) 5986 current_ops_type = CAMERA_OPS_CAPTURE; 5987 5988 if( !mZslEnable || mZslFlashEnable) 5989 mCamOps.mm_camera_init(current_ops_type, NULL, NULL); 5990 5991 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){ 5992 if(!mZslEnable || mZslFlashEnable) { 5993 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) { 5994 ALOGE("initRaw failed. Not taking picture."); 5995 mSnapshotThreadWaitLock.unlock(); 5996 return UNKNOWN_ERROR; 5997 } 5998 } 5999 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){ 6000 if(!initRawSnapshot()){ 6001 ALOGE("initRawSnapshot failed. Not taking picture."); 6002 mSnapshotThreadWaitLock.unlock(); 6003 return UNKNOWN_ERROR; 6004 } 6005 } 6006 6007 mShutterLock.lock(); 6008 mShutterPending = true; 6009 mShutterLock.unlock(); 6010 6011 mSnapshotCancelLock.lock(); 6012 mSnapshotCancel = false; 6013 mSnapshotCancelLock.unlock(); 6014 6015 numJpegReceived = 0; 6016 pthread_attr_t attr; 6017 pthread_attr_init(&attr); 6018 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 6019 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread, 6020 &attr, 6021 snapshot_thread, 6022 NULL); 6023 mSnapshotThreadWaitLock.unlock(); 6024 6025 mInSnapshotModeWaitLock.lock(); 6026 mInSnapshotMode = true; 6027 mInSnapshotModeWaitLock.unlock(); 6028 6029 ALOGV("takePicture: X"); 6030 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR; 6031 } 6032 6033 void QualcommCameraHardware::set_liveshot_exifinfo() 6034 { 6035 6036 setGpsParameters(); 6037 //set TimeStamp 6038 const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME); 6039 if(str != NULL) { 6040 strncpy(dateTime, str, 19); 6041 dateTime[19] = '\0'; 6042 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII, 6043 20, 1, (void *)dateTime); 6044 } 6045 } 6046 6047 6048 status_t QualcommCameraHardware::takeLiveSnapshotInternal() 6049 { 6050 ALOGV("takeLiveSnapshotInternal : E"); 6051 if(liveshot_state == LIVESHOT_IN_PROGRESS || !mRecordingState) { 6052 return NO_ERROR; 6053 } 6054 6055 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660) && (mCurrentTarget != TARGET_MSM7627A)) { 6056 ALOGI("LiveSnapshot not supported on this target"); 6057 liveshot_state = LIVESHOT_STOPPED; 6058 return NO_ERROR; 6059 } 6060 6061 liveshot_state = LIVESHOT_IN_PROGRESS; 6062 6063 if (!initLiveSnapshot(videoWidth, videoHeight)) { 6064 ALOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed. Not taking Live Snapshot."); 6065 liveshot_state = LIVESHOT_STOPPED; 6066 return UNKNOWN_ERROR; 6067 } 6068 uint32_t maxjpegsize = videoWidth * videoHeight *1.5; 6069 set_liveshot_exifinfo(); 6070 if(!LINK_set_liveshot_params(videoWidth, videoHeight, 6071 exif_data, exif_table_numEntries, 6072 (uint8_t *)mJpegLiveSnapMapped->data, maxjpegsize)) { 6073 ALOGE("Link_set_liveshot_params failed."); 6074 if (NULL != mJpegLiveSnapMapped) { 6075 ALOGV("initLiveSnapshot: clearing old mJpegHeap."); 6076 mJpegLiveSnapMapped->release(mJpegLiveSnapMapped); 6077 mJpegLiveSnapMapped = NULL; 6078 } 6079 return NO_ERROR; 6080 } 6081 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) { 6082 if(!native_start_ops(CAMERA_OPS_LIVESHOT, NULL)) { 6083 ALOGE("start_liveshot ioctl failed"); 6084 liveshot_state = LIVESHOT_STOPPED; 6085 if (NULL != mJpegLiveSnapMapped) { 6086 ALOGV("initLiveSnapshot: clearing old mJpegHeap."); 6087 mJpegLiveSnapMapped->release(mJpegLiveSnapMapped); 6088 mJpegLiveSnapMapped = NULL; 6089 } 6090 return UNKNOWN_ERROR; 6091 } 6092 } 6093 6094 ALOGV("takeLiveSnapshotInternal: X"); 6095 return NO_ERROR; 6096 } 6097 6098 status_t QualcommCameraHardware::takeLiveSnapshot() 6099 { 6100 ALOGV("takeLiveSnapshot: E "); 6101 Mutex::Autolock l(&mLock); 6102 ALOGV("takeLiveSnapshot: X "); 6103 return takeLiveSnapshotInternal( ); 6104 } 6105 6106 bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight) 6107 { 6108 ALOGV("initLiveSnapshot E"); 6109 6110 if (NULL != mJpegLiveSnapMapped) { 6111 ALOGV("initLiveSnapshot: clearing old mJpegHeap."); 6112 mJpegLiveSnapMapped->release(mJpegLiveSnapMapped); 6113 mJpegLiveSnapMapped = NULL; 6114 } 6115 6116 mJpegMaxSize = videowidth * videoheight * 1.5; 6117 ALOGV("initLiveSnapshot: initializing mJpegHeap."); 6118 mJpegLiveSnapMapped = mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie); 6119 if(mJpegLiveSnapMapped == NULL) { 6120 ALOGE("Failed to get camera memory for mJpegLibeSnapMapped" ); 6121 return false; 6122 } 6123 ALOGV("initLiveSnapshot X"); 6124 return true; 6125 } 6126 6127 6128 status_t QualcommCameraHardware::cancelPicture() 6129 { 6130 status_t rc; 6131 ALOGV("cancelPicture: E"); 6132 6133 mSnapshotCancelLock.lock(); 6134 ALOGI("%s: setting mSnapshotCancel to true", __FUNCTION__); 6135 mSnapshotCancel = true; 6136 mSnapshotCancelLock.unlock(); 6137 6138 if (mCurrentTarget == TARGET_MSM7627 || 6139 (mCurrentTarget == TARGET_MSM7625A || 6140 mCurrentTarget == TARGET_MSM7627A)) { 6141 mSnapshotDone = TRUE; 6142 mSnapshotThreadWaitLock.lock(); 6143 while (mSnapshotThreadRunning) { 6144 ALOGV("cancelPicture: waiting for snapshot thread to complete."); 6145 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock); 6146 ALOGV("cancelPicture: snapshot thread completed."); 6147 } 6148 mSnapshotThreadWaitLock.unlock(); 6149 } 6150 rc = native_stop_ops(CAMERA_OPS_CAPTURE, NULL) ? NO_ERROR : UNKNOWN_ERROR; 6151 mSnapshotDone = FALSE; 6152 ALOGV("cancelPicture: X: %d", rc); 6153 return rc; 6154 } 6155 6156 status_t QualcommCameraHardware::setParameters(const QCameraParameters& params) 6157 { 6158 ALOGV("setParameters: E params = %p", ¶ms); 6159 6160 Mutex::Autolock l(&mLock); 6161 Mutex::Autolock pl(&mParametersLock); 6162 status_t rc, final_rc = NO_ERROR; 6163 if (mSnapshotThreadRunning) { 6164 if ((rc = setCameraMode(params))) final_rc = rc; 6165 if ((rc = setPreviewSize(params))) final_rc = rc; 6166 if ((rc = setRecordSize(params))) final_rc = rc; 6167 if ((rc = setPictureSize(params))) final_rc = rc; 6168 if ((rc = setJpegThumbnailSize(params))) final_rc = rc; 6169 if ((rc = setJpegQuality(params))) final_rc = rc; 6170 return final_rc; 6171 } 6172 if ((rc = setCameraMode(params))) final_rc = rc; 6173 if ((rc = setPreviewSize(params))) final_rc = rc; 6174 if ((rc = setRecordSize(params))) final_rc = rc; 6175 if ((rc = setPictureSize(params))) final_rc = rc; 6176 if ((rc = setJpegThumbnailSize(params))) final_rc = rc; 6177 if ((rc = setJpegQuality(params))) final_rc = rc; 6178 if ((rc = setPictureFormat(params))) final_rc = rc; 6179 if ((rc = setRecordSize(params))) final_rc = rc; 6180 if ((rc = setPreviewFormat(params))) final_rc = rc; 6181 if ((rc = setEffect(params))) final_rc = rc; 6182 if ((rc = setGpsLocation(params))) final_rc = rc; 6183 if ((rc = setRotation(params))) final_rc = rc; 6184 if ((rc = setZoom(params))) final_rc = rc; 6185 if ((rc = setOrientation(params))) final_rc = rc; 6186 if ((rc = setLensshadeValue(params))) final_rc = rc; 6187 if ((rc = setMCEValue(params))) final_rc = rc; 6188 //if ((rc = setHDRImaging(params))) final_rc = rc; 6189 if ((rc = setExpBracketing(params))) final_rc = rc; 6190 if ((rc = setPictureFormat(params))) final_rc = rc; 6191 if ((rc = setSharpness(params))) final_rc = rc; 6192 if ((rc = setSaturation(params))) final_rc = rc; 6193 if ((rc = setTouchAfAec(params))) final_rc = rc; 6194 if ((rc = setSceneMode(params))) final_rc = rc; 6195 if ((rc = setContrast(params))) final_rc = rc; 6196 if ((rc = setRecordSize(params))) final_rc = rc; 6197 if ((rc = setSceneDetect(params))) final_rc = rc; 6198 if ((rc = setStrTextures(params))) final_rc = rc; 6199 if ((rc = setPreviewFormat(params))) final_rc = rc; 6200 if ((rc = setSkinToneEnhancement(params))) final_rc = rc; 6201 if ((rc = setAntibanding(params))) final_rc = rc; 6202 if ((rc = setRedeyeReduction(params))) final_rc = rc; 6203 if ((rc = setDenoise(params))) final_rc = rc; 6204 if ((rc = setPreviewFpsRange(params))) final_rc = rc; 6205 if ((rc = setZslParam(params))) final_rc = rc; 6206 if ((rc = setSnapshotCount(params))) final_rc = rc; 6207 if((rc = setRecordingHint(params))) final_rc = rc; 6208 const char *str = params.get(QCameraParameters::KEY_SCENE_MODE); 6209 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str); 6210 6211 if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF)) { 6212 if ((rc = setPreviewFrameRate(params))) final_rc = rc; 6213 // if ((rc = setPreviewFrameRateMode(params))) final_rc = rc; 6214 if ((rc = setAutoExposure(params))) final_rc = rc; 6215 if ((rc = setExposureCompensation(params))) final_rc = rc; 6216 if ((rc = setWhiteBalance(params))) final_rc = rc; 6217 if ((rc = setFlash(params))) final_rc = rc; 6218 if ((rc = setFocusMode(params))) final_rc = rc; 6219 if ((rc = setBrightness(params))) final_rc = rc; 6220 if ((rc = setISOValue(params))) final_rc = rc; 6221 if ((rc = setFocusAreas(params))) final_rc = rc; 6222 if ((rc = setMeteringAreas(params))) final_rc = rc; 6223 } 6224 //selectableZoneAF needs to be invoked after continuous AF 6225 if ((rc = setSelectableZoneAf(params))) final_rc = rc; 6226 // setHighFrameRate needs to be done at end, as there can 6227 // be a preview restart, and need to use the updated parameters 6228 if ((rc = setHighFrameRate(params))) final_rc = rc; 6229 6230 ALOGV("setParameters: X"); 6231 return final_rc; 6232 } 6233 6234 QCameraParameters QualcommCameraHardware::getParameters() const 6235 { 6236 ALOGV("getParameters: EX"); 6237 return mParameters; 6238 } 6239 status_t QualcommCameraHardware::setHistogramOn() 6240 { 6241 ALOGV("setHistogramOn: EX"); 6242 mStatsWaitLock.lock(); 6243 mSendData = true; 6244 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE) { 6245 mStatsWaitLock.unlock(); 6246 return NO_ERROR; 6247 } 6248 #if 0 6249 if (mStatHeap != NULL) { 6250 ALOGV("setHistogram on: clearing old mStatHeap."); 6251 mStatHeap.clear(); 6252 } 6253 #endif 6254 6255 mStatSize = sizeof(uint32_t)* HISTOGRAM_STATS_SIZE; 6256 mCurrent = -1; 6257 /*Currently the Ashmem is multiplying the buffer size with total number 6258 of buffers and page aligning. This causes a crash in JNI as each buffer 6259 individually expected to be page aligned */ 6260 int page_size_minus_1 = getpagesize() - 1; 6261 int32_t mAlignedStatSize = ((mStatSize + page_size_minus_1) & (~page_size_minus_1)); 6262 #if 0 6263 mStatHeap = 6264 new AshmemPool(mAlignedStatSize, 6265 3, 6266 mStatSize, 6267 "stat"); 6268 if (!mStatHeap->initialized()) { 6269 ALOGE("Stat Heap X failed "); 6270 mStatHeap.clear(); 6271 ALOGE("setHistogramOn X: error initializing mStatHeap"); 6272 mStatsWaitLock.unlock(); 6273 return UNKNOWN_ERROR; 6274 } 6275 #endif 6276 for(int cnt = 0; cnt<3; cnt++) { 6277 mStatsMapped[cnt]=mGetMemory(-1, mStatSize,1,mCallbackCookie); 6278 if(mStatsMapped[cnt] == NULL) { 6279 ALOGE("Failed to get camera memory for stats heap index: %d", cnt); 6280 mStatsWaitLock.unlock(); 6281 return false; 6282 }else{ 6283 ALOGV("Received following info for stats mapped data:%p,handle:%p, size:%d,release:%p", 6284 mStatsMapped[cnt]->data ,mStatsMapped[cnt]->handle, mStatsMapped[cnt]->size, mStatsMapped[cnt]->release); 6285 } 6286 } 6287 mStatsOn = CAMERA_HISTOGRAM_ENABLE; 6288 mStatsWaitLock.unlock(); 6289 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn); 6290 return NO_ERROR; 6291 } 6292 6293 status_t QualcommCameraHardware::setHistogramOff() 6294 { 6295 ALOGV("setHistogramOff: EX"); 6296 mStatsWaitLock.lock(); 6297 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) { 6298 mStatsWaitLock.unlock(); 6299 return NO_ERROR; 6300 } 6301 mStatsOn = CAMERA_HISTOGRAM_DISABLE; 6302 mStatsWaitLock.unlock(); 6303 6304 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn); 6305 6306 mStatsWaitLock.lock(); 6307 // mStatHeap.clear(); 6308 for(int i=0; i<3; i++){ 6309 if(mStatsMapped[i] != NULL){ 6310 mStatsMapped[i]->release(mStatsMapped[i]); 6311 mStatsMapped[i] = NULL; 6312 } 6313 } 6314 6315 mStatsWaitLock.unlock(); 6316 return NO_ERROR; 6317 } 6318 6319 6320 status_t QualcommCameraHardware::runFaceDetection() 6321 { 6322 bool ret = true; 6323 #if 0 6324 const char *str = mParameters.get(QCameraParameters::KEY_FACE_DETECTION); 6325 if (str != NULL) { 6326 int value = attr_lookup(facedetection, 6327 sizeof(facedetection) / sizeof(str_map), str); 6328 6329 mMetaDataWaitLock.lock(); 6330 if (value == true) { 6331 if(mMetaDataHeap != NULL) 6332 mMetaDataHeap.clear(); 6333 6334 mMetaDataHeap = 6335 new AshmemPool((sizeof(int)*(MAX_ROI*4+1)), 6336 1, 6337 (sizeof(int)*(MAX_ROI*4+1)), 6338 "metadata"); 6339 if (!mMetaDataHeap->initialized()) { 6340 ALOGE("Meta Data Heap allocation failed "); 6341 mMetaDataHeap.clear(); 6342 ALOGE("runFaceDetection X: error initializing mMetaDataHeap"); 6343 mMetaDataWaitLock.unlock(); 6344 return UNKNOWN_ERROR; 6345 } 6346 mSendMetaData = true; 6347 } else { 6348 if(mMetaDataHeap != NULL) 6349 mMetaDataHeap.clear(); 6350 } 6351 mMetaDataWaitLock.unlock(); 6352 ret = native_set_parms(CAMERA_PARM_FD, sizeof(int8_t), (void *)&value); 6353 return ret ? NO_ERROR : UNKNOWN_ERROR; 6354 } 6355 ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str); 6356 #endif 6357 return BAD_VALUE; 6358 } 6359 6360 void* smoothzoom_thread(void* user) 6361 { 6362 // call runsmoothzoomthread 6363 ALOGV("smoothzoom_thread E"); 6364 CAMERA_HAL_UNUSED(user); 6365 6366 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 6367 if (obj != 0) { 6368 obj->runSmoothzoomThread(user); 6369 } 6370 else ALOGE("not starting smooth zoom thread: the object went away!"); 6371 ALOGV("Smoothzoom_thread X"); 6372 return NULL; 6373 } 6374 6375 status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1, 6376 int32_t arg2) 6377 { 6378 ALOGV("sendCommand: EX"); 6379 CAMERA_HAL_UNUSED(arg1); 6380 CAMERA_HAL_UNUSED(arg2); 6381 Mutex::Autolock l(&mLock); 6382 6383 switch(command) { 6384 case CAMERA_CMD_HISTOGRAM_ON: 6385 ALOGV("histogram set to on"); 6386 return setHistogramOn(); 6387 case CAMERA_CMD_HISTOGRAM_OFF: 6388 ALOGV("histogram set to off"); 6389 return setHistogramOff(); 6390 case CAMERA_CMD_HISTOGRAM_SEND_DATA: 6391 mStatsWaitLock.lock(); 6392 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE) 6393 mSendData = true; 6394 mStatsWaitLock.unlock(); 6395 return NO_ERROR; 6396 #if 0 6397 case CAMERA_CMD_FACE_DETECTION_ON: 6398 if(supportsFaceDetection() == false){ 6399 ALOGI("face detection support is not available"); 6400 return NO_ERROR; 6401 } 6402 6403 setFaceDetection("on"); 6404 return runFaceDetection(); 6405 case CAMERA_CMD_FACE_DETECTION_OFF: 6406 if(supportsFaceDetection() == false){ 6407 ALOGI("face detection support is not available"); 6408 return NO_ERROR; 6409 } 6410 setFaceDetection("off"); 6411 return runFaceDetection(); 6412 case CAMERA_CMD_SEND_META_DATA: 6413 mMetaDataWaitLock.lock(); 6414 if(mFaceDetectOn == true) { 6415 mSendMetaData = true; 6416 } 6417 mMetaDataWaitLock.unlock(); 6418 return NO_ERROR; 6419 case CAMERA_CMD_START_SMOOTH_ZOOM : 6420 ALOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2); 6421 mTargetSmoothZoom = arg1; 6422 if(!mPreviewStopping) { 6423 // create smooth zoom thread 6424 mSmoothzoomThreadLock.lock(); 6425 mSmoothzoomThreadExit = false; 6426 pthread_attr_t attr; 6427 pthread_attr_init(&attr); 6428 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 6429 pthread_create(&mSmoothzoomThread, 6430 &attr, 6431 smoothzoom_thread, 6432 NULL); 6433 mSmoothzoomThreadLock.unlock(); 6434 } else 6435 ALOGV(" Not creating smooth zoom thread " 6436 " since preview is stopping "); 6437 mTargetSmoothZoom = arg1; 6438 return NO_ERROR; 6439 6440 case CAMERA_CMD_STOP_SMOOTH_ZOOM : 6441 mSmoothzoomThreadLock.lock(); 6442 mSmoothzoomThreadExit = true; 6443 mSmoothzoomThreadLock.unlock(); 6444 ALOGV("HAL sendcmd stop smooth zoom"); 6445 return NO_ERROR; 6446 #endif 6447 } 6448 return BAD_VALUE; 6449 } 6450 6451 void QualcommCameraHardware::runSmoothzoomThread(void * data) { 6452 6453 ALOGV("runSmoothzoomThread: Current zoom %d - " 6454 "Target %d", mParameters.getInt("zoom"), mTargetSmoothZoom); 6455 int current_zoom = mParameters.getInt("zoom"); 6456 int step = (current_zoom > mTargetSmoothZoom)? -1: 1; 6457 6458 if(current_zoom == mTargetSmoothZoom) { 6459 ALOGV("Smoothzoom target zoom value is same as " 6460 "current zoom value, return..."); 6461 if(!mPreviewStopping) 6462 mNotifyCallback(CAMERA_MSG_ZOOM, 6463 current_zoom, 1, mCallbackCookie); 6464 else 6465 ALOGV("Not issuing callback since preview is stopping"); 6466 return; 6467 } 6468 6469 QCameraParameters p = getParameters(); 6470 6471 mSmoothzoomThreadWaitLock.lock(); 6472 mSmoothzoomThreadRunning = true; 6473 mSmoothzoomThreadWaitLock.unlock(); 6474 6475 int i = current_zoom; 6476 while(1) { // Thread loop 6477 mSmoothzoomThreadLock.lock(); 6478 if(mSmoothzoomThreadExit) { 6479 ALOGV("Exiting smoothzoom thread, as stop smoothzoom called"); 6480 mSmoothzoomThreadLock.unlock(); 6481 break; 6482 } 6483 mSmoothzoomThreadLock.unlock(); 6484 6485 if((i < 0) || (i > mMaxZoom)) { 6486 ALOGE(" ERROR : beyond supported zoom values, break.."); 6487 break; 6488 } 6489 // update zoom 6490 p.set("zoom", i); 6491 setZoom(p); 6492 if(!mPreviewStopping) { 6493 // give call back to zoom listener in app 6494 mNotifyCallback(CAMERA_MSG_ZOOM, i, (mTargetSmoothZoom-i == 0)?1:0, 6495 mCallbackCookie); 6496 } else { 6497 ALOGV("Preview is stopping. Breaking out of smooth zoom loop"); 6498 break; 6499 } 6500 if(i == mTargetSmoothZoom) 6501 break; 6502 6503 i+=step; 6504 6505 /* wait on singal, which will be signalled on 6506 * receiving next preview frame */ 6507 mSmoothzoomThreadWaitLock.lock(); 6508 mSmoothzoomThreadWait.wait(mSmoothzoomThreadWaitLock); 6509 mSmoothzoomThreadWaitLock.unlock(); 6510 } // while loop over, exiting thread 6511 6512 mSmoothzoomThreadWaitLock.lock(); 6513 mSmoothzoomThreadRunning = false; 6514 mSmoothzoomThreadWaitLock.unlock(); 6515 ALOGV("Exiting Smooth Zoom Thread"); 6516 } 6517 6518 extern "C" QualcommCameraHardware* HAL_openCameraHardware(int cameraId) 6519 { 6520 int i; 6521 ALOGI("openCameraHardware: call createInstance"); 6522 for(i = 0; i < HAL_numOfCameras; i++) { 6523 if(i == cameraId) { 6524 ALOGI("openCameraHardware:Valid camera ID %d", cameraId); 6525 parameter_string_initialized = false; 6526 HAL_currentCameraId = cameraId; 6527 /* The least significant two bits of mode parameter indicates the sensor mode 6528 of 2D or 3D. The next two bits indicates the snapshot mode of 6529 ZSL or NONZSL 6530 */ 6531 #if 0 6532 int sensorModeMask = 0x03 & mode; 6533 if(sensorModeMask & HAL_cameraInfo[i].modes_supported){ 6534 HAL_currentCameraMode = sensorModeMask; 6535 }else{ 6536 ALOGE("openCameraHardware:Invalid camera mode (%d) requested", mode); 6537 return NULL; 6538 } 6539 #endif 6540 HAL_currentCameraMode = CAMERA_MODE_2D; 6541 HAL_currentSnapshotMode = CAMERA_SNAPSHOT_NONZSL; 6542 //Remove values set by app other than supported values 6543 //mode = mode & HAL_cameraInfo[cameraId].modes_supported; 6544 //if((mode & CAMERA_SNAPSHOT_ZSL) == CAMERA_SNAPSHOT_ZSL) 6545 // HAL_currentSnapshotMode = CAMERA_SNAPSHOT_ZSL; 6546 ALOGI("%s: HAL_currentSnapshotMode = %d HAL_currentCameraMode = %d", __FUNCTION__, HAL_currentSnapshotMode, 6547 HAL_currentCameraMode); 6548 return QualcommCameraHardware::createInstance(); 6549 } 6550 } 6551 ALOGE("openCameraHardware:Invalid camera ID %d", cameraId); 6552 return NULL; 6553 } 6554 6555 //wp<QualcommCameraHardware> QualcommCameraHardware::singleton; 6556 6557 // If the hardware already exists, return a strong pointer to the current 6558 // object. If not, create a new hardware object, put it in the singleton, 6559 // and return it. 6560 QualcommCameraHardware* QualcommCameraHardware::createInstance() 6561 { 6562 ALOGV("createInstance: E"); 6563 #if 0 6564 singleton_lock.lock(); 6565 6566 // Wait until the previous release is done. 6567 while (singleton_releasing) { 6568 if((singleton_releasing_start_time != 0) && 6569 (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){ 6570 ALOGV("in createinstance system time is %lld %lld %lld ", 6571 systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME); 6572 singleton_lock.unlock(); 6573 ALOGE("Previous singleton is busy and time out exceeded. Returning null"); 6574 return NULL; 6575 } 6576 ALOGI("Wait for previous release."); 6577 singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT); 6578 ALOGI("out of Wait for previous release."); 6579 } 6580 6581 if (singleton != 0) { 6582 sp<CameraHardwareInterface> hardware = singleton.promote(); 6583 if (hardware != 0) { 6584 ALOGD("createInstance: X return existing hardware=%p", &(*hardware)); 6585 singleton_lock.unlock(); 6586 return hardware; 6587 } 6588 } 6589 #endif 6590 { 6591 struct stat st; 6592 int rc = stat("/dev/oncrpc", &st); 6593 if (rc < 0) { 6594 ALOGD("createInstance: X failed to create hardware: %s", strerror(errno)); 6595 singleton_lock.unlock(); 6596 return NULL; 6597 } 6598 } 6599 6600 QualcommCameraHardware *cam = new QualcommCameraHardware(); 6601 hardware=cam; 6602 6603 6604 ALOGI("createInstance: created hardware=%p", cam); 6605 if (!cam->startCamera()) { 6606 ALOGE("%s: startCamera failed!", __FUNCTION__); 6607 //singleton_lock.unlock(); 6608 delete cam; 6609 return NULL; 6610 } 6611 6612 cam->initDefaultParameters(); 6613 //singleton_lock.unlock(); 6614 ALOGV("createInstance: X"); 6615 return cam; 6616 } 6617 6618 // For internal use only, hence the strong pointer to the derived type. 6619 QualcommCameraHardware* QualcommCameraHardware::getInstance() 6620 { 6621 //QualcommCameraHardware* hardware = singleton.promote(); 6622 if (hardware != 0) { 6623 // ALOGV("getInstance: X old instance of hardware"); 6624 // return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get())); 6625 return hardware; 6626 } else { 6627 ALOGV("getInstance: X new instance of hardware"); 6628 return new QualcommCameraHardware(); 6629 } 6630 } 6631 void QualcommCameraHardware::receiveRecordingFrame(struct msm_frame *frame) 6632 { 6633 ALOGV("receiveRecordingFrame E"); 6634 // post busy frame 6635 if (frame) 6636 { 6637 cam_frame_post_video (frame); 6638 } 6639 else ALOGE("in receiveRecordingFrame frame is NULL"); 6640 ALOGV("receiveRecordingFrame X"); 6641 } 6642 6643 6644 bool QualcommCameraHardware::native_zoom_image(int fd, int srcOffset, int dstOffSet, common_crop_t *crop) 6645 { 6646 int result = 0; 6647 struct mdp_blit_req *e; 6648 6649 /* Initialize yuv structure */ 6650 zoomImage.list.count = 1; 6651 6652 e = &zoomImage.list.req[0]; 6653 6654 e->src.width = previewWidth; 6655 e->src.height = previewHeight; 6656 e->src.format = MDP_Y_CBCR_H2V2; 6657 e->src.offset = srcOffset; 6658 e->src.memory_id = fd; 6659 6660 e->dst.width = previewWidth; 6661 e->dst.height = previewHeight; 6662 e->dst.format = MDP_Y_CBCR_H2V2; 6663 e->dst.offset = dstOffSet; 6664 e->dst.memory_id = fd; 6665 6666 e->transp_mask = 0xffffffff; 6667 e->flags = 0; 6668 e->alpha = 0xff; 6669 if (crop->in1_w != 0 && crop->in1_h != 0) { 6670 e->src_rect.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1; 6671 e->src_rect.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1; 6672 e->src_rect.w = crop->in1_w; 6673 e->src_rect.h = crop->in1_h; 6674 } else { 6675 e->src_rect.x = 0; 6676 e->src_rect.y = 0; 6677 e->src_rect.w = previewWidth; 6678 e->src_rect.h = previewHeight; 6679 } 6680 //ALOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d", 6681 // e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h); 6682 6683 e->dst_rect.x = 0; 6684 e->dst_rect.y = 0; 6685 e->dst_rect.w = previewWidth; 6686 e->dst_rect.h = previewHeight; 6687 6688 result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list); 6689 if (result < 0) { 6690 ALOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__); 6691 return FALSE; 6692 } 6693 return TRUE; 6694 } 6695 6696 void QualcommCameraHardware::debugShowPreviewFPS() const 6697 { 6698 static int mFrameCount; 6699 static int mLastFrameCount = 0; 6700 static nsecs_t mLastFpsTime = 0; 6701 static float mFps = 0; 6702 mFrameCount++; 6703 nsecs_t now = systemTime(); 6704 nsecs_t diff = now - mLastFpsTime; 6705 if (diff > ms2ns(250)) { 6706 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 6707 ALOGI("Preview Frames Per Second: %.4f", mFps); 6708 mLastFpsTime = now; 6709 mLastFrameCount = mFrameCount; 6710 } 6711 } 6712 6713 void QualcommCameraHardware::debugShowVideoFPS() const 6714 { 6715 static int mFrameCount; 6716 static int mLastFrameCount = 0; 6717 static nsecs_t mLastFpsTime = 0; 6718 static float mFps = 0; 6719 mFrameCount++; 6720 nsecs_t now = systemTime(); 6721 nsecs_t diff = now - mLastFpsTime; 6722 if (diff > ms2ns(250)) { 6723 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 6724 ALOGI("Video Frames Per Second: %.4f", mFps); 6725 mLastFpsTime = now; 6726 mLastFrameCount = mFrameCount; 6727 } 6728 } 6729 6730 void QualcommCameraHardware::receiveLiveSnapshot(uint32_t jpeg_size) 6731 { 6732 ALOGV("receiveLiveSnapshot E"); 6733 #if DUMP_LIVESHOT_JPEG_FILE 6734 int file_fd = open("/data/LiveSnapshot.jpg", O_RDWR | O_CREAT, 0777); 6735 ALOGV("dumping live shot image in /data/LiveSnapshot.jpg"); 6736 if (file_fd < 0) { 6737 ALOGE("cannot open file\n"); 6738 } 6739 else 6740 { 6741 write(file_fd, (uint8_t *)mJpegLiveSnapMapped->data,jpeg_size); 6742 } 6743 close(file_fd); 6744 #endif 6745 Mutex::Autolock cbLock(&mCallbackLock); 6746 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) { 6747 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mJpegLiveSnapMapped ,data_counter, 6748 NULL, mCallbackCookie); 6749 6750 } 6751 else ALOGV("JPEG callback was cancelled--not delivering image."); 6752 6753 //Reset the Gps Information & relieve memory 6754 exif_table_numEntries = 0; 6755 mJpegHeap.clear(); 6756 6757 liveshot_state = LIVESHOT_DONE; 6758 6759 ALOGV("receiveLiveSnapshot X"); 6760 } 6761 void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame) 6762 { 6763 ALOGV("receivePreviewFrame E"); 6764 if (!mCameraRunning) { 6765 ALOGI("ignoring preview callback--camera has been stopped"); 6766 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,frame); 6767 return; 6768 } 6769 if((mCurrentTarget == TARGET_MSM7627A) && ( liveshot_state == LIVESHOT_IN_PROGRESS)) { 6770 LINK_set_liveshot_frame(frame); 6771 } 6772 if(mPreviewBusyQueue.add(frame) == false) 6773 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,frame); 6774 6775 6776 ALOGV("receivePreviewFrame X"); 6777 } 6778 void QualcommCameraHardware::receiveCameraStats(camstats_type stype, camera_preview_histogram_info* histinfo) 6779 { 6780 // ALOGV("receiveCameraStats E"); 6781 CAMERA_HAL_UNUSED(stype); 6782 6783 if (!mCameraRunning) { 6784 ALOGE("ignoring stats callback--camera has been stopped"); 6785 return; 6786 } 6787 6788 mCallbackLock.lock(); 6789 int msgEnabled = mMsgEnabled; 6790 camera_data_callback scb = mDataCallback; 6791 void *sdata = mCallbackCookie; 6792 mCallbackLock.unlock(); 6793 mStatsWaitLock.lock(); 6794 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) { 6795 mStatsWaitLock.unlock(); 6796 return; 6797 } 6798 if(!mSendData) { 6799 mStatsWaitLock.unlock(); 6800 } else { 6801 mSendData = false; 6802 mCurrent = (mCurrent+1)%3; 6803 // The first element of the array will contain the maximum hist value provided by driver. 6804 // *(uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)) = histinfo->max_value; 6805 // memcpy((uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)+ sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256)); 6806 *(uint32_t *)((unsigned int)(mStatsMapped[mCurrent]->data)) = histinfo->max_value; 6807 memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrent]->data + sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256)); 6808 6809 mStatsWaitLock.unlock(); 6810 6811 if (scb != NULL && (msgEnabled & CAMERA_MSG_STATS_DATA)) 6812 scb(CAMERA_MSG_STATS_DATA, mStatsMapped[mCurrent], data_counter, NULL,sdata); 6813 6814 } 6815 // ALOGV("receiveCameraStats X"); 6816 } 6817 /*=========================================================================== 6818 * FUNCTION - do_mmap - 6819 * 6820 * DESCRIPTION: retured virtual addresss 6821 *==========================================================================*/ 6822 uint8_t *mm_camera_do_mmap(uint32_t size, int *pmemFd) 6823 { 6824 void *ret; /* returned virtual address */ 6825 int pmem_fd; 6826 6827 if(mCurrentTarget == TARGET_MSM8660) 6828 pmem_fd = open("/dev/pmem_smipool", O_RDWR|O_SYNC); 6829 else 6830 pmem_fd = open("/dev/pmem_adsp", O_RDWR|O_SYNC); 6831 if (pmem_fd <= 0) { 6832 ALOGE("do_mmap: Open device /dev/pmem_smipool failed!\n"); 6833 return NULL; 6834 } 6835 /* to make it page size aligned */ 6836 size = (size + 4095) & (~4095); 6837 ret = mmap(NULL, 6838 size, 6839 PROT_READ | PROT_WRITE, 6840 MAP_SHARED, 6841 pmem_fd, 6842 0); 6843 if (ret == MAP_FAILED) { 6844 ALOGE("do_mmap: pmem mmap() failed: %s (%d)\n", strerror(errno), errno); 6845 close(pmem_fd); 6846 return NULL; 6847 } 6848 ALOGI("do_mmap: pmem mmap fd %d ptr %p len %u\n", pmem_fd, ret, size); 6849 *pmemFd = pmem_fd; 6850 return(uint8_t *)ret; 6851 } 6852 6853 6854 bool QualcommCameraHardware::initRecord() 6855 { 6856 const char *pmem_region; 6857 int ion_heap = ION_CP_MM_HEAP_ID; 6858 int CbCrOffset; 6859 int recordBufferSize; 6860 int active, type =0; 6861 6862 ALOGV("initREcord E"); 6863 if(mZslEnable){ 6864 ALOGV("initRecord X.. Not intializing Record buffers in ZSL mode"); 6865 return true; 6866 } 6867 6868 if(mCurrentTarget == TARGET_MSM8660) { 6869 pmem_region = "/dev/pmem_smipool"; 6870 } else { 6871 pmem_region = "/dev/pmem_adsp"; 6872 } 6873 6874 ALOGI("initRecord: mDimension.video_width = %d mDimension.video_height = %d", 6875 mDimension.video_width, mDimension.video_height); 6876 // for 8x60 the Encoder expects the CbCr offset should be aligned to 2K. 6877 if(mCurrentTarget == TARGET_MSM8660) { 6878 CbCrOffset = PAD_TO_2K(mDimension.video_width * mDimension.video_height); 6879 recordBufferSize = CbCrOffset + PAD_TO_2K((mDimension.video_width * mDimension.video_height)/2); 6880 } else { 6881 CbCrOffset = PAD_TO_WORD(mDimension.video_width * mDimension.video_height); 6882 recordBufferSize = (mDimension.video_width * mDimension.video_height *3)/2; 6883 } 6884 6885 /* Buffersize and frameSize will be different when DIS is ON. 6886 * We need to pass the actual framesize with video heap, as the same 6887 * is used at camera MIO when negotiating with encoder. 6888 */ 6889 mRecordFrameSize = PAD_TO_4K(recordBufferSize); 6890 bool dis_disable = 0; 6891 const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 6892 if((str != NULL) && (strcmp(str, QCameraParameters::VIDEO_HFR_OFF))) { 6893 ALOGI("%s: HFR is ON, DIS has to be OFF", __FUNCTION__); 6894 dis_disable = 1; 6895 } 6896 if((mVpeEnabled && mDisEnabled && (!dis_disable))|| mIs3DModeOn){ 6897 mRecordFrameSize = videoWidth * videoHeight * 3 / 2; 6898 if(mCurrentTarget == TARGET_MSM8660){ 6899 mRecordFrameSize = PAD_TO_4K(PAD_TO_2K(videoWidth * videoHeight) 6900 + PAD_TO_2K((videoWidth * videoHeight)/2)); 6901 } 6902 } 6903 ALOGV("mRecordFrameSize = %d", mRecordFrameSize); 6904 //if(mRecordHeap == NULL) { 6905 #if 0 6906 #ifdef USE_ION 6907 mRecordHeap = new IonPool(ion_heap, 6908 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 6909 MSM_PMEM_VIDEO, 6910 recordBufferSize, 6911 kRecordBufferCount, 6912 mRecordFrameSize, 6913 CbCrOffset, 6914 0, 6915 "record"); 6916 #endif 6917 6918 mRecordHeap = new PmemPool(pmem_region, 6919 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 6920 MSM_PMEM_VIDEO, 6921 recordBufferSize, 6922 kRecordBufferCount, 6923 mRecordFrameSize, 6924 CbCrOffset, 6925 0, 6926 "record"); 6927 6928 if (!mRecordHeap->initialized()) { 6929 mRecordHeap.clear(); 6930 mRecordHeap = NULL; 6931 ALOGE("initRecord X: could not initialize record heap."); 6932 return false; 6933 } 6934 6935 } else { 6936 if(mHFRMode == true) { 6937 ALOGI("%s: register record buffers with camera driver", __FUNCTION__); 6938 register_record_buffers(true); 6939 mHFRMode = false; 6940 } 6941 } 6942 #endif 6943 6944 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) { 6945 #if 0 6946 //recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID(); 6947 recordframes[cnt].buffer = (unsigned long)mm_camera_do_mmap(mRecordFrameSize, &(recordframes[cnt].fd)); 6948 //(uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt; 6949 if(!recordframes[cnt].buffer) 6950 { 6951 ALOGE("Buffer allocation for record fram %d failed",cnt); 6952 return false; 6953 } 6954 #endif 6955 #ifdef USE_ION 6956 if (allocate_ion_memory(&record_main_ion_fd[cnt], &record_alloc[cnt], &record_ion_info_fd[cnt], 6957 ion_heap, mRecordFrameSize, &mRecordfd[cnt]) < 0){ 6958 ALOGE("do_mmap: Open device %s failed!\n",pmem_region); 6959 return NULL; 6960 } 6961 #else 6962 mRecordfd[cnt] = open(pmem_region, O_RDWR|O_SYNC); 6963 if (mRecordfd[cnt] <= 0) { 6964 ALOGE("%s: Open device %s failed!\n",__func__, pmem_region); 6965 return NULL; 6966 } 6967 #endif 6968 ALOGI("%s Record fd is %d ", __func__, mRecordfd[cnt]); 6969 mRecordMapped[cnt]=mGetMemory(mRecordfd[cnt], mRecordFrameSize,1,mCallbackCookie); 6970 if(mRecordMapped[cnt]==NULL) { 6971 ALOGE("Failed to get camera memory for mRecordMapped heap"); 6972 }else{ 6973 ALOGI("Received following info for record mapped data:%p,handle:%p, size:%d,release:%p", 6974 mRecordMapped[cnt]->data ,mRecordMapped[cnt]->handle, mRecordMapped[cnt]->size, mRecordMapped[cnt]->release); 6975 } 6976 #if 1 6977 recordframes[cnt].buffer = (unsigned int)mRecordMapped[cnt]->data; 6978 recordframes[cnt].fd = mRecordfd[cnt]; 6979 #endif 6980 recordframes[cnt].planar0_off = 0; 6981 recordframes[cnt].planar1_off = CbCrOffset; 6982 recordframes[cnt].planar2_off = 0; 6983 recordframes[cnt].path = OUTPUT_TYPE_V; 6984 record_buffers_tracking_flag[cnt] = false; 6985 ALOGV ("initRecord : record heap , video buffers buffer=%lu fd=%d y_off=%d cbcr_off=%d \n", 6986 (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].planar0_off, 6987 recordframes[cnt].planar1_off); 6988 active=(cnt<ACTIVE_VIDEO_BUFFERS); 6989 type = MSM_PMEM_VIDEO; 6990 if((mVpeEnabled) && (cnt == kRecordBufferCount-1)) { 6991 type = MSM_PMEM_VIDEO_VPE; 6992 active = 1; 6993 } 6994 ALOGI("Registering buffer %d with kernel",cnt); 6995 register_buf(mRecordFrameSize, 6996 mRecordFrameSize, CbCrOffset, 0, 6997 recordframes[cnt].fd, 6998 0, 6999 (uint8_t *)recordframes[cnt].buffer, 7000 type, 7001 active); 7002 ALOGI("Came back from register call to kernel"); 7003 } 7004 7005 // initial setup : buffers 1,2,3 with kernel , 4 with camframe , 5,6,7,8 in free Q 7006 // flush the busy Q 7007 cam_frame_flush_video(); 7008 7009 mVideoThreadWaitLock.lock(); 7010 while (mVideoThreadRunning) { 7011 ALOGV("initRecord: waiting for old video thread to complete."); 7012 mVideoThreadWait.wait(mVideoThreadWaitLock); 7013 ALOGV("initRecord : old video thread completed."); 7014 } 7015 mVideoThreadWaitLock.unlock(); 7016 7017 // flush free queue and add 5,6,7,8 buffers. 7018 LINK_camframe_release_all_frames(CAM_VIDEO_FRAME); 7019 if(mVpeEnabled) { 7020 //If VPE is enabled, the VPE buffer shouldn't be added to Free Q initally. 7021 for(int i=ACTIVE_VIDEO_BUFFERS;i <kRecordBufferCount-1; i++) 7022 LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[i]); 7023 } else { 7024 for(int i=ACTIVE_VIDEO_BUFFERS;i <kRecordBufferCount; i++) 7025 LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[i]); 7026 } 7027 ALOGV("initREcord X"); 7028 7029 return true; 7030 } 7031 7032 7033 status_t QualcommCameraHardware::setDIS() { 7034 ALOGV("setDIS E"); 7035 7036 video_dis_param_ctrl_t disCtrl; 7037 bool ret = true; 7038 ALOGV("mDisEnabled = %d", mDisEnabled); 7039 7040 int video_frame_cbcroffset; 7041 video_frame_cbcroffset = PAD_TO_WORD(videoWidth * videoHeight); 7042 if(mCurrentTarget == TARGET_MSM8660) 7043 video_frame_cbcroffset = PAD_TO_2K(videoWidth * videoHeight); 7044 7045 disCtrl.dis_enable = mDisEnabled; 7046 const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 7047 if((str != NULL) && (strcmp(str, QCameraParameters::VIDEO_HFR_OFF))) { 7048 ALOGI("%s: HFR is ON, setting DIS as OFF", __FUNCTION__); 7049 disCtrl.dis_enable = 0; 7050 } 7051 disCtrl.video_rec_width = videoWidth; 7052 disCtrl.video_rec_height = videoHeight; 7053 disCtrl.output_cbcr_offset = video_frame_cbcroffset; 7054 7055 ret = native_set_parms( CAMERA_PARM_VIDEO_DIS, 7056 sizeof(disCtrl), &disCtrl); 7057 7058 ALOGV("setDIS X (%d)", ret); 7059 return ret ? NO_ERROR : UNKNOWN_ERROR; 7060 } 7061 7062 status_t QualcommCameraHardware::setVpeParameters() 7063 { 7064 ALOGV("setVpeParameters E"); 7065 7066 video_rotation_param_ctrl_t rotCtrl; 7067 bool ret = true; 7068 ALOGV("videoWidth = %d, videoHeight = %d", videoWidth, videoHeight); 7069 int rotation = (mRotation + sensor_rotation)%360; 7070 rotCtrl.rotation = (rotation == 0) ? ROT_NONE : 7071 ((rotation == 90) ? ROT_CLOCKWISE_90 : 7072 ((rotation == 180) ? ROT_CLOCKWISE_180 : ROT_CLOCKWISE_270)); 7073 7074 if( ((videoWidth == 1280 && videoHeight == 720) || (videoWidth == 800 && videoHeight == 480)) 7075 && (rotation == 90 || rotation == 270) ){ 7076 /* Due to a limitation at video core to support heights greater than 720, adding this check. 7077 * This is a temporary hack, need to be removed once video core support is available 7078 */ 7079 ALOGI("video resolution (%dx%d) with rotation (%d) is not supported, setting rotation to NONE", 7080 videoWidth, videoHeight, rotation); 7081 rotCtrl.rotation = ROT_NONE; 7082 } 7083 ALOGV("rotCtrl.rotation = %d", rotCtrl.rotation); 7084 7085 ret = native_set_parms(CAMERA_PARM_VIDEO_ROT, 7086 sizeof(rotCtrl), &rotCtrl); 7087 7088 ALOGV("setVpeParameters X (%d)", ret); 7089 return ret ? NO_ERROR : UNKNOWN_ERROR; 7090 } 7091 7092 status_t QualcommCameraHardware::startRecording() 7093 { 7094 ALOGV("startRecording E"); 7095 int ret; 7096 Mutex::Autolock l(&mLock); 7097 mReleasedRecordingFrame = false; 7098 if( (ret=startPreviewInternal())== NO_ERROR){ 7099 if(mVpeEnabled){ 7100 ALOGI("startRecording: VPE enabled, setting vpe parameters"); 7101 bool status = setVpeParameters(); 7102 if(status) { 7103 ALOGE("Failed to set VPE parameters"); 7104 return status; 7105 } 7106 } 7107 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || 7108 (mCurrentTarget == TARGET_MSM8660)) { 7109 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) { 7110 if(mStoreMetaDataInFrame) 7111 { 7112 ALOGI("startRecording : meta data mode enabled"); 7113 metadata_memory[cnt] = mGetMemory(-1, sizeof(struct encoder_media_buffer_type), 1, mCallbackCookie); 7114 struct encoder_media_buffer_type * packet = 7115 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 7116 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size 7117 packet->buffer_type = kMetadataBufferTypeCameraSource; 7118 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 7119 nh->data[0] = mRecordfd[cnt]; 7120 nh->data[1] = 0; 7121 nh->data[2] = mRecordFrameSize; 7122 } 7123 } 7124 ALOGV(" in startREcording : calling start_recording"); 7125 native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL); 7126 mRecordingState = 1; 7127 // Remove the left out frames in busy Q and them in free Q. 7128 // this should be done before starting video_thread so that, 7129 // frames in previous recording are flushed out. 7130 ALOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames); 7131 while((g_busy_frame_queue.num_of_frames) >0){ 7132 msm_frame* vframe = cam_frame_get_video (); 7133 LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe); 7134 } 7135 ALOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames); 7136 //Clear the dangling buffers and put them in free queue 7137 for(int cnt = 0; cnt < kRecordBufferCount; cnt++) { 7138 if(record_buffers_tracking_flag[cnt] == true) { 7139 ALOGI("Dangling buffer: offset = %d, buffer = %d", cnt, 7140 (unsigned int)recordframes[cnt].buffer); 7141 LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[cnt]); 7142 record_buffers_tracking_flag[cnt] = false; 7143 } 7144 } 7145 mVideoThreadWaitLock.lock(); 7146 mVideoThreadExit = 0; 7147 pthread_attr_t attr; 7148 pthread_attr_init(&attr); 7149 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 7150 mVideoThreadRunning = pthread_create(&mVideoThread, 7151 &attr, 7152 video_thread, 7153 NULL); 7154 mVideoThreadWaitLock.unlock(); 7155 } else if ( mCurrentTarget == TARGET_MSM7627A ) { 7156 for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 7157 if(mStoreMetaDataInFrame 7158 && (metadata_memory[cnt] == NULL)) 7159 { 7160 ALOGI("startRecording : meta data mode enabled filling metadata memory "); 7161 metadata_memory[cnt] = mGetMemory(-1, sizeof(struct encoder_media_buffer_type), 1, mCallbackCookie); 7162 struct encoder_media_buffer_type * packet = 7163 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 7164 packet->meta_handle = native_handle_create(1, 3); //1 fd, 1 offset and 1 size 7165 packet->buffer_type = kMetadataBufferTypeCameraSource; 7166 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 7167 nh->data[0] = frames[cnt].fd; 7168 nh->data[1] = 0; 7169 nh->data[2] = previewWidth * previewHeight * 3/2; 7170 nh->data[3] = (unsigned int)mPreviewMapped[cnt]->data; 7171 } 7172 } 7173 } 7174 record_flag = 1; 7175 } 7176 return ret; 7177 } 7178 7179 status_t QualcommCameraHardware::startRecordingInternal() 7180 { 7181 ALOGV("%s: E", __FUNCTION__); 7182 mReleasedRecordingFrame = false; 7183 7184 /* In 3D mode, the video thread has to be started as part 7185 * of preview itself, because video buffers and video callback 7186 * need to be used for both display and encoding. 7187 * startRecordingInternal() will be called as part of startPreview(). 7188 * This check is needed to support both 3D and non-3D mode. 7189 */ 7190 if(mVideoThreadRunning) { 7191 ALOGI("Video Thread is in progress"); 7192 return NO_ERROR; 7193 } 7194 7195 if(mVpeEnabled){ 7196 ALOGI("startRecording: VPE enabled, setting vpe parameters"); 7197 bool status = setVpeParameters(); 7198 if(status) { 7199 ALOGE("Failed to set VPE parameters"); 7200 return status; 7201 } 7202 } 7203 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 7204 // Remove the left out frames in busy Q and them in free Q. 7205 // this should be done before starting video_thread so that, 7206 // frames in previous recording are flushed out. 7207 ALOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames); 7208 while((g_busy_frame_queue.num_of_frames) >0){ 7209 msm_frame* vframe = cam_frame_get_video (); 7210 LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe); 7211 } 7212 ALOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames); 7213 7214 //Clear the dangling buffers and put them in free queue 7215 for(int cnt = 0; cnt < kRecordBufferCount; cnt++) { 7216 if(record_buffers_tracking_flag[cnt] == true) { 7217 ALOGI("Dangling buffer: offset = %d, buffer = %d", cnt, (unsigned int)recordframes[cnt].buffer); 7218 LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[cnt]); 7219 record_buffers_tracking_flag[cnt] = false; 7220 } 7221 } 7222 7223 ALOGI(" in startREcording : calling start_recording"); 7224 if(!mIs3DModeOn) 7225 native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL); 7226 7227 // Start video thread and wait for busy frames to be encoded, this thread 7228 // should be closed in stopRecording 7229 mVideoThreadWaitLock.lock(); 7230 mVideoThreadExit = 0; 7231 pthread_attr_t attr; 7232 pthread_attr_init(&attr); 7233 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 7234 mVideoThreadRunning = !pthread_create(&mVideoThread, 7235 &attr, 7236 video_thread, 7237 NULL); 7238 mVideoThreadWaitLock.unlock(); 7239 // Remove the left out frames in busy Q and them in free Q. 7240 } 7241 ALOGV("%s: E", __FUNCTION__); 7242 return NO_ERROR; 7243 } 7244 7245 void QualcommCameraHardware::stopRecording() 7246 { 7247 ALOGV("stopRecording: E"); 7248 record_flag = 0; 7249 Mutex::Autolock l(&mLock); 7250 { 7251 mRecordFrameLock.lock(); 7252 mReleasedRecordingFrame = true; 7253 mRecordWait.signal(); 7254 mRecordFrameLock.unlock(); 7255 7256 if(mDataCallback && !(mCurrentTarget == TARGET_QSD8250) && 7257 (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) { 7258 ALOGV("stopRecording: X, preview still in progress"); 7259 return; 7260 } 7261 } 7262 if (NULL != mJpegLiveSnapMapped) { 7263 ALOGI("initLiveSnapshot: clearing old mJpegHeap."); 7264 mJpegLiveSnapMapped->release(mJpegLiveSnapMapped); 7265 mJpegLiveSnapMapped = NULL; 7266 } 7267 7268 // If output2 enabled, exit video thread, invoke stop recording ioctl 7269 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 7270 /* when 3D mode is ON, don't exit the video thread, as 7271 * we need to support the preview mode. Just set the recordingState 7272 * to zero, so that there won't be any rcb callbacks. video thread 7273 * will be terminated as part of stop preview. 7274 */ 7275 if(mIs3DModeOn) { 7276 ALOGV("%s: 3D mode on, so don't exit video thread", __FUNCTION__); 7277 mRecordingState = 0; 7278 return; 7279 } 7280 7281 mVideoThreadWaitLock.lock(); 7282 mVideoThreadExit = 1; 7283 mVideoThreadWaitLock.unlock(); 7284 native_stop_ops(CAMERA_OPS_VIDEO_RECORDING, NULL); 7285 7286 pthread_mutex_lock(&(g_busy_frame_queue.mut)); 7287 pthread_cond_signal(&(g_busy_frame_queue.wait)); 7288 pthread_mutex_unlock(&(g_busy_frame_queue.mut)); 7289 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) { 7290 if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){ 7291 struct encoder_media_buffer_type * packet = 7292 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 7293 native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle)); 7294 metadata_memory[cnt]->release(metadata_memory[cnt]); 7295 metadata_memory[cnt] = NULL; 7296 } 7297 } 7298 } 7299 else if(mCurrentTarget == TARGET_MSM7627A) { 7300 for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) { 7301 if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){ 7302 struct encoder_media_buffer_type * packet = 7303 (struct encoder_media_buffer_type *)metadata_memory[cnt]->data; 7304 native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle)); 7305 metadata_memory[cnt]->release(metadata_memory[cnt]); 7306 metadata_memory[cnt] = NULL; 7307 } 7308 } 7309 } 7310 #if 0 7311 else // for other targets where output2 is not enabled 7312 stopPreviewInternal(); 7313 if (mJpegHeap != NULL) { 7314 ALOGV("stopRecording: clearing old mJpegHeap."); 7315 mJpegHeap.clear(); 7316 } 7317 #endif 7318 mRecordingState = 0; // recording not started 7319 ALOGV("stopRecording: X"); 7320 } 7321 7322 void QualcommCameraHardware::releaseRecordingFrame(const void *opaque) 7323 { 7324 ALOGI("%s : BEGIN, opaque = 0x%p",__func__, opaque); 7325 Mutex::Autolock rLock(&mRecordFrameLock); 7326 mReleasedRecordingFrame = true; 7327 mRecordWait.signal(); 7328 7329 // Ff 7x30 : add the frame to the free camframe queue 7330 if( (mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) { 7331 ssize_t offset; 7332 size_t size; 7333 //sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 7334 msm_frame* releaseframe = NULL; 7335 int cnt; 7336 for (cnt = 0; cnt < kRecordBufferCount; cnt++) { 7337 if(mStoreMetaDataInFrame){ 7338 if(metadata_memory[cnt] && metadata_memory[cnt]->data == opaque){ 7339 ALOGV("in release recording frame(meta) found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer); 7340 releaseframe = &recordframes[cnt]; 7341 break; 7342 } 7343 }else { 7344 if(recordframes[cnt].buffer && ((unsigned long)opaque == recordframes[cnt].buffer) ){ 7345 ALOGV("in release recording frame found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer); 7346 releaseframe = &recordframes[cnt]; 7347 break; 7348 } 7349 } 7350 } 7351 if(cnt < kRecordBufferCount) { 7352 // do this only if frame thread is running 7353 mFrameThreadWaitLock.lock(); 7354 if(mFrameThreadRunning ) { 7355 //Reset the track flag for this frame buffer 7356 record_buffers_tracking_flag[cnt] = false; 7357 LINK_camframe_add_frame(CAM_VIDEO_FRAME,releaseframe); 7358 } 7359 7360 mFrameThreadWaitLock.unlock(); 7361 } else { 7362 ALOGE("in release recordingframe XXXXX error , buffer not found"); 7363 for (int i=0; i< kRecordBufferCount; i++) { 7364 ALOGE(" recordframes[%d].buffer = %d", i, (unsigned int)recordframes[i].buffer); 7365 } 7366 } 7367 } 7368 7369 ALOGV("releaseRecordingFrame X"); 7370 } 7371 7372 bool QualcommCameraHardware::recordingEnabled() 7373 { 7374 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME); 7375 } 7376 7377 void QualcommCameraHardware::notifyShutter(bool mPlayShutterSoundOnly) 7378 { 7379 private_handle_t *thumbnailHandle; 7380 if(mThumbnailBuffer) { 7381 thumbnailHandle = (private_handle_t *) (*mThumbnailBuffer); 7382 } 7383 mShutterLock.lock(); 7384 //image_rect_type size; 7385 7386 if(mPlayShutterSoundOnly) { 7387 /* At this point, invoke Notify Callback to play shutter sound only. 7388 * We want to call notify callback again when we have the 7389 * yuv picture ready. This is to reduce blanking at the time 7390 * of displaying postview frame. Using ext2 to indicate whether 7391 * to play shutter sound only or register the postview buffers. 7392 */ 7393 mNotifyCallback(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly, 7394 mCallbackCookie); 7395 mShutterLock.unlock(); 7396 return; 7397 } 7398 7399 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) { 7400 //mDisplayHeap = mThumbnailHeap; 7401 #if 0 7402 if (crop != NULL && (crop->in1_w != 0 && crop->in1_h != 0)) { 7403 size.width = crop->in1_w; 7404 size.height = crop->in1_h; 7405 } 7406 else { 7407 size.width = mPostviewWidth; 7408 size.height = mPostviewHeight; 7409 } 7410 #endif 7411 /* 7412 if(strTexturesOn == true) { 7413 mDisplayHeap = mRawHeap; 7414 size.width = mPictureWidth; 7415 size.height = mPictureHeight; 7416 } 7417 */ 7418 /* Now, invoke Notify Callback to unregister preview buffer 7419 * and register postview buffer with surface flinger. Set ext2 7420 * as 0 to indicate not to play shutter sound. 7421 */ 7422 mNotifyCallback(CAMERA_MSG_SHUTTER, 0, 0, 7423 mCallbackCookie); 7424 mShutterPending = false; 7425 } 7426 mShutterLock.unlock(); 7427 } 7428 7429 static void receive_shutter_callback(common_crop_t *crop) 7430 { 7431 ALOGV("receive_shutter_callback: E"); 7432 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 7433 if (obj != 0) { 7434 /* Just play shutter sound at this time */ 7435 obj->notifyShutter(TRUE); 7436 } 7437 ALOGV("receive_shutter_callback: X"); 7438 } 7439 7440 // Crop the picture in place. 7441 static void crop_yuv420(uint32_t width, uint32_t height, 7442 uint32_t cropped_width, uint32_t cropped_height, 7443 uint8_t *image, const char *name) 7444 { 7445 uint32_t i; 7446 uint32_t x, y; 7447 uint8_t* chroma_src, *chroma_dst; 7448 int yOffsetSrc, yOffsetDst, CbCrOffsetSrc, CbCrOffsetDst; 7449 int mSrcSize, mDstSize; 7450 7451 //check if all fields needed eg. size and also how to set y offset. If condition for 7x27 7452 //and need to check if needed for 7x30. 7453 7454 LINK_jpeg_encoder_get_buffer_offset(width, height, (uint32_t *)&yOffsetSrc, 7455 (uint32_t *)&CbCrOffsetSrc, (uint32_t *)&mSrcSize); 7456 7457 LINK_jpeg_encoder_get_buffer_offset(cropped_width, cropped_height, (uint32_t *)&yOffsetDst, 7458 (uint32_t *)&CbCrOffsetDst, (uint32_t *)&mDstSize); 7459 7460 // Calculate the start position of the cropped area. 7461 x = (width - cropped_width) / 2; 7462 y = (height - cropped_height) / 2; 7463 x &= ~1; 7464 y &= ~1; 7465 7466 if((mCurrentTarget == TARGET_MSM7627) 7467 || (mCurrentTarget == TARGET_MSM7625A) 7468 || (mCurrentTarget == TARGET_MSM7627A) 7469 || (mCurrentTarget == TARGET_MSM7630) 7470 || (mCurrentTarget == TARGET_MSM8660)) { 7471 if (!strcmp("snapshot camera", name)) { 7472 chroma_src = image + CbCrOffsetSrc; 7473 chroma_dst = image + CbCrOffsetDst; 7474 } else { 7475 chroma_src = image + width * height; 7476 chroma_dst = image + cropped_width * cropped_height; 7477 yOffsetSrc = 0; 7478 yOffsetDst = 0; 7479 CbCrOffsetSrc = width * height; 7480 CbCrOffsetDst = cropped_width * cropped_height; 7481 } 7482 } else { 7483 chroma_src = image + CbCrOffsetSrc; 7484 chroma_dst = image + CbCrOffsetDst; 7485 } 7486 7487 int32_t bufDst = yOffsetDst; 7488 int32_t bufSrc = yOffsetSrc + (width * y) + x; 7489 7490 if( bufDst > bufSrc ){ 7491 ALOGV("crop yuv Y destination position follows source position"); 7492 /* 7493 * If buffer destination follows buffer source, memcpy 7494 * of lines will lead to overwriting subsequent lines. In order 7495 * to prevent this, reverse copying of lines is performed 7496 * for the set of lines where destination follows source and 7497 * forward copying of lines is performed for lines where source 7498 * follows destination. To calculate the position to switch, 7499 * the initial difference between source and destination is taken 7500 * and divided by difference between width and cropped width. For 7501 * every line copied the difference between source destination 7502 * drops by width - cropped width 7503 */ 7504 //calculating inversion 7505 int position = ( bufDst - bufSrc ) / (width - cropped_width); 7506 // Copy luma component. 7507 for(i=position+1; i < cropped_height; i++){ 7508 memmove(image + yOffsetDst + i * cropped_width, 7509 image + yOffsetSrc + width * (y + i) + x, 7510 cropped_width); 7511 } 7512 for(int j=position; j>=0; j--){ 7513 memmove(image + yOffsetDst + j * cropped_width, 7514 image + yOffsetSrc + width * (y + j) + x, 7515 cropped_width); 7516 } 7517 } else { 7518 // Copy luma component. 7519 for(i = 0; i < cropped_height; i++) 7520 memcpy(image + yOffsetDst + i * cropped_width, 7521 image + yOffsetSrc + width * (y + i) + x, 7522 cropped_width); 7523 } 7524 7525 // Copy chroma components. 7526 cropped_height /= 2; 7527 y /= 2; 7528 7529 bufDst = CbCrOffsetDst; 7530 bufSrc = CbCrOffsetSrc + (width * y) + x; 7531 7532 if( bufDst > bufSrc ) { 7533 ALOGV("crop yuv Chroma destination position follows source position"); 7534 /* 7535 * Similar to y 7536 */ 7537 int position = ( bufDst - bufSrc ) / (width - cropped_width); 7538 for(i=position+1; i < cropped_height; i++){ 7539 memmove(chroma_dst + i * cropped_width, 7540 chroma_src + width * (y + i) + x, 7541 cropped_width); 7542 } 7543 for(int j=position; j >=0; j--){ 7544 memmove(chroma_dst + j * cropped_width, 7545 chroma_src + width * (y + j) + x, 7546 cropped_width); 7547 } 7548 } else { 7549 for(i = 0; i < cropped_height; i++) 7550 memcpy(chroma_dst + i * cropped_width, 7551 chroma_src + width * (y + i) + x, 7552 cropped_width); 7553 } 7554 } 7555 // ReceiveRawPicture for ICS 7556 void QualcommCameraHardware::receiveRawPicture(status_t status,struct msm_frame *postviewframe, struct msm_frame *mainframe) 7557 { 7558 ALOGV("%s: E", __FUNCTION__); 7559 7560 void* cropp; 7561 mSnapshotThreadWaitLock.lock(); 7562 if(mSnapshotThreadRunning == false) { 7563 ALOGE("%s called in wrong state, ignore", __FUNCTION__); 7564 return; 7565 } 7566 mSnapshotThreadWaitLock.unlock(); 7567 7568 if(status != NO_ERROR){ 7569 ALOGE("%s: Failed to get Snapshot Image", __FUNCTION__); 7570 if(mDataCallback && 7571 (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) { 7572 /* get picture failed. Give jpeg callback with NULL data 7573 * to the application to restore to preview mode 7574 */ 7575 ALOGE("get picture failed, giving jpeg callback with NULL data"); 7576 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, NULL, data_counter, NULL, mCallbackCookie); 7577 } 7578 mShutterLock.lock(); 7579 mShutterPending = false; 7580 mShutterLock.unlock(); 7581 mJpegThreadWaitLock.lock(); 7582 mJpegThreadRunning = false; 7583 mJpegThreadWait.signal(); 7584 mJpegThreadWaitLock.unlock(); 7585 mInSnapshotModeWaitLock.lock(); 7586 mInSnapshotMode = false; 7587 mInSnapshotModeWait.signal(); 7588 mInSnapshotModeWaitLock.unlock(); 7589 return; 7590 } 7591 /* call notifyShutter to config surface and overlay 7592 * for postview rendering. 7593 * Its necessary to issue another notifyShutter here with 7594 * mPlayShutterSoundOnly as FALSE, since that is when the 7595 * preview buffers are unregistered with the surface flinger. 7596 * That is necessary otherwise the preview memory wont be 7597 * deallocated. 7598 */ 7599 cropp =postviewframe->cropinfo; 7600 notifyShutter(FALSE); 7601 7602 if(mSnapshotFormat == PICTURE_FORMAT_JPEG) { 7603 if(cropp != NULL){ 7604 common_crop_t *crop = (common_crop_t *)cropp; 7605 if (crop->in1_w != 0 && crop->in1_h != 0) { 7606 zoomCropInfo.left = (crop->out1_w - crop->in1_w + 1) / 2 - 1; 7607 zoomCropInfo.top = (crop->out1_h - crop->in1_h + 1) / 2 - 1; 7608 if(zoomCropInfo.left < 0) zoomCropInfo.left = 0; 7609 if(zoomCropInfo.top < 0) zoomCropInfo.top = 0; 7610 zoomCropInfo.right = zoomCropInfo.left + crop->in1_w; 7611 zoomCropInfo.bottom = zoomCropInfo.top + crop->in1_h; 7612 mPreviewWindow->set_crop(mPreviewWindow, 7613 zoomCropInfo.left, 7614 zoomCropInfo.top, 7615 zoomCropInfo.right, 7616 zoomCropInfo.bottom); 7617 mResetWindowCrop = true; 7618 } else { 7619 zoomCropInfo.left = 0; 7620 zoomCropInfo.top = 0; 7621 zoomCropInfo.right = mPostviewWidth; 7622 zoomCropInfo.bottom = mPostviewHeight; 7623 mPreviewWindow->set_crop(mPreviewWindow, 7624 zoomCropInfo.left, 7625 zoomCropInfo.top, 7626 zoomCropInfo.right, 7627 zoomCropInfo.bottom); 7628 } 7629 } 7630 ALOGI("receiverawpicture : display lock"); 7631 mDisplayLock.lock(); 7632 int index = mapThumbnailBuffer(postviewframe); 7633 ALOGI("receiveRawPicture : mapThumbnailBuffer returned %d", index); 7634 private_handle_t *handle; 7635 if(mThumbnailBuffer[index] != NULL && mZslEnable == false) { 7636 handle = (private_handle_t *)(*mThumbnailBuffer[index]); 7637 ALOGV("%s: Queueing postview buffer for display %d", 7638 __FUNCTION__,handle->fd); 7639 if (BUFFER_LOCKED == mThumbnailLockState[index]) { 7640 if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) { 7641 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 7642 mDisplayLock.unlock(); 7643 return; 7644 } else { 7645 mThumbnailLockState[index] = BUFFER_UNLOCKED; 7646 } 7647 } 7648 status_t retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow, 7649 mThumbnailBuffer[index]); 7650 ALOGI(" enQ thumbnailbuffer"); 7651 if( retVal != NO_ERROR) { 7652 ALOGE("%s: Queuebuffer failed for postview buffer", __FUNCTION__); 7653 } 7654 7655 } 7656 mDisplayLock.unlock(); 7657 ALOGI("receiverawpicture : display unlock"); 7658 /* Give the main Image as raw to upper layers */ 7659 //Either CAMERA_MSG_RAW_IMAGE or CAMERA_MSG_RAW_IMAGE_NOTIFY will be set not both 7660 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)) 7661 mDataCallback(CAMERA_MSG_RAW_IMAGE, mRawMapped[index],data_counter, 7662 NULL, mCallbackCookie); 7663 else if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY)) 7664 mNotifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, 7665 mCallbackCookie); 7666 7667 if(strTexturesOn == true) { 7668 ALOGI("Raw Data given to app for processing...will wait for jpeg encode call"); 7669 mEncodePending = true; 7670 mEncodePendingWaitLock.unlock(); 7671 mJpegThreadWaitLock.lock(); 7672 mJpegThreadWait.signal(); 7673 mJpegThreadWaitLock.unlock(); 7674 } 7675 } else { // Not Jpeg snapshot, it is Raw Snapshot , handle later 7676 ALOGV("ReceiveRawPicture : raw snapshot not Jpeg, sending callback up"); 7677 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) 7678 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, 7679 mRawSnapshotMapped, 7680 data_counter, 7681 NULL, 7682 mCallbackCookie); 7683 7684 // TEMP 7685 ALOGI("receiveRawPicture : gave raw frame to app, giving signal"); 7686 mJpegThreadWaitLock.lock(); 7687 mJpegThreadRunning = false; 7688 mJpegThreadWait.signal(); 7689 mJpegThreadWaitLock.unlock(); 7690 7691 } 7692 /* can start preview at this stage? early preview? */ 7693 mInSnapshotModeWaitLock.lock(); 7694 mInSnapshotMode = false; 7695 mInSnapshotModeWait.signal(); 7696 mInSnapshotModeWaitLock.unlock(); 7697 7698 ALOGV("%s: X", __FUNCTION__); 7699 7700 } 7701 7702 7703 void QualcommCameraHardware::receiveJpegPicture(status_t status, mm_camera_buffer_t *encoded_buffer) 7704 { 7705 Mutex::Autolock cbLock(&mCallbackLock); 7706 numJpegReceived++; 7707 uint32_t offset ; 7708 int32_t index = -1; 7709 int32_t buffer_size = 0; 7710 if(encoded_buffer && status == NO_ERROR) { 7711 buffer_size = encoded_buffer->filled_size; 7712 ALOGV("receiveJpegPicture: E buffer_size %d mJpegMaxSize = %d",buffer_size, mJpegMaxSize); 7713 7714 index = mapJpegBuffer(encoded_buffer); 7715 ALOGI("receiveJpegPicutre : mapJpegBuffer index : %d", index); 7716 } 7717 if((index < 0) || (index >= (MAX_SNAPSHOT_BUFFERS-2))){ 7718 ALOGE("Jpeg index is not valid or fails. "); 7719 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) { 7720 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, NULL, data_counter, NULL, mCallbackCookie); 7721 } 7722 mJpegThreadWaitLock.lock(); 7723 mJpegThreadRunning = false; 7724 mJpegThreadWait.signal(); 7725 mJpegThreadWaitLock.unlock(); 7726 } else { 7727 ALOGV("receiveJpegPicture: Index of Jpeg is %d",index); 7728 7729 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) { 7730 if(status == NO_ERROR) { 7731 ALOGI("receiveJpegPicture : giving jpeg image callback to services"); 7732 mJpegCopyMapped = mGetMemory(-1, encoded_buffer->filled_size,1, mCallbackCookie); 7733 if(!mJpegCopyMapped){ 7734 ALOGE("%s: mGetMemory failed.\n", __func__); 7735 } 7736 memcpy(mJpegCopyMapped->data, mJpegMapped[index]->data, encoded_buffer->filled_size ); 7737 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE,mJpegCopyMapped,data_counter,NULL,mCallbackCookie); 7738 if(NULL != mJpegCopyMapped) { 7739 mJpegCopyMapped->release(mJpegCopyMapped); 7740 mJpegCopyMapped = NULL; 7741 } 7742 } 7743 } else { 7744 ALOGI("JPEG callback was cancelled--not delivering image."); 7745 } 7746 if(numJpegReceived == numCapture){ 7747 mJpegThreadWaitLock.lock(); 7748 mJpegThreadRunning = false; 7749 mJpegThreadWait.signal(); 7750 mJpegThreadWaitLock.unlock(); 7751 } 7752 } 7753 7754 ALOGV("receiveJpegPicture: X callback done."); 7755 } 7756 bool QualcommCameraHardware::previewEnabled() 7757 { 7758 /* If overlay is used the message CAMERA_MSG_PREVIEW_FRAME would 7759 * be disabled at CameraService layer. Hence previewEnabled would 7760 * return FALSE even though preview is running. Hence check for 7761 * mOverlay not being NULL to ensure that previewEnabled returns 7762 * accurate information. 7763 */ 7764 7765 // return mCameraRunning && mDataCallback && 7766 // ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) || (mOverlay != NULL)); 7767 ALOGI(" : mCameraRunning : %d mPreviewWindow = %x",mCameraRunning,mPreviewWindow); 7768 return mCameraRunning;// || (mPreviewWindow != NULL); 7769 } 7770 status_t QualcommCameraHardware::setRecordSize(const QCameraParameters& params) 7771 { 7772 const char *recordSize = NULL; 7773 recordSize = params.get(QCameraParameters::KEY_VIDEO_SIZE); 7774 if(!recordSize) { 7775 mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, ""); 7776 //If application didn't set this parameter string, use the values from 7777 //getPreviewSize() as video dimensions. 7778 ALOGV("No Record Size requested, use the preview dimensions"); 7779 videoWidth = previewWidth; 7780 videoHeight = previewHeight; 7781 } else { 7782 //Extract the record witdh and height that application requested. 7783 ALOGI("%s: requested record size %s", __FUNCTION__, recordSize); 7784 if(!parse_size(recordSize, videoWidth, videoHeight)) { 7785 mParameters.set(QCameraParameters::KEY_VIDEO_SIZE , recordSize); 7786 //VFE output1 shouldn't be greater than VFE output2. 7787 if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) { 7788 //Set preview sizes as record sizes. 7789 ALOGI("Preview size %dx%d is greater than record size %dx%d,\ 7790 resetting preview size to record size",previewWidth,\ 7791 previewHeight, videoWidth, videoHeight); 7792 previewWidth = videoWidth; 7793 previewHeight = videoHeight; 7794 mParameters.setPreviewSize(previewWidth, previewHeight); 7795 } 7796 if( (mCurrentTarget != TARGET_MSM7630) 7797 && (mCurrentTarget != TARGET_QSD8250) 7798 && (mCurrentTarget != TARGET_MSM8660) ) { 7799 //For Single VFE output targets, use record dimensions as preview dimensions. 7800 previewWidth = videoWidth; 7801 previewHeight = videoHeight; 7802 mParameters.setPreviewSize(previewWidth, previewHeight); 7803 } 7804 if(mIs3DModeOn == true) { 7805 /* As preview and video frames are same in 3D mode, 7806 * preview size should be same as video size. This 7807 * cahnge is needed to take of video resolutions 7808 * like 720P and 1080p where the application can 7809 * request different preview sizes like 768x432 7810 */ 7811 previewWidth = videoWidth; 7812 previewHeight = videoHeight; 7813 mParameters.setPreviewSize(previewWidth, previewHeight); 7814 } 7815 } else { 7816 mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, ""); 7817 ALOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize); 7818 return BAD_VALUE; 7819 } 7820 } 7821 ALOGI("%s: preview dimensions: %dx%d", __FUNCTION__, previewWidth, previewHeight); 7822 ALOGI("%s: video dimensions: %dx%d", __FUNCTION__, videoWidth, videoHeight); 7823 mDimension.display_width = previewWidth; 7824 mDimension.display_height= previewHeight; 7825 return NO_ERROR; 7826 } 7827 7828 status_t QualcommCameraHardware::setCameraMode(const QCameraParameters& params) { 7829 int32_t value = params.getInt(QCameraParameters::KEY_CAMERA_MODE); 7830 mParameters.set(QCameraParameters::KEY_CAMERA_MODE,value); 7831 7832 ALOGI("ZSL is enabled %d", value); 7833 if( value != mZslEnable) { 7834 mFrameThreadWaitLock.lock(); 7835 while (mFrameThreadRunning) { 7836 ALOGI("initPreview: waiting for old frame thread to complete."); 7837 mFrameThreadWait.wait(mFrameThreadWaitLock); 7838 ALOGI("initPreview: old frame thread completed."); 7839 } 7840 mFrameThreadWaitLock.unlock(); 7841 } 7842 if(value == 1) { 7843 mZslEnable = true; 7844 /* mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES, 7845 QCameraParameters::FOCUS_MODE_INFINITY); 7846 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, 7847 QCameraParameters::FOCUS_MODE_INFINITY);*/ 7848 }else{ 7849 mZslEnable = false; 7850 /*mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES, 7851 focus_mode_values); 7852 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, 7853 QCameraParameters::FOCUS_MODE_AUTO);*/ 7854 } 7855 return NO_ERROR; 7856 } 7857 7858 status_t QualcommCameraHardware::setPreviewSize(const QCameraParameters& params) 7859 { 7860 int width, height; 7861 params.getPreviewSize(&width, &height); 7862 ALOGV("requested preview size %d x %d", width, height); 7863 7864 // Validate the preview size 7865 for (size_t i = 0; i < PREVIEW_SIZE_COUNT; ++i) { 7866 if (width == preview_sizes[i].width 7867 && height == preview_sizes[i].height) { 7868 mParameters.setPreviewSize(width, height); 7869 //previewWidth = width; 7870 //previewHeight = height; 7871 mDimension.display_width = width; 7872 mDimension.display_height= height; 7873 return NO_ERROR; 7874 } 7875 } 7876 ALOGE("Invalid preview size requested: %dx%d", width, height); 7877 return BAD_VALUE; 7878 } 7879 status_t QualcommCameraHardware::setPreviewFpsRange(const QCameraParameters& params) 7880 { 7881 int minFps,maxFps; 7882 params.getPreviewFpsRange(&minFps,&maxFps); 7883 ALOGI("FPS Range Values: %dx%d", minFps, maxFps); 7884 7885 for(size_t i=0;i<FPS_RANGES_SUPPORTED_COUNT;i++) 7886 { 7887 if(minFps==FpsRangesSupported[i].minFPS && maxFps == FpsRangesSupported[i].maxFPS){ 7888 mParameters.setPreviewFpsRange(minFps,maxFps); 7889 return NO_ERROR; 7890 } 7891 } 7892 return BAD_VALUE; 7893 } 7894 7895 status_t QualcommCameraHardware::setPreviewFrameRate(const QCameraParameters& params) 7896 { 7897 if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){ 7898 ALOGI("Set fps is not supported for this sensor"); 7899 return NO_ERROR; 7900 } 7901 uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate(); 7902 uint16_t fps = (uint16_t)params.getPreviewFrameRate(); 7903 ALOGV("requested preview frame rate is %u", fps); 7904 7905 if(mInitialized && (fps == previousFps)){ 7906 ALOGV("fps same as previous fps"); 7907 return NO_ERROR; 7908 } 7909 7910 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){ 7911 mParameters.setPreviewFrameRate(fps); 7912 bool ret = native_set_parms(CAMERA_PARM_FPS, 7913 sizeof(fps), (void *)&fps); 7914 return ret ? NO_ERROR : UNKNOWN_ERROR; 7915 } 7916 return BAD_VALUE; 7917 } 7918 7919 status_t QualcommCameraHardware::setPreviewFrameRateMode(const QCameraParameters& params) { 7920 if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE) && !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){ 7921 ALOGI("set fps mode is not supported for this sensor"); 7922 return NO_ERROR; 7923 } 7924 7925 const char *previousMode = mParameters.getPreviewFrameRateMode(); 7926 const char *str = params.getPreviewFrameRateMode(); 7927 if( mInitialized && !strcmp(previousMode, str)) { 7928 ALOGV("frame rate mode same as previous mode %s", previousMode); 7929 return NO_ERROR; 7930 } 7931 int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str); 7932 if(frameRateMode != NOT_FOUND) { 7933 ALOGV("setPreviewFrameRateMode: %s ", str); 7934 mParameters.setPreviewFrameRateMode(str); 7935 bool ret = native_set_parms(CAMERA_PARM_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode); 7936 if(!ret) return ret; 7937 //set the fps value when chaging modes 7938 int16_t fps = (uint16_t)params.getPreviewFrameRate(); 7939 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){ 7940 mParameters.setPreviewFrameRate(fps); 7941 ret = native_set_parms(CAMERA_PARM_FPS, 7942 sizeof(fps), (void *)&fps); 7943 return ret ? NO_ERROR : UNKNOWN_ERROR; 7944 } 7945 ALOGE("Invalid preview frame rate value: %d", fps); 7946 return BAD_VALUE; 7947 } 7948 ALOGE("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str); 7949 return BAD_VALUE; 7950 } 7951 7952 status_t QualcommCameraHardware::setJpegThumbnailSize(const QCameraParameters& params){ 7953 int width = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); 7954 int height = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); 7955 ALOGV("requested jpeg thumbnail size %d x %d", width, height); 7956 7957 // Validate the picture size 7958 for (unsigned int i = 0; i < JPEG_THUMBNAIL_SIZE_COUNT; ++i) { 7959 if (width == jpeg_thumbnail_sizes[i].width 7960 && height == jpeg_thumbnail_sizes[i].height) { 7961 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width); 7962 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height); 7963 return NO_ERROR; 7964 } 7965 } 7966 return BAD_VALUE; 7967 } 7968 7969 bool QualcommCameraHardware::updatePictureDimension(const QCameraParameters& params, int& width, int& height) 7970 { 7971 bool retval = false; 7972 int previewWidth, previewHeight; 7973 params.getPreviewSize(&previewWidth, &previewHeight); 7974 ALOGV("updatePictureDimension: %dx%d <- %dx%d", width, height, 7975 previewWidth, previewHeight); 7976 if ((width < previewWidth) && (height < previewHeight)) { 7977 /*As we donot support jpeg downscaling for picture dimension < previewdimesnion/8 , 7978 Adding support for the same for cts testcases*/ 7979 mActualPictWidth = width; 7980 mActualPictHeight = height; 7981 if((previewWidth /8) > width ) { 7982 int ratio = previewWidth/width; 7983 int i; 7984 for(i =0 ; i < ratio ; i++) { 7985 if((ratio >> i) < 8) 7986 break; 7987 } 7988 width = width *i*2; 7989 height = height *i*2; 7990 } 7991 else { 7992 width = previewWidth; 7993 height = previewHeight; 7994 } 7995 mUseJpegDownScaling = true; 7996 retval = true; 7997 } else 7998 mUseJpegDownScaling = false; 7999 return retval; 8000 } 8001 8002 status_t QualcommCameraHardware::setPictureSize(const QCameraParameters& params) 8003 { 8004 int width, height; 8005 params.getPictureSize(&width, &height); 8006 ALOGV("requested picture size %d x %d", width, height); 8007 8008 // Validate the picture size 8009 for (int i = 0; i < supportedPictureSizesCount; ++i) { 8010 if (width == picture_sizes_ptr[i].width 8011 && height == picture_sizes_ptr[i].height) { 8012 mParameters.setPictureSize(width, height); 8013 mDimension.picture_width = width; 8014 mDimension.picture_height = height; 8015 return NO_ERROR; 8016 } 8017 } 8018 /* Dimension not among the ones in the list. Check if 8019 * its a valid dimension, if it is, then configure the 8020 * camera accordingly. else reject it. 8021 */ 8022 if( isValidDimension(width, height) ) { 8023 mParameters.setPictureSize(width, height); 8024 mDimension.picture_width = width; 8025 mDimension.picture_height = height; 8026 return NO_ERROR; 8027 } else 8028 ALOGE("Invalid picture size requested: %dx%d", width, height); 8029 return BAD_VALUE; 8030 } 8031 8032 status_t QualcommCameraHardware::setJpegQuality(const QCameraParameters& params) { 8033 status_t rc = NO_ERROR; 8034 int quality = params.getInt(QCameraParameters::KEY_JPEG_QUALITY); 8035 if (quality >= 0 && quality <= 100) { 8036 mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, quality); 8037 } else { 8038 ALOGE("Invalid jpeg quality=%d", quality); 8039 rc = BAD_VALUE; 8040 } 8041 8042 quality = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 8043 if (quality >= 0 && quality <= 100) { 8044 mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality); 8045 } else { 8046 ALOGE("Invalid jpeg thumbnail quality=%d", quality); 8047 rc = BAD_VALUE; 8048 } 8049 return rc; 8050 } 8051 8052 status_t QualcommCameraHardware::setEffect(const QCameraParameters& params) 8053 { 8054 const char *str = params.get(QCameraParameters::KEY_EFFECT); 8055 int result; 8056 8057 if (str != NULL) { 8058 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str); 8059 if (value != NOT_FOUND) { 8060 if( !mCfgControl.mm_camera_is_parm_supported(CAMERA_PARM_EFFECT, (void *) &value)){ 8061 ALOGI("Camera Effect - %s mode is not supported for this sensor",str); 8062 return NO_ERROR; 8063 }else { 8064 mParameters.set(QCameraParameters::KEY_EFFECT, str); 8065 bool ret = native_set_parms(CAMERA_PARM_EFFECT, sizeof(value), 8066 (void *)&value,(int *)&result); 8067 if(result == MM_CAMERA_ERR_INVALID_OPERATION) { 8068 ALOGI("Camera Effect: %s is not set as the selected value is not supported ", str); 8069 } 8070 return ret ? NO_ERROR : UNKNOWN_ERROR; 8071 } 8072 } 8073 } 8074 ALOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str); 8075 return BAD_VALUE; 8076 } 8077 8078 status_t QualcommCameraHardware::setRecordingHint(const QCameraParameters& params) 8079 { 8080 8081 const char * str = params.get(QCameraParameters::KEY_RECORDING_HINT); 8082 8083 if(str != NULL){ 8084 int32_t value = attr_lookup(recording_Hints, 8085 sizeof(recording_Hints) / sizeof(str_map), str); 8086 if(value != NOT_FOUND){ 8087 8088 native_set_parms(CAMERA_PARM_RECORDING_HINT, sizeof(value), 8089 (void *)&value); 8090 /*native_set_parms(CAMERA_PARM_CAF_ENABLE, sizeof(value), 8091 (void *)&value);*/ 8092 mParameters.set(QCameraParameters::KEY_RECORDING_HINT, str); 8093 } else { 8094 ALOGE("Invalid Picture Format value: %s", str); 8095 return BAD_VALUE; 8096 } 8097 } 8098 return NO_ERROR; 8099 } 8100 8101 status_t QualcommCameraHardware::setExposureCompensation( 8102 const QCameraParameters & params){ 8103 ALOGV("DEBBUG: %s E",__FUNCTION__); 8104 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE_COMPENSATION)) { 8105 ALOGI("Exposure Compensation is not supported for this sensor"); 8106 return NO_ERROR; 8107 } 8108 8109 int numerator = params.getInt(QCameraParameters::KEY_EXPOSURE_COMPENSATION); 8110 if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator && 8111 numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){ 8112 int16_t numerator16 = (int16_t)(numerator & 0x0000ffff); 8113 uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR; 8114 uint32_t value = 0; 8115 value = numerator16 << 16 | denominator16; 8116 8117 mParameters.set(QCameraParameters::KEY_EXPOSURE_COMPENSATION, 8118 numerator); 8119 bool ret = native_set_parms(CAMERA_PARM_EXPOSURE_COMPENSATION, 8120 sizeof(value), (void *)&value); 8121 ALOGI("DEBBUG: %s ret = %d X",__FUNCTION__, ret); 8122 return ret ? NO_ERROR : UNKNOWN_ERROR; 8123 } 8124 ALOGE("Invalid Exposure Compensation"); 8125 return BAD_VALUE; 8126 } 8127 8128 status_t QualcommCameraHardware::setAutoExposure(const QCameraParameters& params) 8129 { 8130 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE)) { 8131 ALOGI("Auto Exposure not supported for this sensor"); 8132 return NO_ERROR; 8133 } 8134 const char *str = params.get(QCameraParameters::KEY_AUTO_EXPOSURE); 8135 if (str != NULL) { 8136 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str); 8137 if (value != NOT_FOUND) { 8138 mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE, str); 8139 bool ret = native_set_parms(CAMERA_PARM_EXPOSURE, sizeof(value), 8140 (void *)&value); 8141 return ret ? NO_ERROR : UNKNOWN_ERROR; 8142 } 8143 } 8144 ALOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str); 8145 return BAD_VALUE; 8146 } 8147 8148 status_t QualcommCameraHardware::setSharpness(const QCameraParameters& params) 8149 { 8150 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SHARPNESS)) { 8151 ALOGI("Sharpness not supported for this sensor"); 8152 return NO_ERROR; 8153 } 8154 int sharpness = params.getInt(QCameraParameters::KEY_SHARPNESS); 8155 if((sharpness < CAMERA_MIN_SHARPNESS 8156 || sharpness > CAMERA_MAX_SHARPNESS)) 8157 return UNKNOWN_ERROR; 8158 8159 ALOGV("setting sharpness %d", sharpness); 8160 mParameters.set(QCameraParameters::KEY_SHARPNESS, sharpness); 8161 bool ret = native_set_parms(CAMERA_PARM_SHARPNESS, sizeof(sharpness), 8162 (void *)&sharpness); 8163 return ret ? NO_ERROR : UNKNOWN_ERROR; 8164 } 8165 8166 status_t QualcommCameraHardware::setContrast(const QCameraParameters& params) 8167 { 8168 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_CONTRAST)) { 8169 ALOGI("Contrast not supported for this sensor"); 8170 return NO_ERROR; 8171 } 8172 8173 const char *str = params.get(QCameraParameters::KEY_SCENE_MODE); 8174 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str); 8175 8176 if(value == CAMERA_BESTSHOT_OFF) { 8177 int contrast = params.getInt(QCameraParameters::KEY_CONTRAST); 8178 if((contrast < CAMERA_MIN_CONTRAST) 8179 || (contrast > CAMERA_MAX_CONTRAST)) 8180 return UNKNOWN_ERROR; 8181 8182 ALOGV("setting contrast %d", contrast); 8183 mParameters.set(QCameraParameters::KEY_CONTRAST, contrast); 8184 bool ret = native_set_parms(CAMERA_PARM_CONTRAST, sizeof(contrast), 8185 (void *)&contrast); 8186 return ret ? NO_ERROR : UNKNOWN_ERROR; 8187 } else { 8188 ALOGI(" Contrast value will not be set " \ 8189 "when the scenemode selected is %s", str); 8190 return NO_ERROR; 8191 } 8192 } 8193 8194 status_t QualcommCameraHardware::setSaturation(const QCameraParameters& params) 8195 { 8196 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SATURATION)) { 8197 ALOGI("Saturation not supported for this sensor"); 8198 return NO_ERROR; 8199 } 8200 int result; 8201 int saturation = params.getInt(QCameraParameters::KEY_SATURATION); 8202 8203 if((saturation < CAMERA_MIN_SATURATION) 8204 || (saturation > CAMERA_MAX_SATURATION)) 8205 return UNKNOWN_ERROR; 8206 8207 ALOGV("Setting saturation %d", saturation); 8208 mParameters.set(QCameraParameters::KEY_SATURATION, saturation); 8209 bool ret = native_set_parms(CAMERA_PARM_SATURATION, sizeof(saturation), 8210 (void *)&saturation, (int *)&result); 8211 if(result == MM_CAMERA_ERR_INVALID_OPERATION) 8212 ALOGI("Saturation Value: %d is not set as the selected value is not supported", saturation); 8213 8214 return ret ? NO_ERROR : UNKNOWN_ERROR; 8215 } 8216 8217 status_t QualcommCameraHardware::setPreviewFormat(const QCameraParameters& params) { 8218 const char *str = params.getPreviewFormat(); 8219 int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str); 8220 if(previewFormat != NOT_FOUND) { 8221 mParameters.set(QCameraParameters::KEY_PREVIEW_FORMAT, str); 8222 mPreviewFormat = previewFormat; 8223 if(HAL_currentCameraMode != CAMERA_MODE_3D) { 8224 ALOGI("Setting preview format to native"); 8225 bool ret = native_set_parms(CAMERA_PARM_PREVIEW_FORMAT, sizeof(previewFormat), 8226 (void *)&previewFormat); 8227 }else{ 8228 ALOGI("Skipping set preview format call to native"); 8229 } 8230 return NO_ERROR; 8231 } 8232 ALOGE("Invalid preview format value: %s", (str == NULL) ? "NULL" : str); 8233 return BAD_VALUE; 8234 } 8235 8236 status_t QualcommCameraHardware::setStrTextures(const QCameraParameters& params) { 8237 const char *str = params.get("strtextures"); 8238 if(str != NULL) { 8239 ALOGV("strtextures = %s", str); 8240 mParameters.set("strtextures", str); 8241 if(!strncmp(str, "on", 2) || !strncmp(str, "ON", 2)) { 8242 strTexturesOn = true; 8243 } else if (!strncmp(str, "off", 3) || !strncmp(str, "OFF", 3)) { 8244 strTexturesOn = false; 8245 } 8246 } 8247 return NO_ERROR; 8248 } 8249 8250 status_t QualcommCameraHardware::setBrightness(const QCameraParameters& params) { 8251 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BRIGHTNESS)) { 8252 ALOGI("Set Brightness not supported for this sensor"); 8253 return NO_ERROR; 8254 } 8255 int brightness = params.getInt("luma-adaptation"); 8256 if (mBrightness != brightness) { 8257 ALOGV(" new brightness value : %d ", brightness); 8258 mBrightness = brightness; 8259 mParameters.set("luma-adaptation", brightness); 8260 bool ret = native_set_parms(CAMERA_PARM_BRIGHTNESS, sizeof(mBrightness), 8261 (void *)&mBrightness); 8262 return ret ? NO_ERROR : UNKNOWN_ERROR; 8263 } 8264 return NO_ERROR; 8265 } 8266 8267 status_t QualcommCameraHardware::setSkinToneEnhancement(const QCameraParameters& params) { 8268 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SCE_FACTOR)) { 8269 ALOGI("SkinToneEnhancement not supported for this sensor"); 8270 return NO_ERROR; 8271 } 8272 int skinToneValue = params.getInt("skinToneEnhancement"); 8273 if (mSkinToneEnhancement != skinToneValue) { 8274 ALOGV(" new skinTone correction value : %d ", skinToneValue); 8275 mSkinToneEnhancement = skinToneValue; 8276 mParameters.set("skinToneEnhancement", skinToneValue); 8277 bool ret = native_set_parms(CAMERA_PARM_SCE_FACTOR, sizeof(mSkinToneEnhancement), 8278 (void *)&mSkinToneEnhancement); 8279 return ret ? NO_ERROR : UNKNOWN_ERROR; 8280 } 8281 return NO_ERROR; 8282 } 8283 8284 status_t QualcommCameraHardware::setWhiteBalance(const QCameraParameters& params) 8285 { 8286 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_WHITE_BALANCE)) { 8287 ALOGI("WhiteBalance not supported for this sensor"); 8288 return NO_ERROR; 8289 } 8290 8291 int result; 8292 8293 const char *str = params.get(QCameraParameters::KEY_WHITE_BALANCE); 8294 if (str != NULL) { 8295 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str); 8296 if (value != NOT_FOUND) { 8297 mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, str); 8298 bool ret = native_set_parms(CAMERA_PARM_WHITE_BALANCE, sizeof(value), 8299 (void *)&value, (int *)&result); 8300 if(result == MM_CAMERA_ERR_INVALID_OPERATION) { 8301 ALOGI("WhiteBalance Value: %s is not set as the selected value is not supported ", str); 8302 } 8303 return ret ? NO_ERROR : UNKNOWN_ERROR; 8304 } 8305 } 8306 ALOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str); 8307 return BAD_VALUE; 8308 8309 } 8310 8311 status_t QualcommCameraHardware::setFlash(const QCameraParameters& params) 8312 { 8313 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) { 8314 ALOGI("%s: flash not supported", __FUNCTION__); 8315 return NO_ERROR; 8316 } 8317 8318 const char *str = params.get(QCameraParameters::KEY_FLASH_MODE); 8319 if (str != NULL) { 8320 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str); 8321 if (value != NOT_FOUND) { 8322 mParameters.set(QCameraParameters::KEY_FLASH_MODE, str); 8323 bool ret = native_set_parms(CAMERA_PARM_LED_MODE, 8324 sizeof(value), (void *)&value); 8325 if(mZslEnable && (value != LED_MODE_OFF)){ 8326 mParameters.set("num-snaps-per-shutter", "1"); 8327 ALOGI("%s Setting num-snaps-per-shutter to 1", __FUNCTION__); 8328 numCapture = 1; 8329 } 8330 return ret ? NO_ERROR : UNKNOWN_ERROR; 8331 } 8332 } 8333 ALOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str); 8334 return BAD_VALUE; 8335 } 8336 8337 status_t QualcommCameraHardware::setAntibanding(const QCameraParameters& params) 8338 { 8339 int result; 8340 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ANTIBANDING)) { 8341 ALOGI("Parameter AntiBanding is not supported for this sensor"); 8342 return NO_ERROR; 8343 } 8344 const char *str = params.get(QCameraParameters::KEY_ANTIBANDING); 8345 if (str != NULL) { 8346 int value = (camera_antibanding_type)attr_lookup( 8347 antibanding, sizeof(antibanding) / sizeof(str_map), str); 8348 if (value != NOT_FOUND) { 8349 camera_antibanding_type temp = (camera_antibanding_type) value; 8350 mParameters.set(QCameraParameters::KEY_ANTIBANDING, str); 8351 bool ret = native_set_parms(CAMERA_PARM_ANTIBANDING, 8352 sizeof(camera_antibanding_type), (void *)&temp ,(int *)&result); 8353 if(result == MM_CAMERA_ERR_INVALID_OPERATION) { 8354 ALOGI("AntiBanding Value: %s is not supported for the given BestShot Mode", str); 8355 } 8356 return ret ? NO_ERROR : UNKNOWN_ERROR; 8357 } 8358 } 8359 ALOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str); 8360 return BAD_VALUE; 8361 } 8362 8363 status_t QualcommCameraHardware::setMCEValue(const QCameraParameters& params) 8364 { 8365 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_MCE)) { 8366 ALOGI("Parameter MCE is not supported for this sensor"); 8367 return NO_ERROR; 8368 } 8369 8370 const char *str = params.get(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT); 8371 if (str != NULL) { 8372 int value = attr_lookup(mce, sizeof(mce) / sizeof(str_map), str); 8373 if (value != NOT_FOUND) { 8374 int8_t temp = (int8_t)value; 8375 ALOGI("%s: setting MCE value of %s", __FUNCTION__, str); 8376 mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT, str); 8377 8378 native_set_parms(CAMERA_PARM_MCE, sizeof(int8_t), (void *)&temp); 8379 return NO_ERROR; 8380 } 8381 } 8382 ALOGE("Invalid MCE value: %s", (str == NULL) ? "NULL" : str); 8383 return BAD_VALUE; 8384 } 8385 8386 status_t QualcommCameraHardware::setHighFrameRate(const QCameraParameters& params) 8387 { 8388 if((!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR)) || (mIs3DModeOn)) { 8389 ALOGI("Parameter HFR is not supported for this sensor"); 8390 return NO_ERROR; 8391 } 8392 8393 const char *str = params.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 8394 if (str != NULL) { 8395 int value = attr_lookup(hfr, sizeof(hfr) / sizeof(str_map), str); 8396 if (value != NOT_FOUND) { 8397 int32_t temp = (int32_t)value; 8398 ALOGI("%s: setting HFR value of %s(%d)", __FUNCTION__, str, temp); 8399 //Check for change in HFR value 8400 const char *oldHfr = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 8401 if(strcmp(oldHfr, str)){ 8402 ALOGI("%s: old HFR: %s, new HFR %s", __FUNCTION__, oldHfr, str); 8403 mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE, str); 8404 mHFRMode = true; 8405 if(mCameraRunning == true) { 8406 mHFRThreadWaitLock.lock(); 8407 pthread_attr_t pattr; 8408 pthread_attr_init(&pattr); 8409 pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); 8410 mHFRThreadRunning = !pthread_create(&mHFRThread, 8411 &pattr, 8412 hfr_thread, 8413 (void*)NULL); 8414 mHFRThreadWaitLock.unlock(); 8415 return NO_ERROR; 8416 } 8417 } 8418 native_set_parms(CAMERA_PARM_HFR, sizeof(int32_t), (void *)&temp); 8419 return NO_ERROR; 8420 } 8421 } 8422 ALOGE("Invalid HFR value: %s", (str == NULL) ? "NULL" : str); 8423 return BAD_VALUE; 8424 } 8425 8426 status_t QualcommCameraHardware::setHDRImaging(const QCameraParameters& params) 8427 { 8428 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HDR) && mZslEnable) { 8429 ALOGI("Parameter HDR is not supported for this sensor/ ZSL mode"); 8430 return NO_ERROR; 8431 } 8432 const char *str = params.get(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING); 8433 if (str != NULL) { 8434 int value = attr_lookup(hdr, sizeof(hdr) / sizeof(str_map), str); 8435 if (value != NOT_FOUND) { 8436 exp_bracketing_t temp; 8437 memset(&temp, 0, sizeof(temp)); 8438 temp.hdr_enable= (int32_t)value; 8439 temp.mode = HDR_MODE; 8440 temp.total_frames = 3; 8441 temp.total_hal_frames = HDR_HAL_FRAME; 8442 mHdrMode = temp.hdr_enable; 8443 ALOGI("%s: setting HDR value of %s", __FUNCTION__, str); 8444 mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING, str); 8445 if(mHdrMode){ 8446 numCapture = temp.total_hal_frames; 8447 } else 8448 numCapture = 1; 8449 native_set_parms(CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp); 8450 return NO_ERROR; 8451 } 8452 } 8453 ALOGE("Invalid HDR value: %s", (str == NULL) ? "NULL" : str); 8454 return BAD_VALUE; 8455 } 8456 8457 status_t QualcommCameraHardware::setExpBracketing(const QCameraParameters& params) 8458 { 8459 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HDR) && mZslEnable) { 8460 ALOGI("Parameter Exposure Bracketing is not supported for this sensor/ZSL mode"); 8461 return NO_ERROR; 8462 } 8463 const char *str = params.get("capture-burst-exposures"); 8464 if ((str != NULL) && (!mHdrMode)) { 8465 char exp_val[MAX_EXP_BRACKETING_LENGTH]; 8466 exp_bracketing_t temp; 8467 memset(&temp, 0, sizeof(temp)); 8468 8469 mExpBracketMode = true; 8470 temp.mode = EXP_BRACKETING_MODE; 8471 temp.hdr_enable = true; 8472 /* App sets values separated by comma. 8473 Thus total number of snapshot to capture is strlen(str)/2 8474 eg: "-1,1,2" */ 8475 strlcpy(exp_val, str, sizeof(exp_val)); 8476 temp.total_frames = (strlen(exp_val) > MAX_SNAPSHOT_BUFFERS -2) ? 8477 MAX_SNAPSHOT_BUFFERS -2 : strlen(exp_val); 8478 temp.total_hal_frames = temp.total_frames; 8479 strlcpy(temp.values, exp_val, MAX_EXP_BRACKETING_LENGTH); 8480 ALOGI("%s: setting Exposure Bracketing value of %s", __FUNCTION__, temp.values); 8481 mParameters.set("capture-burst-exposures", str); 8482 if(!mZslEnable){ 8483 numCapture = temp.total_frames; 8484 } 8485 native_set_parms(CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp); 8486 return NO_ERROR; 8487 } else 8488 mExpBracketMode = false; 8489 return NO_ERROR; 8490 } 8491 8492 status_t QualcommCameraHardware::setLensshadeValue(const QCameraParameters& params) 8493 { 8494 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ROLLOFF)) { 8495 ALOGI("Parameter Rolloff is not supported for this sensor"); 8496 return NO_ERROR; 8497 } 8498 8499 const char *str = params.get(QCameraParameters::KEY_LENSSHADE); 8500 if (str != NULL) { 8501 int value = attr_lookup(lensshade, 8502 sizeof(lensshade) / sizeof(str_map), str); 8503 if (value != NOT_FOUND) { 8504 int8_t temp = (int8_t)value; 8505 mParameters.set(QCameraParameters::KEY_LENSSHADE, str); 8506 8507 native_set_parms(CAMERA_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp); 8508 return NO_ERROR; 8509 } 8510 } 8511 ALOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str); 8512 return NO_ERROR; 8513 } 8514 8515 status_t QualcommCameraHardware::setSelectableZoneAf(const QCameraParameters& params) 8516 { 8517 if(mHasAutoFocusSupport && supportsSelectableZoneAf()) { 8518 const char *str = params.get(QCameraParameters::KEY_SELECTABLE_ZONE_AF); 8519 if (str != NULL) { 8520 int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str); 8521 if (value != NOT_FOUND) { 8522 mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF, str); 8523 bool ret = native_set_parms(CAMERA_PARM_FOCUS_RECT, sizeof(value), 8524 (void *)&value); 8525 return ret ? NO_ERROR : UNKNOWN_ERROR; 8526 } 8527 } 8528 ALOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str); 8529 return BAD_VALUE; 8530 } 8531 return NO_ERROR; 8532 } 8533 8534 status_t QualcommCameraHardware::setTouchAfAec(const QCameraParameters& params) 8535 { 8536 ALOGV("%s",__func__); 8537 if(mHasAutoFocusSupport){ 8538 int xAec, yAec, xAf, yAf; 8539 int cx, cy; 8540 int width, height; 8541 params.getMeteringAreaCenter(&cx, &cy); 8542 mParameters.getPreviewSize(&width, &height); 8543 8544 // @Punit 8545 // The coords sent from upper layer is in range (-1000, -1000) to (1000, 1000) 8546 // So, they are transformed to range (0, 0) to (previewWidth, previewHeight) 8547 cx = cx + 1000; 8548 cy = cy + 1000; 8549 cx = cx * (width / 2000.0f); 8550 cy = cy * (height / 2000.0f); 8551 8552 //Negative values are invalid and does not update anything 8553 ALOGV("Touch Area Center (cx, cy) = (%d, %d)", cx, cy); 8554 8555 //Currently using same values for AF and AEC 8556 xAec = cx; yAec = cy; 8557 xAf = cx; yAf = cy; 8558 8559 const char *str = params.get(QCameraParameters::KEY_TOUCH_AF_AEC); 8560 if (str != NULL) { 8561 int value = attr_lookup(touchafaec, 8562 sizeof(touchafaec) / sizeof(str_map), str); 8563 if (value != NOT_FOUND) { 8564 8565 //Dx,Dy will be same as defined in res/layout/camera.xml 8566 //passed down to HAL in a key.value pair. 8567 int FOCUS_RECTANGLE_DX = params.getInt("touchAfAec-dx"); 8568 int FOCUS_RECTANGLE_DY = params.getInt("touchAfAec-dy"); 8569 mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC, str); 8570 mParameters.setTouchIndexAec(xAec, yAec); 8571 mParameters.setTouchIndexAf(xAf, yAf); 8572 8573 cam_set_aec_roi_t aec_roi_value; 8574 roi_info_t af_roi_value; 8575 8576 memset(&af_roi_value, 0, sizeof(roi_info_t)); 8577 8578 //If touch AF/AEC is enabled and touch event has occured then 8579 //call the ioctl with valid values. 8580 if (value == true 8581 && (xAec >= 0 && yAec >= 0) 8582 && (xAf >= 0 && yAf >= 0)) { 8583 //Set Touch AEC params (Pass the center co-ordinate) 8584 aec_roi_value.aec_roi_enable = AEC_ROI_ON; 8585 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE; 8586 aec_roi_value.aec_roi_position.coordinate.x = xAec; 8587 aec_roi_value.aec_roi_position.coordinate.y = yAec; 8588 8589 //Set Touch AF params (Pass the top left co-ordinate) 8590 af_roi_value.num_roi = 1; 8591 if ((xAf-(FOCUS_RECTANGLE_DX/2)) < 0) 8592 af_roi_value.roi[0].x = 1; 8593 else 8594 af_roi_value.roi[0].x = xAf - (FOCUS_RECTANGLE_DX/2); 8595 8596 if ((yAf-(FOCUS_RECTANGLE_DY/2)) < 0) 8597 af_roi_value.roi[0].y = 1; 8598 else 8599 af_roi_value.roi[0].y = yAf - (FOCUS_RECTANGLE_DY/2); 8600 8601 af_roi_value.roi[0].dx = FOCUS_RECTANGLE_DX; 8602 af_roi_value.roi[0].dy = FOCUS_RECTANGLE_DY; 8603 af_roi_value.is_multiwindow = mMultiTouch; 8604 native_set_parms(CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value); 8605 native_set_parms(CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value); 8606 } 8607 else if(value == false) { 8608 //Set Touch AEC params 8609 aec_roi_value.aec_roi_enable = AEC_ROI_OFF; 8610 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE; 8611 aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE; 8612 aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE; 8613 8614 //Set Touch AF params 8615 af_roi_value.num_roi = 0; 8616 native_set_parms(CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value); 8617 native_set_parms(CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value); 8618 } 8619 //@Punit: If the values are negative, we dont send anything to the lower layer 8620 } 8621 return NO_ERROR; 8622 } 8623 ALOGE("Invalid Touch AF/AEC value: %s", (str == NULL) ? "NULL" : str); 8624 return BAD_VALUE; 8625 } 8626 return NO_ERROR; 8627 } 8628 8629 status_t QualcommCameraHardware::setFaceDetection(const char *str) 8630 { 8631 if(supportsFaceDetection() == false){ 8632 ALOGI("Face detection is not enabled"); 8633 return NO_ERROR; 8634 } 8635 if (str != NULL) { 8636 int value = attr_lookup(facedetection, 8637 sizeof(facedetection) / sizeof(str_map), str); 8638 if (value != NOT_FOUND) { 8639 mMetaDataWaitLock.lock(); 8640 mFaceDetectOn = value; 8641 mMetaDataWaitLock.unlock(); 8642 mParameters.set(QCameraParameters::KEY_FACE_DETECTION, str); 8643 return NO_ERROR; 8644 } 8645 } 8646 ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str); 8647 return BAD_VALUE; 8648 } 8649 8650 status_t QualcommCameraHardware::setRedeyeReduction(const QCameraParameters& params) 8651 { 8652 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_REDEYE_REDUCTION)) { 8653 ALOGI("Parameter Redeye Reduction is not supported for this sensor"); 8654 return NO_ERROR; 8655 } 8656 8657 const char *str = params.get(QCameraParameters::KEY_REDEYE_REDUCTION); 8658 if (str != NULL) { 8659 int value = attr_lookup(redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map), str); 8660 if (value != NOT_FOUND) { 8661 int8_t temp = (int8_t)value; 8662 ALOGI("%s: setting Redeye Reduction value of %s", __FUNCTION__, str); 8663 mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION, str); 8664 8665 native_set_parms(CAMERA_PARM_REDEYE_REDUCTION, sizeof(int8_t), (void *)&temp); 8666 return NO_ERROR; 8667 } 8668 } 8669 ALOGE("Invalid Redeye Reduction value: %s", (str == NULL) ? "NULL" : str); 8670 return BAD_VALUE; 8671 } 8672 8673 status_t QualcommCameraHardware::setISOValue(const QCameraParameters& params) { 8674 int8_t temp_hjr; 8675 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ISO)) { 8676 ALOGI("Parameter ISO Value is not supported for this sensor"); 8677 return NO_ERROR; 8678 } 8679 const char *str = params.get(QCameraParameters::KEY_ISO_MODE); 8680 if (str != NULL) { 8681 int value = (camera_iso_mode_type)attr_lookup( 8682 iso, sizeof(iso) / sizeof(str_map), str); 8683 if (value != NOT_FOUND) { 8684 camera_iso_mode_type temp = (camera_iso_mode_type) value; 8685 if (value == CAMERA_ISO_DEBLUR) { 8686 temp_hjr = true; 8687 native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr); 8688 mHJR = value; 8689 } 8690 else { 8691 if (mHJR == CAMERA_ISO_DEBLUR) { 8692 temp_hjr = false; 8693 native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr); 8694 mHJR = value; 8695 } 8696 } 8697 8698 mParameters.set(QCameraParameters::KEY_ISO_MODE, str); 8699 native_set_parms(CAMERA_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp); 8700 return NO_ERROR; 8701 } 8702 } 8703 ALOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str); 8704 return BAD_VALUE; 8705 } 8706 8707 status_t QualcommCameraHardware::setSceneDetect(const QCameraParameters& params) 8708 { 8709 bool retParm1, retParm2; 8710 if (supportsSceneDetection()) { 8711 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BL_DETECTION) && !mCfgControl.mm_camera_is_supported(CAMERA_PARM_SNOW_DETECTION)) { 8712 ALOGI("Parameter Auto Scene Detection is not supported for this sensor"); 8713 return NO_ERROR; 8714 } 8715 const char *str = params.get(QCameraParameters::KEY_SCENE_DETECT); 8716 if (str != NULL) { 8717 int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str); 8718 if (value != NOT_FOUND) { 8719 mParameters.set(QCameraParameters::KEY_SCENE_DETECT, str); 8720 8721 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value), 8722 (void *)&value); 8723 8724 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value), 8725 (void *)&value); 8726 8727 //All Auto Scene detection modes should be all ON or all OFF. 8728 if(retParm1 == false || retParm2 == false) { 8729 value = !value; 8730 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value), 8731 (void *)&value); 8732 8733 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value), 8734 (void *)&value); 8735 } 8736 return (retParm1 && retParm2) ? NO_ERROR : UNKNOWN_ERROR; 8737 } 8738 } 8739 ALOGE("Invalid auto scene detection value: %s", (str == NULL) ? "NULL" : str); 8740 return BAD_VALUE; 8741 } 8742 return NO_ERROR; 8743 } 8744 8745 status_t QualcommCameraHardware::setSceneMode(const QCameraParameters& params) 8746 { 8747 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BESTSHOT_MODE)) { 8748 ALOGI("Parameter Scenemode is not supported for this sensor"); 8749 return NO_ERROR; 8750 } 8751 8752 const char *str = params.get(QCameraParameters::KEY_SCENE_MODE); 8753 8754 if (str != NULL) { 8755 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str); 8756 int32_t asd_val; 8757 if (value != NOT_FOUND) { 8758 mParameters.set(QCameraParameters::KEY_SCENE_MODE, str); 8759 bool ret = native_set_parms(CAMERA_PARM_BESTSHOT_MODE, sizeof(value), 8760 (void *)&value); 8761 8762 if (ret == NO_ERROR) { 8763 int retParm1, retParm2; 8764 /*if value is auto, set ASD on, else set ASD off*/ 8765 if (value == CAMERA_BESTSHOT_AUTO ) { 8766 asd_val = TRUE; 8767 } else { 8768 asd_val = FALSE; 8769 } 8770 8771 /*note: we need to simplify this logic by using a single ctrl as in 8960*/ 8772 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value), 8773 (void *)&asd_val); 8774 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value), 8775 (void *)&asd_val); 8776 } 8777 return ret ? NO_ERROR : UNKNOWN_ERROR; 8778 } 8779 } 8780 ALOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str); 8781 return BAD_VALUE; 8782 } 8783 status_t QualcommCameraHardware::setGpsLocation(const QCameraParameters& params) 8784 { 8785 const char *method = params.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD); 8786 if (method) { 8787 mParameters.set(QCameraParameters::KEY_GPS_PROCESSING_METHOD, method); 8788 }else { 8789 mParameters.remove(QCameraParameters::KEY_GPS_PROCESSING_METHOD); 8790 } 8791 8792 const char *latitude = params.get(QCameraParameters::KEY_GPS_LATITUDE); 8793 if (latitude) { 8794 ALOGI("latitude %s",latitude); 8795 mParameters.set(QCameraParameters::KEY_GPS_LATITUDE, latitude); 8796 }else { 8797 mParameters.remove(QCameraParameters::KEY_GPS_LATITUDE); 8798 } 8799 8800 const char *latitudeRef = params.get(QCameraParameters::KEY_GPS_LATITUDE_REF); 8801 if (latitudeRef) { 8802 mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef); 8803 }else { 8804 mParameters.remove(QCameraParameters::KEY_GPS_LATITUDE_REF); 8805 } 8806 8807 const char *longitude = params.get(QCameraParameters::KEY_GPS_LONGITUDE); 8808 if (longitude) { 8809 mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE, longitude); 8810 }else { 8811 mParameters.remove(QCameraParameters::KEY_GPS_LONGITUDE); 8812 } 8813 8814 const char *longitudeRef = params.get(QCameraParameters::KEY_GPS_LONGITUDE_REF); 8815 if (longitudeRef) { 8816 mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef); 8817 }else { 8818 mParameters.remove(QCameraParameters::KEY_GPS_LONGITUDE_REF); 8819 } 8820 8821 const char *altitudeRef = params.get(QCameraParameters::KEY_GPS_ALTITUDE_REF); 8822 if (altitudeRef) { 8823 mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef); 8824 }else { 8825 mParameters.remove(QCameraParameters::KEY_GPS_ALTITUDE_REF); 8826 } 8827 8828 const char *altitude = params.get(QCameraParameters::KEY_GPS_ALTITUDE); 8829 if (altitude) { 8830 mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE, altitude); 8831 }else { 8832 mParameters.remove(QCameraParameters::KEY_GPS_ALTITUDE); 8833 } 8834 8835 const char *status = params.get(QCameraParameters::KEY_GPS_STATUS); 8836 if (status) { 8837 mParameters.set(QCameraParameters::KEY_GPS_STATUS, status); 8838 } 8839 8840 const char *dateTime = params.get(QCameraParameters::KEY_EXIF_DATETIME); 8841 if (dateTime) { 8842 mParameters.set(QCameraParameters::KEY_EXIF_DATETIME, dateTime); 8843 }else { 8844 mParameters.remove(QCameraParameters::KEY_EXIF_DATETIME); 8845 } 8846 8847 const char *timestamp = params.get(QCameraParameters::KEY_GPS_TIMESTAMP); 8848 if (timestamp) { 8849 mParameters.set(QCameraParameters::KEY_GPS_TIMESTAMP, timestamp); 8850 }else { 8851 mParameters.remove(QCameraParameters::KEY_GPS_TIMESTAMP); 8852 } 8853 8854 return NO_ERROR; 8855 8856 } 8857 8858 status_t QualcommCameraHardware::setRotation(const QCameraParameters& params) 8859 { 8860 status_t rc = NO_ERROR; 8861 int sensor_mount_angle = HAL_cameraInfo[HAL_currentCameraId].sensor_mount_angle; 8862 int rotation = params.getInt(QCameraParameters::KEY_ROTATION); 8863 if (rotation != NOT_FOUND) { 8864 if (rotation == 0 || rotation == 90 || rotation == 180 8865 || rotation == 270) { 8866 rotation = (rotation + sensor_mount_angle)%360; 8867 mParameters.set(QCameraParameters::KEY_ROTATION, rotation); 8868 mRotation = rotation; 8869 } else { 8870 ALOGE("Invalid rotation value: %d", rotation); 8871 rc = BAD_VALUE; 8872 } 8873 } 8874 return rc; 8875 } 8876 8877 status_t QualcommCameraHardware::setZoom(const QCameraParameters& params) 8878 { 8879 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ZOOM)) { 8880 ALOGI("Parameter setZoom is not supported for this sensor"); 8881 return NO_ERROR; 8882 } 8883 status_t rc = NO_ERROR; 8884 // No matter how many different zoom values the driver can provide, HAL 8885 // provides applictations the same number of zoom levels. The maximum driver 8886 // zoom value depends on sensor output (VFE input) and preview size (VFE 8887 // output) because VFE can only crop and cannot upscale. If the preview size 8888 // is bigger, the maximum zoom ratio is smaller. However, we want the 8889 // zoom ratio of each zoom level is always the same whatever the preview 8890 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So, 8891 // we need to have a fixed maximum zoom value and do read it from the 8892 // driver. 8893 static const int ZOOM_STEP = 1; 8894 int32_t zoom_level = params.getInt("zoom"); 8895 if(zoom_level >= 0 && zoom_level <= mMaxZoom-1) { 8896 mParameters.set("zoom", zoom_level); 8897 int32_t zoom_value = ZOOM_STEP * zoom_level; 8898 bool ret = native_set_parms(CAMERA_PARM_ZOOM, 8899 sizeof(zoom_value), (void *)&zoom_value); 8900 rc = ret ? NO_ERROR : UNKNOWN_ERROR; 8901 } else { 8902 rc = BAD_VALUE; 8903 } 8904 8905 return rc; 8906 } 8907 8908 status_t QualcommCameraHardware::setDenoise(const QCameraParameters& params) 8909 { 8910 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_WAVELET_DENOISE)) { 8911 ALOGI("Wavelet Denoise is not supported for this sensor"); 8912 return NO_ERROR; 8913 } 8914 const char *str = params.get(QCameraParameters::KEY_DENOISE); 8915 if (str != NULL) { 8916 int value = attr_lookup(denoise, 8917 sizeof(denoise) / sizeof(str_map), str); 8918 if ((value != NOT_FOUND) && (mDenoiseValue != value)) { 8919 mDenoiseValue = value; 8920 mParameters.set(QCameraParameters::KEY_DENOISE, str); 8921 bool ret = native_set_parms(CAMERA_PARM_WAVELET_DENOISE, sizeof(value), 8922 (void *)&value); 8923 return ret ? NO_ERROR : UNKNOWN_ERROR; 8924 } 8925 return NO_ERROR; 8926 } 8927 ALOGE("Invalid Denoise value: %s", (str == NULL) ? "NULL" : str); 8928 return BAD_VALUE; 8929 } 8930 8931 status_t QualcommCameraHardware::setZslParam(const QCameraParameters& params) 8932 { 8933 if(!mZslEnable) { 8934 ALOGV("Zsl is not enabled"); 8935 return NO_ERROR; 8936 } 8937 /* This ensures that restart of Preview doesnt happen when taking 8938 * Snapshot for continuous viewfinder */ 8939 const char *str = params.get("continuous-temporal-bracketing"); 8940 if(str !=NULL) { 8941 if(!strncmp(str, "enable", 8)) 8942 mZslPanorama = true; 8943 else 8944 mZslPanorama = false; 8945 return NO_ERROR; 8946 } 8947 mZslPanorama = false; 8948 return NO_ERROR; 8949 8950 } 8951 8952 status_t QualcommCameraHardware::setSnapshotCount(const QCameraParameters& params) 8953 { 8954 int value; 8955 char snapshotCount[5]; 8956 if(!mZslEnable){ 8957 value = numCapture; 8958 } else { 8959 /* ZSL case: Get value from App */ 8960 const char *str = params.get("num-snaps-per-shutter"); 8961 if (str != NULL) { 8962 value = atoi(str); 8963 } else 8964 value = 1; 8965 } 8966 /* Sanity check */ 8967 if(value > MAX_SNAPSHOT_BUFFERS -2) 8968 value = MAX_SNAPSHOT_BUFFERS -2; 8969 else if(value < 1) 8970 value = 1; 8971 snprintf(snapshotCount, sizeof(snapshotCount),"%d",value); 8972 numCapture = value; 8973 mParameters.set("num-snaps-per-shutter", snapshotCount); 8974 ALOGI("%s setting num-snaps-per-shutter to %s", __FUNCTION__, snapshotCount); 8975 return NO_ERROR; 8976 8977 } 8978 8979 status_t QualcommCameraHardware::updateFocusDistances(const char *focusmode) 8980 { 8981 ALOGV("%s: IN", __FUNCTION__); 8982 focus_distances_info_t focusDistances; 8983 if( mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCUS_DISTANCES, 8984 (void *)&focusDistances) == MM_CAMERA_SUCCESS) { 8985 String8 str; 8986 char buffer[32]; 8987 snprintf(buffer, sizeof(buffer), "%f", focusDistances.focus_distance[0]); 8988 str.append(buffer); 8989 snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[1]); 8990 str.append(buffer); 8991 if(strcmp(focusmode, QCameraParameters::FOCUS_MODE_INFINITY) == 0) 8992 snprintf(buffer, sizeof(buffer), ",%s", "Infinity"); 8993 else 8994 snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[2]); 8995 str.append(buffer); 8996 ALOGI("%s: setting KEY_FOCUS_DISTANCES as %s", __FUNCTION__, str.string()); 8997 mParameters.set(QCameraParameters::KEY_FOCUS_DISTANCES, str.string()); 8998 return NO_ERROR; 8999 } 9000 ALOGE("%s: get CAMERA_PARM_FOCUS_DISTANCES failed!!!", __FUNCTION__); 9001 return BAD_VALUE; 9002 } 9003 9004 status_t QualcommCameraHardware::setMeteringAreas(const QCameraParameters& params) 9005 { 9006 const char *str = params.get(QCameraParameters::KEY_METERING_AREAS); 9007 if (str == NULL || (strcmp(str, "0") == 0)) { 9008 ALOGE("%s: Parameter string is null", __FUNCTION__); 9009 } 9010 else { 9011 // handling default string 9012 if ((strcmp("(-2000,-2000,-2000,-2000,0)", str) == 0) || 9013 (strcmp("(0,0,0,0,0)", str) == 0)){ 9014 mParameters.set(QCameraParameters::KEY_METERING_AREAS, NULL); 9015 return NO_ERROR; 9016 } 9017 if(checkAreaParameters(str) != 0) { 9018 ALOGE("%s: Failed to parse the input string '%s'", __FUNCTION__, str); 9019 return BAD_VALUE; 9020 } 9021 mParameters.set(QCameraParameters::KEY_METERING_AREAS, str); 9022 } 9023 9024 return NO_ERROR; 9025 } 9026 9027 status_t QualcommCameraHardware::setFocusAreas(const QCameraParameters& params) 9028 { 9029 const char *str = params.get(QCameraParameters::KEY_FOCUS_AREAS); 9030 9031 if (str == NULL || (strcmp(str, "0") == 0)) { 9032 ALOGE("%s: Parameter string is null", __FUNCTION__); 9033 } 9034 else { 9035 // handling default string 9036 if ((strcmp("(-2000,-2000,-2000,-2000,0)", str) == 0) || 9037 (strcmp("(0,0,0,0,0)", str) == 0)) { 9038 mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, NULL); 9039 return NO_ERROR; 9040 } 9041 9042 if(checkAreaParameters(str) != 0) { 9043 ALOGE("%s: Failed to parse the input string '%s'", __FUNCTION__, str); 9044 return BAD_VALUE; 9045 } 9046 9047 mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, str); 9048 } 9049 9050 return NO_ERROR; 9051 } 9052 status_t QualcommCameraHardware::setFocusMode(const QCameraParameters& params) 9053 { 9054 const char *str = params.get(QCameraParameters::KEY_FOCUS_MODE); 9055 if (str != NULL) { 9056 ALOGI("FocusMode =%s", str); 9057 int32_t value = attr_lookup(focus_modes, 9058 sizeof(focus_modes) / sizeof(str_map), str); 9059 if (value != NOT_FOUND) { 9060 mParameters.set(QCameraParameters::KEY_FOCUS_MODE, str); 9061 9062 if(mHasAutoFocusSupport && (updateFocusDistances(str) != NO_ERROR)) { 9063 ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, str); 9064 return UNKNOWN_ERROR; 9065 } 9066 9067 if(mHasAutoFocusSupport){ 9068 int cafSupport = FALSE; 9069 if(!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) || 9070 !strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)){ 9071 cafSupport = TRUE; 9072 } 9073 ALOGV("Continuous Auto Focus %d", cafSupport); 9074 native_set_parms(CAMERA_PARM_CONTINUOUS_AF, sizeof(int8_t), (void *)&cafSupport); 9075 } 9076 // Focus step is reset to infinity when preview is started. We do 9077 // not need to do anything now. 9078 return NO_ERROR; 9079 } 9080 } 9081 ALOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str); 9082 return BAD_VALUE; 9083 9084 } 9085 QualcommCameraHardware::DispMemPool::DispMemPool(int fd, int buffer_size, 9086 int num_buffers, int frame_size, 9087 const char *name) : 9088 QualcommCameraHardware::MemPool(buffer_size, 9089 num_buffers, 9090 frame_size, 9091 name), 9092 mFD(fd) 9093 { 9094 #if 0 9095 ALOGV("constructing MemPool %s from gralloc memory: " 9096 "%d frames @ %d size " 9097 "buffer size %d", 9098 mName, 9099 num_buffers, frame_size, buffer_size); 9100 /* Use the fd given by gralloc and ask MemoryHeapBase to map it 9101 * in this process space */ 9102 mHeap = new MemoryHeapBase(mFD, buffer_size, MemoryHeapBase::NO_CACHING, 0); 9103 completeInitialization(); 9104 #endif 9105 } 9106 9107 QualcommCameraHardware::DispMemPool::~DispMemPool() 9108 { 9109 /* Not much to do in destructor for now */ 9110 ALOGV(" ~DispMemPool : E "); 9111 mFD = -1; 9112 ALOGV(" ~DispMemPool : X "); 9113 } 9114 status_t QualcommCameraHardware::setOrientation(const QCameraParameters& params) 9115 { 9116 const char *str = params.get("orientation"); 9117 9118 if (str != NULL) { 9119 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) { 9120 // Camera service needs this to decide if the preview frames and raw 9121 // pictures should be rotated. 9122 mParameters.set("orientation", str); 9123 } else { 9124 ALOGE("Invalid orientation value: %s", str); 9125 return BAD_VALUE; 9126 } 9127 } 9128 return NO_ERROR; 9129 } 9130 9131 status_t QualcommCameraHardware::setPictureFormat(const QCameraParameters& params) 9132 { 9133 const char * str = params.get(QCameraParameters::KEY_PICTURE_FORMAT); 9134 9135 if(str != NULL){ 9136 int32_t value = attr_lookup(picture_formats, 9137 sizeof(picture_formats) / sizeof(str_map), str); 9138 if(value != NOT_FOUND){ 9139 mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT, str); 9140 } else { 9141 ALOGE("Invalid Picture Format value: %s", str); 9142 return BAD_VALUE; 9143 } 9144 } 9145 return NO_ERROR; 9146 } 9147 9148 QualcommCameraHardware::MMCameraDL::MMCameraDL(){ 9149 ALOGV("MMCameraDL: E"); 9150 libmmcamera = NULL; 9151 #if DLOPEN_LIBMMCAMERA 9152 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW); 9153 #endif 9154 ALOGV("Open MM camera DL libeomcamera loaded at %p ", libmmcamera); 9155 ALOGV("MMCameraDL: X"); 9156 } 9157 9158 void * QualcommCameraHardware::MMCameraDL::pointer(){ 9159 return libmmcamera; 9160 } 9161 9162 QualcommCameraHardware::MMCameraDL::~MMCameraDL(){ 9163 ALOGV("~MMCameraDL: E"); 9164 LINK_mm_camera_destroy(); 9165 if (libmmcamera != NULL) { 9166 ::dlclose(libmmcamera); 9167 ALOGV("closed MM Camera DL "); 9168 } 9169 libmmcamera = NULL; 9170 ALOGV("~MMCameraDL: X"); 9171 } 9172 9173 wp<QualcommCameraHardware::MMCameraDL> QualcommCameraHardware::MMCameraDL::instance; 9174 Mutex QualcommCameraHardware::MMCameraDL::singletonLock; 9175 9176 9177 sp<QualcommCameraHardware::MMCameraDL> QualcommCameraHardware::MMCameraDL::getInstance(){ 9178 Mutex::Autolock instanceLock(singletonLock); 9179 sp<MMCameraDL> mmCamera = instance.promote(); 9180 if(mmCamera == NULL){ 9181 mmCamera = new MMCameraDL(); 9182 instance = mmCamera; 9183 } 9184 return mmCamera; 9185 } 9186 9187 QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers, 9188 int frame_size, 9189 const char *name) : 9190 mBufferSize(buffer_size), 9191 mNumBuffers(num_buffers), 9192 mFrameSize(frame_size), 9193 mBuffers(NULL), mName(name) 9194 { 9195 int page_size_minus_1 = getpagesize() - 1; 9196 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1); 9197 } 9198 9199 void QualcommCameraHardware::MemPool::completeInitialization() 9200 { 9201 // If we do not know how big the frame will be, we wait to allocate 9202 // the buffers describing the individual frames until we do know their 9203 // size. 9204 9205 if (mFrameSize > 0) { 9206 ALOGI("Before new Mem BASE #buffers :%d",mNumBuffers); 9207 mBuffers = new sp<MemoryBase>[mNumBuffers]; 9208 for (int i = 0; i < mNumBuffers; i++) { 9209 mBuffers[i] = new 9210 MemoryBase(mHeap, 9211 i * mAlignedBufferSize, 9212 mFrameSize); 9213 } 9214 } 9215 } 9216 9217 QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers, 9218 int frame_size, 9219 const char *name) : 9220 QualcommCameraHardware::MemPool(buffer_size, 9221 num_buffers, 9222 frame_size, 9223 name) 9224 { 9225 ALOGV("constructing MemPool %s backed by ashmem: " 9226 "%d frames @ %d uint8_ts, " 9227 "buffer size %d", 9228 mName, 9229 num_buffers, frame_size, buffer_size); 9230 9231 int page_mask = getpagesize() - 1; 9232 int ashmem_size = buffer_size * num_buffers; 9233 ashmem_size += page_mask; 9234 ashmem_size &= ~page_mask; 9235 9236 mHeap = new MemoryHeapBase(ashmem_size); 9237 9238 completeInitialization(); 9239 } 9240 9241 bool QualcommCameraHardware::register_record_buffers(bool register_buffer) { 9242 ALOGI("%s: (%d) E", __FUNCTION__, register_buffer); 9243 struct msm_pmem_info pmemBuf; 9244 #if 0 9245 for (int cnt = 0; cnt < kRecordBufferCount; ++cnt) { 9246 pmemBuf.type = MSM_PMEM_VIDEO; 9247 pmemBuf.fd = mRecordHeap->mHeap->getHeapID(); 9248 pmemBuf.offset = mRecordHeap->mAlignedBufferSize * cnt; 9249 pmemBuf.len = mRecordHeap->mBufferSize; 9250 pmemBuf.vaddr = (uint8_t *)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt; 9251 pmemBuf.planar0_off = 0; 9252 pmemBuf.planar1_off = recordframes[0].planar1_off; 9253 pmemBuf.planar2_off = 0; 9254 if(register_buffer == true) { 9255 pmemBuf.active = (cnt<ACTIVE_VIDEO_BUFFERS); 9256 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) { 9257 pmemBuf.type = MSM_PMEM_VIDEO_VPE; 9258 pmemBuf.active = 1; 9259 } 9260 } else { 9261 pmemBuf.active = false; 9262 } 9263 9264 ALOGV("register_buf: reg = %d buffer = %p", !register_buffer, 9265 (void *)pmemBuf.vaddr); 9266 if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER : 9267 CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) { 9268 ALOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM error %s", 9269 strerror(errno)); 9270 return false; 9271 } 9272 } 9273 #endif 9274 return true; 9275 } 9276 9277 QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool, 9278 int flags, 9279 int pmem_type, 9280 int buffer_size, int num_buffers, 9281 int frame_size, int cbcr_offset, 9282 int yOffset, const char *name) : 9283 QualcommCameraHardware::MemPool(buffer_size, 9284 num_buffers, 9285 frame_size, 9286 name), 9287 mPmemType(pmem_type), 9288 mCbCrOffset(cbcr_offset), 9289 myOffset(yOffset) 9290 { 9291 bool all_chnls = false; 9292 ALOGI("constructing MemPool %s backed by pmem pool %s: " 9293 "%d frames @ %d bytes, buffer size %d", 9294 mName, 9295 pmem_pool, num_buffers, frame_size, 9296 buffer_size); 9297 9298 mMMCameraDLRef = QualcommCameraHardware::MMCameraDL::getInstance(); 9299 9300 9301 // Make a new mmap'ed heap that can be shared across processes. 9302 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??) 9303 mAlignedSize = mAlignedBufferSize * num_buffers; 9304 9305 sp<MemoryHeapBase> masterHeap = 9306 new MemoryHeapBase(pmem_pool, mAlignedSize, flags); 9307 9308 if (masterHeap->getHeapID() < 0) { 9309 ALOGE("failed to construct master heap for pmem pool %s", pmem_pool); 9310 masterHeap.clear(); 9311 return; 9312 } 9313 9314 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags); 9315 if (pmemHeap->getHeapID() >= 0) { 9316 pmemHeap->slap(); 9317 masterHeap.clear(); 9318 mHeap = pmemHeap; 9319 pmemHeap.clear(); 9320 9321 mFd = mHeap->getHeapID(); 9322 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) { 9323 ALOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)", 9324 pmem_pool, 9325 ::strerror(errno), errno); 9326 mHeap.clear(); 9327 return; 9328 } 9329 9330 ALOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld", 9331 pmem_pool, 9332 mFd, 9333 mSize.len); 9334 ALOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize); 9335 // Unregister preview buffers with the camera drivers. Allow the VFE to write 9336 // to all preview buffers except for the last one. 9337 // Only Register the preview, snapshot and thumbnail buffers with the kernel. 9338 if( (strcmp("postview", mName) != 0) ){ 9339 int num_buf = num_buffers; 9340 if(!strcmp("preview", mName)) num_buf = kTotalPreviewBufferCount; 9341 ALOGD("num_buffers = %d", num_buf); 9342 for (int cnt = 0; cnt < num_buf; ++cnt) { 9343 int active = 1; 9344 if(pmem_type == MSM_PMEM_VIDEO){ 9345 active = (cnt<ACTIVE_VIDEO_BUFFERS); 9346 //When VPE is enabled, set the last record 9347 //buffer as active and pmem type as PMEM_VIDEO_VPE 9348 //as this is a requirement from VPE operation. 9349 //No need to set this pmem type to VIDEO_VPE while unregistering, 9350 //because as per camera stack design: "the VPE AXI is also configured 9351 //when VFE is configured for VIDEO, which is as part of preview 9352 //initialization/start. So during this VPE AXI config camera stack 9353 //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and 9354 //change it's type to PMEM_VIDEO". 9355 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) { 9356 active = 1; 9357 pmem_type = MSM_PMEM_VIDEO_VPE; 9358 } 9359 ALOGV(" pmempool creating video buffers : active %d ", active); 9360 } 9361 else if (pmem_type == MSM_PMEM_PREVIEW){ 9362 active = (cnt < ACTIVE_PREVIEW_BUFFERS); 9363 } 9364 else if ((pmem_type == MSM_PMEM_MAINIMG) 9365 || (pmem_type == MSM_PMEM_THUMBNAIL)){ 9366 active = (cnt < ACTIVE_ZSL_BUFFERS); 9367 } 9368 if (pmem_type == MSM_PMEM_PREVIEW && 9369 mPreviewFormat == CAMERA_YUV_420_YV12 && mCurrentTarget != TARGET_MSM7627A) 9370 all_chnls = true; 9371 9372 register_buf(mBufferSize, 9373 mFrameSize, mCbCrOffset, myOffset, 9374 mHeap->getHeapID(), 9375 mAlignedBufferSize * cnt, 9376 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, 9377 pmem_type, 9378 active,true, 9379 all_chnls); 9380 } 9381 } 9382 9383 completeInitialization(); 9384 } 9385 else ALOGE("pmem pool %s error: could not create master heap!", 9386 pmem_pool); 9387 ALOGV("%s: (%s) X ", __FUNCTION__, mName); 9388 } 9389 9390 QualcommCameraHardware::PmemPool::~PmemPool() 9391 { 9392 ALOGI("%s: %s E", __FUNCTION__, mName); 9393 if (mHeap != NULL) { 9394 // Unregister preview buffers with the camera drivers. 9395 // Only Unregister the preview, snapshot and thumbnail 9396 // buffers with the kernel. 9397 if( (strcmp("postview", mName) != 0) ){ 9398 int num_buffers = mNumBuffers; 9399 if(!strcmp("preview", mName)) num_buffers = kTotalPreviewBufferCount; 9400 for (int cnt = 0; cnt < num_buffers; ++cnt) { 9401 register_buf(mBufferSize, 9402 mFrameSize, 9403 mCbCrOffset, 9404 myOffset, 9405 mHeap->getHeapID(), 9406 mAlignedBufferSize * cnt, 9407 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, 9408 mPmemType, 9409 false, 9410 false,/* unregister */ 9411 false); 9412 } 9413 } 9414 } 9415 mMMCameraDLRef.clear(); 9416 ALOGI("%s: %s X", __FUNCTION__, mName); 9417 } 9418 #if 0 9419 #ifdef USE_ION 9420 const char QualcommCameraHardware::IonPool::mIonDevName[] = "/dev/ion"; 9421 QualcommCameraHardware::IonPool::IonPool(int ion_heap_id, int flags, 9422 int ion_type, 9423 int buffer_size, int num_buffers, 9424 int frame_size, int cbcr_offset, 9425 int yOffset, const char *name) : 9426 QualcommCameraHardware::MemPool(buffer_size, 9427 num_buffers, 9428 frame_size, 9429 name), 9430 mIonType(ion_type), 9431 mCbCrOffset(cbcr_offset), 9432 myOffset(yOffset) 9433 { 9434 ALOGI("constructing MemPool %s backed by pmem pool %s: " 9435 "%d frames @ %d bytes, buffer size %d", 9436 mName, 9437 mIonDevName, num_buffers, frame_size, 9438 buffer_size); 9439 9440 mMMCameraDLRef = QualcommCameraHardware::MMCameraDL::getInstance(); 9441 9442 9443 // Make a new mmap'ed heap that can be shared across processes. 9444 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??) 9445 mAlignedSize = mAlignedBufferSize * num_buffers; 9446 sp<MemoryHeapIon> ionHeap = new MemoryHeapIon(mIonDevName, mAlignedSize, 9447 flags, 0x1<<ion_heap_id); 9448 if (ionHeap->getHeapID() >= 0) { 9449 mHeap = ionHeap; 9450 ionHeap.clear(); 9451 9452 mFd = mHeap->getHeapID(); 9453 ALOGE("ion pool %s fd = %d", mIonDevName, mFd); 9454 ALOGE("mBufferSize=%d, mAlignedBufferSize=%d\n", 9455 mBufferSize, mAlignedBufferSize); 9456 9457 // Unregister preview buffers with the camera drivers. Allow the VFE to write 9458 // to all preview buffers except for the last one. 9459 // Only Register the preview, snapshot and thumbnail buffers with the kernel. 9460 if( (strcmp("postview", mName) != 0) ){ 9461 int num_buf = num_buffers; 9462 if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount; 9463 ALOGD("num_buffers = %d", num_buf); 9464 for (int cnt = 0; cnt < num_buf; ++cnt) { 9465 int active = 1; 9466 if(ion_type == MSM_PMEM_VIDEO){ 9467 active = (cnt<ACTIVE_VIDEO_BUFFERS); 9468 //When VPE is enabled, set the last record 9469 //buffer as active and pmem type as PMEM_VIDEO_VPE 9470 //as this is a requirement from VPE operation. 9471 //No need to set this pmem type to VIDEO_VPE while unregistering, 9472 //because as per camera stack design: "the VPE AXI is also configured 9473 //when VFE is configured for VIDEO, which is as part of preview 9474 //initialization/start. So during this VPE AXI config camera stack 9475 //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and 9476 //change it's type to PMEM_VIDEO". 9477 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) { 9478 active = 1; 9479 ion_type = MSM_PMEM_VIDEO_VPE; 9480 } 9481 ALOGV(" pmempool creating video buffers : active %d ", active); 9482 } 9483 else if (ion_type == MSM_PMEM_PREVIEW){ 9484 active = (cnt < ACTIVE_PREVIEW_BUFFERS); 9485 } 9486 else if ((ion_type == MSM_PMEM_MAINIMG) 9487 || (ion_type == MSM_PMEM_THUMBNAIL)){ 9488 active = (cnt < ACTIVE_ZSL_BUFFERS); 9489 } 9490 register_buf(mBufferSize, 9491 mFrameSize, mCbCrOffset, myOffset, 9492 mHeap->getHeapID(), 9493 mAlignedBufferSize * cnt, 9494 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, 9495 ion_type, 9496 active); 9497 } 9498 } 9499 9500 completeInitialization(); 9501 } 9502 else ALOGE("pmem pool %s error: could not create master heap!", 9503 mIonDevName); 9504 ALOGI("%s: (%s) X ", __FUNCTION__, mName); 9505 } 9506 9507 QualcommCameraHardware::IonPool::~IonPool() 9508 { 9509 ALOGI("%s: %s E", __FUNCTION__, mName); 9510 if (mHeap != NULL) { 9511 // Unregister preview buffers with the camera drivers. 9512 // Only Unregister the preview, snapshot and thumbnail 9513 // buffers with the kernel. 9514 if( (strcmp("postview", mName) != 0) ){ 9515 int num_buffers = mNumBuffers; 9516 if(!strcmp("preview", mName)) num_buffers = kPreviewBufferCount; 9517 for (int cnt = 0; cnt < num_buffers; ++cnt) { 9518 register_buf(mBufferSize, 9519 mFrameSize, 9520 mCbCrOffset, 9521 myOffset, 9522 mHeap->getHeapID(), 9523 mAlignedBufferSize * cnt, 9524 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt, 9525 mIonType, 9526 false, 9527 false /* unregister */); 9528 } 9529 } 9530 } 9531 mMMCameraDLRef.clear(); 9532 ALOGI("%s: %s X", __FUNCTION__, mName); 9533 } 9534 #endif 9535 #endif 9536 QualcommCameraHardware::MemPool::~MemPool() 9537 { 9538 ALOGV("destroying MemPool %s", mName); 9539 if (mFrameSize > 0) 9540 delete [] mBuffers; 9541 mHeap.clear(); 9542 ALOGV("destroying MemPool %s completed", mName); 9543 } 9544 9545 status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const 9546 { 9547 const size_t SIZE = 256; 9548 char buffer[SIZE]; 9549 String8 result; 9550 CAMERA_HAL_UNUSED(args); 9551 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n"); 9552 result.append(buffer); 9553 if (mName) { 9554 snprintf(buffer, 255, "mem pool name (%s)\n", mName); 9555 result.append(buffer); 9556 } 9557 if (mHeap != 0) { 9558 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n", 9559 mHeap->getBase(), mHeap->getSize(), 9560 mHeap->getFlags(), mHeap->getDevice()); 9561 result.append(buffer); 9562 } 9563 snprintf(buffer, 255, 9564 "buffer size (%d), number of buffers (%d), frame size(%d)", 9565 mBufferSize, mNumBuffers, mFrameSize); 9566 result.append(buffer); 9567 write(fd, result.string(), result.size()); 9568 return NO_ERROR; 9569 } 9570 9571 static void receive_camframe_callback(struct msm_frame *frame) 9572 { 9573 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9574 if (obj != 0) { 9575 obj->receivePreviewFrame(frame); 9576 } 9577 } 9578 9579 static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo) 9580 { 9581 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9582 if (obj != 0) { 9583 obj->receiveCameraStats(stype,histinfo); 9584 } 9585 } 9586 9587 static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size) 9588 { 9589 if(status == LIVESHOT_SUCCESS) { 9590 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9591 if (obj != 0) { 9592 obj->receiveLiveSnapshot(jpeg_size); 9593 } 9594 } 9595 else 9596 ALOGE("Liveshot not succesful"); 9597 } 9598 9599 9600 static int8_t receive_event_callback(mm_camera_event* event) 9601 { 9602 ALOGV("%s: E", __FUNCTION__); 9603 if(event == NULL) { 9604 ALOGE("%s: event is NULL!", __FUNCTION__); 9605 return FALSE; 9606 } 9607 switch(event->event_type) { 9608 case SNAPSHOT_DONE: 9609 { 9610 /* postview buffer is received */ 9611 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9612 if (obj != 0) { 9613 9614 obj->receiveRawPicture(NO_ERROR, event->event_data.yuv_frames[0], event->event_data.yuv_frames[0]); 9615 } 9616 } 9617 break; 9618 case SNAPSHOT_FAILED: 9619 { 9620 /* postview buffer is received */ 9621 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9622 if (obj != 0) { 9623 9624 obj->receiveRawPicture(UNKNOWN_ERROR, NULL, NULL); 9625 } 9626 } 9627 break; 9628 case JPEG_ENC_DONE: 9629 { 9630 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9631 if (obj != 0) { 9632 obj->receiveJpegPicture(NO_ERROR, event->event_data.encoded_frame); 9633 } 9634 } 9635 break; 9636 case JPEG_ENC_FAILED: 9637 { 9638 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9639 if (obj != 0) { 9640 obj->receiveJpegPicture(UNKNOWN_ERROR, 0); 9641 } 9642 } 9643 break; 9644 default: 9645 ALOGE("%s: ignore default case", __FUNCTION__); 9646 } 9647 return TRUE; 9648 ALOGV("%s: X", __FUNCTION__); 9649 } 9650 // 720p : video frame calbback from camframe 9651 static void receive_camframe_video_callback(struct msm_frame *frame) 9652 { 9653 ALOGV("receive_camframe_video_callback E"); 9654 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9655 if (obj != 0) { 9656 obj->receiveRecordingFrame(frame); 9657 } 9658 ALOGV("receive_camframe_video_callback X"); 9659 } 9660 9661 9662 int QualcommCameraHardware::storeMetaDataInBuffers(int enable) 9663 { 9664 /* this is a dummy func now. fix me later */ 9665 ALOGI("in storeMetaDataInBuffers : enable %d", enable); 9666 mStoreMetaDataInFrame = enable; 9667 return 0; 9668 } 9669 9670 void QualcommCameraHardware::setCallbacks(camera_notify_callback notify_cb, 9671 camera_data_callback data_cb, 9672 camera_data_timestamp_callback data_cb_timestamp, 9673 camera_request_memory get_memory, 9674 void* user) 9675 { 9676 Mutex::Autolock lock(mLock); 9677 mNotifyCallback = notify_cb; 9678 mDataCallback = data_cb; 9679 mDataCallbackTimestamp = data_cb_timestamp; 9680 mGetMemory = get_memory; 9681 mCallbackCookie = user; 9682 } 9683 int32_t QualcommCameraHardware::getNumberOfVideoBuffers() { 9684 ALOGI("getNumOfVideoBuffers: %d", kRecordBufferCount); 9685 return kRecordBufferCount; 9686 } 9687 9688 sp<IMemory> QualcommCameraHardware::getVideoBuffer(int32_t index) { 9689 if(index > kRecordBufferCount) 9690 return NULL; 9691 else 9692 return NULL; 9693 #if 0 9694 return mRecordHeap->mBuffers[index]; 9695 #endif 9696 } 9697 void QualcommCameraHardware::enableMsgType(int32_t msgType) 9698 { 9699 Mutex::Autolock lock(mLock); 9700 mMsgEnabled |= msgType; 9701 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) { 9702 if(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME){ 9703 native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL); 9704 mRecordingState = 1; 9705 } 9706 } 9707 } 9708 9709 void QualcommCameraHardware::disableMsgType(int32_t msgType) 9710 { 9711 Mutex::Autolock lock(mLock); 9712 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) { 9713 if(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME){ 9714 native_stop_ops(CAMERA_OPS_VIDEO_RECORDING, NULL); 9715 mRecordingState = 0; 9716 } 9717 } 9718 mMsgEnabled &= ~msgType; 9719 } 9720 9721 bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType) 9722 { 9723 return (mMsgEnabled & msgType); 9724 } 9725 9726 9727 void QualcommCameraHardware::receive_camframe_error_timeout(void) { 9728 ALOGI("receive_camframe_error_timeout: E"); 9729 Mutex::Autolock l(&mCamframeTimeoutLock); 9730 ALOGE(" Camframe timed out. Not receiving any frames from camera driver "); 9731 camframe_timeout_flag = TRUE; 9732 mNotifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_UNKNOWN, 0, 9733 mCallbackCookie); 9734 ALOGI("receive_camframe_error_timeout: X"); 9735 } 9736 9737 static void receive_camframe_error_callback(camera_error_type err) { 9738 QualcommCameraHardware* obj = QualcommCameraHardware::getInstance(); 9739 if (obj != 0) { 9740 if ((err == CAMERA_ERROR_TIMEOUT) || 9741 (err == CAMERA_ERROR_ESD)) { 9742 /* Handling different error types is dependent on the requirement. 9743 * Do the same action by default 9744 */ 9745 obj->receive_camframe_error_timeout(); 9746 } 9747 } 9748 } 9749 9750 bool QualcommCameraHardware::storePreviewFrameForPostview(void) { 9751 ALOGV("storePreviewFrameForPostview : E "); 9752 9753 /* Since there is restriction on the maximum overlay dimensions 9754 * that can be created, we use the last preview frame as postview 9755 * for 7x30. */ 9756 ALOGV("Copying the preview buffer to postview buffer %d ", 9757 mPreviewFrameSize); 9758 if(mLastPreviewFrameHeap == NULL) { 9759 int CbCrOffset = PAD_TO_WORD(mPreviewFrameSize * 2/3); 9760 #if 0 9761 #ifdef USE_ION 9762 9763 mLastPreviewFrameHeap = 9764 new IonPool(ION_HEAP_ADSP_ID, 9765 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 9766 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2, 9767 mPreviewFrameSize, 9768 1, 9769 mPreviewFrameSize, 9770 CbCrOffset, 9771 0, 9772 "postview"); 9773 #else 9774 mLastPreviewFrameHeap = 9775 new PmemPool("/dev/pmem_adsp", 9776 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING, 9777 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2, 9778 mPreviewFrameSize, 9779 1, 9780 mPreviewFrameSize, 9781 CbCrOffset, 9782 0, 9783 "postview"); 9784 #endif 9785 if (!mLastPreviewFrameHeap->initialized()) { 9786 mLastPreviewFrameHeap.clear(); 9787 ALOGE(" Failed to initialize Postview Heap"); 9788 return false; 9789 } 9790 #endif 9791 } 9792 #if 0 9793 if( mLastPreviewFrameHeap != NULL && mLastQueuedFrame != NULL) { 9794 memcpy(mLastPreviewFrameHeap->mHeap->base(), 9795 (uint8_t *)mLastQueuedFrame, mPreviewFrameSize ); 9796 9797 if(mUseOverlay && !mZslPanorama) { 9798 //mOverlayLock.lock(); 9799 //if(mOverlay != NULL){ 9800 //mOverlay->setFd(mLastPreviewFrameHeap->mHeap->getHeapID()); 9801 if( zoomCropInfo.w !=0 && zoomCropInfo.h !=0) { 9802 ALOGE("zoomCropInfo non-zero, setting crop "); 9803 ALOGE("setCrop with %dx%d and %dx%d", zoomCropInfo.x, zoomCropInfo.y, zoomCropInfo.w, zoomCropInfo.h); 9804 // mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y, 9805 //zoomCropInfo.w, zoomCropInfo.h); 9806 } 9807 ALOGV("Queueing Postview with last frame till the snapshot is done "); 9808 //mOverlay->queueBuffer((void *)0); 9809 } 9810 //mOverlayLock.unlock(); 9811 } 9812 9813 } else 9814 ALOGE("Failed to store Preview frame. No Postview "); 9815 #endif 9816 ALOGV("storePreviewFrameForPostview : X "); 9817 return true; 9818 } 9819 9820 bool QualcommCameraHardware::isValidDimension(int width, int height) { 9821 bool retVal = FALSE; 9822 /* This function checks if a given resolution is valid or not. 9823 * A particular resolution is considered valid if it satisfies 9824 * the following conditions: 9825 * 1. width & height should be multiple of 16. 9826 * 2. width & height should be less than/equal to the dimensions 9827 * supported by the camera sensor. 9828 * 3. the aspect ratio is a valid aspect ratio and is among the 9829 * commonly used aspect ratio as determined by the thumbnail_sizes 9830 * data structure. 9831 */ 9832 9833 if( (width == CEILING16(width)) && (height == CEILING16(height)) 9834 && (width <= maxSnapshotWidth) 9835 && (height <= maxSnapshotHeight) ) 9836 { 9837 uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height); 9838 for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) { 9839 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) { 9840 retVal = TRUE; 9841 break; 9842 } 9843 } 9844 } 9845 return retVal; 9846 } 9847 status_t QualcommCameraHardware::getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize) { 9848 status_t ret; 9849 ALOGV(" getBufferInfo : E "); 9850 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660) ) 9851 { 9852 if( mRecordHeap != NULL){ 9853 ALOGV(" Setting valid buffer information "); 9854 Frame = mRecordHeap->mBuffers[0]; 9855 if( alignedSize != NULL) { 9856 *alignedSize = mRecordHeap->mAlignedBufferSize; 9857 ALOGV(" HAL : alignedSize = %d ", *alignedSize); 9858 ret = NO_ERROR; 9859 } else { 9860 ALOGE(" HAL : alignedSize is NULL. Cannot update alignedSize "); 9861 ret = UNKNOWN_ERROR; 9862 } 9863 } else { 9864 ALOGE(" RecordHeap is null. Buffer information wont be updated "); 9865 Frame = NULL; 9866 ret = UNKNOWN_ERROR; 9867 } 9868 } else { 9869 if(mPreviewHeap != NULL) { 9870 ALOGV(" Setting valid buffer information "); 9871 // Frame = mPreviewHeap->mBuffers[0]; 9872 if( alignedSize != NULL) { 9873 //*alignedSize = mPreviewHeap->mAlignedBufferSize; 9874 ALOGV(" HAL : alignedSize = %d ", *alignedSize); 9875 ret = NO_ERROR; 9876 } else { 9877 ALOGE(" HAL : alignedSize is NULL. Cannot update alignedSize "); 9878 ret = UNKNOWN_ERROR; 9879 } 9880 } else { 9881 ALOGE(" PreviewHeap is null. Buffer information wont be updated "); 9882 Frame = NULL; 9883 ret = UNKNOWN_ERROR; 9884 } 9885 } 9886 ALOGV(" getBufferInfo : X "); 9887 return ret; 9888 } 9889 9890 void QualcommCameraHardware::encodeData() { 9891 ALOGV("encodeData: E"); 9892 9893 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) { 9894 mJpegThreadWaitLock.lock(); 9895 mJpegThreadRunning = true; 9896 mJpegThreadWaitLock.unlock(); 9897 mm_camera_ops_type_t current_ops_type = CAMERA_OPS_ENCODE; 9898 mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms, 9899 (void *)&mImageEncodeParms); 9900 //Wait until jpeg encoding is done and clear the resources. 9901 mJpegThreadWaitLock.lock(); 9902 while (mJpegThreadRunning) { 9903 ALOGV("encodeData: waiting for jpeg thread to complete."); 9904 mJpegThreadWait.wait(mJpegThreadWaitLock); 9905 ALOGV("encodeData: jpeg thread completed."); 9906 } 9907 mJpegThreadWaitLock.unlock(); 9908 } 9909 else ALOGV("encodeData: JPEG callback is NULL, not encoding image."); 9910 9911 mCamOps.mm_camera_deinit(CAMERA_OPS_CAPTURE, NULL, NULL); 9912 //clear the resources 9913 deinitRaw(); 9914 //Encoding is done. 9915 mEncodePendingWaitLock.lock(); 9916 mEncodePending = false; 9917 mEncodePendingWait.signal(); 9918 mEncodePendingWaitLock.unlock(); 9919 9920 ALOGV("encodeData: X"); 9921 } 9922 9923 void QualcommCameraHardware::getCameraInfo() 9924 { 9925 ALOGI("getCameraInfo: IN"); 9926 mm_camera_status_t status; 9927 9928 #if DLOPEN_LIBMMCAMERA 9929 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW); 9930 ALOGI("getCameraInfo: loading libqcamera at %p", libhandle); 9931 if (!libhandle) { 9932 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror()); 9933 } 9934 *(void **)&LINK_mm_camera_get_camera_info = 9935 ::dlsym(libhandle, "mm_camera_get_camera_info"); 9936 #endif 9937 storeTargetType(); 9938 status = LINK_mm_camera_get_camera_info(HAL_cameraInfo, &HAL_numOfCameras); 9939 ALOGI("getCameraInfo: numOfCameras = %d", HAL_numOfCameras); 9940 for(int i = 0; i < HAL_numOfCameras; i++) { 9941 if((HAL_cameraInfo[i].position == BACK_CAMERA )&& 9942 mCurrentTarget == TARGET_MSM8660){ 9943 HAL_cameraInfo[i].modes_supported |= CAMERA_ZSL_MODE; 9944 } else{ 9945 HAL_cameraInfo[i].modes_supported |= CAMERA_NONZSL_MODE; 9946 } 9947 ALOGI("Camera sensor %d info:", i); 9948 ALOGI("camera_id: %d", HAL_cameraInfo[i].camera_id); 9949 ALOGI("modes_supported: %x", HAL_cameraInfo[i].modes_supported); 9950 ALOGI("position: %d", HAL_cameraInfo[i].position); 9951 ALOGI("sensor_mount_angle: %d", HAL_cameraInfo[i].sensor_mount_angle); 9952 } 9953 9954 #if DLOPEN_LIBMMCAMERA 9955 if (libhandle) { 9956 ::dlclose(libhandle); 9957 ALOGV("getCameraInfo: dlclose(libqcamera)"); 9958 } 9959 #endif 9960 ALOGI("getCameraInfo: OUT"); 9961 } 9962 9963 extern "C" int HAL_isIn3DMode() 9964 { 9965 return HAL_currentCameraMode == CAMERA_MODE_3D; 9966 } 9967 9968 extern "C" int HAL_getNumberOfCameras() 9969 { 9970 QualcommCameraHardware::getCameraInfo(); 9971 return HAL_numOfCameras; 9972 } 9973 9974 extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) 9975 { 9976 int i; 9977 char mDeviceName[PROPERTY_VALUE_MAX]; 9978 if(cameraInfo == NULL) { 9979 ALOGE("cameraInfo is NULL"); 9980 return; 9981 } 9982 9983 property_get("ro.board.platform",mDeviceName," "); 9984 9985 for(i = 0; i < HAL_numOfCameras; i++) { 9986 if(i == cameraId) { 9987 ALOGI("Found a matching camera info for ID %d", cameraId); 9988 cameraInfo->facing = (HAL_cameraInfo[i].position == BACK_CAMERA)? 9989 CAMERA_FACING_BACK : CAMERA_FACING_FRONT; 9990 // App Orientation not needed for 7x27 , sensor mount angle 0 is 9991 // enough. 9992 if(cameraInfo->facing == CAMERA_FACING_FRONT) 9993 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle; 9994 else if( !strncmp(mDeviceName, "msm7625a", 8)) 9995 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle; 9996 else if( !strncmp(mDeviceName, "msm7627a", 8)) 9997 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle; 9998 else if( !strncmp(mDeviceName, "msm7627", 7)) 9999 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle; 10000 else if( !strncmp(mDeviceName, "msm8660", 7)) 10001 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle; 10002 else 10003 cameraInfo->orientation = ((APP_ORIENTATION - HAL_cameraInfo[i].sensor_mount_angle) + 360)%360; 10004 10005 ALOGI("%s: orientation = %d", __FUNCTION__, cameraInfo->orientation); 10006 sensor_rotation = HAL_cameraInfo[i].sensor_mount_angle; 10007 cameraInfo->mode = 0; 10008 if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_2D) 10009 cameraInfo->mode |= CAMERA_SUPPORT_MODE_2D; 10010 if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_3D) 10011 cameraInfo->mode |= CAMERA_SUPPORT_MODE_3D; 10012 if((HAL_cameraInfo[i].position == BACK_CAMERA )&& 10013 !strncmp(mDeviceName, "msm8660", 7)){ 10014 cameraInfo->mode |= CAMERA_ZSL_MODE; 10015 } else{ 10016 cameraInfo->mode |= CAMERA_NONZSL_MODE; 10017 } 10018 10019 ALOGI("%s: modes supported = %d", __FUNCTION__, cameraInfo->mode); 10020 10021 return; 10022 } 10023 } 10024 // ALOGE("Unable to find matching camera info for ID %d", cameraId); 10025 } 10026 10027 }; // namespace android 10028