blob: b7077eba3bfe6a104357acb35624947c68599492 [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
2**
3** Copyright 2008, The Android Open Source Project
4** Copyright 2010, Samsung Electronics Co. LTD
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*/
Daniel Hillenbrand353fecb2012-07-22 16:14:08 +020018//#define LOG_NDEBUG 0
19#define LOG_TAG "CameraHardwareSec"
codeworkx62f02ba2012-05-20 12:00:36 +020020#include <utils/Log.h>
21
22#include "SecCameraHWInterface.h"
23#include <utils/threads.h>
24#include <fcntl.h>
25#include <sys/mman.h>
26#include <camera/Camera.h>
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020027#include <media/hardware/MetadataBufferType.h>
codeworkx62f02ba2012-05-20 12:00:36 +020028
29#define VIDEO_COMMENT_MARKER_H 0xFFBE
30#define VIDEO_COMMENT_MARKER_L 0xFFBF
31#define VIDEO_COMMENT_MARKER_LENGTH 4
32#define JPEG_EOI_MARKER 0xFFD9
33#define HIBYTE(x) (((x) >> 8) & 0xFF)
34#define LOBYTE(x) ((x) & 0xFF)
35
36#define BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR "0.10,1.20,Infinity"
37#define BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR "0.10,0.20,Infinity"
38#define BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR "0.10,1.20,Infinity"
39#define FRONT_CAMERA_FOCUS_DISTANCES_STR "0.20,0.25,Infinity"
40#define USE_EGL
41
42// This hack does two things:
43// -- it sets preview to NV21 (YUV420SP)
44// -- it sets gralloc to YV12
45//
46// The reason being: the samsung encoder understands only yuv420sp, and gralloc
47// does yv12 and rgb565. So what we do is we break up the interleaved UV in
48// separate V and U planes, which makes preview look good, and enabled the
49// encoder as well.
50//
51// FIXME: Samsung needs to enable support for proper yv12 coming out of the
52// camera, and to fix their video encoder to work with yv12.
53// FIXME: It also seems like either Samsung's YUV420SP (NV21) or img's YV12 has
54// the color planes switched. We need to figure which side is doing it
55// wrong and have the respective party fix it.
56
57namespace android {
58
59struct addrs {
60 uint32_t type; // make sure that this is 4 byte.
61 unsigned int addr_y;
62 unsigned int addr_cbcr;
63 unsigned int buf_index;
64 unsigned int reserved;
65};
66
67struct addrs_cap {
68 unsigned int addr_y;
69 unsigned int width;
70 unsigned int height;
71};
72
73static const int INITIAL_SKIP_FRAME = 3;
74static const int EFFECT_SKIP_FRAME = 1;
75
76gralloc_module_t const* CameraHardwareSec::mGrallocHal;
77
78CameraHardwareSec::CameraHardwareSec(int cameraId, camera_device_t *dev)
79 :
80 mCaptureInProgress(false),
81 mParameters(),
82 mFrameSizeDelta(0),
83 mCameraSensorName(NULL),
84 mUseInternalISP(false),
85 mSkipFrame(0),
86 mNotifyCb(0),
87 mDataCb(0),
88 mDataCbTimestamp(0),
89 mCallbackCookie(0),
90 mMsgEnabled(CAMERA_MSG_RAW_IMAGE),
91 mRecordRunning(false),
92 mPostViewWidth(0),
93 mPostViewHeight(0),
94 mPostViewSize(0),
95 mCapIndex(0),
96 mRecordHint(false),
97 mTouched(0),
98 mHalDevice(dev)
99{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200100 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200101 memset(&mCapBuffer, 0, sizeof(struct SecBuffer));
102 int ret = 0;
103
104 mPreviewWindow = NULL;
105 mSecCamera = SecCamera::createInstance();
106
107 mRawHeap = NULL;
108 mPreviewHeap = NULL;
109 for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++)
110 mRecordHeap[i] = NULL;
111
112 if (!mGrallocHal) {
113 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal);
114 if (ret)
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200115 ALOGE("ERR(%s):Fail on loading gralloc HAL", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200116 }
117
118 ret = mSecCamera->CreateCamera(cameraId);
119 if (ret < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200120 ALOGE("ERR(%s):Fail on mSecCamera init", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200121 mSecCamera->DestroyCamera();
122 }
123
124 initDefaultParameters(cameraId);
125
126 mExitAutoFocusThread = false;
127 mExitPreviewThread = false;
128 /* whether the PreviewThread is active in preview or stopped. we
129 * create the thread but it is initially in stopped state.
130 */
131 mPreviewRunning = false;
132 mPreviewStartDeferred = false;
133 mPreviewThread = new PreviewThread(this);
134 mAutoFocusThread = new AutoFocusThread(this);
135 mPictureThread = new PictureThread(this);
136}
137
138int CameraHardwareSec::getCameraId() const
139{
140 return mSecCamera->getCameraId();
141}
142
143void CameraHardwareSec::initDefaultParameters(int cameraId)
144{
145 if (mSecCamera == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200146 ALOGE("ERR(%s):mSecCamera object is NULL", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200147 return;
148 }
149
150 CameraParameters p;
151 CameraParameters ip;
152
153 mCameraSensorName = mSecCamera->getCameraSensorName();
154 if (mCameraSensorName == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200155 ALOGE("ERR(%s):mCameraSensorName is NULL", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200156 return;
157 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200158 ALOGV("CameraSensorName: %s", mCameraSensorName);
codeworkx62f02ba2012-05-20 12:00:36 +0200159
160 int preview_max_width = 0;
161 int preview_max_height = 0;
162 int snapshot_max_width = 0;
163 int snapshot_max_height = 0;
164
165 mCameraID = cameraId;
166 mUseInternalISP = mSecCamera->getUseInternalISP();
167
168 if (cameraId == SecCamera::CAMERA_ID_BACK) {
169 if (mUseInternalISP) {
170 //3H2
171 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
172 "720x480,640x384,640x360,640x480,320x240,528x432,176x144");
173 p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
174 "3248x2436,3216x2144,3200x1920,3072x1728,2592x1944,1920x1080,1440x1080,1280x720,1232x1008,800x480,720x480,640x480");
175 p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
176 "1920x1080,1280x720,640x480,176x144");
177 } else {
178 //M5MO
179 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
180 "3264x2448,1920x1080,1280x720,800x480,720x480,640x480,320x240,528x432,176x144");
181 p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
182 "3264x2448,3264x1968,2048x1536,2048x1232,800x480,640x480");
183 }
184 } else {
185 if (mUseInternalISP) {
186 //6A3
187 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
188 "640x480,640x360,480x480,352x288,320x240,176x144");
189 p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
190 "1392x1392,1280x960,1280x720,880x720,640x480");
191 p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
192 "1280x720,640x480,176x144");
193 }
194 }
195
196 p.getSupportedPreviewSizes(mSupportedPreviewSizes);
197
198 String8 parameterString;
199
200 // If these fail, then we are using an invalid cameraId and we'll leave the
201 // sizes at zero to catch the error.
202 if (mSecCamera->getPreviewMaxSize(&preview_max_width,
203 &preview_max_height) < 0)
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200204 ALOGE("getPreviewMaxSize fail (%d / %d)",
codeworkx62f02ba2012-05-20 12:00:36 +0200205 preview_max_width, preview_max_height);
206 if (mSecCamera->getSnapshotMaxSize(&snapshot_max_width,
207 &snapshot_max_height) < 0)
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200208 ALOGE("getSnapshotMaxSize fail (%d / %d)",
codeworkx62f02ba2012-05-20 12:00:36 +0200209 snapshot_max_width, snapshot_max_height);
210
211 parameterString = CameraParameters::PIXEL_FORMAT_YUV420P;
212 parameterString.append(",");
213 parameterString.append(CameraParameters::PIXEL_FORMAT_YUV420SP);
214 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, parameterString);
215 p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420P);
216 mFrameSizeDelta = 16;
217 p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420SP);
218 p.setPreviewSize(preview_max_width, preview_max_height);
219
220 p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
221 p.setPictureSize(snapshot_max_width, snapshot_max_height);
222 p.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // maximum quality
223 p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
224 CameraParameters::PIXEL_FORMAT_JPEG);
225
226 p.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1280x720");
227
228#ifdef USE_FACE_DETECTION
229 if (mUseInternalISP) {
230 p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "5");
231 } else {
232 p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "0");
233 }
234#endif
235
236 if (cameraId == SecCamera::CAMERA_ID_BACK) {
237 parameterString = CameraParameters::FOCUS_MODE_AUTO;
238 /* TODO : sensor will be support this mode */
239 //parameterString.append(",");
240 //parameterString.append(CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO);
241 if (mUseInternalISP) {
242 parameterString.append(",");
243 parameterString.append(CameraParameters::FOCUS_MODE_INFINITY);
244 parameterString.append(",");
245 parameterString.append(CameraParameters::FOCUS_MODE_MACRO);
246 parameterString.append(",");
247 parameterString.append(CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE);
248 }
249 p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
250 parameterString.string());
251 p.set(CameraParameters::KEY_FOCUS_MODE,
252 CameraParameters::FOCUS_MODE_AUTO);
253 p.set(CameraParameters::KEY_FOCUS_DISTANCES,
254 BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR);
255#ifdef USE_TOUCH_AF
256 if (mUseInternalISP)
257 p.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
258#endif
259 p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
260 "320x240,0x0");
261 p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320");
262 p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240");
263 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30");
264 p.setPreviewFrameRate(30);
265 } else {
266 p.set(CameraParameters::KEY_FOCUS_MODE, NULL);
267 p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
268 "160x120,0x0");
269 p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "160");
270 p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "120");
271 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
272 "7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,50,60");
273 p.setPreviewFrameRate(30);
274 }
275
276 parameterString = CameraParameters::EFFECT_NONE;
277 parameterString.append(",");
278 parameterString.append(CameraParameters::EFFECT_MONO);
279 parameterString.append(",");
280 parameterString.append(CameraParameters::EFFECT_NEGATIVE);
281 parameterString.append(",");
282 parameterString.append(CameraParameters::EFFECT_SEPIA);
283 p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, parameterString.string());
284
285 if (cameraId == SecCamera::CAMERA_ID_BACK) {
286 parameterString = CameraParameters::FLASH_MODE_ON;
287 parameterString.append(",");
288 parameterString.append(CameraParameters::FLASH_MODE_OFF);
289 parameterString.append(",");
290 parameterString.append(CameraParameters::FLASH_MODE_AUTO);
291 parameterString.append(",");
292 parameterString.append(CameraParameters::FLASH_MODE_TORCH);
293 p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
294 parameterString.string());
295 p.set(CameraParameters::KEY_FLASH_MODE,
296 CameraParameters::FLASH_MODE_OFF);
297
298 /* we have two ranges, 4-30fps for night mode and
299 * 15-30fps for all others
300 */
301 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)");
302 p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000");
303
304 p.set(CameraParameters::KEY_FOCAL_LENGTH, "3.43");
305 } else {
306 p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(7500,30000)");
307 p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "7500,30000");
308
309 p.set(CameraParameters::KEY_FOCAL_LENGTH, "0.9");
310 }
311 parameterString = CameraParameters::SCENE_MODE_AUTO;
312 parameterString.append(",");
313 parameterString.append(CameraParameters::SCENE_MODE_PORTRAIT);
314 parameterString.append(",");
315 parameterString.append(CameraParameters::SCENE_MODE_LANDSCAPE);
316 parameterString.append(",");
317 parameterString.append(CameraParameters::SCENE_MODE_BEACH);
318 parameterString.append(",");
319 parameterString.append(CameraParameters::SCENE_MODE_SNOW);
320 parameterString.append(",");
321 parameterString.append(CameraParameters::SCENE_MODE_FIREWORKS);
322 parameterString.append(",");
323 parameterString.append(CameraParameters::SCENE_MODE_SPORTS);
324 parameterString.append(",");
325 parameterString.append(CameraParameters::SCENE_MODE_PARTY);
326 parameterString.append(",");
327 parameterString.append(CameraParameters::SCENE_MODE_CANDLELIGHT);
328 parameterString.append(",");
329 parameterString.append(CameraParameters::SCENE_MODE_NIGHT);
330 parameterString.append(",");
331 parameterString.append(CameraParameters::SCENE_MODE_SUNSET);
332 p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
333 parameterString.string());
334 p.set(CameraParameters::KEY_SCENE_MODE,
335 CameraParameters::SCENE_MODE_AUTO);
336
337 parameterString = CameraParameters::WHITE_BALANCE_AUTO;
338 parameterString.append(",");
339 parameterString.append(CameraParameters::WHITE_BALANCE_INCANDESCENT);
340 parameterString.append(",");
341 parameterString.append(CameraParameters::WHITE_BALANCE_FLUORESCENT);
342 parameterString.append(",");
343 parameterString.append(CameraParameters::WHITE_BALANCE_DAYLIGHT);
344 parameterString.append(",");
345 parameterString.append(CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT);
346 p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
347 parameterString.string());
348
349 p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "100");
350
351 p.set(CameraParameters::KEY_ROTATION, 0);
352 p.set(CameraParameters::KEY_WHITE_BALANCE, CameraParameters::WHITE_BALANCE_AUTO);
353
354 p.set(CameraParameters::KEY_EFFECT, CameraParameters::EFFECT_NONE);
355
356 p.set("contrast", 0);
357 p.set("iso", "auto");
358 p.set("metering", "center");
359 p.set("wdr", 0);
360
361 ip.set("chk_dataline", 0);
362 if (cameraId == SecCamera::CAMERA_ID_FRONT) {
363 ip.set("vtmode", 0);
364 ip.set("blur", 0);
365 }
366
367 p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "51.2");
368 p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "39.4");
369
370 p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
371 p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "4");
372 p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-4");
373 p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "1");
374
375 p.set("brightness", 0);
376 p.set("brightness-max", 2);
377 p.set("brightness-min", -2);
378
379 p.set("saturation", 0);
380 p.set("saturation-max", 2);
381 p.set("saturation-min", -2);
382
383 p.set("sharpness", 0);
384 p.set("sharpness-max", 2);
385 p.set("sharpness-min", -2);
386
387 p.set("hue", 0);
388 p.set("hue-max", 2);
389 p.set("hue-min", -2);
390
391 parameterString = CameraParameters::ANTIBANDING_AUTO;
392 parameterString.append(",");
393 parameterString.append(CameraParameters::ANTIBANDING_50HZ);
394 parameterString.append(",");
395 parameterString.append(CameraParameters::ANTIBANDING_60HZ);
396 parameterString.append(",");
397 parameterString.append(CameraParameters::ANTIBANDING_OFF);
398 p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
399 parameterString.string());
400
401 p.set(CameraParameters::KEY_ANTIBANDING, CameraParameters::ANTIBANDING_OFF);
402
403 if (mUseInternalISP) {
404 p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true");
405 p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, "false");
406 }
407
408 if (mUseInternalISP) {
409 p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true");
410 p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, "false");
411 }
412
413 p.set(CameraParameters::KEY_RECORDING_HINT, "false");
414
415#ifdef VIDEO_SNAPSHOT
416 if (mUseInternalISP)
417 p.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, "true");
418#endif
419
420 if (!mUseInternalISP) {
421 p.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true");
422 p.set(CameraParameters::KEY_MAX_ZOOM, ZOOM_LEVEL_MAX - 1);
423 p.set(CameraParameters::KEY_ZOOM_RATIOS, "31,4.0");
424 }
425
426 mPreviewRunning = false;
427 mParameters = p;
428 mInternalParameters = ip;
429
430 /* make sure mSecCamera has all the settings we do. applications
431 * aren't required to call setParameters themselves (only if they
432 * want to change something.
433 */
434 setParameters(p);
435}
436
437CameraHardwareSec::~CameraHardwareSec()
438{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200439 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200440 mSecCamera->DestroyCamera();
441}
442
443status_t CameraHardwareSec::setPreviewWindow(preview_stream_ops *w)
444{
445 int min_bufs;
446
447 mPreviewWindow = w;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200448 ALOGV("%s: mPreviewWindow %p", __func__, mPreviewWindow);
codeworkx62f02ba2012-05-20 12:00:36 +0200449
450 if (!w) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200451 ALOGE("preview window is NULL!");
codeworkx62f02ba2012-05-20 12:00:36 +0200452 return OK;
453 }
454
455 mPreviewLock.lock();
456
457 if (mPreviewRunning && !mPreviewStartDeferred) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200458 ALOGI("stop preview (window change)");
codeworkx62f02ba2012-05-20 12:00:36 +0200459 stopPreviewInternal();
460 }
461
462 if (w->get_min_undequeued_buffer_count(w, &min_bufs)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200463 ALOGE("%s: could not retrieve min undequeued buffer count", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200464 return INVALID_OPERATION;
465 }
466
467 if (min_bufs >= BUFFER_COUNT_FOR_GRALLOC) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200468 ALOGE("%s: min undequeued buffer count %d is too high (expecting at most %d)", __func__,
codeworkx62f02ba2012-05-20 12:00:36 +0200469 min_bufs, BUFFER_COUNT_FOR_GRALLOC - 1);
470 }
471
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200472 ALOGV("%s: setting buffer count to %d", __func__, BUFFER_COUNT_FOR_GRALLOC);
codeworkx62f02ba2012-05-20 12:00:36 +0200473 if (w->set_buffer_count(w, BUFFER_COUNT_FOR_GRALLOC)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200474 ALOGE("%s: could not set buffer count", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200475 return INVALID_OPERATION;
476 }
477
478 int preview_width;
479 int preview_height;
480 mParameters.getPreviewSize(&preview_width, &preview_height);
481
482 int hal_pixel_format;
483
484 const char *str_preview_format = mParameters.getPreviewFormat();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200485 ALOGV("%s: preview format %s", __func__, str_preview_format);
codeworkx62f02ba2012-05-20 12:00:36 +0200486 mFrameSizeDelta = 16;
487
488 hal_pixel_format = HAL_PIXEL_FORMAT_YV12; // default
489
490 if (!strcmp(str_preview_format,
491 CameraParameters::PIXEL_FORMAT_RGB565)) {
492 hal_pixel_format = HAL_PIXEL_FORMAT_RGB_565;
493 mFrameSizeDelta = 0;
494 } else if (!strcmp(str_preview_format,
495 CameraParameters::PIXEL_FORMAT_RGBA8888)) {
496 hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888;
497 mFrameSizeDelta = 0;
498 } else if (!strcmp(str_preview_format,
499 CameraParameters::PIXEL_FORMAT_YUV420SP)) {
500 hal_pixel_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
501 } else if (!strcmp(str_preview_format,
502 CameraParameters::PIXEL_FORMAT_YUV420P))
503 hal_pixel_format = HAL_PIXEL_FORMAT_YV12; // HACK
504
505#ifdef USE_EGL
506#ifdef BOARD_USE_V4L2_ION
507 if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_ION)) {
508#else
509 if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN)) {
510#endif
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200511 ALOGE("%s: could not set usage on gralloc buffer", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200512 return INVALID_OPERATION;
513 }
514#else
515#ifdef BOARD_USE_V4L2_ION
516 if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN
517 | GRALLOC_USAGE_HWC_HWOVERLAY | GRALLOC_USAGE_HW_ION)) {
518#else
519 if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN
520 | GRALLOC_USAGE_HW_FIMC1 | GRALLOC_USAGE_HWC_HWOVERLAY)) {
521#endif
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200522 ALOGE("%s: could not set usage on gralloc buffer", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200523 return INVALID_OPERATION;
524 }
525#endif
526
527 if (w->set_buffers_geometry(w,
528 preview_width, preview_height,
529 hal_pixel_format)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200530 ALOGE("%s: could not set buffers geometry to %s",
codeworkx62f02ba2012-05-20 12:00:36 +0200531 __func__, str_preview_format);
532 return INVALID_OPERATION;
533 }
534
535#ifdef BOARD_USE_V4L2_ION
536 for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++)
537 if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200538 ALOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i);
codeworkx62f02ba2012-05-20 12:00:36 +0200539 return INVALID_OPERATION;
540 }
541#endif
542
543 if (mPreviewRunning && mPreviewStartDeferred) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200544 ALOGV("start/resume preview");
codeworkx62f02ba2012-05-20 12:00:36 +0200545 status_t ret = startPreviewInternal();
546 if (ret == OK) {
547 mPreviewStartDeferred = false;
548 mPreviewCondition.signal();
549 }
550 }
551 mPreviewLock.unlock();
552
553 return OK;
554}
555
556void CameraHardwareSec::setCallbacks(camera_notify_callback notify_cb,
557 camera_data_callback data_cb,
558 camera_data_timestamp_callback data_cb_timestamp,
559 camera_request_memory get_memory,
560 void *user)
561{
562 mNotifyCb = notify_cb;
563 mDataCb = data_cb;
564 mDataCbTimestamp = data_cb_timestamp;
565 mGetMemoryCb = get_memory;
566 mCallbackCookie = user;
567}
568
569void CameraHardwareSec::enableMsgType(int32_t msgType)
570{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200571 ALOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x",
codeworkx62f02ba2012-05-20 12:00:36 +0200572 __func__, msgType, mMsgEnabled);
573 mMsgEnabled |= msgType;
574
575 mPreviewLock.lock();
576 if ((msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_VIDEO_FRAME)) &&
577 mPreviewRunning && mPreviewStartDeferred) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200578 ALOGV("%s: starting deferred preview", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200579 if (startPreviewInternal() == OK) {
580 mPreviewStartDeferred = false;
581 mPreviewCondition.signal();
582 }
583 }
584 mPreviewLock.unlock();
585
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200586 ALOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
codeworkx62f02ba2012-05-20 12:00:36 +0200587}
588
589void CameraHardwareSec::disableMsgType(int32_t msgType)
590{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200591 ALOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x",
codeworkx62f02ba2012-05-20 12:00:36 +0200592 __func__, msgType, mMsgEnabled);
593 mMsgEnabled &= ~msgType;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200594 ALOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
codeworkx62f02ba2012-05-20 12:00:36 +0200595}
596
597bool CameraHardwareSec::msgTypeEnabled(int32_t msgType)
598{
599 return (mMsgEnabled & msgType);
600}
601
602void CameraHardwareSec::setSkipFrame(int frame)
603{
604 Mutex::Autolock lock(mSkipFrameLock);
605 if (frame < mSkipFrame)
606 return;
607
608 mSkipFrame = frame;
609}
610
611int CameraHardwareSec::previewThreadWrapper()
612{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200613 ALOGI("%s: starting", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200614 while (1) {
615 mPreviewLock.lock();
616 while (!mPreviewRunning) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200617 ALOGI("%s: calling mSecCamera->stopPreview() and waiting", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200618 mSecCamera->stopPreview();
619 /* signal that we're stopping */
620 mPreviewStoppedCondition.signal();
621 mPreviewCondition.wait(mPreviewLock);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200622 ALOGI("%s: return from wait", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200623 }
624 mPreviewLock.unlock();
625
626 if (mExitPreviewThread) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200627 ALOGI("%s: exiting", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200628 mSecCamera->stopPreview();
629 return 0;
630 }
631
632 previewThread();
633 }
634}
635
636int CameraHardwareSec::previewThread()
637{
638 int index;
639 nsecs_t timestamp;
640 SecBuffer previewAddr, recordAddr;
641 static int numArray = 0;
642 void *virAddr[3];
643 camera_frame_metadata_t fdmeta;
644 camera_face_t caface[5];
645
646#ifdef BOARD_USE_V4L2_ION
647 private_handle_t *hnd = NULL;
648#else
649 struct addrs *addrs;
650#endif
651
652 fdmeta.faces = caface;
653 index = mSecCamera->getPreview(&fdmeta);
654
655 mFaceData = &fdmeta;
656
657 if (index < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200658 ALOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200659#ifdef BOARD_USE_V4L2_ION
660 if (mSecCamera->getPreviewState()) {
661 stopPreview();
662 startPreview();
663 mSecCamera->clearPreviewState();
664 }
665#endif
666 return UNKNOWN_ERROR;
667 }
668
669#ifdef ZERO_SHUTTER_LAG
670 if (mUseInternalISP && !mRecordHint) {
671 mCapIndex = mSecCamera->getSnapshot();
672
673 if (mCapIndex >= 0) {
674 if (mSecCamera->setSnapshotFrame(mCapIndex) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200675 ALOGE("%s: Fail qbuf, index(%d)", __func__, mCapIndex);
codeworkx62f02ba2012-05-20 12:00:36 +0200676 return INVALID_OPERATION;
677 }
678 }
679 }
680#endif
681
682 mSkipFrameLock.lock();
683 if (mSkipFrame > 0) {
684 mSkipFrame--;
685 mSkipFrameLock.unlock();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200686 ALOGV("%s: index %d skipping frame", __func__, index);
codeworkx62f02ba2012-05-20 12:00:36 +0200687 if (mSecCamera->setPreviewFrame(index) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200688 ALOGE("%s: Could not qbuff[%d]!!", __func__, index);
codeworkx62f02ba2012-05-20 12:00:36 +0200689 return UNKNOWN_ERROR;
690 }
691 return NO_ERROR;
692 }
693 mSkipFrameLock.unlock();
694
695 timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
696
697 int width, height, frame_size, offset;
698
699 mSecCamera->getPreviewSize(&width, &height, &frame_size);
700
701 offset = frame_size * index;
702
703 if (mPreviewWindow && mGrallocHal && mPreviewRunning) {
704#ifdef BOARD_USE_V4L2_ION
705 hnd = (private_handle_t*)*mBufferHandle[index];
706
707 if (mPreviewHeap) {
708 mPreviewHeap->release(mPreviewHeap);
709 mPreviewHeap = 0;
710 }
711
712 mPreviewHeap = mGetMemoryCb(hnd->fd, frame_size, 1, 0);
713
714 hnd = NULL;
715
716 mGrallocHal->unlock(mGrallocHal, *mBufferHandle[index]);
717 if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[index])) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200718 ALOGE("%s: Could not enqueue gralloc buffer[%d]!!", __func__, index);
codeworkx62f02ba2012-05-20 12:00:36 +0200719 goto callbacks;
720 } else {
721 mBufferHandle[index] = NULL;
722 mStride[index] = NULL;
723 }
724
725 numArray = index;
726#endif
727
728 if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[numArray], &mStride[numArray])) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200729 ALOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, numArray);
codeworkx62f02ba2012-05-20 12:00:36 +0200730 goto callbacks;
731 }
732
733 if (!mGrallocHal->lock(mGrallocHal,
734 *mBufferHandle[numArray],
735 GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR,
736 0, 0, width, height, virAddr)) {
737#ifdef BOARD_USE_V4L2
738 mSecCamera->getPreviewAddr(index, &previewAddr);
739 char *frame = (char *)previewAddr.virt.extP[0];
740#else
741 char *frame = ((char *)mPreviewHeap->data) + offset;
742#endif
743
744#ifdef BOARD_USE_V4L2_ION
745 mSecCamera->setUserBufferAddr(virAddr, index, PREVIEW_MODE);
746#else
747 int total = frame_size + mFrameSizeDelta;
748 int h = 0;
749 char *src = frame;
750
751 /* TODO : Need to fix size of planes for supported color fmt.
752 Currnetly we support only YV12(3 plane) and NV21(2 plane)*/
753 // Y
754 memcpy(virAddr[0],src, width * height);
755 src += width * height;
756
757 if (mPreviewFmtPlane == PREVIEW_FMT_2_PLANE) {
758 memcpy(virAddr[1], src, width * height / 2);
759 } else if (mPreviewFmtPlane == PREVIEW_FMT_3_PLANE) {
760 // U
761 memcpy(virAddr[1], src, width * height / 4);
762 src += width * height / 4;
763
764 // V
765 memcpy(virAddr[2], src, width * height / 4);
766 }
767
768 mGrallocHal->unlock(mGrallocHal, **mBufferHandle);
769#endif
770 }
771 else
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200772 ALOGE("%s: could not obtain gralloc buffer", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200773
774 if (mSecCamera->setPreviewFrame(index) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200775 ALOGE("%s: Fail qbuf, index(%d)", __func__, index);
codeworkx62f02ba2012-05-20 12:00:36 +0200776 goto callbacks;
777 }
778
779 index = 0;
780#ifndef BOARD_USE_V4L2_ION
781 if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, *mBufferHandle)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200782 ALOGE("Could not enqueue gralloc buffer!");
codeworkx62f02ba2012-05-20 12:00:36 +0200783 goto callbacks;
784 }
785#endif
786 }
787
788callbacks:
789 // Notify the client of a new frame.
790 if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME && mPreviewRunning)
791 mDataCb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap, index, NULL, mCallbackCookie);
792
793#ifdef USE_FACE_DETECTION
794 if (mUseInternalISP && (mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA) && mPreviewRunning)
795 mDataCb(CAMERA_MSG_PREVIEW_METADATA, mFaceDataHeap, 0, mFaceData, mCallbackCookie);
796#endif
797
798 Mutex::Autolock lock(mRecordLock);
799 if (mRecordRunning == true) {
800 int recordingIndex = 0;
801
802 index = mSecCamera->getRecordFrame();
803 if (index < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200804 ALOGE("ERR(%s):Fail on SecCamera->getRecordFrame()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200805 return UNKNOWN_ERROR;
806 }
807
808#ifdef VIDEO_SNAPSHOT
809 if (mUseInternalISP && mRecordHint) {
810 mCapIndex = mSecCamera->getSnapshot();
811
812 if (mSecCamera->setSnapshotFrame(mCapIndex) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200813 ALOGE("%s: Fail qbuf, index(%d)", __func__, mCapIndex);
codeworkx62f02ba2012-05-20 12:00:36 +0200814 return INVALID_OPERATION;
815 }
816 }
817#endif
818
819#ifdef BOARD_USE_V4L2_ION
820 numArray = index;
821#else
822 recordingIndex = index;
823 mSecCamera->getRecordAddr(index, &recordAddr);
824
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200825 ALOGV("record PhyY(0x%08x) phyC(0x%08x) ", recordAddr.phys.extP[0], recordAddr.phys.extP[1]);
codeworkx62f02ba2012-05-20 12:00:36 +0200826
827 if (recordAddr.phys.extP[0] == 0xffffffff || recordAddr.phys.extP[1] == 0xffffffff) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200828 ALOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __func__,
codeworkx62f02ba2012-05-20 12:00:36 +0200829 recordAddr.phys.extP[0], recordAddr.phys.extP[1]);
830 return UNKNOWN_ERROR;
831 }
832
833 addrs = (struct addrs *)(*mRecordHeap)->data;
834
835 addrs[index].type = kMetadataBufferTypeCameraSource;
836 addrs[index].addr_y = recordAddr.phys.extP[0];
837 addrs[index].addr_cbcr = recordAddr.phys.extP[1];
838 addrs[index].buf_index = index;
839#endif
840
841 // Notify the client of a new frame.
842 if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)
843 mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME,
844 mRecordHeap[numArray], recordingIndex, mCallbackCookie);
845 else
846 mSecCamera->releaseRecordFrame(index);
847 }
848
849 return NO_ERROR;
850}
851
852status_t CameraHardwareSec::startPreview()
853{
854 int ret = 0;
855
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200856 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200857
858 Mutex::Autolock lock(mStateLock);
859 if (mCaptureInProgress) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200860 ALOGE("%s : capture in progress, not allowed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200861 return INVALID_OPERATION;
862 }
863
864 mPreviewLock.lock();
865 if (mPreviewRunning) {
866 // already running
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200867 ALOGE("%s : preview thread already running", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200868 mPreviewLock.unlock();
869 return INVALID_OPERATION;
870 }
871
872 mPreviewRunning = true;
873 mPreviewStartDeferred = false;
874
875 if (!mPreviewWindow &&
876 !(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) &&
877 !(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200878 ALOGI("%s : deferring", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200879 mPreviewStartDeferred = true;
880 mPreviewLock.unlock();
881 return NO_ERROR;
882 }
883
884 ret = startPreviewInternal();
885 if (ret == OK)
886 mPreviewCondition.signal();
887
888 mPreviewLock.unlock();
889 return ret;
890}
891
892status_t CameraHardwareSec::startPreviewInternal()
893{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200894 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200895 int width, height, frame_size;
896
897 mSecCamera->getPreviewSize(&width, &height, &frame_size);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200898 ALOGD("mPreviewHeap(fd(%d), size(%d), width(%d), height(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +0200899 mSecCamera->getCameraFd(SecCamera::PREVIEW), frame_size + mFrameSizeDelta, width, height);
900
901#ifdef BOARD_USE_V4L2_ION
902#ifdef ZERO_SHUTTER_LAG
903/*TODO*/
904 int mPostViewWidth, mPostViewHeight, mPostViewSize;
905 mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
906 for(int i = 0; i < CAP_BUFFERS; i++) {
907 mPostviewHeap[i] = new MemoryHeapBaseIon(mPostViewSize);
908 mSecCamera->setUserBufferAddr(mPostviewHeap[i]->base(), i, CAPTURE_MODE);
909 }
910#endif
911 void *vaddr[3];
912
913 for (int i = 0; i < MAX_BUFFERS; i++) {
914 if (mBufferHandle[i] == NULL) {
915 if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200916 ALOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i);
codeworkx62f02ba2012-05-20 12:00:36 +0200917 return INVALID_OPERATION;
918 }
919 }
920 if (mGrallocHal->lock(mGrallocHal,
921 *mBufferHandle[i],
922 GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR,
923 0, 0, width, height, vaddr)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200924 ALOGE("ERR(%s): Could not get virtual address!!, index = %d", __func__, i);
codeworkx62f02ba2012-05-20 12:00:36 +0200925 return UNKNOWN_ERROR;
926 }
927 mSecCamera->setUserBufferAddr(vaddr, i, PREVIEW_MODE);
928 }
929#endif
930
931 int ret = mSecCamera->startPreview();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200932 ALOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret);
codeworkx62f02ba2012-05-20 12:00:36 +0200933
934 if (ret < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200935 ALOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200936 return UNKNOWN_ERROR;
937 }
938
939 setSkipFrame(INITIAL_SKIP_FRAME);
940
941 if (mPreviewHeap) {
942 mPreviewHeap->release(mPreviewHeap);
943 mPreviewHeap = 0;
944 }
945
946 for(int i=0; i<BUFFER_COUNT_FOR_ARRAY; i++){
947 if (mRecordHeap[i] != NULL) {
948 mRecordHeap[i]->release(mRecordHeap[i]);
949 mRecordHeap[i] = 0;
950 }
951 }
952
953#ifndef BOARD_USE_V4L2
954 mPreviewHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(SecCamera::PREVIEW),
955 frame_size + mFrameSizeDelta,
956 MAX_BUFFERS,
957 0); // no cookie
958#endif
959
960 mFaceDataHeap = mGetMemoryCb(-1, 1, 1, 0);
961
962 mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200963 ALOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",
codeworkx62f02ba2012-05-20 12:00:36 +0200964 mPostViewWidth,mPostViewHeight,mPostViewSize);
965
966 return NO_ERROR;
967}
968
969void CameraHardwareSec::stopPreviewInternal()
970{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200971 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200972
973 /* request that the preview thread stop. */
974 if (mPreviewRunning) {
975 mPreviewRunning = false;
976 if (!mPreviewStartDeferred) {
977 mPreviewCondition.signal();
978 /* wait until preview thread is stopped */
979 mPreviewStoppedCondition.wait(mPreviewLock);
980
981#ifdef BOARD_USE_V4L2_ION
982 for (int i = 0; i < MAX_BUFFERS; i++) {
983 if (mBufferHandle[i] != NULL) {
984 if (0 != mPreviewWindow->cancel_buffer(mPreviewWindow, mBufferHandle[i])) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200985 ALOGE("%s: Fail to cancel buffer[%d]", __func__, i);
codeworkx62f02ba2012-05-20 12:00:36 +0200986 } else {
987 mBufferHandle[i] = NULL;
988 mStride[i] = NULL;
989 }
990 }
991 }
992#endif
993 }
994 else
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200995 ALOGV("%s : preview running but deferred, doing nothing", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200996 } else
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200997 ALOGI("%s : preview not running, doing nothing", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200998}
999
1000void CameraHardwareSec::stopPreview()
1001{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001002 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001003
1004 /* request that the preview thread stop. */
1005 mPreviewLock.lock();
1006 stopPreviewInternal();
1007 mPreviewLock.unlock();
1008}
1009
1010bool CameraHardwareSec::previewEnabled()
1011{
1012 Mutex::Autolock lock(mPreviewLock);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001013 ALOGV("%s : %d", __func__, mPreviewRunning);
codeworkx62f02ba2012-05-20 12:00:36 +02001014 return mPreviewRunning;
1015}
1016
1017status_t CameraHardwareSec::startRecording()
1018{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001019 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001020
1021 Mutex::Autolock lock(mRecordLock);
1022
1023 for(int i = 0; i<BUFFER_COUNT_FOR_ARRAY; i++){
1024 if (mRecordHeap[i] != NULL) {
1025 mRecordHeap[i]->release(mRecordHeap[i]);
1026 mRecordHeap[i] = 0;
1027 }
1028
1029#ifdef BOARD_USE_V4L2_ION
1030 int width, height;
1031
1032 mSecCamera->getRecordingSize(&width, &height);
1033
1034 mRecordHeap[i] = mGetMemoryCb(-1, (ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048)), 1, NULL);
1035
1036 mSecCamera->setUserBufferAddr((void *)(mRecordHeap[i]->data), i, RECORD_MODE);
1037#else
1038 mRecordHeap[i] = mGetMemoryCb(-1, sizeof(struct addrs), MAX_BUFFERS, NULL);
1039#endif
1040 if (!mRecordHeap[i]) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001041 ALOGE("ERR(%s): Record heap[%d] creation fail", __func__, i);
codeworkx62f02ba2012-05-20 12:00:36 +02001042 return UNKNOWN_ERROR;
1043 }
1044 }
1045
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001046 ALOGV("mRecordHeaps alloc done");
codeworkx62f02ba2012-05-20 12:00:36 +02001047
1048 if (mRecordRunning == false) {
1049 if (mSecCamera->startRecord(mRecordHint) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001050 ALOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001051 return UNKNOWN_ERROR;
1052 }
1053 mRecordRunning = true;
1054 }
1055 return NO_ERROR;
1056}
1057
1058void CameraHardwareSec::stopRecording()
1059{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001060 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001061
1062 Mutex::Autolock lock(mRecordLock);
1063
1064 if (mRecordRunning == true) {
1065 if (mSecCamera->stopRecord() < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001066 ALOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001067 return;
1068 }
1069 mRecordRunning = false;
1070 }
1071}
1072
1073bool CameraHardwareSec::recordingEnabled()
1074{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001075 ALOGV("%s :", __func__);
1076 ALOGV("%s : %d", __func__, mPreviewRunning);
codeworkx62f02ba2012-05-20 12:00:36 +02001077
1078 return mRecordRunning;
1079}
1080
1081void CameraHardwareSec::releaseRecordingFrame(const void *opaque)
1082{
1083#ifdef BOARD_USE_V4L2_ION
1084 int i;
1085 for (i = 0; i < MAX_BUFFERS; i++)
1086 if ((char *)mRecordHeap[i]->data == (char *)opaque)
1087 break;
1088
1089 mSecCamera->releaseRecordFrame(i);
1090#else
1091 struct addrs *addrs = (struct addrs *)opaque;
1092 mSecCamera->releaseRecordFrame(addrs->buf_index);
1093#endif
1094}
1095
1096int CameraHardwareSec::autoFocusThread()
1097{
1098 int count =0;
1099 int af_status =0 ;
1100
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001101 ALOGV("%s : starting", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001102
1103 /* block until we're told to start. we don't want to use
1104 * a restartable thread and requestExitAndWait() in cancelAutoFocus()
1105 * because it would cause deadlock between our callbacks and the
1106 * caller of cancelAutoFocus() which both want to grab the same lock
1107 * in CameraServices layer.
1108 */
1109 mFocusLock.lock();
1110 /* check early exit request */
1111 if (mExitAutoFocusThread) {
1112 mFocusLock.unlock();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001113 ALOGV("%s : exiting on request0", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001114 return NO_ERROR;
1115 }
1116 mFocusCondition.wait(mFocusLock);
1117 /* check early exit request */
1118 if (mExitAutoFocusThread) {
1119 mFocusLock.unlock();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001120 ALOGV("%s : exiting on request1", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001121 return NO_ERROR;
1122 }
1123 mFocusLock.unlock();
1124
1125 /* TODO : Currently only possible auto focus at BACK caemra
1126 We need to modify to check that sensor can support auto focus */
1127 if (mCameraID == SecCamera::CAMERA_ID_BACK) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001128 ALOGV("%s : calling setAutoFocus", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001129 if (mTouched == 0) {
1130 if (mSecCamera->setAutofocus() < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001131 ALOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001132 return UNKNOWN_ERROR;
1133 }
1134 } else {
1135 if (mSecCamera->setTouchAF() < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001136 ALOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001137 return UNKNOWN_ERROR;
1138 }
1139 }
1140 }
1141
1142 /* TODO */
1143 /* This is temperary implementation.
1144 When camera support AF blocking mode, this code will be removed
1145 Continous AutoFocus is not need to success */
1146 const char *focusModeStr = mParameters.get(CameraParameters::KEY_FOCUS_MODE);
1147 int isContinousAF = !strncmp(focusModeStr, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, 7);
1148 if (mUseInternalISP && !isContinousAF) {
1149 int i, err = -1;
1150 for (i = 0; i < 400; i++) {
1151 usleep(10000);
1152
1153 af_status = mSecCamera->getAutoFocusResult();
1154
1155 if ((af_status & 0x2)) {
1156 err = 0;
1157 break;
1158 }
1159 }
1160 } else {
1161 af_status = mSecCamera->getAutoFocusResult();
1162 }
1163
1164 if (af_status == 0x01) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001165 ALOGV("%s : AF Cancelled !!", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001166 if (mMsgEnabled & CAMERA_MSG_FOCUS)
1167 mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
1168 } else if (af_status == 0x02) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001169 ALOGV("%s : AF Success !!", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001170 if (mMsgEnabled & CAMERA_MSG_FOCUS) {
1171 /* CAMERA_MSG_FOCUS only takes a bool. true for
1172 * finished and false for failure. cancel is still
1173 * considered a true result.
1174 */
1175 mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
1176 }
1177 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001178 ALOGV("%s : AF Fail !!", __func__);
1179 ALOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
codeworkx62f02ba2012-05-20 12:00:36 +02001180 if (mMsgEnabled & CAMERA_MSG_FOCUS)
1181 mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie);
1182 }
1183
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001184 ALOGV("%s : exiting with no error", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001185 return NO_ERROR;
1186}
1187
1188status_t CameraHardwareSec::autoFocus()
1189{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001190 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001191 /* signal autoFocusThread to run once */
1192 mFocusCondition.signal();
1193 return NO_ERROR;
1194}
1195
1196status_t CameraHardwareSec::cancelAutoFocus()
1197{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001198 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001199
1200 if (mSecCamera->cancelAutofocus() < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001201 ALOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001202 return UNKNOWN_ERROR;
1203 }
1204
1205 return NO_ERROR;
1206}
1207
1208int CameraHardwareSec::save_jpeg( unsigned char *real_jpeg, int jpeg_size)
1209{
1210 FILE *yuv_fp = NULL;
1211 char filename[100], *buffer = NULL;
1212
1213 /* file create/open, note to "wb" */
1214 yuv_fp = fopen("/data/camera_dump.jpeg", "wb");
1215 if (yuv_fp == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001216 ALOGE("Save jpeg file open error");
codeworkx62f02ba2012-05-20 12:00:36 +02001217 return -1;
1218 }
1219
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001220 ALOGV("[BestIQ] real_jpeg size ========> %d", jpeg_size);
codeworkx62f02ba2012-05-20 12:00:36 +02001221 buffer = (char *) malloc(jpeg_size);
1222 if (buffer == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001223 ALOGE("Save YUV] buffer alloc failed");
codeworkx62f02ba2012-05-20 12:00:36 +02001224 if (yuv_fp)
1225 fclose(yuv_fp);
1226
1227 return -1;
1228 }
1229
1230 memcpy(buffer, real_jpeg, jpeg_size);
1231
1232 fflush(stdout);
1233
1234 fwrite(buffer, 1, jpeg_size, yuv_fp);
1235
1236 fflush(yuv_fp);
1237
1238 if (yuv_fp)
1239 fclose(yuv_fp);
1240 if (buffer)
1241 free(buffer);
1242
1243 return 0;
1244}
1245
1246void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t size)
1247{
1248 int nw;
1249 int cnt = 0;
1250 uint32_t written = 0;
1251
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001252 ALOGD("opening file [%s]", fname);
codeworkx62f02ba2012-05-20 12:00:36 +02001253 int fd = open(fname, O_RDWR | O_CREAT);
1254 if (fd < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001255 ALOGE("failed to create file [%s]: %s", fname, strerror(errno));
codeworkx62f02ba2012-05-20 12:00:36 +02001256 return;
1257 }
1258
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001259 ALOGD("writing %d bytes to file [%s]", size, fname);
codeworkx62f02ba2012-05-20 12:00:36 +02001260 while (written < size) {
1261 nw = ::write(fd, buf + written, size - written);
1262 if (nw < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001263 ALOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno));
codeworkx62f02ba2012-05-20 12:00:36 +02001264 break;
1265 }
1266 written += nw;
1267 cnt++;
1268 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001269 ALOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt);
codeworkx62f02ba2012-05-20 12:00:36 +02001270 ::close(fd);
1271}
1272
1273bool CameraHardwareSec::scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHeight,
1274 char *dstBuf, uint32_t dstWidth, uint32_t dstHeight)
1275{
1276 int32_t step_x, step_y;
1277 int32_t iXsrc, iXdst;
1278 int32_t x, y, src_y_start_pos, dst_pos, src_pos;
1279
1280 if (dstWidth % 2 != 0 || dstHeight % 2 != 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001281 ALOGE("scale_down_yuv422: invalid width, height for scaling");
codeworkx62f02ba2012-05-20 12:00:36 +02001282 return false;
1283 }
1284
1285 step_x = srcWidth / dstWidth;
1286 step_y = srcHeight / dstHeight;
1287
1288 dst_pos = 0;
1289 for (uint32_t y = 0; y < dstHeight; y++) {
1290 src_y_start_pos = (y * step_y * (srcWidth * 2));
1291
1292 for (uint32_t x = 0; x < dstWidth; x += 2) {
1293 src_pos = src_y_start_pos + (x * (step_x * 2));
1294
1295 dstBuf[dst_pos++] = srcBuf[src_pos ];
1296 dstBuf[dst_pos++] = srcBuf[src_pos + 1];
1297 dstBuf[dst_pos++] = srcBuf[src_pos + 2];
1298 dstBuf[dst_pos++] = srcBuf[src_pos + 3];
1299 }
1300 }
1301
1302 return true;
1303}
1304
1305bool CameraHardwareSec::YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight)
1306{
1307 int32_t x, y, src_y_start_pos, dst_cbcr_pos, dst_pos, src_pos;
1308 unsigned char *srcBufPointer = (unsigned char *)srcBuf;
1309 unsigned char *dstBufPointer = (unsigned char *)dstBuf;
1310
1311 dst_pos = 0;
1312 dst_cbcr_pos = srcWidth*srcHeight;
1313 for (uint32_t y = 0; y < srcHeight; y++) {
1314 src_y_start_pos = (y * (srcWidth * 2));
1315
1316 for (uint32_t x = 0; x < (srcWidth * 2); x += 2) {
1317 src_pos = src_y_start_pos + x;
1318
1319 dstBufPointer[dst_pos++] = srcBufPointer[src_pos];
1320 }
1321 }
1322 for (uint32_t y = 0; y < srcHeight; y += 2) {
1323 src_y_start_pos = (y * (srcWidth * 2));
1324
1325 for (uint32_t x = 0; x < (srcWidth * 2); x += 4) {
1326 src_pos = src_y_start_pos + x;
1327
1328 dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 3];
1329 dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 1];
1330 }
1331 }
1332
1333 return true;
1334}
1335
1336int CameraHardwareSec::pictureThread()
1337{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001338 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001339
1340 int jpeg_size = 0;
1341 int ret = NO_ERROR;
1342 unsigned char *jpeg_data = NULL;
1343 int postview_offset = 0;
1344 unsigned char *postview_data = NULL;
1345
1346 unsigned char *addr = NULL;
1347 int mPostViewWidth, mPostViewHeight, mPostViewSize;
1348 int mThumbWidth, mThumbHeight, mThumbSize;
1349 int cap_width, cap_height, cap_frame_size;
1350
1351 int JpegImageSize = 0;
1352
1353 mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
1354 mSecCamera->getThumbnailConfig(&mThumbWidth, &mThumbHeight, &mThumbSize);
1355 int postviewHeapSize = mPostViewSize;
1356 if (!mRecordRunning)
1357 mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size);
1358 else
1359 mSecCamera->getVideosnapshotSize(&cap_width, &cap_height, &cap_frame_size);
1360 int mJpegHeapSize;
1361 if (!mUseInternalISP)
1362 mJpegHeapSize = cap_frame_size * SecCamera::getJpegRatio();
1363 else
1364 mJpegHeapSize = cap_frame_size;
1365
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001366 ALOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight);
codeworkx62f02ba2012-05-20 12:00:36 +02001367
1368 camera_memory_t *JpegHeap = mGetMemoryCb(-1, mJpegHeapSize, 1, 0);
1369#ifdef BOARD_USE_V4L2_ION
1370#ifdef ZERO_SHUTTER_LAG
1371 mThumbnailHeap = new MemoryHeapBaseIon(mThumbSize);
1372#else
1373 mPostviewHeap[mCapIndex] = new MemoryHeapBaseIon(mPostViewSize);
1374 mThumbnailHeap = new MemoryHeapBaseIon(mThumbSize);
1375#endif
1376#else
1377 mThumbnailHeap = new MemoryHeapBase(mThumbSize);
1378#endif
1379
1380 if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
1381 int picture_size, picture_width, picture_height;
1382 mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size);
1383 int picture_format = mSecCamera->getSnapshotPixelFormat();
1384
1385 unsigned int thumb_addr, phyAddr;
1386
1387 // Modified the shutter sound timing for Jpeg capture
1388 if (!mUseInternalISP) {
1389 mSecCamera->setSnapshotCmd();
1390
1391 if (mMsgEnabled & CAMERA_MSG_SHUTTER)
1392 mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
1393
1394 jpeg_data = mSecCamera->getJpeg(&JpegImageSize, &mThumbSize, &thumb_addr, &phyAddr);
1395 if (jpeg_data == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001396 ALOGE("ERR(%s):Fail on SecCamera->getJpeg()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001397 ret = UNKNOWN_ERROR;
1398 }
1399
1400 memcpy((unsigned char *)mThumbnailHeap->base(), (unsigned char *)thumb_addr, mThumbSize);
1401 memcpy(JpegHeap->data, jpeg_data, JpegImageSize);
1402 } else {
1403 if (mMsgEnabled & CAMERA_MSG_SHUTTER)
1404 mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
1405
1406#ifdef ZERO_SHUTTER_LAG
1407 mSecCamera->getCaptureAddr(mCapIndex, &mCapBuffer);
1408
1409 if (mCapBuffer.virt.extP[0] == NULL) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001410 ALOGE("ERR(%s):Fail on SecCamera getCaptureAddr = %0x ",
codeworkx62f02ba2012-05-20 12:00:36 +02001411 __func__, mCapBuffer.virt.extP[0]);
1412 return UNKNOWN_ERROR;
1413 }
1414
1415 scaleDownYuv422((char *)mCapBuffer.virt.extP[0], cap_width, cap_height,
1416 (char *)mThumbnailHeap->base(), mThumbWidth, mThumbHeight);
1417#else
1418#ifdef BOARD_USE_V4L2_ION
1419 mCapBuffer.virt.extP[0] = (char *)mPostviewHeap[mCapIndex]->base();
1420#endif
1421#endif
1422
1423 if (mSecCamera->getSnapshotAndJpeg(&mCapBuffer, mCapIndex,
1424 (unsigned char*)JpegHeap->data, &JpegImageSize) < 0) {
1425 mStateLock.lock();
1426 mCaptureInProgress = false;
1427 mStateLock.unlock();
1428 JpegHeap->release(JpegHeap);
1429 return UNKNOWN_ERROR;
1430 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001431 ALOGI("snapshotandjpeg done");
codeworkx62f02ba2012-05-20 12:00:36 +02001432
1433#ifdef ZERO_SHUTTER_LAG
1434 if (!mRecordRunning)
1435 stopPreview();
1436 memset(&mCapBuffer, 0, sizeof(struct SecBuffer));
1437#else
1438 scaleDownYuv422((char *)mCapBuffer.virt.extP[0], cap_width, cap_height,
1439 (char *)mThumbnailHeap->base(), mThumbWidth, mThumbHeight);
1440#endif
1441 }
1442 }
1443
1444#ifndef BOARD_USE_V4L2_ION
1445 int rawHeapSize = cap_frame_size;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001446 ALOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize);
codeworkx62f02ba2012-05-20 12:00:36 +02001447#ifdef BOARD_USE_V4L2_ION
1448 mRawHeap = mGetMemoryCb(mPostviewHeap[mCapIndex]->getHeapID(), rawHeapSize, 1, 0);
1449#else
1450 mRawHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(SecCamera::PICTURE), rawHeapSize, 1, 0);
1451#endif
1452 if (!mRawHeap)
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001453 ALOGE("ERR(%s): Raw heap creation fail", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001454
1455 if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)
1456 mDataCb(CAMERA_MSG_RAW_IMAGE, mRawHeap, 0, NULL, mCallbackCookie);
1457#endif
1458 mStateLock.lock();
1459 mCaptureInProgress = false;
1460 mStateLock.unlock();
1461
1462 if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
1463 camera_memory_t *ExifHeap =
1464 mGetMemoryCb(-1, EXIF_FILE_SIZE + mThumbSize, 1, 0);
1465
1466 int JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data,
1467 (unsigned char *)mThumbnailHeap->base(),
1468 mThumbSize);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001469 ALOGV("JpegExifSize=%d", JpegExifSize);
codeworkx62f02ba2012-05-20 12:00:36 +02001470
1471 if (JpegExifSize < 0) {
1472 ret = UNKNOWN_ERROR;
1473 goto out;
1474 }
1475
1476 int mJpegHeapSize_out = JpegImageSize + JpegExifSize;
1477 camera_memory_t *JpegHeap_out = mGetMemoryCb(-1, mJpegHeapSize_out, 1, 0);
1478
1479 unsigned char *ExifStart = (unsigned char *)JpegHeap_out->data + 2;
1480 unsigned char *ImageStart = ExifStart + JpegExifSize;
1481
1482 memcpy(JpegHeap_out->data, JpegHeap->data, 2);
1483 memcpy(ExifStart, ExifHeap->data, JpegExifSize);
1484 memcpy(ImageStart, JpegHeap->data + 2, JpegImageSize - 2);
1485
1486 mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, JpegHeap_out, 0, NULL, mCallbackCookie);
1487
1488 if (ExifHeap) {
1489 ExifHeap->release(ExifHeap);
1490 ExifHeap = 0;
1491 }
1492
1493 if (JpegHeap_out) {
1494 JpegHeap_out->release(JpegHeap_out);
1495 JpegHeap_out = 0;
1496 }
1497 }
1498
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001499 ALOGV("%s : pictureThread end", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001500
1501out:
1502 if (JpegHeap) {
1503 JpegHeap->release(JpegHeap);
1504 JpegHeap = 0;
1505 }
1506
1507 if (mRawHeap) {
1508 mRawHeap->release(mRawHeap);
1509 mRawHeap = 0;
1510 }
1511
1512 if (!mUseInternalISP && !mRecordRunning)
1513 mSecCamera->endSnapshot();
1514
1515 return ret;
1516}
1517
1518status_t CameraHardwareSec::takePicture()
1519{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001520 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001521
1522#ifdef ZERO_SHUTTER_LAG
1523 if (!mUseInternalISP) {
1524 stopPreview();
1525 }
1526#else
1527 stopPreview();
1528#endif
1529
1530 Mutex::Autolock lock(mStateLock);
1531 if (mCaptureInProgress) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001532 ALOGE("%s : capture already in progress", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001533 return INVALID_OPERATION;
1534 }
1535
1536 if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001537 ALOGE("%s : couldn't run picture thread", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001538 return INVALID_OPERATION;
1539 }
1540 mCaptureInProgress = true;
1541
1542 return NO_ERROR;
1543}
1544
1545status_t CameraHardwareSec::cancelPicture()
1546{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001547 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001548
1549 if (mPictureThread.get()) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001550 ALOGV("%s: waiting for picture thread to exit", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001551 mPictureThread->requestExitAndWait();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001552 ALOGV("%s: picture thread has exited", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001553 }
1554
1555 return NO_ERROR;
1556}
1557
1558bool CameraHardwareSec::CheckVideoStartMarker(unsigned char *pBuf)
1559{
1560 if (!pBuf) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001561 ALOGE("CheckVideoStartMarker() => pBuf is NULL");
codeworkx62f02ba2012-05-20 12:00:36 +02001562 return false;
1563 }
1564
1565 if (HIBYTE(VIDEO_COMMENT_MARKER_H) == * pBuf && LOBYTE(VIDEO_COMMENT_MARKER_H) == *(pBuf + 1) &&
1566 HIBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 2) && LOBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 3))
1567 return true;
1568
1569 return false;
1570}
1571
1572bool CameraHardwareSec::CheckEOIMarker(unsigned char *pBuf)
1573{
1574 if (!pBuf) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001575 ALOGE("CheckEOIMarker() => pBuf is NULL");
codeworkx62f02ba2012-05-20 12:00:36 +02001576 return false;
1577 }
1578
1579 // EOI marker [FF D9]
1580 if (HIBYTE(JPEG_EOI_MARKER) == *pBuf && LOBYTE(JPEG_EOI_MARKER) == *(pBuf + 1))
1581 return true;
1582
1583 return false;
1584}
1585
1586bool CameraHardwareSec::FindEOIMarkerInJPEG(unsigned char *pBuf, int dwBufSize, int *pnJPEGsize)
1587{
1588 if (NULL == pBuf || 0 >= dwBufSize) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001589 ALOGE("FindEOIMarkerInJPEG() => There is no contents.");
codeworkx62f02ba2012-05-20 12:00:36 +02001590 return false;
1591 }
1592
1593 unsigned char *pBufEnd = pBuf + dwBufSize;
1594
1595 while (pBuf < pBufEnd) {
1596 if (CheckEOIMarker(pBuf++))
1597 return true;
1598
1599 (*pnJPEGsize)++;
1600 }
1601
1602 return false;
1603}
1604
1605bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize,
1606 int dwJPEGLineLength, int dwVideoLineLength, int dwVideoHeight,
1607 void *pJPEG, int *pdwJPEGSize,
1608 void *pVideo, int *pdwVideoSize)
1609{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001610 ALOGV("===========SplitFrame Start==============");
codeworkx62f02ba2012-05-20 12:00:36 +02001611
1612 if (NULL == pFrame || 0 >= dwSize) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001613 ALOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize);
codeworkx62f02ba2012-05-20 12:00:36 +02001614 return false;
1615 }
1616
1617 if (0 == dwJPEGLineLength || 0 == dwVideoLineLength) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001618 ALOGE("There in no input information for decoding interleaved jpeg");
codeworkx62f02ba2012-05-20 12:00:36 +02001619 return false;
1620 }
1621
1622 unsigned char *pSrc = pFrame;
1623 unsigned char *pSrcEnd = pFrame + dwSize;
1624
1625 unsigned char *pJ = (unsigned char *)pJPEG;
1626 int dwJSize = 0;
1627 unsigned char *pV = (unsigned char *)pVideo;
1628 int dwVSize = 0;
1629
1630 bool bRet = false;
1631 bool isFinishJpeg = false;
1632
1633 while (pSrc < pSrcEnd) {
1634 // Check video start marker
1635 if (CheckVideoStartMarker(pSrc)) {
1636 int copyLength;
1637
1638 if (pSrc + dwVideoLineLength <= pSrcEnd)
1639 copyLength = dwVideoLineLength;
1640 else
1641 copyLength = pSrcEnd - pSrc - VIDEO_COMMENT_MARKER_LENGTH;
1642
1643 // Copy video data
1644 if (pV) {
1645 memcpy(pV, pSrc + VIDEO_COMMENT_MARKER_LENGTH, copyLength);
1646 pV += copyLength;
1647 dwVSize += copyLength;
1648 }
1649
1650 pSrc += copyLength + VIDEO_COMMENT_MARKER_LENGTH;
1651 } else {
1652 // Copy pure JPEG data
1653 int size = 0;
1654 int dwCopyBufLen = dwJPEGLineLength <= pSrcEnd-pSrc ? dwJPEGLineLength : pSrcEnd - pSrc;
1655
1656 if (FindEOIMarkerInJPEG((unsigned char *)pSrc, dwCopyBufLen, &size)) {
1657 isFinishJpeg = true;
1658 size += 2; // to count EOF marker size
1659 } else {
1660 if ((dwCopyBufLen == 1) && (pJPEG < pJ)) {
1661 unsigned char checkBuf[2] = { *(pJ - 1), *pSrc };
1662
1663 if (CheckEOIMarker(checkBuf))
1664 isFinishJpeg = true;
1665 }
1666 size = dwCopyBufLen;
1667 }
1668
1669 memcpy(pJ, pSrc, size);
1670
1671 dwJSize += size;
1672
1673 pJ += dwCopyBufLen;
1674 pSrc += dwCopyBufLen;
1675 }
1676 if (isFinishJpeg)
1677 break;
1678 }
1679
1680 if (isFinishJpeg) {
1681 bRet = true;
1682 if (pdwJPEGSize)
1683 *pdwJPEGSize = dwJSize;
1684 if (pdwVideoSize)
1685 *pdwVideoSize = dwVSize;
1686 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001687 ALOGE("DecodeInterleaveJPEG_WithOutDT() => Can not find EOI");
codeworkx62f02ba2012-05-20 12:00:36 +02001688 bRet = false;
1689 if (pdwJPEGSize)
1690 *pdwJPEGSize = 0;
1691 if (pdwVideoSize)
1692 *pdwVideoSize = 0;
1693 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001694 ALOGV("===========SplitFrame end==============");
codeworkx62f02ba2012-05-20 12:00:36 +02001695
1696 return bRet;
1697}
1698
1699int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData,
1700 int interleaveDataSize,
1701 int yuvWidth,
1702 int yuvHeight,
1703 int *pJpegSize,
1704 void *pJpegData,
1705 void *pYuvData)
1706{
1707 if (pInterleaveData == NULL)
1708 return false;
1709
1710 bool ret = true;
1711 unsigned int *interleave_ptr = (unsigned int *)pInterleaveData;
1712 unsigned char *jpeg_ptr = (unsigned char *)pJpegData;
1713 unsigned char *yuv_ptr = (unsigned char *)pYuvData;
1714 unsigned char *p;
1715 int jpeg_size = 0;
1716 int yuv_size = 0;
1717
1718 int i = 0;
1719
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001720 ALOGV("decodeInterleaveData Start~~~");
codeworkx62f02ba2012-05-20 12:00:36 +02001721 while (i < interleaveDataSize) {
1722 if ((*interleave_ptr == 0xFFFFFFFF) || (*interleave_ptr == 0x02FFFFFF) ||
1723 (*interleave_ptr == 0xFF02FFFF)) {
1724 // Padding Data
1725 interleave_ptr++;
1726 i += 4;
1727 } else if ((*interleave_ptr & 0xFFFF) == 0x05FF) {
1728 // Start-code of YUV Data
1729 p = (unsigned char *)interleave_ptr;
1730 p += 2;
1731 i += 2;
1732
1733 // Extract YUV Data
1734 if (pYuvData != NULL) {
1735 memcpy(yuv_ptr, p, yuvWidth * 2);
1736 yuv_ptr += yuvWidth * 2;
1737 yuv_size += yuvWidth * 2;
1738 }
1739 p += yuvWidth * 2;
1740 i += yuvWidth * 2;
1741
1742 // Check End-code of YUV Data
1743 if ((*p == 0xFF) && (*(p + 1) == 0x06)) {
1744 interleave_ptr = (unsigned int *)(p + 2);
1745 i += 2;
1746 } else {
1747 ret = false;
1748 break;
1749 }
1750 } else {
1751 // Extract JPEG Data
1752 if (pJpegData != NULL) {
1753 memcpy(jpeg_ptr, interleave_ptr, 4);
1754 jpeg_ptr += 4;
1755 jpeg_size += 4;
1756 }
1757 interleave_ptr++;
1758 i += 4;
1759 }
1760 }
1761 if (ret) {
1762 if (pJpegData != NULL) {
1763 // Remove Padding after EOI
1764 for (i = 0; i < 3; i++) {
1765 if (*(--jpeg_ptr) != 0xFF) {
1766 break;
1767 }
1768 jpeg_size--;
1769 }
1770 *pJpegSize = jpeg_size;
1771
1772 }
1773 // Check YUV Data Size
1774 if (pYuvData != NULL) {
1775 if (yuv_size != (yuvWidth * yuvHeight * 2)) {
1776 ret = false;
1777 }
1778 }
1779 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001780 ALOGV("decodeInterleaveData End~~~");
codeworkx62f02ba2012-05-20 12:00:36 +02001781 return ret;
1782}
1783
1784status_t CameraHardwareSec::dump(int fd) const
1785{
1786 const size_t SIZE = 256;
1787 char buffer[SIZE];
1788 String8 result;
1789 const Vector<String16> args;
1790
1791 if (mSecCamera != 0) {
1792 mSecCamera->dump(fd);
1793 mParameters.dump(fd, args);
1794 mInternalParameters.dump(fd, args);
1795 snprintf(buffer, 255, " preview running(%s)\n", mPreviewRunning?"true": "false");
1796 result.append(buffer);
1797 } else
1798 result.append("No camera client yet.\n");
1799 write(fd, result.string(), result.size());
1800 return NO_ERROR;
1801}
1802
1803bool CameraHardwareSec::isSupportedPreviewSize(const int width,
1804 const int height) const
1805{
1806 unsigned int i;
1807
1808 for (i = 0; i < mSupportedPreviewSizes.size(); i++) {
1809 if (mSupportedPreviewSizes[i].width == width &&
1810 mSupportedPreviewSizes[i].height == height)
1811 return true;
1812 }
1813
1814 return false;
1815}
1816
1817bool CameraHardwareSec::getVideosnapshotSize(int *width, int *height)
1818{
1819 unsigned int i;
1820 Vector<Size> pictureSizes, videoSizes;
1821 int ratio = FRM_RATIO(*width, *height);
1822
1823 mParameters.getSupportedPictureSizes(pictureSizes);
1824 mParameters.getSupportedVideoSizes(videoSizes);
1825
1826 for (i = 0; i < pictureSizes.size(); i++) {
1827 if (FRM_RATIO(pictureSizes[i].width, pictureSizes[i].height) == ratio) {
1828 if (mRecordHint) {
1829 if (pictureSizes[i].width <= videoSizes[0].width) {
1830 *width = pictureSizes[i].width;
1831 *height = pictureSizes[i].height;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001832 ALOGV("%s(width(%d), height(%d))", __func__, *width, *height);
codeworkx62f02ba2012-05-20 12:00:36 +02001833 return true;
1834 }
1835 } else {
1836 *width = pictureSizes[i].width;
1837 *height = pictureSizes[i].height;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001838 ALOGV("%s(width(%d), height(%d))", __func__, *width, *height);
codeworkx62f02ba2012-05-20 12:00:36 +02001839 return true;
1840 }
1841 }
1842 }
1843
1844 return false;
1845}
1846
1847status_t CameraHardwareSec::setParameters(const CameraParameters& params)
1848{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001849 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001850
1851 status_t ret = NO_ERROR;
1852
1853 const char *new_record_hint_str = params.get(CameraParameters::KEY_RECORDING_HINT);
1854 const char *curr_record_hint_str = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001855 ALOGV("new_record_hint_str: %s", new_record_hint_str);
codeworkx62f02ba2012-05-20 12:00:36 +02001856
1857 if (new_record_hint_str) {
1858 if (strncmp(new_record_hint_str, curr_record_hint_str, 5)) {
1859 mRecordHint = !strncmp(new_record_hint_str, "true", 4);
1860 if (mSecCamera->setMode(mRecordHint) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001861 ALOGE("ERR(%s):fail on mSecCamera->setMode(%d)", __func__, mRecordHint);
codeworkx62f02ba2012-05-20 12:00:36 +02001862 ret = UNKNOWN_ERROR;
1863 } else {
1864 mParameters.set(CameraParameters::KEY_RECORDING_HINT, new_record_hint_str);
1865 }
1866
1867 if (mUseInternalISP) {
1868 if (mSecCamera->initSetParams() < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001869 ALOGE("ERR(%s):fail on mSecCamera->initSetParams()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001870 ret = UNKNOWN_ERROR;
1871 }
1872 }
1873 }
1874 }
1875
1876 /* if someone calls us while picture thread is running, it could screw
1877 * up the sensor quite a bit so return error. we can't wait because
1878 * that would cause deadlock with the callbacks
1879 */
1880 mStateLock.lock();
1881 if (mCaptureInProgress) {
1882 mStateLock.unlock();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001883 ALOGE("%s : capture in progress, not allowed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001884 return UNKNOWN_ERROR;
1885 }
1886 mStateLock.unlock();
1887
1888 // preview size
1889 int new_preview_width = 0;
1890 int new_preview_height = 0;
1891 int new_preview_format = 0;
1892
1893 params.getPreviewSize(&new_preview_width, &new_preview_height);
1894
1895 if (mUseInternalISP) {
1896 int videosnapshot_width = new_preview_width;
1897 int videosnapshot_height = new_preview_height;
1898
1899 if (!getVideosnapshotSize(&videosnapshot_width, &videosnapshot_height)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001900 ALOGE("ERR(%s):fail on getVideosnapshotSize(width(%d), height(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02001901 __func__, videosnapshot_width, videosnapshot_height);
1902 ret = UNKNOWN_ERROR;
1903 }
1904
1905 if (mSecCamera->setVideosnapshotSize(videosnapshot_width, videosnapshot_height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001906 ALOGE("ERR(%s):fail on mSecCamera->setVideosnapshotSize(width(%d), height(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02001907 __func__, videosnapshot_width, videosnapshot_height);
1908 ret = UNKNOWN_ERROR;
1909 }
1910 }
1911
1912 const char *new_str_preview_format = params.getPreviewFormat();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001913 ALOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s",
codeworkx62f02ba2012-05-20 12:00:36 +02001914 __func__, new_preview_width, new_preview_height, new_str_preview_format);
1915
1916 if (0 < new_preview_width && 0 < new_preview_height &&
1917 new_str_preview_format != NULL &&
1918 isSupportedPreviewSize(new_preview_width, new_preview_height)) {
1919
1920 mFrameSizeDelta = 16;
1921 if (!strcmp(new_str_preview_format,
1922 CameraParameters::PIXEL_FORMAT_RGB565)) {
1923 new_preview_format = V4L2_PIX_FMT_RGB565;
1924 mFrameSizeDelta = 0;
1925 }
1926 else if (!strcmp(new_str_preview_format,
1927 CameraParameters::PIXEL_FORMAT_RGBA8888)) {
1928 new_preview_format = V4L2_PIX_FMT_RGB32;
1929 mFrameSizeDelta = 0;
1930 }
1931 else if (!strcmp(new_str_preview_format,
1932 CameraParameters::PIXEL_FORMAT_YUV420SP)) {
1933 new_preview_format = V4L2_PIX_FMT_NV21;
1934 mPreviewFmtPlane = PREVIEW_FMT_2_PLANE;
1935 }
1936 else if (!strcmp(new_str_preview_format,
1937 CameraParameters::PIXEL_FORMAT_YUV420P)) {
1938#ifdef BOARD_USE_V4L2_ION
1939 new_preview_format = V4L2_PIX_FMT_YVU420M;
1940#else
1941 new_preview_format = V4L2_PIX_FMT_YVU420;
1942#endif
1943 mPreviewFmtPlane = PREVIEW_FMT_3_PLANE;
1944 }
1945 else if (!strcmp(new_str_preview_format, "yuv420sp_custom"))
1946 new_preview_format = V4L2_PIX_FMT_NV12T;
1947 else if (!strcmp(new_str_preview_format, "yuv422i"))
1948 new_preview_format = V4L2_PIX_FMT_YUYV;
1949 else if (!strcmp(new_str_preview_format, "yuv422p"))
1950 new_preview_format = V4L2_PIX_FMT_YUV422P;
1951 else
1952 new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party
1953
1954 int current_preview_width, current_preview_height, current_frame_size;
1955 mSecCamera->getPreviewSize(&current_preview_width,
1956 &current_preview_height,
1957 &current_frame_size);
1958 int current_pixel_format = mSecCamera->getPreviewPixelFormat();
1959
1960 if (current_preview_width != new_preview_width ||
1961 current_preview_height != new_preview_height ||
1962 current_pixel_format != new_preview_format) {
1963 if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height,
1964 new_preview_format) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001965 ALOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02001966 __func__, new_preview_width, new_preview_height, new_preview_format);
1967 ret = UNKNOWN_ERROR;
1968 } else {
1969 if (mPreviewWindow) {
1970 if (mPreviewRunning && !mPreviewStartDeferred) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001971 ALOGE("ERR(%s): preview is running, cannot change size and format!", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001972 ret = INVALID_OPERATION;
1973 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001974 ALOGV("%s: mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
1975 ALOGV("%s: mPreviewWindow->set_buffers_geometry (%p)", __func__,
codeworkx62f02ba2012-05-20 12:00:36 +02001976 mPreviewWindow->set_buffers_geometry);
1977 mPreviewWindow->set_buffers_geometry(mPreviewWindow,
1978 new_preview_width, new_preview_height,
1979 V4L2_PIX_2_HAL_PIXEL_FORMAT(new_preview_format));
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001980 ALOGV("%s: DONE mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
codeworkx62f02ba2012-05-20 12:00:36 +02001981 }
1982 mParameters.setPreviewSize(new_preview_width, new_preview_height);
1983 mParameters.setPreviewFormat(new_str_preview_format);
1984 }
1985 }
1986 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001987 ALOGE("%s: Invalid preview size(%dx%d)",
codeworkx62f02ba2012-05-20 12:00:36 +02001988 __func__, new_preview_width, new_preview_height);
1989
1990 ret = INVALID_OPERATION;
1991 }
1992
1993 // picture size
1994 int new_picture_width = 0;
1995 int new_picture_height = 0;
1996
1997 params.getPictureSize(&new_picture_width, &new_picture_height);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001998 ALOGV("%s : new_picture_width x new_picture_height = %dx%d", __func__, new_picture_width, new_picture_height);
codeworkx62f02ba2012-05-20 12:00:36 +02001999
2000 int current_picture_width, current_picture_height, current_picture_size;
2001 mSecCamera->getSnapshotSize(&current_picture_width, &current_picture_height, &current_picture_size);
2002
2003 if (new_picture_width != current_picture_width ||
2004 new_picture_height != current_picture_height) {
2005 if (mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002006 ALOGE("ERR(%s):fail on mSecCamera->setSnapshotSize(width(%d), height(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02002007 __func__, new_picture_width, new_picture_height);
2008 ret = UNKNOWN_ERROR;
2009 } else {
2010#ifdef ZERO_SHUTTER_LAG
2011 mSecCamera->stopSnapshot();
2012 if (mUseInternalISP && !mRecordHint && mPreviewRunning){
2013 mSecCamera->startSnapshot(NULL);
2014 }
2015#endif
2016 mParameters.setPictureSize(new_picture_width, new_picture_height);
2017 }
2018 }
2019
2020 // picture format
2021 const char *new_str_picture_format = params.getPictureFormat();
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002022 ALOGV("%s : new_str_picture_format %s", __func__, new_str_picture_format);
codeworkx62f02ba2012-05-20 12:00:36 +02002023 if (new_str_picture_format != NULL) {
2024 int new_picture_format = 0;
2025
2026 if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGB565))
2027 new_picture_format = V4L2_PIX_FMT_RGB565;
2028 else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGBA8888))
2029 new_picture_format = V4L2_PIX_FMT_RGB32;
2030 else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_YUV420SP))
2031 new_picture_format = V4L2_PIX_FMT_NV21;
2032 else if (!strcmp(new_str_picture_format, "yuv420sp_custom"))
2033 new_picture_format = V4L2_PIX_FMT_NV12T;
2034 else if (!strcmp(new_str_picture_format, "yuv420p"))
2035 new_picture_format = V4L2_PIX_FMT_YUV420;
2036 else if (!strcmp(new_str_picture_format, "yuv422i"))
2037 new_picture_format = V4L2_PIX_FMT_YUYV;
2038 else if (!strcmp(new_str_picture_format, "uyv422i_custom")) //Zero copy UYVY format
2039 new_picture_format = V4L2_PIX_FMT_UYVY;
2040 else if (!strcmp(new_str_picture_format, "uyv422i")) //Non-zero copy UYVY format
2041 new_picture_format = V4L2_PIX_FMT_UYVY;
2042 else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_JPEG))
2043 new_picture_format = V4L2_PIX_FMT_YUYV;
2044 else if (!strcmp(new_str_picture_format, "yuv422p"))
2045 new_picture_format = V4L2_PIX_FMT_YUV422P;
2046 else
2047 new_picture_format = V4L2_PIX_FMT_NV21; //for 3rd party
2048
2049 if (mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002050 ALOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __func__, new_picture_format);
codeworkx62f02ba2012-05-20 12:00:36 +02002051 ret = UNKNOWN_ERROR;
2052 } else
2053 mParameters.setPictureFormat(new_str_picture_format);
2054 }
2055
2056 // JPEG image quality
2057 int new_jpeg_quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002058 ALOGV("%s : new_jpeg_quality %d", __func__, new_jpeg_quality);
codeworkx62f02ba2012-05-20 12:00:36 +02002059 /* we ignore bad values */
2060 if (new_jpeg_quality >=1 && new_jpeg_quality <= 100) {
2061 if (mSecCamera->setJpegQuality(new_jpeg_quality) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002062 ALOGE("ERR(%s):Fail on mSecCamera->setJpegQuality(quality(%d))", __func__, new_jpeg_quality);
codeworkx62f02ba2012-05-20 12:00:36 +02002063 ret = UNKNOWN_ERROR;
2064 } else
2065 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, new_jpeg_quality);
2066 }
2067
2068 // JPEG thumbnail size
2069 int new_jpeg_thumbnail_width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
2070 int new_jpeg_thumbnail_height= params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
2071 if (0 <= new_jpeg_thumbnail_width && 0 <= new_jpeg_thumbnail_height) {
2072 if (mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002073 ALOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __func__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height);
codeworkx62f02ba2012-05-20 12:00:36 +02002074 ret = UNKNOWN_ERROR;
2075 } else {
2076 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, new_jpeg_thumbnail_width);
2077 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, new_jpeg_thumbnail_height);
2078 }
2079 }
2080
2081 // JPEG thumbnail quality
2082 int new_jpeg_thumbnail_quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002083 ALOGV("%s : new_jpeg_thumbnail_quality %d", __func__, new_jpeg_thumbnail_quality);
codeworkx62f02ba2012-05-20 12:00:36 +02002084 /* we ignore bad values */
2085 if (new_jpeg_thumbnail_quality >=1 && new_jpeg_thumbnail_quality <= 100) {
2086 if (mSecCamera->setJpegThumbnailQuality(new_jpeg_thumbnail_quality) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002087 ALOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailQuality(quality(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02002088 __func__, new_jpeg_thumbnail_quality);
2089 ret = UNKNOWN_ERROR;
2090 } else
2091 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, new_jpeg_thumbnail_quality);
2092 }
2093
2094 // frame rate
2095 int new_frame_rate = params.getPreviewFrameRate();
2096 /* ignore any fps request, we're determine fps automatically based
2097 * on scene mode. don't return an error because it causes CTS failure.
2098 */
2099 if (mRecordHint) {
2100 if (new_frame_rate) {
2101 if (mUseInternalISP && (mSecCamera->setFrameRate(new_frame_rate) < 0)){
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002102 ALOGE("ERR(%s):Fail on mSecCamera->setFrameRate(%d)", __func__, new_frame_rate);
codeworkx62f02ba2012-05-20 12:00:36 +02002103 ret = UNKNOWN_ERROR;
2104 } else {
2105 mParameters.setPreviewFrameRate(new_frame_rate);
2106 }
2107 }
2108 }
2109
2110 // rotation
2111 int new_rotation = params.getInt(CameraParameters::KEY_ROTATION);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002112 ALOGV("%s : new_rotation %d", __func__, new_rotation);
codeworkx62f02ba2012-05-20 12:00:36 +02002113 if (0 <= new_rotation) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002114 ALOGV("%s : set orientation:%d", __func__, new_rotation);
codeworkx62f02ba2012-05-20 12:00:36 +02002115 if (mSecCamera->setExifOrientationInfo(new_rotation) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002116 ALOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_rotation);
codeworkx62f02ba2012-05-20 12:00:36 +02002117 ret = UNKNOWN_ERROR;
2118 } else
2119 mParameters.set(CameraParameters::KEY_ROTATION, new_rotation);
2120 }
2121
2122 // zoom
2123 int new_zoom = params.getInt(CameraParameters::KEY_ZOOM);
2124 int current_zoom = mParameters.getInt(CameraParameters::KEY_ZOOM);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002125 ALOGV("%s : new_zoom %d", __func__, new_zoom);
codeworkx62f02ba2012-05-20 12:00:36 +02002126 if (0 <= new_zoom) {
2127 if (new_zoom != current_zoom) {
2128 if (mSecCamera->setZoom(new_zoom) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002129 ALOGE("ERR(%s):Fail on mSecCamera->setZoom(zoom(%d))", __func__, new_zoom);
codeworkx62f02ba2012-05-20 12:00:36 +02002130 ret = UNKNOWN_ERROR;
2131 } else {
2132 mParameters.set(CameraParameters::KEY_ZOOM, new_zoom);
2133 }
2134 }
2135 }
2136
2137 // brightness
2138 int new_brightness = params.getInt("brightness");
2139 int max_brightness = params.getInt("brightness-max");
2140 int min_brightness = params.getInt("brightness-min");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002141 ALOGV("%s : new_brightness %d", __func__, new_brightness);
codeworkx62f02ba2012-05-20 12:00:36 +02002142 if ((min_brightness <= new_brightness) &&
2143 (max_brightness >= new_brightness)) {
2144 if (mSecCamera->setBrightness(new_brightness) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002145 ALOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_brightness);
codeworkx62f02ba2012-05-20 12:00:36 +02002146 ret = UNKNOWN_ERROR;
2147 } else {
2148 mParameters.set("brightness", new_brightness);
2149 }
2150 }
2151
2152 // saturation
2153 int new_saturation = params.getInt("saturation");
2154 int max_saturation = params.getInt("saturation-max");
2155 int min_saturation = params.getInt("saturation-min");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002156 ALOGV("%s : new_saturation %d", __func__, new_saturation);
codeworkx62f02ba2012-05-20 12:00:36 +02002157 if ((min_saturation <= new_saturation) &&
2158 (max_saturation >= new_saturation)) {
2159 if (mSecCamera->setSaturation(new_saturation) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002160 ALOGE("ERR(%s):Fail on mSecCamera->setSaturation(saturation(%d))", __func__, new_saturation);
codeworkx62f02ba2012-05-20 12:00:36 +02002161 ret = UNKNOWN_ERROR;
2162 } else {
2163 mParameters.set("saturation", new_saturation);
2164 }
2165 }
2166
2167 // sharpness
2168 int new_sharpness = params.getInt("sharpness");
2169 int max_sharpness = params.getInt("sharpness-max");
2170 int min_sharpness = params.getInt("sharpness-min");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002171 ALOGV("%s : new_sharpness %d", __func__, new_sharpness);
codeworkx62f02ba2012-05-20 12:00:36 +02002172 if ((min_sharpness <= new_sharpness) &&
2173 (max_sharpness >= new_sharpness)) {
2174 if (mSecCamera->setSharpness(new_sharpness) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002175 ALOGE("ERR(%s):Fail on mSecCamera->setSharpness(sharpness(%d))", __func__, new_sharpness);
codeworkx62f02ba2012-05-20 12:00:36 +02002176 ret = UNKNOWN_ERROR;
2177 } else {
2178 mParameters.set("sharpness", new_sharpness);
2179 }
2180 }
2181
2182 // hue
2183 int new_hue = params.getInt("hue");
2184 int max_hue = params.getInt("hue-max");
2185 int min_hue = params.getInt("hue-min");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002186 ALOGV("%s : new_hue %d", __func__, new_hue);
codeworkx62f02ba2012-05-20 12:00:36 +02002187 if ((min_hue <= new_hue) &&
2188 (max_hue >= new_hue)) {
2189 if (mSecCamera->setHue(new_hue) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002190 ALOGE("ERR(%s):Fail on mSecCamera->setHue(hue(%d))", __func__, new_hue);
codeworkx62f02ba2012-05-20 12:00:36 +02002191 ret = UNKNOWN_ERROR;
2192 } else {
2193 mParameters.set("hue", new_hue);
2194 }
2195 }
2196
2197 // exposure
2198 int new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
2199 int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
2200 int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002201 ALOGV("%s : new_exposure_compensation %d", __func__, new_exposure_compensation);
codeworkx62f02ba2012-05-20 12:00:36 +02002202 if ((min_exposure_compensation <= new_exposure_compensation) &&
2203 (max_exposure_compensation >= new_exposure_compensation)) {
2204 if (mSecCamera->setExposure(new_exposure_compensation) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002205 ALOGE("ERR(%s):Fail on mSecCamera->setExposure(exposure(%d))", __func__, new_exposure_compensation);
codeworkx62f02ba2012-05-20 12:00:36 +02002206 ret = UNKNOWN_ERROR;
2207 } else {
2208 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, new_exposure_compensation);
2209 }
2210 }
2211
2212 const char *new_AE_lock = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK);
2213 const char *old_AE_lock = mParameters.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK);
2214 if ((new_AE_lock != NULL) && mUseInternalISP && mPreviewRunning) {
2215 if (strncmp(new_AE_lock, old_AE_lock, 4)) {
2216 int ae_value = !strncmp(new_AE_lock, "true", 4);
2217 if (mSecCamera->setAutoExposureLock(ae_value) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002218 ALOGE("ERR(%s):Fail on mSecCamera->setExposureLock", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02002219 ret = UNKNOWN_ERROR;
2220 } else {
2221 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, new_AE_lock);
2222 }
2223 }
2224 }
2225
2226 // ISO
2227 const char *new_iso_str = params.get("iso");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002228 ALOGV("%s : new_iso_str %s", __func__, new_iso_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002229 if (new_iso_str != NULL) {
2230 int new_iso = -1;
2231
2232 if (!strcmp(new_iso_str, "auto")) {
2233 new_iso = ISO_AUTO;
2234 } else if (!strcmp(new_iso_str, "50")) {
2235 new_iso = ISO_50;
2236 } else if (!strcmp(new_iso_str, "100")) {
2237 new_iso = ISO_100;
2238 } else if (!strcmp(new_iso_str, "200")) {
2239 new_iso = ISO_200;
2240 } else if (!strcmp(new_iso_str, "400")) {
2241 new_iso = ISO_400;
2242 } else if (!strcmp(new_iso_str, "800")) {
2243 new_iso = ISO_800;
2244 } else if (!strcmp(new_iso_str, "1600")) {
2245 new_iso = ISO_1600;
2246 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002247 ALOGE("ERR(%s):Invalid iso value(%s)", __func__, new_iso_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002248 ret = UNKNOWN_ERROR;
2249 }
2250
2251 if (0 <= new_iso) {
2252 if (mSecCamera->setISO(new_iso) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002253 ALOGE("ERR(%s):Fail on mSecCamera->setISO(iso(%d))", __func__, new_iso);
codeworkx62f02ba2012-05-20 12:00:36 +02002254 ret = UNKNOWN_ERROR;
2255 } else {
2256 mParameters.set("iso", new_iso_str);
2257 }
2258 }
2259 }
2260
2261 // Metering
2262 const char *new_metering_str = params.get("metering");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002263 ALOGV("%s : new_metering_str %s", __func__, new_metering_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002264 if (new_metering_str != NULL) {
2265 int new_metering = -1;
2266
2267 if (!strcmp(new_metering_str, "center")) {
2268 new_metering = METERING_CENTER;
2269 } else if (!strcmp(new_metering_str, "spot")) {
2270 new_metering = METERING_SPOT;
2271 } else if (!strcmp(new_metering_str, "matrix")) {
2272 new_metering = METERING_MATRIX;
2273 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002274 ALOGE("ERR(%s):Invalid metering value(%s)", __func__, new_metering_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002275 ret = UNKNOWN_ERROR;
2276 }
2277
2278 if (0 <= new_metering) {
2279 if (mSecCamera->setMetering(new_metering) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002280 ALOGE("ERR(%s):Fail on mSecCamera->setMetering(metering(%d))", __func__, new_metering);
codeworkx62f02ba2012-05-20 12:00:36 +02002281 ret = UNKNOWN_ERROR;
2282 } else {
2283 mParameters.set("metering", new_metering_str);
2284 }
2285 }
2286 }
2287
2288 // AFC
2289 const char *new_antibanding_str = params.get(CameraParameters::KEY_ANTIBANDING);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002290 ALOGV("%s : new_antibanding_str %s", __func__, new_antibanding_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002291 if (new_antibanding_str != NULL) {
2292 int new_antibanding = -1;
2293
2294 if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_AUTO)) {
2295 if (mUseInternalISP)
2296 new_antibanding = IS_AFC_AUTO;
2297 else
2298 new_antibanding = ANTI_BANDING_AUTO;
2299 } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_50HZ)) {
2300 if (mUseInternalISP)
2301 new_antibanding = IS_AFC_MANUAL_50HZ;
2302 else
2303 new_antibanding = ANTI_BANDING_50HZ;
2304 } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_60HZ)) {
2305 if (mUseInternalISP)
2306 new_antibanding = IS_AFC_MANUAL_60HZ;
2307 else
2308 new_antibanding = ANTI_BANDING_60HZ;
2309 } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_OFF)) {
2310 if (mUseInternalISP)
2311 new_antibanding = IS_AFC_DISABLE;
2312 else
2313 new_antibanding = ANTI_BANDING_OFF;
2314 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002315 ALOGE("ERR(%s):Invalid antibanding value(%s)", __func__, new_antibanding_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002316 ret = UNKNOWN_ERROR;
2317 }
2318
2319 if (0 <= new_antibanding) {
2320 if (mSecCamera->setAntiBanding(new_antibanding) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002321 ALOGE("ERR(%s):Fail on mSecCamera->setAntiBanding(antibanding(%d))", __func__, new_antibanding);
codeworkx62f02ba2012-05-20 12:00:36 +02002322 ret = UNKNOWN_ERROR;
2323 } else {
2324 mParameters.set(CameraParameters::KEY_ANTIBANDING, new_antibanding_str);
2325 }
2326 }
2327 }
2328
2329 // scene mode
2330 const char *new_scene_mode_str = params.get(CameraParameters::KEY_SCENE_MODE);
2331 const char *current_scene_mode_str = mParameters.get(CameraParameters::KEY_SCENE_MODE);
2332
2333 // fps range
2334 int new_min_fps = 0;
2335 int new_max_fps = 0;
2336 int current_min_fps, current_max_fps;
2337 params.getPreviewFpsRange(&new_min_fps, &new_max_fps);
2338 mParameters.getPreviewFpsRange(&current_min_fps, &current_max_fps);
2339 /* our fps range is determined by the sensor, reject any request
2340 * that isn't exactly what we're already at.
2341 * but the check is performed when requesting only changing fps range
2342 */
2343 if (new_scene_mode_str && current_scene_mode_str) {
2344 if (!strcmp(new_scene_mode_str, current_scene_mode_str)) {
2345 if ((new_min_fps != current_min_fps) || (new_max_fps != current_max_fps)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002346 ALOGW("%s : requested new_min_fps = %d, new_max_fps = %d not allowed",
codeworkx62f02ba2012-05-20 12:00:36 +02002347 __func__, new_min_fps, new_max_fps);
2348 /* TODO : We need policy for fps. */
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002349 ALOGW("%s : current_min_fps = %d, current_max_fps = %d",
codeworkx62f02ba2012-05-20 12:00:36 +02002350 __func__, current_min_fps, current_max_fps);
2351 //ret = UNKNOWN_ERROR;
2352 }
2353 }
2354 } else {
2355 /* Check basic validation if scene mode is different */
2356 if ((new_min_fps > new_max_fps) ||
2357 (new_min_fps < 0) || (new_max_fps < 0))
2358 ret = UNKNOWN_ERROR;
2359 }
2360
2361 const char *new_flash_mode_str = params.get(CameraParameters::KEY_FLASH_MODE);
2362 const char *new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE);
2363 const char *new_white_str = params.get(CameraParameters::KEY_WHITE_BALANCE);
2364
2365 // fps range is (15000,30000) by default.
2366 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)");
2367 mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000");
2368
2369 if ((new_scene_mode_str != NULL) && (current_scene_mode_str != NULL) && strncmp(new_scene_mode_str, current_scene_mode_str, 5)) {
2370 int new_scene_mode = -1;
2371 if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) {
2372 new_scene_mode = SCENE_MODE_NONE;
2373 } else {
2374 // defaults for non-auto scene modes
2375 new_focus_mode_str = CameraParameters::FOCUS_MODE_AUTO;
2376 new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
2377 new_white_str = CameraParameters::WHITE_BALANCE_AUTO;
2378 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str);
2379
2380 if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_PORTRAIT)) {
2381 new_scene_mode = SCENE_MODE_PORTRAIT;
2382 if (mCameraID == SecCamera::CAMERA_ID_BACK)
2383 new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
2384 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_LANDSCAPE)) {
2385 new_scene_mode = SCENE_MODE_LANDSCAPE;
2386 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SPORTS)) {
2387 new_scene_mode = SCENE_MODE_SPORTS;
2388 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_PARTY)) {
2389 new_scene_mode = SCENE_MODE_PARTY_INDOOR;
2390 if (mCameraID == SecCamera::CAMERA_ID_BACK)
2391 new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
2392 } else if ((!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_BEACH)) ||
2393 (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SNOW))) {
2394 new_scene_mode = SCENE_MODE_BEACH_SNOW;
2395 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SUNSET)) {
2396 new_scene_mode = SCENE_MODE_SUNSET;
2397 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_NIGHT)) {
2398 new_scene_mode = SCENE_MODE_NIGHTSHOT;
2399 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(4000,30000)");
2400 mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "4000,30000");
2401 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_FIREWORKS)) {
2402 new_scene_mode = SCENE_MODE_FIREWORKS;
2403 } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_CANDLELIGHT)) {
2404 new_scene_mode = SCENE_MODE_CANDLE_LIGHT;
2405 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002406 ALOGE("%s::unmatched scene_mode(%s)",
codeworkx62f02ba2012-05-20 12:00:36 +02002407 __func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto
2408 ret = UNKNOWN_ERROR;
2409 }
2410 }
2411
2412 if (0 <= new_scene_mode) {
2413 if (mSecCamera->setSceneMode(new_scene_mode) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002414 ALOGE("%s::mSecCamera->setSceneMode(%d) fail", __func__, new_scene_mode);
codeworkx62f02ba2012-05-20 12:00:36 +02002415 ret = UNKNOWN_ERROR;
2416 } else {
2417 mParameters.set(CameraParameters::KEY_SCENE_MODE, new_scene_mode_str);
2418 }
2419 }
2420 }
2421
2422 // focus mode
2423 /* TODO : currently only posible focus modes at BACK camera */
2424 if ((new_focus_mode_str != NULL) && (mCameraID == SecCamera::CAMERA_ID_BACK)) {
2425 int new_focus_mode = -1;
2426
2427 if (!strcmp(new_focus_mode_str,
2428 CameraParameters::FOCUS_MODE_AUTO)) {
2429 new_focus_mode = FOCUS_MODE_AUTO;
2430 mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
2431 BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR);
2432 } else if (!strcmp(new_focus_mode_str,
2433 CameraParameters::FOCUS_MODE_MACRO)) {
2434 new_focus_mode = FOCUS_MODE_MACRO;
2435 mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
2436 BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR);
2437 } else if (!strcmp(new_focus_mode_str,
2438 CameraParameters::FOCUS_MODE_INFINITY)) {
2439 new_focus_mode = FOCUS_MODE_INFINITY;
2440 mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
2441 BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR);
2442 } else if (!strcmp(new_focus_mode_str,
2443 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ||
2444 !strcmp(new_focus_mode_str,
2445 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) {
2446 new_focus_mode = FOCUS_MODE_CONTINOUS;
2447 } else {
2448 /* TODO */
2449 /* This is temperary implementation.
2450 When camera support all AF mode, this code will be changing */
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002451 ALOGE("%s::unmatched focus_mode(%s)", __func__, new_focus_mode_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002452 ret = UNKNOWN_ERROR;
2453 }
2454
2455 if (0 <= new_focus_mode) {
2456 if (mSecCamera->setFocusMode(new_focus_mode) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002457 ALOGE("%s::mSecCamera->setFocusMode(%d) fail", __func__, new_focus_mode);
codeworkx62f02ba2012-05-20 12:00:36 +02002458 ret = UNKNOWN_ERROR;
2459 } else {
2460 mParameters.set(CameraParameters::KEY_FOCUS_MODE, new_focus_mode_str);
2461 }
2462 }
2463 }
2464
2465 // flash..
2466 if (new_flash_mode_str != NULL) {
2467 int new_flash_mode = -1;
2468
2469 if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_OFF))
2470 new_flash_mode = FLASH_MODE_OFF;
2471 else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_AUTO))
2472 new_flash_mode = FLASH_MODE_AUTO;
2473 else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_ON))
2474 new_flash_mode = FLASH_MODE_ON;
2475 else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_TORCH))
2476 new_flash_mode = FLASH_MODE_TORCH;
2477 else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002478 ALOGE("%s::unmatched flash_mode(%s)", __func__, new_flash_mode_str); //red-eye
codeworkx62f02ba2012-05-20 12:00:36 +02002479 ret = UNKNOWN_ERROR;
2480 }
2481 if (0 <= new_flash_mode) {
2482 if (mSecCamera->setFlashMode(new_flash_mode) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002483 ALOGE("%s::mSecCamera->setFlashMode(%d) fail", __func__, new_flash_mode);
codeworkx62f02ba2012-05-20 12:00:36 +02002484 ret = UNKNOWN_ERROR;
2485 } else {
2486 mParameters.set(CameraParameters::KEY_FLASH_MODE, new_flash_mode_str);
2487 }
2488 }
2489 }
2490
2491 // whitebalance
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002492 ALOGV("%s : new_white_str %s", __func__, new_white_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002493 if ((new_scene_mode_str != NULL) && !strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) {
2494 if (new_white_str != NULL) {
2495 int new_white = -1;
2496
2497 if (!strcmp(new_white_str, CameraParameters::WHITE_BALANCE_AUTO)) {
2498 new_white = WHITE_BALANCE_AUTO;
2499 } else if (!strcmp(new_white_str,
2500 CameraParameters::WHITE_BALANCE_DAYLIGHT)) {
2501 new_white = WHITE_BALANCE_SUNNY;
2502 } else if (!strcmp(new_white_str,
2503 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT)) {
2504 new_white = WHITE_BALANCE_CLOUDY;
2505 } else if (!strcmp(new_white_str,
2506 CameraParameters::WHITE_BALANCE_FLUORESCENT)) {
2507 new_white = WHITE_BALANCE_FLUORESCENT;
2508 } else if (!strcmp(new_white_str,
2509 CameraParameters::WHITE_BALANCE_INCANDESCENT)) {
2510 new_white = WHITE_BALANCE_TUNGSTEN;
2511 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002512 ALOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); //twilight, shade, warm_flourescent
codeworkx62f02ba2012-05-20 12:00:36 +02002513 ret = UNKNOWN_ERROR;
2514 }
2515
2516 if (0 <= new_white) {
2517 if (mSecCamera->setWhiteBalance(new_white) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002518 ALOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white);
codeworkx62f02ba2012-05-20 12:00:36 +02002519 ret = UNKNOWN_ERROR;
2520 } else {
2521 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str);
2522 }
2523 }
2524 }
2525 }
2526
2527 const char *new_AWB_lock = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK);
2528 const char *old_AWB_lock = mParameters.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK);
2529 if (new_AWB_lock != NULL && mUseInternalISP && mPreviewRunning) {
2530 if (strncmp(new_AWB_lock, old_AWB_lock, 4)) {
2531 int awb_value = !strncmp(new_AWB_lock, "true", 4);
2532 if (mSecCamera->setAutoWhiteBalanceLock(awb_value) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002533 ALOGE("ERR(%s):Fail on mSecCamera->setoAutoWhiteBalanceLock()", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02002534 ret = UNKNOWN_ERROR;
2535 } else {
2536 mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, new_AWB_lock);
2537 }
2538 }
2539 }
2540
2541 const char *new_touch_rect_str = params.get(CameraParameters::KEY_FOCUS_AREAS);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002542 ALOGV("Touched rect is '%s'", new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002543
2544 if (new_touch_rect_str != NULL) {
2545 int left = 0, top = 0, right = 0, bottom = 0, touched = 0;
2546 int objx, objy;
2547
2548 char *end;
2549 char delim = ',';
2550 left = (int)strtol(new_touch_rect_str+1, &end, 10);
2551 if (*end != delim) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002552 ALOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002553 return -1;
2554 }
2555 top = (int)strtol(end+1, &end, 10);
2556 if (*end != delim) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002557 ALOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002558 return -1;
2559 }
2560 right = (int)strtol(end+1, &end, 10);
2561 if (*end != delim) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002562 ALOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002563 return -1;
2564 }
2565 bottom = (int)strtol(end+1, &end, 10);
2566 if (*end != delim) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002567 ALOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002568 return -1;
2569 }
2570 touched = (int)strtol(end+1, &end, 10);
2571 if (*end != ')') {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002572 ALOGE("Cannot find ')' in str=%s", new_touch_rect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002573 return -1;
2574 }
2575
2576 /* TODO : Converting axis and Calcurating center of rect. Because driver need (x, y) point. */
2577 objx = (int)((1023 * (left + 1000)) / 2000) + 97;
2578 objy = (int)((1023 * (top + 1000)) / 2000) + 128;
2579
2580 mTouched = touched;
2581 mSecCamera->setObjectPosition(objx, objy);
2582 }
2583
2584 // image effect
2585 const char *new_image_effect_str = params.get(CameraParameters::KEY_EFFECT);
2586 if (new_image_effect_str != NULL) {
2587
2588 int new_image_effect = -1;
2589
2590 if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NONE)) {
2591 new_image_effect = IMAGE_EFFECT_NONE;
2592 } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_MONO)) {
2593 new_image_effect = IMAGE_EFFECT_BNW;
2594 } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_SEPIA)) {
2595 new_image_effect = IMAGE_EFFECT_SEPIA;
2596 } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_AQUA))
2597 new_image_effect = IMAGE_EFFECT_AQUA;
2598 else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NEGATIVE)) {
2599 new_image_effect = IMAGE_EFFECT_NEGATIVE;
2600 } else {
2601 //posterize, whiteboard, blackboard, solarize
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002602 ALOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002603 ret = UNKNOWN_ERROR;
2604 }
2605
2606 if (new_image_effect >= 0) {
2607 if (mSecCamera->setImageEffect(new_image_effect) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002608 ALOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect);
codeworkx62f02ba2012-05-20 12:00:36 +02002609 ret = UNKNOWN_ERROR;
2610 } else {
2611 const char *old_image_effect_str = mParameters.get(CameraParameters::KEY_EFFECT);
2612
2613 if (old_image_effect_str) {
2614 if (strcmp(old_image_effect_str, new_image_effect_str)) {
2615 setSkipFrame(EFFECT_SKIP_FRAME);
2616 }
2617 }
2618
2619 mParameters.set(CameraParameters::KEY_EFFECT, new_image_effect_str);
2620 }
2621 }
2622 }
2623
2624 //contrast
2625 const char *new_contrast_str = params.get("contrast");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002626 ALOGV("%s : new_contrast_str %s", __func__, new_contrast_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002627 if (new_contrast_str != NULL) {
2628 int new_contrast = -1;
2629
2630 if (!strcmp(new_contrast_str, "auto")) {
2631 if (mUseInternalISP)
2632 new_contrast = IS_CONTRAST_AUTO;
2633 else
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002634 ALOGW("WARN(%s):Invalid contrast value (%s)", __func__, new_contrast_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002635 } else if (!strcmp(new_contrast_str, "-2")) {
2636 if (mUseInternalISP)
2637 new_contrast = IS_CONTRAST_MINUS_2;
2638 else
2639 new_contrast = CONTRAST_MINUS_2;
2640 } else if (!strcmp(new_contrast_str, "-1")) {
2641 if (mUseInternalISP)
2642 new_contrast = IS_CONTRAST_MINUS_1;
2643 else
2644 new_contrast = CONTRAST_MINUS_1;
2645 } else if (!strcmp(new_contrast_str, "0")) {
2646 if (mUseInternalISP)
2647 new_contrast = IS_CONTRAST_DEFAULT;
2648 else
2649 new_contrast = CONTRAST_DEFAULT;
2650 } else if (!strcmp(new_contrast_str, "1")) {
2651 if (mUseInternalISP)
2652 new_contrast = IS_CONTRAST_PLUS_1;
2653 else
2654 new_contrast = CONTRAST_PLUS_1;
2655 } else if (!strcmp(new_contrast_str, "2")) {
2656 if (mUseInternalISP)
2657 new_contrast = IS_CONTRAST_PLUS_2;
2658 else
2659 new_contrast = CONTRAST_PLUS_2;
2660 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002661 ALOGE("ERR(%s):Invalid contrast value(%s)", __func__, new_contrast_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002662 ret = UNKNOWN_ERROR;
2663 }
2664
2665 if (0 <= new_contrast) {
2666 if (mSecCamera->setContrast(new_contrast) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002667 ALOGE("ERR(%s):Fail on mSecCamera->setContrast(contrast(%d))", __func__, new_contrast);
codeworkx62f02ba2012-05-20 12:00:36 +02002668 ret = UNKNOWN_ERROR;
2669 } else {
2670 mParameters.set("contrast", new_contrast_str);
2671 }
2672 }
2673 }
2674
2675 //WDR
2676 int new_wdr = params.getInt("wdr");
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002677 ALOGV("%s : new_wdr %d", __func__, new_wdr);
codeworkx62f02ba2012-05-20 12:00:36 +02002678
2679 if (0 <= new_wdr) {
2680 if (mSecCamera->setWDR(new_wdr) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002681 ALOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_wdr);
codeworkx62f02ba2012-05-20 12:00:36 +02002682 ret = UNKNOWN_ERROR;
2683 }
2684 }
2685
2686 //anti shake
2687 int new_anti_shake = mInternalParameters.getInt("anti-shake");
2688
2689 if (0 <= new_anti_shake) {
2690 if (mSecCamera->setAntiShake(new_anti_shake) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002691 ALOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_anti_shake);
codeworkx62f02ba2012-05-20 12:00:36 +02002692 ret = UNKNOWN_ERROR;
2693 }
2694 }
2695
2696 // gps latitude
2697 const char *new_gps_latitude_str = params.get(CameraParameters::KEY_GPS_LATITUDE);
2698 if (mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002699 ALOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __func__, new_gps_latitude_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002700 ret = UNKNOWN_ERROR;
2701 } else {
2702 if (new_gps_latitude_str) {
2703 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, new_gps_latitude_str);
2704 } else {
2705 mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
2706 }
2707 }
2708
2709 // gps longitude
2710 const char *new_gps_longitude_str = params.get(CameraParameters::KEY_GPS_LONGITUDE);
2711
2712 if (mSecCamera->setGPSLongitude(new_gps_longitude_str) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002713 ALOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __func__, new_gps_longitude_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002714 ret = UNKNOWN_ERROR;
2715 } else {
2716 if (new_gps_longitude_str) {
2717 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, new_gps_longitude_str);
2718 } else {
2719 mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
2720 }
2721 }
2722
2723 // gps altitude
2724 const char *new_gps_altitude_str = params.get(CameraParameters::KEY_GPS_ALTITUDE);
2725
2726 if (mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002727 ALOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __func__, new_gps_altitude_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002728 ret = UNKNOWN_ERROR;
2729 } else {
2730 if (new_gps_altitude_str) {
2731 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, new_gps_altitude_str);
2732 } else {
2733 mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
2734 }
2735 }
2736
2737 // gps timestamp
2738 const char *new_gps_timestamp_str = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
2739
2740 if (mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002741 ALOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __func__, new_gps_timestamp_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002742 ret = UNKNOWN_ERROR;
2743 } else {
2744 if (new_gps_timestamp_str) {
2745 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, new_gps_timestamp_str);
2746 } else {
2747 mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
2748 }
2749 }
2750
2751 // gps processing method
2752 const char *new_gps_processing_method_str = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
2753
2754 if (mSecCamera->setGPSProcessingMethod(new_gps_processing_method_str) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002755 ALOGE("%s::mSecCamera->setGPSProcessingMethod(%s) fail", __func__, new_gps_processing_method_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002756 ret = UNKNOWN_ERROR;
2757 } else {
2758 if (new_gps_processing_method_str) {
2759 mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, new_gps_processing_method_str);
2760 } else {
2761 mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
2762 }
2763 }
2764
2765 // Recording size
2766 /* TODO */
2767 /* GED application don't set different recording size before recording button is pushed */
2768 int new_recording_width = 0;
2769 int new_recording_height = 0;
2770 params.getVideoSize(&new_recording_width, &new_recording_height);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002771 ALOGV("new_recording_width (%d) new_recording_height (%d)",
codeworkx62f02ba2012-05-20 12:00:36 +02002772 new_recording_width, new_recording_height);
2773
2774 int current_recording_width, current_recording_height;
2775 mParameters.getVideoSize(&current_recording_width, &current_recording_height);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002776 ALOGV("current_recording_width (%d) current_recording_height (%d)",
codeworkx62f02ba2012-05-20 12:00:36 +02002777 current_recording_width, current_recording_height);
2778
2779 if (current_recording_width != new_recording_width ||
2780 current_recording_height != new_recording_height) {
2781 if (0 < new_recording_width && 0 < new_recording_height) {
2782 if (mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002783 ALOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +02002784 __func__, new_recording_width, new_recording_height);
2785 ret = UNKNOWN_ERROR;
2786 }
2787 mParameters.setVideoSize(new_recording_width, new_recording_height);
2788 }
2789 }
2790
2791 //gamma
2792 const char *new_gamma_str = mInternalParameters.get("video_recording_gamma");
2793
2794 if (new_gamma_str != NULL) {
2795 int new_gamma = -1;
2796 if (!strcmp(new_gamma_str, "off"))
2797 new_gamma = GAMMA_OFF;
2798 else if (!strcmp(new_gamma_str, "on"))
2799 new_gamma = GAMMA_ON;
2800 else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002801 ALOGE("%s::unmatched gamma(%s)", __func__, new_gamma_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002802 ret = UNKNOWN_ERROR;
2803 }
2804
2805 if (0 <= new_gamma) {
2806 if (mSecCamera->setGamma(new_gamma) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002807 ALOGE("%s::mSecCamera->setGamma(%d) fail", __func__, new_gamma);
codeworkx62f02ba2012-05-20 12:00:36 +02002808 ret = UNKNOWN_ERROR;
2809 }
2810 }
2811 }
2812
2813 //slow ae
2814 const char *new_slow_ae_str = mInternalParameters.get("slow_ae");
2815
2816 if (new_slow_ae_str != NULL) {
2817 int new_slow_ae = -1;
2818
2819 if (!strcmp(new_slow_ae_str, "off"))
2820 new_slow_ae = SLOW_AE_OFF;
2821 else if (!strcmp(new_slow_ae_str, "on"))
2822 new_slow_ae = SLOW_AE_ON;
2823 else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002824 ALOGE("%s::unmatched slow_ae(%s)", __func__, new_slow_ae_str);
codeworkx62f02ba2012-05-20 12:00:36 +02002825 ret = UNKNOWN_ERROR;
2826 }
2827
2828 if (0 <= new_slow_ae) {
2829 if (mSecCamera->setSlowAE(new_slow_ae) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002830 ALOGE("%s::mSecCamera->setSlowAE(%d) fail", __func__, new_slow_ae);
codeworkx62f02ba2012-05-20 12:00:36 +02002831 ret = UNKNOWN_ERROR;
2832 }
2833 }
2834 }
2835
2836 /*Camcorder fix fps*/
2837 int new_sensor_mode = mInternalParameters.getInt("cam_mode");
2838
2839 if (0 <= new_sensor_mode) {
2840 if (mSecCamera->setSensorMode(new_sensor_mode) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002841 ALOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __func__, new_sensor_mode);
codeworkx62f02ba2012-05-20 12:00:36 +02002842 ret = UNKNOWN_ERROR;
2843 }
2844 } else {
2845 new_sensor_mode=0;
2846 }
2847
2848 /*Shot mode*/
2849 int new_shot_mode = mInternalParameters.getInt("shot_mode");
2850
2851 if (0 <= new_shot_mode) {
2852 if (mSecCamera->setShotMode(new_shot_mode) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002853 ALOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __func__, new_shot_mode);
codeworkx62f02ba2012-05-20 12:00:36 +02002854 ret = UNKNOWN_ERROR;
2855 }
2856 } else {
2857 new_shot_mode=0;
2858 }
2859
2860 // chk_dataline
2861 int new_dataline = mInternalParameters.getInt("chk_dataline");
2862
2863 if (0 <= new_dataline) {
2864 if (mSecCamera->setDataLineCheck(new_dataline) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002865 ALOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __func__, new_dataline);
codeworkx62f02ba2012-05-20 12:00:36 +02002866 ret = UNKNOWN_ERROR;
2867 }
2868 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002869 ALOGV("%s return ret = %d", __func__, ret);
codeworkx62f02ba2012-05-20 12:00:36 +02002870
2871 return ret;
2872}
2873
2874CameraParameters CameraHardwareSec::getParameters() const
2875{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002876 ALOGV("%s :", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02002877 return mParameters;
2878}
2879
2880status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2)
2881{
2882 /* TODO */
2883 /* CAMERA_CMD_START_FACE_DETECTION and CAMERA_CMD_STOP_FACE_DETECTION
2884 for Face Detection */
2885 if(command == CAMERA_CMD_START_FACE_DETECTION) {
2886 if (mSecCamera->setFaceDetect(FACE_DETECTION_ON) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002887 ALOGE("ERR(%s): Fail on mSecCamera->startFaceDetection()");
codeworkx62f02ba2012-05-20 12:00:36 +02002888 return BAD_VALUE;
2889 } else {
2890 return NO_ERROR;
2891 }
2892 }
2893 if(command == CAMERA_CMD_STOP_FACE_DETECTION) {
2894 if (mSecCamera->setFaceDetect(FACE_DETECTION_OFF) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002895 ALOGE("ERR(%s): Fail on mSecCamera->stopFaceDetection()");
codeworkx62f02ba2012-05-20 12:00:36 +02002896 return BAD_VALUE;
2897 } else {
2898 return NO_ERROR;
2899 }
2900 }
2901
2902 return BAD_VALUE;
2903}
2904
2905void CameraHardwareSec::release()
2906{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002907 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02002908
2909 /* shut down any threads we have that might be running. do it here
2910 * instead of the destructor. we're guaranteed to be on another thread
2911 * than the ones below. if we used the destructor, since the threads
2912 * have a reference to this object, we could wind up trying to wait
2913 * for ourself to exit, which is a deadlock.
2914 */
2915 if (mPreviewThread != NULL) {
2916 /* this thread is normally already in it's threadLoop but blocked
2917 * on the condition variable or running. signal it so it wakes
2918 * up and can exit.
2919 */
2920 mPreviewThread->requestExit();
2921 mExitPreviewThread = true;
2922 mPreviewRunning = true; /* let it run so it can exit */
2923 mPreviewCondition.signal();
2924 mPreviewThread->requestExitAndWait();
2925 mPreviewThread.clear();
2926 }
2927 if (mAutoFocusThread != NULL) {
2928 /* this thread is normally already in it's threadLoop but blocked
2929 * on the condition variable. signal it so it wakes up and can exit.
2930 */
2931 mFocusLock.lock();
2932 mAutoFocusThread->requestExit();
2933 mExitAutoFocusThread = true;
2934 mFocusCondition.signal();
2935 mFocusLock.unlock();
2936 mAutoFocusThread->requestExitAndWait();
2937 mAutoFocusThread.clear();
2938 }
2939 if (mPictureThread != NULL) {
2940 mPictureThread->requestExitAndWait();
2941 mPictureThread.clear();
2942 }
2943
2944 if (mRawHeap) {
2945 mRawHeap->release(mRawHeap);
2946 mRawHeap = 0;
2947 }
2948 if (mPreviewHeap) {
2949 mPreviewHeap->release(mPreviewHeap);
2950 mPreviewHeap = 0;
2951 }
2952 for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) {
2953 if (mRecordHeap[i]) {
2954 mRecordHeap[i]->release(mRecordHeap[i]);
2955 mRecordHeap[i] = 0;
2956 }
2957 }
2958
2959 /* close after all the heaps are cleared since those
2960 * could have dup'd our file descriptor.
2961 */
2962 mSecCamera->DestroyCamera();
2963}
2964
2965static CameraInfo sCameraInfo[] = {
2966 {
2967 CAMERA_FACING_BACK,
2968 90, /* orientation */
2969 },
2970 {
2971 CAMERA_FACING_FRONT,
2972 90, /* orientation */
2973 }
2974};
2975
2976status_t CameraHardwareSec::storeMetaDataInBuffers(bool enable)
2977{
2978 // FIXME:
2979 // metadata buffer mode can be turned on or off.
2980 // Samsung needs to fix this.
2981 if (!enable) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002982 ALOGE("Non-metadata buffer mode is not supported!");
codeworkx62f02ba2012-05-20 12:00:36 +02002983 return INVALID_OPERATION;
2984 }
2985 return OK;
2986}
2987
2988/** Close this device */
2989
2990static camera_device_t *g_cam_device;
2991
2992static int HAL_camera_device_close(struct hw_device_t* device)
2993{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02002994 ALOGI("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02002995 if (device) {
2996 camera_device_t *cam_device = (camera_device_t *)device;
2997 delete static_cast<CameraHardwareSec *>(cam_device->priv);
2998 free(cam_device);
2999 g_cam_device = 0;
3000 }
3001 return 0;
3002}
3003
3004static inline CameraHardwareSec *obj(struct camera_device *dev)
3005{
3006 return reinterpret_cast<CameraHardwareSec *>(dev->priv);
3007}
3008
3009/** Set the preview_stream_ops to which preview frames are sent */
3010static int HAL_camera_device_set_preview_window(struct camera_device *dev,
3011 struct preview_stream_ops *buf)
3012{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003013 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003014 return obj(dev)->setPreviewWindow(buf);
3015}
3016
3017/** Set the notification and data callbacks */
3018static void HAL_camera_device_set_callbacks(struct camera_device *dev,
3019 camera_notify_callback notify_cb,
3020 camera_data_callback data_cb,
3021 camera_data_timestamp_callback data_cb_timestamp,
3022 camera_request_memory get_memory,
3023 void* user)
3024{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003025 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003026 obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp,
3027 get_memory,
3028 user);
3029}
3030
3031/**
3032 * The following three functions all take a msg_type, which is a bitmask of
3033 * the messages defined in include/ui/Camera.h
3034 */
3035
3036/**
3037 * Enable a message, or set of messages.
3038 */
3039static void HAL_camera_device_enable_msg_type(struct camera_device *dev, int32_t msg_type)
3040{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003041 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003042 obj(dev)->enableMsgType(msg_type);
3043}
3044
3045/**
3046 * Disable a message, or a set of messages.
3047 *
3048 * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera
3049 * HAL should not rely on its client to call releaseRecordingFrame() to
3050 * release video recording frames sent out by the cameral HAL before and
3051 * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL
3052 * clients must not modify/access any video recording frame after calling
3053 * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
3054 */
3055static void HAL_camera_device_disable_msg_type(struct camera_device *dev, int32_t msg_type)
3056{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003057 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003058 obj(dev)->disableMsgType(msg_type);
3059}
3060
3061/**
3062 * Query whether a message, or a set of messages, is enabled. Note that
3063 * this is operates as an AND, if any of the messages queried are off, this
3064 * will return false.
3065 */
3066static int HAL_camera_device_msg_type_enabled(struct camera_device *dev, int32_t msg_type)
3067{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003068 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003069 return obj(dev)->msgTypeEnabled(msg_type);
3070}
3071
3072/**
3073 * Start preview mode.
3074 */
3075static int HAL_camera_device_start_preview(struct camera_device *dev)
3076{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003077 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003078 return obj(dev)->startPreview();
3079}
3080
3081/**
3082 * Stop a previously started preview.
3083 */
3084static void HAL_camera_device_stop_preview(struct camera_device *dev)
3085{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003086 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003087 obj(dev)->stopPreview();
3088}
3089
3090/**
3091 * Returns true if preview is enabled.
3092 */
3093static int HAL_camera_device_preview_enabled(struct camera_device *dev)
3094{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003095 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003096 return obj(dev)->previewEnabled();
3097}
3098
3099/**
3100 * Request the camera HAL to store meta data or real YUV data in the video
3101 * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If
3102 * it is not called, the default camera HAL behavior is to store real YUV
3103 * data in the video buffers.
3104 *
3105 * This method should be called before startRecording() in order to be
3106 * effective.
3107 *
3108 * If meta data is stored in the video buffers, it is up to the receiver of
3109 * the video buffers to interpret the contents and to find the actual frame
3110 * data with the help of the meta data in the buffer. How this is done is
3111 * outside of the scope of this method.
3112 *
3113 * Some camera HALs may not support storing meta data in the video buffers,
3114 * but all camera HALs should support storing real YUV data in the video
3115 * buffers. If the camera HAL does not support storing the meta data in the
3116 * video buffers when it is requested to do do, INVALID_OPERATION must be
3117 * returned. It is very useful for the camera HAL to pass meta data rather
3118 * than the actual frame data directly to the video encoder, since the
3119 * amount of the uncompressed frame data can be very large if video size is
3120 * large.
3121 *
3122 * @param enable if true to instruct the camera HAL to store
3123 * meta data in the video buffers; false to instruct
3124 * the camera HAL to store real YUV data in the video
3125 * buffers.
3126 *
3127 * @return OK on success.
3128 */
3129static int HAL_camera_device_store_meta_data_in_buffers(struct camera_device *dev, int enable)
3130{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003131 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003132 return obj(dev)->storeMetaDataInBuffers(enable);
3133}
3134
3135/**
3136 * Start record mode. When a record image is available, a
3137 * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding
3138 * frame. Every record frame must be released by a camera HAL client via
3139 * releaseRecordingFrame() before the client calls
3140 * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
3141 * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
3142 * responsibility to manage the life-cycle of the video recording frames,
3143 * and the client must not modify/access any video recording frames.
3144 */
3145static int HAL_camera_device_start_recording(struct camera_device *dev)
3146{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003147 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003148 return obj(dev)->startRecording();
3149}
3150
3151/**
3152 * Stop a previously started recording.
3153 */
3154static void HAL_camera_device_stop_recording(struct camera_device *dev)
3155{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003156 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003157 obj(dev)->stopRecording();
3158}
3159
3160/**
3161 * Returns true if recording is enabled.
3162 */
3163static int HAL_camera_device_recording_enabled(struct camera_device *dev)
3164{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003165 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003166 return obj(dev)->recordingEnabled();
3167}
3168
3169/**
3170 * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
3171 *
3172 * It is camera HAL client's responsibility to release video recording
3173 * frames sent out by the camera HAL before the camera HAL receives a call
3174 * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to
3175 * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
3176 * responsibility to manage the life-cycle of the video recording frames.
3177 */
3178static void HAL_camera_device_release_recording_frame(struct camera_device *dev,
3179 const void *opaque)
3180{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003181 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003182 obj(dev)->releaseRecordingFrame(opaque);
3183}
3184
3185/**
3186 * Start auto focus, the notification callback routine is called with
3187 * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be
3188 * called again if another auto focus is needed.
3189 */
3190static int HAL_camera_device_auto_focus(struct camera_device *dev)
3191{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003192 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003193 return obj(dev)->autoFocus();
3194}
3195
3196/**
3197 * Cancels auto-focus function. If the auto-focus is still in progress,
3198 * this function will cancel it. Whether the auto-focus is in progress or
3199 * not, this function will return the focus position to the default. If
3200 * the camera does not support auto-focus, this is a no-op.
3201 */
3202static int HAL_camera_device_cancel_auto_focus(struct camera_device *dev)
3203{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003204 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003205 return obj(dev)->cancelAutoFocus();
3206}
3207
3208/**
3209 * Take a picture.
3210 */
3211static int HAL_camera_device_take_picture(struct camera_device *dev)
3212{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003213 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003214 return obj(dev)->takePicture();
3215}
3216
3217/**
3218 * Cancel a picture that was started with takePicture. Calling this method
3219 * when no picture is being taken is a no-op.
3220 */
3221static int HAL_camera_device_cancel_picture(struct camera_device *dev)
3222{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003223 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003224 return obj(dev)->cancelPicture();
3225}
3226
3227/**
3228 * Set the camera parameters. This returns BAD_VALUE if any parameter is
3229 * invalid or not supported.
3230 */
3231static int HAL_camera_device_set_parameters(struct camera_device *dev,
3232 const char *parms)
3233{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003234 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003235 String8 str(parms);
3236 CameraParameters p(str);
3237 return obj(dev)->setParameters(p);
3238}
3239
3240/** Return the camera parameters. */
3241char *HAL_camera_device_get_parameters(struct camera_device *dev)
3242{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003243 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003244 String8 str;
3245 CameraParameters parms = obj(dev)->getParameters();
3246 str = parms.flatten();
3247 return strdup(str.string());
3248}
3249
3250static void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms)
3251{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003252 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003253 free(parms);
3254}
3255
3256/**
3257 * Send command to camera driver.
3258 */
3259static int HAL_camera_device_send_command(struct camera_device *dev,
3260 int32_t cmd, int32_t arg1, int32_t arg2)
3261{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003262 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003263 return obj(dev)->sendCommand(cmd, arg1, arg2);
3264}
3265
3266/**
3267 * Release the hardware resources owned by this object. Note that this is
3268 * *not* done in the destructor.
3269 */
3270static void HAL_camera_device_release(struct camera_device *dev)
3271{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003272 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003273 obj(dev)->release();
3274}
3275
3276/**
3277 * Dump state of the camera hardware
3278 */
3279static int HAL_camera_device_dump(struct camera_device *dev, int fd)
3280{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003281 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003282 return obj(dev)->dump(fd);
3283}
3284
3285static int HAL_getNumberOfCameras()
3286{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003287 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003288
3289 int cam_fd;
3290 static struct v4l2_input input;
3291
3292 cam_fd = open(CAMERA_DEV_NAME, O_RDONLY);
3293 if (cam_fd < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003294 ALOGE("ERR(%s):Cannot open %s (error : %s)", __func__, CAMERA_DEV_NAME, strerror(errno));
codeworkx62f02ba2012-05-20 12:00:36 +02003295 return -1;
3296 }
3297
3298 input.index = 0;
3299 while (ioctl(cam_fd, VIDIOC_ENUMINPUT, &input) == 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003300 ALOGI("Name of input channel[%d] is %s", input.index, input.name);
codeworkx62f02ba2012-05-20 12:00:36 +02003301 input.index++;
3302 }
3303
3304 close(cam_fd);
3305
3306 return --input.index;
3307}
3308
3309static int HAL_getCameraInfo(int cameraId, struct camera_info *cameraInfo)
3310{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003311 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003312 memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
3313 return 0;
3314}
3315
3316#define SET_METHOD(m) m : HAL_camera_device_##m
3317
3318static camera_device_ops_t camera_device_ops = {
3319 SET_METHOD(set_preview_window),
3320 SET_METHOD(set_callbacks),
3321 SET_METHOD(enable_msg_type),
3322 SET_METHOD(disable_msg_type),
3323 SET_METHOD(msg_type_enabled),
3324 SET_METHOD(start_preview),
3325 SET_METHOD(stop_preview),
3326 SET_METHOD(preview_enabled),
3327 SET_METHOD(store_meta_data_in_buffers),
3328 SET_METHOD(start_recording),
3329 SET_METHOD(stop_recording),
3330 SET_METHOD(recording_enabled),
3331 SET_METHOD(release_recording_frame),
3332 SET_METHOD(auto_focus),
3333 SET_METHOD(cancel_auto_focus),
3334 SET_METHOD(take_picture),
3335 SET_METHOD(cancel_picture),
3336 SET_METHOD(set_parameters),
3337 SET_METHOD(get_parameters),
3338 SET_METHOD(put_parameters),
3339 SET_METHOD(send_command),
3340 SET_METHOD(release),
3341 SET_METHOD(dump),
3342};
3343
3344#undef SET_METHOD
3345
3346static int HAL_camera_device_open(const struct hw_module_t* module,
3347 const char *id,
3348 struct hw_device_t** device)
3349{
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003350 ALOGV("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02003351
3352 int cameraId = atoi(id);
3353 if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003354 ALOGE("Invalid camera ID %s", id);
codeworkx62f02ba2012-05-20 12:00:36 +02003355 return -EINVAL;
3356 }
3357
3358 if (g_cam_device) {
3359 if (obj(g_cam_device)->getCameraId() == cameraId) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003360 ALOGV("returning existing camera ID %s", id);
codeworkx62f02ba2012-05-20 12:00:36 +02003361 goto done;
3362 } else {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003363 ALOGE("Cannot open camera %d. camera %d is already running!",
codeworkx62f02ba2012-05-20 12:00:36 +02003364 cameraId, obj(g_cam_device)->getCameraId());
3365 return -ENOSYS;
3366 }
3367 }
3368
3369 g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t));
3370 if (!g_cam_device)
3371 return -ENOMEM;
3372
3373 g_cam_device->common.tag = HARDWARE_DEVICE_TAG;
3374 g_cam_device->common.version = 1;
3375 g_cam_device->common.module = const_cast<hw_module_t *>(module);
3376 g_cam_device->common.close = HAL_camera_device_close;
3377
3378 g_cam_device->ops = &camera_device_ops;
3379
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003380 ALOGI("%s: open camera %s", __func__, id);
codeworkx62f02ba2012-05-20 12:00:36 +02003381
3382 g_cam_device->priv = new CameraHardwareSec(cameraId, g_cam_device);
3383
3384done:
3385 *device = (hw_device_t *)g_cam_device;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02003386 ALOGI("%s: opened camera %s (%p)", __func__, id, *device);
codeworkx62f02ba2012-05-20 12:00:36 +02003387 return 0;
3388}
3389
3390static hw_module_methods_t camera_module_methods = {
3391 open : HAL_camera_device_open
3392};
3393
3394extern "C" {
3395 struct camera_module HAL_MODULE_INFO_SYM = {
3396 common : {
3397 tag : HARDWARE_MODULE_TAG,
3398 version_major : 1,
3399 version_minor : 0,
3400 id : CAMERA_HARDWARE_MODULE_ID,
3401 name : "orion camera HAL",
3402 author : "Samsung Corporation",
3403 methods : &camera_module_methods,
3404 },
3405 get_number_of_cameras : HAL_getNumberOfCameras,
3406 get_camera_info : HAL_getCameraInfo
3407 };
3408}
3409
3410}; // namespace android