Commit | Line | Data |
---|---|---|
5763fb39 T |
1 | /* |
2 | * Copyright 2008, The Android Open Source Project | |
3 | * Copyright 2013, Samsung Electronics Co. LTD | |
4 | * | |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | * you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | /*! | |
19 | * \file SecCameraHardware.cpp | |
20 | * \brief source file for Android Camera Ext HAL | |
21 | * \author teahyung kim (tkon.kim@samsung.com) | |
22 | * \date 2013/04/30 | |
23 | * | |
24 | */ | |
25 | ||
26 | #ifndef ANDROID_HARDWARE_SECCAMERAHARDWARE_CPP | |
27 | #define ANDROID_HARDWARE_SECCAMERAHARDWARE_CPP | |
28 | ||
29 | /* #define LOG_NDEBUG 0 */ | |
30 | #define LOG_TAG "SecCameraHardware" | |
31 | ||
32 | #include "SecCameraHardware.h" | |
33 | ||
34 | #define CLEAR(x) memset(&(x), 0, sizeof(x)) | |
35 | ||
36 | #define CHECK_ERR(x, log) if (CC_UNLIKELY(x < 0)) { \ | |
37 | ALOGE log; \ | |
38 | return false; \ | |
39 | } | |
40 | ||
41 | #define CHECK_ERR_N(x, log) if (CC_UNLIKELY(x < 0)) { \ | |
42 | ALOGE log; \ | |
43 | return x; \ | |
44 | } | |
45 | ||
46 | #define CHECK_ERR_GOTO(out, x, log) if (CC_UNLIKELY(x < 0)) { \ | |
47 | ALOGE log; \ | |
48 | goto out; \ | |
49 | } | |
50 | ||
51 | #ifdef __GNUC__ | |
52 | #define __swap16gen(x) __statement({ \ | |
53 | __uint16_t __swap16gen_x = (x); \ | |
54 | \ | |
55 | (__uint16_t)((__swap16gen_x & 0xff) << 8 | \ | |
56 | (__swap16gen_x & 0xff00) >> 8); \ | |
57 | }) | |
58 | #else /* __GNUC__ */ | |
59 | /* Note that these macros evaluate their arguments several times. */ | |
60 | #define __swap16gen(x) \ | |
61 | (__uint16_t)(((__uint16_t)(x) & 0xff) << 8 | ((__uint16_t)(x) & 0xff00) >> 8) | |
62 | #endif | |
63 | ||
64 | ||
65 | ||
66 | #define MAX_THUMBNAIL_SIZE (60000) | |
67 | ||
68 | #define EXYNOS_MEM_DEVICE_DEV_NAME "/dev/exynos-mem" | |
69 | ||
70 | #ifdef SENSOR_NAME_GET_FROM_FILE | |
71 | int g_rearSensorId = -1; | |
72 | int g_frontSensorId = -1; | |
73 | #endif | |
74 | ||
75 | namespace android { | |
76 | ||
77 | struct record_heap { | |
78 | uint32_t type; // make sure that this is 4 byte. | |
79 | phyaddr_t y; | |
80 | phyaddr_t cbcr; | |
81 | uint32_t buf_index; | |
82 | uint32_t reserved; | |
83 | }; | |
84 | ||
85 | gralloc_module_t const* SecCameraHardware::mGrallocHal; | |
86 | ||
87 | SecCameraHardware::SecCameraHardware(int cameraId, camera_device_t *dev) | |
88 | : ISecCameraHardware(cameraId, dev) | |
89 | { | |
90 | if (cameraId == CAMERA_ID_BACK) | |
91 | mFliteFormat = CAM_PIXEL_FORMAT_YUV422I; | |
92 | else | |
93 | mFliteFormat = CAM_PIXEL_FORMAT_YUV422I; | |
94 | ||
95 | mPreviewFormat = CAM_PIXEL_FORMAT_YUV420SP; | |
96 | /* set suitably */ | |
97 | mRecordingFormat = CAM_PIXEL_FORMAT_YUV420; | |
98 | mPictureFormat = CAM_PIXEL_FORMAT_JPEG; | |
99 | ||
100 | mZoomRatio = 1000.00f; | |
101 | mFimc1CSC = NULL; | |
102 | mFimc2CSC = NULL; | |
103 | ||
104 | CLEAR(mWindowBuffer); | |
105 | ||
106 | if (!mGrallocHal) { | |
107 | int ret = 0; | |
108 | ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal); | |
109 | if (CC_UNLIKELY(ret)) | |
110 | ALOGE("SecCameraHardware: error, fail on loading gralloc HAL"); | |
111 | } | |
112 | ||
113 | createInstance(cameraId); | |
114 | } | |
115 | ||
116 | SecCameraHardware::~SecCameraHardware() | |
117 | { | |
118 | } | |
119 | ||
120 | SecCameraHardware::FLiteV4l2::FLiteV4l2() | |
121 | { | |
122 | mCameraFd = -1; | |
123 | mBufferCount = 0; | |
124 | mStreamOn = false; | |
125 | mCmdStop = 0; | |
126 | mFastCapture = false; | |
127 | } | |
128 | ||
129 | SecCameraHardware::FLiteV4l2::~FLiteV4l2() | |
130 | { | |
131 | } | |
132 | ||
133 | /* HACK */ | |
134 | #define SENSOR_SCENARIO_MASK 0xF0000000 | |
135 | #define SENSOR_SCENARIO_SHIFT 28 | |
136 | #define SENSOR_MODULE_MASK 0x0FFFFFFF | |
137 | #define SENSOR_MODULE_SHIFT 0 | |
138 | ||
139 | int SecCameraHardware::FLiteV4l2::init(const char *devPath, const int cameraId) | |
140 | { | |
141 | int err; | |
142 | int sensorId = 0; | |
143 | ||
144 | mCameraFd = open(devPath, O_RDWR); | |
145 | mCameraId = cameraId; | |
146 | CHECK_ERR_N(mCameraFd, ("FLiteV4l2 init: error %d, open %s (%d - %s)", mCameraFd, devPath, errno, strerror(errno))); | |
147 | CLOGV("DEBUG (%s) : %s, fd(%d) ", devPath, mCameraFd); | |
148 | ||
149 | #if defined(USE_VIDIOC_QUERY_CAP) | |
150 | /* fimc_v4l2_querycap */ | |
151 | struct v4l2_capability cap; | |
152 | CLEAR(cap); | |
153 | err = ioctl(mCameraFd, VIDIOC_QUERYCAP, &cap); | |
154 | CHECK_ERR_N(err, ("FLiteV4l2 init: error %d, VIDIOC_QUERYCAP", err)); | |
155 | ||
156 | if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) { | |
157 | ALOGE("FLiteV4l2 init: error, no capture devices"); | |
158 | return -1; | |
159 | } | |
160 | #endif | |
161 | ||
162 | /* fimc_v4l2_enuminput */ | |
163 | struct v4l2_input input; | |
164 | CLEAR(input); | |
165 | /* input.index = cameraId; */ | |
166 | ||
167 | /* fimc_v4l2_s_input */ | |
168 | sensorId = getSensorId(cameraId); | |
169 | CLOGV("DEBUG (FLiteV4l2::init) : sensor Id(%d) ", __func__, sensorId); | |
170 | ||
171 | input.index = (2 << SENSOR_SCENARIO_SHIFT) | sensorId; // external camera / sensor domule id | |
172 | ||
173 | err = ioctl(mCameraFd, VIDIOC_S_INPUT, &input); | |
174 | CHECK_ERR_N(err, ("FLiteV4l2 init: error %d, VIDIOC_S_INPUT", err)); | |
175 | ||
176 | #ifdef FAKE_SENSOR | |
177 | fakeIndex = 0; | |
178 | fakeByteData = 0; | |
179 | #endif | |
180 | return 0; | |
181 | } | |
182 | ||
183 | void SecCameraHardware::FLiteV4l2::deinit() | |
184 | { | |
185 | if (mCameraFd >= 0) { | |
186 | close(mCameraFd); | |
187 | mCameraFd = -1; | |
188 | } | |
189 | mBufferCount = 0; | |
190 | CLOGV("DEBUG (FLiteV4l2::deinit) : out "); | |
191 | } | |
192 | ||
193 | int SecCameraHardware::FLiteV4l2::startPreview(image_rect_type *fliteSize, | |
194 | cam_pixel_format format, int numBufs, int fps, bool movieMode, node_info_t *mFliteNode) | |
195 | { | |
196 | /* fimc_v4l2_enum_fmt */ | |
197 | int err; | |
198 | bool found = false; | |
199 | ||
200 | #if defined(USE_VIDIOC_ENUM_FORMAT) | |
201 | struct v4l2_fmtdesc fmtdesc; | |
202 | CLEAR(fmtdesc); | |
203 | fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
204 | fmtdesc.index = 0; | |
205 | ||
206 | while ((err = ioctl(mCameraFd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0) { | |
207 | if (fmtdesc.pixelformat == (uint32_t)format) { | |
208 | ALOGV("FLiteV4l2 start: %s", fmtdesc.description); | |
209 | found = true; | |
210 | break; | |
211 | } | |
212 | fmtdesc.index++; | |
213 | } | |
214 | if (!found) { | |
215 | ALOGE("FLiteV4l2 start: error, unsupported pixel format (%c%c%c%c)" | |
216 | " fmtdesc.pixelformat = %d, %s, err=%d", format, format >> 8, format >> 16, format >> 24, | |
217 | fmtdesc.pixelformat, fmtdesc.description, err); | |
218 | return -1; | |
219 | } | |
220 | #endif | |
221 | ||
222 | #ifdef USE_CAPTURE_MODE | |
223 | /* | |
224 | capture_mode = oprmode | |
225 | oprmode = 0 (preview) | |
226 | oprmode = 1 (single capture) | |
227 | oprmode = 2 (HDR capture) | |
228 | */ | |
229 | err = sctrl(CAM_CID_CAPTURE_MODE, false); | |
230 | CHECK_ERR_N(err, ("FLiteV4l2 sctrl: error %d, CAM_CID_CAPTURE_MODE", err)); | |
231 | #endif | |
232 | ||
233 | v4l2_field field; | |
234 | if (movieMode) | |
235 | field = (enum v4l2_field)IS_MODE_PREVIEW_VIDEO; | |
236 | else | |
237 | field = (enum v4l2_field)IS_MODE_PREVIEW_STILL; | |
238 | ||
239 | /* fimc_v4l2_s_fmt */ | |
240 | struct v4l2_format v4l2_fmt; | |
241 | CLEAR(v4l2_fmt); | |
242 | ||
243 | CLOGD("DEBUG (FLiteV4l2::startPreview) : setting( size: %dx%d)", fliteSize->width, fliteSize->height); | |
244 | v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
245 | v4l2_fmt.fmt.pix_mp.width = fliteSize->width; | |
246 | v4l2_fmt.fmt.pix_mp.height = fliteSize->height; | |
247 | v4l2_fmt.fmt.pix_mp.pixelformat = format; | |
248 | v4l2_fmt.fmt.pix_mp.field = field; | |
249 | err = ioctl(mCameraFd, VIDIOC_S_FMT, &v4l2_fmt); | |
250 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_S_FMT", err)); | |
251 | ||
252 | #ifdef CACHEABLE | |
253 | sctrl(V4L2_CID_CACHEABLE, 1); | |
254 | #endif | |
255 | /* setting fps */ | |
256 | CLOGD("DEBUG (FLiteV4l2::startPreview) : setting( fps: %d)", fps); | |
257 | ||
258 | struct v4l2_streamparm streamParam; | |
259 | streamParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
260 | streamParam.parm.capture.timeperframe.numerator = 1; | |
261 | streamParam.parm.capture.timeperframe.denominator = fps; | |
262 | ||
263 | CLOGI("INFO (FLiteV4l2::startPreview) : set framerate (denominator=%d)", fps); | |
264 | err = sparm(&streamParam); | |
265 | ||
266 | CHECK_ERR_N(err, ("ERR(%s): sctrl V4L2_CID_CAM_FRAME_RATE(%d) value(%d)", __FUNCTION__, err, fps)); | |
267 | ||
268 | /* sctrl(V4L2_CID_EMBEDDEDDATA_ENABLE, 0); */ | |
269 | ||
270 | /* fimc_v4l2_reqbufs */ | |
271 | struct v4l2_requestbuffers req; | |
272 | CLEAR(req); | |
273 | req.count = numBufs; | |
274 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
275 | #ifdef USE_USERPTR | |
276 | req.memory = V4L2_MEMORY_USERPTR; | |
277 | #else | |
278 | req.memory = V4L2_MEMORY_MMAP; | |
279 | #endif | |
280 | err = ioctl(mCameraFd, VIDIOC_REQBUFS, &req); | |
281 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_REQBUFS", err)); | |
282 | ||
283 | mBufferCount = (int)req.count; | |
284 | ||
285 | /* setting mFliteNode for Q/DQ */ | |
286 | mFliteNode->width = v4l2_fmt.fmt.pix.width; | |
287 | mFliteNode->height = v4l2_fmt.fmt.pix.height; | |
288 | mFliteNode->format = v4l2_fmt.fmt.pix.pixelformat; | |
289 | mFliteNode->planes = NUM_FLITE_BUF_PLANE + SPARE_PLANE; | |
290 | #ifdef SUPPORT_64BITS | |
291 | mFliteNode->memory = (enum v4l2_memory)req.memory; | |
292 | mFliteNode->type = (enum v4l2_buf_type)req.type; | |
293 | #else | |
294 | mFliteNode->memory = req.memory; | |
295 | mFliteNode->type = req.type; | |
296 | #endif | |
297 | mFliteNode->buffers= numBufs; | |
298 | ||
299 | return 0; | |
300 | } | |
301 | ||
302 | int SecCameraHardware::FLiteV4l2::startCapture(image_rect_type *img, | |
303 | cam_pixel_format format, int numBufs, int capKind) | |
304 | { | |
305 | /* fimc_v4l2_enum_fmt */ | |
306 | int err; | |
307 | #if defined(USE_VIDIOC_ENUM_FORMAT) | |
308 | bool found = false; | |
309 | struct v4l2_fmtdesc fmtdesc; | |
310 | CLEAR(fmtdesc); | |
311 | fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
312 | fmtdesc.index = 0; | |
313 | ||
314 | while ((err = ioctl(mCameraFd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0) { | |
315 | if (fmtdesc.pixelformat == (uint32_t)format) { | |
316 | ALOGV("FLiteV4l2 start: %s", fmtdesc.description); | |
317 | found = true; | |
318 | break; | |
319 | } | |
320 | ||
321 | fmtdesc.index++; | |
322 | } | |
323 | ||
324 | if (!found) { | |
325 | ALOGE("FLiteV4l2 start: error, unsupported pixel format (%c%c%c%c)" | |
326 | " fmtdesc.pixelformat = %d, %s, err=%d", format, format >> 8, format >> 16, format >> 24, | |
327 | fmtdesc.pixelformat, fmtdesc.description, err); | |
328 | return -1; | |
329 | } | |
330 | #endif | |
331 | ||
332 | /* fimc_v4l2_s_fmt */ | |
333 | struct v4l2_format v4l2_fmt; | |
334 | CLEAR(v4l2_fmt); | |
335 | ||
336 | #ifdef USE_CAPTURE_MODE | |
337 | /* | |
338 | capture_mode = oprmode | |
339 | oprmode = 0 (preview) | |
340 | oprmode = 1 (single capture) | |
341 | oprmode = 2 (HDR capture) | |
342 | */ | |
343 | err = sctrl(CAM_CID_CAPTURE_MODE, true); | |
344 | CHECK_ERR_N(err, ("ERR(%s): sctrl V4L2_CID_CAMERA_CAPTURE(%d) enable failed", __FUNCTION__, err)); | |
345 | #endif | |
346 | #ifdef USE_CAPTURE_FPS_CHANGE | |
347 | /* setting fps */ | |
348 | struct v4l2_streamparm streamParam; | |
349 | streamParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
350 | streamParam.parm.capture.timeperframe.numerator = 1; | |
351 | streamParam.parm.capture.timeperframe.denominator = CAPTURE_FRAMERATE; | |
352 | ||
353 | CLOGI("INFO (FLiteV4l2::startCapture) : set framerate (denominator=%d)", CAPTURE_FRAMERATE); | |
354 | err = sparm(&streamParam); | |
355 | ||
356 | CHECK_ERR_N(err, ("ERR(%s): set framerate (denominator=%d) value(%d)", __FUNCTION__, CAPTURE_FRAMERATE, err)); | |
357 | #endif //#if 1 | |
358 | ||
359 | CLOGD("DEBUG(FLiteV4l2::startCapture): requested capture size %dx%d %d", img->width, img->height, format); | |
360 | ||
361 | v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
362 | v4l2_fmt.fmt.pix_mp.width = img->width; | |
363 | v4l2_fmt.fmt.pix_mp.height = img->height; | |
364 | v4l2_fmt.fmt.pix_mp.pixelformat = format; | |
365 | ||
366 | err = ioctl(mCameraFd, VIDIOC_S_FMT, &v4l2_fmt); | |
367 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_S_FMT", err)); | |
368 | ||
369 | /* fimc_v4l2_reqbufs */ | |
370 | struct v4l2_requestbuffers req; | |
371 | CLEAR(req); | |
372 | req.count = SKIP_CAPTURE_CNT; | |
373 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
374 | #ifdef USE_USERPTR | |
375 | req.memory = V4L2_MEMORY_USERPTR; | |
376 | #else | |
377 | req.memory = V4L2_MEMORY_MMAP; | |
378 | #endif | |
379 | ||
380 | err = ioctl(mCameraFd, VIDIOC_REQBUFS, &req); | |
381 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_REQBUFS", err)); | |
382 | ||
383 | mBufferCount = (int)req.count; | |
384 | ||
385 | return 0; | |
386 | } | |
387 | ||
388 | int SecCameraHardware::FLiteV4l2::startRecord(image_rect_type *img, image_rect_type *videoSize, | |
389 | cam_pixel_format format, int numBufs) | |
390 | { | |
391 | /* fimc_v4l2_enum_fmt */ | |
392 | int err; | |
393 | bool found = false; | |
394 | struct v4l2_fmtdesc fmtdesc; | |
395 | CLEAR(fmtdesc); | |
396 | fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
397 | fmtdesc.index = 0; | |
398 | ||
399 | while ((err = ioctl(mCameraFd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0) { | |
400 | if (fmtdesc.pixelformat == (uint32_t)format) { | |
401 | CLOGV("FLiteV4l2 start: %s", fmtdesc.description); | |
402 | found = true; | |
403 | break; | |
404 | } | |
405 | fmtdesc.index++; | |
406 | } | |
407 | ||
408 | if (!found) { | |
409 | CLOGE("FLiteV4l2 start: error, unsupported pixel format (%c%c%c%c)" | |
410 | " fmtdesc.pixelformat = %d, %s, err=%d", format, format >> 8, format >> 16, format >> 24, | |
411 | fmtdesc.pixelformat, fmtdesc.description, err); | |
412 | return -1; | |
413 | } | |
414 | ||
415 | /* fimc_v4l2_s_fmt */ | |
416 | struct v4l2_format v4l2_fmt; | |
417 | CLEAR(v4l2_fmt); | |
418 | ||
419 | v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
420 | v4l2_fmt.fmt.pix.width = videoSize->width; | |
421 | v4l2_fmt.fmt.pix.height = videoSize->height; | |
422 | v4l2_fmt.fmt.pix.pixelformat = format; | |
423 | v4l2_fmt.fmt.pix.priv = V4L2_PIX_FMT_MODE_CAPTURE; | |
424 | ||
425 | err = ioctl(mCameraFd, VIDIOC_S_FMT, &v4l2_fmt); | |
426 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_S_FMT", err)); | |
427 | ||
428 | v4l2_fmt.type = V4L2_BUF_TYPE_PRIVATE; | |
429 | v4l2_fmt.fmt.pix.width = videoSize->width; | |
430 | v4l2_fmt.fmt.pix.height = videoSize->height; | |
431 | v4l2_fmt.fmt.pix.pixelformat = format; | |
432 | v4l2_fmt.fmt.pix.field = (enum v4l2_field)IS_MODE_PREVIEW_STILL; | |
433 | ||
434 | CLOGD("Sensor FMT %dx%d", v4l2_fmt.fmt.pix.width, v4l2_fmt.fmt.pix.height); | |
435 | ||
436 | err = ioctl(mCameraFd, VIDIOC_S_FMT, &v4l2_fmt); | |
437 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_S_FMT", err)); | |
438 | ||
439 | /* fimc_v4l2_reqbufs */ | |
440 | struct v4l2_requestbuffers req; | |
441 | CLEAR(req); | |
442 | req.count = numBufs; | |
443 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
444 | #ifdef USE_USERPTR | |
445 | req.memory = V4L2_MEMORY_USERPTR; | |
446 | #else | |
447 | req.memory = V4L2_MEMORY_MMAP; | |
448 | #endif | |
449 | ||
450 | err = ioctl(mCameraFd, VIDIOC_REQBUFS, &req); | |
451 | CHECK_ERR_N(err, ("FLiteV4l2 start: error %d, VIDIOC_REQBUFS", err)); | |
452 | ||
453 | mBufferCount = (int)req.count; | |
454 | ||
455 | return 0; | |
456 | } | |
457 | ||
458 | int SecCameraHardware::FLiteV4l2::reqBufZero(node_info_t *mFliteNode) | |
459 | { | |
460 | int err; | |
461 | /* fimc_v4l2_reqbufs */ | |
462 | struct v4l2_requestbuffers req; | |
463 | CLEAR(req); | |
464 | req.count = 0; | |
465 | req.type = mFliteNode->type; | |
466 | req.memory = mFliteNode->memory; | |
467 | CLOGV("DEBUG(FLiteV4l2::reqBufZero): type[%d] memory[%d]", req.type, req.memory); | |
468 | err = ioctl(mCameraFd, VIDIOC_REQBUFS, &req); | |
469 | CHECK_ERR_N(err, ("FLiteV4l2 reqBufZero: error %d", err)); | |
470 | return 1; | |
471 | } | |
472 | ||
473 | int SecCameraHardware::FLiteV4l2::querybuf2(unsigned int index, int planeCnt, ExynosBuffer *buf) | |
474 | { | |
475 | struct v4l2_buffer v4l2_buf; | |
476 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | |
477 | int err; | |
478 | ||
479 | CLEAR(v4l2_buf); | |
480 | CLEAR(planes); | |
481 | ||
482 | /* loop for buffer count */ | |
483 | v4l2_buf.index = index; | |
484 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
485 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
486 | v4l2_buf.length = planeCnt; | |
487 | v4l2_buf.m.planes = planes; | |
488 | ||
489 | err = ioctl(mCameraFd , VIDIOC_QUERYBUF, &v4l2_buf); | |
490 | if (err < 0) { | |
491 | CLOGE("ERR(FLiteV4l2::querybuf2)(%d): error %d, index %d", __LINE__, err, index); | |
492 | return 0; | |
493 | } | |
494 | ||
495 | /* loop for planes */ | |
496 | for (int i = 0; i < planeCnt; i++) { | |
497 | unsigned int length = v4l2_buf.m.planes[i].length; | |
498 | unsigned int offset = v4l2_buf.m.planes[i].m.mem_offset; | |
499 | char *vAdr = (char *) mmap(0, | |
500 | v4l2_buf.m.planes[i].length, | |
501 | PROT_READ | PROT_WRITE, MAP_SHARED, | |
502 | mCameraFd, offset); | |
503 | CLOGV("DEBUG(%s): [%d][%d] length %d, offset %d vadr %p", __FUNCTION__, index, i, length, offset, vAdr); | |
504 | if (vAdr == NULL) { | |
505 | CLOGE("ERR(FLiteV4l2::querybuf2)(%d): [%d][%d] vAdr is %p", __LINE__, index, i, vAdr); | |
506 | return 0; | |
507 | } else { | |
508 | buf->virt.extP[i] = vAdr; | |
509 | buf->size.extS[i] = length; | |
510 | memset(buf->virt.extP[i], 0x0, buf->size.extS[i]); | |
511 | } | |
512 | } | |
513 | ||
514 | return 1; | |
515 | } | |
516 | ||
517 | int SecCameraHardware::FLiteV4l2::expBuf(unsigned int index, int planeCnt, ExynosBuffer *buf) | |
518 | { | |
519 | struct v4l2_exportbuffer v4l2_expbuf; | |
520 | int err; | |
521 | ||
522 | for (int i = 0; i < planeCnt; i++) { | |
523 | memset(&v4l2_expbuf, 0, sizeof(v4l2_expbuf)); | |
524 | v4l2_expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
525 | v4l2_expbuf.index = index; | |
526 | err = ioctl(mCameraFd, VIDIOC_EXPBUF, &v4l2_expbuf); | |
527 | if (err < 0) { | |
528 | CLOGE("ERR(FLiteV4l2::expBuf)(%d): [%d][%d] failed %d", __LINE__, index, i, err); | |
529 | goto EXP_ERR; | |
530 | } else { | |
531 | CLOGV("DEBUG(%s): [%d][%d] fd %d", __FUNCTION__, index, i, v4l2_expbuf.fd); | |
532 | buf->fd.extFd[i] = v4l2_expbuf.fd; | |
533 | } | |
534 | } | |
535 | return 1; | |
536 | ||
537 | EXP_ERR: | |
538 | for (int i = 0; i < planeCnt; i++) { | |
539 | if (buf->fd.extFd[i] > 0) | |
540 | ion_close(buf->fd.extFd[i]); | |
541 | } | |
542 | return 0; | |
543 | } | |
544 | ||
545 | ||
546 | sp<MemoryHeapBase> SecCameraHardware::FLiteV4l2::querybuf(uint32_t *frmsize) | |
547 | { | |
548 | struct v4l2_buffer v4l2_buf; | |
549 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
550 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
551 | v4l2_buf.length = 0; | |
552 | ||
553 | for (int i = 0; i < mBufferCount; i++) { | |
554 | int err; | |
555 | v4l2_buf.index = i; | |
556 | err = ioctl(mCameraFd , VIDIOC_QUERYBUF, &v4l2_buf); | |
557 | if (err < 0) { | |
558 | CLOGE("FLiteV4l2 querybufs: error %d, index %d", err, i); | |
559 | *frmsize = 0; | |
560 | return NULL; | |
561 | } | |
562 | } | |
563 | ||
564 | *frmsize = v4l2_buf.length; | |
565 | ||
566 | return mBufferCount == 1 ? | |
567 | new MemoryHeapBase(mCameraFd, v4l2_buf.length, v4l2_buf.m.offset) : NULL; | |
568 | } | |
569 | ||
570 | int SecCameraHardware::FLiteV4l2::qbuf(uint32_t index) | |
571 | { | |
572 | struct v4l2_buffer v4l2_buf; | |
573 | CLEAR(v4l2_buf); | |
574 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
575 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
576 | v4l2_buf.index = index; | |
577 | ||
578 | int err = ioctl(mCameraFd, VIDIOC_QBUF, &v4l2_buf); | |
579 | CHECK_ERR_N(err, ("FLiteV4l2 qbuf: error %d", err)); | |
580 | ||
581 | return 0; | |
582 | } | |
583 | ||
584 | int SecCameraHardware::FLiteV4l2::dqbuf() | |
585 | { | |
586 | struct v4l2_buffer v4l2_buf; | |
587 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
588 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
589 | ||
590 | int err = ioctl(mCameraFd, VIDIOC_DQBUF, &v4l2_buf); | |
591 | CHECK_ERR_N(err, ("FLiteV4l2 dqbuf: error %d", err)); | |
592 | ||
593 | if (v4l2_buf.index > (uint32_t)mBufferCount) { | |
594 | CLOGE("FLiteV4l2 dqbuf: error %d, invalid index", v4l2_buf.index); | |
595 | return -1; | |
596 | } | |
597 | ||
598 | return v4l2_buf.index; | |
599 | } | |
600 | ||
601 | int SecCameraHardware::FLiteV4l2::dqbuf(uint32_t *index) | |
602 | { | |
603 | struct v4l2_buffer v4l2_buf; | |
604 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
605 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
606 | ||
607 | int err = ioctl(mCameraFd, VIDIOC_DQBUF, &v4l2_buf); | |
608 | if (err >= 0) | |
609 | *index = v4l2_buf.index; | |
610 | ||
611 | return err; | |
612 | } | |
613 | ||
614 | int SecCameraHardware::FLiteV4l2::qbuf2(node_info_t *node, uint32_t index) | |
615 | { | |
616 | struct v4l2_buffer v4l2_buf; | |
617 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | |
618 | int i; | |
619 | int ret = 0; | |
620 | ||
621 | CLEAR(planes); | |
622 | CLEAR(v4l2_buf); | |
623 | ||
624 | v4l2_buf.m.planes = planes; | |
625 | v4l2_buf.type = node->type; | |
626 | v4l2_buf.memory = node->memory; | |
627 | v4l2_buf.index = index; | |
628 | v4l2_buf.length = node->planes; | |
629 | ||
630 | for(i = 0; i < node->planes; i++){ | |
631 | if (node->memory == V4L2_MEMORY_DMABUF) | |
632 | v4l2_buf.m.planes[i].m.fd = (int)(node->buffer[index].fd.extFd[i]); | |
633 | else if (node->memory == V4L2_MEMORY_USERPTR) { | |
634 | v4l2_buf.m.planes[i].m.userptr = (unsigned long)(node->buffer[index].virt.extP[i]); | |
635 | } else if (node->memory == V4L2_MEMORY_MMAP) { | |
636 | v4l2_buf.m.planes[i].m.userptr = (unsigned long)(node->buffer[index].virt.extP[i]); | |
637 | } else { | |
638 | CLOGE("ERR(%s):invalid node->memory(%d)", __func__, node->memory); | |
639 | return -1; | |
640 | } | |
641 | v4l2_buf.m.planes[i].length = (unsigned long)(node->buffer[index].size.extS[i]); | |
642 | } | |
643 | ||
644 | ret = exynos_v4l2_qbuf(node->fd, &v4l2_buf); | |
645 | if (ret < 0) { | |
646 | CLOGE("ERR(FLiteV4l2::qbuf2):exynos_v4l2_qbuf failed (index:%d)(ret:%d)", index, ret); | |
647 | return -1; | |
648 | }else{ | |
649 | CLOGV("DEBUG (FLiteV4l2::qbuf2) : exynos_v4l2_qbuf(index:%d)", index); | |
650 | } | |
651 | ||
652 | return ret; | |
653 | } | |
654 | ||
655 | int SecCameraHardware::FLiteV4l2::qbufForCapture(ExynosBuffer *buf, uint32_t index) | |
656 | { | |
657 | struct v4l2_buffer v4l2_buf; | |
658 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | |
659 | unsigned int i; | |
660 | int ret = 0; | |
661 | ||
662 | CLEAR(planes); | |
663 | CLEAR(v4l2_buf); | |
664 | ||
665 | v4l2_buf.m.planes = planes; | |
666 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
667 | #ifdef USE_USERPTR | |
668 | v4l2_buf.memory = V4L2_MEMORY_USERPTR; | |
669 | #else | |
670 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
671 | #endif | |
672 | v4l2_buf.index = index; | |
673 | v4l2_buf.length = 2; | |
674 | ||
675 | for(i = 0; i < v4l2_buf.length; i++){ | |
676 | if (v4l2_buf.memory == V4L2_MEMORY_DMABUF) | |
677 | v4l2_buf.m.planes[i].m.fd = (int)(buf->fd.extFd[i]); | |
678 | else if (v4l2_buf.memory == V4L2_MEMORY_USERPTR) { | |
679 | v4l2_buf.m.planes[i].m.userptr = (unsigned long)(buf->virt.extP[i]); | |
680 | } else if (v4l2_buf.memory == V4L2_MEMORY_MMAP) { | |
681 | v4l2_buf.m.planes[i].m.userptr = (unsigned long)(buf->virt.extP[i]); | |
682 | } else { | |
683 | ALOGE("ERR(FLiteV4l2::qbufForCapture):invalid node->memory(%d)", v4l2_buf.memory); | |
684 | return -1; | |
685 | } | |
686 | v4l2_buf.m.planes[i].length = (unsigned long)(buf->size.extS[i]); | |
687 | } | |
688 | ||
689 | ret = exynos_v4l2_qbuf(this->getFd(), &v4l2_buf); | |
690 | if (ret < 0) { | |
691 | CLOGE("ERR(FLiteV4l2::qbufForCapture):exynos_v4l2_qbuf failed (index:%d)(ret:%d)", index, ret); | |
692 | return -1; | |
693 | } | |
694 | ||
695 | return ret; | |
696 | } | |
697 | ||
698 | ||
699 | int SecCameraHardware::FLiteV4l2::dqbuf2(node_info_t *node) | |
700 | { | |
701 | struct v4l2_buffer v4l2_buf; | |
702 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | |
703 | int ret; | |
704 | ||
705 | CLEAR(planes); | |
706 | CLEAR(v4l2_buf); | |
707 | ||
708 | v4l2_buf.type = node->type; | |
709 | v4l2_buf.memory = node->memory; | |
710 | v4l2_buf.m.planes = planes; | |
711 | v4l2_buf.length = node->planes; | |
712 | ||
713 | ret = exynos_v4l2_dqbuf(node->fd, &v4l2_buf); | |
714 | if (ret < 0) { | |
715 | if (ret != -EAGAIN) | |
716 | ALOGE("ERR(%s):VIDIOC_DQBUF failed (%d)", __func__, ret); | |
717 | return ret; | |
718 | } | |
719 | ||
720 | if (v4l2_buf.flags & V4L2_BUF_FLAG_ERROR) { | |
721 | ALOGE("ERR(FLiteV4l2::dqbuf2):VIDIOC_DQBUF returned with error (%d)", V4L2_BUF_FLAG_ERROR); | |
722 | return -1; | |
723 | }else{ | |
724 | CLOGV("DEBUG [FLiteV4l2::dqbuf2(%d)] exynos_v4l2_dqbuf(index:%d)", __LINE__, v4l2_buf.index); | |
725 | } | |
726 | ||
727 | return v4l2_buf.index; | |
728 | } | |
729 | ||
730 | int SecCameraHardware::FLiteV4l2::dqbufForCapture(ExynosBuffer *buf) | |
731 | { | |
732 | struct v4l2_buffer v4l2_buf; | |
733 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | |
734 | int ret; | |
735 | ||
736 | CLEAR(planes); | |
737 | CLEAR(v4l2_buf); | |
738 | ||
739 | v4l2_buf.m.planes = planes; | |
740 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
741 | #ifdef USE_USERPTR | |
742 | v4l2_buf.memory = V4L2_MEMORY_USERPTR; | |
743 | #else | |
744 | v4l2_buf.memory = V4L2_MEMORY_MMAP; | |
745 | #endif | |
746 | v4l2_buf.length = 2; | |
747 | ||
748 | ret = exynos_v4l2_dqbuf(this->getFd(), &v4l2_buf); | |
749 | if (ret < 0) { | |
750 | if (ret != -EAGAIN) | |
751 | ALOGE("ERR(FLiteV4l2::dqbufForCapture):VIDIOC_DQBUF failed (%d)", ret); | |
752 | return ret; | |
753 | } | |
754 | ||
755 | if (v4l2_buf.flags & V4L2_BUF_FLAG_ERROR) { | |
756 | ALOGE("ERR(FLiteV4l2::dqbufForCapture):VIDIOC_DQBUF returned with error (%d)", V4L2_BUF_FLAG_ERROR); | |
757 | return -1; | |
758 | } | |
759 | ||
760 | return v4l2_buf.index; | |
761 | } | |
762 | ||
763 | #ifdef FAKE_SENSOR | |
764 | int SecCameraHardware::FLiteV4l2::fakeQbuf2(node_info_t *node, uint32_t index) | |
765 | { | |
766 | fakeByteData++; | |
767 | fakeByteData = fakeByteData % 0xFF; | |
768 | ||
769 | for (int i = 0; i < node->planes; i++) { | |
770 | memset(node->buffer[index].virt.extP[i], fakeByteData, | |
771 | node->buffer[index].size.extS[i]); | |
772 | ||
773 | } | |
774 | fakeIndex = index; | |
775 | return fakeIndex; | |
776 | } | |
777 | ||
778 | int SecCameraHardware::FLiteV4l2::fakeDqbuf2(node_info_t *node) | |
779 | { | |
780 | return fakeIndex; | |
781 | } | |
782 | #endif | |
783 | ||
784 | ||
785 | int SecCameraHardware::FLiteV4l2::stream(bool on) | |
786 | { | |
787 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
788 | int err = 0; | |
789 | ||
790 | CLOGV("DEBUG (FLiteV4l2::stream) : in "); | |
791 | ||
792 | err = sctrl(V4L2_CID_IS_S_STREAM, on ? IS_ENABLE_STREAM : IS_DISABLE_STREAM); | |
793 | CHECK_ERR_N(err, ("s_stream: error %d", err)); | |
794 | ||
795 | err = ioctl(mCameraFd, on ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type); | |
796 | CHECK_ERR_N(err, ("FLiteV4l2 stream: error %d", err)); | |
797 | ||
798 | mStreamOn = on; | |
799 | ||
800 | CLOGD("DEBUG (FLiteV4l2::stream) : stream turning %s", on ? "on" : "off"); | |
801 | ||
802 | return 0; | |
803 | } | |
804 | ||
805 | int SecCameraHardware::FLiteV4l2::polling(bool recordingMode) | |
806 | { | |
807 | int err = 0; | |
808 | struct pollfd events; | |
809 | CLEAR(events); | |
810 | events.fd = mCameraFd; | |
811 | events.events = POLLIN | POLLERR; | |
812 | ||
813 | const long timeOut = 1500; | |
814 | ||
815 | if (recordingMode) { | |
816 | const long sliceTimeOut = 66; | |
817 | ||
818 | for (int i = 0; i < (timeOut / sliceTimeOut); i++) { | |
819 | if (!mStreamOn) | |
820 | return 0; | |
821 | err = poll(&events, 1, sliceTimeOut); | |
822 | if (err > 0) | |
823 | break; | |
824 | } | |
825 | } else { | |
826 | #if 1 /* for test fast capture */ | |
827 | const int count = 40; | |
828 | for (int i = 0; i < count; i++) { | |
829 | err = poll(&events, 1, timeOut / count); | |
830 | if (mFastCapture) { | |
831 | return 0; | |
832 | } | |
833 | } | |
834 | #else | |
835 | err = poll(&events, 1, timeOut); | |
836 | #endif | |
837 | } | |
838 | ||
839 | if (CC_UNLIKELY(err <= 0)) | |
840 | CLOGE("FLiteV4l2 poll: error %d", err); | |
841 | ||
842 | return err; | |
843 | } | |
844 | ||
845 | int SecCameraHardware::FLiteV4l2::gctrl(uint32_t id, int *value) | |
846 | { | |
847 | struct v4l2_control ctrl; | |
848 | CLEAR(ctrl); | |
849 | ctrl.id = id; | |
850 | ||
851 | int err = ioctl(mCameraFd, VIDIOC_G_CTRL, &ctrl); | |
852 | CHECK_ERR_N(err, ("FLiteV4l2 gctrl: error %d, id %#x", err, id)); | |
853 | *value = ctrl.value; | |
854 | ||
855 | return 0; | |
856 | } | |
857 | ||
858 | int SecCameraHardware::FLiteV4l2::gctrl(uint32_t id, unsigned short *value) | |
859 | { | |
860 | struct v4l2_control ctrl; | |
861 | CLEAR(ctrl); | |
862 | ctrl.id = id; | |
863 | ||
864 | int err = ioctl(mCameraFd, VIDIOC_G_CTRL, &ctrl); | |
865 | CHECK_ERR_N(err, ("FLiteV4l2 gctrl: error %d, id %#x", err, id)); | |
866 | *value = (unsigned short)ctrl.value; | |
867 | ||
868 | return 0; | |
869 | } | |
870 | ||
871 | int SecCameraHardware::FLiteV4l2::gctrl(uint32_t id, char *value, int size) | |
872 | { | |
873 | struct v4l2_ext_controls ctrls; | |
874 | struct v4l2_ext_control ctrl; | |
875 | ||
876 | CLEAR(ctrls); | |
877 | ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; | |
878 | ctrls.count = 1; | |
879 | ctrls.controls = &ctrl; | |
880 | ||
881 | CLEAR(ctrl); | |
882 | ctrl.id = id; | |
883 | ctrl.string = value; | |
884 | ctrl.size=size; | |
885 | ||
886 | int err = ioctl(mCameraFd, VIDIOC_G_EXT_CTRLS, &ctrls); | |
887 | CHECK_ERR_N(err, ("FLiteV4l2 gctrl: error %d, id %#x", err, id)); | |
888 | ||
889 | return 0; | |
890 | } | |
891 | ||
892 | int SecCameraHardware::FLiteV4l2::sctrl(uint32_t id, int value) | |
893 | { | |
894 | struct v4l2_control ctrl; | |
895 | CLEAR(ctrl); | |
896 | ctrl.id = id; | |
897 | ctrl.value = value; | |
898 | ||
899 | int err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
900 | CHECK_ERR_N(err, ("FLiteV4l2 sctrl: error %d, id %#x value %d", err, id, value)); | |
901 | ||
902 | return 0; | |
903 | } | |
904 | ||
905 | int SecCameraHardware::FLiteV4l2::sparm(struct v4l2_streamparm *stream_parm) | |
906 | { | |
907 | int err = ioctl(mCameraFd, VIDIOC_S_PARM, stream_parm); | |
908 | CHECK_ERR_N(err, ("FLiteV4l2 sparm: error %d, value %d", err, | |
909 | stream_parm->parm.capture.timeperframe.denominator)); | |
910 | ||
911 | return 0; | |
912 | } | |
913 | ||
914 | ||
915 | int SecCameraHardware::FLiteV4l2::getYuvPhyaddr(int index, | |
916 | phyaddr_t *y, | |
917 | phyaddr_t *cbcr) | |
918 | { | |
919 | struct v4l2_control ctrl; | |
920 | int err; | |
921 | ||
922 | if (y) { | |
923 | CLEAR(ctrl); | |
924 | ctrl.id = V4L2_CID_PADDR_Y; | |
925 | ctrl.value = index; | |
926 | ||
927 | err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
928 | CHECK_ERR_N(err, ("FLiteV4l2 getYuvPhyaddr: error %d, V4L2_CID_PADDR_Y", err)); | |
929 | ||
930 | *y = ctrl.value; | |
931 | } | |
932 | ||
933 | if (cbcr) { | |
934 | CLEAR(ctrl); | |
935 | ctrl.id = V4L2_CID_PADDR_CBCR; | |
936 | ctrl.value = index; | |
937 | ||
938 | err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
939 | CHECK_ERR_N(err, ("FLiteV4l2 getYuvPhyaddr: error %d, V4L2_CID_PADDR_CBCR", err)); | |
940 | ||
941 | *cbcr = ctrl.value; | |
942 | } | |
943 | return 0; | |
944 | } | |
945 | ||
946 | int SecCameraHardware::FLiteV4l2::getYuvPhyaddr(int index, | |
947 | phyaddr_t *y, | |
948 | phyaddr_t *cb, | |
949 | phyaddr_t *cr) | |
950 | { | |
951 | struct v4l2_control ctrl; | |
952 | int err; | |
953 | ||
954 | if (y) { | |
955 | CLEAR(ctrl); | |
956 | ctrl.id = V4L2_CID_PADDR_Y; | |
957 | ctrl.value = index; | |
958 | ||
959 | err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
960 | CHECK_ERR_N(err, ("FLiteV4l2 getYuvPhyaddr: error %d, V4L2_CID_PADDR_Y", err)); | |
961 | ||
962 | *y = ctrl.value; | |
963 | } | |
964 | ||
965 | if (cb) { | |
966 | CLEAR(ctrl); | |
967 | ctrl.id = V4L2_CID_PADDR_CB; | |
968 | ctrl.value = index; | |
969 | ||
970 | err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
971 | CHECK_ERR_N(err, ("FLiteV4l2 getYuvPhyaddr: error %d, V4L2_CID_PADDR_CB", err)); | |
972 | ||
973 | *cb = ctrl.value; | |
974 | } | |
975 | ||
976 | if (cr) { | |
977 | CLEAR(ctrl); | |
978 | ctrl.id = V4L2_CID_PADDR_CR; | |
979 | ctrl.value = index; | |
980 | ||
981 | err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
982 | CHECK_ERR_N(err, ("FLiteV4l2 getYuvPhyaddr: error %d, V4L2_CID_PADDR_CR", err)); | |
983 | ||
984 | *cr = ctrl.value; | |
985 | } | |
986 | ||
987 | return 0; | |
988 | } | |
989 | ||
990 | int SecCameraHardware::FLiteV4l2::setFastCaptureFimc(uint32_t IsFastCaptureCalled) | |
991 | { | |
992 | mFastCapture = IsFastCaptureCalled; | |
993 | ALOGD("Set Fast capture in fimc : %d", mFastCapture); | |
994 | return 0; | |
995 | } | |
996 | ||
997 | int SecCameraHardware::FLiteV4l2::reset() | |
998 | { | |
999 | struct v4l2_control ctrl; | |
1000 | CLEAR(ctrl); | |
1001 | ctrl.id = V4L2_CID_CAMERA_RESET; | |
1002 | ctrl.value = 0; | |
1003 | ||
1004 | int err = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl); | |
1005 | CHECK_ERR_N(err, ("FLiteV4l2 reset: error %d", err)); | |
1006 | ||
1007 | return 0; | |
1008 | } | |
1009 | ||
1010 | void SecCameraHardware::FLiteV4l2::forceStop() | |
1011 | { | |
1012 | mCmdStop = 1; | |
1013 | return; | |
1014 | } | |
1015 | ||
1016 | int SecCameraHardware::FLiteV4l2::getFd() | |
1017 | { | |
1018 | return mCameraFd; | |
1019 | } | |
1020 | ||
1021 | bool SecCameraHardware::init() | |
1022 | { | |
1023 | CLOGD("DEBUG [%s(%d)] -in-", __FUNCTION__, __LINE__); | |
1024 | ||
1025 | LOG_PERFORMANCE_START(1); | |
1026 | CLEAR(mFliteNode); | |
1027 | CSC_METHOD cscMethod = CSC_METHOD_HW; | |
1028 | int err; | |
1029 | ||
1030 | if (mCameraId == CAMERA_ID_BACK) | |
1031 | err = mFlite.init(FLITE0_DEV_PATH, mCameraId); | |
1032 | else | |
1033 | err = mFlite.init(FLITE1_DEV_PATH, mCameraId); | |
1034 | ||
1035 | ||
1036 | if (CC_UNLIKELY(err < 0)) { | |
1037 | ALOGE("initCamera X: error(%d), %s", err, | |
1038 | (mCameraId == CAMERA_ID_BACK) ? FLITE0_DEV_PATH : FLITE1_DEV_PATH); | |
1039 | goto fimc_out; | |
1040 | } | |
1041 | if (mCameraId == CAMERA_ID_BACK) { | |
1042 | char read_prop[92]; | |
1043 | int res_prop = 0; | |
1044 | int value = 0; | |
1045 | ||
1046 | CLEAR(read_prop); | |
1047 | res_prop = property_get("persist.sys.camera.fw_update", read_prop, "0"); | |
1048 | ALOGD("Lens Close Hold persist.sys.camera.fw_update [%s], res %d", read_prop, res_prop); | |
1049 | ||
1050 | // ISP boot option : "0" => Normal, "1" => fw_update | |
1051 | if (!strcmp(read_prop, "1")) | |
1052 | value = 0x1; | |
1053 | else | |
1054 | { | |
1055 | CLEAR(read_prop); | |
1056 | res_prop = property_get("persist.sys.camera.samsung", read_prop, "0"); | |
1057 | ALOGD("Lens Close Hold persist.sys.camera.samsung [%s], res %d", read_prop, res_prop); | |
1058 | ||
1059 | // samsung app : "0" => 3th party app, "1" => samsung app | |
1060 | if (!strcmp(read_prop, "1")) | |
1061 | value = 0x0; | |
1062 | else | |
1063 | value = 0x1; | |
1064 | } | |
1065 | ||
1066 | CLEAR(read_prop); | |
1067 | res_prop = property_get("persist.sys.camera.mem", read_prop, "0"); | |
1068 | ALOGD("ISP mem : property get [%s], res %d", read_prop, res_prop); | |
1069 | ||
1070 | // ISP target memory : "0" => NOR, "1" => EEPROM | |
1071 | if (!strcmp(read_prop, "1")) | |
1072 | value |= (0x1 << 8); | |
1073 | else | |
1074 | value |= 0x0; | |
1075 | ||
1076 | ALOGD("call camera init with value: 0x%02X", value); | |
1077 | if (CC_UNLIKELY(err < 0)) { | |
1078 | ALOGE("camera init error:%d", err); | |
1079 | } | |
1080 | } | |
1081 | mFliteNode.fd = mFlite.getFd(); | |
1082 | ALOGV("mFlite fd %d", mFlite.getFd()); | |
1083 | ||
1084 | setExifFixedAttribute(); | |
1085 | ||
1086 | /* init CSC (fimc1, fimc2) */ | |
1087 | mFimc1CSC = csc_init(cscMethod); | |
1088 | if (mFimc1CSC == NULL) | |
1089 | ALOGE("ERR(%s): mFimc1CSC csc_init() fail", __func__); | |
1090 | err = csc_set_hw_property(mFimc1CSC, CSC_HW_PROPERTY_FIXED_NODE, FIMC1_NODE_NUM); | |
1091 | if (err != 0) | |
1092 | ALOGE("ERR(%s): fimc0 open failed %d", __func__, err); | |
1093 | ||
1094 | mFimc2CSC = csc_init(cscMethod); | |
1095 | if (mFimc2CSC == NULL) | |
1096 | ALOGE("ERR(%s): mFimc2CSC csc_init() fail", __func__); | |
1097 | err = csc_set_hw_property(mFimc2CSC, CSC_HW_PROPERTY_FIXED_NODE, FIMC2_NODE_NUM); | |
1098 | if (err != 0) | |
1099 | ALOGE("ERR(%s): fimc1 open failed %d", __func__, err); | |
1100 | ||
1101 | LOG_PERFORMANCE_END(1, "total"); | |
1102 | return ISecCameraHardware::init(); | |
1103 | ||
1104 | fimc_out: | |
1105 | mFlite.deinit(); | |
1106 | return false; | |
1107 | } | |
1108 | ||
1109 | void SecCameraHardware::initDefaultParameters() | |
1110 | { | |
1111 | char str[16]; | |
1112 | CLEAR(str); | |
1113 | if (mCameraId == CAMERA_FACING_BACK) { | |
1114 | snprintf(str, sizeof(str), "%f", (double)Exif::DEFAULT_BACK_FOCAL_LEN_NUM/ | |
1115 | Exif::DEFAULT_BACK_FOCAL_LEN_DEN); | |
1116 | mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, str); | |
1117 | } else { | |
1118 | snprintf(str, sizeof(str), "%f", (double)Exif::DEFAULT_FRONT_FOCAL_LEN_NUM/ | |
1119 | Exif::DEFAULT_FRONT_FOCAL_LEN_DEN); | |
1120 | mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, str); | |
1121 | } | |
1122 | ||
1123 | ISecCameraHardware::initDefaultParameters(); | |
1124 | } | |
1125 | ||
1126 | void SecCameraHardware::release() | |
1127 | { | |
1128 | CLOGD("INFO(%s) : in ",__FUNCTION__); | |
1129 | ||
1130 | /* Forced wake up sound interrupt */ | |
1131 | mCameraPower = false; | |
1132 | ExynosBuffer nullBuf; | |
1133 | int i = 0; | |
1134 | ||
1135 | ISecCameraHardware::release(); | |
1136 | ||
1137 | mFlite.deinit(); | |
1138 | ||
1139 | /* flite buffer free */ | |
1140 | for (i = 0; i < FLITE_BUF_CNT; i++) { | |
1141 | freeMem(&mFliteNode.buffer[i]); | |
1142 | mFliteNode.buffer[i] = nullBuf; | |
1143 | } | |
1144 | ||
1145 | /* capture buffer free */ | |
1146 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
1147 | freeMem(&mPictureBufDummy[i]); | |
1148 | mPictureBufDummy[i] = nullBuf; | |
1149 | } | |
1150 | freeMem(&mPictureBuf); | |
1151 | mPictureBuf = nullBuf; | |
1152 | ||
1153 | mInitRecSrcQ(); | |
1154 | mInitRecDstBuf(); | |
1155 | ||
1156 | /* deinit CSC (fimc0, fimc1) */ | |
1157 | if (mFimc1CSC) | |
1158 | csc_deinit(mFimc1CSC); | |
1159 | mFimc1CSC = NULL; | |
1160 | ||
1161 | if (mFimc2CSC) | |
1162 | csc_deinit(mFimc2CSC); | |
1163 | mFimc2CSC = NULL; | |
1164 | } | |
1165 | ||
1166 | int SecCameraHardware::nativeSetFastCapture(bool onOff) | |
1167 | { | |
1168 | mFastCaptureCalled = onOff; | |
1169 | ||
1170 | mFlite.setFastCaptureFimc(mFastCaptureCalled); | |
1171 | return 0; | |
1172 | } | |
1173 | ||
1174 | bool SecCameraHardware::nativeCreateSurface(uint32_t width, uint32_t height, uint32_t halPixelFormat) | |
1175 | { | |
1176 | CLOGV("INFO(%s) : in ",__FUNCTION__); | |
1177 | ||
1178 | int min_bufs; | |
1179 | ||
1180 | if (CC_UNLIKELY(mFlagANWindowRegister == true)) { | |
1181 | ALOGI("Surface already exist!!"); | |
1182 | return true; | |
1183 | } | |
1184 | ||
1185 | status_t err; | |
1186 | ||
1187 | if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &min_bufs)) { | |
1188 | ALOGE("%s: could not retrieve min undequeued buffer count", __FUNCTION__); | |
1189 | return INVALID_OPERATION; | |
1190 | } | |
1191 | ||
1192 | if (min_bufs >= PREVIEW_BUF_CNT) { | |
1193 | ALOGE("%s: warning, min undequeued buffer count %d is too high (expecting at most %d)", __FUNCTION__, | |
1194 | min_bufs, PREVIEW_BUF_CNT - 1); | |
1195 | } | |
1196 | ||
1197 | CLOGD("DEBUG [%s(%d)] setting buffer count to %d", __FUNCTION__, __LINE__,PREVIEW_BUF_CNT); | |
1198 | if (mPreviewWindow->set_buffer_count(mPreviewWindow, PREVIEW_BUF_CNT)) { | |
1199 | ALOGE("%s: could not set buffer count", __FUNCTION__); | |
1200 | return INVALID_OPERATION; | |
1201 | } | |
1202 | ||
1203 | if (mPreviewWindow->set_usage(mPreviewWindow, GRALLOC_SET_USAGE_FOR_CAMERA) != 0) { | |
1204 | ALOGE("ERR(%s):could not set usage on gralloc buffer", __func__); | |
1205 | return INVALID_OPERATION; | |
1206 | } | |
1207 | ||
1208 | CLOGD("DEBUG [%s(%d)] (%dx%d)", __FUNCTION__, __LINE__, width, height); | |
1209 | if (mPreviewWindow->set_buffers_geometry(mPreviewWindow, | |
1210 | width, height, | |
1211 | halPixelFormat)) { | |
1212 | CLOGE("%s: could not set buffers geometry ", __FUNCTION__); | |
1213 | return INVALID_OPERATION; | |
1214 | } | |
1215 | ||
1216 | mFlagANWindowRegister = true; | |
1217 | ||
1218 | return true; | |
1219 | } | |
1220 | ||
1221 | bool SecCameraHardware::nativeDestroySurface(void) | |
1222 | { | |
1223 | CLOGV("DEBUG [%s(%d)] -in-", __FUNCTION__, __LINE__); | |
1224 | mFlagANWindowRegister = false; | |
1225 | ||
1226 | return true; | |
1227 | } | |
1228 | ||
1229 | int SecCameraHardware::save_dump_path( uint8_t *real_data, int data_size, const char* filePath) | |
1230 | { | |
1231 | FILE *fp = NULL; | |
1232 | char *buffer = NULL; | |
1233 | ||
1234 | CLOGE("save dump E"); | |
1235 | fp = fopen(filePath, "wb"); | |
1236 | ||
1237 | if (fp == NULL) { | |
1238 | CLOGE("Save dump image open error"); | |
1239 | return -1; | |
1240 | } | |
1241 | ||
1242 | CLOGE("%s: real_data size ========> %d", __func__, data_size); | |
1243 | buffer = (char *) malloc(data_size); | |
1244 | if (buffer == NULL) { | |
1245 | CLOGE("Save buffer alloc failed"); | |
1246 | if (fp) | |
1247 | fclose(fp); | |
1248 | ||
1249 | return -1; | |
1250 | } | |
1251 | ||
1252 | memcpy(buffer, real_data, data_size); | |
1253 | ||
1254 | fflush(stdout); | |
1255 | ||
1256 | fwrite(buffer, 1, data_size, fp); | |
1257 | ||
1258 | fflush(fp); | |
1259 | ||
1260 | if (fp) | |
1261 | fclose(fp); | |
1262 | if (buffer) | |
1263 | free(buffer); | |
1264 | ||
1265 | CLOGE("save dump X"); | |
1266 | return 0; | |
1267 | } | |
1268 | ||
1269 | bool SecCameraHardware::nativeFlushSurfaceYUV420(uint32_t width, uint32_t height, uint32_t size, uint32_t index, int type) | |
1270 | { | |
1271 | //ALOGV("%s: width=%d, height=%d, size=0x%x, index=%d", __FUNCTION__, width, height, size, index); | |
1272 | ExynosBuffer dstBuf; | |
1273 | buffer_handle_t *buf_handle = NULL; | |
1274 | ||
1275 | if (CC_UNLIKELY(!mPreviewWindowSize.width)) { | |
1276 | ALOGE("nativeFlushSurfacePostview: error, Preview window %dx%d", mPreviewWindowSize.width, mPreviewWindowSize.height); | |
1277 | return false; | |
1278 | } | |
1279 | ||
1280 | if (CC_UNLIKELY(mFlagANWindowRegister == false)) { | |
1281 | ALOGE("%s::mFlagANWindowRegister == false fail", __FUNCTION__); | |
1282 | return false; | |
1283 | } | |
1284 | ||
1285 | if (mPreviewWindow && mGrallocHal) { | |
1286 | int stride; | |
1287 | if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) { | |
1288 | ALOGE("Could not dequeue gralloc buffer!\n"); | |
1289 | return false; | |
1290 | } else { | |
1291 | if (mPreviewWindow->lock_buffer(mPreviewWindow, buf_handle) != 0) | |
1292 | ALOGE("ERR(%s):Could not lock gralloc buffer !!", __func__ ); | |
1293 | } | |
1294 | ||
1295 | #ifdef SUPPORT_64BITS | |
1296 | void *vaddr[3] = {NULL}; | |
1297 | if (!mGrallocHal->lock(mGrallocHal, | |
1298 | *buf_handle, | |
1299 | GRALLOC_LOCK_FOR_CAMERA, | |
1300 | 0, 0, width, height, vaddr)) { | |
1301 | #else | |
1302 | unsigned int vaddr[3]; | |
1303 | if (!mGrallocHal->lock(mGrallocHal, | |
1304 | *buf_handle, | |
1305 | GRALLOC_LOCK_FOR_CAMERA, | |
1306 | 0, 0, width, height, (void **)vaddr)) { | |
1307 | #endif | |
1308 | ||
1309 | char *src; | |
1310 | char *ptr = (char *)vaddr[0]; | |
1311 | src = (char *)mPostviewHeap->data; | |
1312 | ||
1313 | memcpy(ptr, src, width * height); | |
1314 | src += width * height; | |
1315 | ptr = (char *)vaddr[1]; | |
1316 | memcpy(ptr, src, (width * height ) >> 1); | |
1317 | ||
1318 | mGrallocHal->unlock(mGrallocHal, *buf_handle); | |
1319 | } | |
1320 | ||
1321 | if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) { | |
1322 | ALOGE("Could not enqueue gralloc buffer!\n"); | |
1323 | return false; | |
1324 | } | |
1325 | } else if (!mGrallocHal) { | |
1326 | ALOGE("nativeFlushSurfaceYUV420: gralloc HAL is not loaded"); | |
1327 | return false; | |
1328 | } | |
1329 | ||
1330 | return true; | |
1331 | ||
1332 | CANCEL: | |
1333 | if (mPreviewWindow->cancel_buffer(mPreviewWindow, buf_handle) != 0) | |
1334 | ALOGE("ERR(%s):Fail to cancel buffer", __func__); | |
1335 | ||
1336 | return false; | |
1337 | } | |
1338 | ||
1339 | bool SecCameraHardware::nativeFlushSurface( | |
1340 | uint32_t width, uint32_t height, uint32_t size, uint32_t index, int type) | |
1341 | { | |
1342 | //ALOGV("%s: width=%d, height=%d, size=0x%x, index=%d", __FUNCTION__, width, height, size, index); | |
1343 | ExynosBuffer dstBuf; | |
1344 | buffer_handle_t *buf_handle = NULL; | |
1345 | ||
1346 | if (CC_UNLIKELY(!mPreviewWindowSize.width)) { | |
1347 | CLOGE("nativeFlushSurface: error, Preview window %dx%d", | |
1348 | mPreviewWindowSize.width, mPreviewWindowSize.height); | |
1349 | return false; | |
1350 | } | |
1351 | ||
1352 | if (CC_UNLIKELY(mFlagANWindowRegister == false)) { | |
1353 | CLOGE("%s::mFlagANWindowRegister == false fail", __FUNCTION__); | |
1354 | return false; | |
1355 | } | |
1356 | ||
1357 | if (mPreviewWindow && mGrallocHal) { | |
1358 | int stride; | |
1359 | if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) { | |
1360 | CLOGE("Could not dequeue gralloc buffer!\n"); | |
1361 | return false; | |
1362 | } else { | |
1363 | if (mPreviewWindow->lock_buffer(mPreviewWindow, buf_handle) != 0) | |
1364 | CLOGE("ERR(%s):Could not lock gralloc buffer !!", __func__ ); | |
1365 | } | |
1366 | #ifdef SUPPORT_64BITS | |
1367 | void *vaddr[3] = {NULL}; | |
1368 | if (!mGrallocHal->lock(mGrallocHal, | |
1369 | *buf_handle, | |
1370 | GRALLOC_LOCK_FOR_CAMERA, | |
1371 | 0, 0, width, height, vaddr)) { | |
1372 | #else | |
1373 | unsigned int vaddr[3]; | |
1374 | if (!mGrallocHal->lock(mGrallocHal, | |
1375 | *buf_handle, | |
1376 | GRALLOC_LOCK_FOR_CAMERA, | |
1377 | 0, 0, width, height, (void **)vaddr)) { | |
1378 | #endif | |
1379 | /* csc start flite(s) -> fimc0 -> gralloc(d) */ | |
1380 | if (mFimc1CSC) { | |
1381 | /* set zoom info */ | |
1382 | bool flag; | |
1383 | flag = getCropRect(mFLiteSize.width, mFLiteSize.height, mPreviewSize.width, | |
1384 | mPreviewSize.height, &mPreviewZoomRect.x, &mPreviewZoomRect.y, | |
1385 | &mPreviewZoomRect.w, &mPreviewZoomRect.h, 2, 2, 2, 2, mZoomRatio); | |
1386 | if(false == flag) { | |
1387 | CLOGE("ERR(%s):mFLiteSize.width = %u mFLiteSize.height = %u " | |
1388 | "mPreviewSize.width = %u mPreviewSize.height = %u ", __func__, | |
1389 | mFLiteSize.width, mFLiteSize.height, mPreviewSize.width, mPreviewSize.height); | |
1390 | CLOGE("ERR(%s):Preview CropRect failed X = %u Y = %u W = %u H = %u ", __func__, | |
1391 | mPreviewZoomRect.x, mPreviewZoomRect.y, mPreviewZoomRect.w, mPreviewZoomRect.h); | |
1392 | } | |
1393 | ||
1394 | #ifdef DEBUG_PREVIEW | |
1395 | CLOGD("DEBUG PREVIEW(%s:%d): src(%d,%d,%d,%d,%d,%d), dst(%d,%d), fmt(%s)" | |
1396 | , __FUNCTION__, __LINE__ | |
1397 | , mFLiteSize.width | |
1398 | , mFLiteSize.height | |
1399 | , mPreviewZoomRect.x | |
1400 | , mPreviewZoomRect.y | |
1401 | , mPreviewZoomRect.w | |
1402 | , mPreviewZoomRect.h | |
1403 | , mPreviewSize.width | |
1404 | , mPreviewSize.height | |
1405 | , mFliteNode.format == CAM_PIXEL_FORMAT_YVU420P ? "YV12" : | |
1406 | mFliteNode.format == CAM_PIXEL_FORMAT_YUV420SP ? "NV21" : | |
1407 | mFliteNode.format == CAM_PIXEL_FORMAT_YUV422I ? "YUYV" : | |
1408 | "Others"); | |
1409 | ||
1410 | #endif | |
1411 | ||
1412 | /* src : FLite */ | |
1413 | csc_set_src_format(mFimc1CSC, | |
1414 | mFLiteSize.width, mFLiteSize.height, | |
1415 | mPreviewZoomRect.x, mPreviewZoomRect.y, | |
1416 | mPreviewZoomRect.w, mPreviewZoomRect.h, | |
1417 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
1418 | 0); | |
1419 | ||
1420 | if (type == CAMERA_HEAP_POSTVIEW) { | |
1421 | csc_set_src_buffer(mFimc1CSC, | |
1422 | (void **)mPictureBufDummy[0].fd.extFd, CSC_MEMORY_DMABUF); | |
1423 | } else { | |
1424 | csc_set_src_buffer(mFimc1CSC, | |
1425 | (void **)mFliteNode.buffer[index].fd.extFd, CSC_MEMORY_DMABUF); | |
1426 | } | |
1427 | ||
1428 | //mSaveDump("/data/camera_source%d.yuv", &mFliteNode.buffer[index], index); | |
1429 | ||
1430 | int halPixelFormat = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_FULL; | |
1431 | ||
1432 | /* when recording, narrow color range will be applied */ | |
1433 | if (mMovieMode) | |
1434 | halPixelFormat = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP; | |
1435 | ||
1436 | /* dst : GRALLOC */ | |
1437 | csc_set_dst_format(mFimc1CSC, | |
1438 | mPreviewSize.width, mPreviewSize.height, | |
1439 | 0, 0, | |
1440 | mPreviewSize.width, mPreviewSize.height, | |
1441 | halPixelFormat, | |
1442 | 0); | |
1443 | ||
1444 | const private_handle_t *priv_handle = private_handle_t::dynamicCast(*buf_handle); | |
1445 | dstBuf.fd.extFd[0] = priv_handle->fd; | |
1446 | dstBuf.fd.extFd[1] = priv_handle->fd1; | |
1447 | dstBuf.virt.extP[0] = (char *)vaddr[0]; | |
1448 | dstBuf.virt.extP[1] = (char *)vaddr[1]; | |
1449 | dstBuf.size.extS[0] = mPreviewSize.width * mPreviewSize.height; | |
1450 | dstBuf.size.extS[1] = mPreviewSize.width * mPreviewSize.height / 2; | |
1451 | ||
1452 | csc_set_dst_buffer(mFimc1CSC, | |
1453 | (void **)dstBuf.fd.extFd, CSC_MEMORY_DMABUF); | |
1454 | ||
1455 | mFimc1CSCLock.lock(); | |
1456 | if (csc_convert(mFimc1CSC) != 0) { | |
1457 | ALOGE("ERR(%s):csc_convert(mFimc1CSC) fail", __func__); | |
1458 | mFimc1CSCLock.unlock(); | |
1459 | goto CANCEL; | |
1460 | } | |
1461 | mFimc1CSCLock.unlock(); | |
1462 | } | |
1463 | ||
1464 | mGrallocHal->unlock(mGrallocHal, *buf_handle); | |
1465 | } | |
1466 | ||
1467 | #ifdef USE_DEDICATED_PREVIEW_ENQUEUE_THREAD | |
1468 | m_previewFrameQ.pushProcessQ(&buf_handle); | |
1469 | #else | |
1470 | if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) { | |
1471 | ALOGE("Could not enqueue gralloc buffer!\n"); | |
1472 | return false; | |
1473 | } | |
1474 | #endif | |
1475 | } else if (!mGrallocHal) { | |
1476 | ALOGE("nativeFlushSurface: gralloc HAL is not loaded"); | |
1477 | return false; | |
1478 | } | |
1479 | ||
1480 | #if 0 | |
1481 | static int count=0; | |
1482 | mSaveDump("/data/camera_flush%d.yuv", &dstBuf, count); | |
1483 | count++; | |
1484 | if(count > 3) count = 0; | |
1485 | #endif | |
1486 | /* if CAMERA_MSG_PREVIEW_METADATA, prepare callback buffer */ | |
1487 | if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { | |
1488 | if (nativePreviewCallback(index, &dstBuf) < 0) | |
1489 | ALOGE("ERROR(%s): nativePreviewCallback failed", __func__); | |
1490 | } | |
1491 | ||
1492 | ||
1493 | return true; | |
1494 | ||
1495 | CANCEL: | |
1496 | if (mPreviewWindow->cancel_buffer(mPreviewWindow, buf_handle) != 0) | |
1497 | ALOGE("ERR(%s):Fail to cancel buffer", __func__); | |
1498 | ||
1499 | return false; | |
1500 | } | |
1501 | ||
1502 | bool SecCameraHardware::beautyLiveFlushSurface(uint32_t width, uint32_t height, uint32_t size, uint32_t index, int type) | |
1503 | { | |
1504 | //ALOGV("%s: width=%d, height=%d, size=0x%x, index=%d", __FUNCTION__, width, height, size, index); | |
1505 | ExynosBuffer dstBuf; | |
1506 | buffer_handle_t *buf_handle = NULL; | |
1507 | ||
1508 | if (CC_UNLIKELY(!mPreviewWindowSize.width)) { | |
1509 | ALOGE("beautyLiveFlushSurface: error, Preview window %dx%d", mPreviewWindowSize.width, mPreviewWindowSize.height); | |
1510 | return false; | |
1511 | } | |
1512 | ||
1513 | if (CC_UNLIKELY(mFlagANWindowRegister == false)) { | |
1514 | ALOGE("%s::mFlagANWindowRegister == false fail", __FUNCTION__); | |
1515 | return false; | |
1516 | } | |
1517 | ||
1518 | if (mPreviewWindow && mGrallocHal) { | |
1519 | int stride; | |
1520 | if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) { | |
1521 | ALOGE("Could not dequeue gralloc buffer!\n"); | |
1522 | return false; | |
1523 | } else { | |
1524 | if (mPreviewWindow->lock_buffer(mPreviewWindow, buf_handle) != 0) | |
1525 | ALOGE("ERR(%s):Could not lock gralloc buffer !!", __func__ ); | |
1526 | } | |
1527 | ||
1528 | #ifdef SUPPORT_64BITS | |
1529 | void *vaddr[3] = {NULL}; | |
1530 | if (!mGrallocHal->lock(mGrallocHal, | |
1531 | *buf_handle, | |
1532 | GRALLOC_LOCK_FOR_CAMERA, | |
1533 | 0, 0, width, height, vaddr)) { | |
1534 | #else | |
1535 | unsigned int vaddr[3]; | |
1536 | if (!mGrallocHal->lock(mGrallocHal, | |
1537 | *buf_handle, | |
1538 | GRALLOC_LOCK_FOR_CAMERA, | |
1539 | 0, 0, width, height, (void **)vaddr)) { | |
1540 | #endif | |
1541 | /////////////////////////////////////////////////////////////////////// | |
1542 | char *frame = NULL; | |
1543 | if ( type==CAMERA_HEAP_PREVIEW) { | |
1544 | frame = ((char *)mPreviewHeap->data) + (mPreviewFrameSize * index); | |
1545 | } else { | |
1546 | frame = ((char *)mPostviewHeap->data); | |
1547 | } | |
1548 | char *src = frame; | |
1549 | char *ptr = (char *)vaddr[0]; | |
1550 | ||
1551 | if (src == NULL || ptr == NULL) | |
1552 | return false; | |
1553 | ||
1554 | // Y | |
1555 | memcpy(ptr, src, width * height); | |
1556 | src += width * height; | |
1557 | if (mPreviewFormat == CAM_PIXEL_FORMAT_YVU420P) { | |
1558 | /* YV12 */ | |
1559 | //ALOGV("%s: yuv420p YV12", __func__); | |
1560 | // V | |
1561 | ptr = (char *)vaddr[1]; | |
1562 | if (src == NULL || ptr == NULL) | |
1563 | return false; | |
1564 | ||
1565 | memcpy(ptr, src, width * height / 4); | |
1566 | src += width * height / 4; | |
1567 | // U | |
1568 | ptr = (char *)vaddr[2]; | |
1569 | if (src == NULL || ptr == NULL) | |
1570 | return false; | |
1571 | ||
1572 | memcpy(ptr, src, width * height / 4); | |
1573 | } else if (mPreviewFormat == CAM_PIXEL_FORMAT_YUV420SP) { | |
1574 | /* NV21 */ | |
1575 | //ALOGV("%s: yuv420sp NV21", __func__); | |
1576 | ptr = (char *)vaddr[1]; | |
1577 | if (src == NULL || ptr == NULL) | |
1578 | return false; | |
1579 | ||
1580 | memcpy(ptr, src, (width * height) >> 1); | |
1581 | } | |
1582 | /////////////////////////////////////////////////////////////////////// | |
1583 | mGrallocHal->unlock(mGrallocHal, *buf_handle); | |
1584 | } | |
1585 | ||
1586 | #ifdef USE_DEDICATED_PREVIEW_ENQUEUE_THREAD | |
1587 | m_previewFrameQ.pushProcessQ(&buf_handle); | |
1588 | #else | |
1589 | if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) { | |
1590 | ALOGE("Could not enqueue gralloc buffer!\n"); | |
1591 | return false; | |
1592 | } | |
1593 | #endif | |
1594 | } else if (!mGrallocHal) { | |
1595 | ALOGE("nativeFlushSurface: gralloc HAL is not loaded"); | |
1596 | return false; | |
1597 | } | |
1598 | ||
1599 | /* if CAMERA_MSG_PREVIEW_METADATA, prepare callback buffer */ | |
1600 | if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { | |
1601 | if (nativePreviewCallback(index, &dstBuf) < 0) | |
1602 | ALOGE("ERROR(%s): nativePreviewCallback failed", __func__); | |
1603 | } | |
1604 | ||
1605 | return true; | |
1606 | ||
1607 | CANCEL: | |
1608 | if (mPreviewWindow->cancel_buffer(mPreviewWindow, buf_handle) != 0) | |
1609 | ALOGE("ERR(%s):Fail to cancel buffer", __func__); | |
1610 | ||
1611 | return false; | |
1612 | } | |
1613 | ||
1614 | ||
1615 | ||
1616 | image_rect_type SecCameraHardware::nativeGetWindowSize() | |
1617 | { | |
1618 | image_rect_type window; | |
1619 | if (!mMovieMode) { | |
1620 | window.width = mPreviewSize.width; | |
1621 | window.height = mPreviewSize.height; | |
1622 | return window; | |
1623 | } | |
1624 | ||
1625 | switch (FRM_RATIO(mPreviewSize)) { | |
1626 | case CAM_FRMRATIO_QCIF: | |
1627 | window.width = 528; | |
1628 | window.height = 432; | |
1629 | break; | |
1630 | case CAM_FRMRATIO_VGA: | |
1631 | window.width = 640; | |
1632 | window.height = 480; | |
1633 | break; | |
1634 | case CAM_FRMRATIO_WVGA: | |
1635 | window.width = 800; | |
1636 | window.height = 480; | |
1637 | break; | |
1638 | case CAM_FRMRATIO_D1: | |
1639 | window.width = 720; | |
1640 | window.height = 480; | |
1641 | break; | |
1642 | case CAM_FRMRATIO_HD: | |
1643 | window.width = 800; | |
1644 | window.height = 450; | |
1645 | break; | |
1646 | default: | |
1647 | ALOGW("nativeGetWindowSize: invalid frame ratio %d", FRM_RATIO(mPreviewSize)); | |
1648 | window.width = mPreviewSize.width; | |
1649 | window.height = mPreviewSize.height; | |
1650 | break; | |
1651 | } | |
1652 | return window; | |
1653 | } | |
1654 | ||
1655 | bool SecCameraHardware::allocatePreviewHeap() | |
1656 | { | |
1657 | if (mPreviewHeap) { | |
1658 | mPreviewHeap->release(mPreviewHeap); | |
1659 | mPreviewHeap = 0; | |
1660 | mPreviewHeapFd = -1; | |
1661 | } | |
1662 | ||
1663 | /* not need to alloc MHB by mM2MExyMemFd for ion */ | |
1664 | #ifdef BOARD_USE_MHB_ION | |
1665 | if (mEnableDZoom) { | |
1666 | mPreviewHeap = mGetMemoryCb(-1, mPreviewFrameSize, PREVIEW_BUF_CNT, &mPreviewHeapFd); | |
1667 | if (!mPreviewHeap || mPreviewHeapFd < 0) { | |
1668 | ALOGE("allocatePreviewHeap: error, fail to create preview heap(%d)", mPreviewHeap); | |
1669 | return false; | |
1670 | } | |
1671 | } else { | |
1672 | mPreviewHeap = mGetMemoryCb((int)mFlite.getfd(), mPreviewFrameSize, PREVIEW_BUF_CNT, 0); | |
1673 | if (!mPreviewHeap) { | |
1674 | ALOGE("allocatePreviewHeap: error, fail to create preview heap(%d %d)", mPreviewHeap, mPreviewHeapFd); | |
1675 | return false; | |
1676 | } | |
1677 | } | |
1678 | #else | |
1679 | if (mEnableDZoom) { | |
1680 | mPreviewHeap = mGetMemoryCb(-1, mPreviewFrameSize, PREVIEW_BUF_CNT, 0); | |
1681 | if (!mPreviewHeap) { | |
1682 | ALOGE("allocatePreviewHeap: error, fail to create preview heap(%d)", mPreviewHeap); | |
1683 | return false; | |
1684 | } | |
1685 | } else { | |
1686 | mPreviewHeap = mGetMemoryCb((int)mFlite.getfd(), mPreviewFrameSize, PREVIEW_BUF_CNT, 0); | |
1687 | if (!mPreviewHeap) { | |
1688 | ALOGE("allocatePreviewHeap: error, fail to create preview heap(%d)", mPreviewHeap); | |
1689 | return false; | |
1690 | } | |
1691 | } | |
1692 | #endif | |
1693 | ||
1694 | ALOGD("allocatePreviewHeap: %dx%d, frame %dx%d", | |
1695 | mOrgPreviewSize.width, mOrgPreviewSize.height, mPreviewFrameSize, PREVIEW_BUF_CNT); | |
1696 | ||
1697 | return true; | |
1698 | } | |
1699 | ||
1700 | status_t SecCameraHardware::nativeStartPreview() | |
1701 | { | |
1702 | CLOGV("INFO(%s) : in ",__FUNCTION__); | |
1703 | ||
1704 | int err; | |
1705 | int formatMode; | |
1706 | ||
1707 | /* YV12 */ | |
1708 | CLOGD("DEBUG[%s(%d)]Preview Format = %s", | |
1709 | __FUNCTION__, __LINE__, | |
1710 | mFliteFormat == CAM_PIXEL_FORMAT_YVU420P ? "YV12" : | |
1711 | mFliteFormat == CAM_PIXEL_FORMAT_YUV420SP ? "NV21" : | |
1712 | mFliteFormat == CAM_PIXEL_FORMAT_YUV422I ? "YUYV" : | |
1713 | "Others"); | |
1714 | ||
1715 | err = mFlite.startPreview(&mFLiteSize, mFliteFormat, FLITE_BUF_CNT, mFps, mMovieMode, &mFliteNode); | |
1716 | CHECK_ERR_N(err, ("nativeStartPreview: error, mFlite.start")); | |
1717 | ||
1718 | mFlite.querybuf(&mPreviewFrameSize); | |
1719 | if (mPreviewFrameSize == 0) { | |
1720 | CLOGE("nativeStartPreview: error, mFlite.querybuf"); | |
1721 | return UNKNOWN_ERROR; | |
1722 | } | |
1723 | ||
1724 | if (!allocatePreviewHeap()) { | |
1725 | CLOGE("nativeStartPreview: error, allocatePreviewHeap"); | |
1726 | return NO_MEMORY; | |
1727 | } | |
1728 | ||
1729 | for (int i = 0; i < FLITE_BUF_CNT; i++) { | |
1730 | err = mFlite.qbuf(i); | |
1731 | CHECK_ERR_N(err, ("nativeStartPreview: error %d, mFlite.qbuf(%d)", err, i)); | |
1732 | } | |
1733 | ||
1734 | err = mFlite.stream(true); | |
1735 | CHECK_ERR_N(err, ("nativeStartPreview: error %d, mFlite.stream", err)); | |
1736 | ||
1737 | CLOGV("DEBUG[%s(%d)]-out -", __FUNCTION__, __LINE__); | |
1738 | return NO_ERROR; | |
1739 | } | |
1740 | ||
1741 | status_t SecCameraHardware::nativeStartPreviewZoom() | |
1742 | { | |
1743 | CLOGV("INFO(%s) : in ",__FUNCTION__); | |
1744 | ||
1745 | int err; | |
1746 | int formatMode; | |
1747 | int i = 0; | |
1748 | ExynosBuffer nullBuf; | |
1749 | ||
1750 | /* YV12 */ | |
1751 | CLOGD("DEBUG[%s(%d)] : Preview Format = %s", | |
1752 | __FUNCTION__, __LINE__, | |
1753 | mFliteFormat == CAM_PIXEL_FORMAT_YVU420P ? "YV12" : | |
1754 | mFliteFormat == CAM_PIXEL_FORMAT_YUV420SP ? "NV21" : | |
1755 | mFliteFormat == CAM_PIXEL_FORMAT_YUV422I ? "YUYV" : | |
1756 | "Others"); | |
1757 | ||
1758 | CLOGD("DEBUG[%s(%d)] : size:%dx%d/ fps: %d ", | |
1759 | __FUNCTION__, __LINE__, mFLiteSize.width, mFLiteSize.height, mFps); | |
1760 | ||
1761 | err = mFlite.startPreview(&mFLiteSize, mFliteFormat, FLITE_BUF_CNT, mFps, mMovieMode, &mFliteNode); | |
1762 | CHECK_ERR_N(err, ("nativeStartPreviewZoom: error, mFlite.start")); | |
1763 | mFliteNode.ionClient = mIonCameraClient; | |
1764 | ||
1765 | CLOGI("INFO(%s) : mFliteNode.fd [%d]" , __FUNCTION__, mFliteNode.fd); | |
1766 | CLOGI("INFO(%s) : mFliteNode.width [%d]" , __FUNCTION__, mFliteNode.width); | |
1767 | CLOGI("INFO(%s) : mFliteNode.height [%d]" , __FUNCTION__, mFliteNode.height); | |
1768 | CLOGI("INFO(%s) : mFliteNode.format [%c%c%c%c]" , __FUNCTION__, mFliteNode.format, | |
1769 | mFliteNode.format >> 8, mFliteNode.format >> 16, mFliteNode.format >> 24); | |
1770 | CLOGI("INFO(%s) : mFliteNode.planes [%d]" , __FUNCTION__, mFliteNode.planes); | |
1771 | CLOGI("INFO(%s) : mFliteNode.buffers[%d]" , __FUNCTION__, mFliteNode.buffers); | |
1772 | CLOGI("INFO(%s) : mFliteNode.memory [%d]" , __FUNCTION__, mFliteNode.memory); | |
1773 | CLOGI("INFO(%s) : mFliteNode.type [%d]" , __FUNCTION__, mFliteNode.type); | |
1774 | CLOGI("INFO(%s) : mFliteNode.ionClient [%d]", __FUNCTION__, mFliteNode.ionClient); | |
1775 | ||
1776 | #ifdef USE_USERPTR | |
1777 | /* For FLITE buffer */ | |
1778 | for (i = 0; i < FLITE_BUF_CNT; i++) { | |
1779 | mFliteNode.buffer[i] = nullBuf; | |
1780 | /* YUV size */ | |
1781 | getAlignedYUVSize(mFliteFormat, mFLiteSize.width, mFLiteSize.height, &mFliteNode.buffer[i]); | |
1782 | if (allocMem(mIonCameraClient, &mFliteNode.buffer[i], 0) == false) { | |
1783 | CLOGE("ERR(%s):mFliteNode allocMem() fail", __func__); | |
1784 | return UNKNOWN_ERROR; | |
1785 | } else { | |
1786 | CLOGD("DEBUG(%s): mFliteNode allocMem(%d) adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
1787 | i, mFliteNode.buffer[i].virt.extP[0], mFliteNode.buffer[i].size.extS[0], mIonCameraClient); | |
1788 | memset(mFliteNode.buffer[i].virt.extP[0], 0, mFliteNode.buffer[i].size.extS[0]); | |
1789 | } | |
1790 | } | |
1791 | #else | |
1792 | /* loop for buffer count */ | |
1793 | for (int i = 0; i < mFliteNode.buffers; i++) { | |
1794 | err = mFlite.querybuf2(i, mFliteNode.planes, &mFliteNode.buffer[i]); | |
1795 | CHECK_ERR_N(err, ("nativeStartPreviewZoom: error, mFlite.querybuf2")); | |
1796 | } | |
1797 | #endif | |
1798 | CLOGV("DEBUG(%s) : mMsgEnabled(%d)", __FUNCTION__, mMsgEnabled); | |
1799 | ||
1800 | /* allocate preview callback buffer */ | |
1801 | mPreviewFrameSize = getAlignedYUVSize(mPreviewFormat, mOrgPreviewSize.width, mOrgPreviewSize.height, NULL); | |
1802 | CLOGD("DEBUG(%s) : mPreviewFrameSize(%d)(%dx%d) for callback", __FUNCTION__, | |
1803 | mPreviewFrameSize, mOrgPreviewSize.width, mOrgPreviewSize.height); | |
1804 | ||
1805 | if (!allocatePreviewHeap()) { | |
1806 | CLOGE("ERR(%s)(%d) : allocatePreviewHeap() fail", __FUNCTION__, __LINE__); | |
1807 | goto DESTROYMEM; | |
1808 | } | |
1809 | ||
1810 | mPreviewZoomRect.x = 0; | |
1811 | mPreviewZoomRect.y = 0; | |
1812 | mPreviewZoomRect.w = mFLiteSize.width; | |
1813 | mPreviewZoomRect.h = mFLiteSize.height; | |
1814 | ||
1815 | for (int i = 0; i < FLITE_BUF_CNT; i++) { | |
1816 | err = mFlite.qbuf2(&(mFliteNode), i); | |
1817 | CHECK_ERR_GOTO(DESTROYMEM, err, ("nativeStartPreviewZoom: error %d, mFlite.qbuf(%d)", err, i)); | |
1818 | } | |
1819 | ||
1820 | #if !defined(USE_USERPTR) | |
1821 | /* export FD */ | |
1822 | for (int i = 0; i < mFliteNode.buffers; i++) { | |
1823 | err = mFlite.expBuf(i, mFliteNode.planes, &mFliteNode.buffer[i]); | |
1824 | CHECK_ERR_N(err, ("nativeStartPreviewZoom: error, mFlite.expBuf")); | |
1825 | } | |
1826 | #endif | |
1827 | err = mFlite.stream(true); | |
1828 | CHECK_ERR_GOTO(DESTROYMEM, err, ("nativeStartPreviewZoom: error %d, mFlite.stream", err)); | |
1829 | ||
1830 | CLOGV("INFO(%s) : out ",__FUNCTION__); | |
1831 | return NO_ERROR; | |
1832 | ||
1833 | DESTROYMEM: | |
1834 | #ifdef USE_USERPTR | |
1835 | /* flite buffer free */ | |
1836 | for (i = 0; i < FLITE_BUF_CNT; i++) { | |
1837 | freeMem(&mFliteNode.buffer[i]); | |
1838 | mFliteNode.buffer[i] = nullBuf; | |
1839 | } | |
1840 | #else | |
1841 | if (mFlite.reqBufZero(&mFliteNode) < 0) | |
1842 | ALOGE("ERR(%s): mFlite.reqBufZero() fail", __func__); | |
1843 | for (i = 0; i < FLITE_BUF_CNT; i++) | |
1844 | mFliteNode.buffer[i] = nullBuf; | |
1845 | #endif | |
1846 | return UNKNOWN_ERROR; | |
1847 | } | |
1848 | ||
1849 | int SecCameraHardware::nativeGetPreview() | |
1850 | { | |
1851 | int index = -1; | |
1852 | int retries = 10; | |
1853 | int ret = -1; | |
1854 | ||
1855 | CLOGV("INFO(%s) : in ",__FUNCTION__); | |
1856 | ||
1857 | /* All buffers are empty. Request a frame to the device */ | |
1858 | retry: | |
1859 | if (mFlite.polling() == 0) { | |
1860 | if (mFastCaptureCalled) { | |
1861 | CLOGD("DEBUG[%s(%d)] : mFastCaptureCalled!!-",__FUNCTION__, __LINE__); | |
1862 | return -1; | |
1863 | } | |
1864 | CLOGE("ERR[%s(%d)] : no frame, RESET!!!", __FUNCTION__, __LINE__); | |
1865 | if (retries-- <= 0) | |
1866 | return -1; | |
1867 | ||
1868 | mFlite.stream(false); | |
1869 | mFlite.deinit(); | |
1870 | if (mCameraId == CAMERA_ID_BACK) | |
1871 | mFlite.init(FLITE0_DEV_PATH, mCameraId); | |
1872 | else | |
1873 | mFlite.init(FLITE1_DEV_PATH, mCameraId); | |
1874 | ||
1875 | if (mEnableDZoom) | |
1876 | ret = nativeStartPreviewZoom(); | |
1877 | else | |
1878 | ret = nativeStartPreview(); | |
1879 | ||
1880 | goto retry; | |
1881 | } else { | |
1882 | ret = mFlite.dqbuf2(&mFliteNode); | |
1883 | index = ret; | |
1884 | CHECK_ERR_N(index, ("nativeGetPreview: error, mFlite.dqbuf")); | |
1885 | } | |
1886 | ||
1887 | if (mEnableDZoom) | |
1888 | mRecordTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); | |
1889 | ||
1890 | if (!mPreviewInitialized) { | |
1891 | mPreviewInitialized = true; | |
1892 | CLOGD("DEBUG(%s) : preview started",__FUNCTION__); | |
1893 | } | |
1894 | ||
1895 | return index; | |
1896 | } | |
1897 | ||
1898 | status_t SecCameraHardware::nativePreviewCallback(int index, ExynosBuffer *grallocBuf) | |
1899 | { | |
1900 | /* If orginal size and format(defined by app) is different to | |
1901 | * changed size and format(defined by hal), do CSC again. | |
1902 | * But orginal and changed size and format(defined by app) is same, | |
1903 | * just copy to callback buffer from gralloc buf | |
1904 | */ | |
1905 | ||
1906 | ExynosBuffer dstBuf; | |
1907 | dstBuf.fd.extFd[0] = mPreviewHeapFd; | |
1908 | getAlignedYUVSize(mPreviewFormat, mOrgPreviewSize.width, mOrgPreviewSize.height, &dstBuf); | |
1909 | char *srcAdr = NULL; | |
1910 | srcAdr = (char *)mPreviewHeap->data; | |
1911 | srcAdr += (index * mPreviewFrameSize); | |
1912 | ||
1913 | /* YV12 */ | |
1914 | if (mPreviewFormat == V4L2_PIX_FMT_NV21 || | |
1915 | mPreviewFormat == V4L2_PIX_FMT_NV21M) { | |
1916 | dstBuf.virt.extP[0] = srcAdr; | |
1917 | dstBuf.virt.extP[1] = dstBuf.virt.extP[0] + dstBuf.size.extS[0]; | |
1918 | } else if (mPreviewFormat == V4L2_PIX_FMT_YVU420 || | |
1919 | mPreviewFormat == V4L2_PIX_FMT_YVU420M) { | |
1920 | dstBuf.virt.extP[0] = srcAdr; | |
1921 | dstBuf.virt.extP[1] = dstBuf.virt.extP[0] + dstBuf.size.extS[0]; | |
1922 | dstBuf.virt.extP[2] = dstBuf.virt.extP[1] + dstBuf.size.extS[1]; | |
1923 | } | |
1924 | ||
1925 | if (grallocBuf == NULL || | |
1926 | mOrgPreviewSize.width != mPreviewSize.width || | |
1927 | mOrgPreviewSize.height != mPreviewSize.height || | |
1928 | mOrgPreviewSize.width != mFLiteSize.width || | |
1929 | mOrgPreviewSize.height != mFLiteSize.height || | |
1930 | HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP != V4L2_PIX_2_HAL_PIXEL_FORMAT(mPreviewFormat)) { | |
1931 | ||
1932 | /* csc start flite(s) -> fimc0 -> callback(d) */ | |
1933 | if (mFimc1CSC) { | |
1934 | /* set zoom info */ | |
1935 | bool flag; | |
1936 | flag = getCropRect(mFLiteSize.width, mFLiteSize.height, mPreviewSize.width, | |
1937 | mPreviewSize.height, &mPreviewZoomRect.x, &mPreviewZoomRect.y, | |
1938 | &mPreviewZoomRect.w, &mPreviewZoomRect.h, 2, 2, 2, 2, mZoomRatio); | |
1939 | if(false == flag) { | |
1940 | CLOGE("ERR(%s):mFLiteSize.width = %u mFLiteSize.height = %u " | |
1941 | "mPreviewSize.width = %u mPreviewSize.height = %u ", __func__, | |
1942 | mFLiteSize.width, mFLiteSize.height, mPreviewSize.width, mPreviewSize.height); | |
1943 | CLOGE("ERR(%s):Preview CropRect failed X = %u Y = %u W = %u H = %u ", __func__, | |
1944 | mPreviewZoomRect.x, mPreviewZoomRect.y, mPreviewZoomRect.w, mPreviewZoomRect.h); | |
1945 | } | |
1946 | /* src : FLite */ | |
1947 | CLOGV("DEBUG(%s):SRC size(%u x %u / %u, %u, %u, %u) ,Format(%s)", __func__, | |
1948 | mFLiteSize.width, mFLiteSize.height, mPreviewZoomRect.x, mPreviewZoomRect.y,mPreviewZoomRect.w, mPreviewZoomRect.h, | |
1949 | mFliteNode.format == CAM_PIXEL_FORMAT_YVU420P ? "YV12" : | |
1950 | mFliteNode.format == CAM_PIXEL_FORMAT_YUV420SP ? "NV21" : | |
1951 | mFliteNode.format == CAM_PIXEL_FORMAT_YUV422I ? "YUYV" : | |
1952 | "Others"); | |
1953 | ||
1954 | ||
1955 | csc_set_src_format(mFimc1CSC, | |
1956 | mFLiteSize.width, mFLiteSize.height, | |
1957 | mPreviewZoomRect.x, mPreviewZoomRect.y, | |
1958 | mPreviewZoomRect.w, mPreviewZoomRect.h, | |
1959 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
1960 | 0); | |
1961 | ||
1962 | #ifdef USE_USERPTR | |
1963 | csc_set_src_buffer(mFimc1CSC, (void **)mFliteNode.buffer[index].virt.extP, CSC_MEMORY_USERPTR); | |
1964 | #else | |
1965 | csc_set_dst_buffer(mFimc1CSC, (void **)mFliteNode.buffer[index].fd.extFd, CSC_MEMORY_DMABUF); | |
1966 | #endif | |
1967 | ||
1968 | /* dst : callback buffer(MHB) */ | |
1969 | CLOGV("DEBUG(%s):DST size(%u x %u), Format(%s)", __func__, | |
1970 | mOrgPreviewSize.width, mOrgPreviewSize.height, | |
1971 | mPreviewFormat == CAM_PIXEL_FORMAT_YVU420P ? "YV12" : | |
1972 | mPreviewFormat == CAM_PIXEL_FORMAT_YUV420SP ? "NV21" : | |
1973 | mPreviewFormat == CAM_PIXEL_FORMAT_YUV422I ? "YUYV" : | |
1974 | "Others"); | |
1975 | ||
1976 | csc_set_dst_format(mFimc1CSC, | |
1977 | mOrgPreviewSize.width, mOrgPreviewSize.height, | |
1978 | 0, 0, | |
1979 | mOrgPreviewSize.width, mOrgPreviewSize.height, | |
1980 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mPreviewFormat), | |
1981 | 0); | |
1982 | ||
1983 | csc_set_dst_buffer(mFimc1CSC, | |
1984 | (void **)dstBuf.virt.extP, CSC_MEMORY_USERPTR); | |
1985 | ||
1986 | mFimc1CSCLock.lock(); | |
1987 | if (csc_convert(mFimc1CSC) != 0) { | |
1988 | CLOGE("ERR(%s):csc_convert(mFimc1CSC) fail", __func__); | |
1989 | mFimc1CSCLock.unlock(); | |
1990 | return false; | |
1991 | } | |
1992 | mFimc1CSCLock.unlock(); | |
1993 | } else { | |
1994 | CLOGE("ERR(%s): mFimc1CSC == NULL", __func__); | |
1995 | return false; | |
1996 | } | |
1997 | } else { | |
1998 | for (int plane = 0; plane < 2; plane++) { | |
1999 | /* just memcpy only */ | |
2000 | char *srcAddr = NULL; | |
2001 | char *dstAddr = NULL; | |
2002 | srcAddr = grallocBuf->virt.extP[plane]; | |
2003 | dstAddr = dstBuf.virt.extP[plane]; | |
2004 | memcpy(dstAddr, srcAddr, dstBuf.size.extS[plane]); | |
2005 | } | |
2006 | } | |
2007 | /* mSaveDump("/data/camera_preview%d.yuv", &dstBuf, index); */ | |
2008 | ||
2009 | return NO_ERROR; | |
2010 | } | |
2011 | ||
2012 | ||
2013 | int SecCameraHardware::nativeReleasePreviewFrame(int index) | |
2014 | { | |
2015 | #ifdef FAKE_SENSOR | |
2016 | return mFlite.fakeQbuf2(&mFliteNode, index); | |
2017 | #else | |
2018 | return mFlite.qbuf2(&mFliteNode, index); | |
2019 | #endif | |
2020 | } | |
2021 | ||
2022 | void SecCameraHardware::nativeStopPreview(void) | |
2023 | { | |
2024 | int err = 0; | |
2025 | int i = 0; | |
2026 | ExynosBuffer nullBuf; | |
2027 | ||
2028 | err = mFlite.stream(false); | |
2029 | if (CC_UNLIKELY(err < 0)) | |
2030 | CLOGE("nativeStopPreview: error, mFlite.stream"); | |
2031 | ||
2032 | #ifdef USE_USERPTR | |
2033 | /* flite buffer free */ | |
2034 | for (i = 0; i < FLITE_BUF_CNT; i++) { | |
2035 | freeMem(&mFliteNode.buffer[i]); | |
2036 | mFliteNode.buffer[i] = nullBuf; | |
2037 | } | |
2038 | #else | |
2039 | for (i = 0; i < FLITE_BUF_CNT; i++) { | |
2040 | for (int j = 0; j < mFliteNode.planes; j++) { | |
2041 | munmap((void *)mFliteNode.buffer[i].virt.extP[j], | |
2042 | mFliteNode.buffer[i].size.extS[j]); | |
2043 | ion_free(mFliteNode.buffer[i].fd.extFd[j]); | |
2044 | } | |
2045 | mFliteNode.buffer[i] = nullBuf; | |
2046 | } | |
2047 | ||
2048 | if (mFlite.reqBufZero(&mFliteNode) < 0) | |
2049 | ALOGE("ERR(%s): mFlite.reqBufZero() fail", __func__); | |
2050 | #endif | |
2051 | CLOGV("INFO(%s) : out ",__FUNCTION__); | |
2052 | } | |
2053 | ||
2054 | bool SecCameraHardware::allocateRecordingHeap() | |
2055 | { | |
2056 | int framePlaneSize1 = ALIGN(mVideoSize.width, 16) * ALIGN(mVideoSize.height, 16) + MFC_7X_BUFFER_OFFSET; | |
2057 | int framePlaneSize2 = ALIGN(mVideoSize.width, 16) * ALIGN(mVideoSize.height / 2, 16) + MFC_7X_BUFFER_OFFSET;; | |
2058 | ||
2059 | if (mRecordingHeap != NULL) { | |
2060 | mRecordingHeap->release(mRecordingHeap); | |
2061 | mRecordingHeap = 0; | |
2062 | mRecordHeapFd = -1; | |
2063 | } | |
2064 | ||
2065 | #ifdef BOARD_USE_MHB_ION | |
2066 | mRecordingHeap = mGetMemoryCb(-1, sizeof(struct addrs), REC_BUF_CNT, &mRecordHeapFd); | |
2067 | if (mRecordingHeap == NULL || mRecordHeapFd < 0) { | |
2068 | ALOGE("ERR(%s): mGetMemoryCb(mRecordingHeap(%d), size(%d) fail [Heap %p, Fd %d]",\ | |
2069 | __func__, REC_BUF_CNT, sizeof(struct addrs), mRecordingHeap, mRecordHeapFd); | |
2070 | return false; | |
2071 | } | |
2072 | #else | |
2073 | mRecordingHeap = mGetMemoryCb(-1, sizeof(struct addrs), REC_BUF_CNT, 0); | |
2074 | if (mRecordingHeap == NULL) { | |
2075 | ALOGE("ERR(%s): mGetMemoryCb(mRecordingHeap(%d), size(%d) fail [Heap %p]",\ | |
2076 | __func__, REC_BUF_CNT, sizeof(struct addrs), mRecordingHeap); | |
2077 | return false; | |
2078 | } | |
2079 | #endif | |
2080 | ||
2081 | for (int i = 0; i < REC_BUF_CNT; i++) { | |
2082 | #ifdef BOARD_USE_MHB_ION | |
2083 | for (int j = 0; j < REC_PLANE_CNT; j++) { | |
2084 | if (mRecordDstHeap[i][j] != NULL) { | |
2085 | mRecordDstHeap[i][j]->release(mRecordDstHeap[i][j]); | |
2086 | mRecordDstHeap[i][j] = 0; | |
2087 | mRecordDstHeapFd[i][j] = -1; | |
2088 | } | |
2089 | } | |
2090 | ||
2091 | mRecordDstHeap[i][0] = mGetMemoryCb(-1, framePlaneSize1, 1, &(mRecordDstHeapFd[i][0])); | |
2092 | mRecordDstHeap[i][1] = mGetMemoryCb(-1, framePlaneSize2, 1, &(mRecordDstHeapFd[i][1])); | |
2093 | ALOGV("DEBUG(%s): mRecordDstHeap[%d][0] adr(%p), fd(%d)", __func__, i, mRecordDstHeap[i][0]->data, mRecordDstHeapFd[i][0]); | |
2094 | ALOGV("DEBUG(%s): mRecordDstHeap[%d][1] adr(%p), fd(%d)", __func__, i, mRecordDstHeap[i][1]->data, mRecordDstHeapFd[i][1]); | |
2095 | ||
2096 | if (mRecordDstHeap[i][0] == NULL || mRecordDstHeapFd[i][0] <= 0 || | |
2097 | mRecordDstHeap[i][1] == NULL || mRecordDstHeapFd[i][1] <= 0) { | |
2098 | ALOGE("ERR(%s): mGetMemoryCb(mRecordDstHeap[%d] size(%d/%d) fail",\ | |
2099 | __func__, i, framePlaneSize1, framePlaneSize2); | |
2100 | goto error; | |
2101 | } | |
2102 | ||
2103 | #ifdef NOTDEFINED | |
2104 | if (mRecordDstHeap[i][j] == NULL) { | |
2105 | ALOGE("ERR(%s): mGetMemoryCb(mRecordDstHeap[%d][%d], size(%d) fail",\ | |
2106 | __func__, i, j, framePlaneSize); | |
2107 | goto error; | |
2108 | } | |
2109 | #endif | |
2110 | #else | |
2111 | freeMem(&mRecordingDstBuf[i]); | |
2112 | ||
2113 | mRecordingDstBuf[i].size.extS[0] = framePlaneSize1; | |
2114 | mRecordingDstBuf[i].size.extS[1] = framePlaneSize2; | |
2115 | ||
2116 | if (allocMem(mIonCameraClient, &mRecordingDstBuf[i], ((1 << 1) | 1)) == false) { | |
2117 | ALOGE("ERR(%s):allocMem(mRecordingDstBuf() fail", __func__); | |
2118 | goto error; | |
2119 | } | |
2120 | #endif | |
2121 | } | |
2122 | ||
2123 | ALOGD("DEBUG(%s): %dx%d, frame plane (%d/%d)x%d", __func__, | |
2124 | ALIGN(mVideoSize.width, 16), ALIGN(mVideoSize.height, 2), framePlaneSize1, framePlaneSize2, REC_BUF_CNT); | |
2125 | ||
2126 | return true; | |
2127 | ||
2128 | error: | |
2129 | if (mRecordingHeap == NULL) { | |
2130 | mRecordingHeap->release(mRecordingHeap); | |
2131 | mRecordingHeap = NULL; | |
2132 | } | |
2133 | ||
2134 | for (int i = 0; i < REC_BUF_CNT; i++) { | |
2135 | for (int j = 0; j < REC_PLANE_CNT; j++) { | |
2136 | if (mRecordDstHeap[i][j] != NULL) { | |
2137 | mRecordDstHeap[i][j]->release(mRecordDstHeap[i][j]); | |
2138 | mRecordDstHeap[i][j] = 0; | |
2139 | } | |
2140 | } | |
2141 | ||
2142 | freeMem(&mRecordingDstBuf[i]); | |
2143 | } | |
2144 | ||
2145 | return false; | |
2146 | } | |
2147 | ||
2148 | #ifdef RECORDING_CAPTURE | |
2149 | bool SecCameraHardware::allocateRecordingSnapshotHeap() | |
2150 | { | |
2151 | /* init jpeg heap */ | |
2152 | if (mJpegHeap) { | |
2153 | mJpegHeap->release(mJpegHeap); | |
2154 | mJpegHeap = NULL; | |
2155 | } | |
2156 | ||
2157 | #ifdef BOARD_USE_MHB_ION | |
2158 | int jpegHeapFd = -1; | |
2159 | mJpegHeap = mGetMemoryCb(-1, mRecordingPictureFrameSize, 1, jpegHeapFd); | |
2160 | if (mJpegHeap == NULL || jpegHeapFd < 0) { | |
2161 | ALOGE("allocateRecordingSnapshotHeap: error, fail to create jpeg heap"); | |
2162 | return UNKNOWN_ERROR; | |
2163 | } | |
2164 | #else | |
2165 | mJpegHeap = mGetMemoryCb(-1, mRecordingPictureFrameSize, 1, 0); | |
2166 | if (mJpegHeap == NULL) { | |
2167 | ALOGE("allocateRecordingSnapshotHeap: error, fail to create jpeg heap"); | |
2168 | return UNKNOWN_ERROR; | |
2169 | } | |
2170 | #endif | |
2171 | ||
2172 | ALOGD("allocateRecordingSnapshotHeap: jpeg %dx%d, size %d", | |
2173 | mPictureSize.width, mPictureSize.height, mRecordingPictureFrameSize); | |
2174 | ||
2175 | return true; | |
2176 | } | |
2177 | #endif | |
2178 | ||
2179 | status_t SecCameraHardware::nativeStartRecording(void) | |
2180 | { | |
2181 | CLOGI("INFO(%s) : in ", __FUNCTION__); | |
2182 | #ifdef NOTDEFINED | |
2183 | if (mMirror) { | |
2184 | nativeSetParameters(CAM_CID_HFLIP, 1, 0); | |
2185 | nativeSetParameters(CAM_CID_HFLIP, 1, 1); | |
2186 | } else { | |
2187 | nativeSetParameters(CAM_CID_HFLIP, 0, 0); | |
2188 | nativeSetParameters(CAM_CID_HFLIP, 0, 1); | |
2189 | } | |
2190 | ||
2191 | uint32_t recordingTotalFrameSize; | |
2192 | mFimc1.querybuf(&recordingTotalFrameSize); | |
2193 | if (recordingTotalFrameSize == 0) { | |
2194 | ALOGE("nativeStartPreview: error, mFimc1.querybuf"); | |
2195 | return UNKNOWN_ERROR; | |
2196 | } | |
2197 | ||
2198 | if (!allocateRecordingHeap()) { | |
2199 | ALOGE("nativeStartRecording: error, allocateRecordingHeap"); | |
2200 | return NO_MEMORY; | |
2201 | } | |
2202 | ||
2203 | for (int i = 0; i < REC_BUF_CNT; i++) { | |
2204 | err = mFimc1.qbuf(i); | |
2205 | CHECK_ERR_N(err, ("nativeStartRecording: error, mFimc1.qbuf(%d)", i)); | |
2206 | } | |
2207 | ||
2208 | err = mFimc1.stream(true); | |
2209 | CHECK_ERR_N(err, ("nativeStartRecording: error, mFimc1.stream")); | |
2210 | #endif | |
2211 | CLOGI("INFO(%s) : out ",__FUNCTION__); | |
2212 | return NO_ERROR; | |
2213 | } | |
2214 | ||
2215 | /* for zoom recording */ | |
2216 | status_t SecCameraHardware::nativeStartRecordingZoom(void) | |
2217 | { | |
2218 | int err; | |
2219 | Mutex::Autolock lock(mNativeRecordLock); | |
2220 | ||
2221 | CLOGI("INFO(%s) : in - (%d/%d)", __FUNCTION__, mVideoSize.width, mVideoSize.height); | |
2222 | ||
2223 | /* 1. init zoom size info */ | |
2224 | mRecordZoomRect.x = 0; | |
2225 | mRecordZoomRect.y = 0; | |
2226 | mRecordZoomRect.w = mVideoSize.width; | |
2227 | mRecordZoomRect.h = mVideoSize.height; | |
2228 | ||
2229 | /* 2. init buffer var src and dst */ | |
2230 | mInitRecSrcQ(); | |
2231 | mInitRecDstBuf(); | |
2232 | ||
2233 | /* 3. alloc MHB for recording dst */ | |
2234 | if (!allocateRecordingHeap()) { | |
2235 | ALOGE("nativeStartPostRecording: error, allocateRecordingHeap"); | |
2236 | goto destroyMem; | |
2237 | } | |
2238 | ||
2239 | CLOGI("INFO(%s) : out ",__FUNCTION__); | |
2240 | return NO_ERROR; | |
2241 | ||
2242 | destroyMem: | |
2243 | mInitRecSrcQ(); | |
2244 | mInitRecDstBuf(); | |
2245 | return UNKNOWN_ERROR; | |
2246 | } | |
2247 | ||
2248 | #ifdef NOTDEFINED | |
2249 | int SecCameraHardware::nativeGetRecording() | |
2250 | { | |
2251 | int index; | |
2252 | phyaddr_t y, cbcr; | |
2253 | int err, retries = 3; | |
2254 | ||
2255 | retry: | |
2256 | err = mFimc1.polling(true); | |
2257 | if (CC_UNLIKELY(err <= 0)) { | |
2258 | if (mFimc1.getStreamStatus()) { | |
2259 | if (!err && (retries > 0)) { | |
2260 | ALOGW("nativeGetRecording: warning, wait for input (%d)", retries); | |
2261 | usleep(300000); | |
2262 | retries--; | |
2263 | goto retry; | |
2264 | } | |
2265 | ALOGE("nativeGetRecording: error, mFimc1.polling err=%d cnt=%d", err, retries); | |
2266 | } else { | |
2267 | ALOGV("nativeGetRecording: stop getting a frame"); | |
2268 | } | |
2269 | return UNKNOWN_ERROR; | |
2270 | } | |
2271 | ||
2272 | index = mFimc1.dqbuf(); | |
2273 | CHECK_ERR_N(index, ("nativeGetRecording: error, mFimc1.dqbuf")); | |
2274 | ||
2275 | /* get fimc capture physical addr */ | |
2276 | err = mFimc1.getYuvPhyaddr(index, &y, &cbcr); | |
2277 | CHECK_ERR_N(err, ("nativeGetRecording: error, mFimc1.getYuvPhyaddr")); | |
2278 | ||
2279 | Mutex::Autolock lock(mNativeRecordLock); | |
2280 | ||
2281 | if (!mRecordingHeap) | |
2282 | return NO_MEMORY; | |
2283 | ||
2284 | struct record_heap *heap = (struct record_heap *)mRecordingHeap->data; | |
2285 | heap[index].type = kMetadataBufferTypeCameraSource; | |
2286 | heap[index].y = y; | |
2287 | heap[index].cbcr = cbcr; | |
2288 | heap[index].buf_index = index; | |
2289 | ||
2290 | return index; | |
2291 | } | |
2292 | ||
2293 | int SecCameraHardware::nativeReleaseRecordingFrame(int index) | |
2294 | { | |
2295 | return mFimc1.qbuf(index); | |
2296 | } | |
2297 | ||
2298 | int SecCameraHardware::nativeReleasePostRecordingFrame(int index) | |
2299 | { | |
2300 | return NO_ERROR; | |
2301 | } | |
2302 | void SecCameraHardware::nativeStopPostRecording() | |
2303 | { | |
2304 | Mutex::Autolock lock(mNativeRecordLock); | |
2305 | ||
2306 | ALOGD("nativeStopPostRecording EX"); | |
2307 | } | |
2308 | #endif | |
2309 | ||
2310 | void SecCameraHardware::nativeStopRecording() | |
2311 | { | |
2312 | Mutex::Autolock lock(mNativeRecordLock); | |
2313 | ||
2314 | mInitRecSrcQ(); | |
2315 | mInitRecDstBuf(); | |
2316 | ||
2317 | ALOGD("nativeStopRecording EX"); | |
2318 | } | |
2319 | ||
2320 | bool SecCameraHardware::getCropRect(unsigned int src_w, unsigned int src_h, | |
2321 | unsigned int dst_w, unsigned int dst_h, unsigned int *crop_x, unsigned int *crop_y, | |
2322 | unsigned int *crop_w, unsigned int *crop_h, | |
2323 | int align_x, int align_y, int align_w, int align_h, float zoomRatio) | |
2324 | { | |
2325 | bool flag = true; | |
2326 | *crop_w = src_w; | |
2327 | *crop_h = src_h; | |
2328 | ||
2329 | if (src_w == 0 || src_h == 0 || dst_w == 0 || dst_h == 0) { | |
2330 | ALOGE("ERR(%s):width or height valuse is 0, src(%dx%d), dst(%dx%d)", | |
2331 | __func__, src_w, src_h, dst_w, dst_h); | |
2332 | return false; | |
2333 | } | |
2334 | ||
2335 | /* Calculation aspect ratio */ | |
2336 | if (src_w != dst_w | |
2337 | || src_h != dst_h) { | |
2338 | float src_ratio = 1.0f; | |
2339 | float dst_ratio = 1.0f; | |
2340 | ||
2341 | /* ex : 1024 / 768 */ | |
2342 | src_ratio = (float)src_w / (float)src_h; | |
2343 | ||
2344 | /* ex : 352 / 288 */ | |
2345 | dst_ratio = (float)dst_w / (float)dst_h; | |
2346 | ||
2347 | if (dst_ratio <= src_ratio) { | |
2348 | /* shrink w */ | |
2349 | *crop_w = src_h * dst_ratio; | |
2350 | *crop_h = src_h; | |
2351 | } else { | |
2352 | /* shrink h */ | |
2353 | *crop_w = src_w; | |
2354 | *crop_h = src_w / dst_ratio; | |
2355 | } | |
2356 | } | |
2357 | ||
2358 | flag = getRectZoomAlign(src_w, src_h, dst_w, dst_h, crop_x, crop_y, | |
2359 | crop_w, crop_h, align_x, align_y, align_w, align_h, zoomRatio); | |
2360 | if(false == flag) { | |
2361 | ALOGE("ERR(%s):src_w = %u src_h = %u dst_w = %u dst_h = %u " | |
2362 | "crop_x = %u crop_y = %u crop_w = %u crop_h = %u " | |
2363 | "align_w = %d align_h = %d zoom = %f", __func__, | |
2364 | src_w, src_h, dst_w, dst_h, *crop_x, *crop_y, | |
2365 | *crop_w, *crop_h, align_w, align_h, zoomRatio); | |
2366 | } | |
2367 | ||
2368 | return true; | |
2369 | } | |
2370 | ||
2371 | bool SecCameraHardware::getRectZoomAlign(unsigned int src_w, unsigned int src_h, | |
2372 | unsigned int dst_w, unsigned int dst_h, unsigned int *crop_x, unsigned int *crop_y, | |
2373 | unsigned int *crop_w, unsigned int *crop_h, | |
2374 | int align_x, int align_y, int align_w, int align_h, float zoomRatio) | |
2375 | { | |
2376 | int x = 0; | |
2377 | int y = 0; | |
2378 | ||
2379 | if (zoomRatio != 0) { | |
2380 | /* calculation zoom */ | |
2381 | *crop_w = (unsigned int)((float)*crop_w * 1000 / zoomRatio); | |
2382 | *crop_h = (unsigned int)((float)*crop_h * 1000 / zoomRatio); | |
2383 | } | |
2384 | ||
2385 | /* Alignment by desired size */ | |
2386 | unsigned int w_remain = (*crop_w & (align_w - 1)); | |
2387 | if (w_remain != 0) { | |
2388 | if ( (unsigned int)(align_w >> 1) <= w_remain | |
2389 | && (unsigned int)(*crop_w + (align_w - w_remain)) <= src_w) { | |
2390 | *crop_w += (align_w - w_remain); | |
2391 | } | |
2392 | else | |
2393 | *crop_w -= w_remain; | |
2394 | } | |
2395 | ||
2396 | unsigned int h_remain = (*crop_h & (align_h - 1)); | |
2397 | if (h_remain != 0) { | |
2398 | if ( (unsigned int)(align_h >> 1) <= h_remain | |
2399 | && (unsigned int)(*crop_h + (align_h - h_remain)) <= src_h) { | |
2400 | *crop_h += (align_h - h_remain); | |
2401 | } | |
2402 | else | |
2403 | *crop_h -= h_remain; | |
2404 | } | |
2405 | ||
2406 | x = ((int)src_w - (int)*crop_w) >> 1; | |
2407 | y = ((int)src_h - (int)*crop_h) >> 1; | |
2408 | ||
2409 | if (x < 0 || y < 0) { | |
2410 | ALOGE("ERR(%s):crop size too big (%u, %u, %u, %u)", | |
2411 | __func__, *crop_x, *crop_y, *crop_w, *crop_h); | |
2412 | return false; | |
2413 | } | |
2414 | ||
2415 | *crop_x = ALIGN_DOWN(x, align_x); | |
2416 | *crop_y = ALIGN_DOWN(y, align_y); | |
2417 | ||
2418 | return true; | |
2419 | } | |
2420 | ||
2421 | status_t SecCameraHardware::nativeCSCPreview(int index, int type) | |
2422 | { | |
2423 | ExynosBuffer dstBuf; | |
2424 | char *dstAdr = NULL; | |
2425 | dstAdr = (char *)mPreviewHeap->data; | |
2426 | dstAdr += (index * mPreviewFrameSize); | |
2427 | ||
2428 | if (mFimc1CSC) { | |
2429 | /* set zoom info */ | |
2430 | mPreviewZoomRect.w = ALIGN_DOWN((uint32_t)((float)mFLiteSize.width * 1000 / mZoomRatio), 2); | |
2431 | mPreviewZoomRect.h = ALIGN_DOWN((uint32_t)((float)mFLiteSize.height * 1000 / mZoomRatio), 2); | |
2432 | ||
2433 | mPreviewZoomRect.x = ALIGN_DOWN(((mFLiteSize.width - mPreviewZoomRect.w) / 2), 2); | |
2434 | mPreviewZoomRect.y = ALIGN_DOWN(((mFLiteSize.height - mPreviewZoomRect.h) / 2), 2); | |
2435 | ||
2436 | #ifdef DEBUG_PREVIEW | |
2437 | CLOGD("DEBUG PREVIEW(%s) (%d): src(%d,%d,%d,%d,%d,%d), dst(%d,%d), fmt(%d)" | |
2438 | , __FUNCTION__, __LINE__ | |
2439 | , mFLiteSize.width | |
2440 | , mFLiteSize.height | |
2441 | , mPreviewZoomRect.x | |
2442 | , mPreviewZoomRect.y | |
2443 | , mPreviewZoomRect.w | |
2444 | , mPreviewZoomRect.h | |
2445 | , mPreviewSize.width | |
2446 | , mPreviewSize.height | |
2447 | , V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format) | |
2448 | ); | |
2449 | #endif | |
2450 | ||
2451 | /* src : FLite */ | |
2452 | csc_set_src_format(mFimc1CSC, | |
2453 | mFLiteSize.width, mFLiteSize.height, | |
2454 | mPreviewZoomRect.x, mPreviewZoomRect.y, | |
2455 | mPreviewZoomRect.w, mPreviewZoomRect.h, | |
2456 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2457 | 0); | |
2458 | ||
2459 | if (type == CAMERA_HEAP_POSTVIEW) { | |
2460 | csc_set_src_buffer(mFimc1CSC, (void **)mPictureBufDummy[0].virt.extP, CSC_MEMORY_USERPTR); | |
2461 | } else { | |
2462 | csc_set_src_buffer(mFimc1CSC, (void **)mFliteNode.buffer[index].virt.extP, CSC_MEMORY_USERPTR); | |
2463 | } | |
2464 | ||
2465 | /* mSaveDump("/data/camera_preview%d.yuv", &mFliteNode.buffer[index], index); */ | |
2466 | ||
2467 | int halPixelFormat = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL; | |
2468 | ||
2469 | /* dst : GRALLOC */ | |
2470 | csc_set_dst_format(mFimc1CSC, | |
2471 | mPreviewSize.width, mPreviewSize.height, | |
2472 | 0, 0, | |
2473 | mPreviewSize.width, mPreviewSize.height, | |
2474 | halPixelFormat, | |
2475 | 0); | |
2476 | ||
2477 | dstBuf.fd.extFd[0] = mPreviewHeapFd; | |
2478 | dstBuf.virt.extP[0] = dstAdr; | |
2479 | dstBuf.size.extS[0] = mPreviewSize.width * mPreviewSize.height; | |
2480 | dstBuf.virt.extP[1] = dstBuf.virt.extP[0] + dstBuf.size.extS[0]; | |
2481 | dstBuf.size.extS[1] = mPreviewSize.width * mPreviewSize.height / 2; | |
2482 | ||
2483 | csc_set_dst_buffer(mFimc1CSC, (void **) dstBuf.virt.extP, CSC_MEMORY_USERPTR); | |
2484 | ||
2485 | mFimc1CSCLock.lock(); | |
2486 | if (csc_convert(mFimc1CSC) != 0) { | |
2487 | ALOGE("ERR(%s):csc_convert(mFimc1CSC) fail", __func__); | |
2488 | mFimc1CSCLock.unlock(); | |
2489 | return false; | |
2490 | } | |
2491 | mFimc1CSCLock.unlock(); | |
2492 | } | |
2493 | return true; | |
2494 | } | |
2495 | ||
2496 | status_t SecCameraHardware::nativeCSCRecording(rec_src_buf_t *srcBuf, int dstIdx) | |
2497 | { | |
2498 | Mutex::Autolock lock(mNativeRecordLock); | |
2499 | ||
2500 | /* csc start flite(s) -> fimc1 -> callback(d) */ | |
2501 | if (mFimc2CSC) { | |
2502 | struct addrs *addrs; | |
2503 | bool flag; | |
2504 | /* set zoom info */ | |
2505 | flag = getCropRect(mFLiteSize.width, mFLiteSize.height, mVideoSize.width, | |
2506 | mVideoSize.height, &mRecordZoomRect.x, &mRecordZoomRect.y, | |
2507 | &mRecordZoomRect.w, &mRecordZoomRect.h, 2, 2, 2, 2, mZoomRatio); | |
2508 | if(false == flag) { | |
2509 | ALOGE("ERR(%s):mFLiteSize.width = %u mFLiteSize.height = %u " | |
2510 | "mVideoSize.width = %u mVideoSize.height = %u ", __func__, | |
2511 | mFLiteSize.width, mFLiteSize.height, mVideoSize.width, mVideoSize.height); | |
2512 | ALOGE("ERR(%s):Recording CropRect failed X = %u Y = %u W = %u H = %u ", __func__, | |
2513 | mRecordZoomRect.x, mRecordZoomRect.y, mRecordZoomRect.w, mRecordZoomRect.h); | |
2514 | } | |
2515 | ||
2516 | #ifdef DEBUG_RECORDING | |
2517 | ALOGD("DEBUG RECORDING(%s) (%d): src(%d,%d,%d,%d,%d,%d), dst(%d,%d) %d", __func__, __LINE__ | |
2518 | , mFLiteSize.width | |
2519 | , mFLiteSize.height | |
2520 | , mRecordZoomRect.x | |
2521 | , mRecordZoomRect.y | |
2522 | , mRecordZoomRect.w | |
2523 | , mRecordZoomRect.h | |
2524 | , mVideoSize.width | |
2525 | , mVideoSize.height | |
2526 | , dstIdx | |
2527 | ); | |
2528 | #endif | |
2529 | /* src : FLite */ | |
2530 | csc_set_src_format(mFimc2CSC, | |
2531 | mFLiteSize.width, mFLiteSize.height, | |
2532 | mRecordZoomRect.x, mRecordZoomRect.y, | |
2533 | mRecordZoomRect.w, mRecordZoomRect.h, | |
2534 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2535 | 0); | |
2536 | ||
2537 | csc_set_src_buffer(mFimc2CSC, (void **)srcBuf->buf->fd.extFd, CSC_MEMORY_DMABUF); | |
2538 | //csc_set_src_buffer(mFimc2CSC, (void **)srcBuf->buf->virt.extP, CSC_MEMORY_USERPTR); | |
2539 | ||
2540 | /* dst : MHB(callback */ | |
2541 | csc_set_dst_format(mFimc2CSC, | |
2542 | mVideoSize.width, mVideoSize.height, | |
2543 | 0, 0, mVideoSize.width, mVideoSize.height, | |
2544 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mRecordingFormat), | |
2545 | /* HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP, */ | |
2546 | 0); | |
2547 | ||
2548 | ExynosBuffer dstBuf; | |
2549 | getAlignedYUVSize(mRecordingFormat, mVideoSize.width, mVideoSize.height, &dstBuf); | |
2550 | for (int i = 0; i < REC_PLANE_CNT; i++) { | |
2551 | #if defined(ALLOCATION_REC_BUF_BY_MEM_CB) | |
2552 | dstBuf.virt.extP[i] = (char *)mRecordDstHeap[dstIdx][i]->data; | |
2553 | dstBuf.fd.extFd[i] = mRecordDstHeapFd[dstIdx][i]; | |
2554 | #else | |
2555 | dstBuf.virt.extP[i] = (char *)mRecordingDstBuf[dstIdx].virt.extP[i]; | |
2556 | dstBuf.fd.extFd[i] = mRecordingDstBuf[dstIdx].fd.extFd[i]; | |
2557 | #endif | |
2558 | } | |
2559 | ||
2560 | #ifdef DEBUG_RECORDING | |
2561 | ALOGD("DEBUG(%s) (%d): dst(%d,%d,%p,%p,%d,%d) index(%d)", __func__, __LINE__ | |
2562 | , dstBuf.fd.extFd[0] | |
2563 | , dstBuf.fd.extFd[1] | |
2564 | , dstBuf.virt.extP[0] | |
2565 | , dstBuf.virt.extP[1] | |
2566 | , dstBuf.size.extS[0] | |
2567 | , dstBuf.size.extS[1] | |
2568 | , dstIdx | |
2569 | ); | |
2570 | #endif | |
2571 | csc_set_dst_buffer(mFimc2CSC, (void **)dstBuf.fd.extFd, CSC_MEMORY_DMABUF); | |
2572 | ||
2573 | mFimc2CSCLock.lock(); | |
2574 | if (csc_convert_with_rotation(mFimc2CSC, 0, mflipHorizontal, mflipVertical) != 0) { | |
2575 | ALOGE("ERR(%s):csc_convert(mFimc2CSC) fail", __func__); | |
2576 | mFimc2CSCLock.unlock(); | |
2577 | return false; | |
2578 | } | |
2579 | mFimc2CSCLock.unlock(); | |
2580 | ||
2581 | addrs = (struct addrs *)mRecordingHeap->data; | |
2582 | addrs[dstIdx].type = kMetadataBufferTypeCameraSource; | |
2583 | addrs[dstIdx].fd_y = (unsigned int)dstBuf.fd.extFd[0]; | |
2584 | addrs[dstIdx].fd_cbcr = (unsigned int)dstBuf.fd.extFd[1]; | |
2585 | addrs[dstIdx].buf_index = dstIdx; | |
2586 | /* ALOGV("DEBUG(%s): After CSC Camera Meta index %d fd(%d, %d)", __func__, dstIdx, addrs[dstIdx].fd_y, addrs[dstIdx].fd_cbcr); */ | |
2587 | /* mSaveDump("/data/camera_recording%d.yuv", &dstBuf, dstIdx); */ | |
2588 | } else { | |
2589 | ALOGE("ERR(%s): mFimc2CSC == NULL", __func__); | |
2590 | return false; | |
2591 | } | |
2592 | return true; | |
2593 | } | |
2594 | ||
2595 | status_t SecCameraHardware::nativeCSCCapture(ExynosBuffer *srcBuf, ExynosBuffer *dstBuf) | |
2596 | { | |
2597 | bool flag; | |
2598 | ||
2599 | if (mFimc2CSC) { | |
2600 | /* set zoom info */ | |
2601 | flag = getCropRect(mFLiteCaptureSize.width, mFLiteCaptureSize.height, mPictureSize.width, | |
2602 | mPictureSize.height, &mPictureZoomRect.x, &mPictureZoomRect.y, | |
2603 | &mPictureZoomRect.w, &mPictureZoomRect.h, 2, 2, 2, 2, mZoomRatio); | |
2604 | ||
2605 | if(false == flag) { | |
2606 | ALOGE("ERR(%s):mFLiteCaptureSize.width = %u mFLiteCaptureSize.height = %u " | |
2607 | "mPictureSize.width = %u mPictureSize.height = %u ", __func__, | |
2608 | mFLiteCaptureSize.width, mFLiteCaptureSize.height, mPictureSize.width, mPictureSize.height); | |
2609 | ALOGE("ERR(%s):Capture CropRect failed X = %u Y = %u W = %u H = %u ", __func__, | |
2610 | mPictureZoomRect.x, mPictureZoomRect.y, mPictureZoomRect.w, mPictureZoomRect.h); | |
2611 | } | |
2612 | ||
2613 | #ifdef DEBUG_CAPTURE | |
2614 | ALOGD("DEBUG(%s) (%d): (%d, %d), (%d, %d), (%d, %d, %d, %d)", __func__, __LINE__ | |
2615 | , mFLiteCaptureSize.width | |
2616 | , mFLiteCaptureSize.height | |
2617 | , mPictureSize.width | |
2618 | , mPictureSize.height | |
2619 | , mPictureZoomRect.x | |
2620 | , mPictureZoomRect.y | |
2621 | , mPictureZoomRect.w | |
2622 | , mPictureZoomRect.h | |
2623 | ); | |
2624 | #endif | |
2625 | /* src : FLite */ | |
2626 | csc_set_src_format(mFimc2CSC, | |
2627 | mFLiteCaptureSize.width, mFLiteCaptureSize.height, | |
2628 | mPictureZoomRect.x, mPictureZoomRect.y, | |
2629 | mPictureZoomRect.w, mPictureZoomRect.h, | |
2630 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2631 | 0); | |
2632 | ||
2633 | csc_set_src_buffer(mFimc2CSC, (void **)srcBuf->virt.extP, CSC_MEMORY_USERPTR); | |
2634 | ||
2635 | /* dst : buffer */ | |
2636 | #ifdef USE_NV21_CALLBACK | |
2637 | if (mPictureFormat == CAM_PIXEL_FORMAT_YUV420SP) { | |
2638 | csc_set_dst_format(mFimc2CSC, | |
2639 | mPictureSize.width, mPictureSize.height, | |
2640 | 0, 0, mPictureSize.width, mPictureSize.height, | |
2641 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mPictureFormat), | |
2642 | 0); | |
2643 | ||
2644 | csc_set_dst_buffer(mFimc2CSC, (void **)dstBuf->virt.extP, CSC_MEMORY_USERPTR); | |
2645 | } | |
2646 | else | |
2647 | #endif | |
2648 | { | |
2649 | csc_set_dst_format(mFimc2CSC, | |
2650 | mPictureSize.width, mPictureSize.height, | |
2651 | 0, 0, mPictureSize.width, mPictureSize.height, | |
2652 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2653 | 0); | |
2654 | ||
2655 | csc_set_dst_buffer(mFimc2CSC, (void **)dstBuf->fd.extFd, CSC_MEMORY_DMABUF); | |
2656 | } | |
2657 | ||
2658 | mFimc2CSCLock.lock(); | |
2659 | if (mCameraId == CAMERA_ID_FRONT) { | |
2660 | if (csc_convert_with_rotation(mFimc2CSC, 0, mflipHorizontal, mflipVertical) != 0) { | |
2661 | ALOGE("ERR(%s):csc_convert_with_rotation(mFimc2CSC) fail", __func__); | |
2662 | mFimc2CSCLock.unlock(); | |
2663 | return false; | |
2664 | } | |
2665 | } else { | |
2666 | if (csc_convert(mFimc2CSC) != 0) { | |
2667 | ALOGE("ERR(%s):csc_convert(mFimc2CSC) fail", __func__); | |
2668 | mFimc2CSCLock.unlock(); | |
2669 | return false; | |
2670 | } | |
2671 | } | |
2672 | mFimc2CSCLock.unlock(); | |
2673 | /* mSaveDump("/data/camera_recording%d.yuv", &dstBuf, dstIdx); */ | |
2674 | } else { | |
2675 | ALOGE("ERR(%s): mFimc2CSC == NULL", __func__); | |
2676 | return false; | |
2677 | } | |
2678 | return true; | |
2679 | } | |
2680 | ||
2681 | status_t SecCameraHardware::nativeCSCRecordingCapture(ExynosBuffer *srcBuf, ExynosBuffer *dstBuf) | |
2682 | { | |
2683 | if (mFimc2CSC) { | |
2684 | ALOGD("DEBUG(%s) (%d) src : mFLiteSize(%d x %d), mPreviewZoomRect(%d, %d, %d, %d)", __FUNCTION__, __LINE__, | |
2685 | mFLiteSize.width, | |
2686 | mFLiteSize.height, | |
2687 | mPreviewZoomRect.x, | |
2688 | mPreviewZoomRect.y, | |
2689 | mPreviewZoomRect.w, | |
2690 | mPreviewZoomRect.h); | |
2691 | ||
2692 | ALOGD("DEBUG(%s) (%d) dst : (%d x %d)", __FUNCTION__, __LINE__, | |
2693 | mPreviewSize.width, mPreviewSize.height); | |
2694 | ||
2695 | int dstW = mPictureSize.width; | |
2696 | int dstH = mPictureSize.height; | |
2697 | ||
2698 | /* src : FLite */ | |
2699 | csc_set_src_format(mFimc2CSC, | |
2700 | mFLiteSize.width, mFLiteSize.height, | |
2701 | mPreviewZoomRect.x, mPreviewZoomRect.y, | |
2702 | mPreviewZoomRect.w, mPreviewZoomRect.h, | |
2703 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2704 | 0); | |
2705 | ||
2706 | csc_set_src_buffer(mFimc2CSC, (void **)srcBuf->virt.extP, CSC_MEMORY_USERPTR); | |
2707 | ||
2708 | /* dst : buffer */ | |
2709 | csc_set_dst_format(mFimc2CSC, | |
2710 | dstW, dstH, | |
2711 | 0, 0, dstW, dstH, | |
2712 | V4L2_PIX_2_HAL_PIXEL_FORMAT(mFliteNode.format), | |
2713 | 0); | |
2714 | ||
2715 | csc_set_dst_buffer(mFimc2CSC, (void **)dstBuf->fd.extFd, CSC_MEMORY_DMABUF); | |
2716 | ||
2717 | mFimc2CSCLock.lock(); | |
2718 | if (csc_convert(mFimc2CSC) != 0) { | |
2719 | ALOGE("ERR(%s):csc_convert(mFimc2CSC) fail", __func__); | |
2720 | mFimc2CSCLock.unlock(); | |
2721 | return INVALID_OPERATION; | |
2722 | } | |
2723 | mFimc2CSCLock.unlock(); | |
2724 | /* mSaveDump("/data/camera_recording%d.yuv", &dstBuf, dstIdx); */ | |
2725 | } else { | |
2726 | ALOGE("ERR(%s): mFimc1CSC == NULL", __func__); | |
2727 | return INVALID_OPERATION; | |
2728 | } | |
2729 | return NO_ERROR; | |
2730 | } | |
2731 | ||
2732 | int SecCameraHardware::nativegetWBcustomX() | |
2733 | { | |
2734 | int x_value, err; | |
2735 | ||
2736 | err = mFlite.gctrl(V4L2_CID_CAMERA_WB_CUSTOM_X, &x_value); | |
2737 | CHECK_ERR(err, ("nativegetWBcustomX: error [%d]", x_value)); | |
2738 | ||
2739 | ALOGV("%s res[%d]", __func__, x_value); | |
2740 | ||
2741 | return x_value; | |
2742 | } | |
2743 | ||
2744 | int SecCameraHardware::nativegetWBcustomY() | |
2745 | { | |
2746 | int y_value, err; | |
2747 | ||
2748 | err = mFlite.gctrl(V4L2_CID_CAMERA_WB_CUSTOM_Y, &y_value); | |
2749 | CHECK_ERR(err, ("nativegetWBcustomY: error [%d]", y_value)); | |
2750 | ||
2751 | ALOGV("%s res[%d]", __func__, y_value); | |
2752 | ||
2753 | return y_value; | |
2754 | } | |
2755 | ||
2756 | ||
2757 | ||
2758 | status_t SecCameraHardware::nativeSetZoomRatio(int value) | |
2759 | { | |
2760 | /* Calculation of the crop information */ | |
2761 | mZoomRatio = getZoomRatio(value); | |
2762 | ||
2763 | ALOGD("%s: Zoomlevel = %d, mZoomRatio = %f", __FUNCTION__, value, mZoomRatio); | |
2764 | ||
2765 | return NO_ERROR; | |
2766 | } | |
2767 | ||
2768 | #ifdef RECORDING_CAPTURE | |
2769 | bool SecCameraHardware::nativeGetRecordingJpeg(ExynosBuffer *yuvBuf, uint32_t width, uint32_t height) | |
2770 | { | |
2771 | bool ret = false; | |
2772 | ||
2773 | Exif exif(mCameraId); | |
2774 | ||
2775 | uint8_t *outBuf; | |
2776 | int jpegSize = 0; | |
2777 | int thumbSize = 0; | |
2778 | uint32_t exifSize = 0; | |
2779 | ||
2780 | ExynosBuffer jpegBuf; | |
2781 | jpegBuf.size.extS[0] = width * height * 2; | |
2782 | ||
2783 | ExynosBuffer exifBuf; | |
2784 | exifBuf.size.extS[0] = EXIF_MAX_LEN; | |
2785 | ||
2786 | ExynosBuffer thumbnailYuvBuf; | |
2787 | thumbnailYuvBuf.size.extS[0] = mThumbnailSize.width * mThumbnailSize.height * 2; | |
2788 | ||
2789 | bool thumbnail = false; | |
2790 | ||
2791 | /* Thumbnail */ | |
2792 | LOG_PERFORMANCE_START(1); | |
2793 | ||
2794 | /* use for both thumbnail and main jpeg */ | |
2795 | if (allocMem(mIonCameraClient, &jpegBuf, 1 << 1) == false) { | |
2796 | ALOGE("ERR(%s):(%d)allocMem(jpegBuf) fail", __func__, __LINE__); | |
2797 | goto jpeg_encode_done; | |
2798 | } | |
2799 | ||
2800 | if (mThumbnailSize.width == 0 || mThumbnailSize.height == 0) | |
2801 | goto encode_jpeg; | |
2802 | ||
2803 | if (allocMem(mIonCameraClient, &thumbnailYuvBuf, 1 << 1) == false) { | |
2804 | ALOGE("ERR(%s):(%d)allocMem(thumbnailYuvBuf) fail", __func__, __LINE__); | |
2805 | goto encode_jpeg; | |
2806 | } | |
2807 | ||
2808 | LOG_PERFORMANCE_START(3); | |
2809 | ||
2810 | scaleDownYuv422((uint8_t *)yuvBuf->virt.extP[0], (int)width, (int)height, | |
2811 | (uint8_t *)thumbnailYuvBuf.virt.extP[0], (int)mThumbnailSize.width, (int)mThumbnailSize.height); | |
2812 | ||
2813 | LOG_PERFORMANCE_END(3, "scaleDownYuv422"); | |
2814 | ||
2815 | if (this->EncodeToJpeg(&thumbnailYuvBuf, &jpegBuf, | |
2816 | mThumbnailSize.width, mThumbnailSize.height, | |
2817 | CAM_PIXEL_FORMAT_YUV422I, | |
2818 | &thumbSize, | |
2819 | JPEG_THUMBNAIL_QUALITY) != NO_ERROR) { | |
2820 | ALOGE("ERR(%s):(%d)EncodeToJpeg", __func__, __LINE__); | |
2821 | goto encode_jpeg; | |
2822 | } | |
2823 | ||
2824 | outBuf = (uint8_t *)jpegBuf.virt.extP[0]; | |
2825 | ||
2826 | thumbnail = true; | |
2827 | ||
2828 | LOG_PERFORMANCE_END(1, "encode thumbnail"); | |
2829 | ||
2830 | encode_jpeg: | |
2831 | /* EXIF */ | |
2832 | setExifChangedAttribute(); | |
2833 | ||
2834 | if (allocMem(mIonCameraClient, &exifBuf, 1 << 1) == false) { | |
2835 | ALOGE("ERR(%s):(%d)allocMem(exifBuf) fail", __func__, __LINE__); | |
2836 | goto jpeg_encode_done; | |
2837 | } | |
2838 | ||
2839 | #if 0 //##mmkim for test | |
2840 | if (CC_LIKELY(thumbnail)) | |
2841 | exifSize = exif.make(exifBuf.virt.extP[0], &mExifInfo, exifBuf.size.extS[0], outBuf, thumbSize); | |
2842 | else | |
2843 | exifSize = exif.make(exifBuf.virt.extP[0], &mExifInfo); | |
2844 | ||
2845 | if (CC_UNLIKELY(!exifSize)) { | |
2846 | ALOGE("getJpeg: error, fail to make EXIF"); | |
2847 | goto jpeg_encode_done; | |
2848 | } | |
2849 | #endif | |
2850 | /* Jpeg */ | |
2851 | LOG_PERFORMANCE_START(2); | |
2852 | ||
2853 | #ifdef SAMSUNG_JPEG_QUALITY_ADJUST_TARGET | |
2854 | adjustJpegQuality(); | |
2855 | #endif | |
2856 | ||
2857 | if (this->EncodeToJpeg(yuvBuf, &jpegBuf, | |
2858 | width, height, | |
2859 | CAM_PIXEL_FORMAT_YUV422I, | |
2860 | &jpegSize, | |
2861 | mJpegQuality) != NO_ERROR) { | |
2862 | ALOGE("ERR(%s):(%d)EncodeToJpeg", __func__, __LINE__); | |
2863 | goto jpeg_encode_done; | |
2864 | } | |
2865 | ||
2866 | outBuf = (uint8_t *)jpegBuf.virt.extP[0]; | |
2867 | ||
2868 | LOG_PERFORMANCE_END(2, "encode jpeg"); | |
2869 | ||
2870 | LOG_PERFORMANCE_START(4); | |
2871 | mRecordingPictureFrameSize = jpegSize + exifSize; | |
2872 | /* picture frame size is should be calculated before call allocateSnapshotHeap */ | |
2873 | if (!allocateRecordingSnapshotHeap()) { | |
2874 | ALOGE("getJpeg: error, allocateSnapshotHeap"); | |
2875 | return UNKNOWN_ERROR; | |
2876 | } | |
2877 | ||
2878 | memcpy(mJpegHeap->data, outBuf, 2); | |
2879 | memcpy((uint8_t *)mJpegHeap->data + 2, exifBuf.virt.extP[0], exifSize); | |
2880 | memcpy((uint8_t *)mJpegHeap->data + 2 + exifSize, outBuf + 2, jpegSize - 2); | |
2881 | LOG_PERFORMANCE_END(4, "jpeg + exif"); | |
2882 | ||
2883 | ret = true; | |
2884 | ||
2885 | jpeg_encode_done: | |
2886 | ||
2887 | freeMem(&thumbnailYuvBuf); | |
2888 | freeMem(&exifBuf); | |
2889 | freeMem(&jpegBuf); | |
2890 | ||
2891 | return ret; | |
2892 | } | |
2893 | #endif | |
2894 | ||
2895 | #if FRONT_ZSL | |
2896 | bool SecCameraHardware::allocateFullPreviewHeap() | |
2897 | { | |
2898 | if (mFullPreviewHeap) { | |
2899 | mFullPreviewHeap->release(mFullPreviewHeap); | |
2900 | mFullPreviewHeap = NULL; | |
2901 | } | |
2902 | ||
2903 | mFullPreviewHeap = mGetMemoryCb((int)mFimc1.getfd(), | |
2904 | mFullPreviewFrameSize, kBufferZSLCount, 0); | |
2905 | if (!mFullPreviewHeap || mFullPreviewHeap->data == MAP_FAILED) { | |
2906 | CLOGE("ERR(%s): heap creation fail", __func__); | |
2907 | return false; | |
2908 | } | |
2909 | ||
2910 | CLOGD("allocateFullPreviewHeap: %dx%d, frame %dx%d", | |
2911 | mPictureSize.width, mPictureSize.height, mFullPreviewFrameSize, kBufferZSLCount); | |
2912 | ||
2913 | return true; | |
2914 | } | |
2915 | ||
2916 | status_t SecCameraHardware::nativeStartFullPreview(void) | |
2917 | { | |
2918 | CLOGD("INFO(%s) : in ",__FUNCTION__); | |
2919 | ||
2920 | int err; | |
2921 | cam_pixel_format captureFormat = CAM_PIXEL_FORMAT_YUV422I; | |
2922 | ||
2923 | err = mFimc1.startCapture(&mPictureSize, captureFormat, kBufferZSLCount, 0); | |
2924 | CHECK_ERR_N(err, ("nativeStartFullPreview: error, mFimc1.start")); | |
2925 | ||
2926 | mFimc1.querybuf(&mFullPreviewFrameSize); | |
2927 | if (mFullPreviewFrameSize == 0) { | |
2928 | CLOGE("nativeStartFullPreview: error, mFimc1.querybuf"); | |
2929 | return UNKNOWN_ERROR; | |
2930 | } | |
2931 | ||
2932 | if (!allocateFullPreviewHeap()) { | |
2933 | ALOGE("nativeStartFullPreview: error, allocateFullPreviewHeap"); | |
2934 | return NO_MEMORY; | |
2935 | } | |
2936 | ||
2937 | for (int i = 0; i < kBufferZSLCount; i++) { | |
2938 | err = mFimc1.qbuf(i); | |
2939 | CHECK_ERR_N(err, ("nativeStartFullPreview: error, mFimc1.qbuf(%d)", i)); | |
2940 | } | |
2941 | ||
2942 | rawImageMem = new MemoryHeapBase(mFullPreviewFrameSize); | |
2943 | ||
2944 | err = mFimc1.stream(true); | |
2945 | CHECK_ERR_N(err, ("nativeStartFullPreview: error, mFimc1.stream")); | |
2946 | ||
2947 | CLOGD("INFO(%s) : out ",__FUNCTION__); | |
2948 | return NO_ERROR; | |
2949 | } | |
2950 | ||
2951 | int SecCameraHardware::nativeGetFullPreview() | |
2952 | { | |
2953 | int index; | |
2954 | phyaddr_t y, cbcr; | |
2955 | int err; | |
2956 | ||
2957 | err = mFimc1.polling(); | |
2958 | CHECK_ERR_N(err, ("nativeGetFullPreview: error, mFimc1.polling")); | |
2959 | ||
2960 | index = mFimc1.dqbuf(); | |
2961 | CHECK_ERR_N(index, ("nativeGetFullPreview: error, mFimc1.dqbuf")); | |
2962 | ||
2963 | mJpegIndex = index; | |
2964 | ||
2965 | return index; | |
2966 | } | |
2967 | ||
2968 | int SecCameraHardware::nativeReleaseFullPreviewFrame(int index) | |
2969 | { | |
2970 | return mFimc1.qbuf(index); | |
2971 | } | |
2972 | ||
2973 | void SecCameraHardware::nativeStopFullPreview() | |
2974 | { | |
2975 | if (mFimc1.stream(false) < 0) | |
2976 | CLOGE("nativeStopFullPreview X: error, mFimc1.stream(0)"); | |
2977 | ||
2978 | if (mFullPreviewHeap) { | |
2979 | mFullPreviewHeap->release(mFullPreviewHeap); | |
2980 | mFullPreviewHeap = NULL; | |
2981 | } | |
2982 | ||
2983 | rawImageMem.clear(); | |
2984 | ||
2985 | CLOGD("INFO(%s) : out ",__FUNCTION__); | |
2986 | } | |
2987 | ||
2988 | void SecCameraHardware::nativeForceStopFullPreview() | |
2989 | { | |
2990 | mFimc1.forceStop(); | |
2991 | } | |
2992 | ||
2993 | bool SecCameraHardware::getZSLJpeg() | |
2994 | { | |
2995 | int ret; | |
2996 | ||
2997 | ALOGE("%s:: mJpegIndex : %d", __func__, mJpegIndex); | |
2998 | ||
2999 | #ifdef SUPPORT_64BITS | |
3000 | memcpy( (unsigned char *)rawImageMem->base(), | |
3001 | (unsigned char *)((unsigned long)mFullPreviewHeap->data + mJpegIndex * mFullPreviewFrameSize), | |
3002 | mFullPreviewFrameSize ); | |
3003 | #else | |
3004 | memcpy( (unsigned char *)rawImageMem->base(), | |
3005 | (unsigned char *)((unsigned int)mFullPreviewHeap->data + mJpegIndex * mFullPreviewFrameSize), | |
3006 | mFullPreviewFrameSize ); | |
3007 | #endif | |
3008 | ||
3009 | sp<MemoryHeapBase> thumbnailJpeg; | |
3010 | sp<MemoryHeapBase> rawThumbnail; | |
3011 | ||
3012 | unsigned char *thumb; | |
3013 | int thumbSize = 0; | |
3014 | ||
3015 | bool thumbnail = false; | |
3016 | /* Thumbnail */ | |
3017 | LOG_PERFORMANCE_START(1); | |
3018 | ||
3019 | if (mThumbnailSize.width == 0 || mThumbnailSize.height == 0) | |
3020 | goto encode_jpeg; | |
3021 | ||
3022 | rawThumbnail = new MemoryHeapBase(mThumbnailSize.width * mThumbnailSize.height * 2); | |
3023 | ||
3024 | LOG_PERFORMANCE_START(3); | |
3025 | #ifdef USE_HW_SCALER | |
3026 | ret = scaleDownYUVByFIMC((unsigned char *)rawImageMem->base(), | |
3027 | (int)mPictureSize.width, | |
3028 | (int)mPictureSize.height, | |
3029 | (unsigned char *)rawThumbnail->base(), | |
3030 | (int)mThumbnailSize.width, | |
3031 | (int)mThumbnailSize.height, | |
3032 | CAM_PIXEL_FORMAT_YUV422I); | |
3033 | ||
3034 | if (!ret) { | |
3035 | CLOGE("Fail to scale down YUV data for thumbnail!\n"); | |
3036 | goto encode_jpeg; | |
3037 | } | |
3038 | #else | |
3039 | ret = scaleDownYuv422((unsigned char *)rawImageMem->base(), | |
3040 | (int)mPictureSize.width, | |
3041 | (int)mPictureSize.height, | |
3042 | (unsigned char *)rawThumbnail->base(), | |
3043 | (int)mThumbnailSize.width, | |
3044 | (int)mThumbnailSize.height); | |
3045 | ||
3046 | if (!ret) { | |
3047 | CLOGE("Fail to scale down YUV data for thumbnail!\n"); | |
3048 | goto encode_jpeg; | |
3049 | } | |
3050 | #endif | |
3051 | LOG_PERFORMANCE_END(3, "scaleDownYuv422"); | |
3052 | ||
3053 | thumbnailJpeg = new MemoryHeapBase(mThumbnailSize.width * mThumbnailSize.height * 2); | |
3054 | ||
3055 | #ifdef CHG_ENCODE_JPEG | |
3056 | ret = EncodeToJpeg((unsigned char*)rawThumbnail->base(), | |
3057 | mThumbnailSize.width, | |
3058 | mThumbnailSize.height, | |
3059 | CAM_PIXEL_FORMAT_YUV422I, | |
3060 | (unsigned char*)thumbnailJpeg->base(), | |
3061 | &thumbSize, | |
3062 | JPEG_THUMBNAIL_QUALITY); | |
3063 | ||
3064 | if (ret != NO_ERROR) { | |
3065 | ALOGE("thumbnail:EncodeToJpeg failed\n"); | |
3066 | goto encode_jpeg; | |
3067 | } | |
3068 | #endif | |
3069 | if (thumbSize > MAX_THUMBNAIL_SIZE) { | |
3070 | ALOGE("thumbnail size is over limit\n"); | |
3071 | goto encode_jpeg; | |
3072 | } | |
3073 | ||
3074 | thumb = (unsigned char *)thumbnailJpeg->base(); | |
3075 | thumbnail = true; | |
3076 | ||
3077 | LOG_PERFORMANCE_END(1, "encode thumbnail"); | |
3078 | ||
3079 | encode_jpeg: | |
3080 | ||
3081 | /* EXIF */ | |
3082 | setExifChangedAttribute(); | |
3083 | ||
3084 | Exif exif(mCameraId); | |
3085 | uint32_t exifSize; | |
3086 | ||
3087 | unsigned char *jpeg; | |
3088 | int jpegSize = 0; | |
3089 | int jpegQuality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY); | |
3090 | ||
3091 | sp<MemoryHeapBase> JpegHeap = new MemoryHeapBase(mPictureSize.width * mPictureSize.height * 2); | |
3092 | sp<MemoryHeapBase> exifHeap = new MemoryHeapBase(EXIF_MAX_LEN); | |
3093 | if (!initialized(exifHeap)) { | |
3094 | ALOGE("getJpeg: error, could not initialize Camera exif heap"); | |
3095 | return false; | |
3096 | } | |
3097 | ||
3098 | if (!thumbnail) | |
3099 | exifSize = exif.make(exifHeap->base(), &mExifInfo); | |
3100 | else | |
3101 | exifSize = exif.make(exifHeap->base(), &mExifInfo, exifHeap->getSize(), thumb, thumbSize); | |
3102 | ||
3103 | #ifdef CHG_ENCODE_JPEG | |
3104 | #ifdef SAMSUNG_JPEG_QUALITY_ADJUST_TARGET | |
3105 | adjustJpegQuality(); | |
3106 | #endif | |
3107 | ||
3108 | ret = EncodeToJpeg((unsigned char*)rawImageMem->base(), | |
3109 | mPictureSize.width, | |
3110 | mPictureSize.height, | |
3111 | CAM_PIXEL_FORMAT_YUV422I, | |
3112 | (unsigned char*)JpegHeap->base(), | |
3113 | &jpegSize, | |
3114 | mJpegQuality); | |
3115 | ||
3116 | if (ret != NO_ERROR) { | |
3117 | ALOGE("EncodeToJpeg failed\n"); | |
3118 | return false; | |
3119 | } | |
3120 | #endif | |
3121 | mPictureFrameSize = jpegSize + exifSize; | |
3122 | ||
3123 | /* picture frame size is should be calculated before call allocateSnapshotHeap */ | |
3124 | if (!allocateSnapshotHeap()) { | |
3125 | CLOGE("getJpeg: error, allocateSnapshotHeap"); | |
3126 | return false; | |
3127 | } | |
3128 | ||
3129 | jpeg = (unsigned char *)JpegHeap->base(); | |
3130 | memcpy((unsigned char *)mJpegHeap->data, jpeg, 2); | |
3131 | memcpy((unsigned char *)mJpegHeap->data + 2, exifHeap->base(), exifSize); | |
3132 | memcpy((unsigned char *)mJpegHeap->data + 2 + exifSize, jpeg + 2, jpegSize - 2); | |
3133 | ||
3134 | return true; | |
3135 | } | |
3136 | #endif | |
3137 | ||
3138 | bool SecCameraHardware::allocatePostviewHeap() | |
3139 | { | |
3140 | cam_pixel_format postviewFmt; | |
3141 | ||
3142 | CLOGD("INFO(%s) : in ",__FUNCTION__); | |
3143 | if ( mPostviewHeap && mPostviewHeap->size == mPostviewFrameSize ) | |
3144 | return true; | |
3145 | ||
3146 | if (mPostviewHeap) { | |
3147 | mPostviewHeap->release(mPostviewHeap); | |
3148 | mPostviewHeap = 0; | |
3149 | } | |
3150 | ||
3151 | if (mPostviewHeapTmp) { | |
3152 | mPostviewHeapTmp->release(mPostviewHeapTmp); | |
3153 | mPostviewHeapTmp = NULL; | |
3154 | } | |
3155 | ||
3156 | postviewFmt = CAM_PIXEL_FORMAT_YUV422I; | |
3157 | ||
3158 | mPostviewFrameSize = getAlignedYUVSize(postviewFmt, mPostviewSize.width, mPostviewSize.height, NULL); | |
3159 | mPostviewHeap = mGetMemoryCb(-1, mPostviewFrameSize, 1, &mPostviewHeapFd); | |
3160 | if (!mPostviewHeap || mPostviewHeap->data == MAP_FAILED) { | |
3161 | CLOGE("ERR(%s): Virtual postview heap creation fail", __func__); | |
3162 | return false; | |
3163 | } | |
3164 | ||
3165 | mPostviewHeapTmp = mGetMemoryCb(-1, mPostviewFrameSize, 1, &mPostviewHeapTmpFd); | |
3166 | if (!mPostviewHeapTmp || mPostviewHeapTmp->data == MAP_FAILED) { | |
3167 | CLOGE("ERR(%s): Virtual postview heap creation fail", __func__); | |
3168 | return false; | |
3169 | } | |
3170 | ||
3171 | CLOGD("allocatePostviewHeap: postview %dx%d, frame %d", | |
3172 | mPostviewSize.width, mPostviewSize.height, mPostviewFrameSize); | |
3173 | ||
3174 | return true; | |
3175 | } | |
3176 | ||
3177 | bool SecCameraHardware::allocateSnapshotHeap() | |
3178 | { | |
3179 | /* init jpeg heap */ | |
3180 | if (mJpegHeap) { | |
3181 | mJpegHeap->release(mJpegHeap); | |
3182 | mJpegHeap = 0; | |
3183 | } | |
3184 | ||
3185 | mJpegHeap = mGetMemoryCb(-1, mPictureFrameSize, 1, &mJpegHeapFd); | |
3186 | if (mJpegHeap == NULL || mJpegHeap->data == MAP_FAILED) { | |
3187 | CLOGE("ERR(%s): Jpeg heap creation fail", __func__); | |
3188 | if (mJpegHeap) { | |
3189 | mJpegHeap->release(mJpegHeap); | |
3190 | mJpegHeap = NULL; | |
3191 | } | |
3192 | return false; | |
3193 | } | |
3194 | ||
3195 | CLOGD("allocateSnapshotHeap: jpeg %dx%d, size %d", | |
3196 | mPictureSize.width, mPictureSize.height, mPictureFrameSize); | |
3197 | ||
3198 | #if 0 | |
3199 | /* RAW_IMAGE or POSTVIEW_FRAME heap */ | |
3200 | if ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE) || (mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME)) { | |
3201 | mRawFrameSize = getAlignedYUVSize(mFliteFormat, mRawSize.width, mRawSize.height, NULL); | |
3202 | mRawHeap = mGetMemoryCb(-1, mRawFrameSize, 1, &mRawHeapFd); | |
3203 | ||
3204 | ALOGD("allocateSnapshotHeap: postview %dx%d, frame %d", | |
3205 | mRawSize.width, mRawSize.height, mRawFrameSize); | |
3206 | } | |
3207 | #endif | |
3208 | ||
3209 | return true; | |
3210 | } | |
3211 | ||
3212 | bool SecCameraHardware::allocateHDRHeap() | |
3213 | { | |
3214 | /* init postview heap */ | |
3215 | if (mHDRHeap) { | |
3216 | mHDRHeap->release(mHDRHeap); | |
3217 | mHDRHeap = NULL; | |
3218 | } | |
3219 | ||
3220 | mRawSize = mPictureSize; | |
3221 | mHDRFrameSize = mRawSize.width*mRawSize.height*2; | |
3222 | mHDRHeap = mGetMemoryCb(-1, mHDRFrameSize, 1, &mHDRHeapFd); | |
3223 | if (!mHDRHeap || mHDRHeap->data == MAP_FAILED) { | |
3224 | ALOGE("ERR(%s): HDR heap creation fail", __func__); | |
3225 | goto out; | |
3226 | } | |
3227 | ||
3228 | return true; | |
3229 | ||
3230 | out: | |
3231 | ||
3232 | if (mHDRHeap) { | |
3233 | mHDRHeap->release(mHDRHeap); | |
3234 | mHDRHeap = NULL; | |
3235 | } | |
3236 | ||
3237 | return false; | |
3238 | } | |
3239 | ||
3240 | #ifndef RCJUNG | |
3241 | bool SecCameraHardware::allocateYUVHeap() | |
3242 | { | |
3243 | /* init YUV main image heap */ | |
3244 | if (mYUVHeap) { | |
3245 | mYUVHeap->release(mYUVHeap); | |
3246 | mYUVHeap = 0; | |
3247 | } | |
3248 | ||
3249 | mYUVHeap = mGetMemoryCb(-1, mRawFrameSize, 1, 0); | |
3250 | if (!mYUVHeap || mYUVHeap->data == MAP_FAILED) { | |
3251 | ALOGE("ERR(%s): YUV heap creation fail", __func__); | |
3252 | goto out; | |
3253 | } | |
3254 | ||
3255 | ALOGD("allocateYUVHeap: YUV %dx%d, frame %d", | |
3256 | mOrgPreviewSize.width, mOrgPreviewSize.height, mRawFrameSize); | |
3257 | ||
3258 | return true; | |
3259 | ||
3260 | out: | |
3261 | ||
3262 | if (mYUVHeap) { | |
3263 | mYUVHeap->release(mYUVHeap); | |
3264 | mYUVHeap = NULL; | |
3265 | } | |
3266 | ||
3267 | return false; | |
3268 | } | |
3269 | #endif | |
3270 | ||
3271 | void SecCameraHardware::nativeMakeJpegDump() | |
3272 | { | |
3273 | int postviewOffset; | |
3274 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3275 | ExynosBuffer jpegBuf; | |
3276 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3277 | if (getJpegOnBack(&postviewOffset) >= 0) { | |
3278 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3279 | jpegBuf.size.extS[0] = mPictureFrameSize; | |
3280 | jpegBuf.virt.extP[0] = (char *)mJpegHeap->data; | |
3281 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3282 | mSaveDump("/data/camera_%d.jpeg", &jpegBuf, 0); | |
3283 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3284 | } else { | |
3285 | CLOGV("DEBUG(%s): (%d) fail!!!!", __FUNCTION__, __LINE__); | |
3286 | } | |
3287 | } | |
3288 | ||
3289 | bool SecCameraHardware::nativeStartPostview() | |
3290 | { | |
3291 | ALOGD("nativeStartPostview E"); | |
3292 | ||
3293 | int err; | |
3294 | int nBufs = 1; | |
3295 | int i; | |
3296 | ||
3297 | /* For YUV postview */ | |
3298 | cam_pixel_format captureFormat = CAM_PIXEL_FORMAT_YUV422I; | |
3299 | ||
3300 | if ( captureFormat==CAM_PIXEL_FORMAT_YUV422I ) | |
3301 | mPostviewFrameSize = mPostviewSize.width * mPostviewSize.height * 2; /* yuv422I */ | |
3302 | else if ( captureFormat == CAM_PIXEL_FORMAT_YUV420SP ) | |
3303 | mPostviewFrameSize = mPostviewSize.width * mPostviewSize.height * 1.5; /* yuv420sp */ | |
3304 | ||
3305 | ALOGD("Postview size : width = %d, height = %d, frame size = %d", | |
3306 | mPostviewSize.width, mPostviewSize.height, mPreviewFrameSize); | |
3307 | err = mFlite.startCapture(&mPostviewSize, captureFormat, nBufs, START_CAPTURE_POSTVIEW); | |
3308 | CHECK_ERR(err, ("nativeStartPostview: error, mFlite.start")); | |
3309 | ||
3310 | ALOGD("nativeStartPostview GC"); | |
3311 | ||
3312 | getAlignedYUVSize(captureFormat, mPostviewSize.width, mPostviewSize.height, &mPictureBuf); | |
3313 | if (allocMem(mIonCameraClient, &mPictureBuf, 1 << 1) == false) { | |
3314 | ALOGE("ERR(%s):mPictureBuf allocMem() fail", __func__); | |
3315 | return UNKNOWN_ERROR; | |
3316 | } else { | |
3317 | ALOGV("DEBUG(%s): mPictureBuf allocMem adr(%p), size(%d), ion(%d) w/h(%d/%d)", __FUNCTION__, | |
3318 | mPictureBuf.virt.extP[0], mPictureBuf.size.extS[0], mIonCameraClient, | |
3319 | mPostviewSize.width, mPostviewSize.height); | |
3320 | memset(mPictureBuf.virt.extP[0], 0, mPictureBuf.size.extS[0]); | |
3321 | } | |
3322 | ||
3323 | #ifdef USE_USERPTR | |
3324 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3325 | getAlignedYUVSize(captureFormat, mPostviewSize.width, mPostviewSize.height, &mPictureBufDummy[i]); | |
3326 | if (allocMem(mIonCameraClient, &mPictureBufDummy[i], 1 << 1) == false) { | |
3327 | ALOGE("ERR(%s):mPictureBuf dummy allocMem() fail", __func__); | |
3328 | return UNKNOWN_ERROR; | |
3329 | } else { | |
3330 | ALOGV("DEBUG(%s): mPictureBuf dummy allocMem adr(%p), size(%d), ion(%d) w/h(%d/%d)", __FUNCTION__, | |
3331 | mPictureBufDummy[i].virt.extP[0], mPictureBufDummy[i].size.extS[0], mIonCameraClient, | |
3332 | mPostviewSize.width, mPostviewSize.height); | |
3333 | memset(mPictureBufDummy[i].virt.extP[0], 0, mPictureBufDummy[i].size.extS[0]); | |
3334 | } | |
3335 | } | |
3336 | #else | |
3337 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3338 | err = mFlite.querybuf2(i, mFliteNode.planes, &mPictureBufDummy[i]); | |
3339 | CHECK_ERR_N(err, ("nativeStartPreviewZoom: error, mFlite.querybuf2")); | |
3340 | } | |
3341 | #endif | |
3342 | ||
3343 | /* qbuf dummy buffer for skip */ | |
3344 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3345 | err = mFlite.qbufForCapture(&mPictureBufDummy[i], i); | |
3346 | CHECK_ERR(err, ("nativeStartPostview: error, mFlite.qbuf(%d)", i)); | |
3347 | } | |
3348 | ||
3349 | ALOGD("Normal Capture Stream on"); | |
3350 | err = mFlite.stream(true); | |
3351 | CHECK_ERR(err, ("nativeStartPostview: error, mFlite.stream")); | |
3352 | ||
3353 | if ( mCaptureMode == RUNNING_MODE_SINGLE ) { | |
3354 | // PlayShutterSound(); | |
3355 | // Fimc_stream_true_part2(); | |
3356 | } | |
3357 | ||
3358 | ALOGD("nativeStartPostview X"); | |
3359 | return true; | |
3360 | } | |
3361 | ||
3362 | bool SecCameraHardware::nativeStartYUVSnapshot() | |
3363 | { | |
3364 | ALOGD("nativeStartYUVSnapshot E"); | |
3365 | ||
3366 | int err; | |
3367 | int nBufs = 1; | |
3368 | int i = 0; | |
3369 | ExynosBuffer nullBuf; | |
3370 | ||
3371 | cam_pixel_format captureFormat = CAM_PIXEL_FORMAT_YUV422I; | |
3372 | ||
3373 | err = mFlite.startCapture(&mFLiteCaptureSize, captureFormat, nBufs, START_CAPTURE_YUV_MAIN); | |
3374 | CHECK_ERR(err, ("nativeStartYUVSnapshot: error, mFlite.start")); | |
3375 | ||
3376 | #ifdef USE_USERPTR | |
3377 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3378 | getAlignedYUVSize(captureFormat, mFLiteCaptureSize.width, mFLiteCaptureSize.height, &mPictureBufDummy[i]); | |
3379 | if (allocMem(mIonCameraClient, &mPictureBufDummy[i], 1 << 1) == false) { | |
3380 | ALOGE("ERR(%s):mPictureBuf dummy allocMem() fail", __func__); | |
3381 | return UNKNOWN_ERROR; | |
3382 | } else { | |
3383 | ALOGV("DEBUG(%s): mPictureBuf dummy allocMem adr(%p), size(%d), ion(%d) w/h(%d/%d)", __FUNCTION__, | |
3384 | mPictureBufDummy[i].virt.extP[0], mPictureBufDummy[i].size.extS[0], mIonCameraClient, | |
3385 | mFLiteCaptureSize.width, mFLiteCaptureSize.height); | |
3386 | memset(mPictureBufDummy[i].virt.extP[0], 0, mPictureBufDummy[i].size.extS[0]); | |
3387 | } | |
3388 | } | |
3389 | #else | |
3390 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3391 | err = mFlite.querybuf2(i, mFliteNode.planes, &mPictureBufDummy[i]); | |
3392 | CHECK_ERR_N(err, ("nativeStartYUVSnapshot: error, mFlite.querybuf2")); | |
3393 | } | |
3394 | #endif | |
3395 | ||
3396 | /* qbuf dummy buffer for skip */ | |
3397 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3398 | err = mFlite.qbufForCapture(&mPictureBufDummy[i], i); | |
3399 | CHECK_ERR(err, ("nativeStartYUVSnapshot: error, mFlite.qbuf(%d)", i)); | |
3400 | } | |
3401 | ||
3402 | err = mFlite.stream(true); | |
3403 | CHECK_ERR(err, ("nativeStartYUVSnapshot: error, mFlite.stream")); | |
3404 | ||
3405 | if ( mCaptureMode == RUNNING_MODE_SINGLE ) { | |
3406 | // PlayShutterSound(); | |
3407 | // Fimc_stream_true_part2(); | |
3408 | } | |
3409 | ||
3410 | ALOGD("nativeStartYUVSnapshot X"); | |
3411 | return true; | |
3412 | } | |
3413 | ||
3414 | bool SecCameraHardware::nativeGetYUVSnapshot(int numF, int *postviewOffset) | |
3415 | { | |
3416 | ALOGD("nativeGetYUVSnapshot E"); | |
3417 | ||
3418 | int err; | |
3419 | int i = 0; | |
3420 | ||
3421 | retry: | |
3422 | ||
3423 | // err = mFlite.sctrl(CAM_CID_TRANSFER, numF); | |
3424 | CHECK_ERR(err, ("nativeGetYUVSnapshot: error, capture start")) | |
3425 | /* | |
3426 | * Put here if Capture Start Command code is additionally needed | |
3427 | * in case of ISP. | |
3428 | */ | |
3429 | ||
3430 | /* | |
3431 | * Waiting for frame(stream) to be input. | |
3432 | * ex) poll() | |
3433 | */ | |
3434 | err = mFlite.polling(); | |
3435 | if (CC_UNLIKELY(err <= 0)) { | |
3436 | LOG_FATAL("nativeGetYUVSnapshot: fail to get a frame!"); | |
3437 | return false; | |
3438 | } | |
3439 | ALOGV("DEBUG(%s): (%d) nativeGetYUVSnapshot dq start", __FUNCTION__, __LINE__); | |
3440 | ||
3441 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3442 | int ret = mFlite.dqbufForCapture(&mPictureBufDummy[i]); | |
3443 | ALOGV("DEBUG(%s) (%d): dqbufForCapture dq(%d), ret = %d", __FUNCTION__, __LINE__, i, ret); | |
3444 | } | |
3445 | ||
3446 | /* Stop capturing stream(or frame) data. */ | |
3447 | err = mFlite.stream(false); | |
3448 | CHECK_ERR(err, ("nativeGetYUVSnapshot: error, mFlite.stream")); | |
3449 | ||
3450 | #ifdef SAVE_DUMP | |
3451 | #if 0 | |
3452 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], | |
3453 | mPictureBufDummy[0].size.extS[0], "/data/dump_jpeg_only.jpg"); | |
3454 | #endif | |
3455 | #endif | |
3456 | ||
3457 | if (!allocateHDRHeap()) { | |
3458 | ALOGE("getEncodedJpeg: error, allocateSnapshotHeap"); | |
3459 | return false; | |
3460 | } | |
3461 | memcpy((char *)mHDRHeap->data, (uint8_t *)mPictureBufDummy[0].virt.extP[0], mHDRFrameSize); | |
3462 | ALOGD("%s: mHDRHeap memcpy end size (mHDRFrameSize) = %d", __func__, mHDRFrameSize); | |
3463 | //mGetMemoryCb(mPictureBufDummy[0].fd.extFd[0], mHDRFrameSize, 1, mCallbackCookie); | |
3464 | ||
3465 | #if 0 | |
3466 | err = getYUV(numF); | |
3467 | if (mCaptureMode == RUNNING_MODE_HDR) { | |
3468 | if (numF == 1) { | |
3469 | struct record_heap *scrab_heap = (struct record_heap *)mHDRHeap->data; | |
3470 | ||
3471 | scrab_heap[3].type = kMetadataBufferTypeCameraSource; | |
3472 | scrab_heap[3].buf_index = 3; | |
3473 | scrab_heap[3].reserved = (uint32_t)mPictureBufDummy[0].virt.extP[0]; | |
3474 | ALOGE("Scrab memory set to ION. scrab_heap[3].reserved = %08x", scrab_heap[3].reserved); | |
3475 | } | |
3476 | } | |
3477 | CHECK_ERR(err, ("nativeGetYUVSnapshot: error, getYUV")); | |
3478 | #endif | |
3479 | ALOGD("nativeGetYUVSnapshot X"); | |
3480 | return true; | |
3481 | } | |
3482 | ||
3483 | /* --3 */ | |
3484 | bool SecCameraHardware::nativeStartSnapshot() | |
3485 | { | |
3486 | CLOGV("DEBUG (%s) : in ",__FUNCTION__); | |
3487 | ||
3488 | int err; | |
3489 | int nBufs = 1; | |
3490 | int i = 0; | |
3491 | ExynosBuffer nullBuf; | |
3492 | ||
3493 | cam_pixel_format captureFormat = CAM_PIXEL_FORMAT_YUV422I; | |
3494 | ||
3495 | #if FRONT_ZSL | |
3496 | if (mCameraId == CAMERA_ID_FRONT && ISecCameraHardware::mFullPreviewRunning) | |
3497 | return true; | |
3498 | #endif | |
3499 | ||
3500 | err = mFlite.startCapture(&mFLiteCaptureSize, captureFormat, nBufs, START_CAPTURE_YUV_MAIN); | |
3501 | CHECK_ERR(err, ("nativeStartSnapshot: error, mFlite.start")); | |
3502 | ||
3503 | /* | |
3504 | TODO : The only one buffer should be used | |
3505 | between mPictureBuf and mPictureBufDummy in case of jpeg capture | |
3506 | */ | |
3507 | /* For picture buffer */ | |
3508 | #ifdef USE_NV21_CALLBACK | |
3509 | if(mPictureFormat == CAM_PIXEL_FORMAT_YUV420SP) { | |
3510 | getAlignedYUVSize(mPictureFormat, mPictureSize.width, mPictureSize.height, &mPictureBuf); | |
3511 | mPictureBuf.size.extS[0] = mPictureBuf.size.extS[0] + mPictureBuf.size.extS[1]; | |
3512 | mPictureBuf.size.extS[1] = 0; | |
3513 | } | |
3514 | else | |
3515 | #endif | |
3516 | { | |
3517 | getAlignedYUVSize(captureFormat, mPictureSize.width, mPictureSize.height, &mPictureBuf); | |
3518 | } | |
3519 | ||
3520 | if (allocMem(mIonCameraClient, &mPictureBuf, 1 << 1) == false) { | |
3521 | CLOGE("ERR(%s):mPictureBuf allocMem() fail", __func__); | |
3522 | return UNKNOWN_ERROR; | |
3523 | } else { | |
3524 | CLOGV("DEBUG(%s): mPictureBuf allocMem adr(%p), size(%d), ion(%d) w/h(%d/%d)", __FUNCTION__, | |
3525 | mPictureBuf.virt.extP[0], mPictureBuf.size.extS[0], mIonCameraClient, | |
3526 | mPictureSize.width, mPictureSize.height); | |
3527 | memset(mPictureBuf.virt.extP[0], 0, mPictureBuf.size.extS[0]); | |
3528 | } | |
3529 | ||
3530 | #ifdef USE_USERPTR | |
3531 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3532 | getAlignedYUVSize(captureFormat, mFLiteCaptureSize.width, mFLiteCaptureSize.height, &mPictureBufDummy[i]); | |
3533 | if (allocMem(mIonCameraClient, &mPictureBufDummy[i], 1 << 1) == false) { | |
3534 | CLOGE("ERR(%s):mPictureBuf dummy allocMem() fail", __func__); | |
3535 | return UNKNOWN_ERROR; | |
3536 | } else { | |
3537 | CLOGD("DEBUG(%s): mPictureBuf dummy allocMem adr(%p), size(%d), ion(%d) w/h(%d/%d)", __FUNCTION__, | |
3538 | mPictureBufDummy[i].virt.extP[0], mPictureBufDummy[i].size.extS[0], mIonCameraClient, | |
3539 | mPictureSize.width, mPictureSize.height); | |
3540 | memset(mPictureBufDummy[i].virt.extP[0], 0, mPictureBufDummy[i].size.extS[0]); | |
3541 | } | |
3542 | } | |
3543 | #else | |
3544 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3545 | err = mFlite.querybuf2(i, mFliteNode.planes, &mPictureBufDummy[i]); | |
3546 | CHECK_ERR_N(err, ("nativeStartPreviewZoom: error, mFlite.querybuf2")); | |
3547 | } | |
3548 | #endif | |
3549 | ||
3550 | /* qbuf dummy buffer for skip */ | |
3551 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3552 | err = mFlite.qbufForCapture(&mPictureBufDummy[i], i); | |
3553 | CHECK_ERR(err, ("nativeStartSnapshot: error, mFlite.qbuf(%d)", i)); | |
3554 | } | |
3555 | ||
3556 | #if !defined(USE_USERPTR) | |
3557 | /* export FD */ | |
3558 | for (int i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3559 | err = mFlite.expBuf(i, mFliteNode.planes, &mPictureBufDummy[i]); | |
3560 | CHECK_ERR_N(err, ("nativeStartSnapshot: error, mFlite.expBuf")); | |
3561 | } | |
3562 | #endif | |
3563 | ||
3564 | err = mFlite.stream(true); | |
3565 | CHECK_ERR(err, ("nativeStartSnapshot: error, mFlite.stream")); | |
3566 | ||
3567 | CLOGV("DEBUG (%s) : out ",__FUNCTION__); | |
3568 | return true; | |
3569 | } | |
3570 | ||
3571 | bool SecCameraHardware::nativeGetPostview(int numF) | |
3572 | { | |
3573 | int err; | |
3574 | int i = 0; | |
3575 | ||
3576 | ALOGD("nativeGetPostview E"); | |
3577 | retry: | |
3578 | ||
3579 | /* | |
3580 | * Put here if Capture Start Command code is needed in addition */ | |
3581 | #if 0 | |
3582 | if (mCameraId == CAMERA_ID_BACK) { | |
3583 | err = mFlite.sctrl(CAM_CID_POSTVIEW_TRANSFER, numF); | |
3584 | CHECK_ERR(err, ("nativeGetPostview: error, capture start")); | |
3585 | } | |
3586 | #endif | |
3587 | /* | |
3588 | * Waiting for frame(stream) to be input. | |
3589 | * ex) poll() | |
3590 | */ | |
3591 | err = mFlite.polling(); | |
3592 | if (CC_UNLIKELY(err <= 0)) { | |
3593 | #ifdef ISP_LOGWRITE | |
3594 | ALOGE("polling error - SEC_ISP_DBG_logwrite = %s", __func__); | |
3595 | SEC_ISP_DBG_logwrite(); | |
3596 | #endif | |
3597 | ALOGE("nativeGetPostview: error, mFlite.polling"); | |
3598 | return false; | |
3599 | } | |
3600 | ||
3601 | /* | |
3602 | * Get out a filled buffer from driver's queue. */ | |
3603 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3604 | int ret = mFlite.dqbufForCapture(&mPictureBufDummy[i]); | |
3605 | ALOGV("DEBUG(%s) (%d): dqbufForCapture dq(%d), ret = %d", __FUNCTION__, __LINE__, i, ret); | |
3606 | } | |
3607 | ||
3608 | /* | |
3609 | * Stop capturing stream(or frame) data. */ | |
3610 | err = mFlite.stream(false); | |
3611 | CHECK_ERR(err, ("nativeGetPostview: error, mFlite.stream")); | |
3612 | ||
3613 | if (mCameraId == CAMERA_ID_BACK) { | |
3614 | err = getPostview(numF); | |
3615 | CHECK_ERR(err, ("nativeGetPostview: error, getPostview")); | |
3616 | } | |
3617 | ||
3618 | ALOGD("nativeGetPostview X"); | |
3619 | return true; | |
3620 | } | |
3621 | ||
3622 | /* --4 */ | |
3623 | bool SecCameraHardware::nativeGetSnapshot(int numF, int *postviewOffset) | |
3624 | { | |
3625 | CLOGV("DEBUG (%s) : in ",__FUNCTION__); | |
3626 | ||
3627 | int err; | |
3628 | int i = 0; | |
3629 | bool retryDone = false; | |
3630 | ||
3631 | #if FRONT_ZSL | |
3632 | if (mCameraId == CAMERA_ID_FRONT && ISecCameraHardware::mFullPreviewRunning) | |
3633 | return getZSLJpeg(); | |
3634 | #endif | |
3635 | ||
3636 | retry: | |
3637 | ||
3638 | /* | |
3639 | * Waiting for frame(stream) to be input. | |
3640 | * ex) poll() | |
3641 | */ | |
3642 | err = mFlite.polling(); | |
3643 | if (CC_UNLIKELY(err <= 0)) { | |
3644 | #ifdef DEBUG_CAPTURE_RETRY | |
3645 | LOG_FATAL("nativeGetSnapshot: fail to get a frame!"); | |
3646 | #else | |
3647 | if (!retryDone) { | |
3648 | CLOGW("nativeGetSnapshot: warning. Reset the camera device"); | |
3649 | mFlite.stream(false); | |
3650 | nativeStopSnapshot(); | |
3651 | mFlite.reset(); | |
3652 | nativeStartSnapshot(); | |
3653 | retryDone = true; | |
3654 | goto retry; | |
3655 | } | |
3656 | CLOGE("nativeGetSnapshot: error, mFlite.polling"); | |
3657 | #endif | |
3658 | return false; | |
3659 | } | |
3660 | CLOGV("DEBUG(%s): (%d) nativeGetSnapshot dq start", __FUNCTION__, __LINE__); | |
3661 | ||
3662 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3663 | if(i > 0) { | |
3664 | err = mFlite.polling(); | |
3665 | } | |
3666 | int ret = mFlite.dqbufForCapture(&mPictureBufDummy[i]); | |
3667 | CLOGD("DEBUG(%s) (%d): dqbufForCapture dq(%d), ret = %d", __FUNCTION__, __LINE__, i, ret); | |
3668 | } | |
3669 | ||
3670 | #ifdef SAVE_DUMP | |
3671 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], | |
3672 | mPictureBufDummy[0].size.extS[0], "/data/dump_raw.yuv"); | |
3673 | #endif | |
3674 | ||
3675 | /* Stop capturing stream(or frame) data. */ | |
3676 | err = mFlite.stream(false); | |
3677 | CHECK_ERR(err, ("nativeGetSnapshot: error, mFlite.stream")); | |
3678 | ||
3679 | /* last capture was stored dummy buffer due to zoom. | |
3680 | * and zoom applied to capture image by fimc */ | |
3681 | err = nativeCSCCapture(&mPictureBufDummy[i-1], &mPictureBuf); | |
3682 | CHECK_ERR_N(err, ("nativeGetSnapshot: error, nativeCSCCapture")); | |
3683 | ||
3684 | #ifdef SAVE_DUMP | |
3685 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], | |
3686 | mPictureBufDummy[0].size.extS[0], "/data/dump_jpeg_only.jpg"); | |
3687 | #endif | |
3688 | #ifdef USE_NV21_CALLBACK | |
3689 | if (mPictureFormat == CAM_PIXEL_FORMAT_YUV420SP) { | |
3690 | mPictureFrameSize = mPictureBuf.size.extS[0]; | |
3691 | if (!allocateSnapshotHeap()) { | |
3692 | ALOGE("%s: error , allocateSnapshotHeap", __func__); | |
3693 | return false; | |
3694 | } | |
3695 | memcpy((unsigned char *)mJpegHeap->data, mPictureBuf.virt.extP[0], mPictureBuf.size.extS[0]); | |
3696 | } | |
3697 | else | |
3698 | #endif | |
3699 | { | |
3700 | if (numF == 0 && mCaptureMode == RUNNING_MODE_RAW ) { //(mCaptureMode == RUNNING_MODE_RAW ) { | |
3701 | int jpegSize; | |
3702 | nativeGetParameters(CAM_CID_JPEG_MAIN_SIZE, &jpegSize ); | |
3703 | mPictureFrameSize = (uint32_t)jpegSize; | |
3704 | } else { | |
3705 | /* Get Jpeg image including EXIF. */ | |
3706 | if (mCameraId == CAMERA_ID_BACK) | |
3707 | err = getJpegOnBack(postviewOffset); | |
3708 | else | |
3709 | err = getJpegOnFront(postviewOffset); | |
3710 | ||
3711 | CHECK_ERR(err, ("nativeGetSnapshot: error, getJpeg")); | |
3712 | } | |
3713 | ||
3714 | #if 0 | |
3715 | if ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE) || (mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME)) { | |
3716 | int copySize = mRawFrameSize; | |
3717 | if (mPictureBuf.size.extS[0] < copySize) | |
3718 | copySize = mPictureBuf.size.extS[0]; | |
3719 | ||
3720 | memcpy((char *)mRawHeap->data, mPictureBuf.virt.extP[0], copySize); | |
3721 | ALOGV("DEBUG(%s): (%d) copied mRawHeap", __FUNCTION__, __LINE__); | |
3722 | } | |
3723 | #endif | |
3724 | ||
3725 | #ifdef DUMP_JPEG_FILE | |
3726 | ExynosBuffer jpegBuf; | |
3727 | CLOGV("DEBUG(%s): (%d) %d", __FUNCTION__, __LINE__, mPictureFrameSize); | |
3728 | jpegBuf.size.extS[0] = mPictureFrameSize; | |
3729 | jpegBuf.virt.extP[0] = (char *)mJpegHeap->data; | |
3730 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3731 | mSaveDump("/data/camera_capture%d.jpg", &jpegBuf, 1); | |
3732 | CLOGV("DEBUG(%s): (%d)", __FUNCTION__, __LINE__); | |
3733 | #endif | |
3734 | } | |
3735 | CLOGV("DEBUG (%s) : out ",__FUNCTION__); | |
3736 | return true; | |
3737 | } | |
3738 | ||
3739 | bool SecCameraHardware::nativeStartDualCapture(int numF) | |
3740 | { | |
3741 | int err; | |
3742 | ||
3743 | ALOGD("nativeStartDualCapture E - frame: %d", numF); | |
3744 | err = mFlite.sctrl(V4L2_CID_CAMERA_SET_DUAL_CAPTURE, numF); | |
3745 | CHECK_ERR(err, ("nativeStartDualCapture: error, capture start")); | |
3746 | ||
3747 | ALOGD("nativeStartDualCapture X"); | |
3748 | ||
3749 | return true; | |
3750 | } | |
3751 | ||
3752 | int SecCameraHardware::getYUV(int fnum) | |
3753 | { | |
3754 | ALOGE("%s: start, fnum = %d", __func__, fnum); | |
3755 | ||
3756 | struct record_heap *heap = (struct record_heap *)mHDRHeap->data; | |
3757 | int nAddr; | |
3758 | ||
3759 | nAddr = mPictureBufDummy[0].phys.extP[0]; | |
3760 | ||
3761 | heap[fnum - 1].type = kMetadataBufferTypeCameraSource; | |
3762 | heap[fnum - 1].y = nAddr; | |
3763 | heap[fnum - 1].cbcr = nAddr + (mRawSize.width * mRawSize.height); | |
3764 | heap[fnum - 1].buf_index = fnum - 1; | |
3765 | /* | |
3766 | Just 2 buffer of ION memories are allocated for HDR. | |
3767 | Fimc0 memory is used for last one buffer to reduce | |
3768 | the number of ION memory to 2 from 3. | |
3769 | In case of 16M camera, 64M HDR memory is needed instead of 96M. | |
3770 | */ | |
3771 | ||
3772 | ALOGE("Fnum = %d, ION memory using", fnum); | |
3773 | #ifdef SUPPORT_64BITS | |
3774 | heap[fnum - 1].reserved = (unsigned long)mPictureBufDummy[0].virt.extP[0]; | |
3775 | #else | |
3776 | heap[fnum - 1].reserved = (uint32_t)mPictureBufDummy[0].virt.extP[0]; | |
3777 | #endif | |
3778 | #if 0 | |
3779 | if (fnum <= 2) { | |
3780 | ALOGE("Fnum = %d, ION memory using", fnum); | |
3781 | heap[fnum - 1].reserved = (uint32_t*)mPictureBufDummy[0].virt.extP[0]; | |
3782 | } else { | |
3783 | uint32_t last_frame = (uint32_t)mRawHeap->base(); | |
3784 | heap[fnum - 1].reserved = last_frame; | |
3785 | ALOGE("Fnum = %d, Fimc0 memory using", fnum); | |
3786 | } | |
3787 | #endif | |
3788 | ||
3789 | ALOGE("getYUV hdrheappointer(ion) : %x, mHDRFrameSize = %d", heap[fnum - 1].reserved, mHDRFrameSize); | |
3790 | ||
3791 | /* Note : Sensor return main image size, not only JPEG but also YUV. */ | |
3792 | //err = mFlite.gctrl(V4L2_CID_CAM_JPEG_MAIN_SIZE, &yuvSize); | |
3793 | //CHECK_ERR(err, ("getYUV: error %d, jpeg size", err)); | |
3794 | //mRawFrameSize = yuvSize; | |
3795 | mRawFrameSize = mRawSize.width*mRawSize.height*2; /* yuv422I */ | |
3796 | ||
3797 | /* picture frame size is should be calculated before call allocatePostviewHeap */ | |
3798 | #ifdef SUPPORT_64BITS | |
3799 | char *postview = (char *)mPictureBufDummy[0].virt.extP[0]; | |
3800 | memcpy((char *)(unsigned long)heap[fnum - 1].reserved , postview, mRawFrameSize); | |
3801 | #else | |
3802 | uint8_t *postview = (uint8_t *)mPictureBufDummy[0].virt.extP[0]; | |
3803 | memcpy((void*)heap[fnum - 1].reserved , postview, mRawFrameSize); | |
3804 | #endif | |
3805 | #if 0 /* FIMC output data */ | |
3806 | if (fnum == 1) | |
3807 | save_dump_path(postview, mRawFrameSize, "/data/dump_HDR1.yuv"); | |
3808 | if (fnum == 2) | |
3809 | save_dump_path(postview, mRawFrameSize, "/data/dump_HDR2.yuv"); | |
3810 | if (fnum == 3) | |
3811 | save_dump_path(postview, mRawFrameSize, "/data/dump_HDR3.yuv"); | |
3812 | #endif | |
3813 | #if 0 /* ION memory data */ | |
3814 | if (fnum == 1) | |
3815 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], mHDRFrameSize, "/data/dump_HDR1.yuv"); | |
3816 | if (fnum == 2) | |
3817 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], mHDRFrameSize, "/data/dump_HDR2.yuv"); | |
3818 | if (fnum == 3) | |
3819 | save_dump_path((uint8_t*)mPictureBufDummy[0].virt.extP[0], mHDRFrameSize, "/data/dump_HDR3.yuv"); | |
3820 | #endif | |
3821 | #if 0 /* ION memory data through mHDRHeap pointer */ | |
3822 | if (fnum == 1) | |
3823 | save_dump_path((uint8_t*)(((struct record_heap *)mHDRHeap->data)[fnum - 1].reserved), mHDRFrameSize, "/data/dump_HDR1.yuv"); | |
3824 | if (fnum == 2) | |
3825 | save_dump_path((uint8_t*)(((struct record_heap *)mHDRHeap->data)[fnum - 1].reserved), mHDRFrameSize, "/data/dump_HDR2.yuv"); | |
3826 | if (fnum == 3) | |
3827 | save_dump_path((uint8_t*)(((struct record_heap *)mHDRHeap->data)[fnum - 1].reserved), mHDRFrameSize, "/data/dump_HDR3.yuv"); | |
3828 | #endif | |
3829 | ||
3830 | ALOGD("%s: mPostviewHeap memcpy end size (mRawFrameSize) = %d", __func__, mRawFrameSize); | |
3831 | ||
3832 | return 0; | |
3833 | } | |
3834 | ||
3835 | #ifndef RCJUNG | |
3836 | int SecCameraHardware::getOneYUV() | |
3837 | { | |
3838 | ALOGE("%s: start", __func__); | |
3839 | ||
3840 | int yuvSize = 0; | |
3841 | int err; | |
3842 | ||
3843 | /* Note : Sensor return main image size, not only JPEG but also YUV. */ | |
3844 | err = mFlite.gctrl(V4L2_CID_CAM_JPEG_MAIN_SIZE, &yuvSize); | |
3845 | CHECK_ERR(err, ("getYUV: error %d, jpeg size", err)); | |
3846 | ||
3847 | /* picture frame size is should be calculated before call allocateYUVHeap */ | |
3848 | mRawSize = mPictureSize; | |
3849 | mRawFrameSize = mRawSize.width * mRawSize.height * 2; /* yuv422I */ | |
3850 | ||
3851 | setExifChangedAttribute(); | |
3852 | ||
3853 | uint8_t *YUVmain = (uint8_t *)mPictureBufDummy[0].virt.extP[0]; | |
3854 | ||
3855 | if (!allocateYUVHeap()) { | |
3856 | ALOGE("getYUV: error, allocateYUVHeap"); | |
3857 | return false; | |
3858 | } | |
3859 | ||
3860 | memcpy(mYUVHeap->data, YUVmain, mRawFrameSize); | |
3861 | ||
3862 | ALOGD("%s: mYUVHeap memcpy end size (mRawFrameSize) = %d", __func__, mRawFrameSize); | |
3863 | ||
3864 | return true; | |
3865 | } | |
3866 | #endif | |
3867 | ||
3868 | int SecCameraHardware::getPostview(int num) | |
3869 | { | |
3870 | ALOGD("%s: start", __func__); | |
3871 | ||
3872 | /* picture frame size is should be calculated before call allocatePostviewHeap */ | |
3873 | if (!allocatePostviewHeap()) { | |
3874 | ALOGE("getPostview: error, allocatePostviewHeap"); | |
3875 | return UNKNOWN_ERROR; | |
3876 | } | |
3877 | ||
3878 | uint8_t *postview = (uint8_t *)mPictureBufDummy[0].virt.extP[0]; | |
3879 | ||
3880 | memcpy((char *)mPostviewHeap->data, postview, mPostviewFrameSize); | |
3881 | ||
3882 | #ifdef SAVE_DUMP | |
3883 | #if 0 | |
3884 | char *fileName = NULL; | |
3885 | sprintf(fileName, "%s_%d.yuv%c", "/data/dump_postview_yuv", num, NULL); | |
3886 | ALOGD("getPostview: dump postview image = %s", fileName); | |
3887 | save_dump_path((uint8_t *)mPictureBufDummy[0].virt.extP[0], mPictureBufDummy[0].size.extS[0], fileName); | |
3888 | #endif | |
3889 | #endif | |
3890 | ||
3891 | ALOGE("%s: Postview memcpy end size = %d", __func__, mPostviewFrameSize); | |
3892 | ||
3893 | return 0; | |
3894 | } | |
3895 | ||
3896 | inline int SecCameraHardware::getJpegOnBack(int *postviewOffset) | |
3897 | { | |
3898 | status_t ret; | |
3899 | ||
3900 | #if !defined(REAR_USE_YUV_CAPTURE) | |
3901 | if (mCaptureMode == RUNNING_MODE_RAW) | |
3902 | return internalGetJpegForRawWithZoom(postviewOffset); | |
3903 | else | |
3904 | return internalGetJpegForSocYuvWithZoom(postviewOffset); | |
3905 | #else | |
3906 | if (mEnableDZoom) | |
3907 | ret = internalGetJpegForSocYuvWithZoom(postviewOffset); | |
3908 | else | |
3909 | ret = internalGetJpegForSocYuv(postviewOffset); | |
3910 | ||
3911 | return ret; | |
3912 | #endif | |
3913 | } | |
3914 | ||
3915 | inline int SecCameraHardware::getJpegOnFront(int *postviewOffset) | |
3916 | { | |
3917 | status_t ret; | |
3918 | ret = internalGetJpegForSocYuvWithZoom(postviewOffset); | |
3919 | return ret; | |
3920 | } | |
3921 | ||
3922 | void SecCameraHardware::nativeStopSnapshot() | |
3923 | { | |
3924 | ExynosBuffer nullBuf; | |
3925 | int i = 0; | |
3926 | ||
3927 | if (mRawHeap != NULL) { | |
3928 | mRawHeap->release(mRawHeap); | |
3929 | mRawHeap = 0; | |
3930 | } | |
3931 | ||
3932 | freeMem(&mPictureBuf); | |
3933 | ||
3934 | #ifdef USE_USERPTR | |
3935 | /* capture buffer free */ | |
3936 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3937 | freeMem(&mPictureBufDummy[i]); | |
3938 | mPictureBufDummy[i] = nullBuf; | |
3939 | } | |
3940 | #else | |
3941 | for (i = 0; i < SKIP_CAPTURE_CNT; i++) { | |
3942 | for (int j = 0; j < mFliteNode.planes; j++) { | |
3943 | munmap((void *)mPictureBufDummy[i].virt.extP[j], | |
3944 | mPictureBufDummy[i].size.extS[j]); | |
3945 | ion_free(mPictureBufDummy[i].fd.extFd[j]); | |
3946 | } | |
3947 | mPictureBufDummy[i] = nullBuf; | |
3948 | } | |
3949 | ||
3950 | if (mFlite.reqBufZero(&mFliteNode) < 0) | |
3951 | ALOGE("ERR(%s): mFlite.reqBufZero() fail", __func__); | |
3952 | #endif | |
3953 | ||
3954 | ||
3955 | mPictureBuf = nullBuf; | |
3956 | CLOGD("DEBUG (%s) : out ",__FUNCTION__); | |
3957 | } | |
3958 | ||
3959 | bool SecCameraHardware::nativeSetAutoFocus() | |
3960 | { | |
3961 | ALOGV("nativeSetAutofocus E"); | |
3962 | ||
3963 | int i, waitUs = 10000, tryCount = (900 * 1000) / waitUs; | |
3964 | for (i = 1; i <= tryCount; i++) { | |
3965 | if (mPreviewInitialized) | |
3966 | break; | |
3967 | else | |
3968 | usleep(waitUs); | |
3969 | ||
3970 | if (!(i % 40)) | |
3971 | ALOGD("AF: waiting for preview\n"); | |
3972 | } | |
3973 | ||
3974 | if (CC_UNLIKELY(i > tryCount)) | |
3975 | ALOGI("cancelAutoFocus: cancel timeout"); | |
3976 | ||
3977 | if (!IsAutofocusRunning()) { | |
3978 | ALOGW("nativeSetAutofocus X: AF Cancel is called"); | |
3979 | return true; | |
3980 | } | |
3981 | ||
3982 | int err = mFlite.sctrl(V4L2_CID_CAM_SINGLE_AUTO_FOCUS, AUTO_FOCUS_ON); | |
3983 | CHECK_ERR(err, ("nativeSetAutofocus X: error, mFlite.sctrl")) | |
3984 | ||
3985 | ALOGV("nativeSetAutofocus X"); | |
3986 | ||
3987 | return true; | |
3988 | } | |
3989 | ||
3990 | int SecCameraHardware::nativeGetPreAutoFocus() | |
3991 | { | |
3992 | ALOGV("nativeGetPreAutofocus E"); | |
3993 | int status, i; | |
3994 | ||
3995 | const int tryCount = 500; | |
3996 | ||
3997 | usleep(150000); | |
3998 | ||
3999 | for (i = 0 ; i < tryCount ; i ++) { | |
4000 | int err; | |
4001 | err = mFlite.gctrl(V4L2_CID_CAM_AUTO_FOCUS_RESULT, &status); | |
4002 | CHECK_ERR_N(err, ("nativeGetPreAutoFocus: error %d", err)); | |
4003 | if (status != 0x0) | |
4004 | break; | |
4005 | usleep(10000); | |
4006 | } | |
4007 | ||
4008 | ALOGV("nativeGetPreAutofocus X %d", status); | |
4009 | return status; | |
4010 | } | |
4011 | ||
4012 | int SecCameraHardware::nativeGetAutoFocus() | |
4013 | { | |
4014 | ALOGV("nativeGetAutofocus E"); | |
4015 | int status, i; | |
4016 | /* AF completion takes more much time in case of night mode. | |
4017 | So be careful if you modify tryCount. */ | |
4018 | const int tryCount = 300; | |
4019 | ||
4020 | for (i = 0; i < tryCount; i ++) { | |
4021 | int err; | |
4022 | usleep(20000); | |
4023 | err = mFlite.gctrl(V4L2_CID_CAMERA_AUTO_FOCUS_DONE, &status); | |
4024 | CHECK_ERR_N(err, ("nativeGetAutofocus: error %d", err)); | |
4025 | if ((status != 0x0) && (status != 0x08)) { | |
4026 | break; | |
4027 | } | |
4028 | } | |
4029 | ||
4030 | if (i == tryCount) | |
4031 | ALOGE("nativeGetAutoFocus: error, AF hasn't been finished yet."); | |
4032 | ||
4033 | ALOGV("nativeGetAutofocus X"); | |
4034 | return status; | |
4035 | } | |
4036 | ||
4037 | status_t SecCameraHardware::nativeCancelAutoFocus() | |
4038 | { | |
4039 | ALOGV("nativeCancelAutofocus E1"); | |
4040 | //#if NOTDEFINED | |
4041 | // int err = mFlite.sctrl(V4L2_CID_CAMERA_CANCEL_AUTO_FOCUS, 0); | |
4042 | int err = mFlite.sctrl(V4L2_CID_CAM_SINGLE_AUTO_FOCUS, AUTO_FOCUS_OFF); | |
4043 | CHECK_ERR(err, ("nativeCancelAutofocus: error, mFlite.sctrl")) | |
4044 | //#endif | |
4045 | ALOGV("nativeCancelAutofocus X2"); | |
4046 | return NO_ERROR; | |
4047 | } | |
4048 | ||
4049 | inline status_t SecCameraHardware::nativeSetParameters(cam_control_id id, int value, bool recordingMode) | |
4050 | { | |
4051 | int err = NO_ERROR; | |
4052 | ||
4053 | if (CC_LIKELY(!recordingMode)) | |
4054 | err = mFlite.sctrl(id, value); | |
4055 | else { | |
4056 | if (mCameraId == CAMERA_ID_FRONT) | |
4057 | err = mFlite.sctrl(id, value); | |
4058 | } | |
4059 | ||
4060 | return NO_ERROR; | |
4061 | } | |
4062 | ||
4063 | inline status_t SecCameraHardware::nativeGetParameters(cam_control_id id, int *value, bool recordingMode) | |
4064 | { | |
4065 | int err = NO_ERROR; | |
4066 | ||
4067 | if (CC_LIKELY(!recordingMode)) | |
4068 | err = mFlite.gctrl(id, value); | |
4069 | ||
4070 | CHECK_ERR_N(err, ("nativeGetParameters X: error %d", err)) | |
4071 | ||
4072 | return NO_ERROR; | |
4073 | } | |
4074 | ||
4075 | void SecCameraHardware::setExifFixedAttribute() | |
4076 | { | |
4077 | char property[PROPERTY_VALUE_MAX]; | |
4078 | ||
4079 | CLEAR(mExifInfo); | |
4080 | /* 0th IFD TIFF Tags */ | |
4081 | /* Maker */ | |
4082 | property_get("ro.product.manufacturer", property, Exif::DEFAULT_MAKER); | |
4083 | strncpy((char *)mExifInfo.maker, property, | |
4084 | sizeof(mExifInfo.maker) - 1); | |
4085 | mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0'; | |
4086 | ||
4087 | /* Model */ | |
4088 | property_get("ro.product.model", property, Exif::DEFAULT_MODEL); | |
4089 | strncpy((char *)mExifInfo.model, property, | |
4090 | sizeof(mExifInfo.model) - 1); | |
4091 | mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0'; | |
4092 | ||
4093 | /* Software */ | |
4094 | property_get("ro.build.PDA", property, Exif::DEFAULT_SOFTWARE); | |
4095 | strncpy((char *)mExifInfo.software, property, | |
4096 | sizeof(mExifInfo.software) - 1); | |
4097 | mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0'; | |
4098 | ||
4099 | /* YCbCr Positioning */ | |
4100 | mExifInfo.ycbcr_positioning = Exif::DEFAULT_YCBCR_POSITIONING; | |
4101 | ||
4102 | /* 0th IFD Exif Private Tags */ | |
4103 | /* F Number */ | |
4104 | if (mCameraId == CAMERA_ID_BACK) { | |
4105 | mExifInfo.fnumber.num = Exif::DEFAULT_BACK_FNUMBER_NUM; | |
4106 | mExifInfo.fnumber.den = Exif::DEFAULT_BACK_FNUMBER_DEN; | |
4107 | } else { | |
4108 | mExifInfo.fnumber.num = Exif::DEFAULT_FRONT_FNUMBER_NUM; | |
4109 | mExifInfo.fnumber.den = Exif::DEFAULT_FRONT_FNUMBER_DEN; | |
4110 | } | |
4111 | ||
4112 | /* Exposure Program */ | |
4113 | mExifInfo.exposure_program = Exif::DEFAULT_EXPOSURE_PROGRAM; | |
4114 | ||
4115 | /* Exif Version */ | |
4116 | memcpy(mExifInfo.exif_version, Exif::DEFAULT_EXIF_VERSION, sizeof(mExifInfo.exif_version)); | |
4117 | ||
4118 | /* Aperture */ | |
4119 | double av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); | |
4120 | mExifInfo.aperture.num = av*Exif::DEFAULT_APEX_DEN; | |
4121 | mExifInfo.aperture.den = Exif::DEFAULT_APEX_DEN; | |
4122 | ||
4123 | /* Maximum lens aperture */ | |
4124 | mExifInfo.max_aperture.num = mExifInfo.aperture.num; | |
4125 | mExifInfo.max_aperture.den = mExifInfo.aperture.den; | |
4126 | ||
4127 | /* Lens Focal Length */ | |
4128 | if (mCameraId == CAMERA_ID_BACK) { | |
4129 | mExifInfo.focal_length.num = Exif::DEFAULT_BACK_FOCAL_LEN_NUM; | |
4130 | mExifInfo.focal_length.den = Exif::DEFAULT_BACK_FOCAL_LEN_DEN; | |
4131 | } else { | |
4132 | mExifInfo.focal_length.num = Exif::DEFAULT_FRONT_FOCAL_LEN_NUM; | |
4133 | mExifInfo.focal_length.den = Exif::DEFAULT_FRONT_FOCAL_LEN_DEN; | |
4134 | } | |
4135 | ||
4136 | /* Lens Focal Length in 35mm film*/ | |
4137 | if (mCameraId == CAMERA_ID_BACK) { | |
4138 | mExifInfo.focal_35mm_length = Exif::DEFAULT_BACK_FOCAL_LEN_35mm; | |
4139 | } else { | |
4140 | mExifInfo.focal_35mm_length = Exif::DEFAULT_FRONT_FOCAL_LEN_35mm; | |
4141 | } | |
4142 | ||
4143 | /* Color Space information */ | |
4144 | mExifInfo.color_space = Exif::DEFAULT_COLOR_SPACE; | |
4145 | ||
4146 | /* Exposure Mode */ | |
4147 | mExifInfo.exposure_mode = Exif::DEFAULT_EXPOSURE_MODE; | |
4148 | ||
4149 | /* Sensing Method */ | |
4150 | mExifInfo.sensing_method = Exif::DEFAULT_SENSING_METHOD; | |
4151 | ||
4152 | /* 0th IFD GPS Info Tags */ | |
4153 | unsigned char gps_version[4] = {0x02, 0x02, 0x00, 0x00}; | |
4154 | memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version)); | |
4155 | ||
4156 | /* 1th IFD TIFF Tags */ | |
4157 | mExifInfo.compression_scheme = Exif::DEFAULT_COMPRESSION; | |
4158 | mExifInfo.x_resolution.num = Exif::DEFAULT_RESOLUTION_NUM; | |
4159 | mExifInfo.x_resolution.den = Exif::DEFAULT_RESOLUTION_DEN; | |
4160 | mExifInfo.y_resolution.num = Exif::DEFAULT_RESOLUTION_NUM; | |
4161 | mExifInfo.y_resolution.den = Exif::DEFAULT_RESOLUTION_DEN; | |
4162 | mExifInfo.resolution_unit = Exif::DEFAULT_RESOLUTION_UNIT; | |
4163 | } | |
4164 | ||
4165 | void SecCameraHardware::setExifChangedAttribute() | |
4166 | { | |
4167 | /* 0th IFD TIFF Tags */ | |
4168 | /* Width, Height */ | |
4169 | if (!mMovieMode) { | |
4170 | mExifInfo.width = mPictureSize.width; | |
4171 | mExifInfo.height = mPictureSize.height; | |
4172 | } else { | |
4173 | mExifInfo.width = mVideoSize.width; | |
4174 | mExifInfo.height = mVideoSize.height; | |
4175 | } | |
4176 | ||
4177 | /* ISP firmware version */ | |
4178 | #ifdef SENSOR_FW_GET_FROM_FILE | |
4179 | char *camera_fw = NULL; | |
4180 | char *savePtr = NULL; | |
4181 | char sensor_fw[12]; | |
4182 | size_t sizes = sizeof(sensor_fw) / sizeof(sensor_fw[0]); | |
4183 | camera_fw = strtok_r((char *)getSensorFWFromFile(sensor_fw, sizes, mCameraId), " ", &savePtr); | |
4184 | strncpy((char *)mExifInfo.unique_id, camera_fw, sizeof(mExifInfo.unique_id) - 1); | |
4185 | ALOGD("Exif: unique_id = %s", mExifInfo.unique_id); | |
4186 | #else | |
4187 | char unique_id[12] = {'\0',}; | |
4188 | mFlite.gctrl(V4L2_CID_CAM_SENSOR_FW_VER, unique_id, 12); | |
4189 | ALOGD("Exif: unique_id = %s", unique_id); | |
4190 | strncpy((char *)mExifInfo.unique_id, unique_id, sizeof(mExifInfo.unique_id) - 1); | |
4191 | mExifInfo.unique_id[sizeof(mExifInfo.unique_id) - 1] = '\0'; | |
4192 | #endif | |
4193 | ||
4194 | /* Orientation */ | |
4195 | switch (mParameters.getInt(CameraParameters::KEY_ROTATION)) { | |
4196 | case 90: | |
4197 | mExifInfo.orientation = EXIF_ORIENTATION_90; | |
4198 | break; | |
4199 | case 180: | |
4200 | mExifInfo.orientation = EXIF_ORIENTATION_180; | |
4201 | break; | |
4202 | case 270: | |
4203 | mExifInfo.orientation = EXIF_ORIENTATION_270; | |
4204 | break; | |
4205 | case 0: | |
4206 | default: | |
4207 | mExifInfo.orientation = EXIF_ORIENTATION_UP; | |
4208 | break; | |
4209 | } | |
4210 | ALOGD("Exif: setRotation = %d, orientation = %d", mParameters.getInt(CameraParameters::KEY_ROTATION), mExifInfo.orientation); | |
4211 | ||
4212 | /* Date time */ | |
4213 | time_t rawtime; | |
4214 | struct tm *timeinfo; | |
4215 | time(&rawtime); | |
4216 | timeinfo = localtime(&rawtime); | |
4217 | strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo); | |
4218 | ||
4219 | /* 0th IFD Exif Private Tags */ | |
4220 | /* Exposure Time */ | |
4221 | int err; | |
4222 | int exposureTimeNum; | |
4223 | int exposureTimeDen; | |
4224 | int rt_num, rt_den; | |
4225 | ||
4226 | err = mFlite.gctrl(V4L2_CID_EXIF_EXPOSURE_TIME_NUM, &exposureTimeNum); | |
4227 | if (err < 0) | |
4228 | ALOGE("setExifChangedAttribute: exposure time num err = %d", err); | |
4229 | err = mFlite.gctrl(V4L2_CID_EXIF_EXPOSURE_TIME_DEN, &exposureTimeDen); | |
4230 | if (err < 0) | |
4231 | ALOGE("setExifChangedAttribute: exposure time den err = %d", err); | |
4232 | if (exposureTimeNum > 0) { | |
4233 | mExifInfo.exposure_time.num = exposureTimeNum; | |
4234 | } else { | |
4235 | ALOGE("exposureTimeNum is negative. set to 1"); | |
4236 | mExifInfo.exposure_time.num = 1; | |
4237 | } | |
4238 | mExifInfo.exposure_time.den = exposureTimeDen; | |
4239 | ALOGD("Exif: exposure time num = %d, den = %d", exposureTimeNum, exposureTimeDen); | |
4240 | ||
4241 | /* Shutter Speed */ | |
4242 | double exposure = (double)mExifInfo.exposure_time.den / (double)mExifInfo.exposure_time.num; | |
4243 | mExifInfo.shutter_speed.num = APEX_EXPOSURE_TO_SHUTTER(exposure) * Exif::DEFAULT_APEX_DEN; | |
4244 | if(mExifInfo.shutter_speed.num < 0) | |
4245 | mExifInfo.shutter_speed.num = 0; | |
4246 | mExifInfo.shutter_speed.den = Exif::DEFAULT_APEX_DEN; | |
4247 | ALOGD("Exif: shutter speed num = %d, den = %d", mExifInfo.shutter_speed.num, mExifInfo.shutter_speed.den); | |
4248 | ||
4249 | /* Flash */ | |
4250 | if (mCameraId == CAMERA_ID_BACK) { | |
4251 | err = mFlite.gctrl(V4L2_CID_CAMERA_EXIF_FLASH, (int *)&mExifInfo.flash); | |
4252 | if (err < 0) | |
4253 | ALOGE("setExifChangedAttribute: Flash value err = %d", err); | |
4254 | ALOGD("mEixfInfo.flash = %x", mExifInfo.flash); | |
4255 | } | |
4256 | ||
4257 | /* Color Space information */ | |
4258 | mExifInfo.color_space = Exif::DEFAULT_COLOR_SPACE; | |
4259 | ||
4260 | /* User Comments */ | |
4261 | strncpy((char *)mExifInfo.user_comment, Exif::DEFAULT_USERCOMMENTS, sizeof(mExifInfo.user_comment) - 1); | |
4262 | /* ISO Speed Rating */ | |
4263 | err = mFlite.gctrl(V4L2_CID_CAMERA_EXIF_ISO, (int *)&mExifInfo.iso_speed_rating); | |
4264 | if (err < 0) | |
4265 | ALOGE("setExifChangedAttribute: ISO Speed Rating err = %d", err); | |
4266 | ||
4267 | /* Brightness */ | |
4268 | int bv; | |
4269 | err = mFlite.gctrl(V4L2_CID_CAMERA_EXIF_BV, &bv); | |
4270 | if (err < 0) | |
4271 | ALOGE("setExifChangedAttribute: Brightness value err = %d", err); | |
4272 | mExifInfo.brightness.num = bv; | |
4273 | mExifInfo.brightness.den = Exif::DEFAULT_APEX_DEN; | |
4274 | ||
4275 | if (mCameraId == CAMERA_ID_BACK) { | |
4276 | /* Exposure Bias */ | |
4277 | float exposure = mParameters.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION) * | |
4278 | mParameters.getFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP); | |
4279 | mExifInfo.exposure_bias.num = (exposure * Exif::DEFAULT_APEX_DEN); | |
4280 | mExifInfo.exposure_bias.den = Exif::DEFAULT_APEX_DEN; | |
4281 | } | |
4282 | ||
4283 | /* Metering Mode */ | |
4284 | const char *metering = mParameters.get("metering"); | |
4285 | if (!metering || !strcmp(metering, "center")) | |
4286 | mExifInfo.metering_mode = EXIF_METERING_CENTER; | |
4287 | else if (!strcmp(metering, "spot")) | |
4288 | mExifInfo.metering_mode = EXIF_METERING_SPOT; | |
4289 | else if (!strcmp(metering, "matrix")) | |
4290 | mExifInfo.metering_mode = EXIF_METERING_AVERAGE; | |
4291 | ||
4292 | /* White Balance */ | |
4293 | const char *wb = mParameters.get(CameraParameters::KEY_WHITE_BALANCE); | |
4294 | if (!wb || !strcmp(wb, CameraParameters::WHITE_BALANCE_AUTO)) | |
4295 | mExifInfo.white_balance = EXIF_WB_AUTO; | |
4296 | else | |
4297 | mExifInfo.white_balance = EXIF_WB_MANUAL; | |
4298 | ||
4299 | /* Scene Capture Type */ | |
4300 | switch (mSceneMode) { | |
4301 | case SCENE_MODE_PORTRAIT: | |
4302 | mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT; | |
4303 | break; | |
4304 | case SCENE_MODE_LANDSCAPE: | |
4305 | mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE; | |
4306 | break; | |
4307 | case SCENE_MODE_NIGHTSHOT: | |
4308 | mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT; | |
4309 | break; | |
4310 | default: | |
4311 | mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD; | |
4312 | break; | |
4313 | } | |
4314 | ||
4315 | /* 0th IFD GPS Info Tags */ | |
4316 | const char *strLatitude = mParameters.get(CameraParameters::KEY_GPS_LATITUDE); | |
4317 | const char *strLogitude = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE); | |
4318 | const char *strAltitude = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE); | |
4319 | ||
4320 | if (strLatitude != NULL && strLogitude != NULL && strAltitude != NULL) { | |
4321 | if (atof(strLatitude) > 0) { | |
4322 | strncpy((char *)mExifInfo.gps_latitude_ref, "N", sizeof(mExifInfo.gps_latitude_ref) - 1); | |
4323 | } else { | |
4324 | strncpy((char *)mExifInfo.gps_latitude_ref, "S", sizeof(mExifInfo.gps_latitude_ref) - 1); | |
4325 | } | |
4326 | mExifInfo.gps_latitude_ref[sizeof(mExifInfo.gps_latitude_ref) - 1] = '\0'; | |
4327 | ||
4328 | if (atof(strLogitude) > 0){ | |
4329 | strncpy((char *)mExifInfo.gps_longitude_ref, "E", sizeof(mExifInfo.gps_longitude_ref) - 1); | |
4330 | } else { | |
4331 | strncpy((char *)mExifInfo.gps_longitude_ref, "W", sizeof(mExifInfo.gps_longitude_ref) - 1); | |
4332 | } | |
4333 | mExifInfo.gps_longitude_ref[sizeof(mExifInfo.gps_longitude_ref) - 1] = '\0'; | |
4334 | ||
4335 | if (atof(strAltitude) > 0) | |
4336 | mExifInfo.gps_altitude_ref = 0; | |
4337 | else | |
4338 | mExifInfo.gps_altitude_ref = 1; | |
4339 | ||
4340 | double latitude = fabs(atof(strLatitude)); | |
4341 | double longitude = fabs(atof(strLogitude)); | |
4342 | double altitude = fabs(atof(strAltitude)); | |
4343 | ||
4344 | mExifInfo.gps_latitude[0].num = (uint32_t)latitude; | |
4345 | mExifInfo.gps_latitude[0].den = 1; | |
4346 | mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60); | |
4347 | mExifInfo.gps_latitude[1].den = 1; | |
4348 | mExifInfo.gps_latitude[2].num = (uint32_t)(round((((latitude - mExifInfo.gps_latitude[0].num) * 60) - | |
4349 | mExifInfo.gps_latitude[1].num) * 60)); | |
4350 | mExifInfo.gps_latitude[2].den = 1; | |
4351 | ||
4352 | mExifInfo.gps_longitude[0].num = (uint32_t)longitude; | |
4353 | mExifInfo.gps_longitude[0].den = 1; | |
4354 | mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60); | |
4355 | mExifInfo.gps_longitude[1].den = 1; | |
4356 | mExifInfo.gps_longitude[2].num = (uint32_t)(round((((longitude - mExifInfo.gps_longitude[0].num) * 60) - | |
4357 | mExifInfo.gps_longitude[1].num) * 60)); | |
4358 | mExifInfo.gps_longitude[2].den = 1; | |
4359 | ||
4360 | mExifInfo.gps_altitude.num = (uint32_t)altitude; | |
4361 | mExifInfo.gps_altitude.den = 1; | |
4362 | ||
4363 | const char *strTimestamp = mParameters.get(CameraParameters::KEY_GPS_TIMESTAMP); | |
4364 | long timestamp = 0; | |
4365 | if (strTimestamp) | |
4366 | timestamp = atol(strTimestamp); | |
4367 | ||
4368 | struct tm tm_data; | |
4369 | gmtime_r(×tamp, &tm_data); | |
4370 | mExifInfo.gps_timestamp[0].num = tm_data.tm_hour; | |
4371 | mExifInfo.gps_timestamp[0].den = 1; | |
4372 | mExifInfo.gps_timestamp[1].num = tm_data.tm_min; | |
4373 | mExifInfo.gps_timestamp[1].den = 1; | |
4374 | mExifInfo.gps_timestamp[2].num = tm_data.tm_sec; | |
4375 | mExifInfo.gps_timestamp[2].den = 1; | |
4376 | strftime((char *)mExifInfo.gps_datestamp, sizeof(mExifInfo.gps_datestamp), "%Y:%m:%d", &tm_data); | |
4377 | ||
4378 | const char *progressingMethod = mParameters.get(CameraParameters::KEY_GPS_PROCESSING_METHOD); | |
4379 | if (progressingMethod) { | |
4380 | size_t len = strlen(progressingMethod); | |
4381 | if (len >= sizeof(mExifInfo.gps_processing_method)) | |
4382 | len = sizeof(mExifInfo.gps_processing_method) - 1; | |
4383 | ||
4384 | CLEAR(mExifInfo.gps_processing_method); | |
4385 | strncpy((char *)mExifInfo.gps_processing_method, progressingMethod, len); | |
4386 | } | |
4387 | ||
4388 | mExifInfo.enableGps = true; | |
4389 | } else { | |
4390 | mExifInfo.enableGps = false; | |
4391 | } | |
4392 | ||
4393 | /* 1th IFD TIFF Tags */ | |
4394 | mExifInfo.widthThumb = mThumbnailSize.width; | |
4395 | mExifInfo.heightThumb = mThumbnailSize.height; | |
4396 | ||
4397 | } | |
4398 | ||
4399 | int SecCameraHardware::internalGetJpegForSocYuvWithZoom(int *postviewOffset) | |
4400 | { | |
4401 | ExynosBuffer thumbnailJpeg; | |
4402 | ExynosBuffer rawThumbnail; | |
4403 | ExynosBuffer jpegOutBuf; | |
4404 | ExynosBuffer exifOutBuf; | |
4405 | ExynosBuffer nullBuf; | |
4406 | Exif exif(mCameraId, CAMERA_TYPE_SOC); | |
4407 | int i; | |
4408 | ||
4409 | uint8_t *thumb; | |
4410 | int32_t thumbSize; | |
4411 | bool thumbnail = false; | |
4412 | int err = -1; | |
4413 | int ret = UNKNOWN_ERROR; | |
4414 | ||
4415 | s5p_rect zoomRect; | |
4416 | CLOGD("DEBUG(%s)(%d): picture size(%d/%d)", __FUNCTION__, __LINE__, mPictureSize.width, mPictureSize.height); | |
4417 | CLOGD("DEBUG(%s)(%d): thumbnail size(%d/%d)", __FUNCTION__, __LINE__, mThumbnailSize.width, mThumbnailSize.height); | |
4418 | ||
4419 | zoomRect.w = (uint32_t)((float)mPictureSize.width * 1000 / mZoomRatio); | |
4420 | zoomRect.h = (uint32_t)((float)mPictureSize.height * 1000 / mZoomRatio); | |
4421 | ||
4422 | if (zoomRect.w % 2) | |
4423 | zoomRect.w -= 1; | |
4424 | ||
4425 | if (zoomRect.h % 2) | |
4426 | zoomRect.h -= 1; | |
4427 | ||
4428 | zoomRect.x = (mPictureSize.width - zoomRect.w) / 2; | |
4429 | zoomRect.y = (mPictureSize.height - zoomRect.h) / 2; | |
4430 | ||
4431 | if (zoomRect.x % 2) | |
4432 | zoomRect.x -= 1; | |
4433 | ||
4434 | if (zoomRect.y % 2) | |
4435 | zoomRect.y -= 1; | |
4436 | ||
4437 | /* Making thumbnail image */ | |
4438 | if (mThumbnailSize.width == 0 || mThumbnailSize.height == 0) | |
4439 | goto encodeJpeg; | |
4440 | ||
4441 | /* alloc rawThumbnail */ | |
4442 | rawThumbnail.size.extS[0] = mThumbnailSize.width * mThumbnailSize.height * 2; | |
4443 | if (allocMem(mIonCameraClient, &rawThumbnail, 1 << 1) == false) { | |
4444 | CLOGE("ERR(%s): rawThumbnail allocMem() fail", __func__); | |
4445 | goto destroyMem; | |
4446 | } else { | |
4447 | CLOGV("DEBUG(%s): rawThumbnail allocMem adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
4448 | rawThumbnail.virt.extP[0], rawThumbnail.size.extS[0], mIonCameraClient); | |
4449 | memset(rawThumbnail.virt.extP[0], 0, rawThumbnail.size.extS[0]); | |
4450 | } | |
4451 | ||
4452 | if (mPictureBuf.size.extS[0] <= 0) { | |
4453 | goto destroyMem; | |
4454 | } | |
4455 | ||
4456 | LOG_PERFORMANCE_START(3); | |
4457 | ||
4458 | scaleDownYuv422((unsigned char *)mPictureBuf.virt.extP[0], | |
4459 | (int)mPictureSize.width, | |
4460 | (int)mPictureSize.height, | |
4461 | (unsigned char *)rawThumbnail.virt.extP[0], | |
4462 | (int)mThumbnailSize.width, | |
4463 | (int)mThumbnailSize.height); | |
4464 | LOG_PERFORMANCE_END(3, "scaleDownYuv422"); | |
4465 | ||
4466 | /* alloc thumbnailJpeg */ | |
4467 | thumbnailJpeg.size.extS[0] = mThumbnailSize.width * mThumbnailSize.height * 2; | |
4468 | if (allocMem(mIonCameraClient, &thumbnailJpeg, 1 << 1) == false) { | |
4469 | CLOGE("ERR(%s): thumbnailJpeg allocMem() fail", __func__); | |
4470 | goto destroyMem; | |
4471 | } else { | |
4472 | CLOGV("DEBUG(%s): thumbnailJpeg allocMem adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
4473 | thumbnailJpeg.virt.extP[0], thumbnailJpeg.size.extS[0], mIonCameraClient); | |
4474 | memset(thumbnailJpeg.virt.extP[0], 0, thumbnailJpeg.size.extS[0]); | |
4475 | } | |
4476 | ||
4477 | err = EncodeToJpeg(&rawThumbnail, | |
4478 | &thumbnailJpeg, | |
4479 | mThumbnailSize.width, | |
4480 | mThumbnailSize.height, | |
4481 | CAM_PIXEL_FORMAT_YUV422I, | |
4482 | &thumbSize, | |
4483 | JPEG_THUMBNAIL_QUALITY); | |
4484 | CHECK_ERR_GOTO(encodeJpeg, err, ("getJpeg: error, EncodeToJpeg(thumbnail)")); | |
4485 | ||
4486 | thumb = (uint8_t *)thumbnailJpeg.virt.extP[0]; | |
4487 | thumbnail = true; | |
4488 | ||
4489 | LOG_PERFORMANCE_END(1, "encode thumbnail"); | |
4490 | ||
4491 | encodeJpeg: | |
4492 | /* Making EXIF header */ | |
4493 | ||
4494 | setExifChangedAttribute(); | |
4495 | ||
4496 | uint32_t exifSize; | |
4497 | int32_t jpegSize; | |
4498 | uint8_t *jpeg; | |
4499 | ||
4500 | /* alloc exifOutBuf */ | |
4501 | exifOutBuf.size.extS[0] = EXIF_MAX_LEN; | |
4502 | if (allocMem(mIonCameraClient, &exifOutBuf, 1 << 1) == false) { | |
4503 | CLOGE("ERR(%s): exifTmpBuf allocMem() fail", __func__); | |
4504 | goto destroyMem; | |
4505 | } else { | |
4506 | CLOGV("DEBUG(%s): exifTmpBuf allocMem adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
4507 | exifOutBuf.virt.extP[0], exifOutBuf.size.extS[0], mIonCameraClient); | |
4508 | memset(exifOutBuf.virt.extP[0], 0, exifOutBuf.size.extS[0]); | |
4509 | } | |
4510 | ||
4511 | if (!thumbnail) | |
4512 | exifSize = exif.make((void *)exifOutBuf.virt.extP[0], &mExifInfo); | |
4513 | else | |
4514 | exifSize = exif.make((void *)exifOutBuf.virt.extP[0], &mExifInfo, exifOutBuf.size.extS[0], thumb, thumbSize); | |
4515 | if (CC_UNLIKELY(!exifSize)) { | |
4516 | CLOGE("ERR(%s): getJpeg: error, fail to make EXIF", __FUNCTION__); | |
4517 | goto destroyMem; | |
4518 | } | |
4519 | ||
4520 | /* alloc jpegOutBuf */ | |
4521 | jpegOutBuf.size.extS[0] = mPictureSize.width * mPictureSize.height * 2; | |
4522 | if (allocMem(mIonCameraClient, &jpegOutBuf, 1 << 1) == false) { | |
4523 | CLOGE("ERR(%s): jpegOutBuf allocMem() fail", __func__); | |
4524 | goto destroyMem; | |
4525 | } else { | |
4526 | CLOGV("DEBUG(%s): jpegOutBuf allocMem adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
4527 | jpegOutBuf.virt.extP[0], jpegOutBuf.size.extS[0], mIonCameraClient); | |
4528 | memset(jpegOutBuf.virt.extP[0], 0, jpegOutBuf.size.extS[0]); | |
4529 | } | |
4530 | ||
4531 | /* Making main jpeg image */ | |
4532 | err = EncodeToJpeg(&mPictureBuf, | |
4533 | &jpegOutBuf, | |
4534 | mPictureSize.width, | |
4535 | mPictureSize.height, | |
4536 | CAM_PIXEL_FORMAT_YUV422I, | |
4537 | &jpegSize, | |
4538 | mJpegQuality); | |
4539 | ||
4540 | CHECK_ERR_GOTO(destroyMem, err, ("getJpeg: error, EncodeToJpeg(Main)")); | |
4541 | ||
4542 | /* Finally, Creating Jpeg image file including EXIF */ | |
4543 | mPictureFrameSize = jpegSize + exifSize; | |
4544 | ||
4545 | /*note that picture frame size is should be calculated before call allocateSnapshotHeap */ | |
4546 | if (!allocateSnapshotHeap()) { | |
4547 | ALOGE("getEncodedJpeg: error, allocateSnapshotHeap"); | |
4548 | goto destroyMem; | |
4549 | } | |
4550 | ||
4551 | jpeg = (unsigned char *)jpegOutBuf.virt.extP[0]; | |
4552 | memcpy((unsigned char *)mJpegHeap->data, jpeg, 2); | |
4553 | memcpy((unsigned char *)mJpegHeap->data + 2, exifOutBuf.virt.extP[0], exifSize); | |
4554 | memcpy((unsigned char *)mJpegHeap->data + 2 + exifSize, jpeg + 2, jpegSize - 2); | |
4555 | CLOGD("DEBUG(%s): success making jpeg(%d) and exif(%d)", __FUNCTION__, jpegSize, exifSize); | |
4556 | ||
4557 | ret = NO_ERROR; | |
4558 | ||
4559 | destroyMem: | |
4560 | freeMem(&thumbnailJpeg); | |
4561 | freeMem(&rawThumbnail); | |
4562 | freeMem(&jpegOutBuf); | |
4563 | freeMem(&exifOutBuf); | |
4564 | ||
4565 | return ret; | |
4566 | } | |
4567 | ||
4568 | int SecCameraHardware::internalGetJpegForRawWithZoom(int *postviewOffset) | |
4569 | { | |
4570 | ExynosBuffer thumbnailJpeg; | |
4571 | ExynosBuffer rawThumbnail; | |
4572 | ExynosBuffer jpegOutBuf; | |
4573 | ExynosBuffer exifOutBuf; | |
4574 | ExynosBuffer nullBuf; | |
4575 | Exif exif(mCameraId); | |
4576 | int i; | |
4577 | ||
4578 | uint8_t *thumb; | |
4579 | bool thumbnail = false; | |
4580 | int err; | |
4581 | int ret = UNKNOWN_ERROR; | |
4582 | ||
4583 | int32_t jpegSize = -1; | |
4584 | int32_t jpegOffset; | |
4585 | int32_t thumbSize = 0; | |
4586 | int32_t thumbOffset; | |
4587 | ||
4588 | err = mFlite.gctrl(V4L2_CID_CAM_JPEG_MAIN_SIZE, &jpegSize); | |
4589 | CHECK_ERR(err, ("getJpeg: error %d, jpeg size", err)); | |
4590 | ||
4591 | ALOGD("internalgetJpeg: jpegSize = %d", jpegSize); | |
4592 | ||
4593 | err = mFlite.gctrl(V4L2_CID_CAM_JPEG_MAIN_OFFSET, &jpegOffset); | |
4594 | CHECK_ERR(err, ("getJpeg: error %d, jpeg offset", err)); | |
4595 | ||
4596 | ||
4597 | s5p_rect zoomRect; | |
4598 | ALOGV("DEBUG(%s)(%d): picture size(%d/%d)", __FUNCTION__, __LINE__, mPictureSize.width, mPictureSize.height); | |
4599 | ||
4600 | zoomRect.w = (uint32_t)((float)mPictureSize.width * 1000 / mZoomRatio); | |
4601 | zoomRect.h = (uint32_t)((float)mPictureSize.height * 1000 / mZoomRatio); | |
4602 | ||
4603 | if (zoomRect.w % 2) | |
4604 | zoomRect.w -= 1; | |
4605 | ||
4606 | if (zoomRect.h % 2) | |
4607 | zoomRect.h -= 1; | |
4608 | ||
4609 | zoomRect.x = (mPictureSize.width - zoomRect.w) / 2; | |
4610 | zoomRect.y = (mPictureSize.height - zoomRect.h) / 2; | |
4611 | ||
4612 | if (zoomRect.x % 2) | |
4613 | zoomRect.x -= 1; | |
4614 | ||
4615 | if (zoomRect.y % 2) | |
4616 | zoomRect.y -= 1; | |
4617 | ||
4618 | ||
4619 | if (mPictureBufDummy[0].size.extS[0] <= 0) | |
4620 | return UNKNOWN_ERROR; | |
4621 | ||
4622 | LOG_PERFORMANCE_START(3); | |
4623 | ||
4624 | #if 0 | |
4625 | ALOGD("mPostviewFrameSize = %d", mPostviewFrameSize); | |
4626 | save_dump_path((uint8_t*)mPostviewHeap->data, | |
4627 | mPostviewFrameSize, "/data/dump_postview_yuv.yuv"); | |
4628 | #endif | |
4629 | ||
4630 | thumbnail = false; | |
4631 | ||
4632 | LOG_PERFORMANCE_END(1, "encode thumbnail"); | |
4633 | #ifdef SAVE_DUMP | |
4634 | #if 0 | |
4635 | save_dump_path((uint8_t*)thumbnailJpeg.virt.extP[0], | |
4636 | thumbSize, "/data/dump_thumbnail_jpeg.jpg"); | |
4637 | #endif | |
4638 | #endif | |
4639 | ||
4640 | encodeJpeg: | |
4641 | /* Making EXIF header */ | |
4642 | ||
4643 | setExifChangedAttribute(); | |
4644 | ||
4645 | uint32_t exifSize; | |
4646 | uint8_t *jpeg; | |
4647 | ||
4648 | /* alloc exifOutBuf */ | |
4649 | exifOutBuf.size.extS[0] = EXIF_MAX_LEN; | |
4650 | if (allocMem(mIonCameraClient, &exifOutBuf, 1 << 1) == false) { | |
4651 | ALOGE("ERR(%s): exifTmpBuf allocMem() fail", __func__); | |
4652 | goto destroyMem; | |
4653 | } else { | |
4654 | ALOGV("DEBUG(%s): exifTmpBuf allocMem adr(%p), size(%d), ion(%d)", __FUNCTION__, | |
4655 | exifOutBuf.virt.extP[0], exifOutBuf.size.extS[0], mIonCameraClient); | |
4656 | memset(exifOutBuf.virt.extP[0], 0, exifOutBuf.size.extS[0]); | |
4657 | } | |
4658 | ||
4659 | if (!thumbnail) | |
4660 | exifSize = exif.make((void *)exifOutBuf.virt.extP[0], &mExifInfo); | |
4661 | else | |
4662 | exifSize = exif.make((void *)exifOutBuf.virt.extP[0], &mExifInfo, exifOutBuf.size.extS[0], thumb, thumbSize); | |
4663 | if (CC_UNLIKELY(!exifSize)) { | |
4664 | ALOGE("ERR(%s): getJpeg: error, fail to make EXIF", __FUNCTION__); | |
4665 | goto destroyMem; | |
4666 | } | |
4667 | ||
4668 | /* Finally, Creating Jpeg image file including EXIF */ | |
4669 | mPictureFrameSize = jpegSize + exifSize; | |
4670 | ||
4671 | { | |
4672 | ALOGD("jpegSize = %d, exifSize = %d", jpegSize, exifSize); | |
4673 | /*note that picture frame size is should be calculated before call allocateSnapshotHeap */ | |
4674 | if (!allocateSnapshotHeap()) { | |
4675 | ALOGE("getEncodedJpeg: error, allocateSnapshotHeap"); | |
4676 | goto destroyMem; | |
4677 | } | |
4678 | ||
4679 | // jpeg = (unsigned char *)jpegOutBuf.virt.extP[0]; | |
4680 | jpeg = (unsigned char *)mPictureBufDummy[0].virt.extP[0]; | |
4681 | memcpy((unsigned char *)mJpegHeap->data, jpeg, 2); | |
4682 | memcpy((unsigned char *)mJpegHeap->data + 2, exifOutBuf.virt.extP[0], exifSize); | |
4683 | memcpy((unsigned char *)mJpegHeap->data + 2 + exifSize, jpeg + 2, jpegSize - 2); | |
4684 | ALOGD("DEBUG(%s): success making jpeg(%d) and exif(%d)", __FUNCTION__, jpegSize, exifSize); | |
4685 | ||
4686 | #ifdef SAVE_DUMP | |
4687 | #if 0 | |
4688 | save_dump_path((uint8_t*)mJpegHeap->data, | |
4689 | mPictureFrameSize, "/data/dump_full_img.jpg"); | |
4690 | #endif | |
4691 | #endif | |
4692 | } | |
4693 | ||
4694 | ret = NO_ERROR; | |
4695 | ||
4696 | destroyMem: | |
4697 | freeMemSinglePlane(&jpegOutBuf, 0); | |
4698 | freeMemSinglePlane(&exifOutBuf, 0); | |
4699 | ||
4700 | return ret; | |
4701 | } | |
4702 | ||
4703 | int SecCameraHardware::EncodeToJpeg(ExynosBuffer *yuvBuf, ExynosBuffer *jpegBuf, | |
4704 | int width, int height, cam_pixel_format srcformat, int* jpegSize, int quality) | |
4705 | { | |
4706 | ExynosJpegEncoder *jpegEnc = NULL; | |
4707 | int ret = UNKNOWN_ERROR; | |
4708 | ||
4709 | /* 1. ExynosJpegEncoder create */ | |
4710 | jpegEnc = new ExynosJpegEncoder(); | |
4711 | if (jpegEnc == NULL) { | |
4712 | ALOGE("ERR(%s) (%d): jpegEnc is null", __FUNCTION__, __LINE__); | |
4713 | return ret; | |
4714 | } | |
4715 | ||
4716 | ret = jpegEnc->create(); | |
4717 | if (ret < 0) { | |
4718 | ALOGE("ERR(%s):jpegEnc.create(%d) fail", __func__, ret); | |
4719 | goto jpeg_encode_done; | |
4720 | } | |
4721 | ||
4722 | /* 2. cache on */ | |
4723 | ret = jpegEnc->setCache(JPEG_CACHE_ON); | |
4724 | if (ret < 0) { | |
4725 | ALOGE("ERR(%s):jpegEnc.setCache(%d) fail", __func__, ret); | |
4726 | goto jpeg_encode_done; | |
4727 | } | |
4728 | ||
4729 | /* 3. set quality */ | |
4730 | ret = jpegEnc->setQuality(quality); | |
4731 | if (ret < 0) { | |
4732 | ALOGE("ERR(%s):jpegEnc.setQuality(%d) fail", __func__, ret); | |
4733 | goto jpeg_encode_done; | |
4734 | } | |
4735 | ||
4736 | ret = jpegEnc->setSize(width, height); | |
4737 | if (ret < 0) { | |
4738 | ALOGE("ERR(%s):jpegEnc.setSize() fail", __func__); | |
4739 | goto jpeg_encode_done; | |
4740 | } | |
4741 | ||
4742 | /* 4. set yuv format */ | |
4743 | ret = jpegEnc->setColorFormat(srcformat); | |
4744 | if (ret < 0) { | |
4745 | ALOGE("ERR(%s):jpegEnc.setColorFormat(%d) fail", __func__, ret); | |
4746 | goto jpeg_encode_done; | |
4747 | } | |
4748 | ||
4749 | /* 5. set jpeg format */ | |
4750 | ret = jpegEnc->setJpegFormat(V4L2_PIX_FMT_JPEG_422); | |
4751 | if (ret < 0) { | |
4752 | ALOGE("ERR(%s):jpegEnc.setJpegFormat(%d) fail", __func__, ret); | |
4753 | goto jpeg_encode_done; | |
4754 | } | |
4755 | ||
4756 | /* src and dst buffer alloc */ | |
4757 | /* 6. set yuv format(src) from FLITE */ | |
4758 | ret = jpegEnc->setInBuf(((char **)&(yuvBuf->virt.extP[0])), (int *)yuvBuf->size.extS); | |
4759 | if (ret < 0) { | |
4760 | ALOGE("ERR(%s):jpegEnc.setInBuf(%d) fail", __func__, ret); | |
4761 | goto jpeg_encode_done; | |
4762 | } | |
4763 | ||
4764 | /* 6. set jpeg format(dest) from FLITE */ | |
4765 | ret = jpegEnc->setOutBuf((char *)jpegBuf->virt.extP[0], jpegBuf->size.extS[0]); | |
4766 | if (ret < 0) { | |
4767 | ALOGE("ERR(%s):jpegEnc.setOutBuf(%d) fail", __func__, ret); | |
4768 | goto jpeg_encode_done; | |
4769 | } | |
4770 | ||
4771 | ret = jpegEnc->updateConfig(); | |
4772 | if (ret < 0) { | |
4773 | ALOGE("ERR(%s):jpegEnc.updateConfig(%d) fail", __func__, ret); | |
4774 | goto jpeg_encode_done; | |
4775 | } | |
4776 | ||
4777 | /* start encoding */ | |
4778 | ret = jpegEnc->encode(); | |
4779 | if (ret < 0) { | |
4780 | ALOGE("ERR(%s):jpegEnc.encode(%d) fail", __func__, ret); | |
4781 | goto jpeg_encode_done; | |
4782 | } | |
4783 | ||
4784 | /* start encoding */ | |
4785 | *jpegSize = jpegEnc->getJpegSize(); | |
4786 | if ((*jpegSize) <= 0) { | |
4787 | ALOGE("ERR(%s):jpegEnc.getJpegSize(%d) is too small", __func__, *jpegSize); | |
4788 | goto jpeg_encode_done; | |
4789 | } | |
4790 | ||
4791 | ALOGD("DEBUG(%s): jpegEnc success!! size(%d)", __func__, *jpegSize); | |
4792 | ret = NO_ERROR; | |
4793 | ||
4794 | jpeg_encode_done: | |
4795 | jpegEnc->destroy(); | |
4796 | delete jpegEnc; | |
4797 | ||
4798 | if (ret != NO_ERROR) { | |
4799 | ALOGE("ERR(%s): (%d) [yuvBuf->fd.extFd[0] %d][yuvSize[0] %d]", __FUNCTION__, __LINE__, | |
4800 | yuvBuf->fd.extFd[0], yuvBuf->size.extS[0]); | |
4801 | ALOGE("ERR(%s): (%d) [jpegBuf->fd.extFd %d][jpegBuf->size.extS %d]", __FUNCTION__, __LINE__, | |
4802 | jpegBuf->fd.extFd[0], jpegBuf->size.extS[0]); | |
4803 | ALOGE("ERR(%s): (%d) [w %d][h %d][colorFormat %d]", __FUNCTION__, __LINE__, | |
4804 | width, height, srcformat); | |
4805 | } | |
4806 | ||
4807 | return ret; | |
4808 | } | |
4809 | ||
4810 | bool SecCameraHardware::scaleDownYuv422(uint8_t *srcBuf, int srcW, int srcH, | |
4811 | uint8_t *dstBuf, int dstW, int dstH) | |
4812 | ||
4813 | { | |
4814 | int step_x, step_y; | |
4815 | int dst_pos; | |
4816 | char *src_buf = (char *)srcBuf; | |
4817 | char *dst_buf = (char *)dstBuf; | |
4818 | ||
4819 | if (dstW & 0x01 || dstH & 0x01) { | |
4820 | ALOGE("ERROR(%s): (%d) width or height invalid(%d/%d)", __FUNCTION__, __LINE__, | |
4821 | dstW & 0x01, dstH & 0x01); | |
4822 | return false; | |
4823 | } | |
4824 | ||
4825 | step_x = srcW / dstW; | |
4826 | step_y = srcH / dstH; | |
4827 | ||
4828 | unsigned int srcWStride = srcW * 2; | |
4829 | unsigned int stepXStride = step_x * 2; | |
4830 | ||
4831 | dst_pos = 0; | |
4832 | for (int y = 0; y < dstH; y++) { | |
4833 | int src_y_start_pos; | |
4834 | src_y_start_pos = srcWStride * step_y * y; | |
4835 | for (int x = 0; x < dstW; x += 2) { | |
4836 | int src_pos; | |
4837 | src_pos = src_y_start_pos + (stepXStride * x); | |
4838 | dst_buf[dst_pos++] = src_buf[src_pos]; | |
4839 | dst_buf[dst_pos++] = src_buf[src_pos + 1]; | |
4840 | dst_buf[dst_pos++] = src_buf[src_pos + 2]; | |
4841 | dst_buf[dst_pos++] = src_buf[src_pos + 3]; | |
4842 | } | |
4843 | } | |
4844 | ||
4845 | return true; | |
4846 | } | |
4847 | ||
4848 | bool SecCameraHardware::conversion420to422(uint8_t *srcBuf, uint8_t *dstBuf, int width, int height) | |
4849 | { | |
4850 | int i, j, k; | |
4851 | int vPos1, vPos2, uPos1, uPos2; | |
4852 | ||
4853 | /* copy y table */ | |
4854 | for (i = 0; i < width * height; i++) { | |
4855 | j = i * 2; | |
4856 | dstBuf[j] = srcBuf[i]; | |
4857 | } | |
4858 | ||
4859 | for (i = 0; i < width * height / 2; i += 2) { | |
4860 | j = width * height; | |
4861 | k = width * 2; | |
4862 | uPos1 = (i / width) * k * 2 + (i % width) * 2 + 1; | |
4863 | uPos2 = uPos1 + k; | |
4864 | vPos1 = uPos1 + 2; | |
4865 | vPos2 = uPos2 + 2; | |
4866 | ||
4867 | if (uPos1 >= 0) { | |
4868 | dstBuf[vPos1] = srcBuf[j + i]; /* V table */ | |
4869 | dstBuf[vPos2] = srcBuf[j + i]; /* V table */ | |
4870 | dstBuf[uPos1] = srcBuf[j + i + 1]; /* U table */ | |
4871 | dstBuf[uPos2] = srcBuf[j + i + 1]; /* U table */ | |
4872 | } | |
4873 | } | |
4874 | ||
4875 | return true; | |
4876 | } | |
4877 | ||
4878 | bool SecCameraHardware::conversion420Tto422(uint8_t *srcBuf, uint8_t *dstBuf, int width, int height) | |
4879 | { | |
4880 | int i, j, k; | |
4881 | int vPos1, vPos2, uPos1, uPos2; | |
4882 | ||
4883 | /* copy y table */ | |
4884 | for (i = 0; i < width * height; i++) { | |
4885 | j = i * 2; | |
4886 | dstBuf[j] = srcBuf[i]; | |
4887 | } | |
4888 | for (i = 0; i < width * height / 2; i+=2) { | |
4889 | j = width * height; | |
4890 | k = width * 2; | |
4891 | uPos1 = (i / width) * k * 2 + (i % width) * 2 + 1; | |
4892 | uPos2 = uPos1 + k; | |
4893 | vPos1 = uPos1 + 2; | |
4894 | vPos2 = uPos2 + 2; | |
4895 | ||
4896 | if (uPos1 >= 0) { | |
4897 | dstBuf[uPos1] = srcBuf[j + i]; /* V table */ | |
4898 | dstBuf[uPos2] = srcBuf[j + i]; /* V table */ | |
4899 | dstBuf[vPos1] = srcBuf[j + i + 1]; /* U table */ | |
4900 | dstBuf[vPos2] = srcBuf[j + i + 1]; /* U table */ | |
4901 | } | |
4902 | } | |
4903 | ||
4904 | return true; | |
4905 | } | |
4906 | ||
4907 | int SecCameraHardware::mSaveDump(const char *filepath, ExynosBuffer *dstBuf, int index) | |
4908 | { | |
4909 | FILE *yuv_fp = NULL; | |
4910 | char filename[100]; | |
4911 | char *buffer = NULL; | |
4912 | CLEAR(filename); | |
4913 | ||
4914 | /* file create/open, note to "wb" */ | |
4915 | snprintf(filename, 100, filepath, index); | |
4916 | yuv_fp = fopen(filename, "wb"); | |
4917 | if (yuv_fp == NULL) { | |
4918 | CLOGE("Save jpeg file open error[%s]", filename); | |
4919 | return -1; | |
4920 | } | |
4921 | ||
4922 | int yuv_size = dstBuf->size.extS[0] + dstBuf->size.extS[1] + dstBuf->size.extS[2]; | |
4923 | ||
4924 | buffer = (char *) malloc(yuv_size); | |
4925 | if (buffer == NULL) { | |
4926 | CLOGE("Save YUV] buffer alloc failed"); | |
4927 | if (yuv_fp) | |
4928 | fclose(yuv_fp); | |
4929 | ||
4930 | return -1; | |
4931 | } | |
4932 | ||
4933 | memcpy(buffer, dstBuf->virt.extP[0], dstBuf->size.extS[0]); | |
4934 | if (dstBuf->size.extS[1] > 0) { | |
4935 | memcpy(buffer + dstBuf->size.extS[0], | |
4936 | dstBuf->virt.extP[1], dstBuf->size.extS[1]); | |
4937 | if (dstBuf->size.extS[2] > 0) { | |
4938 | memcpy(buffer + dstBuf->size.extS[0] + dstBuf->size.extS[1], | |
4939 | dstBuf->virt.extP[2], dstBuf->size.extS[2]); | |
4940 | } | |
4941 | } | |
4942 | ||
4943 | fflush(stdout); | |
4944 | ||
4945 | fwrite(buffer, 1, yuv_size, yuv_fp); | |
4946 | ||
4947 | fflush(yuv_fp); | |
4948 | ||
4949 | if (yuv_fp) | |
4950 | fclose(yuv_fp); | |
4951 | if (buffer) | |
4952 | free(buffer); | |
4953 | ||
4954 | return 0; | |
4955 | } | |
4956 | ||
4957 | ||
4958 | int SecCameraHardware::createInstance(int cameraId) | |
4959 | { | |
4960 | if (!init()) { | |
4961 | ALOGE("createInstance: error, camera cannot be initialiezed"); | |
4962 | mInitialized = false; | |
4963 | return NO_INIT; | |
4964 | } | |
4965 | ||
4966 | initDefaultParameters(); | |
4967 | CLOGD("DEBUG[%s(%d)]-%s camera created", __FUNCTION__, __LINE__, | |
4968 | cameraId == CAMERA_ID_BACK ? "Back" : "Front"); | |
4969 | ||
4970 | mInitialized = true; | |
4971 | return NO_ERROR; | |
4972 | } | |
4973 | ||
4974 | int SecCameraHardware::getMaxZoomLevel(void) | |
4975 | { | |
4976 | int zoomLevel = 0; | |
4977 | ||
4978 | zoomLevel = MAX_BASIC_ZOOM_LEVEL; | |
4979 | ||
4980 | return zoomLevel; | |
4981 | } | |
4982 | ||
4983 | int SecCameraHardware::getMaxZoomRatio(void) | |
4984 | { | |
4985 | int maxZoomRatio = 0; | |
4986 | ||
4987 | if (mCameraId == CAMERA_ID_BACK) { | |
4988 | maxZoomRatio = MAX_ZOOM_RATIO; | |
4989 | } else { | |
4990 | maxZoomRatio = MAX_ZOOM_RATIO_FRONT; | |
4991 | } | |
4992 | ||
4993 | return maxZoomRatio; | |
4994 | } | |
4995 | ||
4996 | float SecCameraHardware::getZoomRatio(int zoomLevel) | |
4997 | { | |
4998 | float zoomRatio = 1.00f; | |
4999 | if (IsZoomSupported() == true) | |
5000 | zoomRatio = (float)zoomRatioList[zoomLevel]; | |
5001 | else | |
5002 | zoomRatio = 1000.00f; | |
5003 | ||
5004 | return zoomRatio; | |
5005 | } | |
5006 | ||
5007 | #ifdef SAMSUNG_JPEG_QUALITY_ADJUST_TARGET | |
5008 | void SecCameraHardware::adjustJpegQuality(void) | |
5009 | { | |
5010 | mJpegQuality = JPEG_QUALITY_ADJUST_TARGET; | |
5011 | ALOGD("DEBUG(%s):adjusted JpegQuality %d", __func__, mJpegQuality); | |
5012 | } | |
5013 | #endif | |
5014 | ||
5015 | int getSensorId(int camId) | |
5016 | { | |
5017 | int sensorId = -1; | |
5018 | ||
5019 | #ifdef SENSOR_NAME_GET_FROM_FILE | |
5020 | int &curSensorId = (camId == CAMERA_ID_BACK) ? g_rearSensorId : g_frontSensorId; | |
5021 | ||
5022 | if (curSensorId < 0) { | |
5023 | curSensorId = getSensorIdFromFile(camId); | |
5024 | if (curSensorId < 0) { | |
5025 | ALOGE("ERR(%s): invalid sensor ID %d", __FUNCTION__, sensorId); | |
5026 | } | |
5027 | } | |
5028 | ||
5029 | sensorId = curSensorId; | |
5030 | #else | |
5031 | if (camId == CAMERA_ID_BACK) { | |
5032 | sensorId = BACK_CAMERA_SENSOR_NAME; | |
5033 | } else if (camId == CAMERA_ID_FRONT) { | |
5034 | sensorId = FRONT_CAMERA_SENSOR_NAME; | |
5035 | } else { | |
5036 | ALOGE("ERR(%s):Unknown camera ID(%d)", __FUNCTION__, camId); | |
5037 | } | |
5038 | #endif | |
5039 | ||
5040 | return sensorId; | |
5041 | } | |
5042 | ||
5043 | #ifdef SENSOR_NAME_GET_FROM_FILE | |
5044 | int getSensorIdFromFile(int camId) | |
5045 | { | |
5046 | FILE *fp = NULL; | |
5047 | int numread = -1; | |
5048 | char sensor_name[50]; | |
5049 | int sensorName = -1; | |
5050 | bool ret = true; | |
5051 | ||
5052 | if (camId == CAMERA_ID_BACK) { | |
5053 | fp = fopen(SENSOR_NAME_PATH_BACK, "r"); | |
5054 | if (fp == NULL) { | |
5055 | ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__); | |
5056 | goto err; | |
5057 | } | |
5058 | } else { | |
5059 | fp = fopen(SENSOR_NAME_PATH_FRONT, "r"); | |
5060 | if (fp == NULL) { | |
5061 | ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__); | |
5062 | goto err; | |
5063 | } | |
5064 | } | |
5065 | ||
5066 | if (fgets(sensor_name, sizeof(sensor_name), fp) == NULL) { | |
5067 | ALOGE("ERR(%s[%d]):failed to read sysfs entry", __FUNCTION__, __LINE__); | |
5068 | goto err; | |
5069 | } | |
5070 | ||
5071 | numread = strlen(sensor_name); | |
5072 | ALOGD("DEBUG(%s[%d]):Sensor name is %s(%d)", __FUNCTION__, __LINE__, sensor_name, numread); | |
5073 | ||
5074 | /* TODO: strncmp for check sensor name, str is vendor specific sensor name | |
5075 | * ex) | |
5076 | * if (strncmp((const char*)sensor_name, "str", numread - 1) == 0) { | |
5077 | * sensorName = SENSOR_NAME_IMX135; | |
5078 | * } | |
5079 | */ | |
5080 | sensorName = atoi(sensor_name); | |
5081 | ||
5082 | err: | |
5083 | if (fp != NULL) | |
5084 | fclose(fp); | |
5085 | ||
5086 | return sensorName; | |
5087 | } | |
5088 | #endif | |
5089 | ||
5090 | #ifdef SENSOR_FW_GET_FROM_FILE | |
5091 | const char *getSensorFWFromFile(char *sensor_fw, size_t size, int camId) | |
5092 | { | |
5093 | FILE *fp = NULL; | |
5094 | int numread = -1; | |
5095 | ||
5096 | if (camId == CAMERA_ID_BACK) { | |
5097 | fp = fopen(SENSOR_FW_PATH_BACK, "r"); | |
5098 | if (fp == NULL) { | |
5099 | ALOGE("ERR(%s[%d]):failed to open SENSOR_FW_PATH_BACK", __FUNCTION__, __LINE__); | |
5100 | goto err; | |
5101 | } | |
5102 | } else { | |
5103 | fp = fopen(SENSOR_FW_PATH_FRONT, "r"); | |
5104 | if (fp == NULL) { | |
5105 | ALOGE("ERR(%s[%d]):failed to open SENSOR_FW_PATH_FRONT", __FUNCTION__, __LINE__); | |
5106 | goto err; | |
5107 | } | |
5108 | } | |
5109 | if (fgets(sensor_fw, size, fp) == NULL) { | |
5110 | ALOGE("ERR(%s[%d]):camId(%d)failed to read sysfs entry", __FUNCTION__, __LINE__, camId); | |
5111 | goto err; | |
5112 | } | |
5113 | ||
5114 | numread = strlen(sensor_fw); | |
5115 | ALOGD("DEBUG(%s[%d]):Sensor fw is %s(%d)", __FUNCTION__, __LINE__, sensor_fw, numread); | |
5116 | ||
5117 | err: | |
5118 | if (fp != NULL) | |
5119 | fclose(fp); | |
5120 | ||
5121 | return (const char*)sensor_fw; | |
5122 | } | |
5123 | #endif | |
5124 | ||
5125 | }; /* namespace android */ | |
5126 | ||
5127 | #endif /* ANDROID_HARDWARE_SECCAMERAHARDWARE_CPP */ |