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