blob: 413416f267874d1aceb01b72d80da1cce5e23b7a [file] [log] [blame]
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001/*
2**
3** Copyright 2008, The Android Open Source Project
4** Copyright 2012, Samsung Electronics Co. LTD
5**
6** Licensed under the Apache License, Version 2.0 (the "License");
7** you may not use this file except in compliance with the License.
8** You may obtain a copy of the License at
9**
10** http://www.apache.org/licenses/LICENSE-2.0
11**
12** Unless required by applicable law or agreed to in writing, software
13** distributed under the License is distributed on an "AS IS" BASIS,
14** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15** See the License for the specific language governing permissions and
16** limitations under the License.
17*/
18
19/*!
20 * \file ExynosCameraHWInterface2.cpp
21 * \brief source file for Android Camera API 2.0 HAL
22 * \author Sungjoong Kang(sj3.kang@samsung.com)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +090023 * \date 2012/07/10
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070024 *
25 * <b>Revision History: </b>
26 * - 2012/05/31 : Sungjoong Kang(sj3.kang@samsung.com) \n
27 * Initial Release
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +090028 *
29 * - 2012/07/10 : Sungjoong Kang(sj3.kang@samsung.com) \n
30 * 2nd Release
31 *
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070032 */
33
34//#define LOG_NDEBUG 0
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090035#define LOG_TAG "ExynosCameraHAL2"
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070036#include <utils/Log.h>
37
38#include "ExynosCameraHWInterface2.h"
39#include "exynos_format.h"
40
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070041namespace android {
42
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090043void m_savePostView(const char *fname, uint8_t *buf, uint32_t size)
44{
45 int nw;
46 int cnt = 0;
47 uint32_t written = 0;
48
Sungjoong Kangad378612012-08-17 12:34:33 -070049 ALOGV("opening file [%s], address[%x], size(%d)", fname, (unsigned int)buf, size);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090050 int fd = open(fname, O_RDWR | O_CREAT, 0644);
51 if (fd < 0) {
52 ALOGE("failed to create file [%s]: %s", fname, strerror(errno));
53 return;
54 }
55
Sungjoong Kangad378612012-08-17 12:34:33 -070056 ALOGV("writing %d bytes to file [%s]", size, fname);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090057 while (written < size) {
58 nw = ::write(fd, buf + written, size - written);
59 if (nw < 0) {
60 ALOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno));
61 break;
62 }
63 written += nw;
64 cnt++;
65 }
Sungjoong Kangad378612012-08-17 12:34:33 -070066 ALOGV("done writing %d bytes to file [%s] in %d passes",size, fname, cnt);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090067 ::close(fd);
68}
69
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070070int get_pixel_depth(uint32_t fmt)
71{
72 int depth = 0;
73
74 switch (fmt) {
75 case V4L2_PIX_FMT_JPEG:
76 depth = 8;
77 break;
78
79 case V4L2_PIX_FMT_NV12:
80 case V4L2_PIX_FMT_NV21:
81 case V4L2_PIX_FMT_YUV420:
82 case V4L2_PIX_FMT_YVU420M:
83 case V4L2_PIX_FMT_NV12M:
84 case V4L2_PIX_FMT_NV12MT:
85 depth = 12;
86 break;
87
88 case V4L2_PIX_FMT_RGB565:
89 case V4L2_PIX_FMT_YUYV:
90 case V4L2_PIX_FMT_YVYU:
91 case V4L2_PIX_FMT_UYVY:
92 case V4L2_PIX_FMT_VYUY:
93 case V4L2_PIX_FMT_NV16:
94 case V4L2_PIX_FMT_NV61:
95 case V4L2_PIX_FMT_YUV422P:
96 case V4L2_PIX_FMT_SBGGR10:
97 case V4L2_PIX_FMT_SBGGR12:
98 case V4L2_PIX_FMT_SBGGR16:
99 depth = 16;
100 break;
101
102 case V4L2_PIX_FMT_RGB32:
103 depth = 32;
104 break;
105 default:
106 ALOGE("Get depth failed(format : %d)", fmt);
107 break;
108 }
109
110 return depth;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900111}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700112
113int cam_int_s_fmt(node_info_t *node)
114{
115 struct v4l2_format v4l2_fmt;
116 unsigned int framesize;
117 int ret;
118
119 memset(&v4l2_fmt, 0, sizeof(struct v4l2_format));
120
121 v4l2_fmt.type = node->type;
122 framesize = (node->width * node->height * get_pixel_depth(node->format)) / 8;
123
124 if (node->planes >= 1) {
125 v4l2_fmt.fmt.pix_mp.width = node->width;
126 v4l2_fmt.fmt.pix_mp.height = node->height;
127 v4l2_fmt.fmt.pix_mp.pixelformat = node->format;
128 v4l2_fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
129 } else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900130 ALOGE("%s:S_FMT, Out of bound : Number of element plane",__FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700131 }
132
133 /* Set up for capture */
134 ret = exynos_v4l2_s_fmt(node->fd, &v4l2_fmt);
135
136 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900137 ALOGE("%s: exynos_v4l2_s_fmt fail (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700138
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700139
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700140 return ret;
141}
142
143int cam_int_reqbufs(node_info_t *node)
144{
145 struct v4l2_requestbuffers req;
146 int ret;
147
148 req.count = node->buffers;
149 req.type = node->type;
150 req.memory = node->memory;
151
152 ret = exynos_v4l2_reqbufs(node->fd, &req);
153
154 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900155 ALOGE("%s: VIDIOC_REQBUFS (fd:%d) failed (%d)",__FUNCTION__,node->fd, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700156
157 return req.count;
158}
159
160int cam_int_qbuf(node_info_t *node, int index)
161{
162 struct v4l2_buffer v4l2_buf;
163 struct v4l2_plane planes[VIDEO_MAX_PLANES];
164 int i;
165 int ret = 0;
166
167 v4l2_buf.m.planes = planes;
168 v4l2_buf.type = node->type;
169 v4l2_buf.memory = node->memory;
170 v4l2_buf.index = index;
171 v4l2_buf.length = node->planes;
172
173 for(i = 0; i < node->planes; i++){
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900174 v4l2_buf.m.planes[i].m.fd = (int)(node->buffer[index].fd.extFd[i]);
175 v4l2_buf.m.planes[i].length = (unsigned long)(node->buffer[index].size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700176 }
177
178 ret = exynos_v4l2_qbuf(node->fd, &v4l2_buf);
179
180 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900181 ALOGE("%s: cam_int_qbuf failed (index:%d)(ret:%d)",__FUNCTION__, index, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700182
183 return ret;
184}
185
186int cam_int_streamon(node_info_t *node)
187{
188 enum v4l2_buf_type type = node->type;
189 int ret;
190
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700191
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700192 ret = exynos_v4l2_streamon(node->fd, type);
193
194 if (ret < 0)
Sungjoong Kangad378612012-08-17 12:34:33 -0700195 ALOGE("%s: VIDIOC_STREAMON failed [%d] (%d)",__FUNCTION__, node->fd,ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700196
197 ALOGV("On streaming I/O... ... fd(%d)", node->fd);
198
199 return ret;
200}
201
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900202int cam_int_streamoff(node_info_t *node)
203{
Sungjoong Kangad378612012-08-17 12:34:33 -0700204 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
205 int ret;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900206
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700207
Sungjoong Kangad378612012-08-17 12:34:33 -0700208 ALOGV("Off streaming I/O... fd(%d)", node->fd);
209 ret = exynos_v4l2_streamoff(node->fd, type);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900210
211 if (ret < 0)
212 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
213
Sungjoong Kangad378612012-08-17 12:34:33 -0700214 return ret;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900215}
216
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900217int isp_int_streamoff(node_info_t *node)
218{
Sungjoong Kangad378612012-08-17 12:34:33 -0700219 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
220 int ret;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900221
Sungjoong Kangad378612012-08-17 12:34:33 -0700222 ALOGV("Off streaming I/O... fd(%d)", node->fd);
223 ret = exynos_v4l2_streamoff(node->fd, type);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900224
225 if (ret < 0)
226 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
227
Sungjoong Kangad378612012-08-17 12:34:33 -0700228 return ret;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900229}
230
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700231int cam_int_dqbuf(node_info_t *node)
232{
233 struct v4l2_buffer v4l2_buf;
234 struct v4l2_plane planes[VIDEO_MAX_PLANES];
235 int ret;
236
237 v4l2_buf.type = node->type;
238 v4l2_buf.memory = node->memory;
239 v4l2_buf.m.planes = planes;
240 v4l2_buf.length = node->planes;
241
242 ret = exynos_v4l2_dqbuf(node->fd, &v4l2_buf);
243 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900244 ALOGE("%s: VIDIOC_DQBUF failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700245
246 return v4l2_buf.index;
247}
248
Sungjoong Kangfeb7df42012-08-28 23:35:43 +0900249int cam_int_dqbuf(node_info_t *node, int num_plane)
250{
251 struct v4l2_buffer v4l2_buf;
252 struct v4l2_plane planes[VIDEO_MAX_PLANES];
253 int ret;
254
255 v4l2_buf.type = node->type;
256 v4l2_buf.memory = node->memory;
257 v4l2_buf.m.planes = planes;
258 v4l2_buf.length = num_plane;
259
260 ret = exynos_v4l2_dqbuf(node->fd, &v4l2_buf);
261 if (ret < 0)
262 ALOGE("%s: VIDIOC_DQBUF failed (%d)",__FUNCTION__, ret);
263
264 return v4l2_buf.index;
265}
266
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700267int cam_int_s_input(node_info_t *node, int index)
268{
269 int ret;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900270
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700271 ret = exynos_v4l2_s_input(node->fd, index);
272 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900273 ALOGE("%s: VIDIOC_S_INPUT failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700274
275 return ret;
276}
277
278
279gralloc_module_t const* ExynosCameraHWInterface2::m_grallocHal;
280
281RequestManager::RequestManager(SignalDrivenThread* main_thread):
Sungjoong Kang2bdec062012-08-17 15:47:56 -0700282 m_lastAeMode(0),
283 m_lastAaMode(0),
284 m_lastAwbMode(0),
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700285 m_vdisBubbleEn(false),
Sungjoong Kang2bdec062012-08-17 15:47:56 -0700286 m_lastAeComp(0),
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700287 m_lastCompletedFrameCnt(-1)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700288{
289 m_metadataConverter = new MetadataConverter;
290 m_mainThread = main_thread;
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900291 ResetEntry();
Sungjoong Kangad378612012-08-17 12:34:33 -0700292 m_sensorPipelineSkipCnt = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700293 return;
294}
295
296RequestManager::~RequestManager()
297{
Sungjoong Kang15fd8232012-08-23 16:16:44 -0700298 ALOGV("%s", __FUNCTION__);
299 if (m_metadataConverter != NULL) {
300 delete m_metadataConverter;
301 m_metadataConverter = NULL;
302 }
303
Sungjoong Kang52f54302012-09-04 21:43:06 +0900304 releaseSensorQ();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700305 return;
306}
307
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900308void RequestManager::ResetEntry()
309{
310 Mutex::Autolock lock(m_requestMutex);
311 for (int i=0 ; i<NUM_MAX_REQUEST_MGR_ENTRY; i++) {
312 memset(&(entries[i]), 0x00, sizeof(request_manager_entry_t));
313 entries[i].internal_shot.shot.ctl.request.frameCount = -1;
314 }
315 m_numOfEntries = 0;
316 m_entryInsertionIndex = -1;
317 m_entryProcessingIndex = -1;
318 m_entryFrameOutputIndex = -1;
319}
320
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700321int RequestManager::GetNumEntries()
322{
323 return m_numOfEntries;
324}
325
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900326void RequestManager::SetDefaultParameters(int cropX)
327{
328 m_cropX = cropX;
329}
330
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700331bool RequestManager::IsRequestQueueFull()
332{
333 Mutex::Autolock lock(m_requestMutex);
334 if (m_numOfEntries>=NUM_MAX_REQUEST_MGR_ENTRY)
335 return true;
336 else
337 return false;
338}
339
340void RequestManager::RegisterRequest(camera_metadata_t * new_request)
341{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900342 ALOGV("DEBUG(%s):", __FUNCTION__);
343
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700344 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900345
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700346 request_manager_entry * newEntry = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900347 int newInsertionIndex = GetNextIndex(m_entryInsertionIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900348 ALOGV("DEBUG(%s): got lock, new insertIndex(%d), cnt before reg(%d)", __FUNCTION__,newInsertionIndex,m_numOfEntries );
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700349
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900350
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700351 newEntry = &(entries[newInsertionIndex]);
352
353 if (newEntry->status!=EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900354 ALOGV("DEBUG(%s): Circular buffer abnormal ", __FUNCTION__);
355 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700356 }
357 newEntry->status = REGISTERED;
358 newEntry->original_request = new_request;
Sungjoong Kangad378612012-08-17 12:34:33 -0700359 memset(&(newEntry->internal_shot), 0, sizeof(struct camera2_shot_ext));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900360 m_metadataConverter->ToInternalShot(new_request, &(newEntry->internal_shot));
Sungjoong Kanga85ec382012-09-23 16:49:12 -0700361 newEntry->output_stream_count = 0;
362 if (newEntry->internal_shot.shot.ctl.request.outputStreams[0] & MASK_OUTPUT_SCP)
363 newEntry->output_stream_count++;
364
365 if (newEntry->internal_shot.shot.ctl.request.outputStreams[0] & MASK_OUTPUT_SCC)
366 newEntry->output_stream_count++;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700367
368 m_numOfEntries++;
369 m_entryInsertionIndex = newInsertionIndex;
370
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900371
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700372 ALOGV("## RegisterReq DONE num(%d), insert(%d), processing(%d), frame(%d), (frameCnt(%d))",
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700373 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex, newEntry->internal_shot.shot.ctl.request.frameCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700374}
375
376void RequestManager::DeregisterRequest(camera_metadata_t ** deregistered_request)
377{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900378 ALOGV("DEBUG(%s):", __FUNCTION__);
Sungjoong Kangad378612012-08-17 12:34:33 -0700379 int frame_index;
380 request_manager_entry * currentEntry;
381
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700382 Mutex::Autolock lock(m_requestMutex);
383
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700384 frame_index = GetCompletedIndex();
Sungjoong Kangad378612012-08-17 12:34:33 -0700385 currentEntry = &(entries[frame_index]);
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700386 if (currentEntry->status != COMPLETED) {
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700387 CAM_LOGD("DBG(%s): Circular buffer abnormal. processing(%d), frame(%d), status(%d) ", __FUNCTION__,
388 m_entryProcessingIndex, frame_index,(int)(currentEntry->status));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900389 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700390 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900391 if (deregistered_request) *deregistered_request = currentEntry->original_request;
392
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700393 m_lastCompletedFrameCnt = currentEntry->internal_shot.shot.ctl.request.frameCount;
394
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700395 currentEntry->status = EMPTY;
396 currentEntry->original_request = NULL;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700397 memset(&(currentEntry->internal_shot), 0, sizeof(struct camera2_shot_ext));
398 currentEntry->internal_shot.shot.ctl.request.frameCount = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700399 currentEntry->output_stream_count = 0;
400 m_numOfEntries--;
401 ALOGV("## DeRegistReq DONE num(%d), insert(%d), processing(%d), frame(%d)",
402 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900403
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700404 CheckCompleted(GetNextIndex(frame_index));
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700405 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700406}
407
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900408bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700409 camera_metadata_t ** prepared_frame, int afState)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700410{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900411 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700412 Mutex::Autolock lock(m_requestMutex);
413 status_t res = NO_ERROR;
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700414 int tempFrameOutputIndex = GetCompletedIndex();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900415 request_manager_entry * currentEntry = &(entries[tempFrameOutputIndex]);
416 ALOGV("DEBUG(%s): processing(%d), frameOut(%d), insert(%d) recentlycompleted(%d)", __FUNCTION__,
417 m_entryProcessingIndex, m_entryFrameOutputIndex, m_entryInsertionIndex, m_completedIndex);
418
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700419 if (currentEntry->status != COMPLETED) {
Sungjoong Kangad378612012-08-17 12:34:33 -0700420 ALOGV("DBG(%s): Circular buffer abnormal status(%d)", __FUNCTION__, (int)(currentEntry->status));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900421
422 return false;
423 }
424 m_entryFrameOutputIndex = tempFrameOutputIndex;
Younghwan Joo07b3ad12012-10-03 16:48:02 +0900425 m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 35, 500); //estimated
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700426 add_camera_metadata_entry(m_tempFrameMetadata, ANDROID_CONTROL_AF_STATE, &afState, 1);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900427 res = m_metadataConverter->ToDynamicMetadata(&(currentEntry->internal_shot),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700428 m_tempFrameMetadata);
429 if (res!=NO_ERROR) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900430 ALOGE("ERROR(%s): ToDynamicMetadata (%d) ", __FUNCTION__, res);
431 return false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700432 }
433 *num_entries = get_camera_metadata_entry_count(m_tempFrameMetadata);
434 *frame_size = get_camera_metadata_size(m_tempFrameMetadata);
435 *prepared_frame = m_tempFrameMetadata;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700436 ALOGV("## PrepareFrame DONE: frameOut(%d) frameCnt-req(%d) timestamp(%lld)", m_entryFrameOutputIndex,
437 currentEntry->internal_shot.shot.ctl.request.frameCount, currentEntry->internal_shot.shot.dm.sensor.timeStamp);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900438 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900439 return true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700440}
441
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700442int RequestManager::MarkProcessingRequest(ExynosBuffer* buf, int *afMode)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700443{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900444 struct camera2_shot_ext * shot_ext;
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700445 struct camera2_shot_ext * request_shot;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900446 int targetStreamIndex = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -0700447 request_manager_entry * newEntry = NULL;
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700448 static int count = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900449
Sungjoong Kang52f54302012-09-04 21:43:06 +0900450 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900451 if (m_numOfEntries == 0) {
hyeonmyeong Choi4aa4d732012-09-10 11:53:49 -0700452 CAM_LOGD("DEBUG(%s): Request Manager Empty ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900453 return -1;
454 }
455
456 if ((m_entryProcessingIndex == m_entryInsertionIndex)
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700457 && (entries[m_entryProcessingIndex].status == REQUESTED || entries[m_entryProcessingIndex].status == CAPTURED)) {
Younghwan Jooda7ca692012-09-03 20:47:21 -0700458 ALOGV("## MarkProcReq skipping(request underrun) - num(%d), insert(%d), processing(%d), frame(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900459 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
460 return -1;
461 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700462
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900463 int newProcessingIndex = GetNextIndex(m_entryProcessingIndex);
Sungjoong Kangad378612012-08-17 12:34:33 -0700464 ALOGV("DEBUG(%s): index(%d)", __FUNCTION__, newProcessingIndex);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700465
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700466 newEntry = &(entries[newProcessingIndex]);
Sungjoong Kangad378612012-08-17 12:34:33 -0700467 request_shot = &(newEntry->internal_shot);
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700468 *afMode = (int)(newEntry->internal_shot.shot.ctl.aa.afMode);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700469 if (newEntry->status != REGISTERED) {
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700470 CAM_LOGD("DEBUG(%s)(%d): Circular buffer abnormal, numOfEntries(%d), status(%d)", __FUNCTION__, newProcessingIndex, m_numOfEntries, newEntry->status);
471 for (int i = 0; i < NUM_MAX_REQUEST_MGR_ENTRY; i++) {
472 CAM_LOGD("DBG: entrie[%d].stream output cnt = %d, framecnt(%d)", i, entries[i].output_stream_count, entries[i].internal_shot.shot.ctl.request.frameCount);
473 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900474 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700475 }
Sungjoong Kangad378612012-08-17 12:34:33 -0700476
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700477 newEntry->status = REQUESTED;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700478
Sungjoong Kangad378612012-08-17 12:34:33 -0700479 shot_ext = (struct camera2_shot_ext *)buf->virt.extP[1];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900480
Sungjoong Kangad378612012-08-17 12:34:33 -0700481 memset(shot_ext, 0x00, sizeof(struct camera2_shot_ext));
482 shot_ext->shot.ctl.request.frameCount = request_shot->shot.ctl.request.frameCount;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900483 shot_ext->request_sensor = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900484 shot_ext->dis_bypass = 1;
485 shot_ext->dnr_bypass = 1;
Sungjoong Kangad378612012-08-17 12:34:33 -0700486 shot_ext->fd_bypass = 1;
487 shot_ext->setfile = 0;
488
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700489 targetStreamIndex = newEntry->internal_shot.shot.ctl.request.outputStreams[0];
490 shot_ext->shot.ctl.request.outputStreams[0] = targetStreamIndex;
491 if (targetStreamIndex & MASK_OUTPUT_SCP)
492 shot_ext->request_scp = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900493
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700494 if (targetStreamIndex & MASK_OUTPUT_SCC)
495 shot_ext->request_scc = 1;
496
497 if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
498 shot_ext->fd_bypass = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -0700499
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700500 if (count == 0){
501 shot_ext->shot.ctl.aa.mode = AA_CONTROL_AUTO;
502 } else
503 shot_ext->shot.ctl.aa.mode = AA_CONTROL_NONE;
504
505 count++;
Sungjoong Kangad378612012-08-17 12:34:33 -0700506 shot_ext->shot.ctl.request.metadataMode = METADATA_MODE_FULL;
507 shot_ext->shot.ctl.stats.faceDetectMode = FACEDETECT_MODE_FULL;
508 shot_ext->shot.magicNumber = 0x23456789;
509 shot_ext->shot.ctl.sensor.exposureTime = 0;
510 shot_ext->shot.ctl.sensor.frameDuration = 33*1000*1000;
511 shot_ext->shot.ctl.sensor.sensitivity = 0;
512
Sungjoong Kange4657e32012-08-28 15:02:19 -0700513
514 shot_ext->shot.ctl.scaler.cropRegion[0] = newEntry->internal_shot.shot.ctl.scaler.cropRegion[0];
515 shot_ext->shot.ctl.scaler.cropRegion[1] = newEntry->internal_shot.shot.ctl.scaler.cropRegion[1];
516 shot_ext->shot.ctl.scaler.cropRegion[2] = newEntry->internal_shot.shot.ctl.scaler.cropRegion[2];
Sungjoong Kangad378612012-08-17 12:34:33 -0700517
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900518 m_entryProcessingIndex = newProcessingIndex;
Sungjoong Kangad378612012-08-17 12:34:33 -0700519 return newProcessingIndex;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700520}
521
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900522void RequestManager::NotifyStreamOutput(int frameCnt)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700523{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900524 int index;
525
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900526 Mutex::Autolock lock(m_requestMutex);
527 ALOGV("DEBUG(%s): frameCnt(%d)", __FUNCTION__, frameCnt);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900528
529 index = FindEntryIndexByFrameCnt(frameCnt);
530 if (index == -1) {
531 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
532 return;
533 }
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900534 ALOGV("DEBUG(%s): frameCnt(%d), last cnt (%d)", __FUNCTION__, frameCnt, entries[index].output_stream_count);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900535
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700536 entries[index].output_stream_count--; //TODO : match stream id also
537 CheckCompleted(index);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700538}
539
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900540void RequestManager::CheckCompleted(int index)
541{
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700542 if ((entries[index].status == METADONE || entries[index].status == COMPLETED)
543 && (entries[index].output_stream_count <= 0)){
544 ALOGV("(%s): Completed(index:%d)(frameCnt:%d)", __FUNCTION__,
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900545 index, entries[index].internal_shot.shot.ctl.request.frameCount );
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700546 entries[index].status = COMPLETED;
547 if (m_lastCompletedFrameCnt + 1 == entries[index].internal_shot.shot.ctl.request.frameCount)
548 m_mainThread->SetSignal(SIGNAL_MAIN_STREAM_OUTPUT_DONE);
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900549 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900550}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900551
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700552int RequestManager::GetCompletedIndex()
Sungjoong Kangad378612012-08-17 12:34:33 -0700553{
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700554 return FindEntryIndexByFrameCnt(m_lastCompletedFrameCnt + 1);
Sungjoong Kangad378612012-08-17 12:34:33 -0700555}
556
Sungjoong Kang52f54302012-09-04 21:43:06 +0900557void RequestManager::pushSensorQ(int index)
558{
559 Mutex::Autolock lock(m_requestMutex);
560 m_sensorQ.push_back(index);
561}
562
563int RequestManager::popSensorQ()
564{
565 List<int>::iterator sensor_token;
566 int index;
567
568 Mutex::Autolock lock(m_requestMutex);
569
570 if(m_sensorQ.size() == 0)
571 return -1;
572
573 sensor_token = m_sensorQ.begin()++;
574 index = *sensor_token;
575 m_sensorQ.erase(sensor_token);
576
577 return (index);
578}
579
580void RequestManager::releaseSensorQ()
581{
582 List<int>::iterator r;
583
584 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -0700585 ALOGV("(%s)m_sensorQ.size : %d", __FUNCTION__, m_sensorQ.size());
Sungjoong Kang52f54302012-09-04 21:43:06 +0900586
587 while(m_sensorQ.size() > 0){
588 r = m_sensorQ.begin()++;
589 m_sensorQ.erase(r);
590 }
591 return;
592}
593
Sungjoong Kangad378612012-08-17 12:34:33 -0700594void RequestManager::ApplyDynamicMetadata(struct camera2_shot_ext *shot_ext)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900595{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900596 int index;
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700597 struct camera2_shot_ext * request_shot;
598 nsecs_t timeStamp;
Sungjoong Kangad378612012-08-17 12:34:33 -0700599 int i;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900600
Sungjoong Kang52f54302012-09-04 21:43:06 +0900601 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kangad378612012-08-17 12:34:33 -0700602 ALOGV("DEBUG(%s): frameCnt(%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900603
Sungjoong Kangad378612012-08-17 12:34:33 -0700604 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
605 if((entries[i].internal_shot.shot.ctl.request.frameCount == shot_ext->shot.ctl.request.frameCount)
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900606 && (entries[i].status == CAPTURED)){
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700607 entries[i].status = METADONE;
Sungjoong Kangad378612012-08-17 12:34:33 -0700608 break;
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900609 }
Sungjoong Kangad378612012-08-17 12:34:33 -0700610 }
611
612 if (i == NUM_MAX_REQUEST_MGR_ENTRY){
613 ALOGE("[%s] no entry found(framecount:%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900614 return;
615 }
616
Sungjoong Kangad378612012-08-17 12:34:33 -0700617 request_manager_entry * newEntry = &(entries[i]);
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700618 request_shot = &(newEntry->internal_shot);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900619
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700620 timeStamp = request_shot->shot.dm.sensor.timeStamp;
Sungjoong Kangad378612012-08-17 12:34:33 -0700621 memcpy(&(request_shot->shot.dm), &(shot_ext->shot.dm), sizeof(struct camera2_dm));
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700622 request_shot->shot.dm.sensor.timeStamp = timeStamp;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700623 m_lastTimeStamp = timeStamp;
Sungjoong Kangad378612012-08-17 12:34:33 -0700624 CheckCompleted(i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900625}
626
Younghwan Joo53f62ad2012-09-12 11:50:04 -0700627void RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, int frameCnt, ctl_request_info_t *ctl_info)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900628{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900629 int index, targetStreamIndex;
Sungjoong Kangb56dcc02012-08-08 13:38:09 -0700630 struct camera2_shot_ext * request_shot;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900631
632 ALOGV("DEBUG(%s): updating info with frameCnt(%d)", __FUNCTION__, frameCnt);
633 if (frameCnt < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900634 return;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900635
636 index = FindEntryIndexByFrameCnt(frameCnt);
637 if (index == -1) {
638 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
639 return;
640 }
641
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900642 request_manager_entry * newEntry = &(entries[index]);
Sungjoong Kangad378612012-08-17 12:34:33 -0700643 request_shot = &(newEntry->internal_shot);
Sungjoong Kang2bdec062012-08-17 15:47:56 -0700644 memcpy(&(shot_ext->shot.ctl), &(request_shot->shot.ctl), sizeof(struct camera2_ctl));
Jiyoung Shin2adfa422012-09-10 23:14:54 +0900645 shot_ext->shot.ctl.request.frameCount = frameCnt;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900646 shot_ext->request_sensor = 1;
Sungjoong Kangad378612012-08-17 12:34:33 -0700647 shot_ext->dis_bypass = 1;
648 shot_ext->dnr_bypass = 1;
649 shot_ext->fd_bypass = 1;
Sungjoong Kang10e122b2012-09-26 14:04:23 -0700650 shot_ext->drc_bypass = 1;
Sungjoong Kangad378612012-08-17 12:34:33 -0700651 shot_ext->setfile = 0;
652
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900653 shot_ext->request_scc = 0;
654 shot_ext->request_scp = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -0700655
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700656 shot_ext->isReprocessing = request_shot->isReprocessing;
657 shot_ext->reprocessInput = request_shot->reprocessInput;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900658 shot_ext->shot.ctl.request.outputStreams[0] = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900659
Sungjoong Kang48728d42012-09-26 13:48:48 -0700660 shot_ext->awb_mode_dm = request_shot->awb_mode_dm;
661
Sungjoong Kange4657e32012-08-28 15:02:19 -0700662 shot_ext->shot.ctl.scaler.cropRegion[0] = request_shot->shot.ctl.scaler.cropRegion[0];
663 shot_ext->shot.ctl.scaler.cropRegion[1] = request_shot->shot.ctl.scaler.cropRegion[1];
664 shot_ext->shot.ctl.scaler.cropRegion[2] = request_shot->shot.ctl.scaler.cropRegion[2];
665
Younghwan Joo53f62ad2012-09-12 11:50:04 -0700666 // mapping flash UI mode from aeMode
667 if (request_shot->shot.ctl.aa.aeMode >= AA_AEMODE_ON) {
Younghwan Joo4a9565a2012-09-19 18:41:35 -0700668 if (request_shot->shot.ctl.aa.captureIntent == AA_CAPTURE_INTENT_PREVIEW)
Younghwan Joo73f5ad62012-09-16 21:05:30 -0700669 ctl_info->flash.i_flashMode = request_shot->shot.ctl.aa.aeMode;
Younghwan Joo53f62ad2012-09-12 11:50:04 -0700670 request_shot->shot.ctl.aa.aeMode = AA_AEMODE_ON;
671 }
Younghwan Joo53f62ad2012-09-12 11:50:04 -0700672
673 // Apply ae/awb lock or unlock
Younghwan Jooe117f752012-09-12 22:21:55 -0700674 if (request_shot->ae_lock == AEMODE_LOCK_ON)
675 request_shot->shot.ctl.aa.aeMode = AA_AEMODE_LOCKED;
676 if (request_shot->awb_lock == AWBMODE_LOCK_ON)
677 request_shot->shot.ctl.aa.awbMode = AA_AWBMODE_LOCKED;
Younghwan Joo53f62ad2012-09-12 11:50:04 -0700678
Sungjoong Kang2bdec062012-08-17 15:47:56 -0700679 if (m_lastAaMode == request_shot->shot.ctl.aa.mode) {
680 shot_ext->shot.ctl.aa.mode = (enum aa_mode)(0);
681 }
682 else {
683 shot_ext->shot.ctl.aa.mode = request_shot->shot.ctl.aa.mode;
684 m_lastAaMode = (int)(shot_ext->shot.ctl.aa.mode);
685 }
686 if (m_lastAeMode == request_shot->shot.ctl.aa.aeMode) {
687 shot_ext->shot.ctl.aa.aeMode = (enum aa_aemode)(0);
688 }
689 else {
690 shot_ext->shot.ctl.aa.aeMode = request_shot->shot.ctl.aa.aeMode;
691 m_lastAeMode = (int)(shot_ext->shot.ctl.aa.aeMode);
692 }
693 if (m_lastAwbMode == request_shot->shot.ctl.aa.awbMode) {
694 shot_ext->shot.ctl.aa.awbMode = (enum aa_awbmode)(0);
695 }
696 else {
697 shot_ext->shot.ctl.aa.awbMode = request_shot->shot.ctl.aa.awbMode;
698 m_lastAwbMode = (int)(shot_ext->shot.ctl.aa.awbMode);
699 }
700 if (m_lastAeComp == request_shot->shot.ctl.aa.aeExpCompensation) {
701 shot_ext->shot.ctl.aa.aeExpCompensation = 0;
702 }
703 else {
704 shot_ext->shot.ctl.aa.aeExpCompensation = request_shot->shot.ctl.aa.aeExpCompensation;
705 m_lastAeComp = (int)(shot_ext->shot.ctl.aa.aeExpCompensation);
706 }
Sungjoong Kangef6f83c2012-08-28 22:59:48 +0900707
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700708 if (request_shot->shot.ctl.aa.videoStabilizationMode) {
709 m_vdisBubbleEn = true;
710 shot_ext->dis_bypass = 0;
Hyeonmyeong Choi7ef20f42012-10-05 13:10:21 +0900711 shot_ext->dnr_bypass = 0;
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700712 } else {
713 m_vdisBubbleEn = false;
714 shot_ext->dis_bypass = 1;
Hyeonmyeong Choi7ef20f42012-10-05 13:10:21 +0900715 shot_ext->dnr_bypass = 1;
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700716 }
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700717
Sungjoong Kangef6f83c2012-08-28 22:59:48 +0900718 shot_ext->shot.ctl.aa.afTrigger = 0;
719
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700720 targetStreamIndex = newEntry->internal_shot.shot.ctl.request.outputStreams[0];
721 shot_ext->shot.ctl.request.outputStreams[0] = targetStreamIndex;
722 if (targetStreamIndex & MASK_OUTPUT_SCP)
723 shot_ext->request_scp = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900724
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700725 if (targetStreamIndex & MASK_OUTPUT_SCC)
726 shot_ext->request_scc = 1;
727
728 if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
729 shot_ext->fd_bypass = 0;
730
731 if (targetStreamIndex & STREAM_MASK_RECORD) {
732 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
733 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
Sungjoong Kang83bc2902012-09-29 00:21:47 -0700734 } else {
735 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = request_shot->shot.ctl.aa.aeTargetFpsRange[0];
736 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = request_shot->shot.ctl.aa.aeTargetFpsRange[1];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900737 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700738
739 ALOGV("(%s): applied aa(%d) aemode(%d) expComp(%d), awb(%d) afmode(%d), ", __FUNCTION__,
740 (int)(shot_ext->shot.ctl.aa.mode), (int)(shot_ext->shot.ctl.aa.aeMode),
741 (int)(shot_ext->shot.ctl.aa.aeExpCompensation), (int)(shot_ext->shot.ctl.aa.awbMode),
742 (int)(shot_ext->shot.ctl.aa.afMode));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900743}
744
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700745bool RequestManager::IsVdisEnable(void)
746{
747 return m_vdisBubbleEn;
748}
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700749
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900750int RequestManager::FindEntryIndexByFrameCnt(int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900751{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900752 for (int i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700753 if (entries[i].internal_shot.shot.ctl.request.frameCount == frameCnt)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900754 return i;
755 }
756 return -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900757}
758
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900759void RequestManager::RegisterTimestamp(int frameCnt, nsecs_t * frameTime)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900760{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900761 int index = FindEntryIndexByFrameCnt(frameCnt);
762 if (index == -1) {
763 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
764 return;
765 }
766
767 request_manager_entry * currentEntry = &(entries[index]);
Sungjoong Kanga8be0012012-09-19 00:13:43 -0700768 if (currentEntry->internal_shot.isReprocessing == 1) {
769 ALOGV("DEBUG(%s): REPROCESSING : preserving timestamp for reqIndex(%d) frameCnt(%d) (%lld)", __FUNCTION__,
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700770 index, frameCnt, currentEntry->internal_shot.shot.dm.sensor.timeStamp);
Sungjoong Kanga8be0012012-09-19 00:13:43 -0700771 } else {
772 currentEntry->internal_shot.shot.dm.sensor.timeStamp = *((uint64_t*)frameTime);
773 ALOGV("DEBUG(%s): applied timestamp for reqIndex(%d) frameCnt(%d) (%lld)", __FUNCTION__,
774 index, frameCnt, currentEntry->internal_shot.shot.dm.sensor.timeStamp);
775 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900776}
777
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700778
779nsecs_t RequestManager::GetTimestampByFrameCnt(int frameCnt)
780{
781 int index = FindEntryIndexByFrameCnt(frameCnt);
782 if (index == -1) {
783 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d) returning saved time(%lld)", __FUNCTION__, frameCnt, m_lastTimeStamp);
784 return m_lastTimeStamp;
785 }
786 else
787 return GetTimestamp(index);
788}
789
790nsecs_t RequestManager::GetTimestamp(int index)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900791{
Sungjoong Kang5f643a72012-09-13 16:16:51 -0700792 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -0700793 if (index < 0 || index >= NUM_MAX_REQUEST_MGR_ENTRY) {
794 ALOGE("ERR(%s): Request entry outside of bounds (%d)", __FUNCTION__, index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900795 return 0;
796 }
797
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900798 request_manager_entry * currentEntry = &(entries[index]);
Sungjoong Kang5f643a72012-09-13 16:16:51 -0700799 nsecs_t frameTime = currentEntry->internal_shot.shot.dm.sensor.timeStamp;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700800 if (frameTime == 0) {
801 ALOGV("DEBUG(%s): timestamp null, returning saved value", __FUNCTION__);
802 frameTime = m_lastTimeStamp;
803 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900804 ALOGV("DEBUG(%s): Returning timestamp for reqIndex(%d) (%lld)", __FUNCTION__, index, frameTime);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900805 return frameTime;
806}
807
Sungjoong Kang2f4d1752012-09-17 16:50:07 -0700808uint8_t RequestManager::GetOutputStreamByFrameCnt(int frameCnt)
809{
810 int index = FindEntryIndexByFrameCnt(frameCnt);
811 if (index == -1) {
812 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
813 return 0;
814 }
815 else
816 return GetOutputStream(index);
817}
818
819uint8_t RequestManager::GetOutputStream(int index)
820{
821 Mutex::Autolock lock(m_requestMutex);
822 if (index < 0 || index >= NUM_MAX_REQUEST_MGR_ENTRY) {
823 ALOGE("ERR(%s): Request entry outside of bounds (%d)", __FUNCTION__, index);
824 return 0;
825 }
826
827 request_manager_entry * currentEntry = &(entries[index]);
828 return currentEntry->internal_shot.shot.ctl.request.outputStreams[0];
829}
830
Sungjoong Kang69d1e6e2012-10-03 00:39:13 -0700831camera2_shot_ext * RequestManager::GetInternalShotExtByFrameCnt(int frameCnt)
832{
833 int index = FindEntryIndexByFrameCnt(frameCnt);
834 if (index == -1) {
835 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
836 return 0;
837 }
838 else
839 return GetInternalShotExt(index);
840}
841
842camera2_shot_ext * RequestManager::GetInternalShotExt(int index)
843{
844 Mutex::Autolock lock(m_requestMutex);
845 if (index < 0 || index >= NUM_MAX_REQUEST_MGR_ENTRY) {
846 ALOGE("ERR(%s): Request entry outside of bounds (%d)", __FUNCTION__, index);
847 return 0;
848 }
849
850 request_manager_entry * currentEntry = &(entries[index]);
851 return &currentEntry->internal_shot;
852}
853
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900854int RequestManager::FindFrameCnt(struct camera2_shot_ext * shot_ext)
855{
Sungjoong Kang041f38d2012-09-25 01:39:19 -0700856 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kangad378612012-08-17 12:34:33 -0700857 int i;
858
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700859 if (m_numOfEntries == 0) {
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700860 CAM_LOGD("DBG(%s): No Entry found", __FUNCTION__);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700861 return -1;
862 }
Sungjoong Kangad378612012-08-17 12:34:33 -0700863
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700864 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
Sungjoong Kangad378612012-08-17 12:34:33 -0700865 if(entries[i].internal_shot.shot.ctl.request.frameCount != shot_ext->shot.ctl.request.frameCount)
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700866 continue;
Sungjoong Kangad378612012-08-17 12:34:33 -0700867
868 if (entries[i].status == REQUESTED) {
869 entries[i].status = CAPTURED;
870 return entries[i].internal_shot.shot.ctl.request.frameCount;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700871 }
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700872 CAM_LOGE("ERR(%s): frameCount(%d), index(%d), status(%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount, i, entries[i].status);
Sungjoong Kangad378612012-08-17 12:34:33 -0700873
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700874 }
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700875 CAM_LOGD("(%s): No Entry found frame count(%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Sungjoong Kangad378612012-08-17 12:34:33 -0700876
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700877 return -1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900878}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900879
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700880void RequestManager::SetInitialSkip(int count)
881{
882 ALOGV("(%s): Pipeline Restarting. setting cnt(%d) - current(%d)", __FUNCTION__, count, m_sensorPipelineSkipCnt);
883 if (count > m_sensorPipelineSkipCnt)
884 m_sensorPipelineSkipCnt = count;
885}
886
Sungjoong Kangad378612012-08-17 12:34:33 -0700887int RequestManager::GetSkipCnt()
888{
889 ALOGV("(%s): skip cnt(%d)", __FUNCTION__, m_sensorPipelineSkipCnt);
890 if (m_sensorPipelineSkipCnt == 0)
891 return m_sensorPipelineSkipCnt;
892 else
893 return --m_sensorPipelineSkipCnt;
894}
895
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900896void RequestManager::Dump(void)
897{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900898 int i = 0;
899 request_manager_entry * currentEntry;
Sungjoong Kangad378612012-08-17 12:34:33 -0700900 ALOGD("## Dump totalentry(%d), insert(%d), processing(%d), frame(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900901 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
902
903 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
904 currentEntry = &(entries[i]);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700905 ALOGD("[%2d] status[%d] frameCnt[%3d] numOutput[%d] outstream[0]-%x ", i,
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700906 currentEntry->status, currentEntry->internal_shot.shot.ctl.request.frameCount,
Sungjoong Kangad378612012-08-17 12:34:33 -0700907 currentEntry->output_stream_count,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700908 currentEntry->internal_shot.shot.ctl.request.outputStreams[0]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900909 }
910}
911
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900912int RequestManager::GetNextIndex(int index)
913{
914 index++;
915 if (index >= NUM_MAX_REQUEST_MGR_ENTRY)
916 index = 0;
917
918 return index;
919}
920
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700921int RequestManager::GetPrevIndex(int index)
922{
923 index--;
924 if (index < 0)
925 index = NUM_MAX_REQUEST_MGR_ENTRY-1;
926
927 return index;
928}
929
Sungjoong Kang6044e502012-08-27 00:29:28 -0700930ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_t *dev, ExynosCamera2 * camera, int *openInvalid):
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700931 m_requestQueueOps(NULL),
932 m_frameQueueOps(NULL),
933 m_callbackCookie(NULL),
934 m_numOfRemainingReqInSvc(0),
935 m_isRequestQueuePending(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900936 m_isRequestQueueNull(true),
Sungjoong Kangad378612012-08-17 12:34:33 -0700937 m_isIspStarted(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900938 m_ionCameraClient(0),
hyeonmyeong Choi308291d2012-08-29 13:55:01 -0700939 m_zoomRatio(1),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900940 m_scp_closing(false),
941 m_scp_closed(false),
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700942 m_afState(HAL_AFSTATE_INACTIVE),
943 m_afMode(NO_CHANGE),
944 m_afMode2(NO_CHANGE),
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -0700945 m_vdisBubbleCnt(0),
946 m_vdisDupFrame(0),
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700947 m_IsAfModeUpdateRequired(false),
948 m_IsAfTriggerRequired(false),
949 m_IsAfLockRequired(false),
Sungjoong Kang90e439c2012-09-20 02:26:22 -0700950 m_sccLocalBufferValid(false),
Sungjoong Kang15fd8232012-08-23 16:16:44 -0700951 m_wideAspect(false),
Sungjoong Kangb55ed662012-08-31 21:31:34 -0700952 m_scpOutputSignalCnt(0),
953 m_scpOutputImageCnt(0),
Sungjoong Kang0f26b202012-08-17 15:43:12 -0700954 m_afTriggerId(0),
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -0700955 m_afPendingTriggerId(0),
956 m_afModeWaitingCnt(0),
Sungjoong Kangf9a06602012-09-24 13:46:10 -0700957 m_scpForceSuspended(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900958 m_halDevice(dev),
Sungjoong Kanga15b4e32012-08-28 12:55:39 -0700959 m_nightCaptureCnt(0),
Sungjoong Kang2f4d1752012-09-17 16:50:07 -0700960 m_nightCaptureFrameCnt(0),
Sungjoong Kang572470e2012-10-03 19:30:25 -0700961 m_lastSceneMode(0),
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +0900962 m_cameraId(cameraId),
963 m_thumbNailW(160),
964 m_thumbNailH(120)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700965{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -0700966 ALOGD("(%s): ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700967 int ret = 0;
Sungjoong Kang6044e502012-08-27 00:29:28 -0700968 int res = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700969
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900970 m_exynosPictureCSC = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900971 m_exynosVideoCSC = NULL;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900972
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700973 if (!m_grallocHal) {
974 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&m_grallocHal);
975 if (ret)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900976 ALOGE("ERR(%s):Fail on loading gralloc HAL", __FUNCTION__);
977 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700978
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700979 m_camera2 = camera;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700980 m_ionCameraClient = createIonClient(m_ionCameraClient);
981 if(m_ionCameraClient == 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900982 ALOGE("ERR(%s):Fail on ion_client_create", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700983
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900984
985 m_BayerManager = new BayerBufManager();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700986 m_mainThread = new MainThread(this);
Sungjoong Kang52f54302012-09-04 21:43:06 +0900987 m_requestManager = new RequestManager((SignalDrivenThread*)(m_mainThread.get()));
Sungjoong Kang6044e502012-08-27 00:29:28 -0700988 *openInvalid = InitializeISPChain();
989 if (*openInvalid < 0) {
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -0700990 ALOGD("(%s): ISP chain init failed. exiting", __FUNCTION__);
Sungjoong Kang6044e502012-08-27 00:29:28 -0700991 // clean process
992 // 1. close video nodes
993 // SCP
Sungjoong Kang5506ceb2012-09-11 20:41:10 -0700994 res = exynos_v4l2_close(m_camera_info.scp.fd);
Sungjoong Kang6044e502012-08-27 00:29:28 -0700995 if (res != NO_ERROR ) {
996 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
997 }
998 // SCC
999 res = exynos_v4l2_close(m_camera_info.capture.fd);
1000 if (res != NO_ERROR ) {
1001 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
1002 }
1003 // Sensor
1004 res = exynos_v4l2_close(m_camera_info.sensor.fd);
1005 if (res != NO_ERROR ) {
1006 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
1007 }
1008 // ISP
1009 res = exynos_v4l2_close(m_camera_info.isp.fd);
1010 if (res != NO_ERROR ) {
1011 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
1012 }
1013 } else {
1014 m_sensorThread = new SensorThread(this);
1015 m_mainThread->Start("MainThread", PRIORITY_DEFAULT, 0);
Sungjoong Kang053d38c2012-09-17 17:46:52 -07001016 m_sensorThread->Start("SensorThread", PRIORITY_DEFAULT, 0);
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001017 ALOGV("DEBUG(%s): created sensorthread ", __FUNCTION__);
Sungjoong Kang52f54302012-09-04 21:43:06 +09001018
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001019 for (int i = 0 ; i < STREAM_ID_LAST+1 ; i++)
1020 m_subStreams[i].type = SUBSTREAM_TYPE_NONE;
Sungjoong Kang6044e502012-08-27 00:29:28 -07001021 CSC_METHOD cscMethod = CSC_METHOD_HW;
1022 m_exynosPictureCSC = csc_init(cscMethod);
1023 if (m_exynosPictureCSC == NULL)
1024 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
1025 csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_FIXED_NODE, PICTURE_GSC_NODE_NUM);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001026
Sungjoong Kang6044e502012-08-27 00:29:28 -07001027 m_exynosVideoCSC = csc_init(cscMethod);
1028 if (m_exynosVideoCSC == NULL)
1029 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
1030 csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_FIXED_NODE, VIDEO_GSC_NODE_NUM);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001031
Sungjoong Kang6044e502012-08-27 00:29:28 -07001032 m_setExifFixedAttribute();
Younghwan Joo9a710a42012-09-05 17:52:08 -07001033
1034 // contol information clear
1035 // flash
1036 m_ctlInfo.flash.i_flashMode = AA_AEMODE_ON;
1037 m_ctlInfo.flash.m_afFlashDoneFlg= false;
Younghwan Joo9a710a42012-09-05 17:52:08 -07001038 m_ctlInfo.flash.m_flashEnableFlg = false;
Younghwan Joo9a710a42012-09-05 17:52:08 -07001039 m_ctlInfo.flash.m_flashFrameCount = 0;
1040 m_ctlInfo.flash.m_flashCnt = 0;
1041 m_ctlInfo.flash.m_flashTimeOut = 0;
Younghwan Joocaea49e2012-09-07 13:34:20 -07001042 m_ctlInfo.flash.m_flashDecisionResult = false;
1043 m_ctlInfo.flash.m_flashTorchMode = false;
Younghwan Jooe117f752012-09-12 22:21:55 -07001044 m_ctlInfo.flash.m_precaptureState = 0;
1045 m_ctlInfo.flash.m_precaptureTriggerId = 0;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07001046 // ae
1047 m_ctlInfo.ae.aeStateNoti = AE_STATE_INACTIVE;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07001048 // af
1049 m_ctlInfo.af.m_afTriggerTimeOut = 0;
Younghwan Joo275c9742012-09-25 21:12:30 +09001050 // scene
1051 m_ctlInfo.scene.prevSceneMode = AA_SCENE_MODE_MAX;
Sungjoong Kang6044e502012-08-27 00:29:28 -07001052 }
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001053 ALOGD("(%s): EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001054}
1055
1056ExynosCameraHWInterface2::~ExynosCameraHWInterface2()
1057{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001058 ALOGD("(%s): ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001059 this->release();
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001060 ALOGD("(%s): EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001061}
1062
1063void ExynosCameraHWInterface2::release()
1064{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001065 int i, res;
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001066 ALOGD("(HAL2::release): ENTER");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001067
Sungjoong Kangad378612012-08-17 12:34:33 -07001068 if (m_streamThreads[1] != NULL) {
1069 m_streamThreads[1]->release();
1070 m_streamThreads[1]->SetSignal(SIGNAL_THREAD_TERMINATE);
1071 }
1072
1073 if (m_streamThreads[0] != NULL) {
1074 m_streamThreads[0]->release();
1075 m_streamThreads[0]->SetSignal(SIGNAL_THREAD_TERMINATE);
1076 }
1077
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001078 if (m_sensorThread != NULL) {
1079 m_sensorThread->release();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001080 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001081
1082 if (m_mainThread != NULL) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001083 m_mainThread->release();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001084 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001085
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001086 if (m_exynosPictureCSC)
1087 csc_deinit(m_exynosPictureCSC);
1088 m_exynosPictureCSC = NULL;
1089
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001090 if (m_exynosVideoCSC)
1091 csc_deinit(m_exynosVideoCSC);
1092 m_exynosVideoCSC = NULL;
1093
Sungjoong Kangad378612012-08-17 12:34:33 -07001094 if (m_streamThreads[1] != NULL) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001095 ALOGD("(HAL2::release): START Waiting for (indirect) stream thread 1 termination");
Sungjoong Kangad378612012-08-17 12:34:33 -07001096 while (!m_streamThreads[1]->IsTerminated())
Sungjoong Kang041f38d2012-09-25 01:39:19 -07001097 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001098 ALOGD("(HAL2::release): END Waiting for (indirect) stream thread 1 termination");
Sungjoong Kangad378612012-08-17 12:34:33 -07001099 m_streamThreads[1] = NULL;
1100 }
1101
1102 if (m_streamThreads[0] != NULL) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001103 ALOGD("(HAL2::release): START Waiting for (indirect) stream thread 0 termination");
Sungjoong Kangad378612012-08-17 12:34:33 -07001104 while (!m_streamThreads[0]->IsTerminated())
Sungjoong Kang041f38d2012-09-25 01:39:19 -07001105 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001106 ALOGD("(HAL2::release): END Waiting for (indirect) stream thread 0 termination");
Sungjoong Kangad378612012-08-17 12:34:33 -07001107 m_streamThreads[0] = NULL;
1108 }
1109
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001110 if (m_sensorThread != NULL) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001111 ALOGD("(HAL2::release): START Waiting for (indirect) sensor thread termination");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001112 while (!m_sensorThread->IsTerminated())
Sungjoong Kang041f38d2012-09-25 01:39:19 -07001113 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001114 ALOGD("(HAL2::release): END Waiting for (indirect) sensor thread termination");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001115 m_sensorThread = NULL;
1116 }
1117
Sungjoong Kangad378612012-08-17 12:34:33 -07001118 if (m_mainThread != NULL) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001119 ALOGD("(HAL2::release): START Waiting for (indirect) main thread termination");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001120 while (!m_mainThread->IsTerminated())
Sungjoong Kang041f38d2012-09-25 01:39:19 -07001121 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07001122 ALOGD("(HAL2::release): END Waiting for (indirect) main thread termination");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001123 m_mainThread = NULL;
1124 }
1125
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001126 if (m_requestManager != NULL) {
1127 delete m_requestManager;
1128 m_requestManager = NULL;
1129 }
1130
1131 if (m_BayerManager != NULL) {
1132 delete m_BayerManager;
1133 m_BayerManager = NULL;
1134 }
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001135 for (i = 0; i < NUM_BAYER_BUFFERS; i++)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001136 freeCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
1137
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001138 if (m_sccLocalBufferValid) {
1139 for (i = 0; i < NUM_SCC_BUFFERS; i++)
1140#ifdef ENABLE_FRAME_SYNC
1141 freeCameraMemory(&m_sccLocalBuffer[i], 2);
1142#else
1143 freeCameraMemory(&m_sccLocalBuffer[i], 1);
1144#endif
1145 }
1146 else {
1147 for (i = 0; i < NUM_SCC_BUFFERS; i++)
1148 freeCameraMemory(&m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
1149 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001150
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001151 ALOGV("DEBUG(%s): calling exynos_v4l2_close - sensor", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001152 res = exynos_v4l2_close(m_camera_info.sensor.fd);
1153 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001154 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001155 }
1156
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001157 ALOGV("DEBUG(%s): calling exynos_v4l2_close - isp", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001158 res = exynos_v4l2_close(m_camera_info.isp.fd);
1159 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001160 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001161 }
1162
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001163 ALOGV("DEBUG(%s): calling exynos_v4l2_close - capture", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001164 res = exynos_v4l2_close(m_camera_info.capture.fd);
1165 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001166 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001167 }
1168
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001169 ALOGV("DEBUG(%s): calling exynos_v4l2_close - scp", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001170 res = exynos_v4l2_close(m_camera_info.scp.fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001171 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001172 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001173 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001174 ALOGV("DEBUG(%s): calling deleteIonClient", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001175 deleteIonClient(m_ionCameraClient);
Sungjoong Kangad378612012-08-17 12:34:33 -07001176
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001177 ALOGD("(HAL2::release): EXIT");
Sungjoong Kangad378612012-08-17 12:34:33 -07001178}
1179
Sungjoong Kang6044e502012-08-27 00:29:28 -07001180int ExynosCameraHWInterface2::InitializeISPChain()
Sungjoong Kangad378612012-08-17 12:34:33 -07001181{
1182 char node_name[30];
1183 int fd = 0;
1184 int i;
Sungjoong Kang6044e502012-08-27 00:29:28 -07001185 int ret = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -07001186
1187 /* Open Sensor */
1188 memset(&node_name, 0x00, sizeof(char[30]));
1189 sprintf(node_name, "%s%d", NODE_PREFIX, 40);
1190 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1191
1192 if (fd < 0) {
1193 ALOGE("ERR(%s): failed to open sensor video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1194 }
1195 else {
1196 ALOGV("DEBUG(%s): sensor video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1197 }
1198 m_camera_info.sensor.fd = fd;
1199
1200 /* Open ISP */
1201 memset(&node_name, 0x00, sizeof(char[30]));
1202 sprintf(node_name, "%s%d", NODE_PREFIX, 41);
1203 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1204
1205 if (fd < 0) {
1206 ALOGE("ERR(%s): failed to open isp video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1207 }
1208 else {
1209 ALOGV("DEBUG(%s): isp video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1210 }
1211 m_camera_info.isp.fd = fd;
1212
1213 /* Open ScalerC */
1214 memset(&node_name, 0x00, sizeof(char[30]));
1215 sprintf(node_name, "%s%d", NODE_PREFIX, 42);
1216 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1217
1218 if (fd < 0) {
1219 ALOGE("ERR(%s): failed to open capture video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1220 }
1221 else {
1222 ALOGV("DEBUG(%s): capture video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1223 }
1224 m_camera_info.capture.fd = fd;
1225
1226 /* Open ScalerP */
1227 memset(&node_name, 0x00, sizeof(char[30]));
1228 sprintf(node_name, "%s%d", NODE_PREFIX, 44);
1229 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1230 if (fd < 0) {
1231 ALOGE("DEBUG(%s): failed to open preview video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1232 }
1233 else {
1234 ALOGV("DEBUG(%s): preview video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1235 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001236 m_camera_info.scp.fd = fd;
Sungjoong Kangad378612012-08-17 12:34:33 -07001237
1238 if(m_cameraId == 0)
1239 m_camera_info.sensor_id = SENSOR_NAME_S5K4E5;
1240 else
1241 m_camera_info.sensor_id = SENSOR_NAME_S5K6A3;
1242
1243 memset(&m_camera_info.dummy_shot, 0x00, sizeof(struct camera2_shot_ext));
1244 m_camera_info.dummy_shot.shot.ctl.request.metadataMode = METADATA_MODE_FULL;
1245 m_camera_info.dummy_shot.shot.magicNumber = 0x23456789;
1246
1247 m_camera_info.dummy_shot.dis_bypass = 1;
1248 m_camera_info.dummy_shot.dnr_bypass = 1;
1249 m_camera_info.dummy_shot.fd_bypass = 1;
1250
1251 /*sensor setting*/
1252 m_camera_info.dummy_shot.shot.ctl.sensor.exposureTime = 0;
1253 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 0;
1254 m_camera_info.dummy_shot.shot.ctl.sensor.sensitivity = 0;
1255
1256 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[0] = 0;
1257 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[1] = 0;
1258
1259 /*request setting*/
1260 m_camera_info.dummy_shot.request_sensor = 1;
1261 m_camera_info.dummy_shot.request_scc = 0;
1262 m_camera_info.dummy_shot.request_scp = 0;
1263 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[0] = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -07001264
1265 m_camera_info.sensor.width = m_camera2->getSensorRawW();
1266 m_camera_info.sensor.height = m_camera2->getSensorRawH();
1267
1268 m_camera_info.sensor.format = V4L2_PIX_FMT_SBGGR16;
1269 m_camera_info.sensor.planes = 2;
1270 m_camera_info.sensor.buffers = NUM_BAYER_BUFFERS;
1271 m_camera_info.sensor.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1272 m_camera_info.sensor.memory = V4L2_MEMORY_DMABUF;
Sungjoong Kangad378612012-08-17 12:34:33 -07001273
1274 for(i = 0; i < m_camera_info.sensor.buffers; i++){
1275 initCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
1276 m_camera_info.sensor.buffer[i].size.extS[0] = m_camera_info.sensor.width*m_camera_info.sensor.height*2;
1277 m_camera_info.sensor.buffer[i].size.extS[1] = 8*1024; // HACK, driver use 8*1024, should be use predefined value
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001278 allocCameraMemory(m_ionCameraClient, &m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes, 1<<1);
Sungjoong Kangad378612012-08-17 12:34:33 -07001279 }
1280
1281 m_camera_info.isp.width = m_camera_info.sensor.width;
1282 m_camera_info.isp.height = m_camera_info.sensor.height;
1283 m_camera_info.isp.format = m_camera_info.sensor.format;
1284 m_camera_info.isp.planes = m_camera_info.sensor.planes;
1285 m_camera_info.isp.buffers = m_camera_info.sensor.buffers;
1286 m_camera_info.isp.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1287 m_camera_info.isp.memory = V4L2_MEMORY_DMABUF;
Sungjoong Kangad378612012-08-17 12:34:33 -07001288
1289 for(i = 0; i < m_camera_info.isp.buffers; i++){
1290 initCameraMemory(&m_camera_info.isp.buffer[i], m_camera_info.isp.planes);
1291 m_camera_info.isp.buffer[i].size.extS[0] = m_camera_info.sensor.buffer[i].size.extS[0];
1292 m_camera_info.isp.buffer[i].size.extS[1] = m_camera_info.sensor.buffer[i].size.extS[1];
1293 m_camera_info.isp.buffer[i].fd.extFd[0] = m_camera_info.sensor.buffer[i].fd.extFd[0];
1294 m_camera_info.isp.buffer[i].fd.extFd[1] = m_camera_info.sensor.buffer[i].fd.extFd[1];
1295 m_camera_info.isp.buffer[i].virt.extP[0] = m_camera_info.sensor.buffer[i].virt.extP[0];
1296 m_camera_info.isp.buffer[i].virt.extP[1] = m_camera_info.sensor.buffer[i].virt.extP[1];
1297 };
1298
1299 /* init ISP */
Sungjoong Kang6044e502012-08-27 00:29:28 -07001300 ret = cam_int_s_input(&(m_camera_info.isp), m_camera_info.sensor_id);
1301 if (ret < 0) {
1302 ALOGE("ERR(%s): cam_int_s_input(%d) failed!!!! ", __FUNCTION__, m_camera_info.sensor_id);
1303 return false;
1304 }
Sungjoong Kangad378612012-08-17 12:34:33 -07001305 cam_int_s_fmt(&(m_camera_info.isp));
1306 ALOGV("DEBUG(%s): isp calling reqbuf", __FUNCTION__);
1307 cam_int_reqbufs(&(m_camera_info.isp));
1308 ALOGV("DEBUG(%s): isp calling querybuf", __FUNCTION__);
1309 ALOGV("DEBUG(%s): isp mem alloc done", __FUNCTION__);
1310
1311 /* init Sensor */
1312 cam_int_s_input(&(m_camera_info.sensor), m_camera_info.sensor_id);
1313 ALOGV("DEBUG(%s): sensor s_input done", __FUNCTION__);
1314 if (cam_int_s_fmt(&(m_camera_info.sensor))< 0) {
1315 ALOGE("ERR(%s): sensor s_fmt fail", __FUNCTION__);
1316 }
1317 ALOGV("DEBUG(%s): sensor s_fmt done", __FUNCTION__);
1318 cam_int_reqbufs(&(m_camera_info.sensor));
1319 ALOGV("DEBUG(%s): sensor reqbuf done", __FUNCTION__);
1320 for (i = 0; i < m_camera_info.sensor.buffers; i++) {
1321 ALOGV("DEBUG(%s): sensor initial QBUF [%d]", __FUNCTION__, i);
Sungjoong Kangad378612012-08-17 12:34:33 -07001322 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 33*1000*1000; // apply from frame #1
1323 m_camera_info.dummy_shot.shot.ctl.request.frameCount = -1;
Sungjoong Kang52f54302012-09-04 21:43:06 +09001324 memcpy( m_camera_info.sensor.buffer[i].virt.extP[1], &(m_camera_info.dummy_shot),
1325 sizeof(struct camera2_shot_ext));
Sungjoong Kangad378612012-08-17 12:34:33 -07001326 }
Sungjoong Kang52f54302012-09-04 21:43:06 +09001327
1328 for (i = 0; i < NUM_MIN_SENSOR_QBUF; i++)
1329 cam_int_qbuf(&(m_camera_info.sensor), i);
1330
1331 for (i = NUM_MIN_SENSOR_QBUF; i < m_camera_info.sensor.buffers; i++)
1332 m_requestManager->pushSensorQ(i);
1333
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001334 ALOGV("== stream_on :: sensor");
Sungjoong Kangad378612012-08-17 12:34:33 -07001335 cam_int_streamon(&(m_camera_info.sensor));
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001336 m_camera_info.sensor.status = true;
Sungjoong Kangad378612012-08-17 12:34:33 -07001337
1338 /* init Capture */
1339 m_camera_info.capture.width = m_camera2->getSensorW();
1340 m_camera_info.capture.height = m_camera2->getSensorH();
1341 m_camera_info.capture.format = V4L2_PIX_FMT_YUYV;
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09001342#ifdef ENABLE_FRAME_SYNC
1343 m_camera_info.capture.planes = 2;
1344#else
Sungjoong Kangad378612012-08-17 12:34:33 -07001345 m_camera_info.capture.planes = 1;
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09001346#endif
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001347 m_camera_info.capture.buffers = NUM_SCC_BUFFERS;
Sungjoong Kangad378612012-08-17 12:34:33 -07001348 m_camera_info.capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1349 m_camera_info.capture.memory = V4L2_MEMORY_DMABUF;
Sungjoong Kangad378612012-08-17 12:34:33 -07001350
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001351 m_camera_info.capture.status = false;
1352
1353 return true;
1354}
1355
1356void ExynosCameraHWInterface2::StartSCCThread(bool threadExists)
1357{
1358 ALOGV("(%s)", __FUNCTION__);
1359 StreamThread *AllocatedStream;
1360 stream_parameters_t newParameters;
1361 uint32_t format_actual;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001362
1363
1364 if (!threadExists) {
1365 m_streamThreads[1] = new StreamThread(this, 1);
Sungjoong Kangad378612012-08-17 12:34:33 -07001366 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001367 AllocatedStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07001368 if (!threadExists) {
Sungjoong Kang053d38c2012-09-17 17:46:52 -07001369 AllocatedStream->Start("StreamThread", PRIORITY_DEFAULT, 0);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001370 m_streamThreadInitialize((SignalDrivenThread*)AllocatedStream);
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07001371 AllocatedStream->m_numRegisteredStream = 1;
1372 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001373 AllocatedStream->m_index = 1;
Sungjoong Kangad378612012-08-17 12:34:33 -07001374
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001375 format_actual = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV
1376
1377 newParameters.width = m_camera2->getSensorW();
1378 newParameters.height = m_camera2->getSensorH();
1379 newParameters.format = format_actual;
1380 newParameters.streamOps = NULL;
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001381 newParameters.numHwBuffers = NUM_SCC_BUFFERS;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001382#ifdef ENABLE_FRAME_SYNC
1383 newParameters.planes = 2;
1384#else
1385 newParameters.planes = 1;
1386#endif
1387
1388 newParameters.numSvcBufsInHal = 0;
1389
1390 newParameters.node = &m_camera_info.capture;
1391
1392 AllocatedStream->streamType = STREAM_TYPE_INDIRECT;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001393 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, AllocatedStream->m_numRegisteredStream);
1394
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001395 if (!threadExists) {
1396 if (!m_sccLocalBufferValid) {
1397 for (int i = 0; i < m_camera_info.capture.buffers; i++){
1398 initCameraMemory(&m_camera_info.capture.buffer[i], newParameters.node->planes);
1399 m_camera_info.capture.buffer[i].size.extS[0] = m_camera_info.capture.width*m_camera_info.capture.height*2;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001400#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001401 m_camera_info.capture.buffer[i].size.extS[1] = 4*1024; // HACK, driver use 4*1024, should be use predefined value
1402 allocCameraMemory(m_ionCameraClient, &m_camera_info.capture.buffer[i], m_camera_info.capture.planes, 1<<1);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001403#else
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001404 allocCameraMemory(m_ionCameraClient, &m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001405#endif
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001406 m_sccLocalBuffer[i] = m_camera_info.capture.buffer[i];
1407 }
1408 m_sccLocalBufferValid = true;
1409 }
1410 } else {
1411 if (m_sccLocalBufferValid) {
1412 for (int i = 0; i < m_camera_info.capture.buffers; i++)
1413 m_camera_info.capture.buffer[i] = m_sccLocalBuffer[i];
1414 } else {
1415 ALOGE("(%s): SCC Thread starting with no buffer", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001416 }
1417 }
1418 cam_int_s_input(newParameters.node, m_camera_info.sensor_id);
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001419 m_camera_info.capture.buffers = NUM_SCC_BUFFERS;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001420 cam_int_s_fmt(newParameters.node);
Sungjoong Kangad378612012-08-17 12:34:33 -07001421 ALOGV("DEBUG(%s): capture calling reqbuf", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001422 cam_int_reqbufs(newParameters.node);
Sungjoong Kangad378612012-08-17 12:34:33 -07001423 ALOGV("DEBUG(%s): capture calling querybuf", __FUNCTION__);
1424
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001425 for (int i = 0; i < newParameters.node->buffers; i++) {
Sungjoong Kangad378612012-08-17 12:34:33 -07001426 ALOGV("DEBUG(%s): capture initial QBUF [%d]", __FUNCTION__, i);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001427 cam_int_qbuf(newParameters.node, i);
1428 newParameters.svcBufStatus[i] = ON_DRIVER;
Sungjoong Kangad378612012-08-17 12:34:33 -07001429 }
1430
1431 ALOGV("== stream_on :: capture");
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001432 if (cam_int_streamon(newParameters.node) < 0) {
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001433 ALOGE("ERR(%s): capture stream on fail", __FUNCTION__);
1434 } else {
1435 m_camera_info.capture.status = true;
1436 }
Sungjoong Kang6044e502012-08-27 00:29:28 -07001437
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001438 AllocatedStream->setParameter(&newParameters);
1439 AllocatedStream->m_activated = true;
1440 AllocatedStream->m_isBufferInit = true;
Sungjoong Kangad378612012-08-17 12:34:33 -07001441}
1442
1443void ExynosCameraHWInterface2::StartISP()
1444{
Sungjoong Kangad378612012-08-17 12:34:33 -07001445 ALOGV("== stream_on :: isp");
1446 cam_int_streamon(&(m_camera_info.isp));
Sungjoong Kangad378612012-08-17 12:34:33 -07001447 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_ENABLE_STREAM);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001448}
1449
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001450int ExynosCameraHWInterface2::getCameraId() const
1451{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001452 return m_cameraId;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001453}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001454
1455int ExynosCameraHWInterface2::setRequestQueueSrcOps(const camera2_request_queue_src_ops_t *request_src_ops)
1456{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001457 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001458 if ((NULL != request_src_ops) && (NULL != request_src_ops->dequeue_request)
1459 && (NULL != request_src_ops->free_request) && (NULL != request_src_ops->request_count)) {
1460 m_requestQueueOps = (camera2_request_queue_src_ops_t*)request_src_ops;
1461 return 0;
1462 }
1463 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001464 ALOGE("DEBUG(%s):setRequestQueueSrcOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001465 return 1;
1466 }
1467}
1468
1469int ExynosCameraHWInterface2::notifyRequestQueueNotEmpty()
1470{
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001471 int i = 0;
1472
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001473 ALOGV("DEBUG(%s):setting [SIGNAL_MAIN_REQ_Q_NOT_EMPTY] current(%d)", __FUNCTION__, m_requestManager->GetNumEntries());
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001474 if ((NULL==m_frameQueueOps)|| (NULL==m_requestQueueOps)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001475 ALOGE("DEBUG(%s):queue ops NULL. ignoring request", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001476 return 0;
1477 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001478 m_isRequestQueueNull = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07001479 if (m_requestManager->GetNumEntries() == 0)
Sungjoong Kang572470e2012-10-03 19:30:25 -07001480 m_requestManager->SetInitialSkip(0);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001481
1482 if (m_isIspStarted == false) {
1483 /* isp */
1484 m_camera_info.sensor.buffers = NUM_BAYER_BUFFERS;
1485 m_camera_info.isp.buffers = m_camera_info.sensor.buffers;
1486 cam_int_s_fmt(&(m_camera_info.isp));
1487 cam_int_reqbufs(&(m_camera_info.isp));
1488
1489 /* sensor */
1490 if (m_camera_info.sensor.status == false) {
1491 cam_int_s_fmt(&(m_camera_info.sensor));
1492 cam_int_reqbufs(&(m_camera_info.sensor));
1493
1494 for (i = 0; i < m_camera_info.sensor.buffers; i++) {
1495 ALOGV("DEBUG(%s): sensor initial QBUF [%d]", __FUNCTION__, i);
1496 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 33*1000*1000; // apply from frame #1
1497 m_camera_info.dummy_shot.shot.ctl.request.frameCount = -1;
1498 memcpy( m_camera_info.sensor.buffer[i].virt.extP[1], &(m_camera_info.dummy_shot),
1499 sizeof(struct camera2_shot_ext));
1500 }
1501 for (i = 0; i < NUM_MIN_SENSOR_QBUF; i++)
1502 cam_int_qbuf(&(m_camera_info.sensor), i);
1503
1504 for (i = NUM_MIN_SENSOR_QBUF; i < m_camera_info.sensor.buffers; i++)
1505 m_requestManager->pushSensorQ(i);
1506 ALOGV("DEBUG(%s): calling sensor streamon", __FUNCTION__);
1507 cam_int_streamon(&(m_camera_info.sensor));
1508 m_camera_info.sensor.status = true;
1509 }
1510 }
1511 if (!(m_streamThreads[1].get())) {
1512 ALOGV("DEBUG(%s): stream thread 1 not exist. starting without stream", __FUNCTION__);
1513 StartSCCThread(false);
1514 } else {
1515 if (m_streamThreads[1]->m_activated == false) {
1516 ALOGV("DEBUG(%s): stream thread 1 suspended. restarting", __FUNCTION__);
1517 StartSCCThread(true);
1518 } else {
1519 if (m_camera_info.capture.status == false) {
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001520 m_camera_info.capture.buffers = NUM_SCC_BUFFERS;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001521 cam_int_s_fmt(&(m_camera_info.capture));
1522 ALOGV("DEBUG(%s): capture calling reqbuf", __FUNCTION__);
1523 cam_int_reqbufs(&(m_camera_info.capture));
1524 ALOGV("DEBUG(%s): capture calling querybuf", __FUNCTION__);
1525
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07001526 if (m_streamThreads[1]->streamType == STREAM_TYPE_DIRECT) {
1527 StreamThread * targetStream = m_streamThreads[1].get();
1528 stream_parameters_t *targetStreamParms = &(targetStream->m_parameters);
1529 node_info_t *currentNode = targetStreamParms->node;
1530
1531 struct v4l2_buffer v4l2_buf;
1532 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1533
1534 for (i = 0 ; i < targetStreamParms->numSvcBuffers ; i++) {
1535 v4l2_buf.m.planes = planes;
1536 v4l2_buf.type = currentNode->type;
1537 v4l2_buf.memory = currentNode->memory;
1538
1539 v4l2_buf.length = currentNode->planes;
1540 v4l2_buf.index = i;
1541 ExynosBuffer metaBuf = targetStreamParms->metaBuffers[i];
1542
1543 if (i < currentNode->buffers) {
1544#ifdef ENABLE_FRAME_SYNC
1545 v4l2_buf.m.planes[0].m.fd = targetStreamParms->svcBuffers[i].fd.extFd[0];
1546 v4l2_buf.m.planes[2].m.fd = targetStreamParms->svcBuffers[i].fd.extFd[1];
1547 v4l2_buf.m.planes[1].m.fd = targetStreamParms->svcBuffers[i].fd.extFd[2];
1548 v4l2_buf.length += targetStreamParms->metaPlanes;
1549 v4l2_buf.m.planes[v4l2_buf.length-1].m.fd = metaBuf.fd.extFd[0];
1550 v4l2_buf.m.planes[v4l2_buf.length-1].length = metaBuf.size.extS[0];
1551
1552 ALOGV("Qbuf metaBuf: fd(%d), length(%d) plane(%d)", metaBuf.fd.extFd[0], metaBuf.size.extS[0], v4l2_buf.length);
1553#endif
1554 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
1555 ALOGE("ERR(%s): exynos_v4l2_qbuf() fail fd(%d)", __FUNCTION__, currentNode->fd);
1556 }
1557 ALOGV("DEBUG(%s): exynos_v4l2_qbuf() success fd(%d)", __FUNCTION__, currentNode->fd);
1558 targetStreamParms->svcBufStatus[i] = REQUIRES_DQ_FROM_SVC;
1559 }
1560 else {
1561 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
1562 }
1563
1564 }
1565
1566 } else {
1567 for (int i = 0; i < m_camera_info.capture.buffers; i++) {
1568 ALOGV("DEBUG(%s): capture initial QBUF [%d]", __FUNCTION__, i);
1569 cam_int_qbuf(&(m_camera_info.capture), i);
1570 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001571 }
1572 ALOGV("== stream_on :: capture");
1573 if (cam_int_streamon(&(m_camera_info.capture)) < 0) {
1574 ALOGE("ERR(%s): capture stream on fail", __FUNCTION__);
1575 } else {
1576 m_camera_info.capture.status = true;
1577 }
1578 }
Sungjoong Kangf9a06602012-09-24 13:46:10 -07001579 if (m_scpForceSuspended) {
1580 m_scpForceSuspended = false;
1581 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001582 }
1583 }
1584 if (m_isIspStarted == false) {
1585 StartISP();
1586 ALOGV("DEBUG(%s):starting sensor thread", __FUNCTION__);
Sungjoong Kang71f3bb32012-10-04 13:37:07 -07001587 m_requestManager->SetInitialSkip(6);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001588 m_sensorThread->Start("SensorThread", PRIORITY_DEFAULT, 0);
1589 m_isIspStarted = true;
1590 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001591 m_mainThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
1592 return 0;
1593}
1594
1595int ExynosCameraHWInterface2::setFrameQueueDstOps(const camera2_frame_queue_dst_ops_t *frame_dst_ops)
1596{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001597 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001598 if ((NULL != frame_dst_ops) && (NULL != frame_dst_ops->dequeue_frame)
1599 && (NULL != frame_dst_ops->cancel_frame) && (NULL !=frame_dst_ops->enqueue_frame)) {
1600 m_frameQueueOps = (camera2_frame_queue_dst_ops_t *)frame_dst_ops;
1601 return 0;
1602 }
1603 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001604 ALOGE("DEBUG(%s):setFrameQueueDstOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001605 return 1;
1606 }
1607}
1608
1609int ExynosCameraHWInterface2::getInProgressCount()
1610{
1611 int inProgressCount = m_requestManager->GetNumEntries();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001612 ALOGV("DEBUG(%s): # of dequeued req (%d)", __FUNCTION__, inProgressCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001613 return inProgressCount;
1614}
1615
1616int ExynosCameraHWInterface2::flushCapturesInProgress()
1617{
1618 return 0;
1619}
1620
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001621int ExynosCameraHWInterface2::constructDefaultRequest(int request_template, camera_metadata_t **request)
1622{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001623 ALOGV("DEBUG(%s): making template (%d) ", __FUNCTION__, request_template);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001624
1625 if (request == NULL) return BAD_VALUE;
1626 if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
1627 return BAD_VALUE;
1628 }
1629 status_t res;
1630 // Pass 1, calculate size and allocate
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001631 res = m_camera2->constructDefaultRequest(request_template,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001632 request,
1633 true);
1634 if (res != OK) {
1635 return res;
1636 }
1637 // Pass 2, build request
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001638 res = m_camera2->constructDefaultRequest(request_template,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001639 request,
1640 false);
1641 if (res != OK) {
1642 ALOGE("Unable to populate new request for template %d",
1643 request_template);
1644 }
1645
1646 return res;
1647}
1648
1649int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, int format, const camera2_stream_ops_t *stream_ops,
1650 uint32_t *stream_id, uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers)
1651{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001652 ALOGD("(%s): stream width(%d) height(%d) format(%x)", __FUNCTION__, width, height, format);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001653 bool useDirectOutput = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001654 StreamThread *AllocatedStream;
1655 stream_parameters_t newParameters;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001656 substream_parameters_t *subParameters;
1657 StreamThread *parentStream;
1658 status_t res;
1659 int allocCase = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001660
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001661 if ((format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED || format == CAMERA2_HAL_PIXEL_FORMAT_OPAQUE) &&
1662 m_camera2->isSupportedResolution(width, height)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001663 if (!(m_streamThreads[0].get())) {
1664 ALOGV("DEBUG(%s): stream 0 not exist", __FUNCTION__);
1665 allocCase = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001666 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001667 else {
Alex Ray6bbb5932012-07-27 17:19:48 -07001668 if ((m_streamThreads[0].get())->m_activated == true) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001669 ALOGV("DEBUG(%s): stream 0 exists and activated.", __FUNCTION__);
1670 allocCase = 1;
1671 }
1672 else {
1673 ALOGV("DEBUG(%s): stream 0 exists and deactivated.", __FUNCTION__);
1674 allocCase = 2;
1675 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001676 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001677
1678 // TODO : instead of that, use calculate aspect ratio and selection with calculated ratio.
1679 if ((width == 1920 && height == 1080) || (width == 1280 && height == 720)
1680 || (width == 720 && height == 480) || (width == 1440 && height == 960)
1681 || (width == 1344 && height == 896)) {
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001682 m_wideAspect = true;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001683 } else {
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001684 m_wideAspect = false;
1685 }
1686 ALOGV("DEBUG(%s): m_wideAspect (%d)", __FUNCTION__, m_wideAspect);
1687
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001688 if (allocCase == 0 || allocCase == 2) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001689 *stream_id = STREAM_ID_PREVIEW;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001690
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001691 m_streamThreads[0] = new StreamThread(this, *stream_id);
1692
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001693 AllocatedStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kang053d38c2012-09-17 17:46:52 -07001694 AllocatedStream->Start("StreamThread", PRIORITY_DEFAULT, 0);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001695 m_streamThreadInitialize((SignalDrivenThread*)AllocatedStream);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001696
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001697 *format_actual = HAL_PIXEL_FORMAT_EXYNOS_YV12;
1698 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
1699 *max_buffers = 6;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001700
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001701 newParameters.width = width;
1702 newParameters.height = height;
1703 newParameters.format = *format_actual;
1704 newParameters.streamOps = stream_ops;
1705 newParameters.usage = *usage;
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001706 newParameters.numHwBuffers = NUM_SCP_BUFFERS;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001707 newParameters.numOwnSvcBuffers = *max_buffers;
1708 newParameters.planes = NUM_PLANES(*format_actual);
1709 newParameters.metaPlanes = 1;
1710 newParameters.numSvcBufsInHal = 0;
Sungjoong Kanga85ec382012-09-23 16:49:12 -07001711 newParameters.minUndequedBuffer = 3;
Sungjoong Kangbf961722012-09-27 15:40:59 -07001712 newParameters.needsIonMap = true;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001713
1714 newParameters.node = &m_camera_info.scp;
1715 newParameters.node->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1716 newParameters.node->memory = V4L2_MEMORY_DMABUF;
1717
1718 AllocatedStream->streamType = STREAM_TYPE_DIRECT;
1719 AllocatedStream->m_index = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001720 AllocatedStream->setParameter(&newParameters);
1721 AllocatedStream->m_activated = true;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001722 AllocatedStream->m_numRegisteredStream = 1;
1723 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, AllocatedStream->m_numRegisteredStream);
Sungjoong Kangad378612012-08-17 12:34:33 -07001724 m_requestManager->SetDefaultParameters(m_camera2->getSensorW());
1725 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[2] = m_camera2->getSensorW();
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001726 if (m_subStreams[STREAM_ID_RECORD].type != SUBSTREAM_TYPE_NONE)
1727 AllocatedStream->attachSubStream(STREAM_ID_RECORD, 10);
1728 if (m_subStreams[STREAM_ID_PRVCB].type != SUBSTREAM_TYPE_NONE)
1729 AllocatedStream->attachSubStream(STREAM_ID_PRVCB, 70);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001730 return 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001731 } else if (allocCase == 1) {
1732 *stream_id = STREAM_ID_RECORD;
1733
1734 subParameters = &m_subStreams[STREAM_ID_RECORD];
1735 memset(subParameters, 0, sizeof(substream_parameters_t));
1736
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001737 parentStream = (StreamThread*)(m_streamThreads[0].get());
1738 if (!parentStream) {
1739 return 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001740 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001741
Sungjoong Kang804236a2012-08-05 10:36:19 -07001742 *format_actual = HAL_PIXEL_FORMAT_YCbCr_420_SP; // NV12M
Alex Ray6bbb5932012-07-27 17:19:48 -07001743 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
James Dong26306792012-08-24 14:42:26 -07001744 *max_buffers = 6;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001745
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001746 subParameters->type = SUBSTREAM_TYPE_RECORD;
1747 subParameters->width = width;
1748 subParameters->height = height;
1749 subParameters->format = *format_actual;
1750 subParameters->svcPlanes = NUM_PLANES(*format_actual);
1751 subParameters->streamOps = stream_ops;
1752 subParameters->usage = *usage;
1753 subParameters->numOwnSvcBuffers = *max_buffers;
1754 subParameters->numSvcBufsInHal = 0;
1755 subParameters->needBufferInit = false;
1756 subParameters->minUndequedBuffer = 2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001757
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001758 res = parentStream->attachSubStream(STREAM_ID_RECORD, 20);
1759 if (res != NO_ERROR) {
1760 ALOGE("(%s): substream attach failed. res(%d)", __FUNCTION__, res);
1761 return 1;
1762 }
1763 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, parentStream->m_numRegisteredStream);
1764 ALOGV("(%s): Enabling Record", __FUNCTION__);
1765 return 0;
1766 }
1767 }
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07001768 else if ((format == CAMERA2_HAL_PIXEL_FORMAT_ZSL)
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001769 && (width == m_camera2->getSensorW()) && (height == m_camera2->getSensorH())) {
1770
1771 if (!(m_streamThreads[1].get())) {
1772 ALOGV("DEBUG(%s): stream thread 1 not exist", __FUNCTION__);
1773 useDirectOutput = true;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001774 }
1775 else {
1776 ALOGV("DEBUG(%s): stream thread 1 exists and deactivated.", __FUNCTION__);
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001777 useDirectOutput = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001778 }
1779 if (useDirectOutput) {
1780 *stream_id = STREAM_ID_ZSL;
1781
Sungjoong Kang053d38c2012-09-17 17:46:52 -07001782 m_streamThreads[1] = new StreamThread(this, *stream_id);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001783 AllocatedStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kang053d38c2012-09-17 17:46:52 -07001784 AllocatedStream->Start("StreamThread", PRIORITY_DEFAULT, 0);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001785 m_streamThreadInitialize((SignalDrivenThread*)AllocatedStream);
1786
1787 *format_actual = HAL_PIXEL_FORMAT_EXYNOS_YV12;
1788 *max_buffers = 6;
1789
1790 *format_actual = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV
1791 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
1792 *max_buffers = 6;
1793
1794 newParameters.width = width;
1795 newParameters.height = height;
1796 newParameters.format = *format_actual;
1797 newParameters.streamOps = stream_ops;
1798 newParameters.usage = *usage;
Sungjoong Kangac8c2062012-09-14 02:46:47 -07001799 newParameters.numHwBuffers = NUM_SCC_BUFFERS;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001800 newParameters.numOwnSvcBuffers = *max_buffers;
1801 newParameters.planes = NUM_PLANES(*format_actual);
1802 newParameters.metaPlanes = 1;
1803
1804 newParameters.numSvcBufsInHal = 0;
Sungjoong Kanga85ec382012-09-23 16:49:12 -07001805 newParameters.minUndequedBuffer = 2;
Sungjoong Kangbf961722012-09-27 15:40:59 -07001806 newParameters.needsIonMap = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001807
1808 newParameters.node = &m_camera_info.capture;
1809 newParameters.node->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1810 newParameters.node->memory = V4L2_MEMORY_DMABUF;
1811
1812 AllocatedStream->streamType = STREAM_TYPE_DIRECT;
1813 AllocatedStream->m_index = 1;
1814 AllocatedStream->setParameter(&newParameters);
1815 AllocatedStream->m_activated = true;
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07001816 AllocatedStream->m_numRegisteredStream = 1;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001817 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, AllocatedStream->m_numRegisteredStream);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001818 return 0;
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001819 } else {
1820 bool bJpegExists = false;
1821 AllocatedStream = (StreamThread*)(m_streamThreads[1].get());
1822 subParameters = &m_subStreams[STREAM_ID_JPEG];
1823 if (subParameters->type == SUBSTREAM_TYPE_JPEG) {
1824 ALOGD("(%s): jpeg stream exists", __FUNCTION__);
1825 bJpegExists = true;
1826 AllocatedStream->detachSubStream(STREAM_ID_JPEG);
1827 }
1828 AllocatedStream->m_releasing = true;
1829 ALOGD("START stream thread 1 release %d", __LINE__);
1830 do {
1831 AllocatedStream->release();
Sungjoong Kang041f38d2012-09-25 01:39:19 -07001832 usleep(SIG_WAITING_TICK);
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001833 } while (AllocatedStream->m_releasing);
1834 ALOGD("END stream thread 1 release %d", __LINE__);
1835
1836 *stream_id = STREAM_ID_ZSL;
1837
1838 m_streamThreadInitialize((SignalDrivenThread*)AllocatedStream);
1839
1840 *format_actual = HAL_PIXEL_FORMAT_EXYNOS_YV12;
1841 *max_buffers = 6;
1842
1843 *format_actual = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV
1844 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
1845 *max_buffers = 6;
1846
1847 newParameters.width = width;
1848 newParameters.height = height;
1849 newParameters.format = *format_actual;
1850 newParameters.streamOps = stream_ops;
1851 newParameters.usage = *usage;
1852 newParameters.numHwBuffers = NUM_SCC_BUFFERS;
1853 newParameters.numOwnSvcBuffers = *max_buffers;
1854 newParameters.planes = NUM_PLANES(*format_actual);
1855 newParameters.metaPlanes = 1;
1856
1857 newParameters.numSvcBufsInHal = 0;
Sungjoong Kangbf961722012-09-27 15:40:59 -07001858 newParameters.minUndequedBuffer = 2;
1859 newParameters.needsIonMap = false;
Sungjoong Kang90e439c2012-09-20 02:26:22 -07001860
1861 newParameters.node = &m_camera_info.capture;
1862 newParameters.node->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1863 newParameters.node->memory = V4L2_MEMORY_DMABUF;
1864
1865 AllocatedStream->streamType = STREAM_TYPE_DIRECT;
1866 AllocatedStream->m_index = 1;
1867 AllocatedStream->setParameter(&newParameters);
1868 AllocatedStream->m_activated = true;
1869 AllocatedStream->m_numRegisteredStream = 1;
1870 if (bJpegExists) {
1871 AllocatedStream->attachSubStream(STREAM_ID_JPEG, 10);
1872 }
1873 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, AllocatedStream->m_numRegisteredStream);
1874 return 0;
1875
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001876 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001877 }
Sungjoong Kangad378612012-08-17 12:34:33 -07001878 else if (format == HAL_PIXEL_FORMAT_BLOB
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001879 && m_camera2->isSupportedJpegResolution(width, height)) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001880 *stream_id = STREAM_ID_JPEG;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001881
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001882 subParameters = &m_subStreams[*stream_id];
1883 memset(subParameters, 0, sizeof(substream_parameters_t));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001884
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001885 if (!(m_streamThreads[1].get())) {
1886 ALOGV("DEBUG(%s): stream thread 1 not exist", __FUNCTION__);
1887 StartSCCThread(false);
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001888 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001889 else if (m_streamThreads[1]->m_activated == false) {
1890 ALOGV("DEBUG(%s): stream thread 1 suspended. restarting", __FUNCTION__);
1891 StartSCCThread(true);
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001892 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001893 parentStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001894
1895 *format_actual = HAL_PIXEL_FORMAT_BLOB;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001896 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang37e122d2012-08-08 11:13:48 -07001897 *max_buffers = 4;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001898
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001899 subParameters->type = SUBSTREAM_TYPE_JPEG;
1900 subParameters->width = width;
1901 subParameters->height = height;
1902 subParameters->format = *format_actual;
1903 subParameters->svcPlanes = 1;
1904 subParameters->streamOps = stream_ops;
1905 subParameters->usage = *usage;
1906 subParameters->numOwnSvcBuffers = *max_buffers;
1907 subParameters->numSvcBufsInHal = 0;
1908 subParameters->needBufferInit = false;
1909 subParameters->minUndequedBuffer = 2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001910
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001911 res = parentStream->attachSubStream(STREAM_ID_JPEG, 10);
1912 if (res != NO_ERROR) {
1913 ALOGE("(%s): substream attach failed. res(%d)", __FUNCTION__, res);
1914 return 1;
1915 }
1916 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, parentStream->m_numRegisteredStream);
1917 ALOGV("(%s): Enabling Jpeg", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001918 return 0;
1919 }
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001920 else if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001921 *stream_id = STREAM_ID_PRVCB;
1922
1923 subParameters = &m_subStreams[STREAM_ID_PRVCB];
1924 memset(subParameters, 0, sizeof(substream_parameters_t));
1925
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001926 parentStream = (StreamThread*)(m_streamThreads[0].get());
1927 if (!parentStream) {
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001928 return 1;
1929 }
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001930
1931 *format_actual = format;
1932 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001933 *max_buffers = 6;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001934
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001935 subParameters->type = SUBSTREAM_TYPE_PRVCB;
1936 subParameters->width = width;
1937 subParameters->height = height;
1938 subParameters->format = *format_actual;
1939 subParameters->svcPlanes = NUM_PLANES(*format_actual);
1940 subParameters->streamOps = stream_ops;
1941 subParameters->usage = *usage;
1942 subParameters->numOwnSvcBuffers = *max_buffers;
1943 subParameters->numSvcBufsInHal = 0;
1944 subParameters->needBufferInit = false;
1945 subParameters->minUndequedBuffer = 2;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001946
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001947 if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
1948 subParameters->internalFormat = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP;
1949 subParameters->internalPlanes = NUM_PLANES(HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001950 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001951 else {
1952 subParameters->internalFormat = HAL_PIXEL_FORMAT_EXYNOS_YV12;
1953 subParameters->internalPlanes = NUM_PLANES(HAL_PIXEL_FORMAT_EXYNOS_YV12);
1954 }
1955
1956 res = parentStream->attachSubStream(STREAM_ID_PRVCB, 20);
1957 if (res != NO_ERROR) {
1958 ALOGE("(%s): substream attach failed. res(%d)", __FUNCTION__, res);
1959 return 1;
1960 }
1961 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, parentStream->m_numRegisteredStream);
1962 ALOGV("(%s): Enabling previewcb", __FUNCTION__);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07001963 return 0;
1964 }
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001965 ALOGE("(%s): Unsupported Pixel Format", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001966 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001967}
1968
1969int ExynosCameraHWInterface2::registerStreamBuffers(uint32_t stream_id,
1970 int num_buffers, buffer_handle_t *registeringBuffers)
1971{
1972 int i,j;
1973 void *virtAddr[3];
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001974 int plane_index = 0;
1975 StreamThread * targetStream;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001976 stream_parameters_t *targetStreamParms;
1977 node_info_t *currentNode;
1978
1979 struct v4l2_buffer v4l2_buf;
1980 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1981
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07001982 ALOGD("(%s): stream_id(%d), num_buff(%d), handle(%x) ", __FUNCTION__,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001983 stream_id, num_buffers, (uint32_t)registeringBuffers);
1984
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001985 if (stream_id == STREAM_ID_PREVIEW && m_streamThreads[0].get()) {
1986 targetStream = m_streamThreads[0].get();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001987 targetStreamParms = &(m_streamThreads[0]->m_parameters);
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07001988
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001989 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001990 else if (stream_id == STREAM_ID_JPEG || stream_id == STREAM_ID_RECORD || stream_id == STREAM_ID_PRVCB) {
1991 substream_parameters_t *targetParms;
1992 targetParms = &m_subStreams[stream_id];
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001993
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001994 targetParms->numSvcBuffers = num_buffers;
Sungjoong Kang15fd8232012-08-23 16:16:44 -07001995
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07001996 for (i = 0 ; i < targetParms->numSvcBuffers ; i++) {
1997 ALOGV("(%s): registering substream(%d) Buffers[%d] (%x) ", __FUNCTION__,
1998 i, stream_id, (uint32_t)(registeringBuffers[i]));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001999 if (m_grallocHal) {
2000 if (m_grallocHal->lock(m_grallocHal, registeringBuffers[i],
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002001 targetParms->usage, 0, 0,
2002 targetParms->width, targetParms->height, virtAddr) != 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002003 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
2004 }
2005 else {
2006 ExynosBuffer currentBuf;
2007 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002008 if (targetParms->svcPlanes == 1) {
2009 currentBuf.fd.extFd[0] = priv_handle->fd;
2010 currentBuf.size.extS[0] = priv_handle->size;
2011 currentBuf.size.extS[1] = 0;
2012 currentBuf.size.extS[2] = 0;
2013 } else if (targetParms->svcPlanes == 2) {
2014 currentBuf.fd.extFd[0] = priv_handle->fd;
2015 currentBuf.fd.extFd[1] = priv_handle->fd1;
2016
2017 } else if (targetParms->svcPlanes == 3) {
2018 currentBuf.fd.extFd[0] = priv_handle->fd;
2019 currentBuf.fd.extFd[1] = priv_handle->fd1;
2020 currentBuf.fd.extFd[2] = priv_handle->fd2;
2021 }
2022 for (plane_index = 0 ; plane_index < targetParms->svcPlanes ; plane_index++) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002023 currentBuf.virt.extP[plane_index] = (char *)virtAddr[plane_index];
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002024 CAM_LOGV("DEBUG(%s): plane(%d): fd(%d) addr(%x) size(%d)",
Sungjoong Kang804236a2012-08-05 10:36:19 -07002025 __FUNCTION__, plane_index, currentBuf.fd.extFd[plane_index],
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002026 (unsigned int)currentBuf.virt.extP[plane_index], currentBuf.size.extS[plane_index]);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002027 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002028 targetParms->svcBufStatus[i] = ON_SERVICE;
2029 targetParms->svcBuffers[i] = currentBuf;
2030 targetParms->svcBufHandle[i] = registeringBuffers[i];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002031 }
2032 }
2033 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002034 targetParms->needBufferInit = true;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002035 return 0;
2036 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002037 else if (stream_id == STREAM_ID_ZSL && m_streamThreads[1].get()) {
2038 targetStream = m_streamThreads[1].get();
2039 targetStreamParms = &(m_streamThreads[1]->m_parameters);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07002040 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002041 else {
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07002042 ALOGE("(%s): unregistered stream id (%d)", __FUNCTION__, stream_id);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002043 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002044 }
2045
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002046 if (targetStream->streamType == STREAM_TYPE_DIRECT) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002047 if (num_buffers < targetStreamParms->numHwBuffers) {
2048 ALOGE("ERR(%s) registering insufficient num of buffers (%d) < (%d)",
2049 __FUNCTION__, num_buffers, targetStreamParms->numHwBuffers);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002050 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002051 }
2052 }
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002053 CAM_LOGV("DEBUG(%s): format(%x) width(%d), height(%d) svcPlanes(%d)",
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002054 __FUNCTION__, targetStreamParms->format, targetStreamParms->width,
2055 targetStreamParms->height, targetStreamParms->planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002056 targetStreamParms->numSvcBuffers = num_buffers;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002057 currentNode = targetStreamParms->node;
2058 currentNode->width = targetStreamParms->width;
2059 currentNode->height = targetStreamParms->height;
2060 currentNode->format = HAL_PIXEL_FORMAT_2_V4L2_PIX(targetStreamParms->format);
2061 currentNode->planes = targetStreamParms->planes;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002062 currentNode->buffers = targetStreamParms->numHwBuffers;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002063 cam_int_s_input(currentNode, m_camera_info.sensor_id);
2064 cam_int_s_fmt(currentNode);
2065 cam_int_reqbufs(currentNode);
2066 for (i = 0 ; i < targetStreamParms->numSvcBuffers ; i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002067 ALOGV("DEBUG(%s): registering Stream Buffers[%d] (%x) ", __FUNCTION__,
2068 i, (uint32_t)(registeringBuffers[i]));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002069 v4l2_buf.m.planes = planes;
2070 v4l2_buf.type = currentNode->type;
2071 v4l2_buf.memory = currentNode->memory;
2072 v4l2_buf.index = i;
2073 v4l2_buf.length = currentNode->planes;
2074
2075 ExynosBuffer currentBuf;
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002076 ExynosBuffer metaBuf;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002077 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
2078
2079 m_getAlignedYUVSize(currentNode->format,
2080 currentNode->width, currentNode->height, &currentBuf);
Alex Ray24231222012-06-27 15:18:15 -07002081
Sungjoong Kang37e122d2012-08-08 11:13:48 -07002082 ALOGV("DEBUG(%s): ion_size(%d), stride(%d), ", __FUNCTION__, priv_handle->size, priv_handle->stride);
2083 if (currentNode->planes == 1) {
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07002084 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
2085 currentBuf.fd.extFd[0] = priv_handle->fd;
Sungjoong Kang37e122d2012-08-08 11:13:48 -07002086 currentBuf.size.extS[0] = priv_handle->size;
2087 currentBuf.size.extS[1] = 0;
2088 currentBuf.size.extS[2] = 0;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07002089 } else if (currentNode->planes == 2) {
2090 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
2091 v4l2_buf.m.planes[1].m.fd = priv_handle->fd1;
2092 currentBuf.fd.extFd[0] = priv_handle->fd;
2093 currentBuf.fd.extFd[1] = priv_handle->fd1;
2094
2095 } else if (currentNode->planes == 3) {
2096 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
2097 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
2098 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
2099 currentBuf.fd.extFd[0] = priv_handle->fd;
2100 currentBuf.fd.extFd[2] = priv_handle->fd1;
2101 currentBuf.fd.extFd[1] = priv_handle->fd2;
Sungjoong Kang37e122d2012-08-08 11:13:48 -07002102 }
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002103
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002104 for (plane_index = 0 ; plane_index < (int)v4l2_buf.length ; plane_index++) {
Sungjoong Kangbf961722012-09-27 15:40:59 -07002105 if (targetStreamParms->needsIonMap)
2106 currentBuf.virt.extP[plane_index] = (char *)ion_map(currentBuf.fd.extFd[plane_index], currentBuf.size.extS[plane_index], 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002107 v4l2_buf.m.planes[plane_index].length = currentBuf.size.extS[plane_index];
Sungjoong Kangbf961722012-09-27 15:40:59 -07002108 ALOGV("(%s): MAPPING plane(%d): fd(%d) addr(%x), length(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002109 __FUNCTION__, plane_index, v4l2_buf.m.planes[plane_index].m.fd,
2110 (unsigned int)currentBuf.virt.extP[plane_index],
2111 v4l2_buf.m.planes[plane_index].length);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002112 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002113
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002114 if (i < currentNode->buffers) {
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002115
2116
2117#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002118 /* add plane for metadata*/
2119 metaBuf.size.extS[0] = 4*1024;
2120 allocCameraMemory(m_ionCameraClient , &metaBuf, 1, 1<<0);
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002121
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002122 v4l2_buf.length += targetStreamParms->metaPlanes;
2123 v4l2_buf.m.planes[v4l2_buf.length-1].m.fd = metaBuf.fd.extFd[0];
2124 v4l2_buf.m.planes[v4l2_buf.length-1].length = metaBuf.size.extS[0];
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002125
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002126 ALOGV("Qbuf metaBuf: fd(%d), length(%d) plane(%d)", metaBuf.fd.extFd[0], metaBuf.size.extS[0], v4l2_buf.length);
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002127#endif
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002128 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
2129 ALOGE("ERR(%s): stream id(%d) exynos_v4l2_qbuf() fail fd(%d)",
2130 __FUNCTION__, stream_id, currentNode->fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002131 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002132 ALOGV("DEBUG(%s): stream id(%d) exynos_v4l2_qbuf() success fd(%d)",
2133 __FUNCTION__, stream_id, currentNode->fd);
2134 targetStreamParms->svcBufStatus[i] = REQUIRES_DQ_FROM_SVC;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002135 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002136 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002137 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
2138 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002139
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002140 targetStreamParms->svcBuffers[i] = currentBuf;
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09002141 targetStreamParms->metaBuffers[i] = metaBuf;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002142 targetStreamParms->svcBufHandle[i] = registeringBuffers[i];
2143 }
Sungjoong Kangad378612012-08-17 12:34:33 -07002144
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002145 ALOGV("DEBUG(%s): calling streamon stream id = %d", __FUNCTION__, stream_id);
2146 cam_int_streamon(targetStreamParms->node);
Sungjoong Kangad378612012-08-17 12:34:33 -07002147 ALOGV("DEBUG(%s): calling streamon END", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002148 currentNode->status = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002149 ALOGV("DEBUG(%s): END registerStreamBuffers", __FUNCTION__);
Sungjoong Kangad378612012-08-17 12:34:33 -07002150
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002151 return 0;
2152}
2153
2154int ExynosCameraHWInterface2::releaseStream(uint32_t stream_id)
2155{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002156 StreamThread *targetStream;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002157 status_t res = NO_ERROR;
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07002158 ALOGD("(%s): stream_id(%d)", __FUNCTION__, stream_id);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002159 bool releasingScpMain = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002160
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002161 if (stream_id == STREAM_ID_PREVIEW) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002162 targetStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kangd0a2bb62012-09-30 02:31:54 -07002163 if (!targetStream) {
2164 ALOGW("(%s): Stream Not Exists", __FUNCTION__);
2165 return 1;
2166 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002167 targetStream->m_numRegisteredStream--;
2168 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, targetStream->m_numRegisteredStream);
2169 releasingScpMain = true;
Sungjoong Kangbf961722012-09-27 15:40:59 -07002170 if (targetStream->m_parameters.needsIonMap) {
2171 for (int i = 0; i < targetStream->m_parameters.numSvcBuffers; i++) {
2172 for (int j = 0; j < targetStream->m_parameters.planes; j++) {
2173 ion_unmap(targetStream->m_parameters.svcBuffers[i].virt.extP[j],
2174 targetStream->m_parameters.svcBuffers[i].size.extS[j]);
2175 ALOGV("(%s) ummap stream buffer[%d], plane(%d), fd %d vaddr %x", __FUNCTION__, i, j,
2176 targetStream->m_parameters.svcBuffers[i].fd.extFd[j], targetStream->m_parameters.svcBuffers[i].virt.extP[j]);
2177 }
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002178 }
2179 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002180 } else if (stream_id == STREAM_ID_JPEG) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002181 targetStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kangd0a2bb62012-09-30 02:31:54 -07002182 if (!targetStream) {
2183 ALOGW("(%s): Stream Not Exists", __FUNCTION__);
2184 return 1;
2185 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002186 memset(&m_subStreams[stream_id], 0, sizeof(substream_parameters_t));
2187 if (m_resizeBuf.size.s != 0) {
2188 freeCameraMemory(&m_resizeBuf, 1);
2189 }
2190 if (targetStream)
2191 res = targetStream->detachSubStream(stream_id);
2192 if (res != NO_ERROR) {
2193 ALOGE("(%s): substream detach failed. res(%d)", __FUNCTION__, res);
2194 return 1;
2195 }
2196 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, targetStream->m_numRegisteredStream);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002197 return 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002198 } else if (stream_id == STREAM_ID_RECORD) {
2199 targetStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kangd0a2bb62012-09-30 02:31:54 -07002200 if (!targetStream) {
2201 ALOGW("(%s): Stream Not Exists", __FUNCTION__);
2202 return 1;
2203 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002204 memset(&m_subStreams[stream_id], 0, sizeof(substream_parameters_t));
2205 if (targetStream)
2206 res = targetStream->detachSubStream(stream_id);
2207 else
2208 return 0;
Sungjoong Kangf0708d22012-09-26 13:31:46 -07002209 if (targetStream->m_numRegisteredStream != 0)
2210 return 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002211 } else if (stream_id == STREAM_ID_PRVCB) {
2212 targetStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kangd0a2bb62012-09-30 02:31:54 -07002213 if (!targetStream) {
2214 ALOGW("(%s): Stream Not Exists", __FUNCTION__);
2215 return 1;
2216 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002217 if (m_resizeBuf.size.s != 0) {
2218 freeCameraMemory(&m_previewCbBuf, m_subStreams[stream_id].internalPlanes);
2219 }
2220 memset(&m_subStreams[stream_id], 0, sizeof(substream_parameters_t));
2221 if (targetStream)
2222 res = targetStream->detachSubStream(stream_id);
2223 else
2224 return 0;
Sungjoong Kangf0708d22012-09-26 13:31:46 -07002225 if (targetStream->m_numRegisteredStream != 0)
2226 return 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002227 } else if (stream_id == STREAM_ID_ZSL) {
2228 targetStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kangd0a2bb62012-09-30 02:31:54 -07002229 if (!targetStream) {
2230 ALOGW("(%s): Stream Not Exists", __FUNCTION__);
2231 return 1;
2232 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002233 targetStream->m_numRegisteredStream--;
2234 ALOGV("(%s): m_numRegisteredStream = %d", __FUNCTION__, targetStream->m_numRegisteredStream);
Sungjoong Kangbf961722012-09-27 15:40:59 -07002235 if (targetStream->m_parameters.needsIonMap) {
2236 for (int i = 0; i < targetStream->m_parameters.numSvcBuffers; i++) {
2237 for (int j = 0; j < targetStream->m_parameters.planes; j++) {
2238 ion_unmap(targetStream->m_parameters.svcBuffers[i].virt.extP[j],
2239 targetStream->m_parameters.svcBuffers[i].size.extS[j]);
2240 ALOGV("(%s) ummap stream buffer[%d], plane(%d), fd %d vaddr %x", __FUNCTION__, i, j,
2241 targetStream->m_parameters.svcBuffers[i].fd.extFd[j], targetStream->m_parameters.svcBuffers[i].virt.extP[j]);
2242 }
2243 }
2244 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002245 } else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002246 ALOGE("ERR:(%s): wrong stream id (%d)", __FUNCTION__, stream_id);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002247 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002248 }
2249
Sungjoong Kang2d5655e2012-09-24 01:48:33 -07002250 if (m_sensorThread != NULL) {
2251 m_sensorThread->release();
2252 ALOGD("(%s): START Waiting for (indirect) sensor thread termination", __FUNCTION__);
2253 while (!m_sensorThread->IsTerminated())
Sungjoong Kang48728d42012-09-26 13:48:48 -07002254 usleep(SIG_WAITING_TICK);
Sungjoong Kang2d5655e2012-09-24 01:48:33 -07002255 ALOGD("(%s): END Waiting for (indirect) sensor thread termination", __FUNCTION__);
2256 }
2257 else {
2258 ALOGE("+++++++ sensor thread is NULL %d", __LINE__);
2259 }
2260
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002261 if (m_streamThreads[1]->m_numRegisteredStream == 0 && m_streamThreads[1]->m_activated) {
2262 ALOGV("(%s): deactivating stream thread 1 ", __FUNCTION__);
2263 targetStream = (StreamThread*)(m_streamThreads[1].get());
2264 targetStream->m_releasing = true;
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002265 ALOGD("START stream thread release %d", __LINE__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002266 do {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002267 targetStream->release();
Sungjoong Kang041f38d2012-09-25 01:39:19 -07002268 usleep(SIG_WAITING_TICK);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002269 } while (targetStream->m_releasing);
Sungjoong Kanga8be0012012-09-19 00:13:43 -07002270 m_camera_info.capture.status = false;
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002271 ALOGD("END stream thread release %d", __LINE__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002272 }
2273
Sungjoong Kanga8be0012012-09-19 00:13:43 -07002274 if (releasingScpMain || (m_streamThreads[0].get() != NULL && m_streamThreads[0]->m_numRegisteredStream == 0 && m_streamThreads[0]->m_activated)) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002275 ALOGV("(%s): deactivating stream thread 0", __FUNCTION__);
2276 targetStream = (StreamThread*)(m_streamThreads[0].get());
2277 targetStream->m_releasing = true;
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002278 ALOGD("(%s): START Waiting for (indirect) stream thread release - line(%d)", __FUNCTION__, __LINE__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002279 do {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002280 targetStream->release();
Sungjoong Kang041f38d2012-09-25 01:39:19 -07002281 usleep(SIG_WAITING_TICK);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002282 } while (targetStream->m_releasing);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002283 ALOGD("(%s): END Waiting for (indirect) stream thread release - line(%d)", __FUNCTION__, __LINE__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002284 targetStream->SetSignal(SIGNAL_THREAD_TERMINATE);
2285
2286 if (targetStream != NULL) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002287 ALOGD("(%s): START Waiting for (indirect) stream thread termination", __FUNCTION__);
2288 while (!targetStream->IsTerminated())
Sungjoong Kang041f38d2012-09-25 01:39:19 -07002289 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07002290 ALOGD("(%s): END Waiting for (indirect) stream thread termination", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002291 m_streamThreads[0] = NULL;
2292 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002293 if (m_camera_info.capture.status == true) {
Sungjoong Kangf9a06602012-09-24 13:46:10 -07002294 m_scpForceSuspended = true;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002295 }
2296 m_isIspStarted = false;
2297 }
2298 ALOGV("(%s): END", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002299 return 0;
2300}
2301
2302int ExynosCameraHWInterface2::allocateReprocessStream(
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002303 uint32_t width, uint32_t height, uint32_t format,
2304 const camera2_stream_in_ops_t *reprocess_stream_ops,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002305 uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers)
2306{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002307 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002308 return 0;
2309}
2310
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002311int ExynosCameraHWInterface2::allocateReprocessStreamFromStream(
2312 uint32_t output_stream_id,
2313 const camera2_stream_in_ops_t *reprocess_stream_ops,
2314 // outputs
2315 uint32_t *stream_id)
2316{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07002317 ALOGD("(%s): output_stream_id(%d)", __FUNCTION__, output_stream_id);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002318 *stream_id = STREAM_ID_JPEG_REPROCESS;
2319
2320 m_reprocessStreamId = *stream_id;
2321 m_reprocessOps = reprocess_stream_ops;
2322 m_reprocessOutputStreamId = output_stream_id;
2323 return 0;
2324}
2325
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002326int ExynosCameraHWInterface2::releaseReprocessStream(uint32_t stream_id)
2327{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07002328 ALOGD("(%s): stream_id(%d)", __FUNCTION__, stream_id);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002329 if (stream_id == STREAM_ID_JPEG_REPROCESS) {
2330 m_reprocessStreamId = 0;
2331 m_reprocessOps = NULL;
2332 m_reprocessOutputStreamId = 0;
2333 return 0;
2334 }
2335 return 1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002336}
2337
2338int ExynosCameraHWInterface2::triggerAction(uint32_t trigger_id, int ext1, int ext2)
2339{
Sungjoong Kang0f26b202012-08-17 15:43:12 -07002340 ALOGV("DEBUG(%s): id(%x), %d, %d", __FUNCTION__, trigger_id, ext1, ext2);
2341
2342 switch (trigger_id) {
2343 case CAMERA2_TRIGGER_AUTOFOCUS:
2344 ALOGV("DEBUG(%s):TRIGGER_AUTOFOCUS id(%d)", __FUNCTION__, ext1);
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07002345 OnAfTriggerStart(ext1);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07002346 break;
2347
2348 case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
2349 ALOGV("DEBUG(%s):CANCEL_AUTOFOCUS id(%d)", __FUNCTION__, ext1);
2350 OnAfCancel(ext1);
2351 break;
Younghwan Jooe117f752012-09-12 22:21:55 -07002352 case CAMERA2_TRIGGER_PRECAPTURE_METERING:
2353 ALOGV("DEBUG(%s):CAMERA2_TRIGGER_PRECAPTURE_METERING id(%d)", __FUNCTION__, ext1);
2354 OnPrecaptureMeteringTriggerStart(ext1);
2355 break;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07002356 default:
2357 break;
2358 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002359 return 0;
2360}
2361
2362int ExynosCameraHWInterface2::setNotifyCallback(camera2_notify_callback notify_cb, void *user)
2363{
Sungjoong Kang0f26b202012-08-17 15:43:12 -07002364 ALOGV("DEBUG(%s): cb_addr(%x)", __FUNCTION__, (unsigned int)notify_cb);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002365 m_notifyCb = notify_cb;
2366 m_callbackCookie = user;
2367 return 0;
2368}
2369
2370int ExynosCameraHWInterface2::getMetadataVendorTagOps(vendor_tag_query_ops_t **ops)
2371{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002372 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002373 return 0;
2374}
2375
2376int ExynosCameraHWInterface2::dump(int fd)
2377{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002378 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002379 return 0;
2380}
2381
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002382void ExynosCameraHWInterface2::m_getAlignedYUVSize(int colorFormat, int w, int h, ExynosBuffer *buf)
2383{
2384 switch (colorFormat) {
2385 // 1p
2386 case V4L2_PIX_FMT_RGB565 :
2387 case V4L2_PIX_FMT_YUYV :
2388 case V4L2_PIX_FMT_UYVY :
2389 case V4L2_PIX_FMT_VYUY :
2390 case V4L2_PIX_FMT_YVYU :
2391 buf->size.extS[0] = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(colorFormat), w, h);
2392 buf->size.extS[1] = 0;
2393 buf->size.extS[2] = 0;
2394 break;
2395 // 2p
2396 case V4L2_PIX_FMT_NV12 :
2397 case V4L2_PIX_FMT_NV12T :
2398 case V4L2_PIX_FMT_NV21 :
2399 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
2400 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 16);
2401 buf->size.extS[2] = 0;
2402 break;
2403 case V4L2_PIX_FMT_NV12M :
2404 case V4L2_PIX_FMT_NV12MT_16X16 :
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002405 case V4L2_PIX_FMT_NV21M:
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002406 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
2407 buf->size.extS[1] = ALIGN(buf->size.extS[0] / 2, 256);
2408 buf->size.extS[2] = 0;
2409 break;
2410 case V4L2_PIX_FMT_NV16 :
2411 case V4L2_PIX_FMT_NV61 :
2412 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
2413 buf->size.extS[1] = ALIGN(w, 16) * ALIGN(h, 16);
2414 buf->size.extS[2] = 0;
2415 break;
2416 // 3p
2417 case V4L2_PIX_FMT_YUV420 :
2418 case V4L2_PIX_FMT_YVU420 :
2419 buf->size.extS[0] = (w * h);
2420 buf->size.extS[1] = (w * h) >> 2;
2421 buf->size.extS[2] = (w * h) >> 2;
2422 break;
2423 case V4L2_PIX_FMT_YUV420M:
2424 case V4L2_PIX_FMT_YVU420M :
Sungjoong Kang4a3f1822012-09-28 20:07:32 -07002425 buf->size.extS[0] = ALIGN(w, 32) * ALIGN(h, 16);
2426 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
2427 buf->size.extS[2] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
2428 break;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002429 case V4L2_PIX_FMT_YUV422P :
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002430 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002431 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
2432 buf->size.extS[2] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
2433 break;
2434 default:
2435 ALOGE("ERR(%s):unmatched colorFormat(%d)", __FUNCTION__, colorFormat);
2436 return;
2437 break;
2438 }
2439}
2440
2441bool ExynosCameraHWInterface2::m_getRatioSize(int src_w, int src_h,
2442 int dst_w, int dst_h,
2443 int *crop_x, int *crop_y,
2444 int *crop_w, int *crop_h,
2445 int zoom)
2446{
2447 *crop_w = src_w;
2448 *crop_h = src_h;
2449
2450 if ( src_w != dst_w
2451 || src_h != dst_h) {
2452 float src_ratio = 1.0f;
2453 float dst_ratio = 1.0f;
2454
2455 // ex : 1024 / 768
2456 src_ratio = (float)src_w / (float)src_h;
2457
2458 // ex : 352 / 288
2459 dst_ratio = (float)dst_w / (float)dst_h;
2460
2461 if (dst_w * dst_h < src_w * src_h) {
2462 if (dst_ratio <= src_ratio) {
2463 // shrink w
2464 *crop_w = src_h * dst_ratio;
2465 *crop_h = src_h;
2466 } else {
2467 // shrink h
2468 *crop_w = src_w;
2469 *crop_h = src_w / dst_ratio;
2470 }
2471 } else {
2472 if (dst_ratio <= src_ratio) {
2473 // shrink w
2474 *crop_w = src_h * dst_ratio;
2475 *crop_h = src_h;
2476 } else {
2477 // shrink h
2478 *crop_w = src_w;
2479 *crop_h = src_w / dst_ratio;
2480 }
2481 }
2482 }
2483
2484 if (zoom != 0) {
2485 float zoomLevel = ((float)zoom + 10.0) / 10.0;
2486 *crop_w = (int)((float)*crop_w / zoomLevel);
2487 *crop_h = (int)((float)*crop_h / zoomLevel);
2488 }
2489
2490 #define CAMERA_CROP_WIDTH_RESTRAIN_NUM (0x2)
2491 unsigned int w_align = (*crop_w & (CAMERA_CROP_WIDTH_RESTRAIN_NUM - 1));
2492 if (w_align != 0) {
2493 if ( (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1) <= w_align
2494 && *crop_w + (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align) <= dst_w) {
2495 *crop_w += (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align);
2496 }
2497 else
2498 *crop_w -= w_align;
2499 }
2500
2501 #define CAMERA_CROP_HEIGHT_RESTRAIN_NUM (0x2)
2502 unsigned int h_align = (*crop_h & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - 1));
2503 if (h_align != 0) {
2504 if ( (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1) <= h_align
2505 && *crop_h + (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align) <= dst_h) {
2506 *crop_h += (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align);
2507 }
2508 else
2509 *crop_h -= h_align;
2510 }
2511
2512 *crop_x = (src_w - *crop_w) >> 1;
2513 *crop_y = (src_h - *crop_h) >> 1;
2514
2515 if (*crop_x & (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1))
2516 *crop_x -= 1;
2517
2518 if (*crop_y & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1))
2519 *crop_y -= 1;
2520
2521 return true;
2522}
2523
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002524BayerBufManager::BayerBufManager()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002525{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002526 ALOGV("DEBUG(%s): ", __FUNCTION__);
2527 for (int i = 0; i < NUM_BAYER_BUFFERS ; i++) {
2528 entries[i].status = BAYER_ON_HAL_EMPTY;
2529 entries[i].reqFrameCnt = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002530 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002531 sensorEnqueueHead = 0;
2532 sensorDequeueHead = 0;
2533 ispEnqueueHead = 0;
2534 ispDequeueHead = 0;
2535 numOnSensor = 0;
2536 numOnIsp = 0;
2537 numOnHalFilled = 0;
2538 numOnHalEmpty = NUM_BAYER_BUFFERS;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002539}
2540
Sungjoong Kang15fd8232012-08-23 16:16:44 -07002541BayerBufManager::~BayerBufManager()
2542{
2543 ALOGV("%s", __FUNCTION__);
2544}
2545
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002546int BayerBufManager::GetIndexForSensorEnqueue()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002547{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002548 int ret = 0;
2549 if (numOnHalEmpty == 0)
2550 ret = -1;
2551 else
2552 ret = sensorEnqueueHead;
2553 ALOGV("DEBUG(%s): returning (%d)", __FUNCTION__, ret);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002554 return ret;
2555}
2556
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002557int BayerBufManager::MarkSensorEnqueue(int index)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002558{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002559 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
2560
2561 // sanity check
2562 if (index != sensorEnqueueHead) {
2563 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, sensorEnqueueHead);
2564 return -1;
2565 }
2566 if (entries[index].status != BAYER_ON_HAL_EMPTY) {
2567 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
2568 index, entries[index].status, BAYER_ON_HAL_EMPTY);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002569 return -1;
2570 }
2571
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002572 entries[index].status = BAYER_ON_SENSOR;
2573 entries[index].reqFrameCnt = 0;
2574 numOnHalEmpty--;
2575 numOnSensor++;
2576 sensorEnqueueHead = GetNextIndex(index);
2577 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
2578 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
2579 return 0;
2580}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002581
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002582int BayerBufManager::MarkSensorDequeue(int index, int reqFrameCnt, nsecs_t *timeStamp)
2583{
2584 ALOGV("DEBUG(%s) : BayerIndex[%d] reqFrameCnt(%d)", __FUNCTION__, index, reqFrameCnt);
2585
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002586 if (entries[index].status != BAYER_ON_SENSOR) {
Sungjoong Kangad378612012-08-17 12:34:33 -07002587 ALOGE("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002588 index, entries[index].status, BAYER_ON_SENSOR);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002589 return -1;
2590 }
2591
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002592 entries[index].status = BAYER_ON_HAL_FILLED;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002593 numOnHalFilled++;
2594 numOnSensor--;
Sungjoong Kangad378612012-08-17 12:34:33 -07002595
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002596 return 0;
2597}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002598
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002599int BayerBufManager::GetIndexForIspEnqueue(int *reqFrameCnt)
2600{
2601 int ret = 0;
2602 if (numOnHalFilled == 0)
2603 ret = -1;
2604 else {
2605 *reqFrameCnt = entries[ispEnqueueHead].reqFrameCnt;
2606 ret = ispEnqueueHead;
2607 }
2608 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
2609 return ret;
2610}
2611
2612int BayerBufManager::GetIndexForIspDequeue(int *reqFrameCnt)
2613{
2614 int ret = 0;
2615 if (numOnIsp == 0)
2616 ret = -1;
2617 else {
2618 *reqFrameCnt = entries[ispDequeueHead].reqFrameCnt;
2619 ret = ispDequeueHead;
2620 }
2621 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
2622 return ret;
2623}
2624
2625int BayerBufManager::MarkIspEnqueue(int index)
2626{
2627 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
2628
2629 // sanity check
2630 if (index != ispEnqueueHead) {
2631 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispEnqueueHead);
2632 return -1;
2633 }
2634 if (entries[index].status != BAYER_ON_HAL_FILLED) {
2635 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
2636 index, entries[index].status, BAYER_ON_HAL_FILLED);
2637 return -1;
2638 }
2639
2640 entries[index].status = BAYER_ON_ISP;
2641 numOnHalFilled--;
2642 numOnIsp++;
2643 ispEnqueueHead = GetNextIndex(index);
2644 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
2645 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
2646 return 0;
2647}
2648
2649int BayerBufManager::MarkIspDequeue(int index)
2650{
2651 ALOGV("DEBUG(%s) : BayerIndex[%d]", __FUNCTION__, index);
2652
2653 // sanity check
2654 if (index != ispDequeueHead) {
2655 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispDequeueHead);
2656 return -1;
2657 }
2658 if (entries[index].status != BAYER_ON_ISP) {
2659 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
2660 index, entries[index].status, BAYER_ON_ISP);
2661 return -1;
2662 }
2663
2664 entries[index].status = BAYER_ON_HAL_EMPTY;
2665 entries[index].reqFrameCnt = 0;
2666 numOnHalEmpty++;
2667 numOnIsp--;
2668 ispDequeueHead = GetNextIndex(index);
2669 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
2670 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
2671 return 0;
2672}
2673
2674int BayerBufManager::GetNumOnSensor()
2675{
2676 return numOnSensor;
2677}
2678
2679int BayerBufManager::GetNumOnHalFilled()
2680{
2681 return numOnHalFilled;
2682}
2683
2684int BayerBufManager::GetNumOnIsp()
2685{
2686 return numOnIsp;
2687}
2688
2689int BayerBufManager::GetNextIndex(int index)
2690{
2691 index++;
2692 if (index >= NUM_BAYER_BUFFERS)
2693 index = 0;
2694
2695 return index;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002696}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002697
2698void ExynosCameraHWInterface2::m_mainThreadFunc(SignalDrivenThread * self)
2699{
2700 camera_metadata_t *currentRequest = NULL;
2701 camera_metadata_t *currentFrame = NULL;
2702 size_t numEntries = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002703 size_t frameSize = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002704 camera_metadata_t * preparedFrame = NULL;
2705 camera_metadata_t *deregisteredRequest = NULL;
2706 uint32_t currentSignal = self->GetProcessingSignal();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002707 MainThread * selfThread = ((MainThread*)self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002708 int res = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002709
Sungjoong Kangad378612012-08-17 12:34:33 -07002710 int ret;
2711
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002712 ALOGV("DEBUG(%s): m_mainThreadFunc (%x)", __FUNCTION__, currentSignal);
2713
2714 if (currentSignal & SIGNAL_THREAD_RELEASE) {
2715 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
2716
2717 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE DONE", __FUNCTION__);
2718 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
2719 return;
2720 }
2721
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002722 if (currentSignal & SIGNAL_MAIN_REQ_Q_NOT_EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002723 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_REQ_Q_NOT_EMPTY", __FUNCTION__);
Sungjoong Kangad378612012-08-17 12:34:33 -07002724 if (m_requestManager->IsRequestQueueFull()==false) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002725 m_requestQueueOps->dequeue_request(m_requestQueueOps, &currentRequest);
2726 if (NULL == currentRequest) {
Igor Murashkine2068c92012-10-08 13:16:07 -07002727 ALOGD("DEBUG(%s)(0x%x): No more service requests left in the queue ", __FUNCTION__, currentSignal);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002728 m_isRequestQueueNull = true;
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07002729 if (m_requestManager->IsVdisEnable())
2730 m_vdisBubbleCnt = 1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002731 }
2732 else {
2733 m_requestManager->RegisterRequest(currentRequest);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002734
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002735 m_numOfRemainingReqInSvc = m_requestQueueOps->request_count(m_requestQueueOps);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002736 ALOGV("DEBUG(%s): remaining req cnt (%d)", __FUNCTION__, m_numOfRemainingReqInSvc);
Sungjoong Kangad378612012-08-17 12:34:33 -07002737 if (m_requestManager->IsRequestQueueFull()==false)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002738 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY); // dequeue repeatedly
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002739
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002740 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
2741 }
2742 }
2743 else {
2744 m_isRequestQueuePending = true;
2745 }
2746 }
2747
2748 if (currentSignal & SIGNAL_MAIN_STREAM_OUTPUT_DONE) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002749 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__);
2750 /*while (1)*/ {
Sungjoong Kang0f26b202012-08-17 15:43:12 -07002751 ret = m_requestManager->PrepareFrame(&numEntries, &frameSize, &preparedFrame, GetAfStateForService());
Sungjoong Kangad378612012-08-17 12:34:33 -07002752 if (ret == false)
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002753 CAM_LOGE("ERR(%s): PrepareFrame ret = %d", __FUNCTION__, ret);
Sungjoong Kangad378612012-08-17 12:34:33 -07002754
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002755 m_requestManager->DeregisterRequest(&deregisteredRequest);
Sungjoong Kangad378612012-08-17 12:34:33 -07002756
2757 ret = m_requestQueueOps->free_request(m_requestQueueOps, deregisteredRequest);
2758 if (ret < 0)
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002759 CAM_LOGE("ERR(%s): free_request ret = %d", __FUNCTION__, ret);
Sungjoong Kangad378612012-08-17 12:34:33 -07002760
2761 ret = m_frameQueueOps->dequeue_frame(m_frameQueueOps, numEntries, frameSize, &currentFrame);
2762 if (ret < 0)
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07002763 CAM_LOGE("ERR(%s): dequeue_frame ret = %d", __FUNCTION__, ret);
Sungjoong Kangad378612012-08-17 12:34:33 -07002764
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002765 if (currentFrame==NULL) {
Sungjoong Kangad378612012-08-17 12:34:33 -07002766 ALOGV("DBG(%s): frame dequeue returned NULL",__FUNCTION__ );
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002767 }
2768 else {
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07002769 ALOGV("DEBUG(%s): frame dequeue done. numEntries(%d) frameSize(%d)",__FUNCTION__ , numEntries, frameSize);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002770 }
2771 res = append_camera_metadata(currentFrame, preparedFrame);
2772 if (res==0) {
2773 ALOGV("DEBUG(%s): frame metadata append success",__FUNCTION__);
2774 m_frameQueueOps->enqueue_frame(m_frameQueueOps, currentFrame);
2775 }
2776 else {
2777 ALOGE("ERR(%s): frame metadata append fail (%d)",__FUNCTION__, res);
2778 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002779 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002780 if (!m_isRequestQueueNull) {
2781 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002782 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002783
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002784 if (getInProgressCount()>0) {
2785 ALOGV("DEBUG(%s): STREAM_OUTPUT_DONE and signalling REQ_PROCESSING",__FUNCTION__);
2786 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002787 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002788 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002789 ALOGV("DEBUG(%s): MainThread Exit", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002790 return;
2791}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002792
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002793void ExynosCameraHWInterface2::DumpInfoWithShot(struct camera2_shot_ext * shot_ext)
2794{
Sungjoong Kangad378612012-08-17 12:34:33 -07002795 ALOGD("#### common Section");
2796 ALOGD("#### magic(%x) ",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002797 shot_ext->shot.magicNumber);
Sungjoong Kangad378612012-08-17 12:34:33 -07002798 ALOGD("#### ctl Section");
2799 ALOGD("#### meta(%d) aper(%f) exp(%lld) duration(%lld) ISO(%d) AWB(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002800 shot_ext->shot.ctl.request.metadataMode,
Sungjoong Kangb56dcc02012-08-08 13:38:09 -07002801 shot_ext->shot.ctl.lens.aperture,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002802 shot_ext->shot.ctl.sensor.exposureTime,
2803 shot_ext->shot.ctl.sensor.frameDuration,
Sungjoong Kangb56dcc02012-08-08 13:38:09 -07002804 shot_ext->shot.ctl.sensor.sensitivity,
2805 shot_ext->shot.ctl.aa.awbMode);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002806
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002807 ALOGD("#### OutputStream Sensor(%d) SCP(%d) SCC(%d) streams(%x)",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002808 shot_ext->request_sensor, shot_ext->request_scp, shot_ext->request_scc,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07002809 shot_ext->shot.ctl.request.outputStreams[0]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002810
Sungjoong Kangad378612012-08-17 12:34:33 -07002811 ALOGD("#### DM Section");
2812 ALOGD("#### meta(%d) aper(%f) exp(%lld) duration(%lld) ISO(%d) timestamp(%lld) AWB(%d) cnt(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002813 shot_ext->shot.dm.request.metadataMode,
Sungjoong Kangb56dcc02012-08-08 13:38:09 -07002814 shot_ext->shot.dm.lens.aperture,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002815 shot_ext->shot.dm.sensor.exposureTime,
2816 shot_ext->shot.dm.sensor.frameDuration,
2817 shot_ext->shot.dm.sensor.sensitivity,
Sungjoong Kangb56dcc02012-08-08 13:38:09 -07002818 shot_ext->shot.dm.sensor.timeStamp,
2819 shot_ext->shot.dm.aa.awbMode,
2820 shot_ext->shot.dm.request.frameCount );
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002821}
2822
Younghwan Jooe117f752012-09-12 22:21:55 -07002823void ExynosCameraHWInterface2::m_preCaptureSetter(struct camera2_shot_ext * shot_ext)
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002824{
Younghwan Jooe117f752012-09-12 22:21:55 -07002825 // Flash
2826 switch (m_ctlInfo.flash.m_flashCnt) {
2827 case IS_FLASH_STATE_ON:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002828 ALOGV("(%s): [Flash] Flash ON for Capture (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Joo4a9565a2012-09-19 18:41:35 -07002829 // check AF locked
2830 if (m_ctlInfo.flash.m_precaptureTriggerId > 0) {
2831 if (m_ctlInfo.flash.m_flashTimeOut == 0) {
2832 if (m_ctlInfo.flash.i_flashMode == AA_AEMODE_ON_ALWAYS_FLASH) {
2833 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_ON_ALWAYS;
2834 m_ctlInfo.flash.m_flashTimeOut = 5;
2835 } else
2836 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_ON;
2837 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON_WAIT;
2838 } else {
2839 m_ctlInfo.flash.m_flashTimeOut--;
2840 }
2841 } else {
2842 if (m_ctlInfo.flash.i_flashMode == AA_AEMODE_ON_ALWAYS_FLASH) {
2843 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_ON_ALWAYS;
2844 m_ctlInfo.flash.m_flashTimeOut = 5;
2845 } else
2846 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_ON;
2847 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON_WAIT;
2848 }
Younghwan Joo9a710a42012-09-05 17:52:08 -07002849 break;
Younghwan Jooe117f752012-09-12 22:21:55 -07002850 case IS_FLASH_STATE_ON_WAIT:
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002851 break;
Younghwan Jooe117f752012-09-12 22:21:55 -07002852 case IS_FLASH_STATE_ON_DONE:
2853 if (!m_ctlInfo.flash.m_afFlashDoneFlg)
2854 // auto transition at pre-capture trigger
2855 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_AE_AWB_LOCK;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002856 break;
Younghwan Jooe117f752012-09-12 22:21:55 -07002857 case IS_FLASH_STATE_AUTO_AE_AWB_LOCK:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002858 ALOGV("(%s): [Flash] IS_FLASH_AF_AUTO_AE_AWB_LOCK (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Jooe117f752012-09-12 22:21:55 -07002859 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_AUTO;
2860 //shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_LOCKED;
2861 shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_LOCKED;
2862 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AE_AWB_LOCK_WAIT;
2863 break;
2864 case IS_FLASH_STATE_AE_AWB_LOCK_WAIT:
2865 case IS_FLASH_STATE_AUTO_WAIT:
2866 shot_ext->shot.ctl.aa.aeMode =(enum aa_aemode)0;
2867 shot_ext->shot.ctl.aa.awbMode = (enum aa_awbmode)0;
2868 break;
2869 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002870 ALOGV("(%s): [Flash] IS_FLASH_AF_AUTO DONE (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Jood91c0262012-09-14 18:21:16 -07002871 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_OFF;
Younghwan Jooe117f752012-09-12 22:21:55 -07002872 break;
2873 case IS_FLASH_STATE_AUTO_OFF:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002874 ALOGV("(%s): [Flash] IS_FLASH_AF_AUTO Clear (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Jooe117f752012-09-12 22:21:55 -07002875 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_OFF;
Younghwan Jooe117f752012-09-12 22:21:55 -07002876 m_ctlInfo.flash.m_flashEnableFlg = false;
2877 break;
2878 case IS_FLASH_STATE_CAPTURE:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002879 ALOGV("(%s): [Flash] IS_FLASH_CAPTURE (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Jooe117f752012-09-12 22:21:55 -07002880 m_ctlInfo.flash.m_flashTimeOut = FLASH_STABLE_WAIT_TIMEOUT;
2881 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_CAPTURE;
2882 shot_ext->request_scc = 0;
2883 shot_ext->request_scp = 0;
2884 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE_WAIT; // auto transition
2885 break;
2886 case IS_FLASH_STATE_CAPTURE_WAIT:
2887 shot_ext->request_scc = 0;
2888 shot_ext->request_scp = 0;
2889 break;
2890 case IS_FLASH_STATE_CAPTURE_JPEG:
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002891 ALOGV("(%s): [Flash] Flash Capture (%d)!!!!!", __FUNCTION__, (FLASH_STABLE_WAIT_TIMEOUT -m_ctlInfo.flash.m_flashTimeOut));
Younghwan Jooe117f752012-09-12 22:21:55 -07002892 shot_ext->request_scc = 1;
2893 shot_ext->request_scp = 1;
2894 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE_END; // auto transition
2895 break;
2896 case IS_FLASH_STATE_CAPTURE_END:
Younghwan Joo40acdcc2012-09-29 16:32:43 +09002897 ALOGV("(%s): [Flash] Flash Capture END (%d)", __FUNCTION__, shot_ext->shot.ctl.request.frameCount);
Younghwan Jooe117f752012-09-12 22:21:55 -07002898 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_OFF;
2899 shot_ext->request_scc = 0;
2900 shot_ext->request_scp = 0;
2901 m_ctlInfo.flash.m_flashEnableFlg = false;
2902 m_ctlInfo.flash.m_flashCnt = 0;
2903 m_ctlInfo.flash.m_afFlashDoneFlg= false;
Younghwan Joocdd53a92012-10-03 17:00:15 +09002904 break;
2905 case IS_FLASH_STATE_NONE:
Younghwan Jooe117f752012-09-12 22:21:55 -07002906 break;
2907 default:
2908 ALOGE("(%s): [Flash] flash state error!! (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002909 }
2910}
2911
Younghwan Jooe117f752012-09-12 22:21:55 -07002912void ExynosCameraHWInterface2::m_preCaptureListenerSensor(struct camera2_shot_ext * shot_ext)
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002913{
Younghwan Jooe117f752012-09-12 22:21:55 -07002914 // Flash
2915 switch (m_ctlInfo.flash.m_flashCnt) {
2916 case IS_FLASH_STATE_AUTO_WAIT:
2917 if (m_ctlInfo.flash.m_flashDecisionResult) {
2918 if (shot_ext->shot.dm.flash.flashMode == CAM2_FLASH_MODE_OFF) {
2919 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_DONE;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002920 ALOGV("(%s): [Flash] Lis : AUTO -> OFF (%d)", __FUNCTION__, shot_ext->shot.dm.flash.flashMode);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002921 } else {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002922 ALOGV("(%s): [Flash] Waiting : AUTO -> OFF", __FUNCTION__);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002923 }
Younghwan Jooe117f752012-09-12 22:21:55 -07002924 } else {
2925 //If flash isn't activated at flash auto mode, skip flash auto control
2926 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_DONE;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002927 ALOGV("(%s): [Flash] Skip : AUTO -> OFF", __FUNCTION__);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002928 }
Younghwan Jooe117f752012-09-12 22:21:55 -07002929 break;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002930 }
Younghwan Joo9a710a42012-09-05 17:52:08 -07002931}
2932
Younghwan Jooe117f752012-09-12 22:21:55 -07002933void ExynosCameraHWInterface2::m_preCaptureListenerISP(struct camera2_shot_ext * shot_ext)
Younghwan Joo9a710a42012-09-05 17:52:08 -07002934{
Younghwan Jooe117f752012-09-12 22:21:55 -07002935 // Flash
2936 switch (m_ctlInfo.flash.m_flashCnt) {
2937 case IS_FLASH_STATE_ON_WAIT:
2938 if (shot_ext->shot.dm.flash.decision > 0) {
2939 // store decision result to skip capture sequenece
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002940 ALOGV("(%s): [Flash] IS_FLASH_ON, decision - %d", __FUNCTION__, shot_ext->shot.dm.flash.decision);
Younghwan Jooe117f752012-09-12 22:21:55 -07002941 if (shot_ext->shot.dm.flash.decision == 2)
2942 m_ctlInfo.flash.m_flashDecisionResult = false;
2943 else
2944 m_ctlInfo.flash.m_flashDecisionResult = true;
2945 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON_DONE;
2946 } else {
2947 if (m_ctlInfo.flash.m_flashTimeOut == 0) {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002948 ALOGV("(%s): [Flash] Timeout IS_FLASH_ON, decision is false setting", __FUNCTION__);
Younghwan Jooe117f752012-09-12 22:21:55 -07002949 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON_DONE;
2950 m_ctlInfo.flash.m_flashDecisionResult = false;
2951 } else {
2952 m_ctlInfo.flash.m_flashTimeOut--;
2953 }
2954 }
2955 break;
2956 case IS_FLASH_STATE_AE_AWB_LOCK_WAIT:
2957 if (shot_ext->shot.dm.aa.awbMode == AA_AWBMODE_LOCKED) {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002958 ALOGV("(%s): [Flash] FLASH_AUTO_AE_AWB_LOCK_WAIT - %d", __FUNCTION__, shot_ext->shot.dm.aa.awbMode);
Younghwan Jooe117f752012-09-12 22:21:55 -07002959 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_WAIT;
2960 } else {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07002961 ALOGV("(%s): [Flash] Waiting : AA_AWBMODE_LOCKED", __FUNCTION__);
Younghwan Jooe117f752012-09-12 22:21:55 -07002962 }
2963 break;
2964 case IS_FLASH_STATE_CAPTURE_WAIT:
2965 if (m_ctlInfo.flash.m_flashDecisionResult) {
2966 if (shot_ext->shot.dm.flash.firingStable) {
2967 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE_JPEG;
Younghwan Joo9257e292012-09-08 21:11:18 -07002968 } else {
2969 if (m_ctlInfo.flash.m_flashTimeOut == 0) {
Younghwan Jooe117f752012-09-12 22:21:55 -07002970 ALOGE("(%s): [Flash] Wait firingStable time-out!!", __FUNCTION__);
2971 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE_JPEG;
Younghwan Joo9257e292012-09-08 21:11:18 -07002972 } else {
Younghwan Jooe117f752012-09-12 22:21:55 -07002973 ALOGV("(%s): [Flash] Wait firingStable - %d", __FUNCTION__, m_ctlInfo.flash.m_flashTimeOut);
Younghwan Joo9257e292012-09-08 21:11:18 -07002974 m_ctlInfo.flash.m_flashTimeOut--;
2975 }
2976 }
Younghwan Jooe117f752012-09-12 22:21:55 -07002977 } else {
2978 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE_JPEG;
Younghwan Joo9257e292012-09-08 21:11:18 -07002979 }
Younghwan Jooe117f752012-09-12 22:21:55 -07002980 break;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002981 }
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07002982}
2983
Younghwan Joocdd53a92012-10-03 17:00:15 +09002984void ExynosCameraHWInterface2::m_preCaptureAeState(struct camera2_shot_ext * shot_ext)
2985{
2986 switch (m_ctlInfo.flash.i_flashMode) {
2987 case AA_AEMODE_ON:
2988 // At flash off mode, capture can be done as zsl capture
2989 shot_ext->shot.dm.aa.aeState = AE_STATE_CONVERGED;
2990 break;
2991 case AA_AEMODE_ON_AUTO_FLASH:
2992 // At flash auto mode, main flash have to be done if pre-flash was done.
2993 if (m_ctlInfo.flash.m_flashDecisionResult && m_ctlInfo.flash.m_afFlashDoneFlg)
2994 shot_ext->shot.dm.aa.aeState = AE_STATE_FLASH_REQUIRED;
2995 break;
2996 }
2997}
2998
Younghwan Joo4a9565a2012-09-19 18:41:35 -07002999void ExynosCameraHWInterface2::m_updateAfRegion(struct camera2_shot_ext * shot_ext)
3000{
3001 if (0 == shot_ext->shot.ctl.aa.afRegions[0] && 0 == shot_ext->shot.ctl.aa.afRegions[1]
3002 && 0 == shot_ext->shot.ctl.aa.afRegions[2] && 0 == shot_ext->shot.ctl.aa.afRegions[3]) {
3003 ALOGV("(%s): AF region resetting", __FUNCTION__);
3004 lastAfRegion[0] = 0;
3005 lastAfRegion[1] = 0;
3006 lastAfRegion[2] = 0;
3007 lastAfRegion[3] = 0;
3008 } else {
Younghwan Joo275c9742012-09-25 21:12:30 +09003009 // clear region infos in case of CAF mode
3010 if (m_afMode == AA_AFMODE_CONTINUOUS_VIDEO || m_afMode == AA_AFMODE_CONTINUOUS_PICTURE) {
Sungjoong Kangca31bf22012-10-04 19:38:41 -07003011 shot_ext->shot.ctl.aa.afRegions[0] = shot_ext->shot.ctl.aa.aeRegions[0] = lastAfRegion[0] = 0;
3012 shot_ext->shot.ctl.aa.afRegions[1] = shot_ext->shot.ctl.aa.aeRegions[1] = lastAfRegion[1] = 0;
3013 shot_ext->shot.ctl.aa.afRegions[2] = shot_ext->shot.ctl.aa.aeRegions[2] = lastAfRegion[2] = 0;
3014 shot_ext->shot.ctl.aa.afRegions[3] = shot_ext->shot.ctl.aa.aeRegions[3] = lastAfRegion[3] = 0;
Younghwan Joo275c9742012-09-25 21:12:30 +09003015 } else if (!(lastAfRegion[0] == shot_ext->shot.ctl.aa.afRegions[0] && lastAfRegion[1] == shot_ext->shot.ctl.aa.afRegions[1]
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003016 && lastAfRegion[2] == shot_ext->shot.ctl.aa.afRegions[2] && lastAfRegion[3] == shot_ext->shot.ctl.aa.afRegions[3])) {
Younghwan Joo1e73adb2012-09-21 00:42:08 -07003017 ALOGD("(%s): AF region changed : triggering (%d)", __FUNCTION__, m_afMode);
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003018 shot_ext->shot.ctl.aa.afTrigger = 1;
3019 shot_ext->shot.ctl.aa.afMode = m_afMode;
3020 m_afState = HAL_AFSTATE_STARTED;
3021 lastAfRegion[0] = shot_ext->shot.ctl.aa.afRegions[0];
3022 lastAfRegion[1] = shot_ext->shot.ctl.aa.afRegions[1];
3023 lastAfRegion[2] = shot_ext->shot.ctl.aa.afRegions[2];
3024 lastAfRegion[3] = shot_ext->shot.ctl.aa.afRegions[3];
3025 m_IsAfTriggerRequired = false;
3026 }
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003027 }
3028}
3029
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003030void ExynosCameraHWInterface2::m_afTrigger(struct camera2_shot_ext * shot_ext, int mode)
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003031{
3032 if (m_afState == HAL_AFSTATE_SCANNING) {
3033 ALOGD("(%s): restarting trigger ", __FUNCTION__);
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003034 } else if (!mode) {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003035 if (m_afState != HAL_AFSTATE_NEEDS_COMMAND)
3036 ALOGD("(%s): wrong trigger state %d", __FUNCTION__, m_afState);
3037 else
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003038 m_afState = HAL_AFSTATE_STARTED;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003039 }
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003040 ALOGD("### AF Triggering with mode (%d) (%d)", m_afMode, m_afState);
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003041 shot_ext->shot.ctl.aa.afTrigger = 1;
3042 shot_ext->shot.ctl.aa.afMode = m_afMode;
3043 m_IsAfTriggerRequired = false;
3044}
3045
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003046void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
3047{
3048 uint32_t currentSignal = self->GetProcessingSignal();
3049 SensorThread * selfThread = ((SensorThread*)self);
3050 int index;
Sungjoong Kangad378612012-08-17 12:34:33 -07003051 int index_isp;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003052 status_t res;
3053 nsecs_t frameTime;
3054 int bayersOnSensor = 0, bayersOnIsp = 0;
Sungjoong Kangad378612012-08-17 12:34:33 -07003055 int j = 0;
3056 bool isCapture = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003057 ALOGV("DEBUG(%s): m_sensorThreadFunc (%x)", __FUNCTION__, currentSignal);
3058
3059 if (currentSignal & SIGNAL_THREAD_RELEASE) {
hyeonmyeong Choi2c872802012-09-08 15:39:58 -07003060 CAM_LOGD("(%s): ENTER processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003061
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003062 ALOGV("(%s): calling sensor streamoff", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003063 cam_int_streamoff(&(m_camera_info.sensor));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003064 ALOGV("(%s): calling sensor streamoff done", __FUNCTION__);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003065
3066 m_camera_info.sensor.buffers = 0;
3067 ALOGV("DEBUG(%s): sensor calling reqbuf 0 ", __FUNCTION__);
3068 cam_int_reqbufs(&(m_camera_info.sensor));
3069 ALOGV("DEBUG(%s): sensor calling reqbuf 0 done", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003070 m_camera_info.sensor.status = false;
Sungjoong Kangad378612012-08-17 12:34:33 -07003071
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003072 ALOGV("(%s): calling ISP streamoff", __FUNCTION__);
3073 isp_int_streamoff(&(m_camera_info.isp));
3074 ALOGV("(%s): calling ISP streamoff done", __FUNCTION__);
Sungjoong Kangad378612012-08-17 12:34:33 -07003075
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003076 m_camera_info.isp.buffers = 0;
3077 ALOGV("DEBUG(%s): isp calling reqbuf 0 ", __FUNCTION__);
3078 cam_int_reqbufs(&(m_camera_info.isp));
3079 ALOGV("DEBUG(%s): isp calling reqbuf 0 done", __FUNCTION__);
3080
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003081 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_DISABLE_STREAM);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003082
Sungjoong Kang52f54302012-09-04 21:43:06 +09003083 m_requestManager->releaseSensorQ();
Jiyoung Shin2adfa422012-09-10 23:14:54 +09003084 m_requestManager->ResetEntry();
Sungjoong Kangad378612012-08-17 12:34:33 -07003085 ALOGV("(%s): EXIT processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003086 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
3087 return;
3088 }
3089
3090 if (currentSignal & SIGNAL_SENSOR_START_REQ_PROCESSING)
3091 {
3092 ALOGV("DEBUG(%s): SensorThread processing SIGNAL_SENSOR_START_REQ_PROCESSING", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003093 int targetStreamIndex = 0, i=0;
Sungjoong Kangad378612012-08-17 12:34:33 -07003094 int matchedFrameCnt = -1, processingReqIndex;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003095 struct camera2_shot_ext *shot_ext;
Sungjoong Kangad378612012-08-17 12:34:33 -07003096 struct camera2_shot_ext *shot_ext_capture;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003097 bool triggered = false;
3098 int afMode;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003099
Sungjoong Kangad378612012-08-17 12:34:33 -07003100 /* dqbuf from sensor */
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003101 ALOGV("Sensor DQbuf start");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003102 index = cam_int_dqbuf(&(m_camera_info.sensor));
Sungjoong Kang52f54302012-09-04 21:43:06 +09003103 m_requestManager->pushSensorQ(index);
3104 ALOGV("Sensor DQbuf done(%d)", index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003105 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
Sungjoong Kangad378612012-08-17 12:34:33 -07003106
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003107 if (m_nightCaptureCnt != 0) {
3108 matchedFrameCnt = m_nightCaptureFrameCnt;
Younghwan Jooe117f752012-09-12 22:21:55 -07003109 } else if (m_ctlInfo.flash.m_flashCnt >= IS_FLASH_STATE_CAPTURE) {
Younghwan Joo9a710a42012-09-05 17:52:08 -07003110 matchedFrameCnt = m_ctlInfo.flash.m_flashFrameCount;
Younghwan Joocaea49e2012-09-07 13:34:20 -07003111 ALOGV("Skip frame, request is fixed at %d", matchedFrameCnt);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003112 } else {
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003113 matchedFrameCnt = m_requestManager->FindFrameCnt(shot_ext);
3114 }
Sungjoong Kangad378612012-08-17 12:34:33 -07003115
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003116 if (matchedFrameCnt == -1 && m_vdisBubbleCnt > 0) {
3117 matchedFrameCnt = m_vdisDupFrame;
3118 }
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003119
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07003120 if (matchedFrameCnt != -1) {
Hyeonmyeong Choice773652012-10-02 13:08:59 +09003121 if (m_vdisBubbleCnt == 0 || m_vdisDupFrame != matchedFrameCnt) {
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003122 frameTime = systemTime();
3123 m_requestManager->RegisterTimestamp(matchedFrameCnt, &frameTime);
3124 m_requestManager->UpdateIspParameters(shot_ext, matchedFrameCnt, &m_ctlInfo);
Hyeonmyeong Choice773652012-10-02 13:08:59 +09003125 } else {
3126 ALOGV("bubble for vids: m_vdisBubbleCnt %d, matchedFrameCnt %d", m_vdisDupFrame, matchedFrameCnt);
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003127 }
Younghwan Joo9a710a42012-09-05 17:52:08 -07003128
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003129 // face af mode setting in case of face priority scene mode
3130 if (m_ctlInfo.scene.prevSceneMode != shot_ext->shot.ctl.aa.sceneMode) {
3131 ALOGV("(%s): Scene mode changed (%d)", __FUNCTION__, shot_ext->shot.ctl.aa.sceneMode);
3132 m_ctlInfo.scene.prevSceneMode = shot_ext->shot.ctl.aa.sceneMode;
3133 }
3134
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07003135 if (m_afModeWaitingCnt != 0) {
3136 ALOGV("### Af Trigger pulled, waiting for mode change cnt(%d) ", m_afModeWaitingCnt);
3137 m_afModeWaitingCnt --;
3138 if (m_afModeWaitingCnt == 1) {
Sungjoong Kangcd13bb72012-08-28 13:05:01 -07003139 m_afModeWaitingCnt = 0;
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07003140 OnAfTrigger(m_afPendingTriggerId);
3141 }
3142 }
hyeonmyeong Choi308291d2012-08-29 13:55:01 -07003143 m_zoomRatio = (float)m_camera2->getSensorW() / (float)shot_ext->shot.ctl.scaler.cropRegion[2];
Sungjoong Kange4657e32012-08-28 15:02:19 -07003144 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
3145 int crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0;
3146
3147 m_getRatioSize(m_camera2->getSensorW(), m_camera2->getSensorH(),
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003148 m_streamThreads[0]->m_parameters.width, m_streamThreads[0]->m_parameters.height,
Sungjoong Kange4657e32012-08-28 15:02:19 -07003149 &crop_x, &crop_y,
3150 &crop_w, &crop_h,
3151 0);
3152
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003153 if (m_streamThreads[0]->m_parameters.width >= m_streamThreads[0]->m_parameters.height) {
hyeonmyeong Choi308291d2012-08-29 13:55:01 -07003154 zoomWidth = m_camera2->getSensorW() / m_zoomRatio;
Sungjoong Kange4657e32012-08-28 15:02:19 -07003155 zoomHeight = zoomWidth *
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003156 m_streamThreads[0]->m_parameters.height / m_streamThreads[0]->m_parameters.width;
Sungjoong Kange4657e32012-08-28 15:02:19 -07003157 } else {
hyeonmyeong Choi308291d2012-08-29 13:55:01 -07003158 zoomHeight = m_camera2->getSensorH() / m_zoomRatio;
Sungjoong Kange4657e32012-08-28 15:02:19 -07003159 zoomWidth = zoomHeight *
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003160 m_streamThreads[0]->m_parameters.width / m_streamThreads[0]->m_parameters.height;
Sungjoong Kange4657e32012-08-28 15:02:19 -07003161 }
3162 zoomLeft = (crop_w - zoomWidth) / 2;
3163 zoomTop = (crop_h - zoomHeight) / 2;
3164
3165 int32_t new_cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3166
Hyeonmyeong Choi408f6162012-10-02 12:57:42 +09003167 int cropCompensation = (new_cropRegion[0] * 2 + new_cropRegion[2]) - ALIGN(crop_w, 4);
3168 if (cropCompensation)
3169 new_cropRegion[2] -= cropCompensation;
hyeonmyeong Choi308291d2012-08-29 13:55:01 -07003170
Sungjoong Kange4657e32012-08-28 15:02:19 -07003171 shot_ext->shot.ctl.scaler.cropRegion[0] = new_cropRegion[0];
3172 shot_ext->shot.ctl.scaler.cropRegion[1] = new_cropRegion[1];
3173 shot_ext->shot.ctl.scaler.cropRegion[2] = new_cropRegion[2];
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003174 if (m_IsAfModeUpdateRequired && (m_ctlInfo.flash.m_precaptureTriggerId == 0)) {
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07003175 ALOGD("### AF Mode change(Mode %d) ", m_afMode);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003176 shot_ext->shot.ctl.aa.afMode = m_afMode;
3177 if (m_afMode == AA_AFMODE_CONTINUOUS_VIDEO || m_afMode == AA_AFMODE_CONTINUOUS_PICTURE) {
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07003178 ALOGD("### With Automatic triger for continuous modes");
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003179 m_afState = HAL_AFSTATE_STARTED;
3180 shot_ext->shot.ctl.aa.afTrigger = 1;
3181 triggered = true;
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003182 if ((m_ctlInfo.scene.prevSceneMode == AA_SCENE_MODE_UNSUPPORTED) ||
3183 (m_ctlInfo.scene.prevSceneMode == AA_SCENE_MODE_FACE_PRIORITY)) {
3184 switch (m_afMode) {
3185 case AA_AFMODE_CONTINUOUS_PICTURE:
3186 shot_ext->shot.ctl.aa.afMode = AA_AFMODE_CONTINUOUS_PICTURE_FACE;
3187 ALOGD("### Face AF Mode change (Mode %d) ", shot_ext->shot.ctl.aa.afMode);
3188 break;
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003189 }
3190 }
Younghwan Joocdd53a92012-10-03 17:00:15 +09003191 // reset flash result
3192 if (m_ctlInfo.flash.m_afFlashDoneFlg) {
3193 m_ctlInfo.flash.m_flashEnableFlg = false;
3194 m_ctlInfo.flash.m_afFlashDoneFlg = false;
3195 m_ctlInfo.flash.m_flashDecisionResult = false;
3196 m_ctlInfo.flash.m_flashCnt = 0;
3197 }
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003198 m_ctlInfo.af.m_afTriggerTimeOut = 1;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003199 }
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003200
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003201 m_IsAfModeUpdateRequired = false;
Younghwan Joo311d52e2012-09-13 22:07:41 -07003202 // support inifinity focus mode
Younghwan Joofdbaf5d2012-09-15 01:22:10 -07003203 if ((m_afMode == AA_AFMODE_MANUAL) && ( shot_ext->shot.ctl.lens.focusDistance == 0)) {
Younghwan Joo311d52e2012-09-13 22:07:41 -07003204 shot_ext->shot.ctl.aa.afMode = AA_AFMODE_INFINITY;
3205 shot_ext->shot.ctl.aa.afTrigger = 1;
3206 triggered = true;
3207 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003208 if (m_afMode2 != NO_CHANGE) {
3209 enum aa_afmode tempAfMode = m_afMode2;
3210 m_afMode2 = NO_CHANGE;
3211 SetAfMode(tempAfMode);
3212 }
3213 }
3214 else {
3215 shot_ext->shot.ctl.aa.afMode = NO_CHANGE;
3216 }
3217 if (m_IsAfTriggerRequired) {
Younghwan Jooe117f752012-09-12 22:21:55 -07003218 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003219 // flash case
Younghwan Jooe117f752012-09-12 22:21:55 -07003220 if (m_ctlInfo.flash.m_flashCnt == IS_FLASH_STATE_ON_DONE) {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003221 if ((m_afMode != AA_AFMODE_AUTO) && (m_afMode != AA_AFMODE_MACRO)) {
3222 // Flash is enabled and start AF
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003223 m_afTrigger(shot_ext, 1);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003224 } else {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003225 if (m_ctlInfo.af.m_afTriggerTimeOut == 0)
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003226 m_afTrigger(shot_ext, 0);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003227 else
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003228 m_ctlInfo.af.m_afTriggerTimeOut--;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003229 }
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003230 }
3231 } else {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003232 // non-flash case
3233 if ((m_afMode != AA_AFMODE_AUTO) && (m_afMode != AA_AFMODE_MACRO)) {
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003234 m_afTrigger(shot_ext, 0);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003235 } else {
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003236 if (m_ctlInfo.af.m_afTriggerTimeOut == 0)
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09003237 m_afTrigger(shot_ext, 0);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003238 else
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003239 m_ctlInfo.af.m_afTriggerTimeOut--;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003240 }
Sungjoong Kang36c106c2012-08-23 17:38:20 -07003241 }
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003242 } else {
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07003243 shot_ext->shot.ctl.aa.afTrigger = 0;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003244 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003245
3246 if (m_wideAspect) {
3247 shot_ext->setfile = ISS_SUB_SCENARIO_VIDEO;
3248 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
Sungjoong Kang15fd8232012-08-23 16:16:44 -07003249 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003250 } else {
3251 shot_ext->setfile = ISS_SUB_SCENARIO_STILL;
Sungjoong Kang15fd8232012-08-23 16:16:44 -07003252 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003253 if (triggered)
3254 shot_ext->shot.ctl.aa.afTrigger = 1;
3255
3256 // TODO : check collision with AFMode Update
3257 if (m_IsAfLockRequired) {
3258 shot_ext->shot.ctl.aa.afMode = AA_AFMODE_OFF;
3259 m_IsAfLockRequired = false;
3260 }
Rebecca Schultz Zavin4ed2f102012-08-22 00:55:29 -07003261 ALOGV("### Isp Qbuf start(%d) count (%d), SCP(%d) SCC(%d) DIS(%d) shot_size(%d)",
Sungjoong Kangad378612012-08-17 12:34:33 -07003262 index,
3263 shot_ext->shot.ctl.request.frameCount,
3264 shot_ext->request_scp,
3265 shot_ext->request_scc,
3266 shot_ext->dis_bypass, sizeof(camera2_shot));
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003267
3268 // update AF region
3269 m_updateAfRegion(shot_ext);
3270
Sungjoong Kang572470e2012-10-03 19:30:25 -07003271 m_lastSceneMode = shot_ext->shot.ctl.aa.sceneMode;
Sungjoong Kang6bf36b62012-09-13 01:50:21 -07003272 if (shot_ext->shot.ctl.aa.sceneMode == AA_SCENE_MODE_NIGHT
3273 && shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_LOCKED)
3274 shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_ON;
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003275 if (m_nightCaptureCnt == 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003276 if (shot_ext->shot.ctl.aa.captureIntent == AA_CAPTURE_INTENT_STILL_CAPTURE
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003277 && shot_ext->shot.ctl.aa.sceneMode == AA_SCENE_MODE_NIGHT) {
3278 shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_NIGHT_CAPTURE;
Sungjoong Kang1c5e6922012-09-22 00:47:33 -07003279 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 2;
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003280 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
3281 m_nightCaptureCnt = 4;
3282 m_nightCaptureFrameCnt = matchedFrameCnt;
3283 shot_ext->request_scc = 0;
3284 }
3285 }
3286 else if (m_nightCaptureCnt == 1) {
3287 shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_NIGHT_CAPTURE;
Sungjoong Kang1c5e6922012-09-22 00:47:33 -07003288 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
3289 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003290 m_nightCaptureCnt--;
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003291 m_nightCaptureFrameCnt = 0;
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003292 shot_ext->request_scc = 1;
3293 }
Sungjoong Kang6bf36b62012-09-13 01:50:21 -07003294 else if (m_nightCaptureCnt == 2) {
3295 shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_NIGHT_CAPTURE;
Sungjoong Kang1c5e6922012-09-22 00:47:33 -07003296 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 2;
3297 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
Sungjoong Kang6bf36b62012-09-13 01:50:21 -07003298 m_nightCaptureCnt--;
3299 shot_ext->request_scc = 0;
3300 }
Sungjoong Kang1c5e6922012-09-22 00:47:33 -07003301 else if (m_nightCaptureCnt == 3) {
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003302 shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_NIGHT_CAPTURE;
Sungjoong Kang1c5e6922012-09-22 00:47:33 -07003303 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 2;
3304 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
3305 m_nightCaptureCnt--;
3306 shot_ext->request_scc = 0;
3307 }
3308 else if (m_nightCaptureCnt == 4) {
3309 shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_NIGHT_CAPTURE;
3310 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 2;
3311 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003312 m_nightCaptureCnt--;
3313 shot_ext->request_scc = 0;
3314 }
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003315
3316 // Flash mode
3317 // Keep and Skip request_scc = 1 at flash enable mode to operate flash sequence
Younghwan Jooe117f752012-09-12 22:21:55 -07003318 if ((m_ctlInfo.flash.i_flashMode >= AA_AEMODE_ON_AUTO_FLASH)
3319 && (shot_ext->shot.ctl.aa.captureIntent == AA_CAPTURE_INTENT_STILL_CAPTURE)
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003320 && (m_cameraId == 0)) {
Younghwan Jooe117f752012-09-12 22:21:55 -07003321 if (!m_ctlInfo.flash.m_flashDecisionResult) {
3322 m_ctlInfo.flash.m_flashEnableFlg = false;
3323 m_ctlInfo.flash.m_afFlashDoneFlg = false;
3324 m_ctlInfo.flash.m_flashCnt = 0;
Younghwan Joocdd53a92012-10-03 17:00:15 +09003325 } else if ((m_ctlInfo.flash.m_flashCnt == IS_FLASH_STATE_AUTO_DONE) ||
3326 (m_ctlInfo.flash.m_flashCnt == IS_FLASH_STATE_AUTO_OFF)) {
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003327 ALOGD("(%s): [Flash] Flash capture start : skip request scc 1#####", __FUNCTION__);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003328 shot_ext->request_scc = 0;
Younghwan Joo9a710a42012-09-05 17:52:08 -07003329 m_ctlInfo.flash.m_flashFrameCount = matchedFrameCnt;
3330 m_ctlInfo.flash.m_flashEnableFlg = true;
Younghwan Jooe117f752012-09-12 22:21:55 -07003331 m_ctlInfo.flash.m_afFlashDoneFlg = false;
3332 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_CAPTURE;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07003333 } else if (m_ctlInfo.flash.m_flashCnt < IS_FLASH_STATE_AUTO_DONE) {
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003334 ALOGE("(%s): [Flash] Flash capture Error- wrong state !!!!!! (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
3335 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_OFF;
3336 m_ctlInfo.flash.m_flashEnableFlg = false;
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003337 m_ctlInfo.flash.m_afFlashDoneFlg= false;
Younghwan Joocdd53a92012-10-03 17:00:15 +09003338 m_ctlInfo.flash.m_flashCnt = 0;
Younghwan Joocaea49e2012-09-07 13:34:20 -07003339 }
Younghwan Joo4a9565a2012-09-19 18:41:35 -07003340 } else if (shot_ext->shot.ctl.aa.captureIntent == AA_CAPTURE_INTENT_STILL_CAPTURE) {
3341 m_ctlInfo.flash.m_flashDecisionResult = false;
Younghwan Joocaea49e2012-09-07 13:34:20 -07003342 }
3343
3344 // TODO : set torch mode for video recording. need to find proper position.
3345 // m_wideAspect is will be changed to recording hint
3346 if ((shot_ext->shot.ctl.flash.flashMode == CAM2_FLASH_MODE_SINGLE) && m_wideAspect) {
3347 shot_ext->shot.ctl.flash.flashMode = CAM2_FLASH_MODE_TORCH;
3348 shot_ext->shot.ctl.flash.firingPower = 10;
3349 m_ctlInfo.flash.m_flashTorchMode = true;
3350 } else if (m_wideAspect){
3351 shot_ext->shot.ctl.flash.flashMode = CAM2_FLASH_MODE_OFF;
3352 shot_ext->shot.ctl.flash.firingPower = 0;
3353 m_ctlInfo.flash.m_flashTorchMode = false;
3354 } else {
3355 if (m_ctlInfo.flash.m_flashTorchMode) {
3356 shot_ext->shot.ctl.flash.flashMode = CAM2_FLASH_MODE_OFF;
3357 shot_ext->shot.ctl.flash.firingPower = 0;
3358 m_ctlInfo.flash.m_flashTorchMode = false;
3359 } else {
3360 shot_ext->shot.ctl.flash.flashMode = CAM2_FLASH_MODE_NOP;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07003361 }
3362 }
3363
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003364 if (shot_ext->isReprocessing) {
Sungjoong Kang69d1e6e2012-10-03 00:39:13 -07003365 ALOGV("(%s): Sending signal for Reprocess request", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003366 m_currentReprocessOutStreams = shot_ext->shot.ctl.request.outputStreams[0];
3367 shot_ext->request_scp = 0;
3368 shot_ext->request_scc = 0;
3369 m_reprocessingFrameCnt = shot_ext->shot.ctl.request.frameCount;
Sungjoong Kang69d1e6e2012-10-03 00:39:13 -07003370 m_ctlInfo.flash.m_flashDecisionResult = false;
3371 memcpy(&m_jpegMetadata, (void*)(m_requestManager->GetInternalShotExtByFrameCnt(m_reprocessingFrameCnt)),
3372 sizeof(struct camera2_shot_ext));
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003373 m_streamThreads[1]->SetSignal(SIGNAL_STREAM_REPROCESSING_START);
Younghwan Joocdd53a92012-10-03 17:00:15 +09003374 m_ctlInfo.flash.m_flashEnableFlg = false;
3375 }
3376
3377 if (m_ctlInfo.flash.m_flashEnableFlg) {
3378 m_preCaptureListenerSensor(shot_ext);
3379 m_preCaptureSetter(shot_ext);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003380 }
Younghwan Joofdbaf5d2012-09-15 01:22:10 -07003381
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07003382 ALOGV("(%s): queued aa(%d) aemode(%d) awb(%d) afmode(%d) trigger(%d)", __FUNCTION__,
3383 (int)(shot_ext->shot.ctl.aa.mode), (int)(shot_ext->shot.ctl.aa.aeMode),
3384 (int)(shot_ext->shot.ctl.aa.awbMode), (int)(shot_ext->shot.ctl.aa.afMode),
3385 (int)(shot_ext->shot.ctl.aa.afTrigger));
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07003386
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003387 if (m_vdisBubbleCnt > 0 && m_vdisDupFrame == matchedFrameCnt) {
3388 shot_ext->dis_bypass = 1;
3389 shot_ext->request_scp = 0;
3390 shot_ext->request_scc = 0;
3391 m_vdisBubbleCnt--;
3392 matchedFrameCnt = -1;
3393 } else {
3394 m_vdisDupFrame = matchedFrameCnt;
3395 }
Sungjoong Kangf9a06602012-09-24 13:46:10 -07003396 if (m_scpForceSuspended)
3397 shot_ext->request_scc = 0;
hyeonmyeong Choi5c88d1f2012-09-13 02:05:37 -07003398
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003399 uint32_t current_scp = shot_ext->request_scp;
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003400 uint32_t current_scc = shot_ext->request_scc;
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07003401
hyeonmyeong Choic0b6e172012-09-05 00:51:31 -07003402 if (shot_ext->shot.dm.request.frameCount == 0) {
hyeonmyeong Choi4aa4d732012-09-10 11:53:49 -07003403 CAM_LOGE("ERR(%s): dm.request.frameCount = %d", __FUNCTION__, shot_ext->shot.dm.request.frameCount);
hyeonmyeong Choic0b6e172012-09-05 00:51:31 -07003404 }
3405
Sungjoong Kangad378612012-08-17 12:34:33 -07003406 cam_int_qbuf(&(m_camera_info.isp), index);
Sungjoong Kangad378612012-08-17 12:34:33 -07003407
Sungjoong Kangad378612012-08-17 12:34:33 -07003408 ALOGV("### isp DQBUF start");
3409 index_isp = cam_int_dqbuf(&(m_camera_info.isp));
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003410
Sungjoong Kangad378612012-08-17 12:34:33 -07003411 shot_ext = (struct camera2_shot_ext *)(m_camera_info.isp.buffer[index_isp].virt.extP[1]);
3412
Younghwan Jooe117f752012-09-12 22:21:55 -07003413 if (m_ctlInfo.flash.m_flashEnableFlg)
3414 m_preCaptureListenerISP(shot_ext);
Younghwan Joo9a710a42012-09-05 17:52:08 -07003415
Hyeonmyeong Choi7ef20f42012-10-05 13:10:21 +09003416 ALOGV("### Isp DQbuf done(%d) count (%d), SCP(%d) SCC(%d) dis_bypass(%d) dnr_bypass(%d) shot_size(%d)",
Sungjoong Kangad378612012-08-17 12:34:33 -07003417 index,
3418 shot_ext->shot.ctl.request.frameCount,
3419 shot_ext->request_scp,
3420 shot_ext->request_scc,
Hyeonmyeong Choi7ef20f42012-10-05 13:10:21 +09003421 shot_ext->dis_bypass,
3422 shot_ext->dnr_bypass, sizeof(camera2_shot));
Younghwan Joofdbaf5d2012-09-15 01:22:10 -07003423
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003424 ALOGV("(%s): DM aa(%d) aemode(%d) awb(%d) afmode(%d)", __FUNCTION__,
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07003425 (int)(shot_ext->shot.dm.aa.mode), (int)(shot_ext->shot.dm.aa.aeMode),
3426 (int)(shot_ext->shot.dm.aa.awbMode),
3427 (int)(shot_ext->shot.dm.aa.afMode));
Sungjoong Kangad378612012-08-17 12:34:33 -07003428
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003429#ifndef ENABLE_FRAME_SYNC
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003430 m_currentOutputStreams = shot_ext->shot.ctl.request.outputStreams[0];
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003431#endif
Jiyoung Shin2adfa422012-09-10 23:14:54 +09003432
Sungjoong Kangfd2d78a2012-08-26 17:44:25 -07003433 if (!shot_ext->fd_bypass) {
3434 /* FD orientation axis transformation */
3435 for (int i=0; i < CAMERA2_MAX_FACES; i++) {
3436 if (shot_ext->shot.dm.stats.faceRectangles[i][0] > 0)
3437 shot_ext->shot.dm.stats.faceRectangles[i][0] = (m_camera2->m_curCameraInfo->sensorW
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003438 * shot_ext->shot.dm.stats.faceRectangles[i][0])
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003439 / m_streamThreads[0].get()->m_parameters.width;
Sungjoong Kangfd2d78a2012-08-26 17:44:25 -07003440 if (shot_ext->shot.dm.stats.faceRectangles[i][1] > 0)
3441 shot_ext->shot.dm.stats.faceRectangles[i][1] = (m_camera2->m_curCameraInfo->sensorH
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003442 * shot_ext->shot.dm.stats.faceRectangles[i][1])
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003443 / m_streamThreads[0].get()->m_parameters.height;
Sungjoong Kangfd2d78a2012-08-26 17:44:25 -07003444 if (shot_ext->shot.dm.stats.faceRectangles[i][2] > 0)
3445 shot_ext->shot.dm.stats.faceRectangles[i][2] = (m_camera2->m_curCameraInfo->sensorW
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003446 * shot_ext->shot.dm.stats.faceRectangles[i][2])
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003447 / m_streamThreads[0].get()->m_parameters.width;
Sungjoong Kangfd2d78a2012-08-26 17:44:25 -07003448 if (shot_ext->shot.dm.stats.faceRectangles[i][3] > 0)
3449 shot_ext->shot.dm.stats.faceRectangles[i][3] = (m_camera2->m_curCameraInfo->sensorH
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003450 * shot_ext->shot.dm.stats.faceRectangles[i][3])
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003451 / m_streamThreads[0].get()->m_parameters.height;
Sungjoong Kangfd2d78a2012-08-26 17:44:25 -07003452 }
3453 }
Younghwan Joocdd53a92012-10-03 17:00:15 +09003454 // aeState control
3455 if (shot_ext->shot.ctl.aa.sceneMode != AA_SCENE_MODE_NIGHT)
3456 m_preCaptureAeState(shot_ext);
Younghwan Joo47d3a1e2012-09-22 01:15:20 -07003457
Younghwan Joo275c9742012-09-25 21:12:30 +09003458 // At scene mode face priority
Younghwan Joo40acdcc2012-09-29 16:32:43 +09003459 if (shot_ext->shot.dm.aa.afMode == AA_AFMODE_CONTINUOUS_PICTURE_FACE)
3460 shot_ext->shot.dm.aa.afMode = AA_AFMODE_CONTINUOUS_PICTURE;
Younghwan Joo275c9742012-09-25 21:12:30 +09003461
Sungjoong Kang48728d42012-09-26 13:48:48 -07003462 if (matchedFrameCnt != -1 && m_nightCaptureCnt == 0 && (m_ctlInfo.flash.m_flashCnt < IS_FLASH_STATE_CAPTURE)) {
Sungjoong Kanga15b4e32012-08-28 12:55:39 -07003463 m_requestManager->ApplyDynamicMetadata(shot_ext);
3464 }
Sungjoong Kang69d1e6e2012-10-03 00:39:13 -07003465
3466 if (current_scc != shot_ext->request_scc) {
3467 ALOGD("(%s): scc frame drop1 request_scc(%d to %d)",
3468 __FUNCTION__, current_scc, shot_ext->request_scc);
3469 m_requestManager->NotifyStreamOutput(shot_ext->shot.ctl.request.frameCount);
3470 }
3471 if (shot_ext->request_scc) {
3472 ALOGV("send SIGNAL_STREAM_DATA_COMING (SCC)");
3473 if (shot_ext->shot.ctl.request.outputStreams[0] & STREAM_MASK_JPEG) {
3474 if (m_ctlInfo.flash.m_flashCnt < IS_FLASH_STATE_CAPTURE)
3475 memcpy(&m_jpegMetadata, (void*)(m_requestManager->GetInternalShotExtByFrameCnt(shot_ext->shot.ctl.request.frameCount)),
3476 sizeof(struct camera2_shot_ext));
3477 else
3478 memcpy(&m_jpegMetadata, (void*)shot_ext, sizeof(struct camera2_shot_ext));
3479 }
3480 m_streamThreads[1]->SetSignal(SIGNAL_STREAM_DATA_COMING);
3481 }
3482 if (current_scp != shot_ext->request_scp) {
3483 ALOGD("(%s): scp frame drop1 request_scp(%d to %d)",
3484 __FUNCTION__, current_scp, shot_ext->request_scp);
3485 m_requestManager->NotifyStreamOutput(shot_ext->shot.ctl.request.frameCount);
3486 }
3487 if (shot_ext->request_scp) {
3488 ALOGV("send SIGNAL_STREAM_DATA_COMING (SCP)");
3489 m_streamThreads[0]->SetSignal(SIGNAL_STREAM_DATA_COMING);
3490 }
3491
3492 ALOGV("(%s): SCP_CLOSING check sensor(%d) scc(%d) scp(%d) ", __FUNCTION__,
3493 shot_ext->request_sensor, shot_ext->request_scc, shot_ext->request_scp);
3494 if (shot_ext->request_scc + shot_ext->request_scp + shot_ext->request_sensor == 0) {
3495 ALOGV("(%s): SCP_CLOSING check OK ", __FUNCTION__);
3496 m_scp_closed = true;
3497 }
3498 else
3499 m_scp_closed = false;
3500
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003501 OnAfNotification(shot_ext->shot.dm.aa.afState);
Younghwan Joo73f5ad62012-09-16 21:05:30 -07003502 OnPrecaptureMeteringNotificationISP();
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003503 } else {
Hyeonmyeong Choi8b5b8072012-09-29 17:38:37 +09003504 memcpy(&shot_ext->shot.ctl, &m_camera_info.dummy_shot.shot.ctl, sizeof(struct camera2_ctl));
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003505 shot_ext->shot.ctl.request.frameCount = 0xfffffffe;
3506 shot_ext->request_sensor = 1;
3507 shot_ext->dis_bypass = 1;
3508 shot_ext->dnr_bypass = 1;
3509 shot_ext->fd_bypass = 1;
3510 shot_ext->drc_bypass = 1;
3511 shot_ext->request_scc = 0;
3512 shot_ext->request_scp = 0;
3513 if (m_wideAspect) {
3514 shot_ext->setfile = ISS_SUB_SCENARIO_VIDEO;
3515 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
3516 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
3517 } else {
3518 shot_ext->setfile = ISS_SUB_SCENARIO_STILL;
3519 }
Sungjoong Kang572470e2012-10-03 19:30:25 -07003520 shot_ext->shot.ctl.aa.sceneMode = (enum aa_scene_mode)m_lastSceneMode;
3521 if (shot_ext->shot.ctl.aa.sceneMode == AA_SCENE_MODE_NIGHT_CAPTURE || shot_ext->shot.ctl.aa.sceneMode == AA_SCENE_MODE_NIGHT) {
3522 shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 8;
3523 shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
3524 }
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003525 shot_ext->shot.ctl.aa.aeflashMode = AA_FLASHMODE_OFF;
Younghwan Joocdd53a92012-10-03 17:00:15 +09003526 shot_ext->shot.ctl.flash.flashMode = CAM2_FLASH_MODE_OFF;
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003527 ALOGV("### isp QBUF start (bubble)");
Hyeonmyeong Choi8b5b8072012-09-29 17:38:37 +09003528 ALOGV("bubble: queued aa(%d) aemode(%d) awb(%d) afmode(%d) trigger(%d)",
3529 (int)(shot_ext->shot.ctl.aa.mode), (int)(shot_ext->shot.ctl.aa.aeMode),
3530 (int)(shot_ext->shot.ctl.aa.awbMode), (int)(shot_ext->shot.ctl.aa.afMode),
3531 (int)(shot_ext->shot.ctl.aa.afTrigger));
3532
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003533 cam_int_qbuf(&(m_camera_info.isp), index);
3534 ALOGV("### isp DQBUF start (bubble)");
3535 index_isp = cam_int_dqbuf(&(m_camera_info.isp));
3536 shot_ext = (struct camera2_shot_ext *)(m_camera_info.isp.buffer[index_isp].virt.extP[1]);
Hyeonmyeong Choi8b5b8072012-09-29 17:38:37 +09003537 ALOGV("bubble: DM aa(%d) aemode(%d) awb(%d) afmode(%d)",
3538 (int)(shot_ext->shot.dm.aa.mode), (int)(shot_ext->shot.dm.aa.aeMode),
3539 (int)(shot_ext->shot.dm.aa.awbMode),
3540 (int)(shot_ext->shot.dm.aa.afMode));
3541
Sungjoong Kang10e122b2012-09-26 14:04:23 -07003542 OnAfNotification(shot_ext->shot.dm.aa.afState);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003543 }
Sungjoong Kangad378612012-08-17 12:34:33 -07003544
Sungjoong Kang52f54302012-09-04 21:43:06 +09003545 index = m_requestManager->popSensorQ();
3546 if(index < 0){
3547 ALOGE("sensorQ is empty");
3548 return;
3549 }
3550
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003551 processingReqIndex = m_requestManager->MarkProcessingRequest(&(m_camera_info.sensor.buffer[index]), &afMode);
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003552 if (processingReqIndex != -1)
Sungjoong Kang0f26b202012-08-17 15:43:12 -07003553 SetAfMode((enum aa_afmode)afMode);
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003554
Sungjoong Kangad378612012-08-17 12:34:33 -07003555
3556 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
3557 if (m_scp_closing || m_scp_closed) {
3558 ALOGD("(%s): SCP_CLOSING(%d) SCP_CLOSED(%d)", __FUNCTION__, m_scp_closing, m_scp_closed);
3559 shot_ext->request_scc = 0;
3560 shot_ext->request_scp = 0;
3561 shot_ext->request_sensor = 0;
3562 }
Sungjoong Kangad378612012-08-17 12:34:33 -07003563 cam_int_qbuf(&(m_camera_info.sensor), index);
Sungjoong Kang52f54302012-09-04 21:43:06 +09003564 ALOGV("Sensor Qbuf done(%d)", index);
Sungjoong Kangad378612012-08-17 12:34:33 -07003565
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003566 if (!m_scp_closing
3567 && ((matchedFrameCnt == -1) || (processingReqIndex == -1))){
Younghwan Jooda7ca692012-09-03 20:47:21 -07003568 ALOGV("make bubble shot: matchedFramcnt(%d) processingReqIndex(%d)",
Sungjoong Kangef6f83c2012-08-28 22:59:48 +09003569 matchedFrameCnt, processingReqIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003570 selfThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003571 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003572 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003573 return;
3574}
3575
Sungjoong Kang86646da2012-08-28 17:29:11 +09003576void ExynosCameraHWInterface2::m_streamBufferInit(SignalDrivenThread *self)
3577{
3578 uint32_t currentSignal = self->GetProcessingSignal();
3579 StreamThread * selfThread = ((StreamThread*)self);
3580 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003581 node_info_t *currentNode = selfStreamParms->node;
3582 substream_parameters_t *subParms;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003583 buffer_handle_t * buf = NULL;
3584 status_t res;
3585 void *virtAddr[3];
3586 int i, j;
3587 int index;
3588 nsecs_t timestamp;
3589
3590 if (!(selfThread->m_isBufferInit))
3591 {
3592 for ( i=0 ; i < selfStreamParms->numSvcBuffers; i++) {
3593 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
3594 if (res != NO_ERROR || buf == NULL) {
3595 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
3596 return;
3597 }
3598 ALOGV("DEBUG(%s): got buf(%x) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
3599 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
3600
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003601 index = selfThread->findBufferIndex(buf);
Sungjoong Kang86646da2012-08-28 17:29:11 +09003602 if (index == -1) {
3603 ALOGE("ERR(%s): could not find buffer index", __FUNCTION__);
3604 }
3605 else {
3606 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
3607 __FUNCTION__, index, selfStreamParms->svcBufStatus[index]);
3608 if (selfStreamParms->svcBufStatus[index]== REQUIRES_DQ_FROM_SVC)
3609 selfStreamParms->svcBufStatus[index] = ON_DRIVER;
3610 else if (selfStreamParms->svcBufStatus[index]== ON_SERVICE)
3611 selfStreamParms->svcBufStatus[index] = ON_HAL;
3612 else {
3613 ALOGV("DBG(%s): buffer status abnormal (%d) "
3614 , __FUNCTION__, selfStreamParms->svcBufStatus[index]);
3615 }
3616 selfStreamParms->numSvcBufsInHal++;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003617 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003618 selfStreamParms->bufIndex = 0;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003619 }
3620 selfThread->m_isBufferInit = true;
3621 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003622 for (int i = 0 ; i < NUM_MAX_SUBSTREAM ; i++) {
3623 if (selfThread->m_attachedSubStreams[i].streamId == -1)
3624 continue;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003625
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003626 subParms = &m_subStreams[selfThread->m_attachedSubStreams[i].streamId];
3627 if (subParms->type && subParms->needBufferInit) {
3628 ALOGV("(%s): [subStream] (id:%d) Buffer Initialization numsvcbuf(%d)",
3629 __FUNCTION__, selfThread->m_attachedSubStreams[i].streamId, subParms->numSvcBuffers);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003630 int checkingIndex = 0;
3631 bool found = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003632 for ( i = 0 ; i < subParms->numSvcBuffers; i++) {
3633 res = subParms->streamOps->dequeue_buffer(subParms->streamOps, &buf);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003634 if (res != NO_ERROR || buf == NULL) {
3635 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
3636 return;
3637 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003638 subParms->numSvcBufsInHal++;
3639 ALOGV("DEBUG(%s): [subStream] got buf(%x) bufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
3640 subParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003641
3642 if (m_grallocHal->lock(m_grallocHal, *buf,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003643 subParms->usage, 0, 0,
3644 subParms->width, subParms->height, virtAddr) != 0) {
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003645 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
3646 }
3647 else {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003648 ALOGV("DEBUG(%s): [subStream] locked img buf plane0(%x) plane1(%x) plane2(%x)",
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003649 __FUNCTION__, (unsigned int)virtAddr[0], (unsigned int)virtAddr[1], (unsigned int)virtAddr[2]);
3650 }
3651 found = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003652 for (checkingIndex = 0; checkingIndex < subParms->numSvcBuffers ; checkingIndex++) {
3653 if (subParms->svcBufHandle[checkingIndex] == *buf ) {
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003654 found = true;
3655 break;
3656 }
3657 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003658 ALOGV("DEBUG(%s): [subStream] found(%d) - index[%d]", __FUNCTION__, found, checkingIndex);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003659 if (!found) break;
3660
3661 index = checkingIndex;
3662
3663 if (index == -1) {
3664 ALOGV("ERR(%s): could not find buffer index", __FUNCTION__);
3665 }
3666 else {
3667 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003668 __FUNCTION__, index, subParms->svcBufStatus[index]);
3669 if (subParms->svcBufStatus[index]== ON_SERVICE)
3670 subParms->svcBufStatus[index] = ON_HAL;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003671 else {
3672 ALOGV("DBG(%s): buffer status abnormal (%d) "
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003673 , __FUNCTION__, subParms->svcBufStatus[index]);
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003674 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003675 if (*buf != subParms->svcBufHandle[index])
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003676 ALOGV("DBG(%s): different buf_handle index ", __FUNCTION__);
3677 else
3678 ALOGV("DEBUG(%s): same buf_handle index", __FUNCTION__);
3679 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003680 subParms->svcBufIndex = 0;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003681 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003682 if (subParms->type == SUBSTREAM_TYPE_JPEG) {
3683 m_resizeBuf.size.extS[0] = ALIGN(subParms->width, 16) * ALIGN(subParms->height, 16) * 2;
3684 m_resizeBuf.size.extS[1] = 0;
3685 m_resizeBuf.size.extS[2] = 0;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003686
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003687 if (allocCameraMemory(m_ionCameraClient, &m_resizeBuf, 1) == -1) {
3688 ALOGE("ERR(%s): Failed to allocate resize buf", __FUNCTION__);
3689 }
3690 }
3691 if (subParms->type == SUBSTREAM_TYPE_PRVCB) {
3692 m_getAlignedYUVSize(HAL_PIXEL_FORMAT_2_V4L2_PIX(subParms->internalFormat), subParms->width,
3693 subParms->height, &m_previewCbBuf);
3694
3695 if (allocCameraMemory(m_ionCameraClient, &m_previewCbBuf, subParms->internalPlanes) == -1) {
3696 ALOGE("ERR(%s): Failed to allocate prvcb buf", __FUNCTION__);
3697 }
3698 }
3699 subParms->needBufferInit= false;
3700 }
3701 }
Sungjoong Kang86646da2012-08-28 17:29:11 +09003702}
3703
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003704void ExynosCameraHWInterface2::m_streamThreadInitialize(SignalDrivenThread * self)
3705{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003706 StreamThread * selfThread = ((StreamThread*)self);
3707 ALOGV("DEBUG(%s): ", __FUNCTION__ );
3708 memset(&(selfThread->m_parameters), 0, sizeof(stream_parameters_t));
3709 selfThread->m_isBufferInit = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003710 for (int i = 0 ; i < NUM_MAX_SUBSTREAM ; i++) {
3711 selfThread->m_attachedSubStreams[i].streamId = -1;
3712 selfThread->m_attachedSubStreams[i].priority = 0;
3713 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003714 return;
3715}
3716
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003717int ExynosCameraHWInterface2::m_runSubStreamFunc(StreamThread *selfThread, ExynosBuffer *srcImageBuf,
3718 int stream_id, nsecs_t frameTimeStamp)
3719{
3720 substream_parameters_t *subParms = &m_subStreams[stream_id];
3721
3722 switch (stream_id) {
3723
3724 case STREAM_ID_JPEG:
3725 return m_jpegCreator(selfThread, srcImageBuf, frameTimeStamp);
3726
3727 case STREAM_ID_RECORD:
3728 return m_recordCreator(selfThread, srcImageBuf, frameTimeStamp);
3729
3730 case STREAM_ID_PRVCB:
3731 return m_prvcbCreator(selfThread, srcImageBuf, frameTimeStamp);
3732
3733 default:
3734 return 0;
3735 }
3736}
3737void ExynosCameraHWInterface2::m_streamFunc_direct(SignalDrivenThread *self)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003738{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003739 uint32_t currentSignal = self->GetProcessingSignal();
3740 StreamThread * selfThread = ((StreamThread*)self);
3741 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003742 node_info_t *currentNode = selfStreamParms->node;
3743 int i = 0;
3744 nsecs_t frameTimeStamp;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003745
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003746 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003747 CAM_LOGD("(%s): [%d] START SIGNAL_THREAD_RELEASE", __FUNCTION__, selfThread->m_index);
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003748
3749 if (selfThread->m_isBufferInit) {
Sungjoong Kanga8be0012012-09-19 00:13:43 -07003750 if (!(currentNode->fd == m_camera_info.capture.fd && m_camera_info.capture.status == false)) {
3751 ALOGV("(%s): [%d] calling streamoff (fd:%d)", __FUNCTION__,
3752 selfThread->m_index, currentNode->fd);
3753 if (cam_int_streamoff(currentNode) < 0 ) {
3754 ALOGE("ERR(%s): stream off fail", __FUNCTION__);
3755 }
3756 ALOGV("(%s): [%d] streamoff done and calling reqbuf 0 (fd:%d)", __FUNCTION__,
3757 selfThread->m_index, currentNode->fd);
3758 currentNode->buffers = 0;
3759 cam_int_reqbufs(currentNode);
3760 ALOGV("(%s): [%d] reqbuf 0 DONE (fd:%d)", __FUNCTION__,
3761 selfThread->m_index, currentNode->fd);
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003762 }
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003763 }
3764#ifdef ENABLE_FRAME_SYNC
3765 // free metabuffers
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003766 for (i = 0; i < NUM_MAX_CAMERA_BUFFERS; i++)
3767 if (selfStreamParms->metaBuffers[i].fd.extFd[0] != 0) {
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003768 freeCameraMemory(&(selfStreamParms->metaBuffers[i]), 1);
3769 selfStreamParms->metaBuffers[i].fd.extFd[0] = 0;
3770 selfStreamParms->metaBuffers[i].size.extS[0] = 0;
3771 }
3772#endif
3773 selfThread->m_isBufferInit = false;
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003774 selfThread->m_releasing = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003775 selfThread->m_activated = false;
3776 ALOGV("(%s): [%d] END SIGNAL_THREAD_RELEASE", __FUNCTION__, selfThread->m_index);
3777 return;
3778 }
3779 if (currentSignal & SIGNAL_STREAM_REPROCESSING_START) {
3780 status_t res;
3781 buffer_handle_t * buf = NULL;
3782 bool found = false;
3783 ALOGV("(%s): streamthread[%d] START SIGNAL_STREAM_REPROCESSING_START",
3784 __FUNCTION__, selfThread->m_index);
3785 res = m_reprocessOps->acquire_buffer(m_reprocessOps, &buf);
3786 if (res != NO_ERROR || buf == NULL) {
3787 ALOGE("ERR(%s): [reprocess] unable to acquire_buffer : %d",__FUNCTION__ , res);
3788 return;
3789 }
3790 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
3791 int checkingIndex = 0;
3792 for (checkingIndex = 0; checkingIndex < selfStreamParms->numSvcBuffers ; checkingIndex++) {
3793 if (priv_handle->fd == selfStreamParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
3794 found = true;
3795 break;
3796 }
3797 }
3798 ALOGV("DEBUG(%s): dequeued buf %x => found(%d) index(%d) ",
3799 __FUNCTION__, (unsigned int)buf, found, checkingIndex);
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003800
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003801 if (!found) return;
3802
3803 for (int i = 0 ; i < NUM_MAX_SUBSTREAM ; i++) {
3804 if (selfThread->m_attachedSubStreams[i].streamId == -1)
3805 continue;
3806
3807#ifdef ENABLE_FRAME_SYNC
Sungjoong Kanga8be0012012-09-19 00:13:43 -07003808 frameTimeStamp = m_requestManager->GetTimestampByFrameCnt(m_reprocessingFrameCnt);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003809 m_requestManager->NotifyStreamOutput(m_reprocessingFrameCnt);
3810#else
3811 frameTimeStamp = m_requestManager->GetTimestamp(m_requestManager->GetFrameIndex());
3812#endif
3813 if (m_currentReprocessOutStreams & (1<<selfThread->m_attachedSubStreams[i].streamId))
3814 m_runSubStreamFunc(selfThread, &(selfStreamParms->svcBuffers[checkingIndex]),
3815 selfThread->m_attachedSubStreams[i].streamId, frameTimeStamp);
3816 }
3817
3818 res = m_reprocessOps->release_buffer(m_reprocessOps, buf);
3819 if (res != NO_ERROR) {
3820 ALOGE("ERR(%s): [reprocess] unable to release_buffer : %d",__FUNCTION__ , res);
3821 return;
3822 }
3823 ALOGV("(%s): streamthread[%d] END SIGNAL_STREAM_REPROCESSING_START",
3824 __FUNCTION__,selfThread->m_index);
Sungjoong Kangb55ed662012-08-31 21:31:34 -07003825
3826 return;
3827 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003828 if (currentSignal & SIGNAL_STREAM_DATA_COMING) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003829 buffer_handle_t * buf = NULL;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003830 status_t res = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003831 int i, j;
3832 int index;
Sungjoong Kangad378612012-08-17 12:34:33 -07003833 nsecs_t timestamp;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003834#ifdef ENABLE_FRAME_SYNC
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003835 camera2_stream *frame;
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003836 uint8_t currentOutputStreams;
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003837 bool directOutputEnabled = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003838#endif
hyeonmyeong Choic0b6e172012-09-05 00:51:31 -07003839 int numOfUndqbuf = 0;
hyeonmyeong Choic0b6e172012-09-05 00:51:31 -07003840
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003841 ALOGV("(%s): streamthread[%d] START SIGNAL_STREAM_DATA_COMING", __FUNCTION__,selfThread->m_index);
Sungjoong Kangad378612012-08-17 12:34:33 -07003842
Sungjoong Kang86646da2012-08-28 17:29:11 +09003843 m_streamBufferInit(self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003844
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003845 do {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003846 ALOGV("DEBUG(%s): streamthread[%d] type(%d) DQBUF START ",__FUNCTION__,
3847 selfThread->m_index, selfThread->streamType);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003848
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003849#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003850 selfStreamParms->bufIndex = cam_int_dqbuf(currentNode, selfStreamParms->planes + selfStreamParms->metaPlanes);
3851 frame = (struct camera2_stream *)(selfStreamParms->metaBuffers[selfStreamParms->bufIndex].virt.extP[0]);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003852 frameTimeStamp = m_requestManager->GetTimestampByFrameCnt(frame->rcount);
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003853 currentOutputStreams = m_requestManager->GetOutputStreamByFrameCnt(frame->rcount);
3854 ALOGV("frame count streamthread[%d] : %d, outputStream(%x)", selfThread->m_index, frame->rcount, currentOutputStreams);
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003855 if (((currentOutputStreams & STREAM_MASK_PREVIEW) && selfThread->m_index == 0)||
3856 ((currentOutputStreams & STREAM_MASK_ZSL) && selfThread->m_index == 1)) {
3857 directOutputEnabled = true;
3858 }
3859 if (!directOutputEnabled) {
3860 if (!m_nightCaptureFrameCnt)
3861 m_requestManager->NotifyStreamOutput(frame->rcount);
3862 }
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003863#else
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003864 selfStreamParms->bufIndex = cam_int_dqbuf(currentNode);
3865 frameTimeStamp = m_requestManager->GetTimestamp(m_requestManager->GetFrameIndex())
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003866#endif
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003867 ALOGV("DEBUG(%s): streamthread[%d] DQBUF done index(%d) sigcnt(%d)",__FUNCTION__,
3868 selfThread->m_index, selfStreamParms->bufIndex, m_scpOutputSignalCnt);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003869
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003870 if (selfStreamParms->svcBufStatus[selfStreamParms->bufIndex] != ON_DRIVER)
Sungjoong Kang86646da2012-08-28 17:29:11 +09003871 ALOGV("DBG(%s): DQed buffer status abnormal (%d) ",
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003872 __FUNCTION__, selfStreamParms->svcBufStatus[selfStreamParms->bufIndex]);
3873 selfStreamParms->svcBufStatus[selfStreamParms->bufIndex] = ON_HAL;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003874
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003875 for (int i = 0 ; i < NUM_MAX_SUBSTREAM ; i++) {
3876 if (selfThread->m_attachedSubStreams[i].streamId == -1)
3877 continue;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003878#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003879 if (currentOutputStreams & (1<<selfThread->m_attachedSubStreams[i].streamId)) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003880 m_runSubStreamFunc(selfThread, &(selfStreamParms->svcBuffers[selfStreamParms->bufIndex]),
3881 selfThread->m_attachedSubStreams[i].streamId, frameTimeStamp);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003882 }
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003883#else
3884 if (m_currentOutputStreams & (1<<selfThread->m_attachedSubStreams[i].streamId)) {
3885 m_runSubStreamFunc(selfThread, &(selfStreamParms->svcBuffers[selfStreamParms->bufIndex]),
3886 selfThread->m_attachedSubStreams[i].streamId, frameTimeStamp);
3887 }
3888#endif
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003889 }
hyeonmyeong Choic0b6e172012-09-05 00:51:31 -07003890
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003891 if (m_requestManager->GetSkipCnt() <= 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003892#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003893 if ((currentOutputStreams & STREAM_MASK_PREVIEW) && selfThread->m_index == 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003894 ALOGV("** Display Preview(frameCnt:%d)", frame->rcount);
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003895 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
3896 frameTimeStamp,
3897 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
3898 }
3899 else if ((currentOutputStreams & STREAM_MASK_ZSL) && selfThread->m_index == 1) {
3900 ALOGV("** SCC output (frameCnt:%d), last(%d)", frame->rcount);
3901 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
3902 frameTimeStamp,
3903 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
3904 }
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003905 else {
3906 res = selfStreamParms->streamOps->cancel_buffer(selfStreamParms->streamOps,
3907 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
3908 ALOGV("DEBUG(%s): streamthread[%d] cancel_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
3909 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003910#else
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003911 if ((m_currentOutputStreams & STREAM_MASK_PREVIEW) && selfThread->m_index == 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003912 ALOGV("** Display Preview(frameCnt:%d)", m_requestManager->GetFrameIndex());
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003913 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
3914 frameTimeStamp,
3915 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003916 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003917 else if ((m_currentOutputStreams & STREAM_MASK_ZSL) && selfThread->m_index == 1) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003918 ALOGV("** SCC output (frameCnt:%d), last(%d)", m_requestManager->GetFrameIndex());
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003919 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
3920 frameTimeStamp,
3921 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07003922 }
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003923#endif
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003924 ALOGV("DEBUG(%s): streamthread[%d] enqueue_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
Sungjoong Kang86646da2012-08-28 17:29:11 +09003925 }
3926 else {
3927 res = selfStreamParms->streamOps->cancel_buffer(selfStreamParms->streamOps,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003928 &(selfStreamParms->svcBufHandle[selfStreamParms->bufIndex]));
3929 ALOGV("DEBUG(%s): streamthread[%d] cancel_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
Sungjoong Kang86646da2012-08-28 17:29:11 +09003930 }
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003931#ifdef ENABLE_FRAME_SYNC
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003932 if (directOutputEnabled) {
3933 if (!m_nightCaptureFrameCnt)
3934 m_requestManager->NotifyStreamOutput(frame->rcount);
3935 }
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07003936#endif
Sungjoong Kang86646da2012-08-28 17:29:11 +09003937 if (res == 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003938 selfStreamParms->svcBufStatus[selfStreamParms->bufIndex] = ON_SERVICE;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003939 selfStreamParms->numSvcBufsInHal--;
3940 }
3941 else {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003942 selfStreamParms->svcBufStatus[selfStreamParms->bufIndex] = ON_HAL;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003943 }
3944
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003945 }
Sungjoong Kangce8e8302012-09-13 16:29:41 -07003946 while(0);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003947
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003948 while ((selfStreamParms->numSvcBufsInHal - (selfStreamParms->numSvcBuffers - NUM_SCP_BUFFERS))
3949 < selfStreamParms->minUndequedBuffer) {
Sungjoong Kang86646da2012-08-28 17:29:11 +09003950 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
3951 if (res != NO_ERROR || buf == NULL) {
Sungjoong Kanga85ec382012-09-23 16:49:12 -07003952 ALOGV("DEBUG(%s): streamthread[%d] dequeue_buffer fail res(%d) numInHal(%d)",__FUNCTION__ , selfThread->m_index, res, selfStreamParms->numSvcBufsInHal);
Sungjoong Kang86646da2012-08-28 17:29:11 +09003953 break;
3954 }
3955 selfStreamParms->numSvcBufsInHal++;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003956 ALOGV("DEBUG(%s): streamthread[%d] got buf(%x) numInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__,
Sungjoong Kang86646da2012-08-28 17:29:11 +09003957 selfThread->m_index, (uint32_t)(*buf), selfStreamParms->numSvcBufsInHal,
3958 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
3959 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
3960
3961 bool found = false;
3962 int checkingIndex = 0;
3963 for (checkingIndex = 0; checkingIndex < selfStreamParms->numSvcBuffers ; checkingIndex++) {
3964 if (priv_handle->fd == selfStreamParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
3965 found = true;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003966 break;
3967 }
Sungjoong Kang86646da2012-08-28 17:29:11 +09003968 }
Sungjoong Kang86646da2012-08-28 17:29:11 +09003969 if (!found) break;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003970 selfStreamParms->bufIndex = checkingIndex;
3971 if (selfStreamParms->bufIndex < selfStreamParms->numHwBuffers) {
Sungjoong Kang86646da2012-08-28 17:29:11 +09003972 uint32_t plane_index = 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003973 ExynosBuffer* currentBuf = &(selfStreamParms->svcBuffers[selfStreamParms->bufIndex]);
Sungjoong Kang86646da2012-08-28 17:29:11 +09003974 struct v4l2_buffer v4l2_buf;
3975 struct v4l2_plane planes[VIDEO_MAX_PLANES];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003976
Sungjoong Kang86646da2012-08-28 17:29:11 +09003977 v4l2_buf.m.planes = planes;
3978 v4l2_buf.type = currentNode->type;
3979 v4l2_buf.memory = currentNode->memory;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003980 v4l2_buf.index = selfStreamParms->bufIndex;
Sungjoong Kang86646da2012-08-28 17:29:11 +09003981 v4l2_buf.length = currentNode->planes;
3982
3983 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
3984 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
3985 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
3986 for (plane_index=0 ; plane_index < v4l2_buf.length ; plane_index++) {
3987 v4l2_buf.m.planes[plane_index].length = currentBuf->size.extS[plane_index];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003988 }
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003989#ifdef ENABLE_FRAME_SYNC
3990 /* add plane for metadata*/
3991 v4l2_buf.length += selfStreamParms->metaPlanes;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003992 v4l2_buf.m.planes[v4l2_buf.length-1].m.fd = selfStreamParms->metaBuffers[selfStreamParms->bufIndex].fd.extFd[0];
3993 v4l2_buf.m.planes[v4l2_buf.length-1].length = selfStreamParms->metaBuffers[selfStreamParms->bufIndex].size.extS[0];
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09003994#endif
Sungjoong Kang86646da2012-08-28 17:29:11 +09003995 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07003996 ALOGE("ERR(%s): streamthread[%d] exynos_v4l2_qbuf() fail",
Sungjoong Kang86646da2012-08-28 17:29:11 +09003997 __FUNCTION__, selfThread->m_index);
3998 return;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003999 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004000 selfStreamParms->svcBufStatus[selfStreamParms->bufIndex] = ON_DRIVER;
4001 ALOGV("DEBUG(%s): streamthread[%d] QBUF done index(%d)",
4002 __FUNCTION__, selfThread->m_index, selfStreamParms->bufIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004003 }
4004 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07004005
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004006 ALOGV("(%s): streamthread[%d] END SIGNAL_STREAM_DATA_COMING", __FUNCTION__,selfThread->m_index);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07004007 }
Sungjoong Kang86646da2012-08-28 17:29:11 +09004008 return;
4009}
4010
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004011void ExynosCameraHWInterface2::m_streamFunc_indirect(SignalDrivenThread *self)
Sungjoong Kang86646da2012-08-28 17:29:11 +09004012{
4013 uint32_t currentSignal = self->GetProcessingSignal();
4014 StreamThread * selfThread = ((StreamThread*)self);
4015 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004016 node_info_t *currentNode = selfStreamParms->node;
Sungjoong Kang86646da2012-08-28 17:29:11 +09004017
Sungjoong Kang86646da2012-08-28 17:29:11 +09004018
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004019 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004020 CAM_LOGV("(%s): [%d] START SIGNAL_THREAD_RELEASE", __FUNCTION__, selfThread->m_index);
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004021
4022 if (selfThread->m_isBufferInit) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004023 if (currentNode->fd == m_camera_info.capture.fd) {
4024 if (m_camera_info.capture.status == true) {
4025 ALOGV("DEBUG(%s): calling streamthread[%d] streamoff (fd:%d)", __FUNCTION__,
4026 selfThread->m_index, currentNode->fd);
4027 if (cam_int_streamoff(currentNode) < 0 ){
4028 ALOGE("ERR(%s): stream off fail", __FUNCTION__);
4029 } else {
4030 m_camera_info.capture.status = false;
4031 }
4032 }
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004033 } else {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004034 ALOGV("DEBUG(%s): calling streamthread[%d] streamoff (fd:%d)", __FUNCTION__,
4035 selfThread->m_index, currentNode->fd);
4036 if (cam_int_streamoff(currentNode) < 0 ){
4037 ALOGE("ERR(%s): stream off fail", __FUNCTION__);
4038 }
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004039 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004040 ALOGV("DEBUG(%s): calling streamthread[%d] streamoff done", __FUNCTION__, selfThread->m_index);
4041 ALOGV("DEBUG(%s): calling streamthread[%d] reqbuf 0 (fd:%d)", __FUNCTION__,
4042 selfThread->m_index, currentNode->fd);
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004043 currentNode->buffers = 0;
4044 cam_int_reqbufs(currentNode);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004045 ALOGV("DEBUG(%s): calling streamthread[%d] reqbuf 0 DONE(fd:%d)", __FUNCTION__,
4046 selfThread->m_index, currentNode->fd);
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004047 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004048
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004049 selfThread->m_isBufferInit = false;
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004050 selfThread->m_releasing = false;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004051 selfThread->m_activated = false;
4052 ALOGV("(%s): [%d] END SIGNAL_THREAD_RELEASE", __FUNCTION__, selfThread->m_index);
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004053 return;
4054 }
4055
Sungjoong Kang86646da2012-08-28 17:29:11 +09004056 if (currentSignal & SIGNAL_STREAM_DATA_COMING) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004057#ifdef ENABLE_FRAME_SYNC
Jiyoung Shin2adfa422012-09-10 23:14:54 +09004058 camera2_stream *frame;
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07004059 uint8_t currentOutputStreams;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004060#endif
4061 nsecs_t frameTimeStamp;
Sungjoong Kang86646da2012-08-28 17:29:11 +09004062
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004063 ALOGV("DEBUG(%s): streamthread[%d] processing SIGNAL_STREAM_DATA_COMING",
Sungjoong Kang86646da2012-08-28 17:29:11 +09004064 __FUNCTION__,selfThread->m_index);
4065
4066 m_streamBufferInit(self);
4067
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07004068 ALOGV("DEBUG(%s): streamthread[%d] DQBUF START", __FUNCTION__, selfThread->m_index);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004069 selfStreamParms->bufIndex = cam_int_dqbuf(currentNode);
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07004070 ALOGV("DEBUG(%s): streamthread[%d] DQBUF done index(%d)",__FUNCTION__,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004071 selfThread->m_index, selfStreamParms->bufIndex);
Jiyoung Shin2adfa422012-09-10 23:14:54 +09004072
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09004073#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004074 frame = (struct camera2_stream *)(currentNode->buffer[selfStreamParms->bufIndex].virt.extP[selfStreamParms->planes -1]);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004075 frameTimeStamp = m_requestManager->GetTimestampByFrameCnt(frame->rcount);
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07004076 currentOutputStreams = m_requestManager->GetOutputStreamByFrameCnt(frame->rcount);
4077 ALOGV("frame count(SCC) : %d outputStream(%x)", frame->rcount, currentOutputStreams);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004078#else
4079 frameTimeStamp = m_requestManager->GetTimestamp(m_requestManager->GetFrameIndex());
Sungjoong Kangfeb7df42012-08-28 23:35:43 +09004080#endif
Sungjoong Kang86646da2012-08-28 17:29:11 +09004081
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004082 for (int i = 0 ; i < NUM_MAX_SUBSTREAM ; i++) {
4083 if (selfThread->m_attachedSubStreams[i].streamId == -1)
4084 continue;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004085#ifdef ENABLE_FRAME_SYNC
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07004086 if (currentOutputStreams & (1<<selfThread->m_attachedSubStreams[i].streamId)) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004087 m_requestManager->NotifyStreamOutput(frame->rcount);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004088 m_runSubStreamFunc(selfThread, &(currentNode->buffer[selfStreamParms->bufIndex]),
4089 selfThread->m_attachedSubStreams[i].streamId, frameTimeStamp);
Sungjoong Kang86646da2012-08-28 17:29:11 +09004090 }
Sungjoong Kang2f4d1752012-09-17 16:50:07 -07004091#else
4092 if (m_currentOutputStreams & (1<<selfThread->m_attachedSubStreams[i].streamId)) {
4093 m_runSubStreamFunc(selfThread, &(currentNode->buffer[selfStreamParms->bufIndex]),
4094 selfThread->m_attachedSubStreams[i].streamId, frameTimeStamp);
4095 }
4096#endif
Sungjoong Kang86646da2012-08-28 17:29:11 +09004097 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004098 cam_int_qbuf(currentNode, selfStreamParms->bufIndex);
4099 ALOGV("DEBUG(%s): streamthread[%d] QBUF DONE", __FUNCTION__, selfThread->m_index);
Sungjoong Kang86646da2012-08-28 17:29:11 +09004100
Sungjoong Kang86646da2012-08-28 17:29:11 +09004101
Sungjoong Kang86646da2012-08-28 17:29:11 +09004102
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004103 ALOGV("DEBUG(%s): streamthread[%d] processing SIGNAL_STREAM_DATA_COMING DONE",
4104 __FUNCTION__, selfThread->m_index);
Sungjoong Kang86646da2012-08-28 17:29:11 +09004105 }
4106
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004107
Sungjoong Kang86646da2012-08-28 17:29:11 +09004108 return;
4109}
4110
Sungjoong Kang86646da2012-08-28 17:29:11 +09004111void ExynosCameraHWInterface2::m_streamThreadFunc(SignalDrivenThread * self)
4112{
4113 uint32_t currentSignal = self->GetProcessingSignal();
4114 StreamThread * selfThread = ((StreamThread*)self);
4115 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004116 node_info_t *currentNode = selfStreamParms->node;
Sungjoong Kang86646da2012-08-28 17:29:11 +09004117
4118 ALOGV("DEBUG(%s): m_streamThreadFunc[%d] (%x)", __FUNCTION__, selfThread->m_index, currentSignal);
4119
Sungjoong Kang86646da2012-08-28 17:29:11 +09004120 // Do something in Child thread handler
4121 // Should change function to class that inherited StreamThread class to support dynamic stream allocation
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004122 if (selfThread->streamType == STREAM_TYPE_DIRECT) {
4123 m_streamFunc_direct(self);
4124 } else if (selfThread->streamType == STREAM_TYPE_INDIRECT) {
4125 m_streamFunc_indirect(self);
Sungjoong Kang86646da2012-08-28 17:29:11 +09004126 }
4127
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07004128 return;
4129}
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004130int ExynosCameraHWInterface2::m_jpegCreator(StreamThread *selfThread, ExynosBuffer *srcImageBuf, nsecs_t frameTimeStamp)
4131{
4132 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
4133 substream_parameters_t *subParms = &m_subStreams[STREAM_ID_JPEG];
4134 status_t res;
4135 ExynosRect jpegRect;
4136 bool found = false;
Sungjoong Kangde48e362012-09-23 18:57:37 -07004137 int srcW, srcH, srcCropX, srcCropY;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004138 int pictureW, pictureH, pictureFramesize = 0;
4139 int pictureFormat;
4140 int cropX, cropY, cropW, cropH = 0;
4141 ExynosBuffer resizeBufInfo;
4142 ExynosRect m_jpegPictureRect;
4143 buffer_handle_t * buf = NULL;
Sungjoong Kangc06b3292012-09-28 17:14:57 -07004144 camera2_jpeg_blob * jpegBlob = NULL;
4145 int jpegBufSize = 0;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004146
4147 ALOGV("DEBUG(%s): index(%d)",__FUNCTION__, subParms->svcBufIndex);
4148 for (int i = 0 ; subParms->numSvcBuffers ; i++) {
4149 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_HAL) {
4150 found = true;
4151 break;
4152 }
4153 subParms->svcBufIndex++;
4154 if (subParms->svcBufIndex >= subParms->numSvcBuffers)
4155 subParms->svcBufIndex = 0;
4156 }
4157 if (!found) {
4158 ALOGE("(%s): cannot find free svc buffer", __FUNCTION__);
4159 subParms->svcBufIndex++;
4160 return 1;
4161 }
4162
Sungjoong Kangde48e362012-09-23 18:57:37 -07004163 m_getRatioSize(selfStreamParms->width, selfStreamParms->height,
4164 m_streamThreads[0]->m_parameters.width, m_streamThreads[0]->m_parameters.height,
4165 &srcCropX, &srcCropY,
4166 &srcW, &srcH,
4167 0);
4168
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004169 m_jpegPictureRect.w = subParms->width;
4170 m_jpegPictureRect.h = subParms->height;
4171
4172 ALOGV("DEBUG(%s):w = %d, h = %d, w = %d, h = %d",
4173 __FUNCTION__, selfStreamParms->width, selfStreamParms->height,
4174 m_jpegPictureRect.w, m_jpegPictureRect.h);
4175
Sungjoong Kangde48e362012-09-23 18:57:37 -07004176 m_getRatioSize(srcW, srcH,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004177 m_jpegPictureRect.w, m_jpegPictureRect.h,
4178 &cropX, &cropY,
4179 &pictureW, &pictureH,
4180 0);
4181 pictureFormat = V4L2_PIX_FMT_YUYV;
4182 pictureFramesize = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat), pictureW, pictureH);
4183
4184 if (m_exynosPictureCSC) {
4185 float zoom_w = 0, zoom_h = 0;
4186 if (m_zoomRatio == 0)
4187 m_zoomRatio = 1;
4188
4189 if (m_jpegPictureRect.w >= m_jpegPictureRect.h) {
4190 zoom_w = pictureW / m_zoomRatio;
4191 zoom_h = zoom_w * m_jpegPictureRect.h / m_jpegPictureRect.w;
4192 } else {
4193 zoom_h = pictureH / m_zoomRatio;
4194 zoom_w = zoom_h * m_jpegPictureRect.w / m_jpegPictureRect.h;
4195 }
Sungjoong Kangde48e362012-09-23 18:57:37 -07004196 cropX = (srcW - zoom_w) / 2;
4197 cropY = (srcH - zoom_h) / 2;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004198 cropW = zoom_w;
4199 cropH = zoom_h;
4200
4201 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
4202 __FUNCTION__, cropX, cropY, cropW, cropH);
4203
4204 csc_set_src_format(m_exynosPictureCSC,
Sungjoong Kangde48e362012-09-23 18:57:37 -07004205 ALIGN(srcW, 16), ALIGN(srcH, 16),
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004206 cropX, cropY, cropW, cropH,
4207 V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat),
4208 0);
4209
4210 csc_set_dst_format(m_exynosPictureCSC,
4211 m_jpegPictureRect.w, m_jpegPictureRect.h,
4212 0, 0, m_jpegPictureRect.w, m_jpegPictureRect.h,
4213 V4L2_PIX_2_HAL_PIXEL_FORMAT(V4L2_PIX_FMT_NV16),
4214 0);
4215 for (int i = 0 ; i < 3 ; i++)
4216 ALOGV("DEBUG(%s): m_pictureBuf.fd.extFd[%d]=%d ",
4217 __FUNCTION__, i, srcImageBuf->fd.extFd[i]);
4218 csc_set_src_buffer(m_exynosPictureCSC,
4219 (void **)&srcImageBuf->fd.fd);
4220
4221 csc_set_dst_buffer(m_exynosPictureCSC,
4222 (void **)&m_resizeBuf.fd.fd);
4223 for (int i = 0 ; i < 3 ; i++)
4224 ALOGV("DEBUG(%s): m_resizeBuf.virt.extP[%d]=%d m_resizeBuf.size.extS[%d]=%d",
4225 __FUNCTION__, i, m_resizeBuf.fd.extFd[i], i, m_resizeBuf.size.extS[i]);
4226
4227 if (csc_convert(m_exynosPictureCSC) != 0)
4228 ALOGE("ERR(%s): csc_convert() fail", __FUNCTION__);
4229
4230 }
4231 else {
4232 ALOGE("ERR(%s): m_exynosPictureCSC == NULL", __FUNCTION__);
4233 }
4234
4235 resizeBufInfo = m_resizeBuf;
4236
4237 m_getAlignedYUVSize(V4L2_PIX_FMT_NV16, m_jpegPictureRect.w, m_jpegPictureRect.h, &m_resizeBuf);
4238
4239 for (int i = 1; i < 3; i++) {
4240 if (m_resizeBuf.size.extS[i] != 0)
4241 m_resizeBuf.fd.extFd[i] = m_resizeBuf.fd.extFd[i-1] + m_resizeBuf.size.extS[i-1];
4242
4243 ALOGV("(%s): m_resizeBuf.size.extS[%d] = %d", __FUNCTION__, i, m_resizeBuf.size.extS[i]);
4244 }
4245
4246 jpegRect.w = m_jpegPictureRect.w;
4247 jpegRect.h = m_jpegPictureRect.h;
4248 jpegRect.colorFormat = V4L2_PIX_FMT_NV16;
4249
4250 for (int j = 0 ; j < 3 ; j++)
4251 ALOGV("DEBUG(%s): dest buf node fd.extFd[%d]=%d size=%d virt=%x ",
4252 __FUNCTION__, j, subParms->svcBuffers[subParms->svcBufIndex].fd.extFd[j],
4253 (unsigned int)subParms->svcBuffers[subParms->svcBufIndex].size.extS[j],
4254 (unsigned int)subParms->svcBuffers[subParms->svcBufIndex].virt.extP[j]);
4255
Sungjoong Kangc06b3292012-09-28 17:14:57 -07004256 jpegBufSize = subParms->svcBuffers[subParms->svcBufIndex].size.extS[0];
4257 if (yuv2Jpeg(&m_resizeBuf, &subParms->svcBuffers[subParms->svcBufIndex], &jpegRect) == false) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004258 ALOGE("ERR(%s):yuv2Jpeg() fail", __FUNCTION__);
Sungjoong Kangc06b3292012-09-28 17:14:57 -07004259 } else {
4260 m_resizeBuf = resizeBufInfo;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004261
Sungjoong Kangc06b3292012-09-28 17:14:57 -07004262 int jpegSize = subParms->svcBuffers[subParms->svcBufIndex].size.s;
4263 ALOGD("(%s): (%d x %d) jpegbuf size(%d) encoded size(%d)", __FUNCTION__,
4264 m_jpegPictureRect.w, m_jpegPictureRect.h, jpegBufSize, jpegSize);
4265 char * jpegBuffer = (char*)(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0]);
4266 jpegBlob = (camera2_jpeg_blob*)(&jpegBuffer[jpegBufSize - sizeof(camera2_jpeg_blob)]);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004267
Sungjoong Kangc06b3292012-09-28 17:14:57 -07004268 if (jpegBuffer[jpegSize-1] == 0)
4269 jpegSize--;
4270 jpegBlob->jpeg_size = jpegSize;
4271 jpegBlob->jpeg_blob_id = CAMERA2_JPEG_BLOB_ID;
4272 }
Sungjoong Kangcf593312012-10-01 23:47:22 -07004273 subParms->svcBuffers[subParms->svcBufIndex].size.extS[0] = jpegBufSize;
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004274 res = subParms->streamOps->enqueue_buffer(subParms->streamOps, frameTimeStamp, &(subParms->svcBufHandle[subParms->svcBufIndex]));
4275
4276 ALOGV("DEBUG(%s): streamthread[%d] enqueue_buffer index(%d) to svc done res(%d)",
4277 __FUNCTION__, selfThread->m_index, subParms->svcBufIndex, res);
4278 if (res == 0) {
4279 subParms->svcBufStatus[subParms->svcBufIndex] = ON_SERVICE;
4280 subParms->numSvcBufsInHal--;
4281 }
4282 else {
4283 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4284 }
4285
4286 while (subParms->numSvcBufsInHal <= subParms->minUndequedBuffer)
4287 {
4288 bool found = false;
4289 int checkingIndex = 0;
4290
4291 ALOGV("DEBUG(%s): jpeg currentBuf#(%d)", __FUNCTION__ , subParms->numSvcBufsInHal);
4292
4293 res = subParms->streamOps->dequeue_buffer(subParms->streamOps, &buf);
4294 if (res != NO_ERROR || buf == NULL) {
4295 ALOGV("DEBUG(%s): jpeg stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
4296 break;
4297 }
4298 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
4299 subParms->numSvcBufsInHal ++;
4300 ALOGV("DEBUG(%s): jpeg got buf(%x) numBufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
4301 subParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
4302
4303
4304 for (checkingIndex = 0; checkingIndex < subParms->numSvcBuffers ; checkingIndex++) {
4305 if (priv_handle->fd == subParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
4306 found = true;
4307 break;
4308 }
4309 }
4310 ALOGV("DEBUG(%s): jpeg dequeueed_buffer found index(%d)", __FUNCTION__, found);
4311
4312 if (!found) {
4313 break;
4314 }
4315
4316 subParms->svcBufIndex = checkingIndex;
4317 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_SERVICE) {
4318 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4319 }
4320 else {
4321 ALOGV("DEBUG(%s): jpeg bufstatus abnormal [%d] status = %d", __FUNCTION__,
4322 subParms->svcBufIndex, subParms->svcBufStatus[subParms->svcBufIndex]);
4323 }
4324 }
4325 return 0;
4326}
4327
4328int ExynosCameraHWInterface2::m_recordCreator(StreamThread *selfThread, ExynosBuffer *srcImageBuf, nsecs_t frameTimeStamp)
4329{
4330 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
4331 substream_parameters_t *subParms = &m_subStreams[STREAM_ID_RECORD];
4332 status_t res;
4333 ExynosRect jpegRect;
4334 bool found = false;
4335 int cropX, cropY, cropW, cropH = 0;
4336 buffer_handle_t * buf = NULL;
4337
4338 ALOGV("DEBUG(%s): index(%d)",__FUNCTION__, subParms->svcBufIndex);
4339 for (int i = 0 ; subParms->numSvcBuffers ; i++) {
4340 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_HAL) {
4341 found = true;
4342 break;
4343 }
4344 subParms->svcBufIndex++;
4345 if (subParms->svcBufIndex >= subParms->numSvcBuffers)
4346 subParms->svcBufIndex = 0;
4347 }
4348 if (!found) {
4349 ALOGE("(%s): cannot find free svc buffer", __FUNCTION__);
4350 subParms->svcBufIndex++;
4351 return 1;
4352 }
4353
4354 if (m_exynosVideoCSC) {
4355 int videoW = subParms->width, videoH = subParms->height;
4356 int cropX, cropY, cropW, cropH = 0;
4357 int previewW = selfStreamParms->width, previewH = selfStreamParms->height;
4358 m_getRatioSize(previewW, previewH,
4359 videoW, videoH,
4360 &cropX, &cropY,
4361 &cropW, &cropH,
4362 0);
4363
4364 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
4365 __FUNCTION__, cropX, cropY, cropW, cropH);
4366
4367 csc_set_src_format(m_exynosVideoCSC,
Sungjoong Kang4a3f1822012-09-28 20:07:32 -07004368 ALIGN(previewW, 32), previewH,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004369 cropX, cropY, cropW, cropH,
4370 selfStreamParms->format,
4371 0);
4372
4373 csc_set_dst_format(m_exynosVideoCSC,
4374 videoW, videoH,
4375 0, 0, videoW, videoH,
4376 subParms->format,
4377 1);
4378
4379 csc_set_src_buffer(m_exynosVideoCSC,
4380 (void **)&srcImageBuf->fd.fd);
4381
4382 csc_set_dst_buffer(m_exynosVideoCSC,
4383 (void **)(&(subParms->svcBuffers[subParms->svcBufIndex].fd.fd)));
4384
4385 if (csc_convert(m_exynosVideoCSC) != 0) {
4386 ALOGE("ERR(%s):csc_convert() fail", __FUNCTION__);
4387 }
4388 else {
4389 ALOGV("(%s):csc_convert() SUCCESS", __FUNCTION__);
4390 }
4391 }
4392 else {
4393 ALOGE("ERR(%s):m_exynosVideoCSC == NULL", __FUNCTION__);
4394 }
4395
4396 res = subParms->streamOps->enqueue_buffer(subParms->streamOps, frameTimeStamp, &(subParms->svcBufHandle[subParms->svcBufIndex]));
4397
4398 ALOGV("DEBUG(%s): streamthread[%d] enqueue_buffer index(%d) to svc done res(%d)",
4399 __FUNCTION__, selfThread->m_index, subParms->svcBufIndex, res);
4400 if (res == 0) {
4401 subParms->svcBufStatus[subParms->svcBufIndex] = ON_SERVICE;
4402 subParms->numSvcBufsInHal--;
4403 }
4404 else {
4405 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4406 }
4407
4408 while (subParms->numSvcBufsInHal <= subParms->minUndequedBuffer)
4409 {
4410 bool found = false;
4411 int checkingIndex = 0;
4412
4413 ALOGV("DEBUG(%s): record currentBuf#(%d)", __FUNCTION__ , subParms->numSvcBufsInHal);
4414
4415 res = subParms->streamOps->dequeue_buffer(subParms->streamOps, &buf);
4416 if (res != NO_ERROR || buf == NULL) {
4417 ALOGV("DEBUG(%s): record stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
4418 break;
4419 }
4420 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
4421 subParms->numSvcBufsInHal ++;
4422 ALOGV("DEBUG(%s): record got buf(%x) numBufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
4423 subParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
4424
4425 for (checkingIndex = 0; checkingIndex < subParms->numSvcBuffers ; checkingIndex++) {
4426 if (priv_handle->fd == subParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
4427 found = true;
4428 break;
4429 }
4430 }
4431 ALOGV("DEBUG(%s): record dequeueed_buffer found(%d) index = %d", __FUNCTION__, found, checkingIndex);
4432
4433 if (!found) {
4434 break;
4435 }
4436
4437 subParms->svcBufIndex = checkingIndex;
4438 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_SERVICE) {
4439 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4440 }
4441 else {
4442 ALOGV("DEBUG(%s): record bufstatus abnormal [%d] status = %d", __FUNCTION__,
4443 subParms->svcBufIndex, subParms->svcBufStatus[subParms->svcBufIndex]);
4444 }
4445 }
4446 return 0;
4447}
4448
4449int ExynosCameraHWInterface2::m_prvcbCreator(StreamThread *selfThread, ExynosBuffer *srcImageBuf, nsecs_t frameTimeStamp)
4450{
4451 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
4452 substream_parameters_t *subParms = &m_subStreams[STREAM_ID_PRVCB];
4453 status_t res;
4454 bool found = false;
4455 int cropX, cropY, cropW, cropH = 0;
4456 buffer_handle_t * buf = NULL;
4457
4458 ALOGV("DEBUG(%s): index(%d)",__FUNCTION__, subParms->svcBufIndex);
4459 for (int i = 0 ; subParms->numSvcBuffers ; i++) {
4460 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_HAL) {
4461 found = true;
4462 break;
4463 }
4464 subParms->svcBufIndex++;
4465 if (subParms->svcBufIndex >= subParms->numSvcBuffers)
4466 subParms->svcBufIndex = 0;
4467 }
4468 if (!found) {
4469 ALOGE("(%s): cannot find free svc buffer", __FUNCTION__);
4470 subParms->svcBufIndex++;
4471 return 1;
4472 }
4473
4474 if (subParms->format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
4475 if (m_exynosVideoCSC) {
4476 int previewCbW = subParms->width, previewCbH = subParms->height;
4477 int cropX, cropY, cropW, cropH = 0;
4478 int previewW = selfStreamParms->width, previewH = selfStreamParms->height;
4479 m_getRatioSize(previewW, previewH,
4480 previewCbW, previewCbH,
4481 &cropX, &cropY,
4482 &cropW, &cropH,
4483 0);
4484
4485 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
4486 __FUNCTION__, cropX, cropY, cropW, cropH);
4487 csc_set_src_format(m_exynosVideoCSC,
Sungjoong Kang4a3f1822012-09-28 20:07:32 -07004488 ALIGN(previewW, 32), previewH,
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004489 cropX, cropY, cropW, cropH,
4490 selfStreamParms->format,
4491 0);
4492
4493 csc_set_dst_format(m_exynosVideoCSC,
4494 previewCbW, previewCbH,
4495 0, 0, previewCbW, previewCbH,
4496 subParms->internalFormat,
4497 1);
4498
4499 csc_set_src_buffer(m_exynosVideoCSC,
4500 (void **)&srcImageBuf->fd.fd);
4501
4502 csc_set_dst_buffer(m_exynosVideoCSC,
4503 (void **)(&(m_previewCbBuf.fd.fd)));
4504
4505 if (csc_convert(m_exynosVideoCSC) != 0) {
4506 ALOGE("ERR(%s):previewcb csc_convert() fail", __FUNCTION__);
4507 }
4508 else {
4509 ALOGV("(%s):previewcb csc_convert() SUCCESS", __FUNCTION__);
4510 }
4511 if (previewCbW == ALIGN(previewCbW, 16)) {
4512 memcpy(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0],
4513 m_previewCbBuf.virt.extP[0], previewCbW * previewCbH);
4514 memcpy(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0] + previewCbW * previewCbH,
4515 m_previewCbBuf.virt.extP[1], previewCbW * previewCbH / 2 );
4516 }
4517 else {
4518 // TODO : copy line by line ?
4519 }
4520 }
4521 else {
4522 ALOGE("ERR(%s):m_exynosVideoCSC == NULL", __FUNCTION__);
4523 }
4524 }
4525 else if (subParms->format == HAL_PIXEL_FORMAT_YV12) {
4526 int previewCbW = subParms->width, previewCbH = subParms->height;
4527 int stride = ALIGN(previewCbW, 16);
Sungjoong Kang4a3f1822012-09-28 20:07:32 -07004528 int uv_stride = ALIGN(previewCbW/2, 16);
hyeonmyeong Choi0d220b42012-09-12 16:50:09 -07004529 int c_stride = ALIGN(stride / 2, 16);
Sungjoong Kang4a3f1822012-09-28 20:07:32 -07004530
4531 if (previewCbW == ALIGN(previewCbW, 32)) {
4532 memcpy(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0],
4533 srcImageBuf->virt.extP[0], stride * previewCbH);
4534 memcpy(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0] + stride * previewCbH,
4535 srcImageBuf->virt.extP[1], c_stride * previewCbH / 2 );
4536 memcpy(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0] + (stride * previewCbH) + (c_stride * previewCbH / 2),
4537 srcImageBuf->virt.extP[2], c_stride * previewCbH / 2 );
4538 } else {
4539 char * dstAddr = (char *)(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0]);
4540 char * srcAddr = (char *)(srcImageBuf->virt.extP[0]);
4541 for (int i = 0 ; i < previewCbH ; i++) {
4542 memcpy(dstAddr, srcAddr, previewCbW);
4543 dstAddr += stride;
4544 srcAddr += ALIGN(stride, 32);
4545 }
4546 dstAddr = (char *)(subParms->svcBuffers[subParms->svcBufIndex].virt.extP[0] + stride * previewCbH);
4547 srcAddr = (char *)(srcImageBuf->virt.extP[1]);
4548 for (int i = 0 ; i < previewCbH/2 ; i++) {
4549 memcpy(dstAddr, srcAddr, previewCbW/2);
4550 dstAddr += c_stride;
4551 srcAddr += uv_stride;
4552 }
4553 srcAddr = (char *)(srcImageBuf->virt.extP[2]);
4554 for (int i = 0 ; i < previewCbH/2 ; i++) {
4555 memcpy(dstAddr, srcAddr, previewCbW/2);
4556 dstAddr += c_stride;
4557 srcAddr += uv_stride;
4558 }
4559 }
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07004560 }
4561 res = subParms->streamOps->enqueue_buffer(subParms->streamOps, frameTimeStamp, &(subParms->svcBufHandle[subParms->svcBufIndex]));
4562
4563 ALOGV("DEBUG(%s): streamthread[%d] enqueue_buffer index(%d) to svc done res(%d)",
4564 __FUNCTION__, selfThread->m_index, subParms->svcBufIndex, res);
4565 if (res == 0) {
4566 subParms->svcBufStatus[subParms->svcBufIndex] = ON_SERVICE;
4567 subParms->numSvcBufsInHal--;
4568 }
4569 else {
4570 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4571 }
4572
4573 while (subParms->numSvcBufsInHal <= subParms->minUndequedBuffer)
4574 {
4575 bool found = false;
4576 int checkingIndex = 0;
4577
4578 ALOGV("DEBUG(%s): prvcb currentBuf#(%d)", __FUNCTION__ , subParms->numSvcBufsInHal);
4579
4580 res = subParms->streamOps->dequeue_buffer(subParms->streamOps, &buf);
4581 if (res != NO_ERROR || buf == NULL) {
4582 ALOGV("DEBUG(%s): prvcb stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
4583 break;
4584 }
4585 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
4586 subParms->numSvcBufsInHal ++;
4587 ALOGV("DEBUG(%s): prvcb got buf(%x) numBufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
4588 subParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
4589
4590
4591 for (checkingIndex = 0; checkingIndex < subParms->numSvcBuffers ; checkingIndex++) {
4592 if (priv_handle->fd == subParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
4593 found = true;
4594 break;
4595 }
4596 }
4597 ALOGV("DEBUG(%s): prvcb dequeueed_buffer found(%d) index = %d", __FUNCTION__, found, checkingIndex);
4598
4599 if (!found) {
4600 break;
4601 }
4602
4603 subParms->svcBufIndex = checkingIndex;
4604 if (subParms->svcBufStatus[subParms->svcBufIndex] == ON_SERVICE) {
4605 subParms->svcBufStatus[subParms->svcBufIndex] = ON_HAL;
4606 }
4607 else {
4608 ALOGV("DEBUG(%s): prvcb bufstatus abnormal [%d] status = %d", __FUNCTION__,
4609 subParms->svcBufIndex, subParms->svcBufStatus[subParms->svcBufIndex]);
4610 }
4611 }
4612 return 0;
4613}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07004614
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004615bool ExynosCameraHWInterface2::m_checkThumbnailSize(int w, int h)
4616{
4617 int sizeOfSupportList;
4618
4619 //REAR Camera
4620 if(this->getCameraId() == 0) {
4621 sizeOfSupportList = sizeof(SUPPORT_THUMBNAIL_REAR_SIZE) / (sizeof(int)*2);
4622
4623 for(int i = 0; i < sizeOfSupportList; i++) {
4624 if((SUPPORT_THUMBNAIL_REAR_SIZE[i][0] == w) &&(SUPPORT_THUMBNAIL_REAR_SIZE[i][1] == h))
4625 return true;
4626 }
4627
4628 }
4629 else {
4630 sizeOfSupportList = sizeof(SUPPORT_THUMBNAIL_FRONT_SIZE) / (sizeof(int)*2);
4631
4632 for(int i = 0; i < sizeOfSupportList; i++) {
4633 if((SUPPORT_THUMBNAIL_FRONT_SIZE[i][0] == w) &&(SUPPORT_THUMBNAIL_FRONT_SIZE[i][1] == h))
4634 return true;
4635 }
4636 }
4637
4638 return false;
4639}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004640bool ExynosCameraHWInterface2::yuv2Jpeg(ExynosBuffer *yuvBuf,
4641 ExynosBuffer *jpegBuf,
4642 ExynosRect *rect)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07004643{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004644 unsigned char *addr;
4645
4646 ExynosJpegEncoderForCamera jpegEnc;
4647 bool ret = false;
4648 int res = 0;
4649
4650 unsigned int *yuvSize = yuvBuf->size.extS;
4651
4652 if (jpegEnc.create()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004653 ALOGE("ERR(%s):jpegEnc.create() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004654 goto jpeg_encode_done;
4655 }
4656
Hyeonmyeong Choi87423e52012-10-04 16:34:55 +09004657 if (jpegEnc.setQuality(m_jpegMetadata.shot.ctl.jpeg.quality)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004658 ALOGE("ERR(%s):jpegEnc.setQuality() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004659 goto jpeg_encode_done;
4660 }
4661
4662 if (jpegEnc.setSize(rect->w, rect->h)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004663 ALOGE("ERR(%s):jpegEnc.setSize() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004664 goto jpeg_encode_done;
4665 }
4666 ALOGV("%s : width = %d , height = %d\n", __FUNCTION__, rect->w, rect->h);
4667
4668 if (jpegEnc.setColorFormat(rect->colorFormat)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004669 ALOGE("ERR(%s):jpegEnc.setColorFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004670 goto jpeg_encode_done;
4671 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004672
4673 if (jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004674 ALOGE("ERR(%s):jpegEnc.setJpegFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004675 goto jpeg_encode_done;
4676 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004677
Sungjoong Kang48728d42012-09-26 13:48:48 -07004678 if((m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[0] != 0) && (m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[1] != 0)) {
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004679 mExifInfo.enableThumb = true;
Sungjoong Kang48728d42012-09-26 13:48:48 -07004680 if(!m_checkThumbnailSize(m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[0], m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[1])) {
Sungjoong Kang4017b082012-09-21 15:44:48 -07004681 // in the case of unsupported parameter, disable thumbnail
4682 mExifInfo.enableThumb = false;
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004683 } else {
Sungjoong Kang48728d42012-09-26 13:48:48 -07004684 m_thumbNailW = m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[0];
4685 m_thumbNailH = m_jpegMetadata.shot.ctl.jpeg.thumbnailSize[1];
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004686 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004687
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004688 ALOGV("(%s) m_thumbNailW = %d, m_thumbNailH = %d", __FUNCTION__, m_thumbNailW, m_thumbNailH);
4689
4690 } else {
4691 mExifInfo.enableThumb = false;
4692 }
4693
4694 if (jpegEnc.setThumbnailSize(m_thumbNailW, m_thumbNailH)) {
4695 ALOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, m_thumbNailH, m_thumbNailH);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07004696 goto jpeg_encode_done;
4697 }
4698
Sungjoong Kang2d5e6ec2012-08-30 15:14:17 +09004699 ALOGV("(%s):jpegEnc.setThumbnailSize(%d, %d) ", __FUNCTION__, m_thumbNailW, m_thumbNailW);
Hyeonmyeong Choi87423e52012-10-04 16:34:55 +09004700 if (jpegEnc.setThumbnailQuality(m_jpegMetadata.shot.ctl.jpeg.thumbnailQuality)) {
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07004701 ALOGE("ERR(%s):jpegEnc.setThumbnailQuality fail", __FUNCTION__);
4702 goto jpeg_encode_done;
4703 }
4704
4705 m_setExifChangedAttribute(&mExifInfo, rect, &m_jpegMetadata);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004706 ALOGV("DEBUG(%s):calling jpegEnc.setInBuf() yuvSize(%d)", __FUNCTION__, *yuvSize);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07004707 if (jpegEnc.setInBuf((int *)&(yuvBuf->fd.fd), &(yuvBuf->virt.p), (int *)yuvSize)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004708 ALOGE("ERR(%s):jpegEnc.setInBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004709 goto jpeg_encode_done;
4710 }
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07004711 if (jpegEnc.setOutBuf(jpegBuf->fd.fd, jpegBuf->virt.p, jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2])) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004712 ALOGE("ERR(%s):jpegEnc.setOutBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004713 goto jpeg_encode_done;
4714 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004715
4716 if (jpegEnc.updateConfig()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004717 ALOGE("ERR(%s):jpegEnc.updateConfig() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004718 goto jpeg_encode_done;
4719 }
4720
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07004721 if (res = jpegEnc.encode((int *)&jpegBuf->size.s, &mExifInfo)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09004722 ALOGE("ERR(%s):jpegEnc.encode() fail ret(%d)", __FUNCTION__, res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004723 goto jpeg_encode_done;
4724 }
4725
4726 ret = true;
4727
4728jpeg_encode_done:
4729
4730 if (jpegEnc.flagCreate() == true)
4731 jpegEnc.destroy();
4732
4733 return ret;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07004734}
4735
Younghwan Jooe117f752012-09-12 22:21:55 -07004736void ExynosCameraHWInterface2::OnPrecaptureMeteringTriggerStart(int id)
4737{
4738 m_ctlInfo.flash.m_precaptureTriggerId = id;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004739 m_ctlInfo.ae.aeStateNoti = AE_STATE_INACTIVE;
Younghwan Jooe117f752012-09-12 22:21:55 -07004740 if ((m_ctlInfo.flash.i_flashMode >= AA_AEMODE_ON_AUTO_FLASH) && (m_cameraId == 0)) {
4741 // flash is required
4742 switch (m_ctlInfo.flash.m_flashCnt) {
4743 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Jood91c0262012-09-14 18:21:16 -07004744 case IS_FLASH_STATE_AUTO_OFF:
Younghwan Jooe117f752012-09-12 22:21:55 -07004745 // Flash capture sequence, AF flash was executed before
4746 break;
4747 default:
4748 // Full flash sequence
4749 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON;
4750 m_ctlInfo.flash.m_flashEnableFlg = true;
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09004751 m_ctlInfo.flash.m_flashTimeOut = 0;
Younghwan Jooe117f752012-09-12 22:21:55 -07004752 }
4753 } else {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004754 // Skip pre-capture in case of non-flash.
4755 ALOGV("[PreCap] Flash OFF mode ");
Younghwan Jooe117f752012-09-12 22:21:55 -07004756 m_ctlInfo.flash.m_flashEnableFlg = false;
4757 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_NONE;
Younghwan Jooe117f752012-09-12 22:21:55 -07004758 }
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004759 ALOGV("[PreCap] OnPrecaptureMeteringTriggerStart (ID %d) (flag : %d) (cnt : %d)", id, m_ctlInfo.flash.m_flashEnableFlg, m_ctlInfo.flash.m_flashCnt);
4760 OnPrecaptureMeteringNotificationSensor();
Younghwan Jooe117f752012-09-12 22:21:55 -07004761}
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07004762void ExynosCameraHWInterface2::OnAfTriggerStart(int id)
4763{
4764 m_afPendingTriggerId = id;
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07004765 m_afModeWaitingCnt = 6;
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07004766}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09004767
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004768void ExynosCameraHWInterface2::OnAfTrigger(int id)
4769{
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07004770 m_afTriggerId = id;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07004771
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004772 switch (m_afMode) {
4773 case AA_AFMODE_AUTO:
4774 case AA_AFMODE_MACRO:
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07004775 case AA_AFMODE_OFF:
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004776 ALOGV("[AF] OnAfTrigger - AUTO,MACRO,OFF (Mode %d) ", m_afMode);
Younghwan Joocaea49e2012-09-07 13:34:20 -07004777 // If flash is enable, Flash operation is executed before triggering AF
4778 if ((m_ctlInfo.flash.i_flashMode >= AA_AEMODE_ON_AUTO_FLASH)
Younghwan Jooe117f752012-09-12 22:21:55 -07004779 && (m_ctlInfo.flash.m_flashEnableFlg == false)
Younghwan Joocaea49e2012-09-07 13:34:20 -07004780 && (m_cameraId == 0)) {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004781 ALOGV("[Flash] AF Flash start with Mode (%d)", m_afMode);
Younghwan Jooe117f752012-09-12 22:21:55 -07004782 m_ctlInfo.flash.m_flashEnableFlg = true;
4783 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON;
Younghwan Joocaea49e2012-09-07 13:34:20 -07004784 m_ctlInfo.flash.m_flashDecisionResult = false;
Younghwan Jooe117f752012-09-12 22:21:55 -07004785 m_ctlInfo.flash.m_afFlashDoneFlg = true;
Younghwan Joocaea49e2012-09-07 13:34:20 -07004786 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004787 OnAfTriggerAutoMacro(id);
4788 break;
4789 case AA_AFMODE_CONTINUOUS_VIDEO:
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004790 ALOGV("[AF] OnAfTrigger - AA_AFMODE_CONTINUOUS_VIDEO (Mode %d) ", m_afMode);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004791 OnAfTriggerCAFVideo(id);
4792 break;
4793 case AA_AFMODE_CONTINUOUS_PICTURE:
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004794 ALOGV("[AF] OnAfTrigger - AA_AFMODE_CONTINUOUS_PICTURE (Mode %d) ", m_afMode);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004795 OnAfTriggerCAFPicture(id);
4796 break;
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07004797
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004798 default:
4799 break;
4800 }
4801}
4802
4803void ExynosCameraHWInterface2::OnAfTriggerAutoMacro(int id)
4804{
4805 int nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004806
4807 switch (m_afState) {
4808 case HAL_AFSTATE_INACTIVE:
Sungjoong Kang6caa0c82012-10-04 18:19:14 -07004809 case HAL_AFSTATE_PASSIVE_FOCUSED:
4810 case HAL_AFSTATE_SCANNING:
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004811 nextState = HAL_AFSTATE_NEEDS_COMMAND;
4812 m_IsAfTriggerRequired = true;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07004813 m_ctlInfo.af.m_afTriggerTimeOut = 4;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004814 break;
4815 case HAL_AFSTATE_NEEDS_COMMAND:
4816 nextState = NO_TRANSITION;
4817 break;
4818 case HAL_AFSTATE_STARTED:
4819 nextState = NO_TRANSITION;
4820 break;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004821 case HAL_AFSTATE_LOCKED:
4822 nextState = HAL_AFSTATE_NEEDS_COMMAND;
4823 m_IsAfTriggerRequired = true;
4824 break;
4825 case HAL_AFSTATE_FAILED:
4826 nextState = HAL_AFSTATE_NEEDS_COMMAND;
4827 m_IsAfTriggerRequired = true;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07004828 m_ctlInfo.af.m_afTriggerTimeOut = 4;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004829 break;
4830 default:
4831 break;
4832 }
4833 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
4834 if (nextState != NO_TRANSITION)
4835 m_afState = nextState;
4836}
4837
4838void ExynosCameraHWInterface2::OnAfTriggerCAFPicture(int id)
4839{
4840 int nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004841
4842 switch (m_afState) {
4843 case HAL_AFSTATE_INACTIVE:
4844 nextState = HAL_AFSTATE_FAILED;
4845 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
4846 break;
4847 case HAL_AFSTATE_NEEDS_COMMAND:
4848 // not used
4849 break;
4850 case HAL_AFSTATE_STARTED:
4851 nextState = HAL_AFSTATE_NEEDS_DETERMINATION;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07004852 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004853 break;
4854 case HAL_AFSTATE_SCANNING:
4855 nextState = HAL_AFSTATE_NEEDS_DETERMINATION;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07004856 m_AfHwStateFailed = false;
Younghwan Joocaea49e2012-09-07 13:34:20 -07004857 // If flash is enable, Flash operation is executed before triggering AF
4858 if ((m_ctlInfo.flash.i_flashMode >= AA_AEMODE_ON_AUTO_FLASH)
Younghwan Jooe117f752012-09-12 22:21:55 -07004859 && (m_ctlInfo.flash.m_flashEnableFlg == false)
Younghwan Joocaea49e2012-09-07 13:34:20 -07004860 && (m_cameraId == 0)) {
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004861 ALOGV("[AF Flash] AF Flash start with Mode (%d) state (%d) id (%d)", m_afMode, m_afState, id);
Younghwan Jooe117f752012-09-12 22:21:55 -07004862 m_ctlInfo.flash.m_flashEnableFlg = true;
4863 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_ON;
Younghwan Joocaea49e2012-09-07 13:34:20 -07004864 m_ctlInfo.flash.m_flashDecisionResult = false;
Younghwan Jooe117f752012-09-12 22:21:55 -07004865 m_ctlInfo.flash.m_afFlashDoneFlg = true;
Younghwan Joocaea49e2012-09-07 13:34:20 -07004866 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004867 break;
4868 case HAL_AFSTATE_NEEDS_DETERMINATION:
4869 nextState = NO_TRANSITION;
4870 break;
4871 case HAL_AFSTATE_PASSIVE_FOCUSED:
4872 m_IsAfLockRequired = true;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07004873 if (m_AfHwStateFailed) {
Younghwan Joocaea49e2012-09-07 13:34:20 -07004874 ALOGE("(%s): [CAF] LAST : fail", __FUNCTION__);
Sungjoong Kang36c106c2012-08-23 17:38:20 -07004875 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
4876 nextState = HAL_AFSTATE_FAILED;
4877 }
4878 else {
Younghwan Joocaea49e2012-09-07 13:34:20 -07004879 ALOGV("(%s): [CAF] LAST : success", __FUNCTION__);
Sungjoong Kang36c106c2012-08-23 17:38:20 -07004880 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
4881 nextState = HAL_AFSTATE_LOCKED;
4882 }
4883 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004884 break;
4885 case HAL_AFSTATE_LOCKED:
4886 nextState = NO_TRANSITION;
4887 break;
4888 case HAL_AFSTATE_FAILED:
4889 nextState = NO_TRANSITION;
4890 break;
4891 default:
4892 break;
4893 }
4894 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
4895 if (nextState != NO_TRANSITION)
4896 m_afState = nextState;
4897}
4898
4899
4900void ExynosCameraHWInterface2::OnAfTriggerCAFVideo(int id)
4901{
4902 int nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07004903
4904 switch (m_afState) {
4905 case HAL_AFSTATE_INACTIVE:
4906 nextState = HAL_AFSTATE_FAILED;
4907 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
4908 break;
4909 case HAL_AFSTATE_NEEDS_COMMAND:
4910 // not used
4911 break;
4912 case HAL_AFSTATE_STARTED:
4913 m_IsAfLockRequired = true;
4914 nextState = HAL_AFSTATE_FAILED;
4915 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
4916 break;
4917 case HAL_AFSTATE_SCANNING:
4918 m_IsAfLockRequired = true;
4919 nextState = HAL_AFSTATE_FAILED;
4920 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
4921 break;
4922 case HAL_AFSTATE_NEEDS_DETERMINATION:
4923 // not used
4924 break;
4925 case HAL_AFSTATE_PASSIVE_FOCUSED:
4926 m_IsAfLockRequired = true;
4927 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
4928 nextState = HAL_AFSTATE_LOCKED;
4929 break;
4930 case HAL_AFSTATE_LOCKED:
4931 nextState = NO_TRANSITION;
4932 break;
4933 case HAL_AFSTATE_FAILED:
4934 nextState = NO_TRANSITION;
4935 break;
4936 default:
4937 break;
4938 }
4939 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
4940 if (nextState != NO_TRANSITION)
4941 m_afState = nextState;
4942}
4943
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004944void ExynosCameraHWInterface2::OnPrecaptureMeteringNotificationSensor()
4945{
4946 if (m_ctlInfo.flash.m_precaptureTriggerId > 0) {
4947 // Just noti of pre-capture start
4948 if (m_ctlInfo.ae.aeStateNoti != AE_STATE_PRECAPTURE) {
4949 m_notifyCb(CAMERA2_MSG_AUTOEXPOSURE,
4950 ANDROID_CONTROL_AE_STATE_PRECAPTURE,
4951 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
4952 ALOGV("(%s) ANDROID_CONTROL_AE_STATE_PRECAPTURE (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
4953 m_notifyCb(CAMERA2_MSG_AUTOWB,
4954 ANDROID_CONTROL_AWB_STATE_CONVERGED,
4955 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
4956 m_ctlInfo.ae.aeStateNoti = AE_STATE_PRECAPTURE;
4957 }
4958 }
4959}
4960
4961void ExynosCameraHWInterface2::OnPrecaptureMeteringNotificationISP()
Younghwan Jooe117f752012-09-12 22:21:55 -07004962{
4963 if (m_ctlInfo.flash.m_precaptureTriggerId > 0) {
4964 if (m_ctlInfo.flash.m_flashEnableFlg) {
4965 // flash case
4966 switch (m_ctlInfo.flash.m_flashCnt) {
4967 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Jood91c0262012-09-14 18:21:16 -07004968 case IS_FLASH_STATE_AUTO_OFF:
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004969 if (m_ctlInfo.ae.aeStateNoti == AE_STATE_PRECAPTURE) {
4970 // End notification
Younghwan Jood91c0262012-09-14 18:21:16 -07004971 m_notifyCb(CAMERA2_MSG_AUTOEXPOSURE,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09004972 ANDROID_CONTROL_AE_STATE_CONVERGED,
Younghwan Jood91c0262012-09-14 18:21:16 -07004973 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09004974 ALOGV("(%s) ANDROID_CONTROL_AE_STATE_CONVERGED (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
Younghwan Jood91c0262012-09-14 18:21:16 -07004975 m_notifyCb(CAMERA2_MSG_AUTOWB,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09004976 ANDROID_CONTROL_AWB_STATE_CONVERGED,
Younghwan Jood91c0262012-09-14 18:21:16 -07004977 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
4978 m_ctlInfo.flash.m_precaptureTriggerId = 0;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004979 } else {
4980 m_notifyCb(CAMERA2_MSG_AUTOEXPOSURE,
4981 ANDROID_CONTROL_AE_STATE_PRECAPTURE,
4982 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
Younghwan Joo40acdcc2012-09-29 16:32:43 +09004983 ALOGV("(%s) ANDROID_CONTROL_AE_STATE_PRECAPTURE (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004984 m_notifyCb(CAMERA2_MSG_AUTOWB,
4985 ANDROID_CONTROL_AWB_STATE_CONVERGED,
4986 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
4987 m_ctlInfo.ae.aeStateNoti = AE_STATE_PRECAPTURE;
Younghwan Jood91c0262012-09-14 18:21:16 -07004988 }
Younghwan Jooe117f752012-09-12 22:21:55 -07004989 break;
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004990 case IS_FLASH_STATE_CAPTURE:
4991 case IS_FLASH_STATE_CAPTURE_WAIT:
4992 case IS_FLASH_STATE_CAPTURE_JPEG:
4993 case IS_FLASH_STATE_CAPTURE_END:
4994 ALOGV("(%s) INVALID flash state count. (%d)", __FUNCTION__, (int)m_ctlInfo.flash.m_flashCnt);
4995 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_DONE;
4996 m_notifyCb(CAMERA2_MSG_AUTOEXPOSURE,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09004997 ANDROID_CONTROL_AE_STATE_CONVERGED,
Younghwan Joo73f5ad62012-09-16 21:05:30 -07004998 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
4999 m_notifyCb(CAMERA2_MSG_AUTOWB,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09005000 ANDROID_CONTROL_AWB_STATE_CONVERGED,
Younghwan Joo73f5ad62012-09-16 21:05:30 -07005001 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
5002 m_ctlInfo.flash.m_precaptureTriggerId = 0;
5003 break;
Younghwan Jooe117f752012-09-12 22:21:55 -07005004 }
5005 } else {
5006 // non-flash case
Younghwan Joo73f5ad62012-09-16 21:05:30 -07005007 if (m_ctlInfo.ae.aeStateNoti == AE_STATE_PRECAPTURE) {
Younghwan Jood91c0262012-09-14 18:21:16 -07005008 m_notifyCb(CAMERA2_MSG_AUTOEXPOSURE,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09005009 ANDROID_CONTROL_AE_STATE_CONVERGED,
Younghwan Jood91c0262012-09-14 18:21:16 -07005010 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09005011 ALOGV("(%s) ANDROID_CONTROL_AE_STATE_CONVERGED (%d)", __FUNCTION__, m_ctlInfo.flash.m_flashCnt);
Younghwan Jooe117f752012-09-12 22:21:55 -07005012 m_notifyCb(CAMERA2_MSG_AUTOWB,
Younghwan Joo8a3fc5d2012-09-26 22:51:10 +09005013 ANDROID_CONTROL_AWB_STATE_CONVERGED,
Younghwan Jooe117f752012-09-12 22:21:55 -07005014 m_ctlInfo.flash.m_precaptureTriggerId, 0, m_callbackCookie);
Younghwan Jood91c0262012-09-14 18:21:16 -07005015 m_ctlInfo.flash.m_precaptureTriggerId = 0;
Younghwan Jooe117f752012-09-12 22:21:55 -07005016 }
5017 }
5018 }
5019}
5020
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005021void ExynosCameraHWInterface2::OnAfNotification(enum aa_afstate noti)
5022{
5023 switch (m_afMode) {
5024 case AA_AFMODE_AUTO:
5025 case AA_AFMODE_MACRO:
5026 OnAfNotificationAutoMacro(noti);
5027 break;
5028 case AA_AFMODE_CONTINUOUS_VIDEO:
5029 OnAfNotificationCAFVideo(noti);
5030 break;
5031 case AA_AFMODE_CONTINUOUS_PICTURE:
5032 OnAfNotificationCAFPicture(noti);
5033 break;
5034 case AA_AFMODE_OFF:
5035 default:
5036 break;
5037 }
5038}
5039
5040void ExynosCameraHWInterface2::OnAfNotificationAutoMacro(enum aa_afstate noti)
5041{
5042 int nextState = NO_TRANSITION;
5043 bool bWrongTransition = false;
5044
5045 if (m_afState == HAL_AFSTATE_INACTIVE || m_afState == HAL_AFSTATE_NEEDS_COMMAND) {
5046 switch (noti) {
5047 case AA_AFSTATE_INACTIVE:
5048 case AA_AFSTATE_ACTIVE_SCAN:
5049 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5050 case AA_AFSTATE_AF_FAILED_FOCUS:
5051 default:
5052 nextState = NO_TRANSITION;
5053 break;
5054 }
5055 }
5056 else if (m_afState == HAL_AFSTATE_STARTED) {
5057 switch (noti) {
5058 case AA_AFSTATE_INACTIVE:
5059 nextState = NO_TRANSITION;
5060 break;
5061 case AA_AFSTATE_ACTIVE_SCAN:
5062 nextState = HAL_AFSTATE_SCANNING;
5063 SetAfStateForService(ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN);
5064 break;
5065 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5066 nextState = NO_TRANSITION;
5067 break;
5068 case AA_AFSTATE_AF_FAILED_FOCUS:
5069 nextState = NO_TRANSITION;
5070 break;
5071 default:
5072 bWrongTransition = true;
5073 break;
5074 }
5075 }
5076 else if (m_afState == HAL_AFSTATE_SCANNING) {
5077 switch (noti) {
5078 case AA_AFSTATE_INACTIVE:
5079 bWrongTransition = true;
5080 break;
5081 case AA_AFSTATE_ACTIVE_SCAN:
5082 nextState = NO_TRANSITION;
5083 break;
5084 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
Younghwan Joo9a710a42012-09-05 17:52:08 -07005085 // If Flash mode is enable, after AF execute pre-capture metering
Younghwan Jooe117f752012-09-12 22:21:55 -07005086 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
5087 switch (m_ctlInfo.flash.m_flashCnt) {
5088 case IS_FLASH_STATE_ON_DONE:
5089 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_AE_AWB_LOCK;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005090 nextState = NO_TRANSITION;
Younghwan Jooe117f752012-09-12 22:21:55 -07005091 break;
5092 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005093 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_OFF;
Younghwan Joo9a710a42012-09-05 17:52:08 -07005094 nextState = HAL_AFSTATE_LOCKED;
5095 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
Younghwan Jooe117f752012-09-12 22:21:55 -07005096 break;
5097 default:
Younghwan Joo9a710a42012-09-05 17:52:08 -07005098 nextState = NO_TRANSITION;
5099 }
5100 } else {
5101 nextState = HAL_AFSTATE_LOCKED;
5102 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
5103 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005104 break;
5105 case AA_AFSTATE_AF_FAILED_FOCUS:
Younghwan Joo9a710a42012-09-05 17:52:08 -07005106 // If Flash mode is enable, after AF execute pre-capture metering
Younghwan Jooe117f752012-09-12 22:21:55 -07005107 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
5108 switch (m_ctlInfo.flash.m_flashCnt) {
5109 case IS_FLASH_STATE_ON_DONE:
5110 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_AE_AWB_LOCK;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005111 nextState = NO_TRANSITION;
Younghwan Jooe117f752012-09-12 22:21:55 -07005112 break;
5113 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005114 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_OFF;
Younghwan Joo9a710a42012-09-05 17:52:08 -07005115 nextState = HAL_AFSTATE_FAILED;
5116 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
Younghwan Jooe117f752012-09-12 22:21:55 -07005117 break;
5118 default:
Younghwan Joo9a710a42012-09-05 17:52:08 -07005119 nextState = NO_TRANSITION;
5120 }
5121 } else {
5122 nextState = HAL_AFSTATE_FAILED;
5123 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
5124 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005125 break;
5126 default:
5127 bWrongTransition = true;
5128 break;
5129 }
5130 }
5131 else if (m_afState == HAL_AFSTATE_LOCKED) {
5132 switch (noti) {
5133 case AA_AFSTATE_INACTIVE:
5134 case AA_AFSTATE_ACTIVE_SCAN:
5135 bWrongTransition = true;
5136 break;
5137 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5138 nextState = NO_TRANSITION;
5139 break;
5140 case AA_AFSTATE_AF_FAILED_FOCUS:
5141 default:
5142 bWrongTransition = true;
5143 break;
5144 }
5145 }
5146 else if (m_afState == HAL_AFSTATE_FAILED) {
5147 switch (noti) {
5148 case AA_AFSTATE_INACTIVE:
5149 case AA_AFSTATE_ACTIVE_SCAN:
5150 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5151 bWrongTransition = true;
5152 break;
5153 case AA_AFSTATE_AF_FAILED_FOCUS:
5154 nextState = NO_TRANSITION;
5155 break;
5156 default:
5157 bWrongTransition = true;
5158 break;
5159 }
5160 }
5161 if (bWrongTransition) {
5162 ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
5163 return;
5164 }
5165 ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
5166 if (nextState != NO_TRANSITION)
5167 m_afState = nextState;
5168}
5169
5170void ExynosCameraHWInterface2::OnAfNotificationCAFPicture(enum aa_afstate noti)
5171{
5172 int nextState = NO_TRANSITION;
5173 bool bWrongTransition = false;
5174
5175 if (m_afState == HAL_AFSTATE_INACTIVE) {
5176 switch (noti) {
5177 case AA_AFSTATE_INACTIVE:
5178 case AA_AFSTATE_ACTIVE_SCAN:
5179 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5180 case AA_AFSTATE_AF_FAILED_FOCUS:
5181 default:
5182 nextState = NO_TRANSITION;
5183 break;
5184 }
Younghwan Joo40acdcc2012-09-29 16:32:43 +09005185 // Check AF notification after triggering
5186 if (m_ctlInfo.af.m_afTriggerTimeOut > 0) {
5187 if (m_ctlInfo.af.m_afTriggerTimeOut > 5) {
5188 ALOGE("(%s) AF notification error - try to re-trigger mode (%)", __FUNCTION__, m_afMode);
5189 SetAfMode(AA_AFMODE_OFF);
5190 SetAfMode(m_afMode);
5191 m_ctlInfo.af.m_afTriggerTimeOut = 0;
5192 } else {
5193 m_ctlInfo.af.m_afTriggerTimeOut++;
5194 }
5195 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005196 }
5197 else if (m_afState == HAL_AFSTATE_STARTED) {
5198 switch (noti) {
5199 case AA_AFSTATE_INACTIVE:
5200 nextState = NO_TRANSITION;
5201 break;
5202 case AA_AFSTATE_ACTIVE_SCAN:
5203 nextState = HAL_AFSTATE_SCANNING;
5204 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
Younghwan Joo40acdcc2012-09-29 16:32:43 +09005205 m_ctlInfo.af.m_afTriggerTimeOut = 0;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005206 break;
5207 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5208 nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
5209 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
Younghwan Joo40acdcc2012-09-29 16:32:43 +09005210 m_ctlInfo.af.m_afTriggerTimeOut = 0;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005211 break;
5212 case AA_AFSTATE_AF_FAILED_FOCUS:
Sungjoong Kangcd13bb72012-08-28 13:05:01 -07005213 //nextState = HAL_AFSTATE_FAILED;
5214 //SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
5215 nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005216 break;
5217 default:
5218 bWrongTransition = true;
5219 break;
5220 }
5221 }
5222 else if (m_afState == HAL_AFSTATE_SCANNING) {
5223 switch (noti) {
5224 case AA_AFSTATE_INACTIVE:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005225 nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005226 break;
5227 case AA_AFSTATE_ACTIVE_SCAN:
5228 nextState = NO_TRANSITION;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005229 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005230 break;
5231 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5232 nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005233 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005234 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
5235 break;
5236 case AA_AFSTATE_AF_FAILED_FOCUS:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005237 nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
5238 m_AfHwStateFailed = true;
5239 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005240 break;
5241 default:
5242 bWrongTransition = true;
5243 break;
5244 }
5245 }
5246 else if (m_afState == HAL_AFSTATE_PASSIVE_FOCUSED) {
5247 switch (noti) {
5248 case AA_AFSTATE_INACTIVE:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005249 nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005250 break;
5251 case AA_AFSTATE_ACTIVE_SCAN:
5252 nextState = HAL_AFSTATE_SCANNING;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005253 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005254 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
5255 break;
5256 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5257 nextState = NO_TRANSITION;
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005258 m_AfHwStateFailed = false;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005259 break;
5260 case AA_AFSTATE_AF_FAILED_FOCUS:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005261 nextState = NO_TRANSITION;
5262 m_AfHwStateFailed = true;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005263 break;
5264 default:
5265 bWrongTransition = true;
5266 break;
5267 }
5268 }
5269 else if (m_afState == HAL_AFSTATE_NEEDS_DETERMINATION) {
Younghwan Joof7f8d322012-09-21 00:42:08 -07005270 //Skip notification in case of flash, wait the end of flash on
5271 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
5272 if (m_ctlInfo.flash.m_flashCnt < IS_FLASH_STATE_ON_DONE)
5273 return;
5274 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005275 switch (noti) {
5276 case AA_AFSTATE_INACTIVE:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005277 nextState = NO_TRANSITION;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005278 break;
5279 case AA_AFSTATE_ACTIVE_SCAN:
5280 nextState = NO_TRANSITION;
5281 break;
5282 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
Younghwan Joocaea49e2012-09-07 13:34:20 -07005283 // If Flash mode is enable, after AF execute pre-capture metering
Younghwan Jooe117f752012-09-12 22:21:55 -07005284 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
Younghwan Jooe117f752012-09-12 22:21:55 -07005285 switch (m_ctlInfo.flash.m_flashCnt) {
5286 case IS_FLASH_STATE_ON_DONE:
Younghwan Joof7f8d322012-09-21 00:42:08 -07005287 ALOGV("[AF Flash] AUTO start with Mode (%d) state (%d) noti (%d)", m_afMode, m_afState, (int)noti);
Younghwan Jooe117f752012-09-12 22:21:55 -07005288 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_AE_AWB_LOCK;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005289 nextState = NO_TRANSITION;
Younghwan Jooe117f752012-09-12 22:21:55 -07005290 break;
5291 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Joof7f8d322012-09-21 00:42:08 -07005292 ALOGV("[AF Flash] AUTO end with Mode (%d) state (%d) noti (%d)", m_afMode, m_afState, (int)noti);
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005293 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_OFF;
Younghwan Joocaea49e2012-09-07 13:34:20 -07005294 m_IsAfLockRequired = true;
5295 nextState = HAL_AFSTATE_LOCKED;
5296 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
Younghwan Jooe117f752012-09-12 22:21:55 -07005297 break;
5298 default:
Younghwan Joocaea49e2012-09-07 13:34:20 -07005299 nextState = NO_TRANSITION;
5300 }
5301 } else {
5302 m_IsAfLockRequired = true;
5303 nextState = HAL_AFSTATE_LOCKED;
5304 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
5305 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005306 break;
5307 case AA_AFSTATE_AF_FAILED_FOCUS:
Younghwan Joocaea49e2012-09-07 13:34:20 -07005308 // If Flash mode is enable, after AF execute pre-capture metering
Younghwan Jooe117f752012-09-12 22:21:55 -07005309 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
Younghwan Jooe117f752012-09-12 22:21:55 -07005310 switch (m_ctlInfo.flash.m_flashCnt) {
5311 case IS_FLASH_STATE_ON_DONE:
Younghwan Joof7f8d322012-09-21 00:42:08 -07005312 ALOGV("[AF Flash] AUTO start with Mode (%d) state (%d) noti (%d)", m_afMode, m_afState, (int)noti);
Younghwan Jooe117f752012-09-12 22:21:55 -07005313 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_AE_AWB_LOCK;
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005314 nextState = NO_TRANSITION;
Younghwan Jooe117f752012-09-12 22:21:55 -07005315 break;
5316 case IS_FLASH_STATE_AUTO_DONE:
Younghwan Joof7f8d322012-09-21 00:42:08 -07005317 ALOGV("[AF Flash] AUTO end with Mode (%d) state (%d) noti (%d)", m_afMode, m_afState, (int)noti);
Younghwan Joo4a9565a2012-09-19 18:41:35 -07005318 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_OFF;
Younghwan Joocaea49e2012-09-07 13:34:20 -07005319 m_IsAfLockRequired = true;
5320 nextState = HAL_AFSTATE_FAILED;
5321 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
Younghwan Jooe117f752012-09-12 22:21:55 -07005322 break;
5323 default:
Younghwan Joocaea49e2012-09-07 13:34:20 -07005324 nextState = NO_TRANSITION;
5325 }
5326 } else {
5327 m_IsAfLockRequired = true;
5328 nextState = HAL_AFSTATE_FAILED;
5329 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
5330 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005331 break;
5332 default:
5333 bWrongTransition = true;
5334 break;
5335 }
5336 }
5337 else if (m_afState == HAL_AFSTATE_LOCKED) {
5338 switch (noti) {
5339 case AA_AFSTATE_INACTIVE:
5340 nextState = NO_TRANSITION;
5341 break;
5342 case AA_AFSTATE_ACTIVE_SCAN:
5343 bWrongTransition = true;
5344 break;
5345 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5346 nextState = NO_TRANSITION;
5347 break;
5348 case AA_AFSTATE_AF_FAILED_FOCUS:
5349 default:
5350 bWrongTransition = true;
5351 break;
5352 }
5353 }
5354 else if (m_afState == HAL_AFSTATE_FAILED) {
5355 switch (noti) {
5356 case AA_AFSTATE_INACTIVE:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005357 bWrongTransition = true;
5358 break;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005359 case AA_AFSTATE_ACTIVE_SCAN:
Sungjoong Kang36c106c2012-08-23 17:38:20 -07005360 nextState = HAL_AFSTATE_SCANNING;
5361 break;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005362 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5363 bWrongTransition = true;
5364 break;
5365 case AA_AFSTATE_AF_FAILED_FOCUS:
5366 nextState = NO_TRANSITION;
5367 break;
5368 default:
5369 bWrongTransition = true;
5370 break;
5371 }
5372 }
5373 if (bWrongTransition) {
5374 ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
5375 return;
5376 }
5377 ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
5378 if (nextState != NO_TRANSITION)
5379 m_afState = nextState;
5380}
5381
5382void ExynosCameraHWInterface2::OnAfNotificationCAFVideo(enum aa_afstate noti)
5383{
5384 int nextState = NO_TRANSITION;
5385 bool bWrongTransition = false;
5386
5387 if (m_afState == HAL_AFSTATE_INACTIVE) {
5388 switch (noti) {
5389 case AA_AFSTATE_INACTIVE:
5390 case AA_AFSTATE_ACTIVE_SCAN:
5391 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5392 case AA_AFSTATE_AF_FAILED_FOCUS:
5393 default:
5394 nextState = NO_TRANSITION;
5395 break;
5396 }
5397 }
5398 else if (m_afState == HAL_AFSTATE_STARTED) {
5399 switch (noti) {
5400 case AA_AFSTATE_INACTIVE:
5401 nextState = NO_TRANSITION;
5402 break;
5403 case AA_AFSTATE_ACTIVE_SCAN:
5404 nextState = HAL_AFSTATE_SCANNING;
5405 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
5406 break;
5407 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5408 nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
5409 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
5410 break;
5411 case AA_AFSTATE_AF_FAILED_FOCUS:
5412 nextState = HAL_AFSTATE_FAILED;
5413 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
5414 break;
5415 default:
5416 bWrongTransition = true;
5417 break;
5418 }
5419 }
5420 else if (m_afState == HAL_AFSTATE_SCANNING) {
5421 switch (noti) {
5422 case AA_AFSTATE_INACTIVE:
5423 bWrongTransition = true;
5424 break;
5425 case AA_AFSTATE_ACTIVE_SCAN:
5426 nextState = NO_TRANSITION;
5427 break;
5428 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5429 nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
5430 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
5431 break;
5432 case AA_AFSTATE_AF_FAILED_FOCUS:
5433 nextState = NO_TRANSITION;
5434 break;
5435 default:
5436 bWrongTransition = true;
5437 break;
5438 }
5439 }
5440 else if (m_afState == HAL_AFSTATE_PASSIVE_FOCUSED) {
5441 switch (noti) {
5442 case AA_AFSTATE_INACTIVE:
5443 bWrongTransition = true;
5444 break;
5445 case AA_AFSTATE_ACTIVE_SCAN:
5446 nextState = HAL_AFSTATE_SCANNING;
5447 SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
5448 break;
5449 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5450 nextState = NO_TRANSITION;
5451 break;
5452 case AA_AFSTATE_AF_FAILED_FOCUS:
5453 nextState = HAL_AFSTATE_FAILED;
5454 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07005455 // TODO : needs NO_TRANSITION ?
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005456 break;
5457 default:
5458 bWrongTransition = true;
5459 break;
5460 }
5461 }
5462 else if (m_afState == HAL_AFSTATE_NEEDS_DETERMINATION) {
5463 switch (noti) {
5464 case AA_AFSTATE_INACTIVE:
5465 bWrongTransition = true;
5466 break;
5467 case AA_AFSTATE_ACTIVE_SCAN:
5468 nextState = NO_TRANSITION;
5469 break;
5470 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5471 m_IsAfLockRequired = true;
5472 nextState = HAL_AFSTATE_LOCKED;
5473 SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
5474 break;
5475 case AA_AFSTATE_AF_FAILED_FOCUS:
5476 nextState = HAL_AFSTATE_FAILED;
5477 SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
5478 break;
5479 default:
5480 bWrongTransition = true;
5481 break;
5482 }
5483 }
5484 else if (m_afState == HAL_AFSTATE_LOCKED) {
5485 switch (noti) {
5486 case AA_AFSTATE_INACTIVE:
5487 nextState = NO_TRANSITION;
5488 break;
5489 case AA_AFSTATE_ACTIVE_SCAN:
5490 bWrongTransition = true;
5491 break;
5492 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5493 nextState = NO_TRANSITION;
5494 break;
5495 case AA_AFSTATE_AF_FAILED_FOCUS:
5496 default:
5497 bWrongTransition = true;
5498 break;
5499 }
5500 }
5501 else if (m_afState == HAL_AFSTATE_FAILED) {
5502 switch (noti) {
5503 case AA_AFSTATE_INACTIVE:
5504 case AA_AFSTATE_ACTIVE_SCAN:
5505 case AA_AFSTATE_AF_ACQUIRED_FOCUS:
5506 bWrongTransition = true;
5507 break;
5508 case AA_AFSTATE_AF_FAILED_FOCUS:
5509 nextState = NO_TRANSITION;
5510 break;
5511 default:
5512 bWrongTransition = true;
5513 break;
5514 }
5515 }
5516 if (bWrongTransition) {
5517 ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
5518 return;
5519 }
5520 ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
5521 if (nextState != NO_TRANSITION)
5522 m_afState = nextState;
5523}
5524
5525void ExynosCameraHWInterface2::OnAfCancel(int id)
5526{
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07005527 m_afTriggerId = id;
5528
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005529 switch (m_afMode) {
5530 case AA_AFMODE_AUTO:
5531 case AA_AFMODE_MACRO:
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07005532 case AA_AFMODE_OFF:
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005533 OnAfCancelAutoMacro(id);
5534 break;
5535 case AA_AFMODE_CONTINUOUS_VIDEO:
5536 OnAfCancelCAFVideo(id);
5537 break;
5538 case AA_AFMODE_CONTINUOUS_PICTURE:
5539 OnAfCancelCAFPicture(id);
5540 break;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005541 default:
5542 break;
5543 }
5544}
5545
5546void ExynosCameraHWInterface2::OnAfCancelAutoMacro(int id)
5547{
5548 int nextState = NO_TRANSITION;
5549 m_afTriggerId = id;
5550
Younghwan Jooe117f752012-09-12 22:21:55 -07005551 if (m_ctlInfo.flash.m_flashEnableFlg && m_ctlInfo.flash.m_afFlashDoneFlg) {
5552 m_ctlInfo.flash.m_flashCnt = IS_FLASH_STATE_AUTO_OFF;
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07005553 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005554 switch (m_afState) {
5555 case HAL_AFSTATE_INACTIVE:
5556 nextState = NO_TRANSITION;
Sungjoong Kangcd13bb72012-08-28 13:05:01 -07005557 SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005558 break;
5559 case HAL_AFSTATE_NEEDS_COMMAND:
5560 case HAL_AFSTATE_STARTED:
5561 case HAL_AFSTATE_SCANNING:
5562 case HAL_AFSTATE_LOCKED:
5563 case HAL_AFSTATE_FAILED:
5564 SetAfMode(AA_AFMODE_OFF);
5565 SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
5566 nextState = HAL_AFSTATE_INACTIVE;
5567 break;
5568 default:
5569 break;
5570 }
5571 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
5572 if (nextState != NO_TRANSITION)
5573 m_afState = nextState;
5574}
5575
5576void ExynosCameraHWInterface2::OnAfCancelCAFPicture(int id)
5577{
5578 int nextState = NO_TRANSITION;
5579 m_afTriggerId = id;
5580
5581 switch (m_afState) {
5582 case HAL_AFSTATE_INACTIVE:
5583 nextState = NO_TRANSITION;
5584 break;
5585 case HAL_AFSTATE_NEEDS_COMMAND:
5586 case HAL_AFSTATE_STARTED:
5587 case HAL_AFSTATE_SCANNING:
5588 case HAL_AFSTATE_LOCKED:
5589 case HAL_AFSTATE_FAILED:
5590 case HAL_AFSTATE_NEEDS_DETERMINATION:
5591 case HAL_AFSTATE_PASSIVE_FOCUSED:
5592 SetAfMode(AA_AFMODE_OFF);
5593 SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
5594 SetAfMode(AA_AFMODE_CONTINUOUS_PICTURE);
5595 nextState = HAL_AFSTATE_INACTIVE;
5596 break;
5597 default:
5598 break;
5599 }
5600 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
5601 if (nextState != NO_TRANSITION)
5602 m_afState = nextState;
5603}
5604
5605void ExynosCameraHWInterface2::OnAfCancelCAFVideo(int id)
5606{
5607 int nextState = NO_TRANSITION;
5608 m_afTriggerId = id;
5609
5610 switch (m_afState) {
5611 case HAL_AFSTATE_INACTIVE:
5612 nextState = NO_TRANSITION;
5613 break;
5614 case HAL_AFSTATE_NEEDS_COMMAND:
5615 case HAL_AFSTATE_STARTED:
5616 case HAL_AFSTATE_SCANNING:
5617 case HAL_AFSTATE_LOCKED:
5618 case HAL_AFSTATE_FAILED:
5619 case HAL_AFSTATE_NEEDS_DETERMINATION:
5620 case HAL_AFSTATE_PASSIVE_FOCUSED:
5621 SetAfMode(AA_AFMODE_OFF);
5622 SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
5623 SetAfMode(AA_AFMODE_CONTINUOUS_VIDEO);
5624 nextState = HAL_AFSTATE_INACTIVE;
5625 break;
5626 default:
5627 break;
5628 }
5629 ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
5630 if (nextState != NO_TRANSITION)
5631 m_afState = nextState;
5632}
5633
5634void ExynosCameraHWInterface2::SetAfStateForService(int newState)
5635{
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07005636 if (m_serviceAfState != newState || newState == 0)
5637 m_notifyCb(CAMERA2_MSG_AUTOFOCUS, newState, m_afTriggerId, 0, m_callbackCookie);
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005638 m_serviceAfState = newState;
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005639}
5640
5641int ExynosCameraHWInterface2::GetAfStateForService()
5642{
5643 return m_serviceAfState;
5644}
5645
5646void ExynosCameraHWInterface2::SetAfMode(enum aa_afmode afMode)
5647{
5648 if (m_afMode != afMode) {
5649 if (m_IsAfModeUpdateRequired) {
5650 m_afMode2 = afMode;
5651 ALOGV("(%s): pending(%d) and new(%d)", __FUNCTION__, m_afMode, afMode);
5652 }
5653 else {
5654 ALOGV("(%s): current(%d) new(%d)", __FUNCTION__, m_afMode, afMode);
5655 m_IsAfModeUpdateRequired = true;
5656 m_afMode = afMode;
Sungjoong Kangcd13bb72012-08-28 13:05:01 -07005657 if (m_afModeWaitingCnt != 0) {
5658 m_afModeWaitingCnt = 0;
hyeonmyeong Choi7d0efb52012-09-02 16:02:13 -07005659 m_afState = HAL_AFSTATE_INACTIVE;
Sungjoong Kangcd13bb72012-08-28 13:05:01 -07005660 OnAfTrigger(m_afPendingTriggerId);
5661 }
Sungjoong Kang8e2c2fd2012-08-27 00:02:22 -07005662 }
Sungjoong Kang0f26b202012-08-17 15:43:12 -07005663 }
5664}
5665
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005666void ExynosCameraHWInterface2::m_setExifFixedAttribute(void)
5667{
5668 char property[PROPERTY_VALUE_MAX];
5669
5670 //2 0th IFD TIFF Tags
Rebecca Schultz Zavin1b8ef182012-09-04 09:44:10 -07005671#if 0 // STOPSHIP TODO(aray): remove before launch, but for now don't leak product data
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005672 //3 Maker
5673 property_get("ro.product.brand", property, EXIF_DEF_MAKER);
5674 strncpy((char *)mExifInfo.maker, property,
5675 sizeof(mExifInfo.maker) - 1);
5676 mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0';
5677 //3 Model
5678 property_get("ro.product.model", property, EXIF_DEF_MODEL);
5679 strncpy((char *)mExifInfo.model, property,
5680 sizeof(mExifInfo.model) - 1);
5681 mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0';
5682 //3 Software
5683 property_get("ro.build.id", property, EXIF_DEF_SOFTWARE);
5684 strncpy((char *)mExifInfo.software, property,
5685 sizeof(mExifInfo.software) - 1);
5686 mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0';
Alex Ray5a92f772012-08-27 17:23:41 -07005687#endif
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005688
5689 //3 YCbCr Positioning
5690 mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING;
5691
5692 //2 0th IFD Exif Private Tags
5693 //3 F Number
Sungjoong Kange00f6592012-09-07 19:05:31 -07005694 mExifInfo.fnumber.num = (uint32_t)(m_camera2->m_curCameraInfo->fnumber * EXIF_DEF_FNUMBER_DEN);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005695 mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN;
5696 //3 Exposure Program
5697 mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM;
5698 //3 Exif Version
5699 memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version));
5700 //3 Aperture
Sungjoong Kange00f6592012-09-07 19:05:31 -07005701 double av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den);
5702 mExifInfo.aperture.num = (uint32_t)(av*EXIF_DEF_APEX_DEN);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005703 mExifInfo.aperture.den = EXIF_DEF_APEX_DEN;
5704 //3 Maximum lens aperture
5705 mExifInfo.max_aperture.num = mExifInfo.aperture.num;
5706 mExifInfo.max_aperture.den = mExifInfo.aperture.den;
5707 //3 Lens Focal Length
Sungjoong Kange00f6592012-09-07 19:05:31 -07005708 mExifInfo.focal_length.num = (uint32_t)(m_camera2->m_curCameraInfo->focalLength * 100);
5709
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005710 mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN;
5711 //3 User Comments
5712 strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS);
5713 //3 Color Space information
5714 mExifInfo.color_space = EXIF_DEF_COLOR_SPACE;
5715 //3 Exposure Mode
5716 mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE;
5717
5718 //2 0th IFD GPS Info Tags
5719 unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 };
5720 memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version));
5721
5722 //2 1th IFD TIFF Tags
5723 mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION;
5724 mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM;
5725 mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN;
5726 mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM;
5727 mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN;
5728 mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT;
5729}
5730
5731void ExynosCameraHWInterface2::m_setExifChangedAttribute(exif_attribute_t *exifInfo, ExynosRect *rect,
Sungjoong Kang48728d42012-09-26 13:48:48 -07005732 camera2_shot_ext *currentEntry)
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005733{
Sungjoong Kang48728d42012-09-26 13:48:48 -07005734 camera2_dm *dm = &(currentEntry->shot.dm);
5735 camera2_ctl *ctl = &(currentEntry->shot.ctl);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005736
5737 ALOGV("(%s): framecnt(%d) exp(%lld) iso(%d)", __FUNCTION__, ctl->request.frameCount, dm->sensor.exposureTime,dm->aa.isoValue );
5738 if (!ctl->request.frameCount)
5739 return;
5740 //2 0th IFD TIFF Tags
5741 //3 Width
5742 exifInfo->width = rect->w;
5743 //3 Height
5744 exifInfo->height = rect->h;
5745 //3 Orientation
5746 switch (ctl->jpeg.orientation) {
5747 case 90:
5748 exifInfo->orientation = EXIF_ORIENTATION_90;
5749 break;
5750 case 180:
5751 exifInfo->orientation = EXIF_ORIENTATION_180;
5752 break;
5753 case 270:
5754 exifInfo->orientation = EXIF_ORIENTATION_270;
5755 break;
5756 case 0:
5757 default:
5758 exifInfo->orientation = EXIF_ORIENTATION_UP;
5759 break;
5760 }
5761
5762 //3 Date time
5763 time_t rawtime;
5764 struct tm *timeinfo;
5765 time(&rawtime);
5766 timeinfo = localtime(&rawtime);
5767 strftime((char *)exifInfo->date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
5768
5769 //2 0th IFD Exif Private Tags
5770 //3 Exposure Time
5771 int shutterSpeed = (dm->sensor.exposureTime/1000);
5772
Sungjoong Kang9a77d672012-09-17 18:02:01 -07005773 // To display exposure time just above 500ms as 1/2sec, not 1 sec.
5774 if (shutterSpeed > 500000)
5775 shutterSpeed -= 100000;
5776
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005777 if (shutterSpeed < 0) {
5778 shutterSpeed = 100;
5779 }
5780
5781 exifInfo->exposure_time.num = 1;
5782 // x us -> 1/x s */
5783 //exifInfo->exposure_time.den = (uint32_t)(1000000 / shutterSpeed);
5784 exifInfo->exposure_time.den = (uint32_t)((double)1000000 / shutterSpeed);
5785
5786 //3 ISO Speed Rating
5787 exifInfo->iso_speed_rating = dm->aa.isoValue;
5788
5789 uint32_t av, tv, bv, sv, ev;
5790 av = APEX_FNUM_TO_APERTURE((double)exifInfo->fnumber.num / exifInfo->fnumber.den);
5791 tv = APEX_EXPOSURE_TO_SHUTTER((double)exifInfo->exposure_time.num / exifInfo->exposure_time.den);
5792 sv = APEX_ISO_TO_FILMSENSITIVITY(exifInfo->iso_speed_rating);
5793 bv = av + tv - sv;
5794 ev = av + tv;
5795 //ALOGD("Shutter speed=%d us, iso=%d", shutterSpeed, exifInfo->iso_speed_rating);
Sungjoong Kangc06b3292012-09-28 17:14:57 -07005796 ALOGV("AV=%d, TV=%d, SV=%d", av, tv, sv);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005797
5798 //3 Shutter Speed
5799 exifInfo->shutter_speed.num = tv * EXIF_DEF_APEX_DEN;
5800 exifInfo->shutter_speed.den = EXIF_DEF_APEX_DEN;
5801 //3 Brightness
5802 exifInfo->brightness.num = bv*EXIF_DEF_APEX_DEN;
5803 exifInfo->brightness.den = EXIF_DEF_APEX_DEN;
5804 //3 Exposure Bias
5805 if (ctl->aa.sceneMode== AA_SCENE_MODE_BEACH||
5806 ctl->aa.sceneMode== AA_SCENE_MODE_SNOW) {
5807 exifInfo->exposure_bias.num = EXIF_DEF_APEX_DEN;
5808 exifInfo->exposure_bias.den = EXIF_DEF_APEX_DEN;
5809 } else {
5810 exifInfo->exposure_bias.num = 0;
5811 exifInfo->exposure_bias.den = 0;
5812 }
5813 //3 Metering Mode
5814 /*switch (m_curCameraInfo->metering) {
5815 case METERING_MODE_CENTER:
5816 exifInfo->metering_mode = EXIF_METERING_CENTER;
5817 break;
5818 case METERING_MODE_MATRIX:
5819 exifInfo->metering_mode = EXIF_METERING_MULTISPOT;
5820 break;
5821 case METERING_MODE_SPOT:
5822 exifInfo->metering_mode = EXIF_METERING_SPOT;
5823 break;
5824 case METERING_MODE_AVERAGE:
5825 default:
5826 exifInfo->metering_mode = EXIF_METERING_AVERAGE;
5827 break;
5828 }*/
5829 exifInfo->metering_mode = EXIF_METERING_CENTER;
5830
5831 //3 Flash
Younghwan Joo9257e292012-09-08 21:11:18 -07005832 if (m_ctlInfo.flash.m_flashDecisionResult)
5833 exifInfo->flash = 1;
5834 else
5835 exifInfo->flash = EXIF_DEF_FLASH;
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005836
5837 //3 White Balance
Sungjoong Kang48728d42012-09-26 13:48:48 -07005838 if (currentEntry->awb_mode_dm == AA_AWBMODE_WB_AUTO)
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005839 exifInfo->white_balance = EXIF_WB_AUTO;
5840 else
5841 exifInfo->white_balance = EXIF_WB_MANUAL;
5842
5843 //3 Scene Capture Type
5844 switch (ctl->aa.sceneMode) {
5845 case AA_SCENE_MODE_PORTRAIT:
5846 exifInfo->scene_capture_type = EXIF_SCENE_PORTRAIT;
5847 break;
5848 case AA_SCENE_MODE_LANDSCAPE:
5849 exifInfo->scene_capture_type = EXIF_SCENE_LANDSCAPE;
5850 break;
5851 case AA_SCENE_MODE_NIGHT_PORTRAIT:
5852 exifInfo->scene_capture_type = EXIF_SCENE_NIGHT;
5853 break;
5854 default:
5855 exifInfo->scene_capture_type = EXIF_SCENE_STANDARD;
5856 break;
5857 }
5858
5859 //2 0th IFD GPS Info Tags
5860 if (ctl->jpeg.gpsCoordinates[0] != 0 && ctl->jpeg.gpsCoordinates[1] != 0) {
5861
5862 if (ctl->jpeg.gpsCoordinates[0] > 0)
5863 strcpy((char *)exifInfo->gps_latitude_ref, "N");
5864 else
5865 strcpy((char *)exifInfo->gps_latitude_ref, "S");
5866
5867 if (ctl->jpeg.gpsCoordinates[1] > 0)
5868 strcpy((char *)exifInfo->gps_longitude_ref, "E");
5869 else
5870 strcpy((char *)exifInfo->gps_longitude_ref, "W");
5871
5872 if (ctl->jpeg.gpsCoordinates[2] > 0)
5873 exifInfo->gps_altitude_ref = 0;
5874 else
5875 exifInfo->gps_altitude_ref = 1;
5876
Sungjoong Kang0066b2c2012-10-04 13:31:13 -07005877 double latitude = fabs(ctl->jpeg.gpsCoordinates[0]);
5878 double longitude = fabs(ctl->jpeg.gpsCoordinates[1]);
5879 double altitude = fabs(ctl->jpeg.gpsCoordinates[2]);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005880
5881 exifInfo->gps_latitude[0].num = (uint32_t)latitude;
5882 exifInfo->gps_latitude[0].den = 1;
5883 exifInfo->gps_latitude[1].num = (uint32_t)((latitude - exifInfo->gps_latitude[0].num) * 60);
5884 exifInfo->gps_latitude[1].den = 1;
5885 exifInfo->gps_latitude[2].num = (uint32_t)((((latitude - exifInfo->gps_latitude[0].num) * 60)
5886 - exifInfo->gps_latitude[1].num) * 60);
5887 exifInfo->gps_latitude[2].den = 1;
5888
5889 exifInfo->gps_longitude[0].num = (uint32_t)longitude;
5890 exifInfo->gps_longitude[0].den = 1;
5891 exifInfo->gps_longitude[1].num = (uint32_t)((longitude - exifInfo->gps_longitude[0].num) * 60);
5892 exifInfo->gps_longitude[1].den = 1;
5893 exifInfo->gps_longitude[2].num = (uint32_t)((((longitude - exifInfo->gps_longitude[0].num) * 60)
5894 - exifInfo->gps_longitude[1].num) * 60);
5895 exifInfo->gps_longitude[2].den = 1;
5896
5897 exifInfo->gps_altitude.num = (uint32_t)altitude;
5898 exifInfo->gps_altitude.den = 1;
5899
5900 struct tm tm_data;
5901 long timestamp;
5902 timestamp = (long)ctl->jpeg.gpsTimestamp;
5903 gmtime_r(&timestamp, &tm_data);
5904 exifInfo->gps_timestamp[0].num = tm_data.tm_hour;
5905 exifInfo->gps_timestamp[0].den = 1;
5906 exifInfo->gps_timestamp[1].num = tm_data.tm_min;
5907 exifInfo->gps_timestamp[1].den = 1;
5908 exifInfo->gps_timestamp[2].num = tm_data.tm_sec;
5909 exifInfo->gps_timestamp[2].den = 1;
5910 snprintf((char*)exifInfo->gps_datestamp, sizeof(exifInfo->gps_datestamp),
5911 "%04d:%02d:%02d", tm_data.tm_year + 1900, tm_data.tm_mon + 1, tm_data.tm_mday);
5912
Sungjoong Kang0066b2c2012-10-04 13:31:13 -07005913 memcpy(exifInfo->gps_processing_method, currentEntry->gpsProcessingMethod, 32);
Sungjoong Kangeed7ed12012-08-23 16:35:08 -07005914 exifInfo->enableGps = true;
5915 } else {
5916 exifInfo->enableGps = false;
5917 }
5918
5919 //2 1th IFD TIFF Tags
5920 exifInfo->widthThumb = ctl->jpeg.thumbnailSize[0];
5921 exifInfo->heightThumb = ctl->jpeg.thumbnailSize[1];
5922}
5923
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005924ExynosCameraHWInterface2::MainThread::~MainThread()
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07005925{
Sungjoong Kangad378612012-08-17 12:34:33 -07005926 ALOGV("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005927}
5928
5929void ExynosCameraHWInterface2::MainThread::release()
5930{
Sungjoong Kangad378612012-08-17 12:34:33 -07005931 ALOGV("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005932 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005933}
5934
5935ExynosCameraHWInterface2::SensorThread::~SensorThread()
5936{
Sungjoong Kangad378612012-08-17 12:34:33 -07005937 ALOGV("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005938}
5939
5940void ExynosCameraHWInterface2::SensorThread::release()
5941{
Sungjoong Kangad378612012-08-17 12:34:33 -07005942 ALOGV("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005943 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005944}
5945
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005946ExynosCameraHWInterface2::StreamThread::~StreamThread()
5947{
Sungjoong Kangad378612012-08-17 12:34:33 -07005948 ALOGV("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005949}
5950
5951void ExynosCameraHWInterface2::StreamThread::setParameter(stream_parameters_t * new_parameters)
5952{
5953 ALOGV("DEBUG(%s):", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07005954 memcpy(&m_parameters, new_parameters, sizeof(stream_parameters_t));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005955}
5956
5957void ExynosCameraHWInterface2::StreamThread::release()
5958{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09005959 ALOGV("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005960 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09005961}
5962
5963int ExynosCameraHWInterface2::StreamThread::findBufferIndex(void * bufAddr)
5964{
5965 int index;
5966 for (index = 0 ; index < m_parameters.numSvcBuffers ; index++) {
5967 if (m_parameters.svcBuffers[index].virt.extP[0] == bufAddr)
5968 return index;
5969 }
5970 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07005971}
5972
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07005973int ExynosCameraHWInterface2::StreamThread::findBufferIndex(buffer_handle_t * bufHandle)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09005974{
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07005975 int index;
5976 for (index = 0 ; index < m_parameters.numSvcBuffers ; index++) {
5977 if (m_parameters.svcBufHandle[index] == *bufHandle)
5978 return index;
5979 }
5980 return -1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09005981}
5982
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07005983status_t ExynosCameraHWInterface2::StreamThread::attachSubStream(int stream_id, int priority)
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07005984{
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07005985 ALOGV("(%s): substream_id(%d)", __FUNCTION__, stream_id);
5986 int index, vacantIndex;
5987 bool vacancy = false;
5988
5989 for (index = 0 ; index < NUM_MAX_SUBSTREAM ; index++) {
5990 if (!vacancy && m_attachedSubStreams[index].streamId == -1) {
5991 vacancy = true;
5992 vacantIndex = index;
5993 } else if (m_attachedSubStreams[index].streamId == stream_id) {
5994 return BAD_VALUE;
5995 }
5996 }
5997 if (!vacancy)
5998 return NO_MEMORY;
5999 m_attachedSubStreams[vacantIndex].streamId = stream_id;
6000 m_attachedSubStreams[vacantIndex].priority = priority;
6001 m_numRegisteredStream++;
6002 return NO_ERROR;
6003}
6004
6005status_t ExynosCameraHWInterface2::StreamThread::detachSubStream(int stream_id)
6006{
6007 ALOGV("(%s): substream_id(%d)", __FUNCTION__, stream_id);
6008 int index;
6009 bool found = false;
6010
6011 for (index = 0 ; index < NUM_MAX_SUBSTREAM ; index++) {
6012 if (m_attachedSubStreams[index].streamId == stream_id) {
6013 found = true;
6014 break;
6015 }
6016 }
6017 if (!found)
6018 return BAD_VALUE;
6019 m_attachedSubStreams[index].streamId = -1;
6020 m_attachedSubStreams[index].priority = 0;
6021 m_numRegisteredStream--;
6022 return NO_ERROR;
Sungjoong Kang74d78eb2012-08-29 13:25:46 -07006023}
6024
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006025int ExynosCameraHWInterface2::createIonClient(ion_client ionClient)
6026{
6027 if (ionClient == 0) {
6028 ionClient = ion_client_create();
6029 if (ionClient < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006030 ALOGE("[%s]src ion client create failed, value = %d\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006031 return 0;
6032 }
6033 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006034 return ionClient;
6035}
6036
6037int ExynosCameraHWInterface2::deleteIonClient(ion_client ionClient)
6038{
6039 if (ionClient != 0) {
6040 if (ionClient > 0) {
6041 ion_client_destroy(ionClient);
6042 }
6043 ionClient = 0;
6044 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006045 return ionClient;
6046}
6047
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006048int ExynosCameraHWInterface2::allocCameraMemory(ion_client ionClient, ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006049{
Sungjoong Kang181e4252012-08-29 02:11:07 -07006050 return allocCameraMemory(ionClient, buf, iMemoryNum, 0);
6051}
6052
6053int ExynosCameraHWInterface2::allocCameraMemory(ion_client ionClient, ExynosBuffer *buf, int iMemoryNum, int cacheFlag)
6054{
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006055 int ret = 0;
6056 int i = 0;
Sungjoong Kang181e4252012-08-29 02:11:07 -07006057 int flag = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006058
6059 if (ionClient == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006060 ALOGE("[%s] ionClient is zero (%d)\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006061 return -1;
6062 }
6063
Sungjoong Kang181e4252012-08-29 02:11:07 -07006064 for (i = 0 ; i < iMemoryNum ; i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006065 if (buf->size.extS[i] == 0) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006066 break;
6067 }
Sungjoong Kang181e4252012-08-29 02:11:07 -07006068 if (1 << i & cacheFlag)
6069 flag = ION_FLAG_CACHED;
6070 else
6071 flag = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006072 buf->fd.extFd[i] = ion_alloc(ionClient, \
Sungjoong Kang181e4252012-08-29 02:11:07 -07006073 buf->size.extS[i], 0, ION_HEAP_EXYNOS_MASK, flag);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006074 if ((buf->fd.extFd[i] == -1) ||(buf->fd.extFd[i] == 0)) {
6075 ALOGE("[%s]ion_alloc(%d) failed\n", __FUNCTION__, buf->size.extS[i]);
6076 buf->fd.extFd[i] = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006077 freeCameraMemory(buf, iMemoryNum);
6078 return -1;
6079 }
6080
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006081 buf->virt.extP[i] = (char *)ion_map(buf->fd.extFd[i], \
6082 buf->size.extS[i], 0);
6083 if ((buf->virt.extP[i] == (char *)MAP_FAILED) || (buf->virt.extP[i] == NULL)) {
6084 ALOGE("[%s]src ion map failed(%d)\n", __FUNCTION__, buf->size.extS[i]);
6085 buf->virt.extP[i] = (char *)MAP_FAILED;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006086 freeCameraMemory(buf, iMemoryNum);
6087 return -1;
6088 }
Sungjoong Kang181e4252012-08-29 02:11:07 -07006089 ALOGV("allocCameraMem : [%d][0x%08x] size(%d) flag(%d)", i, (unsigned int)(buf->virt.extP[i]), buf->size.extS[i], flag);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006090 }
6091
6092 return ret;
6093}
6094
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006095void ExynosCameraHWInterface2::freeCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006096{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006097
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07006098 int i = 0 ;
Sungjoong Kang15fd8232012-08-23 16:16:44 -07006099 int ret = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006100
6101 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006102 if (buf->fd.extFd[i] != -1) {
6103 if (buf->virt.extP[i] != (char *)MAP_FAILED) {
Sungjoong Kang15fd8232012-08-23 16:16:44 -07006104 ret = ion_unmap(buf->virt.extP[i], buf->size.extS[i]);
6105 if (ret < 0)
6106 ALOGE("ERR(%s)", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006107 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006108 ion_free(buf->fd.extFd[i]);
Sungjoong Kang90e439c2012-09-20 02:26:22 -07006109 ALOGV("freeCameraMemory : [%d][0x%08x] size(%d)", i, (unsigned int)(buf->virt.extP[i]), buf->size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006110 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006111 buf->fd.extFd[i] = -1;
6112 buf->virt.extP[i] = (char *)MAP_FAILED;
6113 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006114 }
6115}
6116
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006117void ExynosCameraHWInterface2::initCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006118{
6119 int i =0 ;
6120 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006121 buf->virt.extP[i] = (char *)MAP_FAILED;
6122 buf->fd.extFd[i] = -1;
6123 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006124 }
6125}
6126
6127
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006128
6129
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006130static camera2_device_t *g_cam2_device = NULL;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07006131static bool g_camera_vaild = false;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006132ExynosCamera2 * g_camera2[2] = { NULL, NULL };
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006133
6134static int HAL2_camera_device_close(struct hw_device_t* device)
6135{
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07006136 ALOGD("(%s): ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006137 if (device) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006138
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006139 camera2_device_t *cam_device = (camera2_device_t *)device;
Sungjoong Kangad378612012-08-17 12:34:33 -07006140 ALOGV("cam_device(0x%08x):", (unsigned int)cam_device);
6141 ALOGV("g_cam2_device(0x%08x):", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006142 delete static_cast<ExynosCameraHWInterface2 *>(cam_device->priv);
6143 free(cam_device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07006144 g_camera_vaild = false;
Sungjoong Kang053d38c2012-09-17 17:46:52 -07006145 g_cam2_device = NULL;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006146 }
Sungjoong Kang15fd8232012-08-23 16:16:44 -07006147
Sungjoong Kanged4ad5f2012-09-14 13:50:31 -07006148 ALOGD("(%s): EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006149 return 0;
6150}
6151
6152static inline ExynosCameraHWInterface2 *obj(const struct camera2_device *dev)
6153{
6154 return reinterpret_cast<ExynosCameraHWInterface2 *>(dev->priv);
6155}
6156
6157static int HAL2_device_set_request_queue_src_ops(const struct camera2_device *dev,
6158 const camera2_request_queue_src_ops_t *request_src_ops)
6159{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006160 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006161 return obj(dev)->setRequestQueueSrcOps(request_src_ops);
6162}
6163
6164static int HAL2_device_notify_request_queue_not_empty(const struct camera2_device *dev)
6165{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006166 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006167 return obj(dev)->notifyRequestQueueNotEmpty();
6168}
6169
6170static int HAL2_device_set_frame_queue_dst_ops(const struct camera2_device *dev,
6171 const camera2_frame_queue_dst_ops_t *frame_dst_ops)
6172{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006173 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006174 return obj(dev)->setFrameQueueDstOps(frame_dst_ops);
6175}
6176
6177static int HAL2_device_get_in_progress_count(const struct camera2_device *dev)
6178{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006179 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006180 return obj(dev)->getInProgressCount();
6181}
6182
6183static int HAL2_device_flush_captures_in_progress(const struct camera2_device *dev)
6184{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006185 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006186 return obj(dev)->flushCapturesInProgress();
6187}
6188
6189static int HAL2_device_construct_default_request(const struct camera2_device *dev,
6190 int request_template, camera_metadata_t **request)
6191{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006192 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006193 return obj(dev)->constructDefaultRequest(request_template, request);
6194}
6195
6196static int HAL2_device_allocate_stream(
6197 const struct camera2_device *dev,
6198 // inputs
6199 uint32_t width,
6200 uint32_t height,
6201 int format,
6202 const camera2_stream_ops_t *stream_ops,
6203 // outputs
6204 uint32_t *stream_id,
6205 uint32_t *format_actual,
6206 uint32_t *usage,
6207 uint32_t *max_buffers)
6208{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006209 ALOGV("(%s): ", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006210 return obj(dev)->allocateStream(width, height, format, stream_ops,
6211 stream_id, format_actual, usage, max_buffers);
6212}
6213
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006214static int HAL2_device_register_stream_buffers(const struct camera2_device *dev,
6215 uint32_t stream_id,
6216 int num_buffers,
6217 buffer_handle_t *buffers)
6218{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006219 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006220 return obj(dev)->registerStreamBuffers(stream_id, num_buffers, buffers);
6221}
6222
6223static int HAL2_device_release_stream(
6224 const struct camera2_device *dev,
6225 uint32_t stream_id)
6226{
Sungjoong Kangad378612012-08-17 12:34:33 -07006227 ALOGV("DEBUG(%s)(id: %d):", __FUNCTION__, stream_id);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07006228 if (!g_camera_vaild)
6229 return 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006230 return obj(dev)->releaseStream(stream_id);
6231}
6232
6233static int HAL2_device_allocate_reprocess_stream(
6234 const struct camera2_device *dev,
6235 uint32_t width,
6236 uint32_t height,
6237 uint32_t format,
6238 const camera2_stream_in_ops_t *reprocess_stream_ops,
6239 // outputs
6240 uint32_t *stream_id,
6241 uint32_t *consumer_usage,
6242 uint32_t *max_buffers)
6243{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006244 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006245 return obj(dev)->allocateReprocessStream(width, height, format, reprocess_stream_ops,
6246 stream_id, consumer_usage, max_buffers);
6247}
6248
Eino-Ville Talvala2b0421d2012-09-04 13:41:55 -07006249static int HAL2_device_allocate_reprocess_stream_from_stream(
6250 const struct camera2_device *dev,
6251 uint32_t output_stream_id,
6252 const camera2_stream_in_ops_t *reprocess_stream_ops,
6253 // outputs
6254 uint32_t *stream_id)
6255{
6256 ALOGV("DEBUG(%s):", __FUNCTION__);
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07006257 return obj(dev)->allocateReprocessStreamFromStream(output_stream_id,
6258 reprocess_stream_ops, stream_id);
Eino-Ville Talvala2b0421d2012-09-04 13:41:55 -07006259}
6260
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006261static int HAL2_device_release_reprocess_stream(
6262 const struct camera2_device *dev,
6263 uint32_t stream_id)
6264{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006265 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006266 return obj(dev)->releaseReprocessStream(stream_id);
6267}
6268
6269static int HAL2_device_trigger_action(const struct camera2_device *dev,
6270 uint32_t trigger_id,
6271 int ext1,
6272 int ext2)
6273{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006274 ALOGV("DEBUG(%s):", __FUNCTION__);
Sungjoong Kangb8d41ae2012-09-13 20:49:27 -07006275 if (!g_camera_vaild)
6276 return 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006277 return obj(dev)->triggerAction(trigger_id, ext1, ext2);
6278}
6279
6280static int HAL2_device_set_notify_callback(const struct camera2_device *dev,
6281 camera2_notify_callback notify_cb,
6282 void *user)
6283{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006284 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006285 return obj(dev)->setNotifyCallback(notify_cb, user);
6286}
6287
6288static int HAL2_device_get_metadata_vendor_tag_ops(const struct camera2_device*dev,
6289 vendor_tag_query_ops_t **ops)
6290{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006291 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006292 return obj(dev)->getMetadataVendorTagOps(ops);
6293}
6294
6295static int HAL2_device_dump(const struct camera2_device *dev, int fd)
6296{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006297 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006298 return obj(dev)->dump(fd);
6299}
6300
6301
6302
6303
6304
6305static int HAL2_getNumberOfCameras()
6306{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006307 ALOGV("(%s): returning 2", __FUNCTION__);
6308 return 2;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006309}
6310
6311
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006312static int HAL2_getCameraInfo(int cameraId, struct camera_info *info)
6313{
Sungjoong Kangad378612012-08-17 12:34:33 -07006314 ALOGV("DEBUG(%s): cameraID: %d", __FUNCTION__, cameraId);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006315 static camera_metadata_t * mCameraInfo[2] = {NULL, NULL};
Sungjoong Kangad378612012-08-17 12:34:33 -07006316
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006317 status_t res;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006318
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006319 if (cameraId == 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006320 info->facing = CAMERA_FACING_BACK;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006321 if (!g_camera2[0])
6322 g_camera2[0] = new ExynosCamera2(0);
6323 }
6324 else if (cameraId == 1) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006325 info->facing = CAMERA_FACING_FRONT;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006326 if (!g_camera2[1])
6327 g_camera2[1] = new ExynosCamera2(1);
6328 }
6329 else
6330 return BAD_VALUE;
6331
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006332 info->orientation = 0;
6333 info->device_version = HARDWARE_DEVICE_API_VERSION(2, 0);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006334 if (mCameraInfo[cameraId] == NULL) {
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006335 res = g_camera2[cameraId]->constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, true);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006336 if (res != OK) {
6337 ALOGE("%s: Unable to allocate static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006338 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006339 return res;
6340 }
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07006341 res = g_camera2[cameraId]->constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, false);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006342 if (res != OK) {
6343 ALOGE("%s: Unable to fill in static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006344 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006345 return res;
6346 }
6347 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006348 info->static_camera_characteristics = mCameraInfo[cameraId];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006349 return NO_ERROR;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006350}
6351
6352#define SET_METHOD(m) m : HAL2_device_##m
6353
6354static camera2_device_ops_t camera2_device_ops = {
6355 SET_METHOD(set_request_queue_src_ops),
6356 SET_METHOD(notify_request_queue_not_empty),
6357 SET_METHOD(set_frame_queue_dst_ops),
6358 SET_METHOD(get_in_progress_count),
6359 SET_METHOD(flush_captures_in_progress),
6360 SET_METHOD(construct_default_request),
6361 SET_METHOD(allocate_stream),
6362 SET_METHOD(register_stream_buffers),
6363 SET_METHOD(release_stream),
6364 SET_METHOD(allocate_reprocess_stream),
Eino-Ville Talvala2b0421d2012-09-04 13:41:55 -07006365 SET_METHOD(allocate_reprocess_stream_from_stream),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006366 SET_METHOD(release_reprocess_stream),
6367 SET_METHOD(trigger_action),
6368 SET_METHOD(set_notify_callback),
6369 SET_METHOD(get_metadata_vendor_tag_ops),
6370 SET_METHOD(dump),
6371};
6372
6373#undef SET_METHOD
6374
6375
6376static int HAL2_camera_device_open(const struct hw_module_t* module,
6377 const char *id,
6378 struct hw_device_t** device)
6379{
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006380 int cameraId = atoi(id);
Sungjoong Kang6044e502012-08-27 00:29:28 -07006381 int openInvalid = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006382
Sungjoong Kangb5237e62012-07-27 07:39:05 -07006383 g_camera_vaild = false;
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07006384 ALOGD("\n\n>>> I'm Samsung's CameraHAL_2(ID:%d) <<<\n\n", cameraId);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006385 if (cameraId < 0 || cameraId >= HAL2_getNumberOfCameras()) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006386 ALOGE("ERR(%s):Invalid camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006387 return -EINVAL;
6388 }
6389
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07006390 ALOGD("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006391 if (g_cam2_device) {
6392 if (obj(g_cam2_device)->getCameraId() == cameraId) {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07006393 ALOGD("DEBUG(%s):returning existing camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006394 goto done;
6395 } else {
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07006396 ALOGD("(%s): START waiting for cam device free", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006397 while (g_cam2_device)
Sungjoong Kang041f38d2012-09-25 01:39:19 -07006398 usleep(SIG_WAITING_TICK);
Sungjoong Kang0eb27a92012-09-18 01:13:52 -07006399 ALOGD("(%s): END waiting for cam device free", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006400 }
6401 }
6402
6403 g_cam2_device = (camera2_device_t *)malloc(sizeof(camera2_device_t));
Sungjoong Kangad378612012-08-17 12:34:33 -07006404 ALOGV("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09006405
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006406 if (!g_cam2_device)
6407 return -ENOMEM;
6408
6409 g_cam2_device->common.tag = HARDWARE_DEVICE_TAG;
6410 g_cam2_device->common.version = CAMERA_DEVICE_API_VERSION_2_0;
6411 g_cam2_device->common.module = const_cast<hw_module_t *>(module);
6412 g_cam2_device->common.close = HAL2_camera_device_close;
6413
6414 g_cam2_device->ops = &camera2_device_ops;
6415
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006416 ALOGV("DEBUG(%s):open camera2 %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006417
Sungjoong Kang6044e502012-08-27 00:29:28 -07006418 g_cam2_device->priv = new ExynosCameraHWInterface2(cameraId, g_cam2_device, g_camera2[cameraId], &openInvalid);
6419 if (!openInvalid) {
Sungjoong Kang5506ceb2012-09-11 20:41:10 -07006420 ALOGE("DEBUG(%s): ExynosCameraHWInterface2 creation failed", __FUNCTION__);
Younghwan Joo6f19b6c2012-08-30 13:56:53 -07006421 return -ENODEV;
Sungjoong Kang6044e502012-08-27 00:29:28 -07006422 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006423done:
6424 *device = (hw_device_t *)g_cam2_device;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09006425 ALOGV("DEBUG(%s):opened camera2 %s (%p)", __FUNCTION__, id, *device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07006426 g_camera_vaild = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07006427
6428 return 0;
6429}
6430
6431
6432static hw_module_methods_t camera_module_methods = {
6433 open : HAL2_camera_device_open
6434};
6435
6436extern "C" {
6437 struct camera_module HAL_MODULE_INFO_SYM = {
6438 common : {
6439 tag : HARDWARE_MODULE_TAG,
6440 module_api_version : CAMERA_MODULE_API_VERSION_2_0,
6441 hal_api_version : HARDWARE_HAL_API_VERSION,
6442 id : CAMERA_HARDWARE_MODULE_ID,
6443 name : "Exynos Camera HAL2",
6444 author : "Samsung Corporation",
6445 methods : &camera_module_methods,
6446 dso: NULL,
6447 reserved: {0},
6448 },
6449 get_number_of_cameras : HAL2_getNumberOfCameras,
6450 get_camera_info : HAL2_getCameraInfo
6451 };
6452}
6453
6454}; // namespace android